GRobot 01


A ~5 hours project with LEGo Mindstorm and NQC programing.

How it started

This is a 5 hours project with my son Gérémy (7 years old at the time) who showed interest in doing some robotic using our old LEGO Mindstorm by building an RC car1 and wanted to build the RCX line following robot described in the Mindstorm books. You can read that part of the story in this post.

I was of course happy to help and, building on this idea, I proposed to add an harm and a hand to pick objects around the track. Base on the diameter of his eyes and his jaw on the floor, it was safe to say that he liked the idea.

1 - Mobility base (0.5 hour)

Following the instructions, Gérémy had already build the generic wheeled base by patiently finding all the right parts in our sea of mixed LEGO bricks.

2 - Line Following (1 hour)

Again, following the Mindstorm design, Gérémy installed a light sensor in front of the robot and,
using NQC installed on an laptop running Ubuntu 12.04, we coded a very simple line following algorithm. To keep the complexity very low, the robot is only able to turn left.
For this part, I did all the actual coding but explained each lines to Gérémy.


3 - Stopping At Stations (1 hour)

To make the robot stop and then go again, we used our first variable (stopVar). This was the first 'advance' programming concept the Gérémy had to learn. The goal of this variable was to tell the robot to stop once when it find a black bar and then reset itself when white is found.
Again, I did all the typing by this time Gérémy remembered the principle and some of the methods names.


4 - Claw tests & design (1.5 hour)

This time we had to find how to run a motor forward and backward. We found the right commands in the NQC documentation and created a test program that would run the motor for one second forward and then one second backward.


This time Gérémy was at the keyboard and I show him the magic of Copy-Paste. Thanks to his online kids gaming practices, he was already at ease with manipulating the mouse and keyboard. Selecting test was a new skill though and it took him a bit to get the hang of that. It's a good thing that we were on a Notebook laptop because I'm not sure he could reach the Ctrl-C and Ctrl-V on a normal keyboard.
The claw physical design is 70% his. I helped with a couple of things and added the slip-gears to protect the motor from excess strain.


5 – Final assembly (1 hour)

We put everything together and ran it for the first time. Right away we saw that the claw was not reopening as planned and I fixed the code. It turns out that the On() command will run the motor in the last direction call by OnFwd() or OnRev().
And there it is. Gérémy's first robot including code.



On to the next project.



The code:


#define gColor_Follow  SENSOR_1
#define gColor_Stop  SENSOR_2
#define MOTOR_A  OUT_A
#define MOTOR_B  OUT_B
#define MOTOR_C  OUT_C

task main()
{
    On(MOTOR_A+MOTOR_C);
    int stopVar = 0;
    int clawVar = 0;

    //Open claw
    OnFwd(MOTOR_B);
    Wait(10);
    Off(MOTOR_B);

    SetSensor(gColor_Follow, SENSOR_LIGHT);
    SetSensorMode(gColor_Follow, SENSOR_MODE_RAW);

    SetSensor(gColor_Stop, SENSOR_LIGHT);
    SetSensorMode(gColor_Stop, SENSOR_MODE_RAW);

    while(true){
        if(gColor_Stop > 750 && stopVar == 0){ //Stop
            stopVar = 1;
            Off(MOTOR_A+MOTOR_C);
               
            if(clawVar == 0){
                //close claw
                OnRev(MOTOR_B);
                Wait(10);
                Off(MOTOR_B);
                clawVar = 1;
            }else{
                //Open claw
                OnFwd(MOTOR_B);
                Wait(10);
                Off(MOTOR_B);
                clawVar = 0;
            }

            //Wait with sound
            PlaySound(2);
            Wait(200);
            PlaySound(1);
            Wait(20);

            On(MOTOR_A+MOTOR_C);               \
        } else if(gColor_Follow > 750){// Forward
            On(MOTOR_A+MOTOR_C);
        } else {// Turn left
            Off(MOTOR_A);
        }

        if(gColor_Stop < 750) { // Reset after stop
            stopVar = 0;
        }

        Wait(10);
    }
}