Monday, April 29, 2013

Change default path for Lego Mindstorms NXT

Every time I open the Mindstorms software the default path points to the home folder of a user that doesn't even exist on my laptop (I assume this is because I installed the software a while back when this user existed but in the meantime I deleted it) so each time I want to save a new program I have to browse to the real path. I looked around and found these directions about how to change it: all I had to do is edit the 'settings.ini' file in "C:\documents and settings\%username%\My Documents\Lego Creations\Mindstorms Projects\Profiles\Default\" and change the "Data Directory=" to the path where I want the files to be saved. Simple but very useful, especially if you are on a network as it is the case in the page I referred to.

Thursday, July 1, 2010

Getting git

My plan is to host all my NXT projects using Google Code and SVN. However, a few days ago I discovered github and git and it sounded really cool. Last night I tried to see how it works so I created a local git repository for some code that is going to be used with my Arduino (the app itself is hosted with Google App Engine which is free for the volume of code and traffic I have).

Because I want to be able to share the project between a couple of computers on different networks, I looked for a server where I can create a central repository - yes, I know, the strength and beauty of git is the fact that there is no need for this but I tried anyway. I discovered gitorious so I created a project there and pushed a portion of my local project to it - I don't want the entire project, because it contains Eclipse files and library jars that get created/installed when I create the project on a different computer.

From the other computer I tried to clone this repository (using git clone) but because the destination directory already existed I had troubles doing this. I kept digging for info about how to do this but couldn't find any (I'm sure it's out there and it was only my fault for not finding it). Finally, I got an idea: if git init creates a repository and git pull gets the code, why not try it this way. And it worked.

So, for my future projects that will be in this situation where I want to souorce control only a few files, what I need to do when moving to a new computer is:
  • create the new project
  • start git and cd to the project dir
  • instead of git clone do: git init
  • followed by: git pull git@gitorious.org:<project>/<repository.git>
Like I said, I am sure this info is out there somewhere but I couldn't find it so I am posting it here for future reference. When reading/learning about git, I found a lot of info on different website but there are a couple resources I want to mention in particular:

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.

Tuesday, April 20, 2010

MindSqualls rocks! NXTasy.org does, too!

Now that I decided on using MindSqualls, let's get coding. First stumble block was the MessageRead() method takes as a second argument the local mailbox. What is the local mailbox? I decided to ask in the NXTasy forum and John Hansen promptly replied saying that the local mailbox should be ignored because there isn't one. He also mentioned something else that at the time I didn't understand:
The call to SendResponseString will simply write the value of out (S1, S2, etc...) to the outbound or response mailbox numbered 11. Response mailboxes have numbers equal to the specified mailbox number plus 10. You actually have to pass the response mailbox number (i.e., 10..19) rather than the "regular" mailbox number (0..9), unless Mindsquals is doing something weird and adding 10 to the number you pass in (which it should not do).
On the NXT side I stuck with the code I mentioned in my previous post (page 43 of Daniele Benedettelli's tutorial at bricxcc site):

//SLAVE
#define BT_CONN 1
#define INBOX 5
#define OUTBOX 1

task main(){
  string in, out, iStr;
  int i = 0;
  while(true){
    iStr = NumToStr(i);
    out = StrCat("S",iStr);
    ReceiveRemoteString(INBOX, true, in);
    SendResponseString(OUTBOX,out);
    TextOut(10,LCD_LINE3,in);
    TextOut(10,LCD_LINE5,out);
    Wait(100);
    i++;
  }
}

On the PC side I wrote something really simple (please note that I am using this code only as a rough example, it is by no means 100% functional, large sections were left out):
using NKH.MindSqualls;

namespace BTMasterMessage
{
    public partial class Form1 : Form
    {
        ............................
        private void GetMessage()
        {
            byte comPort = byte.Parse(this.txtComPort.Text);
            NxtCommunicationProtocol comm = new NxtBluetoothConnection(comPort);
            comm.Connect();
            string msg = comm.MessageRead(NxtMailbox2.Box1, NxtMailbox.Box0, true);
            this.Text = msg;
        }
    }
}

Well, nothing worked, there was no message displayed PC side. Then I read more closely what John mentioned in his answer and I decided to change the first argument of MessageRead from Box1 to Box11:
string msg = comm.MessageRead(NxtMailbox2.Box11, NxtMailbox.Box0, true);

It was a magical moment when I ran the program and I got an "S173" or something like it on my screen. It was so awesome!

The conclusion: MindSqualls rocks and the helpful and friendly people in the NXTasy forum do as well! Big thanks to both teams!

Monday, April 19, 2010

Starting with Bluetooth

Now that I am able to connect to my NXT via Bluetooth is time to try to communicate with it. I don't have 2 NXT's so what I focused on was communicating between a PC and the NXT brick. Since I know Java, I looked for a Java library that was able to accomplish this. iCommand is a sub-project of leJOS and it was the first thing I tried. I downloaded iCommand 0.7 and tried to make the sample programs work. To my surprise, the bluecove jar mentioned in the docs was missing but I was able to find it in an older version: 0.6. I asked on the leJOS forum why is this and was told that iCommand is not supported anymore.

Anyway, after I installed the missing jar and I set the classpath, I was able to run most of the sample programs that came with it with great results. It was a real breakthrough and I was very happy! However, none of the samples were showing how to send a message to the NXT and receive some message back. After quite a lot of digging, I found out there are 2 ways of communicating with the NXT: one is Direct Commands (basically, your code on the PC sends a command to the NXT that is interpreted directly by the firmware), the other is sending/receiving messages to/from specific mailboxes (sometimes named queues in some libraries I found). To test the communication, I got a very simple NXC program from Daniele Benedettelli's tutorial at bricxcc site (page 43) that is supposed to receive a message from another NXT and send a response message back.

Because I was able to use iCommand successfully, I figured next step was to use it to send a message to the NXT. Unfortunately, it didn't work. Later I found out in the leJOS forum what I already mentioned: that iCommand is not supported anymore. Indeed, looking in the source code for NXTCommand class that is supposed to handle the communication, messageRead and messageWrite are marked UNTESTED. It looks to me that they should work but they didn't and without being able to get some help, I moved on.

Next try: use the newer code in the leJOS project. I installed it and tried some sample code that I found, again without any success. A response to my question in the leJOS forum revealed that leJOS uses streams to talk to the NXT and not mailboxes. The solution is to install the leJOS firmware on the NXT and use streams. This didn't sound too bad but I didn't want to get too deep in proprietary firmware and communication stuff so I abandoned the idea.

Looking around I found several libraries that seemed able to use mailboxes, a comprehensive list is here on Team Hassenplug's site. I decided that if Java didn't work, maybe I should try C# (which I don't know but it is close to Java as far as I know) so I decided to try MindSqualls (another alternative seems to be NXT# but the website was down every time I tried).

So, it is MindSqualls' turn. But about this, in a later post.

A great book and a solution to my Bluetooth problem

A few weeks ago I've seen in a local bookstore Daniele Benedettelli's Creating Cool MINDSTORMS NXT Robots book and I loved it from the moment I opened it. I purchased a copy and started reading it and immediately I was very happy with it: the way theory aspects are presented and explained, the building instructions, the code, everything is really accessible.

One thing I am really grateful for are the steps for connecting the NXT brick to the PC via Bluetooth. I tried to do this before following the steps in the Mindstorms docs (initiating the connection from the brick) and even if the NXT connected fine with the PC, the Mindstorms software could not see it. I gave up thinking the BT driver on my computer is somehow unable to connect properly. After following the steps in the Appendix in this book (and initiated the connection from the BT device manager on the PC) I was able to connect not only the Bricxx IDE but also the Mindstorms software. This is a huge breakthrough - no more wires that need to be connected to load the program and disconnected later to run it. Just this simple aspect makes purchasing this book great, at least for me!

Those of you that don't have this book but have problems connecting via Bluetooth can find help in John Hansen's article on nxtasy.org