<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
               "http://docbook.org/xml/4.2/docbookx.dtd"
	       [
	       <!ENTITY copyright SYSTEM "copyright.xml">
	       ]>

<chapter title="Lego MindStorms" id="17">
<title id="Lego MindStorms"> Lego MindStorms </title>

<tocchap>
<title>
Contents
</title>
<toclevel1>


<tocentry>
  <ulink url="#Making Hardware into Jini Services">
    Making Hardware into Jini Services
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#MindStorms">
    MindStorms
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#MindStorms as a Jini Service">
    MindStorms as a Jini Service
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#RCXPort">
    RCXPort
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#RCX Programs">
    RCX Programs
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#Jini classes">
    Jini classes
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#Entry objects for a robot">
    Entry objects for a robot
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#A client-side RCX class">
    A client-side RCX class
  </ulink>
</tocentry>
<tocentry>
  <ulink url="#Higher level mechanisms: Not Quite C">
    Higher level mechanisms: Not Quite C
  </ulink>
</tocentry>

</toclevel1>
</tocchap>

<abstract>
Lego MindStorms is a ``Robotics Invention System'' that allows you
to build Lego toys with a programmable computer. This chapter looks
at the issues in interfacing with a specialised hardware device,
using MindStorms as example
</abstract>

<sect1>
<title id="Making Hardware into Jini Services">
Making Hardware into Jini Services
</title>
<para>
Hardware devices and pre-existing software applications 
can equally be turned into Jini services.
A ``legacy'' piece of software can have a ``wrapper'' placed around
and this wrapper acts as a Jini service. Remote method calls into this
service can then make calls into the application.
Hardware devices are a little more complex
because they are defined at a lower level, and often have resource constraints
that do not apply to software.
</para>

<para>
There are two major categories of hardware service: those that can run a
Java Virtual Machine and those that do not have enough memory or an adequate
processor. For example, an 8086 with 20-bit addressing and only 1M of addressable
memory would not be an adequate processor, while the owner of a Palm Pilot might
not wish to squander too many of its limited resources running a JVM. 
Devices capable of running a
JVM may be further subdivided into those that are capable of running a
standard JDK 1.2 JVM and core libraries and those that have to run some
stripped-down version. At the time of writing, the lightweight JVM under
development by Sun MicroSystems called KVM does not support features
of JDK 1.2 required to run Jini.
</para>

<para>
Jini does not require all of the core Java classes to run a service.
For example, for a service to engage in discovery and registration
does not require the AWT. However, it does require support for the
newer RMI features found in JDK 1.2, and it does require enough
of the standard language features. Again, this is not inclusive of
all parts of Java: for example, floating point numbers are not
required. While many of the current embedded or small JVM's have
removed features and standard core libraries, at present none of
them have enough support for JDK 1.2 features too run Jini.
</para>

<para>
Anything above this level
will be more flexible, upto the level of a full JDK 1.2 with Jini.
Whatever, one is looking at a device with 8M of RAM or more, with 
networking capabilities, on a 32-bit processor.
</para>

<para>
If the device cannot run a JVM, then something else must run the JVM and
act as a proxy for the device. Your blender is unlikely to have 32M RAM,
but your home control center (possibly located on the front of the fridge)
may have this capability. In that case the blender service would be located
in this JVM, and the fridge would have some means of sending commands to the
blender.
</para>
</sect1>


<sect1>
<title id="MindStorms">
MindStorms
</title>

<para>
Lego MindStorms 
<ulink url="http://www.legomindstorms.com"> (http://www.legomindstorms.com)
</ulink>
is a ``Robotics Invention System'' which consists
of a number of Lego parts and a microcomputer called the RCX,
plus an infra-red transmitter (connected to the serial port of an
ordinary computer) and various sensors and motors.
Using this, one can build an almost indefinite variety of Lego robots
that can be controlled by the RCX. This computer can be sent
``immediate'' commands, or can have a (small) program downloaded and
then run.
</para>

<para>
MindStorms is a pretty cool system, that can be driven at a number of levels.
A primary audience for programming this is children, and there is a
visual programming environment to help in this. This visual environment
only runs on Windows or Macintosh machines which are connected
to the RCX by their serial port and the infrared transmitter. 
Behind this environment is a Visual
Basic set of procedures captured in an OCX, 
and behind <em>that</em> is the machine  code of the RCX which can be
sent as byte codes on the serial port.
</para>

<para>
The RCX computer is completely incapable of running Jini. It is a 16-bit
processor with a mere 32k of RAM, and the default firmware will only allow
32 variables. It can only be driven by a service running on, say, an
ordinary PC.
</para>
</sect1>

<sect1>
<title id="MindStorms as a Jini Service">
MindStorms as a Jini Service
</title>

<para>
A MindStorms robot can be programmed and run from an infrared transmitter
attached to the serial port of a computer. There is no security or real
location for the RCX: it will accept commands from any 
transmitter in range. We will assume a ``home'' computer  for it.
</para>

<para>
There must be a way of communicating with this device. For a MindStorms
robot this is by the serial port, but other devices may have different
mechanisms. Communication may be by Java code or by native code.
Even if Java code is used, at some stage it must drop down to the
native code level in order to communicate with the device - the only
question is whether you write the native code or someone else
does it for you and wraps it up in Java object methods.
</para>

<para>
For the serial port, Sun has an extension package - the <code>commAPI</code> -
to talk to serial and parallel ports
<ulink url="http://java.sun.com/products/javacomm/index.html">
(http://java.sun.com/products/javacomm/index.html)
</ulink>. 
This gives platform-independent Java code, and also platform
specific native code libraries supplied as DLL's for Windows and Solaris. 
I am running Linux on
my laptop, so I need a Linux version of the DLL.
This has been made by Trent Jarvi (trentjarvi@yahoo.com), and can be found at
<ulink url="http://www.frii.com/~jarvi/rxtx/">
http://www.frii.com/~jarvi/rxtx/</ulink>.
The native code part of communicating to the device has been done for us,
and it is all wrapped up in a set of portable Java classes.
</para>

<para>
The RCX expects particular message formats, such as starting 
with standard headers. A Java package to make this easier is available
by Dario Laverde at
<ulink url="http://www.escape.com/~dario/java/rcx">
http://www.escape.com/~dario/java/rcx</ulink>.
There are other packages that will do the same thing: see the 
``Lego Mindstorms Internals'' page by Russell Nelson at
<ulink url="http://www.crynwr.com/lego-robotics/">
http://www.crynwr.com/lego-robotics/</ulink>.
</para>

<para>
With this as background, we can look at how to make an RCX into a
Jini service. It will involve being able to construct an RCX program
on a client and send this back to the server where it can be sent
on to the RCX via the serial port. This will then allow a client
to control a Mindstorms robot remotely. Actually, the Jini part is
pretty easy - the hard part was tracking down all the bits and pieces
needed to drive the RCX from Java. With your own lumps of hardware,
the hard part will be writing the JNI and Java code to drive it.
</para>
</sect1>

<sect1>
<title id="RCXPort">RCXPort</title>

<para>
Version 1.1 of the package by Dario Laverde 
defines various classes, of which the
most important is <code>RCXPort</code>:
<programlisting>
package rcx;

public class RCXPort {
    public RCXPort(String port);
    public void addRCXListener(RCXListener rl);
    public boolean open();
    public void close();
    public boolean isOpen();
    public OutputStream getOutputStream();
    public InputStream getInputStream();
    public synchronized boolean write(byte[] bArray);
    public String getLastError();
}
</programlisting>
The class <code>RCXOpcode</code> has a useful method for creating
byte code
<programlisting>
package rcx;

public class RCXOpcode {
    public static byte[] parseString(String str);
}
</programlisting>
(There are minor changes from version 1.0 of this package.)
</para>

<para>
We may not need all of these in this project, but never mind -
we can just ignore the ones we don't want. The ones we do want are
<orderedlist>
<listitem>
  The constructor <code>RCXPort()</code>. This takes the name of
  a port as parameter, and this should be something like
  <code>COM1</code> for Windows and <code>/dev/ttyS0</code> for Linux.
</listitem>
<listitem>
  The method <code>write()</code> is used to send an array of opcodes
  and their arguments to the RCX. This is <emphasis>machine code</emphasis>
  and you can only read it by a dis-assembler or a Unix tool like
  octal dump (<code>od -t xC</code>).
</listitem>
<listitem>
  The <emphasis>static</emphasis> method <code>parseString()</code>
  of <code>RCXOpcode</code>
  can be used to translate a string of instructions in readable form
  to an array of byte for sending to the RCX. It isn't as good as an
  assembler, as you have to give strings such as <code>"21 81"</code>
  to start the A motor. To use this for Jini, we will have to use
  a non-static method in our interface since static methods are not
  allowed.
</listitem>
<listitem>
  To handle responses from the RCX, a listener may be added by
  <code>addRCXListener()</code>. The listener must implement the
  interface
  <programlisting>
<?program "/usr/local/src/rcx/RCXListener.java" ?>
  </programlisting>
</listitem>

</orderedlist>
</para>

</sect1>

<sect1>
<title id="RCX Programs">
RCX Programs
</title>
<para>
At the lowest level, the RCX is controlled by machine-code programs
sent via the infrared link. It will respond to these by stopping and
starting motors, changing speed, etc. As it completes commands or
receives information from sensors, it can send replies back to the
host computer. The RCX can handle instructions sent directly, or have
a program downloaded into firmware and run from there.
</para>

<para>
Kekoa Proudfoot has produced a list of the opcodes understood by the
RCX which is available at 
<ulink url="http://graphics.stanford.edu/~kekoa/rcx/">
http://graphics.stanford.edu/~kekoa/rcx</ulink>.
Using these and the <code>rcx</code> package from Dario Laverde 
means we can control the RCX from the ``home'' computer by 
standalone programs such as
<programlisting>
<?program "standalone/TestRCX.java" ?>
</programlisting>
</para>

</sect1>

<sect1>
<title id="Jini classes">Jini classes</title>

<para>
A simple Jini service can use an RMI proxy, where the service just
remains in the server and the client makes remote method calls on it.
The service will hold an <code>RCXPort</code> and will feed the
messages through it.
This means constructing the hierarchy of classes of figure <xref linkend="rcx_classes"/>.
<figure id="rcx_classes">
<graphic fileref="images/rcx_classes.gif" align="center"> </graphic>
<title>Class diagram for MindStorms with RMI proxies</title>
</figure>
<br /> Figure 1: Jini classes for RCX
</para>

<para>
The <code>RCXPortInterface</code> just defines the methods we shall
be making available from the Jini service. It doesn't have to follow
the <code>RCXPort</code> methods completely, because these will be wrapped
up in implementation classes such as <code>RCXPortImpl</code>.
The interface is defined as
<programlisting>
<?program "rcx/jini/RCXPortInterface.java" ?>
</programlisting>
We have chosen to make it a sub-package of the <code>rcx</code> package
to make its role clearer. Note that it has no static methods, but makes
<code>parseString()</code> into an ordinary instance method. 
</para>

<para>
This interface contains two types of methods: those used to prepare and
send messages to the RCX (<code>write()</code> and <code>parseString()</code>),
and those for handling messages sent from the RCX (<code>addListener()</code>,
<code>getMessage()</code> and <code>getError()</code>). Adding a listener
means that it will be informed of events generated by implementations of this
interface by having the listener's <code>notify()</code> method called.
However, a <code>RemoteEvent</code> does not contain detailed information
about what has happened, only an event type (<code>MESSAGE_EVENT</code> or
<code>ERROR_EVENT</code>). It is up to the listener to make queries back into
the object to discover what the event meant, which it does by 
<code>getMessage()</code> and <code>getError()</code>.
</para>

<para>
The interface <code>RemoteRCXPort</code> adds the <code>Remote</code>
interface as before
<programlisting>
<?program "rcx/jini/RemoteRCXPort.java" ?>
</programlisting>
</para>

<para>
The <code>RCXPortImpl</code> constructs its own <code>RCXPort</code>
object and feeds methods through to it, such as <code>write()</code>.
Since it extends <code>UnicastRemoteObject</code> it also adds exceptions
to each method, which cannot be done to the original <code>RCXPort</code>
class. In addition, it picks up the value of the port name from the
<code>port</code> property. (This follows the example of the
<code>RCXLoader</code> in the <code>rcx</code> package which gives a
GUI interface to driving the RCX.) It looks for this property in a file
<code>parameters.txt</code> which should have lines such as
<programlisting>
    port=/dev/ttyS0
</programlisting>
Note that the parameters file exists of course on the server side -
no client would know this information!
</para>

<para>
The <code>RCXPortImpl</code> also acts as a listener for ``ordinary'' RCX
events signalling messages from the RCX. It uses the callback methods
<code>receivedMessage()</code> and <code>receivedError()</code> to create
a new <code>RemoteEvent</code> object and send it to the implementation's
listener object (if any) by calling its <code>notify()</code> method.
</para>

<para>
The implementation looks like
<programlisting>
<?program "rcx/jini/RCXPortImpl.java" ?>
</programlisting>
</para>

</sect1>

<sect1>
<title id="Getting it running">Getting it running</title>

<para>
To make use of these classes, we need to provide a server to get
the service put onto the network, and some clients to make use of the
service. This section will just look at a simple way of doing this,
and later sections will try to put in more structure.
</para>

<para>
A simple server follows earlier servers using RMI proxies,
just substituting <code>RCXPort</code>
for <code>FileClassifier</code>, and using a <code>JoinManager</code>.
It creates an <code>RCXPortImpl</code> object and registers it (rather,
the RMI proxy) with lookup services:
<programlisting>
<?program "rcx/jini/RCXServer.java" ?>
</programlisting>
Why is it simplistic <emphasis>as a service</emphasis>? 
Well,  it doesn't contain any
information to allow a client to distinguish one Lego Mindstorms robot
from another, so that if there are many robots on the network then a
client could ask the wrong one to do things!
</para>

<para>
An equally simplistic client to make the RCX do a few actions is given below.
In addition to sending a set of commands to the RCX, it must also listen
for replies from the RCX. We separate out this listener as an
<code>EventHandler</code> for readability. The listener will act as a remote
event listener, with its <code>notify()</code> method called from the server.
This can be done by letting it run an RMI stub on the server, so we subclass
it from <code>UnicastRemoteObject</code>.

<para>
This particular client is designed to drive a particular robot: the 
``RoverBot'' described in the Lego MindStorms ``Constructopedia''
and pictured in figure <xref linkend="gadget1"/>.
<figure id="gadget1">
<graphic fileref="images/gadget1.jpg" align="center"> </graphic> 
<title>RoverBot MindStorms robot</title>
</figure>
This has motors to drive tracks or wheels on either side. The client
can send instructions to make the RoverBot move forwards or backwards,
stop, or turn to the left or right. The set of commands (and their 
implementation as RCX instructions) depends on the robot, and on what
you want to do with it.

</para>
<programlisting>
<?program "client/TestRCX.java"?>
</programlisting>
Why is one simplistic <emphasis>as a client</emphasis>? 
It tries to find all robots on the local
network, and sends the same set of commands to it. Worse, if a robot
has registered with, say, half-a-dozen service locators, and the client
finds all of these, then it will send the same set of commands six times
to the same robot! Some smarts are needed here...
</para>

</sect1>

<sect1>
<title id="Entry objects for a robot">Entry objects for a robot</title>
<para>
The RCX was not designed for network visibility. It has no concept of 
identity or location. The closest it comes to this is when it communicates
to other RCX's by the infrared transmitter: then one RCX may have to decide
if it is the master, which it does by setting a local variable
to `master' if it broadcasts before it receives, while the other RCX's
will set the variable to `slave' if they receive before broadcasting.
Then each waits for a random amount of time before broadcasting.
Crude, but it works.
</para>

<para>
In a Jini environment, there may be many RCX devices. These devices are not
`tied' to any particular computer, as they will respond to any infrared
transmitter on the correct frequency talking the right protocol.
All the devices within range of a transmitter will accept signals from
the transmitter, although this can cause problems as the source
computers tend to assume that there is only one target at a time and can get
confused by responses from multiple RCXs. 
The advice is to ``turn off all but one
RCX when a program is being downloaded'' to avoid this confusion. Then turn
on the next, and download to it, etc.
</para>

<para>
An RCX may also be mobile - it can control motors, so if it is placed in a mobile
robot it can drive itself out of the range of one PC and (maybe) into the range
of another. There are no mechanisms to signal either passing out of range, or 
coming into range.
</para>

<para>
The RCX is a poorly behaved animal from a network viewpoint. However,
we will need to distinguish between different RCX's in order to drive the
correct ones. An <code>Entry</code> class to distinguish them should 
contain information such as
<orderedlist>
<listitem>
  An identifier for robot type, such as ``Robo 1'', ``Acrobot 1'', etc.
  This will allow the robot that the RCX is built into to be determined.
  The RCX will have no knowledge of this - it must be externally supplied.
</listitem>
<listitem>
  The RCX can be driven by direct commands, or by executing a program already
  downloaded (there may be upto five of these). 
  An identifier for each program downloaded should be available for choice.
</listitem>
<listitem>
  The RCX will have some sort of location, although it may move around to a
  limited extent. This information may be available from the controlling computer,
  using the Jini <code>Location</code> or <code>Address</code> classes.
</listitem>
</orderedlist>
There may be other useful attributes, and there are certainly issues about
how the information could be stored and accessed from an RCX. However, they
stray beyond the bounds of this chapter.


</para>
</sect1>

<sect1>
<title id="A client-side RCX class">A client-side RCX class</title>
<para>
In the simplistic client given earlier, there were many steps that
will be the same for all clients that can drive the RCX. In a similar
way that <code>JoinManager</code> simplifies repetitive code on the
server side, we can define a ``convenience'' class for the RCX that
will do the same on the client side. The aim is to supply a class
that will make remote RCX programming as easy as local RCX programming.
</para>

<para>
A class to encapsulate client-side behaviour may as well look as much 
as possible like the local <code>RCXPort</code> class. We define its
(public) methods as
<programlisting>
public class JiniRCXPort {
    public JiniRCXPort();
    public void addRCXListener(RCXListener l);
    public boolean write(byte[] bArray);
    public byte[] parseString(String str);
}
</programlisting>
This class should have some control over how it looks for services, 
by including entry information, group information about locators,
and any specific locators it should try. There are a variety of
constructors, all ending up in
<programlisting>
    public JiniRCXPort(Entry[] entries,
		       java.lang.String[] groups, 
		       LookupLocator[] locators)
</programlisting>
The class is also concerned with <emphasis>uniqueness</emphasis> issues,
as it should not attempt to send the same instructions to an RCX
more than once. However, it could send the same instructions to more
than one RCX if it matches the search criteria. So this class maintains
a list of RCX's, and does not add to the list if it has already seen
the RCX from another service locator. This implies that a single RCX
is registered with the same <code>ServiceID</code> with all locators,
which it has because the RCX server uses <code>JoinManager</code>.
</para>
</sect1>

<sect1>
<title id="Higher level mechanisms: Not Quite C">
Higher level mechanisms: Not Quite C</title>
<para>
``Not Quite C'' is a language and a compiler from David Baum, designed
for the RCX. It defines a language with C-like syntax which defines 
<emphasis>tasks</emphasis> which can be executed concurrently. The RCX API also
defines a number of constants, functions and macros targetted specifically
to the RCX. These include constants such as <code>OUT_A</code> (for output
`A') and functions such as <code>OnFwd</code> to turn a motor on forwards.
</para>

<para>
A trivial NQC program to turn motor `A' on for 1 second (units are 1/100th
of a second) is
<programlisting>
<?program "rcx/simple.nqc"?>
</programlisting>
Writing programs using a higher-level language such as this is clearly
preferable to writing in Assembler!
</para>

<para>
NQC is not the only higher-level language for programming the RCX. 
There are links to many others on the alternative MindStorms site
<ulink url="http://www.crynwr.com/lego-robotics/">
http://www.crynwr.com/lego-robotics/</ulink>.
It is one of the earliest and more popular ones, though,
and forms a typical example of a stand-alone, non-GUI program
written in a language other than Java that can still
be used as a Jini service.
</para>

<para>
The NQC compiler is written in C++ and needs to be compiled for each 
platform that it will run on. Pre-compiled versions are available for
a number of systems such as Windows and Linux. Once compiled, it is tied to a
particular computer (at least, to computers with a particular O/S and
shared library configuration). It is software, not hardware like
the MindStorms robots, but is nevertheless not mobile. It cannot be
moved around like Java code can. However, it can be turned into a Jini
service in exactly the same way as MindStorms, by wrapping it in a
Java class that can be exported as a Jini service. This also fits
the RMI proxy model, with the client-side using a thin proxy that makes
calls to a service that invokes the NQC compiler.
</para>

<para>
The class diagram follows other RMI proxy diagrams and is shown in
figure <xref linkend="NotQuiteC"/>.
<figure id="NotQuiteC">
<graphic fileref="images/NotQuiteC.gif" align="center"> </graphic> 
<title>Class diagram for NQC with RMI proxy</title>
</figure>
The interfaces are defined by
<programlisting>
<?program "rcx/jini/NotQuiteC.java"?>
</programlisting>
and 
<programlisting>
<?program "rcx/jini/RemoteNotQuiteC.java"?>
</programlisting>
The compile exception is thrown when things go wrong, and is
<programlisting>
<?program "rcx/jini/CompileException.java"?>
</programlisting>


</para>

<para>
The implementation needs to encapsulate a traditional application running
in an environment of just reading and writing files. GUI applications,
or those nuisance Unix ones that insist on using an interactive terminal
(such as <code>telnet</code>) will need more complex encapsulation methods.
The <code>nqc</code> type of application will read 
from standard input or from a file,
often depending on command line flags. Similarly, it will write to a
file or to standard output, again depending on command line flags.
Applications either succeed or fail in their task: 
this should be indicated by what is
know as an <emphasis>exit code</emphasis>, which by convention is zero
for success, something else for failure. If a failure occurs, an
application will usually write diagnostic output to the standard error
channel.
</para>

<para>
The current version of <code>nqc</code> (version 2.0.2) is badly behaved
for reading from standard input (it crashes) and writing to standard output
(no way of doing this). So we can't create a <code>Process</code> to run
<code>nqc</code> and feed
into its input and output. Instead, we need to create temporary files and
write to and read from these files, so that the Jini wrapper can communicate
wtih <code>nqc</code>. These files also need to be cleaned up on
termination, whether the normal or exception routes are followed! 
On the other hand, if errors occur they will be reported on the
error channel of the process, and this needs to be captured in some way -
here we do it via an exception constructor.
</para>

<para>
The hard part in this example is ploughing your way through the Java I/O
maze, and deciding exactly how to hook up I/O streams and/or files to
the external process. The following code uses temporary files for ordinary
I/O with the process (the current version I have of <code>nqc</code> has a bug
with pipelines), and the standard error stream for compile errors.
<programlisting>
<?program "rcx/jini/NotQuiteCImpl.java"?>
</programlisting>

</para>

<para>
This section does not give  server and client implementations: the server
is the same as servers delivering other RMI services (is there a design
pattern here - or just an implementation pattern?). A client will make
a call on this service, specifying the program to be compiled. It can 
then write the byte stream to the RCX using the classes given earlier.
</para>

</sect1>

<sect1>
<title id="Summary">
Summary
</title>
<para>
This chapter has considered some of the issues involved in making a
piece of hardware with a Jini service. This was illustrated with
Lego MindStorms, where a large part of the base work of native code
libraries and encapsulation in Java classes has already been done.
Even then, there is still much work to make it into a suitable
Jini service, and these have been discussed. This not yet complete,
and more work remains to be done for Lego MindStorms.
</para>

</sect1>

&copyright;
</chapter>

