0% found this document useful (0 votes)
6 views29 pages

Robotics - Lecture 5

Robotics - Lecture 5 (1)

Uploaded by

mohammed shakeel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views29 pages

Robotics - Lecture 5

Robotics - Lecture 5 (1)

Uploaded by

mohammed shakeel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

Robotics - Event Driven Programming

Francisco Ferreira, with slides mostly courtesy of Dave Cohen


Term 2, Academic Year 2023/2024
Computer Science, Royal Holloway, University of London

1
Behaviours, and Project Extras
First - more about good programming!

1
Feedback

int x; boolean t; x = 0; // WTF (that stands for what the fuzz)


for (x = 1; x <= 5; x = x + 1){mLeft.forward();
Delay.msDelay(173);} // WTF (three or four times)
NXTSoundSensor ss = new NXTSoundSensor(SensorPort.S3);
SampleProvider sp = ss.getDBAMode();
float[] samples = new float[1];
ss.fetchSample(samples, 0);
if (samples[0] > 0.50f) {
return(true);
else {
return (false);
} // BIG WTF

2
Feedback

final int FORWARD_TIME = 173;


final int SIDES = 4;

for (int side = 0; side < SIDES; side++){


mLeft.forward();
Thread.sleep(FORWARD_TIME);
}
NXTSoundSensor ss = new NXTSoundSensor(SensorPort.S3);
SampleProvider sp = ss.getDBAMode();
float[] samples = new float[1];
ss.fetchSample(samples, 0);
return samples[0] > 0.50f;

3
It’s Final

Naming Numbers
• Its nice to use words instead of having to type numbers.
• We should use Math.PI instead of remembering 3.141592654...
• Its better to use a name that you define once (like WHEEL_SIZE).
• When you change the wheels, you only have to change one line of code.
• Define constants just like other fields, but in UPPER CASE.
• Use Comments to help the reader (you in a week).
• Do not use static (global) objects!
Create them in a short main
Pass objects to the constructor of other classes.

4
Behaviours
The Rodney Brooks subsumption architecture
We have to manage complex robot behaviour
• We managed robot movement using the navigation stack
• Now we need to combine many simple tasks
• To make a robot that appears intelligent
• To make a robot that plans to achieve its goals
• Better than Threads: Who’s watching that Battery Voltage?

5
Subsumption

A guy with three active behaviours


• walking along (behaviour 1),
• eating (behaviour 2) and
• chatting (behaviour 3).
• . . . who falls over - arms shoot forwards (behavior 4 subsumption).

It is vitally important that behaviours subsume each other.

6
Subsumption architecture

Plants do not grow towards the sun.


• The hormone Auxin promotes growth.
• The hormone Auxin is denatured by sunlight.
• Plants have no intelligence.
• Behaviours just get triggered.
• Plant cells grow when not in sunlight.
• Responsive behaviours = Complexity.

7
Subsumption

A Group of behaviours is intelligence


• No central controller.
• Behaviours have conditions on which they become active.
• Behaviours control different activities.
• When active they do their thing.
• They are suppressed by higher level behaviours.

Do you remember the last time conditions made you touch your face/hair.

8
The Behaviour Stack: Subsumption in leJOS
An Arbitrator manages a list of Behavior objects.
• Loops forever asking each Behavior object whether it wants to takeControl.
• Runs the highest priority action method in its own thread.

WHILE TRUE:
// Build a list of waiting Behaviour actions
ASK each Behavior if it wants to takeControl.

IF no Behavior action is currently running THEN:


RUN highest priority waiting Behavior
ELSE IF there is a higher priority Behavior waiting
// Notice that we NEVER STOP a currently active Behaviour
CALL suppress on the currently running Behavior
9
The Behaviour Stack: Subsumption in leJOS
Subsumption - suppress and action run in different Threads
• CASE ONE: When a Behavior is running
and a higher priority Behavior needs to take over
. . . the Arbitrator keeps calling suppress
. . . eventually this running Behaviour will get the message (and stop)
• CASE TWO: When no Behavior is currently running
. . . the Arbitrator starts the highest priority waiting Behavior

The suppress method can be called any number of times (including none).
• If a Behavior has a short action then it can ignore suppress calls.
The action will finish in good time anyway.
• A long running action method must notice suppress.
The action method should finish early and exit gracefully. 10
Subsumption in leJOS: The Behavior interface

An Arbitrator manages a list of Behavior objects.


Every Behavior in leJOS must implement these three methods

• a boolean takeControl() that the Arbitrator calls to see if it wants control.


• an void action() that it wants to do when it has control.
• a void suppress() method the Arbitrator invokes to persuade the
Behavior to finish quickly and exit gracefully.

11
Understanding a Behavior

A Single Behavior responds to a certain set of conditions


• It deals with some problem (e.g. Battery Voltage)
• It just gets some appropriate task done (e.g. Turning Left, Going Home)

leJOS lets us create many Behavior objects and think about them separately
• We let an Arbitrator object organise them for us.
• Each Behavior takes control of the robot when it is active.
• It should respond nicely when the Arbitrator tells it to stop. . .
• . . . because another (more important) Behavior needs a turn.

12
Building a Behavior

Sharing is playing nicely


• We have a class for each type of Behavior that we need.
• A Behavior class may need access to the Pilot, or the Navigator or to
sensors.
• A Behavior class may need to access some state control object.
• It is fine to store the (shared) objects as local variables in your main method.
• Pass each (shared) object (as needed) into the constructor for a Behavior
object.

13
Building a Behavior continued

Sharing is playing nicely


• Each Behavior object stores (a reference to) the shared object in a
private static field.
• If only one Behavior needs to access an object then push the object down to a
(private static) field in that class.
• Construct and store objects as close as possible to where they are needed.

14
An example - Behaviour controlled driving

public class Driver {


public static void main(String[] args) {
MovePilot pilot = getPilot(MotorPort.A, MotorPort.B, 60, 29);
pilot.setLinearSpeed(200);
Behavior trundle = new Trundle(pilot);
Behavior escape = new Escape(pilot);
Arbitrator ab = new Arbitrator(new Behavior[] {trundle, escape});
ab.go(); // This never returns! It is a blocking call.
}
private static MovePilot getPilot(Port left, Port right, int diam, int offset) {
BaseRegulatedMotor mL = new EV3LargeRegulatedMotor(left);
Wheel wL = WheeledChassis.modelWheel(mL, diam).offset(-1 * offset);
BaseRegulatedMotor mR = new EV3LargeRegulatedMotor(right);
Wheel wR = WheeledChassis.modelWheel(mR, diam).offset(offset);
Wheel[] wheels = new Wheel[] {wR, wL};
Chassis chassis = new WheeledChassis(wheels, WheeledChassis.TYPE_DIFFERENTIAL);
return new MovePilot(chassis);
}
} 15
An example Behavior - Keep on Trucking

public class Trundle implements Behavior {


private MovePilot pilot;
Trundle(MovePilot p) {
this.pilot = p; // Save the (shared) pilot in a field
}
// Start trundling and return control immediately.
public void action() {
pilot.forward();
}
// Since action returns immediately this is probably never called
public void suppress() {}
// Is it my turn?
public boolean takeControl() {
return true; // Yeah - we are SO eager
}
}

16
An Example Behavior - Get Me Out of Here

public class Escape implements Behavior {


private MovePilot turner; // The passed in shared pilot
private EV3UltrasonicSensor us = new EV3UltrasonicSensor(SensorPort.S1);
private SampleProvider sp = us.getDistanceMode(); // This sensor will just be used by us
private Random rgen = new Random(); // just used by us (a new piece of Java?)
private float[] distance = new float[1]; // just used by us - clever name huh!
Trundle(MovePilot p) {
turner = p;
}
public void action() {
turner.travel(-50);
turner.rotate((2 * rgen.nextInt(2) - 1) * 30); // right or left 30 degrees at random.
}
public void suppress() { } // Not sensible to suppress this Behavior. Ignore suppress.
public boolean takeControl() { // Is it my turn?
sp.fetchSample(distance, 0);
return (distance[0] < 0.20f); // See how this is short, but still easy to read?
}
} 17
Project Extras and more advanced programming
State Based Behaviours

Your robot has to do one thing and then another


• The conditions for a Behavior may not just be sensors values
• Think of a game where you alternate moves.
• A button press could disable all of my move behaviours.
• Another button press makes them possible again.

Use a shared State object to disable behaviours


• (Only when state.getState() == 'M'). Behaviours: Move to Thing
• (Only when state.getState() == 'P'). Behaviours: Pick up Thing
• (Only when state.getState() == 'I'). Behaviours: Identify Thing
• (Only when state.getState() == 'H'). Behaviours: Take Thing Home

18
Sharing the State object: What sort of state am I in?
State is a kind of internal sensor - looking at the state of the robot
• Create a State class and then a State instance state in main.
• The state will record what the robot is trying to do.
• Share state with any Behaviour that depends on, or alters, the robot state.
• The State class can have a single char field with getters and setters.

public boolean takeControl() { // Check some condition


return ... && state.getState == 'P'; // AND it is our turn
}
public void action() { // Look for something
...
state.setState(`I'); // Got it! change to Identifying.
} 19
HARD: Using (shared) state for rising edge detection (separate claps)
public class State { // methods rather than a char field is better
private boolean waitingForRising = true;
public boolean isWaitingForRising() { return waitingForRising; }
public void setWaitingForRising(boolean b) { waitingForRising = b; }
}

// wait for a loud sound after a quiet one public class WFFall implements Behavior {
public class WFRise implements Behavior { private State sharedState;
private State sharedState; private float[] sound = new float[1];
private float[] sound = new float[1]; public boolean takeControl() {
public boolean takeControl() { if (sharedState.isWaitingForRising()) {
if (!sharedState.isWaitingForRising()) return false; return false;
sp.fetchSample(sound, 0); }
return (sound[0] > 0.5f); sp.fetchSample(sound, 0);
} return (sound[0] < 0.2f);
public void suppress() {} }
public void action(){ public void suppress() {}
// Do the "Heard a new clap" action public void action() {
sharedState.setWaitingForRising(false); sharedState.setWaitingForRising(true);
} // constructor and sp def'n not shown } // constructor and sp def'n not shown 20
States and Personality

Changing from one state of certainty to another


• We can control the flow of behaviours using a shared state.
• Drawing a state diagram is a very useful process.
• Groups of behaviours may be self-contained, e.g. behaviours for finding food.
• A robot appears to have a certain personality when doing these behaviours.
• Of course, different personalities can share some behaviours.
• We can make a table of which behaviours are possible in each personality.

21
Worrying Pitfalls

suppress must make action stop


• After calling an action method no other action can start until this one
finishes.
• Long running action methods that ignore calls to suppress break the system.
• suppress can set a field that is checked by action method, causing it to return.

Fast Methods
• If action never takes a long time then suppress can just return.
• suppress should always return quickly.
• suppress will be called multiple times if action takes a while to finish.

22
Extra Sensors, Extra Programs
Extra Sensors

The cyclingProfessor GitHub account


The Android app in the EV3Sensors repository, connects to a leJOS brick.
It does OpenCV image processing, continually finds QR codes and reads NFC tags.
The Readme.md in the repository tells you how to make this work.

• You can use it as a set of extra sensors for your brick.

The examples repository contains several interesting examples


The LejosExamples repository includes code for the leJOS end of EV3Sensors.
It also contains the (in progress) PCMapper program.

23
Self Test

Questions
1. Are you ready?

24

You might also like