import java.util.Iterator; /** *
* Implementation of IAgent to handle a simple flocking algorithm. *
* @author Michael Schuresko * @version %I%, %G% * @since 1.0 */ public class SimpleFlockingAgent implements ITreeAlgAgent // IAgent { double m_lfSpeedScale; double m_lfHeadingRate; public SimpleFlockingAgent() { m_lfSpeedScale = 1.0; m_lfHeadingRate = 0.1; } public SimpleFlockingAgent(double lfSpeed) { m_lfSpeedScale = lfSpeed; m_lfHeadingRate = 0.1; } /** * Set function for parameter to determine speed of robots */ public void setSpeed(double lfSpeed) { m_lfSpeedScale = lfSpeed; } /** * Sets rate of convergence of heading */ public void setHeadingRage(double lfRate) { m_lfHeadingRate = lfRate; } public boolean checkStateValidity(StateBundle state) { return (state != null && state.getControlFunc() != null); } /** * inner class used for flocking state */ public static class SimpFlockState implements ILogicVarBundle { double m_lfHeading; int m_nId; public SimpFlockState() { m_nId = -1; m_lfHeading = Math.PI*(2.0*Math.random()-1.0); } public SimpFlockState(double lfHeading) { m_nId = -1; m_lfHeading = lfHeading; } public SimpFlockState(SimpFlockState src) { m_nId = src.m_nId; m_lfHeading = src.m_lfHeading; } public void init() { m_lfHeading = Math.PI*(2.0*Math.random()-1.0); } /** * makes a copy and returns it */ public SimpFlockState makeCopy() { return new SimpFlockState(this); } public Integer getIntVar(Object refObject) { return null;} public boolean insertIntVar(Object refObject, int nValue) {return false;} public Boolean getBoolVar(Object refObject) {return null;} public boolean insertBoolVar(Object refObject, boolean bValue) {return false;} /** * Removes any values indexed by refObject * @param refObject remove values associated with this. */ public void removeVar(Object refObject) { return; } /** * Gets unique Id of this agent */ public int getId() { return m_nId; } /** * Sets unique Id of this agent */ public void setId(int nId) { m_nId = nId; } public double getHeading() { return m_lfHeading; } public void setHeading(double lfHeading) {m_lfHeading = lfHeading; } public double getHeadingDelta(double lfHead, double lfRate) { double lfDiff = lfHead - m_lfHeading; while(lfDiff >= Math.PI) { lfDiff -= 2.0*Math.PI; } while(lfDiff < -Math.PI) { lfDiff += 2.0*Math.PI; } return lfRate*lfDiff; } } /** * inner class used for flocking messages */ public class SimpFlockMsg implements IMsg { double m_lfHeading; void set(double lfHeading) { m_lfHeading = lfHeading; } public SimpFlockMsg() { set(0.0); } public SimpFlockMsg(double lfTheta) { set(lfTheta); } public SimpFlockMsg(SimpFlockMsg src) { set(src.m_lfHeading); } public SimpFlockMsg(SimpFlockState src) { set(src.getHeading()); } public SimpFlockMsg makeCopy() { return new SimpFlockMsg(this); } public double getHeading() { return m_lfHeading; } } /** *Given the state of an agent, and the channels * it can send messages on, push the next set of messages * onto the appropriate channels. * Channels are assumed to be modified by this operation. * One weakness of this signature is that it requires * programmer discipline not to look at the continuous state * of agents other then your neighbors.
* @param discreteState discrete component of agent state * @param arrLfStateCont global vector of continuous state * @param nIdxStateOffset offset into global state vector * corresonding to this agent. * @param channelsToSendOn Iterator containing objects of type * CommLink corresponding to channels to send messages * on (neighbor indices can be ascertained from channels). * @see CommLink for type handled by iterator */ public void getMsgs(ILogicVarBundle discreteState, IDiscreteDynamicsCallback dynCallback, double arrLfStateCont[], double lfCurrTime, int nIdxStateOffset, IteratorGiven the previous state of an agent, and the channels * to recieve messages from, recieve messages (destructively) * and return new state (non-destructively).
* @param statePrev previous state (do not modify) * @param arrLfStateCont vector of all continuous states (do not modify) * @param nIdxStateOffset offset into arrLfStateCont corresponding to * start of this agents continuous variables * @param channelsRecieveFrom iterator storing CommLink * classes corresponding incoming channels * @see CommLink for type handled by iterator * @return new discrete state of agent */ public StateBundle updateState(ILogicVarBundle statePrev, double arrLfStateCont[], double lfCurrTime, int nIdxStateOffset, IEnvironment env, Iterator