LegoTM meets JavaTM : RoboJDE vs. LeJOS

by Jessica Sant

Introduction

I recently took a Robot Building Lab as part of my Master's degree program. The class was a mix of graduate and undergraduate Computer Science students. The majority of the course was taught using the HandyBoard controller programmed with a C derivative called IC4. Being the Java geek that I am, I was thrilled when my professor mentioned there was a Java product out there that you could use to program the HandyBoard. Enter RoboJDE. All the graduate students had an additional requirement to program an RCX robot using leJOS. This article is based on my experience of the two platforms. This is by no means a definitive comparison of the two platforms.

Every language has its purpose, and this may have not been the ideal application of Java due to the extremely limited memory on the platforms (~12k for the JVM, program, and the execution space), but trying to code java small was a very interesting (albeit sometimes frustrating) exercise. Plus, I always get a kick out of writing a program that "does something cool". And getting a robot to do stuff like following a flash light, avoiding obstacles it encounters, and determining where it is along a wall based on what it sees with its sonar definitely qualify as "cool".

Highlights

RoboJDE and leJOS both have strong aspects to their platform. Some highlights include: leJOS's built in RotationNavigator that performs both forward and inverse kinematics (basically knowing where it is on a 1' x 1' grid and the ability to go to a particular point on that grid); and RoboJDE's sensor interaction that better encapsulates the behavior of different sensors. Because both platforms are Java-based it is possible to create stand-alone programs in order to test the needed functionality off-line and without the use of the actual robot. Each of these aspects proved quite helpful in the respective labs.

Each platform has their issues... the main problem that sticks out for leJOS is its lack of Garbage Collection. The extremely limited memory is hard enough to deal with, and not having the ability to free the memory after its been allocated makes the situation more challenging for significant programs. RoboJDE has a very efficient built-in garbage collector. The main issue with RoboJDE is that its only available on the Windows platform, leJOS is available on both Windows and Linux.

Hardware comparison

The RCX—brain of the Robotics Invention System
The RCX controller. Source: O'ReillyNet.com The HandyBoard controller. Source: HandyBoard.com


I/O ports
The Lego Mindstorm RCX board has a limited number of input and output ports (three each). However the ability to overlap sensors allows the programmer to use more sensors than there are ports available. Overlapping sensors has the side effect that the readings from the sensors can be received but it is often impossible to differentiate between which overlapped sensor is sending the signal.

The HandyBoard had seven analog input ports, seven digital input ports and two digital input / output ports. The limited number of digital I/O ports became a problem during the 2nd half of the course because we needed to use two encoders (used with kinematics to determine where the robot is) and a sonar sensor. Each of these sensors required the use of an individual digital input/output port. The HandyBoard does not have the ability to overlap sensors, and so we were forced to use only one encoder along with the sonar sensor.
*Note: as a work around we could have written native code to allow one of the encoders to run on a pure input port, but this proved too difficult given the time constraints and my pathetic understanding of the Motorola M68HC11 assembly language.

LCD
The RCX board has a severely limited display. It allows only a total of 5 characters to be shown on the board whereas the HandyBoard can display a total of 32 characters (2 lines, 16 characters in length). The ability for the HandyBoard to display a more significant output significantly aids in the process of debugging.

Robot Interface
The Handyboard interfaces with the PC through the serial port, which connects to a standard phone line, which connects to the robot. So, if you'd like to get debug information sent back to the PC during the robot's run, it must remain "tethered" via the phone cord.

The RCX on the other hand uses a USB tower to send signals via IR (I believe the tower can also be connected to the PC via a serial port, but we didn't have the appropriate hardware in our kits). Whether it was due to the IR speed or the RCX loading software's speed, the RCX took a significantly longer amount of time to download programs to the robot than the HandyBoard software. The nice advantage about the built-in IR capabilities of the RCX robots is that it doesn't need to be tethered in order to send debug information back to the PC.

Software comparison

The Tools
RoboJDE is a commercial product that compiles code for the Handyboard. It has a more elegant user interface and cleaner out-of-the-box experience than the UI used with leJOS. RoboJDE runs only on windows, but the installation is much cleaner, requiring only the execution of a simple setup executable. The UI itself produces a significant amount of statistics about the user's program during compilation (program size, number of static variables, number of classes used, etc) and execution (free bytes available, free blocks available, % CPU used, % memory used). This information proved quite useful while coding and debugging the HandyBoard.

leJOS is an open-source product and thus has several available interfaces that can be used to compile and download programs. Bricxcc required several products to be installed as well as multiple environment variables to be set, and I was unable to configure it successfully. Instead, I used RCXDownload, which requires only that the JDK and the USB Tower driver be installed. It provides none of the helpful statistics provided by RoboJDE; it is simply a way to compile and download the leJOS programs.

The API
Both RoboJDE and leJOS are Java-based platforms, but they differ in the amount of the standard Java API they implement and how they interact with the Robot.

RoboJDE API:      http://www.ridgesoft.com/robojde/1.2/docs/apidoc/index.html
leJOS API:      http://lejos.sourceforge.net/apidocs/index.html

Robot Interaction
One of the significant comparisons that need to be made between RoboJDE and leJOS is how easily the two interact with and control the robot.

RoboJDE provides specialized classes to handle a select set of sensors. These classes encapsulate all the functionality of the particular sensor. For example, the conversion of a sonar reading into a distance (see Figure 1) is handled by the RangeFinder class. If necessary, this class can also be extended to support different brands of Range Finders other than the DevantechSRF04.

Instead of providing specialized classes that handle different sensors, leJOS provides a generic Sensor class which, when initialized with different "Type and Modes", will behave differently. These types can range anywhere from TOUCH to TEMP or LIGHT.

I find that RoboJDE's method of interacting with sensors is more intuitive and easier to implement than the one used by leJOS.

Figure 1: Example of leJOS and RoboJDE code to interact with sonar
leJOS
//initialize the sonar      
   Sensor.S2.setTypeAndMode (3, 0x80);       
   Sensor.S2.activate();
//read the raw value of the sonar      
   float value = Sensor.S2.readValue();
//manually convert sonar reading to distance in centimeters      
   float distance = (float)(12f+.53*a*2.54);
 
RoboJDE
//initialize the sonar     
   RangeFinder sonar = new DevantechSRF04(...);     
   float distance = 0.0f;
//send out a ping and read the value within 100 milliseconds     
   sonar.ping();    
   long timeout = System.currentTimeMillis() + 100;   
   do {
//RoboJDE automatically converts sensor reading to distance   
      result = sonar.getDistanceCentimeters();  
   } while ((result < 0.0f) && (System.currentTimeMillis() < timeout));

Both RoboJDE and leJOS have a similar method of interacting with the Motors (see Figure 2). With both API's, you set the power levels of the motors their directions.

Two very useful features that leJOS possesses that are lacking in RoboJDE are the methods Motor.X.isMoving() and Motor.X.flt(). These methods tell the program if the motor is currently being moved, and tells the motor to stop applying power to the motor, respectively. The .flt() command is different than stop in that it removes power, rather than bringing the motor to an abrupt stop.

Figure 2: Example of controlling motors in RoboJDE vs leJOS
leJOS
//Performs a left turn by moving the left motor (A) slowly     
    Motor.A.setPower(1);
    Motor.A.forward();  
//moving the right motor (C) quickly     
    Motor.C.setPower(7);
    Motor.C.forward();
//pausing     
    Thread.sleep (1000);
//stopping both motors     
    Motor.A.stop();     
    Motor.C.stop();	
 
RoboJDE
//initializes the motors     
    Motor leftMotor = HandyBoard.getMotor(0);    
    Motor rightMotor = HandyBoard.getMotor(1);
//performs the turn by moving the left motor slowly 
    leftMotor.setPower( Motor.FORWARD );
//moving the right motor quickly    
    rightMotor.setPower( Motor.FORWARD/10 );
//pausing    
    Thread.sleep(1000);
//stopping both motors     
    leftMotor.setPower( Motor.STOP );  
    rightMotor.setPower( Motor.STOP );


Kinematics
LeJOS makes kinematics almost a trivial task. LeJOS provides a class called RotationNavigator that uses two encoders to calculate the distance the robot has traveled, and in what direction. The RotationNavigator performs the desired move by using commands such as RotationNavigator.gotoPoint() (inverse kinematics). It also can calculate where the robot is currently located by using commands such as RotationNavigator.getX() and .getY() (hence forward kinematics).

When using RoboJDE, all of the functionality provided by a class such as RotationNavigator needed to be designed and coded. Granted, having to code this myself gave me a renewed appreciation for high school geometry as well as a better understanding of how the kinematics calculations were actually performed.

Bump detection
Due to the limited number of input ports available on the RCX, the two bump sensors were stacked on a single input port and it was not possible to determine if the bump occurred on the left or right side of the robot. So, when avoiding a bump the robot always attempted to avoid the obstacle by turning to the right. This caused a problem sometimes because the robot would take several tries to completely avoid an obstacle, which would in turn cause the robot to hit the obstacle more, and possibly collect more error in the calculation of its position.

Figure 3: RoboJDE vs leJOS in detecting a bump.
leJOS
Sensor.S2.setTypeAndMode (SensorConstants.SENSOR_TYPE_TOUCH,
    SensorConstants.SENSOR_MODE_BOOL);
if( Sensor.S2.readBooleanValue() ) {   
    // avoids obstacle
}
 
RoboJDE
DigitalInput leftBumper = HandyBoard.getDigitalInput(15);
DigitalInput leftBumper = HandyBoard.getDigitalInput(13);
if( leftBumper.isSet() && rightBumper.isSet() ) {
    //center hit avoid obstacle
} 
else if( leftBumper.isSet() && !rightBumper.isSet() ) {   
    // left hit avoid obstacle
} 
else if( !leftBumper.isSet() && rightBumper.isSet() ) {   
    // right hit, avoid obstacle
}


Debugging
Debugging the robot's program for logical errors is a much easier task in the HandyBoard due in large part to the RoboJDE UI as well as the large LCD on the HandyBoard. Error messages, variable values and other helpful debugging statements can easily be sent to the host machine (and simultaneously displayed on the LCD) by simply calling System.out.println(). As mentioned before, the RoboJDE interface that tracks the amount of memory and CPU used as well as program size etc is incredibly helpful when debugging.

This type of helpful debugging is much more involved with the Mindstorm. There is no simple way to print to the host, and the limited size of the LCD prevents much useful information from being displayed. We found that "debugging" is often reduced to adding different sounds to be played at various points in the program and trying to interpret these sounds to mean that the program has successfully reached a particular area in the code. *In all fairness to the RCX and leJOS, because it has an IR connection to the PC, you can send message through the IR in order to debug problems -- but I didn't realize this at the time I was programming it.

Garbage Collection
One significant advantage that RoboJDE has over leJOS is its automatic Garbage Collection. When an object or variable is no longer used it is removed and the memory is freed in order to be used by other variables. In leJOS the programmer must be diligent and not produce more objects than necessary because there is no way to reclaim memory once it is used. The lack of a Garbage Collector is a huge detriment due to the extremely small amount of memory on the RCX.

RoboJDE is also very efficient when it compiles your program. Any methods or classes not used will not be compiled and built into byte code for the HandyBoard. This also aids in significantly reducing the size of your program.

Other Stuff
One significant advantage that leJOS has over RoboJDE is that it has a Persistent memory area that can be used to store calibration values from one program execution to the next. This functionality would have proven useful during the first half of the course when we were constantly calibrating and recalibrating the light and reflection sensors. If we could have calibrated the robot once and stored these values in a Persistent memory area, we could have saved time from one run to the next.

Simulating the Robot
Due to Java's object oriented nature, it was easy to encapsulate much of the functionality of the labs as individual classes that were not dependent on the Robot code itself. This quality became very useful when writing and testing some of the major pieces of the labs.

For example, in one of the final labs a map of the world needed to be built and stored on the HandyBoard based on the Sensor inputs. We were able to hard-code a simulated set of sonar readings into a main class. These values were then manipulated and stored so that they could later be used to find an optimal path to the goal. The ability to do all of this off-line with the use of real debugging utilities such as those built into IntelliJ IDEA significantly reduced the number of logical errors present in the program once it was actually used by the Handyboard.

What I think

In the end, I found that using and debugging RoboJDE was easier than leJOS. The UI provided by RoboJDE made it easier to identify memory problems as well as logical errors, and as I mentioned before, I found the API a bit more intuitive to use as well.

All that being said, for the average robot geek (and particularly for the recreational robot geek), money is almost always an issue. LeJOS is a free open source product, and the Mindstorm itself costs about $200. The HandyBoard costs about $300, and RoboJDE is about $100 (there is a free Lite version available as well). So, for the casual geek, RoboJDE may not be the most cost-efficient path, but I believe for the academic arena, its certainly a strong choice.

Links