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.