Wednesday, May 26, 2010

Learning NXC - part 2

This idea to try to rewrite NXT-G programs from David J.Perdue's The Unofficial LEGO MINDSTORMS NXT Inventor's Guide using NXC really helps me learn. I just did this for the ClawBot1 program (which you can find in the chapter 11-16 source code archive on this page) and it was a lot faster than my initial try for the BumperBot. The code is on Google code here.

Nothing fancy, just 3 things I want to mention so I don't forget:
  1. When I first started to write the code, repeat(3) didn't work for some reason. I changed to repeat(repeatTimes) where repeatTimes = 3 and it started to work. Later when the program was done, I changed back to repeat(3) and this time it worked great. So, I guess the initial problem was just a fluke.
  2. The equivalent of NXT-G's "Wait for completion" when playing a sound file is this:
    until (SoundFlags() == SOUND_FLAGS_IDLE);
    I found this in John Hansen's LEGO Mindstorms NXT Power Programming: Robotics in C book and it is a great find: thanks, John!
  3. From a learning point of view, is really cool to try to match an existing program to the dot. I wrote code for the US Sensor before and never really bothered with exact distances, it worked pretty well using values like 20 or 35 (I knew that it returns values between 0 and 255) but I really had no idea what these numbers represent. Since the original program looked for 11 inches I had to dig a bit (in the forums at nxtasy.org) and found out that 0 to 255 are centimeters; knowing this it was easy to obtain the distance in inches. This is not a big deal but I just learned something more.
Update: I just finished the NXC version of ClawBot2 program in 2 versions: everything in main() and using a function (I noticed that some of the actions were common with only a couple of differences so I tried to use a function with 2 arguments and it worked great).

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.