Programming with Lejos Part 1
What is lejos? Cut-down version of Java for the RCX platform Includes: –Lejos API –JVM API includes functionality needed to control motors, sensors, buttons as well as many components from the standard Java API
How it works Lego firmware is replaced with lejos JVM (only has to be done once) Program source code is written & compiled on PC Compiled code (Java byte code) is downloaded to & runs on RCX
JVM & RCX technical specifications RCX has 32k of RAM –4K unusable –16K for Lejos – 12K free memory for user code! Built-in support for: –Floating-point numbers (useful for trig/navigation) –Limited multithreading –2-dimensional Arrays –Limited recursion
Events & the lejos API Objects & their listeners: –Timer: TimerListener –Button: ButtonListener –Sensor: SensorListener Object acts as event source; when event occurs, all registered listeners we notified & can execute appropriate code
Exception Handling & Garbage Collection Lejos follows standard Java exception- handling model Lejos does NOT have automatic garbage collection –Important to re-use objects rather the just creating new ones –Forces good memory “hygiene”
josx.platfom.rcx: includes classes for controlling –3 output ports (A, B & C) –3 input ports (1, 2 & 3) –3 buttons (Prgm, Run, View) –LCD display –Speaker output –IR communication There are also classes for accessing system time & monitoring battery power Packages in the Lejos API
java.lang: Includes some of the most commonly used standard classes –Math –String –StringBuffer: mutable version of String –System –Thread –Throwable
Packages in the Lejos API java.util: like java.lang, includes some familiar and/or useful classes –Random –Vector: dynamic array –BitSet: series of bits
Packages in the Lejos API java.io: provides support for transmitting data streams via the IR port –Serializable interface –InputStream, OutputStream, DataInputStream, DataOutputStream and IOException classes
Packages in the Lejos API josx.robotics: generic classes & methods for robot-specific tasks –Behavior Control classes: includes Behavior interface & Arbitrator class –Navigation classes
Classes in josx.platform.rcx Sound class contains a set of static methods that can produce predefined or custom sounds: –Sound.beep() // beeps once –Sound.twoBeeps() // beeps twice –Sound. buzz() // emits almost inaudible tone –Sound. beepSequence() // series of // downward tones –Sound. playTone (int frequency, int duration) MinSound class is a cut-down version - contains only the (deprecated) playTone method
Classes in josx.platform.rcx Unlike most Java environments, robots running Lejos are physical objects The RCX brick has 3 programmable buttons, 3 sensor connections and 3 power output ports When programming for the RCX, these components are represented by predefined static objects; it wouldn’t make sense to instantiate more sensor ports, for example, because physically there are just 3
Classes in josx.platform.rcx The LCD, MinLCD and TextLCD classes relate to various aspects of the RCX’s LCD display MinLCD, like MinSound, is a cut-down version primarily used to conserve memory LCD is used for number display, while TextLCD can display Strings
LCD class methods (all are static) void refresh() void setNumber (int code, int value, int point) - parameters: –code: value Indicates use of signed or unsigned number, use of 5 th digit –value: number to display –point: code indicating position of decimal point These 2 methods are also found in MinLCD
LCD class methods (all are static) void clear(): clears display void showNumber(int i): displays an unsigned, up to 4-digit number void setSegment (int code): activates the display segment indicated by code; codes are defined by static constants in the Segment interface
Example 1: Sounds & Display import josx.platform.rcx.*; public class MakeNoise { public static void main(String[] args) throws InterruptedException { int freq;// frequency of tone for (freq = 440; freq < 10000; freq = 110 * freq / 100) { // ascending tones LCD.showNumber(freq); Sound.playTone(freq, 50); Thread.sleep(500); } for (freq = 440; freq > 20; freq = 90 * freq / 100) { // descending tones LCD.showNumber(freq); Sound.playTone(freq, 50); Thread.sleep(500); }
Classes in josx.platform.rcx Button class methods include: –public void addButtonListener (ButtonListener b) –public boolean isPressed() –public static int readButtons() Returns int with bits set: 0x02 (view button pressed) 0x04 (prgm button pressed), 0x01 (run button pressed). If all buttons are released, this method returns 0. –void waitForPressAndRelease () throws InterruptedException stops execution until button pressed & released
Classes in josx.platform.rcx Button class also contains static fields that represent the RCX buttons: –Button.PRGM –Button.RUN –Button.VIEW ButtonListener interface specifies 2 methods: –public void buttonPressed (Button b) –public void buttonReleased (Button b)
Classes in josx.platform.rcx ROM class: provides access to embedded routines in the RCX ROM; includes static method int getBatteryPower() Motor class: includes methods controlling DC output to ports A, B and C Sensor class: includes methods to communicate with sensor controllers 1, 2 and 3
Motor class methods: mutators void forward(): motor rotates forward void backward(): motor rotates backward void stop(): stops with braking action void flt(): motor floats to a stop void reverseDirection(): changes from forward to backward, or vice-versa void setPower(int power): sets motor power; 7 is high, 0 low
Motor class methods: accessors int getPower(): returns current power setting char getID(): returns motor ID (A, B or C) All of the following methods return a boolean value –isBackward() –isFloating() –isForward() –isMoving() –isStopped()
Example import josx.platform.rcx.*; public class Patrol { public static void main(String[] args) throws InterruptedException { Motor.A.forward(); while (true) { Motor.C.forward(); // go forward Thread.sleep (5000); Motor.C.reverse(); // turn around Thread.sleep (1000); }
Sensor class There are several types of sensors available for the RCX, including: –Touch –Light –Rotation Because each operates differently, there is more complexity built into this class than in most of the rest of the lejos API
Sensor Type and Mode A predefined set of constants is used to describe: –the kind of sensor attached to a particular connector (type) and –the kind of readings that are recorded by the sensor (mode) These values as used as arguments to the Sensor class’s setTypeAndMode method, which is used to initially set up a sensor
Type and Mode examples Sensor.S1.setTypeAndMode(1, 0x20); // 1 represents touch sensor; // 0x20 is boolean mode Sensor.S1.setTypeAndMode(3, 0x80); // 3 represents light sensor; // 0x80 is percent mode
Example import josx.platform.rcx.*; public class GoForward implements SensorConstants { public static void main(String[] args) { Sensor.S2.setTypeAndMode(SENSOR_TYPE_TOUCH, SENSOR_MODE_BOOL); // sets up touch sensor using constants from SensorConstants interface Motor.A.forward(); Motor.C.forward(); while( Sensor.S2.readValue() != 1 ) ; // loop ends (& robot stops) when bumper is touched }
Methods of Sensor class public void activate () –activates sensor –should be called after setTypeAndMode Methods that return Sensor readings: –public final boolean readBooleanValue() –public final int readValue() –public final int readRawValue() Sensor readings can also be handled by a SensorListener as described on the next slide
Sensor Listeners Sensor Listener interface specifies a single method: public void stateChanged(Sensor s, int old, int new) s: event source old: previous value new: new value As with the GUI components we have looked at before, the steps are –define a class that implements the interface, and with the code for the method –add the listener to the appropriate Sensor
Serial class Methods The Serial class is used for RCX to IR and RCX to RCX communication Methods work on the most basic level of network communication, passing around packets in the form of arrays of bytes A separate communications API provides support for higher-level operations
One more example import josx.platform.rcx.*; public class ListenerExample implements SensorConstants, SensorListener { public static void main(String[] args) { ListenerExample exam = new ListenerExample(); Sensor.S1.setTypeAndMode(SENSOR_TYPE_TOUCH, SENSOR_MODE_BOOL); Sensor.S3.setTypeAndMode(SENSOR_TYPE_TOUCH, SENSOR_MODE_BOOL); Sensor.S1.addSensorListener(exam); Sensor.S3.addSensorListener(exam); exam.patrol(); }
Example continues public void patrol () { try { Motor.A.forward(); while (true) { Motor.C.forward(); Thread.sleep(3000); Motor.C.backward(); Thread.sleep(1000); } } catch (Exception e) { }
End of example public void stateChanged(Sensor source, int oldValue, int newValue) { if (newValue == 1) if (source.getId() == 0) // left bumper Sound.playTone(220, 50); else if (source.getId() == 2) // right bumper Sound.playTone(660, 50); } } // end class ListenerExample