event driven programming minus the gui plus a robot by charlie vick

Post on 05-Jan-2016

221 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Event Driven ProgrammingMinus the GUIPlus a RobotBy Charlie Vick

Why Event-Driven Robotics?

• This robot consists of sensors and motors.• Event driven programming decouples sensor

monitoring and motor controlling. Different classes specialize, compartmentalizing the hardware.

• Can more easily switch out sensors or motors, as long as everyone can use the same event system and events.

Robot Gear

• Hardware: Lego Mindstorm NXT - servos, sensors and an ARM processor

• Software: open-source 3rd party firmware called leJOS, which runs compiled Java bytecode

The old bot configuration

Current bot configuration

QuickTime™ and a decompressor

are needed to see this picture.

Architecture (part 1)

• Lejos library has a class, ‘SensorPort’• SensorPort.addSensorPortListener( Se

nsorPortListener aListener) is a public method

• SensorPortListener: Interface, has one method:void stateChanged(SensorPort source, int oldValue, int newValue)

This seemed a real coup

• leJOS looked to be designed for event-driven programming

• Wire up SensorPortListeners to a few sensors, have each steer in different ways when triggered

Problem

• API Documentation out of date. Forum search revealed SensorPortListener was deprecated for most sensors.

• Only works on one sensor I have, touch.

• Doesn’t actually work.

Program Architecture (part 2)

• Slightly more complex.

• One class, SensorReader, iterates through a couple of sensors. If certain values are hit, fire a certain event.

• Another class, EventHandler, receives these events and changes the motors accordingly.

How do these classes communicate?

• Each runs on its own thread. • They pass messages over a shared,

synchronized queue.• This means events are handled approximately

in the order created, barring synchronization issues

(Bonus: What is a better / more granular / more responsive data structure than a regular queue, given events with different priorities?)

DIAGRAM

QuickTime™ and a decompressor

are needed to see this picture.

public static void main (String[] aArg) { Robot robot = new Robot(); SensorPort.S1. addSensorPortListener(robot); robot.moveForward();}

In Robot:public void moveForward() { Motor.A.setSpeed(20); Motor.B.setSpeed(20); while (!ts.isPressed()) { //ts instanceof TouchSensor Motor.A.forward(); Motor.B.forward(); } } //bonus - what part is NOT very event-driven here?

Code sample from Architecture 1

Code sample from Architecture 1 public void stateChanged(SensorPort port, int oldValue, int newValue)

{ //replace with diff values checking in oldValue, newValue //otherwise not very event-driven if (oldValue < 500 && newValue < 500) { Motor.A.stop();

Motor.B.stop(); Motor.A.setSpeed(20); Motor.B.setSpeed(20); Motor.A.backward(); Motor.B.backward(); Thread.sleep(100); Motor.A.stop(); Motor.B.stop(); Motor.A.forward(); Motor.B.backward(); Thread.sleep(250); Motor.A.stop(); Motor.B.stop(); moveForward(); }

Architecture 2 Codepublic class SynchronizedQueue<E> {

private final ArrayList<E> queue;public void push(E o) {

synchronized(queue) {queue.add(o);queue.notify();

} }public E pop() {

synchronized(queue) {while (queue.isEmpty()) {

queue.wait(); } return queue.remove(0);

} }

}

public void run() {while (true) {

if(ts.isPressed()) {queue.push(new RobotEvent(

RobotEventInt.BACKUP));} else {

queue.push(new RobotEvent( RobotEventInt.FORWARD));

}

try {Thread.sleep(200);

} catch (InterruptedException e) {System.out.println("Sensor interrupted");

}}

}

public void run() {while(true) {

RobotEventInt curr = queue.pop();if (curr.getName().equals(

RobotEventInt.FORWARD)) {

leftMotor.forward();rightMotor.forward();

} else if (curr.getName().equals( RobotEventInt.BACKUP))

{if (!leftMotor.isStopped() &&

!rightMotor.isStopped()) {

leftMotor.stop();rightMotor.stop();

}leftMotor.backward();rightMotor.backward();Thread.sleep(40);

}}

}

Interface Runnable

• One method:

public void run() {}

Add a Runnable implementor to a Thread, run Thread.start(), and the code in run() executes asynchronously.

RobotEvent

• Implements RobotEventInt, a collection of static String values (RobotEventInt.BACKUP) and one method, getName(), which should always be one of RobotEventInt’s static String values.

Architecture 2 Working Yet?

• Still working at it. Robot throws an error that indicates not all classes loaded, which print statements don’t seem to verify. Runs fine until queue.pop() in EventResponder.

Lessons Learned

• If you learn about deprecated classes in a library from an online forum and NOT from the library’s API, try to switch libraries.

• (Also, if you shutdown and accidentally suspend an Ubuntu laptop and then power-cycle it, some perfect storm wipes out /sys and some of /sbin)

• (On a related note, Dropbox is great for backing up your work)

top related