All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lejos.robotics.subsumption.Arbitrator Maven / Gradle / Ivy

Go to download

leJOS (pronounced like the Spanish word "lejos" for "far") is a tiny Java Virtual Machine. In 2013 it was ported to the LEGO EV3 brick.

The newest version!
package lejos.robotics.subsumption;


/**
 *An  Arbitrator object  manages a behavior control system by starting and stopping individual  behaviors  
 *
by the calling the action() and suppress() methods on them. *
These Behavior objects are stored in an array, in order of increasing priority. *
Arbitrator has three major responsibilities:
* 1. Determine the highest priority behavior among those that returns true to takeControl() .
* 2. Suppress the active behavior if its priority is less than highest * priority. These two taska are performed the Arbitrator's internal Monitor thread.
* 3. When the action() method exits, call action() on the Behavior of highest priority.
* This task is performed by the Arbitrator main thread. *
The Arbitrator assumes that a Behavior is no longer active when action() exits, *
therefore it will only call suppress() on the active Behavior i.e. whose action() method is running. *
It can make consecutive calls of action() on the same Behavior. *
Requirements for a Behavior: *
When suppress() is called, terminate action() immediately. *
When action() exits, the robot is in a safe state (e.g. motors stopped) *
When the behavior should take control, the takeControl() should continue to return true *
until its action starts. *
After your code instantiates the Arbitrator, it should call go() to start it running. *
* @see Behavior * @author Roger Glassey */ public class Arbitrator { private final int NONE = -1; private Behavior[] _behavior; // highest priority behavior that wants control ; set by start() used by monitor private int _highestPriority = NONE; private int _active = NONE; // active behavior; set by monitor, used by start(); private boolean _returnWhenInactive; public boolean keepRunning = true; /** * Monitor is an inner class. It polls the behavior array to find the behavior of hightst * priority. If higher than the active behavior, it calls active.suppress() */ private Monitor monitor; /** * Allocates an Arbitrator object and initializes it with an array of * Behavior objects. The index of a behavior in this array is its priority level, so * the behavior of the largest index has the highest the priority level. * The behaviors in an Arbitrator can not * be changed once the arbitrator is initialized.
* NOTE: Once the Arbitrator is initialized, the method go() must be * called to begin the arbitration. * @param behaviorList an array of Behavior objects. * @param returnWhenInactive if true, the go() method returns when no Behavior is active. */ public Arbitrator(Behavior[] behaviorList, boolean returnWhenInactive) { _behavior = behaviorList; _returnWhenInactive = returnWhenInactive; monitor = new Monitor(); monitor.setDaemon(true); System.out.println("Arbitrator created"); } /** * Same as Arbitrator(behaviorList, false) Arbitrator start() never exits * @param behaviorList An array of Behavior objects. */ public Arbitrator(Behavior[] behaviorList) { this(behaviorList, false); } /** * This method starts the arbitration of Behaviors and runs an endless loop.
* Note: Arbitrator does not run in a separate thread. The go() * method will not return unless
1. no action() method is running and *
2. no behavior takeControl() returns true and *
3. the returnWhenInacative flag is true, */ public void go() { monitor.start(); while (_highestPriority == NONE) { Thread.yield();//wait for some behavior to take control } while (true) { synchronized (monitor) { if (_highestPriority > NONE) { _active = _highestPriority; } else if (_returnWhenInactive) {// no behavior wants to run monitor.more = false;//9 shut down monitor thread return; } }// monitor released before action is called if (_active != NONE) //_highestPrioirty could be NONE { _behavior[_active].action(); _active = NONE; // no active behavior at the moment } Thread.yield(); } } public void stop() { keepRunning = false; } /** * Finds the highest priority behavior that returns true to takeControl(); * If this priority is higher than the active behavior, it calls active.suppress(). */ private class Monitor extends Thread { boolean more = true; int maxPriority = _behavior.length - 1; public void run() { while (keepRunning) { //FIND HIGHEST PRIORITY BEHAVIOR THAT WANTS CONTROL synchronized (this) { _highestPriority = NONE; // -1 for (int i = maxPriority; i > _active; i--) // only behaviors with higher priority are interesting { if (_behavior[i].takeControl()) { _highestPriority = i; break; } } int active = _active; // local copy in case _active is set to NONE by the primary thread if (_active != NONE && _highestPriority > _active) { _behavior[active].suppress(); } }// end synchronize block - main thread can run now Thread.yield(); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy