The Source for Java Technology Collaboration
User: Password:



   

Robotics: Using Lego Mindstorms and Java Robotics: Using Lego Mindstorms and Java

by Krishnan Viswanath
02/21/2005

Contents
Inside LEGO Mindstorms
Getting and Setting up leJOS
LeJOS API
   Motor
   Sensor
   Buttons
   Communication
Peek Under the Hood
Test Drive
Conclusion
Resources

In the past, robotics and related research was pretty much limited to serious hobbyists or to those working at big corporations, research institutions, and universities. The introduction of affordable Robotics Invention System by LEGO Mindstorms has helped make the art and science of robotics available to every one. The LEGO Robotics Invention Kit has all the necessary LEGO components to design, build and program a fully functional robot in very little time requiring very little prior experience. In this article we will explore the brain of LEGO Mindstorms that will enable us to program the robot to perform the functions we intend to. You will look at installing and using the Java-based leJOS firmware.

Inside LEGO Mindstorms

The brain of the LEGO Mindstorms is the programmable microcontroller brick, called RCX. The RCX evolved from MIT's programmable brick, which was originally developed so that a developer could design and build small mobile devices that work independently without requiring a physical connection to a host machine. Programs are created on a host computer and downloaded to the brick, either through an infrared link or through a wired connection. Once the program is downloaded into the brick, the mobile device can start functioning independently from the host machine.

The RCX is the programmable brick that was designed and developed by LEGO. At the core of the RCX brick is a Hitachi H8 3297 microcontroller that has 32K of external RAM. There is also an on-the-chip 16K ROM that has the drivers that run when the RCX is turned on for the first time. The 32K of RAM is logically divided into sections: 16K for the firmware, 6K for storing user programs, and 10K for interpreting the byte code and handling the program execution. The RCX can be programmed to simultaneously control up to three motors, three sensors, and an infrared communication device.

The RCX is programmed using the legOS-supplied GUI utility tool, which abstracts the details of the programming semantics and provides an intuitive user interface, where the user can drag and drop to assemble components to generate the program. The program that is generated can then be downloaded into the firmware using the infrared tower. The default firmware, however, can be replaced with a variety of alternate firmware, driven by the choice of programming languages. In our case, we will be replacing the original firmware with the Java-based leJOS firmware that will enable us to develop the user programs in Java.

Getting and Setting up leJOS

Firmware is the operating system that runs inside of the RCX brick, which is responsible for executing the user programs. A brand new RCX does not come with a firmware pre-installed; the LEGO Mindstorms Robotics Invention System kit includes a CD-ROM that contains the LEGO Firmware. The user has to download appropriate firmware into the RCX. As far as the firmware that supports the Java programming model goes, there are two choices available: leJOS and TinyVM. Both of these projects are open source and are hosted on SourceForge.net. In this article, we will primarily look at leJOS, with occasional reference to the TinyVM project. The leJOS firmware has a virtual machine for interpreting the Java bytecode, as well as additional software resources to load and run Java programs.

To set up leJOS, first obtain the leJOS binaries from www.lejos.org. The binary is distributed in .zip format. After extracting the contents of the .zip file to the local file system, the next step is setting up the environment variables. The environment variables that need to be set up are:

  • Setting LEJOS_HOME to the directory where leJOS was extracted:
    • SET LEGOS_HOME=<Directory where leJOS .zip was extracted>
  • Setting the CLASSPATH environment variable to include leJOS classes:
    • SET CLASSPATH=.;%CLASSPATH%;%LEGOS_HOME%\lib\classes.jar;% LEGOS_HOME\lib\ pcrcxcomm.jar
  • Setting the PATH environment variable to include the leJOS bin directory:
    • SET PATH=%PATH%;%LEGOS_HOME%\bin;
  • Setting the RCXTTY environment variable to the tower device communication mechanism:
    • SET RCXTTY=USB (if communication is via USB) or SET RCXTTY=COM1 (for communication via the serial port)

Once the environment variables are set up, the leJOS firmware can be uploaded into the RCX brick. This is accomplished by executing the MSDOS batch file firmdl.bat, which is provided along with the distribution. Essentially, this batch file transfers the JVM image file lejos.srec for the RCX, which is supplied in the LEGOS_HOME/bin directory of the distribution. This firmware file is in Motorola's "S Record" format. Of course, the RCX should be turned on and aligned properly with the tower for successful transfer of the firmware to the RCX. When this command returns without error, the leJOS firmware has been downloaded into the RCX. During the download process, the counter in the LCD window of the RCX is incremented until it reaches 1662. Each unit indicates that 10 bytes of data has been downloaded into the RCX; the total size of the firmware is 16624 bytes. The RCX device will beep twice when the download completes successfully. The display in the LCD screen of the RCX will now refresh to show the voltage level and the number 0.

Figure 1
Figure 1.

If the user wants the RCX to go back to its original state, the leJOS firmware can be deleted simply by removing the batteries from the RCX brick for about 30 seconds. Consequently, when the battery is removed, the leJOS firmware will be completely removed, along with any user programs. The following image indicates the RCX and tower setup during the leJOS download process.

Figure 2
Figure 2.

The next step in the process is to test drive the robot by writing an application. The code can be written using any standard Java IDE or your favorite text editor. Once the code is written, it needs to be compiled using the batch file lejosjc.bat provided with the leJOS distribution. All that this batch files does is compile the source with 1.1 as target by passing the target option to the VM. This will not work with JDK version 5.0 (and above). The output from the compiler, the standard Java byte code, then becomes input for lejoslink.bat, which produces a binary file for download. The linker's main function is to figure out all of the byte code that the program requires and then bundle it up. The operating mechanism here is different than it is for regular Java applications, where the virtual machine loads up the classes in a lazy manner. In the RCX world, once the program is downloaded, the RCX does not establish a connection to the host to request more byte codes at runtime. The last step in the process is to download the binary file produced from the linker into the RCX using the supplied MSDOS .bat file lejosdl.bat.

LeJOS API

In order to get a concrete understanding of a technology, it's imperative that we dive into writing code and then see for ourselves how it works. However, before we do that, let's take a look the core leJOS API that covers various programming semantics dealing with RCX, such as navigation, sensors, communication, vision, and speech.

Motor

The LEGO motor is represented by josx.platform.rcx.Motor class and has methods that provide important mechanisms to control the robot. This class has three static member variables that logically represent the three black motor output connectors in the RCX brick, labelled A, B, and C. The motor class has a few control methods, including forward(), backward(), and stop(). Invoking these results in the motor performing the operations; moving forward and backward, and stopping. The other important method is flt(). This will let the motor float free and is especially useful when the robot is navigating a sharp curve. The other important method that will enable the developer to set and get the power level of the motor is setPower(int). This method takes an integer number between 0 and 7 as parameter. Here, 7 represents the highest power level and 0 the lowest. getPower() returns the current power level as an integer.

Sensor

The LEGO sensor is represented by the josx.platform.rcx.Sensor class and has methods to read the sensor's values. This class has three static member variables that logically represent the three gray output connectors in the RCX brick named 1, 2, and 3. Before the sensor can be used, the mode and type of the sensor needs to be set using the method setTypeAndMode(). The josx.platform.rcx.SensorConstants interface provides constants that provide the type and mode for the sensor.

Use sensors in conjunction with josx.platform.rcx.SensorListener to provide an event-based mechanism that reacts, based on sensor events. The stateChanged() method of the object that has registered with the sensor object will be notified when the state of the sensor changes. For example, the following inner class deals with handling an event generated by a touch sensor.


   Sensor.S1.setTypeAndMode (SensorConstants.SENSOR_TYPE_TOUCH, 
                                     SensorConstants.SENSOR_MODE_BOOL);
   Sensor.S1.addSensorListener (new SensorListener() {
    public void stateChanged (Sensor src, int oldValue, int newValue) {
       boolean flag = src.readBooleanValue();
       if ( flag) {
	// do some thing important here!!! 
       }
     }
   });
Buttons

There are four rubber buttons on top of the RCX brick. The red button is for powering the RCX brick on and off, and leJOS doesn't provide any API abstraction for this button. leJOS provides three constants that defines the other three button on the RCX. Button.VIEW defines the black "view" button, Button.PRGM defines the gray "Prgm" button, and Button.RUN defines the green "Run" button. Buttons, like sensors, fire events when the button is pressed or released. The listener object registered with a button defines two callback methods, buttonPressed() and buttonReleased(), where appropriate handling logic can be defined.

Communication

The leJOS comes with rich communication APIs. Using the API, it's possible to achieve communication from the RCX to the host PC, from RCX to RCX, and from the remote control to the RCX. The leJOS communication API can be found in the java.io, josx.rcxcomm, and josx.rcxcomm.remotecontrol packages. The communication classes use streams to send and receive data. The leJOS has most of the basic streams, such as InputStream, OutputStream, DataInputStream, and DataOutputStream. However, some of the functionalities that are available with streams in the core JDK are not available here due to memory restrictions. Additionally, the leJOS does not provide support for object streams and serialization.

The data transfer between the RCX and the host PC is possible through either the serial tower or USB tower in the Windows environment. In other environments, such as Linux or Mac OS X, only the serial mechanism is currently supported. There are four different port implementations that can be used to address communication between the RCX and host PC.

  • RCXPort: This class supports reliable streams using low-level communication. This makes use of native methods to read and write bytes to and from the IR tower. It ensures that all packets get through. Communication will stop when the IR tower is not in view or in range, and will resume when it comes back into view.
  • RCXF7Port: This is an interface similar to java.net.Socket and supports not-so reliable streams using the F7 LEGO firmware opcode. This class uses serial communication and not low-level communication.
  • RCXLNPPort: This is an interface similar to java.net.Socket and uses the legOS Networking Protocol (LNP). This version of RCXPort uses the Integrity Layer of LNP. This ensures that packets are not corrupted, but does not ensure that they get through. Packets can get lost.
  • RCXLNPAddrPort: This is an interface similar to java.net.Socket and supports point-to-point connections using the LNP Addressing protocol layer. The LNP Integrity layer is used to ensure that packets are not corrupted, but they are not guaranteed to get through. Packets can get lost.

Pages: 1, 2

Next Page » 

View all java.net Articles.

 Feed java.net RSS Feeds