ROBOTC.net forums
http://www.robotc.net/forums/

Learning Color Sorter
http://www.robotc.net/forums/viewtopic.php?f=15&t=6272
Page 1 of 1

Author:  NeXT-Generation [ Mon Jul 15, 2013 10:25 am ]
Post subject:  Learning Color Sorter

Some of you might remember the sorter I posted about a year ago (and still never finished explaining... darned procrastination.) I mentioned that my goal had been to make it able to learn where the colors belong as it goes, and a short while later I posted some learning code.

These two projects have accumulated into this sorter, which I call.... Learning Color Sorter. :? I stink at names.

Image

Unlike my past sorter which did only use one NXT, but also 7 extra motors beyond the three NXT ones, this has only three motors and sensors. Plus a PF light and battery box. This simplification did not, unfortunately, allow me to have it auto-loading. However, as I was stretched for time as I was building this only days before Brickworld, I kept it manual.



This is the part where it scans the brick. The motor with the wheel on it pulls the stack down until a brick breaks the light beam from the PF LED (not visible here), then the motor with the beam on it lowers and stops all but the brick being pulled by the wheel.

Image



The sled is then pulled into position by this motor, and the brick is dropped in. It waits for you to press the red (incorrect) or the green (correct) button if it doesn't know whether it made the right move or not.

Image



The program. (you really need to add spoilers Vu)

Code:
#pragma config(Sensor, S1,     YesBtn,         sensorTouch)
#pragma config(Sensor, S2,     NoBtn,          sensorTouch)
#pragma config(Sensor, S3,     ClrSns,         sensorCOLORFULL)
#pragma config(Sensor, S4,     SledPos,        sensorTouch)
#pragma config(Motor,  motorA,          SledMtr,       tmotorNXT, PIDControl, reversed, encoder)
#pragma config(Motor,  motorB,          StprMtr,       tmotorNXT, PIDControl, encoder)
#pragma config(Motor,  motorC,          ScannerMtr,    tmotorNXT, PIDControl, encoder)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

#define UNKNOWN 0
#define NO 1
#define YES 2

void MoveSled(byte Location);

byte LastLoc = 0;
byte SledLoc = 3;

task main()
{
   typedef struct
   {
      bool ColorDefined;
      byte WhereDoesColorBelong;
      byte DoesColorBelong[6];
   }BRICK_STRUCT;

   BRICK_STRUCT BrickInfo[6];

   bool EndProgram = false;

   for(int i = 0; i <= 5; i++)
   {
      BrickInfo[i].ColorDefined = false;
      BrickInfo[i].WhereDoesColorBelong = 0;

      for(int x = 0; x <= 5; x++)
      {
         BrickInfo[i].DoesColorBelong[x] = UNKNOWN;
      }
   }

   eraseDisplay();
   nxtDisplayRICFile(22, 4, "smile 01.ric");

   //while(true);

   //SledPosThrs = SensorValue[SledPos] - 20;

   motor[SledMtr] = -40;
   while(SensorValue[SledPos] == 0);
   motor[SledMtr] = 0;



   while(EndProgram == false)
   {
      SensorType[ClrSns] = sensorCOLORNONE;

      wait1Msec(500);

      motor[ScannerMtr] = 25;
      time1[T1] = 0;
      while(SensorValue[ClrSns] >= 20 && time1[T1] <= 2000);
      if(SensorValue[ClrSns] < 20)
      {
         wait1Msec(150);
         SensorType[ClrSns] = sensorCOLORFULL;
         motor[ScannerMtr] = 0;

         motor[StprMtr] = -50;
         wait1Msec(100);
         motor[StprMtr] = 0;

         wait1Msec(200);

         int BrickColor = SensorValue[ClrSns] - 1;

         //PlayImmediateTone(1000, 20);

         switch(SensorValue[ClrSns])
         {
         case BLACKCOLOR:
            PlaySoundFile("Black.rso");
            break;
         case WHITECOLOR:
            PlaySoundFile("White.rso");
            break;
         case YELLOWCOLOR:
            PlaySoundFile("Yellow.rso");
            break;
         case REDCOLOR:
            PlaySoundFile("Red.rso");
            break;
         case GREENCOLOR:
            PlaySoundFile("Green.rso");
            break;
         case BLUECOLOR:
            PlaySoundFile("Blue.rso");
            break;
         }

         while(bSoundActive);

         int RandomLoc = random[5];

         if(BrickInfo[BrickColor].ColorDefined == true)
         {
            eraseDisplay();
            nxtDisplayRICFile(22, 4, "smile 01.ric");

            MoveSled(BrickInfo[BrickColor].WhereDoesColorBelong);
         }
         else
         {
            eraseDisplay();
            nxtDisplayRICFile(22, 4, "smile 02.ric");

            bool FoundUnkownLoc = false;

            while(FoundUnkownLoc == false)
            {
               if(BrickInfo[BrickColor].DoesColorBelong[RandomLoc] == UNKNOWN)
               {
                  FoundUnkownLoc = true;
               }
               else
               {
                  RandomLoc = random[5];
               }
            }

            MoveSled(RandomLoc + 1);

            while(SensorValue[YesBtn] == 0 && SensorValue[NoBtn] == 0);

            if(SensorValue[YesBtn] == 1)
            {
               //PlayImmediateTone(1250, 20);

               eraseDisplay();
               nxtDisplayRICFile(22, 4, "smile 01.ric");

               while(SensorValue[YesBtn] == 1);

               BrickInfo[BrickColor].ColorDefined = true;
               BrickInfo[BrickColor].WhereDoesColorBelong = RandomLoc + 1;
               BrickInfo[BrickColor].DoesColorBelong[RandomLoc] = YES;

               for(int y = 0; y <= 5; y++)
               {
                  if(BrickInfo[y].DoesColorBelong[RandomLoc] == UNKNOWN)
                  {
                     BrickInfo[y].DoesColorBelong[RandomLoc] = NO;
                  }
               }

               switch(random[4])
               {
               case 0:
                  PlaySoundFile("Aha.rso");
                  break;
               case 1:
                  PlaySoundFile("Right.rso");
                  break;
               case 2:
                  PlaySoundFile("Champion.rso");
                  break;
               case 3:
                  PlaySoundFile("You're Good.rso");
                  break;
               }
               while(bSoundActive);
            }
            else if(SensorValue[NoBtn] == 1)
            {
               //PlayImmediateTone(800, 20);

               eraseDisplay();
               nxtDisplayRICFile(22, 4, "smile 03.ric");

               while(SensorValue[NoBtn] == 1);

               BrickInfo[BrickColor].DoesColorBelong[RandomLoc] = NO;

               switch(random[6])
               {
               case 0:
                  PlaySoundFile("Woops.rso");
                  break;
               case 1:
                  PlaySoundFile("Sorry.rso");
                  break;
               case 3:
                  PlaySoundFile("Crying 02.rso");
                  break;
               case 4:
                  PlaySoundFile("Ahnoo.rso");
                  break;
               case 5:
                  PlaySoundFile("Buuuhh.rso");
                  break;
               }
               while(bSoundActive);
            }
         }
      }
      else
      {
         motor[ScannerMtr] = 0;

         PlaySound(soundException);

         eraseDisplay();
         nxtDisplayCenteredTextLine(0, "Out of bricks!");
         nxtDisplayCenteredTextLine(2, "After reloading,");
         nxtDisplayCenteredTextLine(3, "press the green");
         nxtDisplayCenteredTextLine(4, "button.  If done");
         nxtDisplayCenteredTextLine(5, "using, press");
         nxtDisplayCenteredTextLine(6, "the red button.");

         while(SensorValue[YesBtn] == 0 && SensorValue[NoBtn] == 0);

         if(SensorValue[NoBtn] == 1)
         {
            EndProgram = true;

            PlaySoundFile("Goodbye.rso");
            while(bSoundActive);
            wait1Msec(500);
            PlaySoundFile("NiceDay.rso");
            while(bSoundActive);
         }
      }
   }
}

void MoveSled(byte Location)
{
   int LocVals[] = {0, 165, 165 * 2, 165 * 3, 165 * 4, 165 * 5};

   if(LastLoc == Location);
   else if(Location == 1)
   {
      motor[SledMtr] = -40;
      while(SensorValue[SledPos] == 0);
      motor[SledMtr] = 0;

      nMotorEncoder[SledMtr] = 0;
   }
   else if(nMotorEncoder[SledMtr] > LocVals[Location - 1])
   {
      motor[SledMtr] = -40;
      while(nMotorEncoder[SledMtr] > LocVals[Location - 1]);
      motor[SledMtr] = 0;
   }
   else if(nMotorEncoder[SledMtr] < LocVals[Location - 1])
   {
      motor[SledMtr] = 40;
      while(nMotorEncoder[SledMtr] < LocVals[Location - 1]);
      motor[SledMtr] = 0;
   }


   motor[ScannerMtr] = 25;
   wait1Msec(500);
   motor[ScannerMtr] = 0;

   motor[StprMtr] = 50;
   wait1Msec(90);
   motor[StprMtr] = 0;

   LastLoc = Location;
}


And, of course, the video. Note about the video, this is my first attempt at making a more professional looking video, so all comments about it are appreciated. I know I'm not gonna be Sariel, but I hope it's at least better than what I've had in the past.


Author:  Coder A [ Thu Aug 22, 2013 6:24 pm ]
Post subject:  Re: Learning Color Sorter

So, after you have taught the robot where to drop the bricks, if in program you switch the dropboxes around, will it relearn, or will it take some time? In other words, is the learning local(learning mainly over the past few actions) or global(learning over the entire actions, being better for long term learning but terrible for exception management, such as the aforementioned switching of dropboxes)?

Author:  NeXT-Generation [ Thu Aug 22, 2013 7:18 pm ]
Post subject:  Re: Learning Color Sorter

You can switch the boxes, but only in between runs. It has no way to know where the colors go besides your input, and I never added any code to re-learn mid-run.

Author:  Coder A [ Thu Aug 22, 2013 7:26 pm ]
Post subject:  Re: Learning Color Sorter

If you make the program only learn and act based on the past 50 actions or so, and add code for trial and error, like an action being correct once but wrong twice, thus making the action perceived as wrong, then the program would be able to relearn mid-run.

Author:  Coder A [ Fri Aug 23, 2013 11:57 am ]
Post subject:  Re: Learning Color Sorter

And what happens if you either always hit correct or always hit incorrect? Have you tried those?


Does it get mad if all you ever hit is incorrect? :)

Author:  Coder A [ Fri Aug 23, 2013 11:58 am ]
Post subject:  Re: Learning Color Sorter

[ deleted comment due to accidental double post -Coder A]

Author:  NeXT-Generation [ Fri Aug 23, 2013 12:02 pm ]
Post subject:  Re: Learning Color Sorter

The universe implodes.

You can delete posts. There's a little 'x' in the bottom right corner of the post. It deletes it.
Actually, it'll just get the program stuck in an infinite, unsolvable loop.

Author:  Coder A [ Fri Aug 23, 2013 12:06 pm ]
Post subject:  Re: Learning Color Sorter

I don't see an "x." I do see an '!,' though. Haha! I love prooving things aren't fool(or jerk) proof! Computer bug exploitation should be a class in school!



Like in minecraft PE, which I have recently become addicted to, there is currently a bug that allows for infinite iron, gold, diamond, and quartz at the tap of a finger! So nice!

Author:  NeXT-Generation [ Fri Aug 23, 2013 12:51 pm ]
Post subject:  Re: Learning Color Sorter

Hmm. Maybe it's only available for a certain amount of time after you make the post.

Page 1 of 1 All times are UTC - 5 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/