Saturday, May 15, 2010

Learning NXC

In the past few weeks I got 2 Mindstorms NXT books, both of them great: LEGO Mindstorms NXT Power Programming: Robotics in C by John Hansen and David J.Perdue's The Unofficial LEGO MINDSTORMS NXT Inventor's Guide. I am right now reading both of them in an effort to learn more about building NXT robots and both NXT-G and NXC programming.

I just built and programmed the BumperBot with the second program from David's book (which you can find in the chapter 11-16 source code archive on this page; named Bumper-Bot2) and I decided to try to learn NXC by "translating" this program. I read a lot of John's book already but it is quite different to try to write something vs. just understanding the code in the book.

And I did it! The program I came up with is this (also on Google code here):
task main() {

     SetSensorTouch(S1);
     // wait for the bumper to be touched
     until(SENSOR_1);
     // play a tone
     PlayTone(330, MS_500);
     // and start moving: go in a straight line; motors are oriented
     // such a way that they need to go backwards for the robot to go forward
     while(true) {
          OnRevSync(OUT_BC, 75, 0);
          // interesting: without the following Wait the robot doesn't start moving!
          Wait(500);
          // bumper was touched
          until(SENSOR_1);
          PlayFile("! Sonar.rso");
          // go back one rotation (360 degrees)
          RotateMotorEx(OUT_BC, 75, 360, 0, true, false);
          int ending = 481, starting = 120;
          unsigned int degrees = Random(ending-starting)+starting; // 120..480 inclusive
          // turn around a random angle, between 120 and 480
          RotateMotorEx(OUT_BC, -75, degrees, -100, true, false);
     }
}

Nothing really special, you've more than likely seen more advanced NXC code on the web. But it's worth noticing a few things:
  • When I first set the Touch sensor, I used: SetSensor(S1, SENSOR_TOUCH). The weird thing though was that until(SENSOR_1) didn't work in this case; but as soon as I changed to SetSensorTouch(S1) the until statement started to work. I don't know why this was the case but I will definitely remember it next time.

    Update: Digging through the NXC API with the help of John Hansen's excellent NXC Programmer's Guide, I noticed a ResetSensor function. I gave it a try thinking that it may help with my original problem and it did. So, basically, to setup the touch sensor I was able to use the version above:
    SetSensorTouch(S1);

    but it also works like this:
    SetSensor(S1, SENSOR_TOUCH);
    ResetSensor(S1);

    I'm glad I discovered this since I haven't seen any example like it or notes about this behavior anywhere.
  • In the while block, if the Wait() statement is not present, the first robot move command doesn't do anything. I am not sure why this is the case but it was quite puzzling for a while, why the robot didn't move when the command was there.
  • Last thing: in the beginning, I followed the blocks in the NXT-G program to a "t" so the RotateMotorEx commands had the last argument set to true (to break the motors). But I noticed that the robot was moving more jerkily with the NXC program compared to the NXT-G one; so, I changed it to false (meaning Coast). I am still not sure why the difference, why Break in NXT-G seems to move the robot smoother than Break in NXC.
Like I said when I started this blog: these short articles are both for my benefit, to write down what I learned so I can remember it next time, and for you the reader's benefit, if you find anything useful here. This short exercise of rewriting an NXT-G program in NXC seemed a no brainer at the beginning but I definitely learned a few things while doing it.

No comments:

Post a Comment