Table of Contents



1. Lejos

This chapter will overview computer hardware for real-time systems. Toshiba H8/3292, which is the computer used in the RCX Mindstorm box, will be used as a sample computer system.

1 Lejos Software Development Environment

The hardware of the Lejos software development environment includes a PC running Windows 2000, a USB Lego infrared communication tower, and RCX box. The software consists of a Lejos Java compiler called lejosc, which runs on the PC, Java class loader called lejos, which loads Java classes to the RCX box, and the JVM loader, which downloads the Lejos Java virtual machine to the RCX box.

Figure 1.1-1 Lejos architecture.

2 Lejos Classes

Lejos provides a wide range of classes that provide an interface to hardware devices. Table 0-1 lists classes defined in Lejos and a brief description each. In this section, we will discuss how to use each class and along with its corresponding hardware device.

Table 0-1 Lejos classes.

|Class Name |Description |

|Motor |Abstraction for a motor. |

|Button |Abstraction for an RCX button. |

|Sensor |Abstraction for a sensor |

|LCD |LCD routines |

|MinLCD |Only the most basic APIs from LCD. |

|TextLCD |Display text on the LCD screen. |

|Sound |RCX sound routines. |

|MinSound |Only the most basic APIs from Sound. |

|Poll |Provides blocking access to events from the RCX. |

|Serial |Low-level API for infra-red (IR) communication between an RCX and the IR tower or between two|

| |RCXs. |

|ProximitySensor |A 'sensor' to detect object proximity. |

|Battery |Provides access to Battery. |

|MinuteTimer |Provides access to Battery.???? |

|Memory |Provides access to memory. |

|PersistentMemoryArea |A memory area for persistent storage. |

|Servo |Implementation of a servo using a Motor and a Rotation Sensor. |

|ROM |Provides access to ROM routines. |

1.2.1 Motor

The first thing anyone wants to do with a robot is probably to it move and move in a controlled way. Lejos defines a class called Motor to encapsulate the control of the three output ports that can be connected to motors. Three static instances of Motor, A, B, and C are defined in the Motor class corresponding to the motor output ports A, B, and C, respectively. The only constructor of the Motor class is declared private so it is not possible for a user to declare any other instance of Motor. The Motor class defines methods for controlling the motion of a motor and querying the status of each motor. Table 0-2 shows the methods defined in Motor.

Table 0-2 The Motor class.

|Method Signature |Description |

|void backward() |Causes motor to rotate backwards. |

|void forward() |Causes motor to rotate forward. |

|void reverseDirection() |Reverses direction of the motor. |

|void stop() |Causes motor to stop |

|void flt() |Causes motor to float. |

|void setPower(int aPower) |Sets motor power to a value between 0 and 7. |

|boolean isBackward() |Return true if motor is backward. |

|boolean isForward() |Return true if motor is forward. |

|boolean isMoving() | |

|boolean isStopped() |Return true if motor is stopped. |

|boolean isFloating() | |

|int getPower() |Returns the current motor power. |

|char getId() |Get the ID of the motor. |

The first group of Motor methods is to control motion of motors and they can switch a motor on and move it forward, backward, or reverseDirection. Actually a program does not know what direction forward (backward) is. The forward and backward only mean that two opposite voltage levels applied to the output. Whether the motor really moves forward or backward totally depends on the construction. If the forward method causes the motor to move backward, just turn the wire connector to the port by 180o.

The second group of methods is to query the status of a motor, for example, whether it is moving forward, the power level of a motor and the identification of a motor.

|[pic] |

Figure 1.2-1 Robot for MotorControl.

For example, the robot shown in Figure 1.2-1 has motors mounted on ports A and B. The following program moves the robot forward for 10 seconds and then keeps it turning left for 4 seconds, repeats for 10 times. The turning left is done by turn the left wheel backwards and the right wheel forward. Thread.sleep() is a method defined in the Thread class and it makes the current calling thread (or the current running program) delay for a given period of time. When the program is sleeping the two motors keeping the current state, i.e., moving forward or turning left.

|public class MotorControl { |

| |

|private int motorSpeed = 1; |

| |

|public MotorControl() throws InterruptedException { |

| |

|for (int j = 0; j < 10; j++) { |

|// set motor power ( 0 throught 7) |

|Motor.A.setPower(motorSpeed); |

|Motor.B.setPower(motorSpeed); |

|// Increase the speed for next round |

|motorSpeed = (motorSpeed + 1) % 7 + 1; |

| |

|// go forward for 10 seconds |

|Motor.A.backward(); |

|Motor.B.forward(); |

|Thread.sleep(10000); |

| |

|// keep turning left for 4 millisecond |

|Motor.A.forward(); |

|Motor.B.forward(); |

|Thread.sleep(4000); |

|} |

|// stop both motors (A and B) |

|Motor.A.stop(); |

|Motor.B.stop(); |

|} |

|public static void main(String args[]) throws InterruptedException { |

|MotorControl motor = new MotorControl(); |

|} |

|} |

The power of a motor can be set to a value in the range of 0 through 7 inclusive with 0 for no power and 7 for the highest power. Once the power is set it does not change until it is set to a new value. The same is for the motion direction. That is why in the above sample code the power and moving direction are set only once and the thread sleep for 100 milliseconds. Thread.sleep(milliseconds) is a static method defined in the class Thread. It delays the calling thread for milliseconds.

1.2.2 Button

The RCX has four buttons: On/Off, Run, View, and Prgm. The On/Off button is used to turn the power of the RCX on or off, and it cannot be programmed. The other three buttons can be programmed as input. Lejos defines the Button class to encapsulate the details of interactions with the buttons. The static instances of Button, RUN, VIEW, and PRGM are defined to represent the Run, View, and Prgm buttons, respectively. Table 0-3 shows all the methods of the Button class.

Table 0-3 The Button class.

|Method Signature |Description |

|void addButtonListener(ButtonListener aListener) |Adds a listener of button events. |

|void callListeners() | |

|int getId() |Return the ID of the button. |

|boolean isPressed() | |

|void waitForPressAndRelease() |Wait until the button is released. |

|static int readButtons() |Reads status of buttons. |

The three buttons may be monitored in two different ways. One way is polling. A program can poll the status of a button: whether it is pressed or not. The isPressed returns true if the button is pressed. The readButtons method returns an integer that represents the status of all the three buttons. The rightmost bit (least significant) of the returned integer, bit 0, represents the Run button, 1 for pressed and 0 not pressed; bit 1 for View, and bit 2 for Prgm. The unused bits are set zero. Thus, a return value 2 (in decimal) means the View button is being pressed. When all the buttons are released, it returns the value zero. Polling is very inefficient since it wastes many CPU cycles and also since the isPressed and readButtons methods return true only when the button is being held down fast button presses may go undetected.

The other method is interrupt. Each button may generate two interrupts: one for button is pressed and the other for released. Each button may be attached with multiple listeners for each kind of interrupts. When the button is pressed (or released), the JVM stops whatever it is executing and invokes and executes all the listeners for button press. After all the listeners are completed, the JVM resumes the execution of the interrupted thread from where it was interrupted.

This interrupt is implemented as event listeners in Java. The Button class defines the addButtonListener method that can be used to attach button listeners that implement the ButtonListener interface. A button listener must implement public void buttonPressed(ButtonListener bl) and public void buttonReleased(ButtonListener bl) methods. When the button is pressed (or released), the buttonPressed (or buttonReleased) method of a listener is invoked. After all the listeners are executed, the JVM resumes whatever was interrupted.

The following example shows how buttons may be monitored using interrupts.

|public class ButtonMonitor implements ButtonListener { |

| |

|public ButtonMonitor() throws InterruptedException { |

|TextLCD.print("prs b"); |

|Button.RUN.addButtonListener(this); |

|Button.PRGM.addButtonListener(this); |

|Button.VIEW.addButtonListener(this); |

|} |

| |

|public void buttonPressed(Button b) { |

|if(b==Button.RUN) { |

|TextLCD.print("RUN"); |

|} |

|else if(b==Button.PRGM) { |

|TextLCD.print("PRGM"); |

|} |

|else if(b==Button.VIEW) { |

|TextLCD.print("VIEW"); |

|} |

|} |

| |

|public void buttonReleased(Button b) { |

|TextLCD.print("relis"); |

|} |

| |

|public static void main(String args[]) throws InterruptedException { |

|ButtonMonitor bm = new ButtonMonitor(); |

| |

|while(true); |

|} |

|} |

The WaitForPressAndRelease method waits until the button is pressed and then released. For example, a robot keeps moving forward until Prgm is pressed and released.

|import josx.platform.rcx.*; |

| |

|public class MotorButton { |

| |

|static private int motorSpeed = 5; |

| |

|public static void main(String args[]) throws InterruptedException { |

| |

|Motor.A.setPower(motorSpeed); |

|Motor.B.setPower(motorSpeed); |

| |

|Motor.A.backward(); |

|Motor.B.forward(); |

| |

|//Move forward untill View is pressed |

|Button.VIEW.waitForPressAndRelease(); |

| |

|Motor.A.stop(); |

|Motor.B.stop(); |

|} |

|} |

getIId return the value 1 for the Run button, 2, for View, 4 for Prgm.

1.2.2 Sensor

The RCX has three input ports that can be connected to a wide range of different sensors. A sensor normally maps the physical state of the sensed as a voltage and this voltage is connected to a A/D (analog to digital) converter. The A/D converter converts the analog value to its corresponding digital value represented in 10 bits. The software can read this digital value from the A/D converter. Currently Lejos supports five different types of sensors: touch, light, rotation, temperature, and raw. The SensorConstants interface defines the five types as the following constants:

static int SENSOR_TYPE_TOUCH

static int SENSOR_TYPE_LIGHT

static int SENSOR_TYPE_ROT

static int SENSOR_TYPE_TEMP

static int SENSOR_TYPE_RAW

Normally there are three steps that must be performed to set up a sensor before it can read properly. First set sensor type, then sensor mode, and activate the sensor. Setting sensor type and sensor mode can be performed by the Sensor.setTypeAndMode method of the Sensor class, and activation may be carried out by the Sensor.activate method.

Different types of sensors require different hardware level signals for proper operation. The RCX hardware does not have any intelligence in determining the sensor types connected to its ports. It is the programmer’s responsibility to use Sensor.setTypeAndMode to inform the RCX what sensor is being used so it interacts with the sensor using proper signals. All sensors are connected to analog to digital conversion input ports and so the RCX read the sensor as an unsigned 10-bit value in the range 0-1023. This is referred as the sensor’s raw value. This raw value may be interpreted differently based on the sensor mode set by Sensor.setTypeAndMode.

|Sensor Mode |Sensor Type |Remark |

|SENSOR_MODE_BOOL |Touch |High raw values are mapped to false, low values to true. |

|SENSOR_MODE_RAW |All |Digital voltage level, no interpretation, 0...1023 |

|SENSOR_MODE_PCT |All |Scales raw values to 0-100 with 0 = high raw value, 100 = |

| | |low raw value. 0...100 |

|SENSOR_MODE_ANGLE |Rotation |Accumulate signals from a rotation sensor and return the sum|

| | |of all signals received up to now. Signals have a sign and |

| | |may add to or subtract from the sum. |

|SENSOR_MODE_DEGC |Temperature |Map to degrees centigrade. |

|SENSOR_MODE_DEGF |Temperature |Map to degrees Fahrenheit. |

|SENSOR_MODE_EDGE |Touch |Interpret as SENSOR_MODE_BOOL; Returns the total number of |

| | |value changes received up to now. This is the number of |

| | |times a touch sensor was pressed or released. 0... |

|SENSOR_MODE_PULSE |Touch |Interpret as SENSOR_MODE_BOOL; Return the total number of |

| | |changes from 1 to 0 received up to now. This is the number |

| | |of times a touch sensor was released. 0... |

Table 0-4The Sensor class.

|Method Signature |Description |

|void activate() |Activates the sensor. |

|void addSensorListener(SensorListener aListener) |Adds a sensor listener. |

|void callListeners() |Return the ID of the button. |

|int getId() |Return the ID of the sensor. |

|void passivate() |Passivates the sensor. |

|boolean readBooleanValue() |Reads the Boolean value of the sensor. |

|int readRawValue() |Reads the raw value of the sensor. |

|static int readSensorValue(int aSensorId, int aRequestType) |Low-level API for reading sensor values. |

|int readValue() |Reads the canonical value of the sensor. |

|void setPreviousValue(int aValue) |Resets the canonical sensor value. |

|void setTypeAndMode(int aType, int aMode) |Sets the sensor's mode and type. |

|import josx.platform.rcx.*; |

| |

|public class Tracer implements ButtonListener { |

| |

|private static final int BLACK_COLOR = 35; |

|private static final int MOTOR_SPEED = 7; |

|private int color1 = 0; |

|private int color2 = 0; |

|private boolean running = true; |

| |

|public static void main(String args[]) throws InterruptedException { |

|Tracer roboDemo = new Tracer(); |

|} |

| |

|public Tracer() throws InterruptedException { |

|Sensor.S1.setTypeAndMode(SensorConstants.SENSOR_TYPE_LIGHT, |

|SensorConstants.SENSOR_MODE_PCT); |

|Sensor.S1.activate(); |

|Sensor.S2.setTypeAndMode(SensorConstants.SENSOR_TYPE_LIGHT, |

|SensorConstants.SENSOR_MODE_PCT); |

|Sensor.S2.activate(); |

| |

|Button.RUN.addButtonListener(this); |

| |

|LCD.clear(); /* Clear the LCD display */ |

| |

|Motor.A.setPower(MOTOR_SPEED); |

|Motor.B.setPower(MOTOR_SPEED); |

| |

|color1 = Sensor.S1.readValue(); |

|color2 = Sensor.S2.readValue(); |

|while (color1 > BLACK_COLOR && color2 > BLACK_COLOR) { |

|TextLCD.print("srch"); |

|Motor.A.backward(); |

|Motor.B.forward(); |

|color1 = Sensor.S1.readValue(); |

|color2 = Sensor.S2.readValue(); |

|Thread.sleep(100); |

|} |

|while (true) { |

| |

|while (running) { |

|color1 = Sensor.S1.readValue(); |

|color2 = Sensor.S2.readValue(); |

|if (color1 ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download