Lego Java
Lego Java
Programming Lego Mindstorms NXT with Java. LeJOS NXJ Virtual Machine.
Legal notes
2008,2011 Silesian University of Technology, Gliwice, Poland, Ph. D. Piotr Czekalski This document is copyrighted. Copying, lending, distribution and redistribution on author's permission only. This document contains noncommercial, educational content only thus cannot be utilized as a part of of any commercial business. Author of this document assures that has made efforts to achieve correctness of the contents of this document as well as tried to provide latest and most modern review of the related technology on the hardware, software and programming methods. However it is obvious that author cannot guarantee the content not to contain some minor or major mistakes or shortcomings, mostly because of rapid popularity on the subject, changes of legal state, changes in current knowledge and trends, hardware and software updates, etc. This document is provided as is with no warranty of any kind and cannot be a subject of any claims on the content nor author. Author kindly requests all users of this document to provide information on any mistakes or shortcomings in this documents pro publico bono. As this document can exist in many versions it is necessary to check doubtful content versus latest release of this document. Any trademarks used in this document may be copyrighted by appropriate owners, particularly: LEGO, the LEGO logo, DUPLO, BIONICLE, MINDSTORMS, the BELVILLE, CLIKITS, KNIGHTS KINGDOM and EXO-FORCE logos, the Brick and Knob configurations and the Minifigure is a trademark of the LEGO Group. Microsoft, Robotics Studio, .NET logo, Visual Studio, ActiveX and Windows is a trademark of the Microsoft Corporation. Java, JDK and JAVA logo is a trademark of the Oracle Corp. ageia PhysX is a trademark of the nVIDIA Corporation.
Part 1
LeJOS NXJ
New firmware replaces genuine LEGO (reversible operation). Dedicated compiler and linker (imports it's own java.lang.* libraries). A set of utilities to work with NXT Brick. API covers both Genuine LEGO and 3rd party components (sensors, servos, comm., etc.). It is Open Source project. Current version 0.9.0 beta (16th May 2011) Formerly API was for RCX (RIS) now NXT. LeJOS powered robot Jitter flew on International Space Station in 2001 ;-).
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
Setup procedure.
LEGO Mindstorms Edu/Retail Software
Dedicated setup.
LeJOS http://lejos.sourceforge.net/nxj-downloads.php
Dedicated setup (also ZIP available).
LibUSB http://libusb-win32.sourceforge.net/#downloads
Dedicated setup. Extra procedure for Windows 7/Vista exists, not for x64.
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
NXJ_HOME LeJOS folder, i.e: c:\Program Files\LeJOS NXJ or C:\Program Files (x86)\leJOS NXJ (on x64) JAVA_HOME JDK setup folder (must be JDK instead of JRE) (warning: for x64 Windows OSes JDK have to be x86 anyway) ANT_HOME Ant scripts folder, i.e.: c:\apache-ant-1.8.2ant PATH - %NXJ_HOME%\bin;%JAVA_HOME%\bin;%ANT_HOME %\bin;%PATH%
CLASSPATH - .;C:\icommand0.7\dist\icommand.jar;C:\icommand0.7\dist\bluecove-2.1.0.jar;
Ph.D. Eng. Piotr Czekalski
Brick have to be connected over USB, detected (drivers installed) and ready. cmd: > nxjflash or nxjflashg Sometime manual entering into firmware update mode is necessary (press hardware reset button for few seconds see image below). NXJ can be replaced with genuine firmware again (the NXJ firmware flashing is reversible procedure) using LEGO Mindstorms Edu/Retail NXT software NXT Intelligent Brick allows up to about 100 updates to the firmware.
Cmd:> cd %NXJ_HOME%\samples\View (Lejos v 0.6) Cmd:> cd %USERPROFILE%\leJOSNXJProjects\samples\View (v 0.7 and newer) Cmd:> nxjc View.java Cmd:> nxj -r -u View
Allows to watch NXT(NXJ) robot state: View sensor values. View servomotors state. View system state.
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
10
Part 2
Configuring Eclipse to compile autonomous projects for NXJ. Creating a project for NXJ. Configuring three exteral tools (compile, upload, browse NXT brick contents) to work with NXT directly from Eclipse IDE.
11
Configuring Eclipse.
Eclipse http://www.eclipse.org/downloads/
Follow instructions available on-line (currently just unpack).
12
13
14
15
16
17
}
Ph.D. Eng. Piotr Czekalski
18
Program starting procedure: 1.Compile. 2.Upload to NXT. 3.Run using nxjbrowse or directly from the firmware menu.
19
Using LeJOS plugin for Eclipse: Installation procedure. Configuration procedure. Sample project.
20
21
22
23
LeJOS comes with bunch of valuable tools. Those may be configured as Eclipse External Tools, i.e.: nxjbrowse NXJ brick file explorer nxjmonitor a remote program monitor allows to browse sensor input and servomotor output values almost realtime (well, not in fact too slow for most applications), also draws tracing message (useful). Works over Bluetooth connection. nxjdataviewer data logger downloader and presentation tool (both BT & usb) nxjconsoleviewer RConsole output (graphical tool) nxjconsole as above but command line nxjcontrol combines above in one + some extra features nxjdebug debugger no longer exists, replaced by nxjconsole The tools include trace and debugging, also nxjbrowse tool. Procedure same as configuring compiler and linker using external tools.
24
LeJOS API.
Three modes (two remote, one autonomous):
lejos.nxt,lejos.robotics, lejos.geom
Autonomous:
java.awt, java.io, java.lang, java.util, java.awt Micro edition: javax.bluetooth, javax.microedition.io, javax.microedition.lcdui Other: lejos.devices, lejos.robotics.navigation, lejos.nxt, lejos.nxt.comm, lejos.nxt.debug, lejos.nxt.remote, lejos.rcxcomm, lejos.robotics.subsumption, lejos.util, lejos.robotics
Ph.D. Eng. Piotr Czekalski
25
26
tracing, i.e. asserts, data loggers, watches, timers, recycled classes, button click counters, etc.
lejos.addon.keyboard SPP (over BT) keyboard
support classes.
compatibility classes.
27
28
lejos.io lejos specific stream reader / writer classes native support for java.io
29
Basic components, most common use when compiling for NXT Intelligent Brick:
Common solution part. Different and exceptional cases.
30
31
Sample:
32
Methods (general description): Draw lines, arcs, figures, images, Strings, Ints, Chars Drawing style and fill can be provided.
33
34
35
Sample:
import lejos.nxt.*; public class ButtonPresses { void public static void main (String[] args) throws Exception { while (true) { LCD.clear(); If (Button.ENTER.isPressed()) LCD.drawString("ENTER",0,0); if (Button.ESCAPE.isPressed()) LCD.drawString("ESCAPE",0,0); if (Button.LEFT.isPressed()) LCD.drawString("LEFT",0,0); if (Button.RIGHT.isPressed()) LCD.drawString("RIGHT",0,0); } }
Ph.D. Eng. Piotr Czekalski
36
Sample:
import lejos.nxt.*; public class ButtonTest { void public static void main (String[] args) throws Exception { Button.ENTER.waitForPressAndRelease(); LCD.drawString("Finished", 3, 4); Thread.sleep(2000); } }
37
Methods:
static float getVoltage(); static int getVoltageMilliVolt();
Sample:
import lejos.nxt.*; public class BatteryTest { void main (String[] args) throws Exception { LCD.drawString("Battery: " + Battery.getVoltage(),0,0); Thread.sleep(2000); } }
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
38
Methods:
public static void systemSound(boolean aQueued, int aCode); Acode=(0: short beep, 1: double beep, 2: descending, 3: ascending) public static void beep(); public static void twoBeeps(); public static void beepSequence(); public static void beepSequenceUp(); public static void buzz();
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
39
import lejos.nxt.*; public class Tune { private static final short [] note = { 2349,115, 0,5, 1760,165, 0,35, 1760,28, 0,13, 1976,23, 0,18, 1760,18, 0,23, 1568,15, 0,25, 1480,103, 0,18, 1175,180, 0,20, 1760,18, 0,23, 1976,20, 0,20, 1760,15, 0,25, 1568,15, 0,25, 2217,98, 0,23, 1760,88, 0,33, 1760,75, 0,5, 1760,20, 0,20, 1760,20, 0,20, 1976,18, 0,23, 1760,18, 0,23, 2217,225, 0,15, 2217,218}; void public static void main(String [] args) {
final short w = note[i+1]; final int n = note[i]; if (n != 0) Sound.playTone(n, w*10); try { Thread.sleep(w*10); } catch (InterruptedException e) {}
Ph.D. Eng. Piotr Czekalski
}}} 40
Touch sensor.
Class:
TouchSensor class instance with port;
Constructor:
public TouchSensor(ADSensorPort port);
Common methods:
public boolean isPressed();
41
} }
42
Light sensor.
Class:
Constructor:
public LightSensor(ADSensorPort port);
Methods:
void setFloodlight(boolean bOn); public int readValue(); public int readNormalizedValue(); void calibrateHigh(); void calibrateLow(); void setHigh(int high); void setLow(int low); int getHigh(); int getLow();
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
43
throws Exception {
44
Sound sensor.
Class:
Constructor:
public SoundSensor(ADSensorPort port); public SoundSensor(ADSensorPort port, boolean bDBA);
Methods:
int readValue(); void setDBA(boolean dba);
45
import lejos.nxt.*; public class SoundScope { void main (String[] args) throws Exception { SoundSensor light = new SoundSensor(SensorPort.S1); while (!Button.ESCAPE.isPressed()) { LCD.clear(); for(int i=0;i<100;i++) LCD.setPixel(1,i,60 - (sound.readValue()/2)); Thread.sleep(20); } } } }
46
Constructor:
public UltrasonicSensor(I2CPort port);
Methods:
int getDistance(); void ping(); int readDistances(int [] distances); int continuous();
47
import lejos.nxt.*; public class SonicTest { void main(String[] args) throws Exception { UltrasonicSensor sonic = new UltrasonicSensor(SensorPort.S1); while(!Button.ESCAPE.isPressed()) { LCD.clear(); LCD.drawInt(sonic.getDistance(), 0, 3); } } }
48
Methods:
void flt(); void forward(); void backward(); int getActualSpeed(); float getBasePower(); int getLimitAngle(); int getMode(); int getPower(); int getSpeed(); int getStopAngle();
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
49
50
51
import lejos.nxt.*; public class HelloWorld { public static void main(String [] args) {
Motor.B.resetTachoCount(); Motor.C.resetTachoCount();
while (!Button.ENTER.isPressed()) {
}}}
52
(...) Motor.B.setSpeed(720);// 2 RPM Motor.C.setSpeed(720); Motor.B.forward(); Motor.C.forward(); Thread.sleep (1000); //to trzeba oboy musi by Try-catch eby skompilowa Motor.A.stop(); Motor.C.stop(); Motor.A.regulateSpeed(true); Motor.A.rotateTo( 360); Motor.A.rotate(-720,true); while(Motor.A.isRotating()){}; int angle = Motor.A.getTachoCount(); // should be -360 (...)
Ph.D. Eng. Piotr Czekalski
53
rd
Sensors other than I2C use A/D port (ADSensorPort) and have dedicated classes, not inheriting common base class (but object, as all classes do). All I2C sensors inherit from I2CSensor.
54
rd
Constructor:
public UltrasonicSensor(I2CPort port);
Methods:
int getData(int register, byte[] buf, int len); int sendData(int register, byte value); int sendData(int register, byte[] buf, int len); void setAddress(int addr); // 7-bit I2CPort getPort(); String getProductID(); String getSensorType(); String getVersion();
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
55
Compass sensor.
Both HiTechnic & Mindsensors:
Constructor:
public CompassSensor(I2CPort port);
Methods:
float getDegrees(); //0.1 grade accuracy clockwise float getDegreesCartesian; // counterwise void resetCartesianZero(); void startCalibration(); // min. 20s/per turn, Mindsensors min. 2 turns, HiTechinc: 1.5 to 2 void stopCalibration();
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
56
Compass sensor.
Sample:
import lejos.nxt.*; import lejos.nxt.addon.*; public class Compass { public static void main(String [] args) { CompassSensor cs = new CompassSensor(SensorPort.S4); Motor.B.setSpeed(60); Motor.B.forward(); float stopnie=cs.getDegrees(); while (stopnie>1) { LCD.clear(); LCD.drawInt((int)stopnie, 1, 1); stopnie=cs.getDegrees(); } Motor.B.stop(); LCD.clear(); LCD.drawString("Znalazlem polnoc!", 1, 2); try { Button.ENTER.waitForPressAndRelease(); } catch(InterruptedException e){}} }
57
Tilt / acceleration.
HiTechnic:
AccelHTSensor;
Constructor:
public AccelHTSensor(I2CPort port); public AccelHTSensor(I2CPort port, int address);
Methods:
int getXAccel(); int getXTilt(); int getYAccel(); int getYTilt(); int getZAccel(); int getZTilt();
58
Tilt / acceleration.
Mindsensors:
AccelMindSensor;
Constructor:
public AccelMindSensor(I2CPort port); public AccelMindSensor(I2CPort port, int address);
Methods:
int getXAccel(); int getXTilt(); int getYAccel(); int getYTilt(); int getZAccel(); int getZTilt();
59
Gyro sensor.
Class:
Constructor:
public GyroSensor(AdSensorPort port);
Methods:
int readValue(); void setOffset(int offset);
Requires setting the offset to provide accurate results (offset can be measured during runtime). DirectionFinder based on gyro (keeps heading):
public GyroDirectionFinder
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
60
Constructor: public ColorSensorHT(I2CPort port); Methods: Color getColor(); - returns RGB at once in Color class int getBlue/Green/Red(); int getColorIndexNumber();int getColorID(); int getMode(); int getRGBNormalized(int color); int getRGBRaw(int color); int initBlackLevel(); int initWhiteBalance();
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
61
Constructor: public ColorSensor(I2CPort port); public ColorSensor(I2CPort port, int mode); public ColorSensor(I2CPort port, int address, int mode, int type); Methods: calibrateAngle() getAccAngle() - read accumulated angle getAngle() - read current angle getRPM() - read current rotation speed resetAccAngle() - reset the accumulated angle count
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
62
IRSeeker class instance with I2C port; IRSeekerV2 class instance with I2C port; OpticalDistanceSensor class instance with I2C port; NXTCam class instance with I2C port;
NXTCam (Mindsensors):
63
PFMate I2C control LEGO Power Functions IR receiver PFMateMotor Motor class for PFMate PFMotorPort Motorport class for PFMate
64
RFIDSensor I2C
HiTechnic EOPD (Electro Optical Proximity Detector) capable to detect very small distance changes, spotlight independent:
LinearActuator MotorPort
Ph.D. Eng. Piotr Czekalski
65
66
67
RCX Motor:
RCXMotor class instance, using BasicMotorPort class;
RCXRotationSensor class instance, using LegacySensorPort class; RCXTemperatureSensor class instance, using LegacySensorPort class;
Ph.D. Eng. Piotr Czekalski
68
69
70
71
When pressing Esc select returns -1, when canceled by quit() returns -2.
Select is a blocking call, quit() can be called by
72
PIDController;
Constructor: public PIDController(int setpoint); Methods: doPID(int processVariable) PID calculation for single iteration freezeIntegral(boolean status) getPIDParam(int paramID) setPIDParam(int paramID, float value)
73
Method:
static Properties getProperties(); static String getProperty(String key, String defaultValue); static void getProperty(String key, String Value);
74
75
76
77
Debugging.
LeJOS NXJ provides basic support for handling critical situations and finding errors: Runtime exception handling, Debugging over USB. NXJ supports most of standard Java exceptions. Remote debugging requires to communicate with a PC computer by: Calling one following methods in NXJ program:
public static void open(int timeout); public static void open();
78
Debugging (cont.).
Send text to the debugger:
public static void out(String s);
79
Programming using pilot and navigator classes. Subsumption programming with behaviours implementation, hierarchy and cooperation.
80
Navigator classes
lejos.robotics.navigation pack. Generally for Tribots, however servomotor ports can be defined freely. Supports abstract/high level creation of the robot moves. Programming of movements by high level navigator classes (implement Navigator); SimpleNavigator (acutally useless, obsolete) TachoNavigator; CompassNavigator; Uses Pilot or CompassPilot classes to execute desired robot movment and to identify XY localisation. Warning for the inertia of movements, according to the physical phenomenas (see theory vs practice)
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
81
Subsumption programming.
lejos.robotics.subsumption pack. High level definition of the robot behaviour. Pro's: clear and well organized code, clear relations among behaviours, separates behaviours from the low level action implementation, very easy extension by new behaviours.. Flaws: longer project startup time (at the beginning), hard to identify all possibilities, template based project organisation (may be pro),
Version 1.53 | 20th November 2011
difficult debugging.
82
Subsumption programming.
Behaviour class must implement lejos.robotics.subsumption.Behavior interface. Interface methods to implement (obligatory): void action(); // main behaviour actions void supress(); // stop/brake executed to stop action(); Won't finish until action(); stops, thus developer must ensure to make action(); safely interruptable by it's own. boolean takeControl(); // tests, if the action shall be executed.
83
Subsumption programming.
Arbitrator class ensures checking if behaviour shall be executed and calling appropriate actions: lejos.robotics.subsumption.Arbitrator Constructor: Arbitrator(Behavior[] behaviors); // start(); need to be called afterwards void start(); Arbitrator circulates over behaviours with respect to their priority and checks if execution condition is true for takeControl(); behaviors table index is a priority of the behaviour.
84
Subsumption programming.
If two behaviours are ready to execute, only the higher priority one is executed.
Arbitrator is singlethreaded ! Can loose some environment / sensor events because interaction can disappear before behaviour receives control to check execution condition. Execution buffering is necessary then (foolproof takeControl() method). When higher level behaviour occurs, the lower level behaviour's supress() method is called to break it. One behaviour is never executed one by one. If during next check the same behaviour is still active, next lower priority behaviour is being executed.
85
86
Button.ENTER.addButtonListener(new ButtonListener() {
LCD.drawString("ENTER pressed",0,0);
LCD.clear(); ();
87
88
iCommand is currently obsolete, as replaced by LEJOS NXJ however still provide remote controlled environment even if LEJOS is efficient but autonomous. LCP compatible firmware needed (NXJ or Genuine v. 1.05 or later). Firmware acts as communication broker between PC and NXT brick. Main algorithm is executed on the PC using PC Java virtual machine (JRE) (Windows/Linux/Mac OS). Packages icommand.*(since Lejos 0.8 it is dead)
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
89
May 2009)
90
91
92
93
LeJOS PC API is designed for Oracle / Sun Java classes.jar libraries. Subset of autonomous packages, similar programing and behaviour. Firmware acts as communication broker between PC and NXT brick (using LCP). Main algorithm is executed on the PC using PC Java virtual machine (JRE) (Windows/Linux/Mac OS).
Works with almost any firmware that supports LCP (in theory).
Version 1.53 | 20th November 2011 Ph.D. Eng. Piotr Czekalski
94
Packages:
95
Packages:
96
Literature
Maximum LEGO NXT: Building Robots with Java Brains, Brian Bagnall, 2007. On-line: LeJOS Tutorial, http://lejos.sourceforge.net/nxt/nxj/tutorial/index.htm, August 2011. On-line: NXJ API, http://lejos.sourceforge.net/nxt/nxj/api/index.html, August 2011. On-line: PC NXJ API: http://lejos.sourceforge.net/nxt/pc/api/index.html, August 2011. On-line: iCommand API: http://lejos.sourceforge.net/nxt/icommand/api/index.html, December 2010.
97
98