Download presentation
Presentation is loading. Please wait.
Published byKatherine Wilkinson Modified over 9 years ago
1
Event Driven Programming Minus the GUI Plus a Robot By Charlie Vick
2
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.
3
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
4
The old bot configuration
5
Current bot configuration
6
Architecture (part 1) Lejos library has a class, ‘SensorPort’ SensorPort.addSensorPortListener( SensorPortListener aListener) is a public method SensorPortListener: Interface, has one method: void stateChanged(SensorPort source, int oldValue, int newValue)
7
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
8
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.
9
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.
10
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?)
11
DIAGRAM
12
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
13
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(); }
14
Architecture 2 Code public class SynchronizedQueue { private final ArrayList 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); }
15
Architecture 2 code: SensorReader (note: ‘ts’ is a TouchSensor instance) 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"); }
16
Architecture 2 code: EventResponder’s run method. Both implement Runnable, an interface allowing them to run in separate Threads. Bonus: What is missing? 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); }
17
Interface Runnable One method: public void run() {} Add a Runnable implementor to a Thread, run Thread.start(), and the code in run() executes asynchronously.
18
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.
19
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.
20
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)
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.