package demo.helicopter; import java.text.*; // for class DecimalFormat import java.util.*; // for class Vector import mil.navy.nps.dis.*; // for class EntityStatePdu import mil.navy.nps.testing.*; // for MulticastPduSender import mil.navy.nps.util.*; import mil.navy.nps.disEnumerations.*; import mil.navy.nps.relate.*; import java.io.*; //========================================================= // Designed by Quay Jones // last update 2 June 2000 // // agents added by Mike Dickson and Kim Roddy 21 July 2000 //========================================================= /** * The referee monitors the execution of the simulation. It receives all state * PDUs, maintains each entities information, and performs the necessary actions * to update the visual simulation. It enforces the rules of the simulation, * awarding points as appropriate and reseting the simulation whenever a team * return the opposing teams' flag to it's homebase. The Referee directly * controls the state of the team flags. */ public class Referee extends Thread { /** * the interval between PDUs */ private float pduSendInterval; // time delay between pdus /** * Used for screen output format */ private DecimalFormat df; // pretty print screen output /** * Pdu to send entity state to VRML scene */ private EntityStatePdu redEspdu; /** * Pdu to send entity state to VRML scene */ private EntityStatePdu blueEspdu; /** * the connection to the network */ private BehaviorStreamBufferUDP behaviorStreamBuffer; // tie in to the network /** * Multi-cast IP Address of the simulation */ private String ipAddress; /** * port number for the simulation */ private int portNumber; /** * blue entity id */ private int blueId; /** * red entity id */ private int redId; /** * id of the red flag when a blue entity has possession of it */ private int RedFlagTakenByBlueId; /** * if of the blue flag when a red entity has possession of it */ private int BlueFlagTakenByRedId; /** * the number of wins for the blue team */ private int blueWins; /** * The number of wins for the red team */ private int redWins; /** * indicates if the red flag is in the blue team's possession */ private boolean redFlagTakenByBlue = false; /** * indicates of the blue flag is in the red team's possession */ private boolean blueFlagTakenByRed = false; /** * Indicates the 'running' status of the simulation */ private boolean playing = false; private ArticulationParameter redPoint; private ArticulationParameter redWinner; private ArticulationParameter bluePoint; private ArticulationParameter blueWinner; /** * detects collision between the entities and the terrain */ private static CollisionDetectionTerrainReader terrain; private double [] normalHeight; /** * default time-to-live of the PDU packets: set to the local campus default */ private static int timeToLive = 15; // default ttl convention is local campus /** * default for the sleep time beteen execution rounds */ private static int sleepTime = 0; /** * Inicates if the simulation is an RTP match */ private static boolean rtpMatch = false; /** * Used for debugging purposes to textually trace the executionof the simulation */ private static boolean traceCommandLineFlag = false; /** * PDU to send entity state to VRML scene */ private EntityStatePdu teamEspdu; /** * PDU sent to creat an entity */ private CreateEntityPdu cepdu; /** * PDU that contains only comments */ private CommentPdu cpdu; /** * PDU used for removing an entity */ private RemoveEntityPdu repdu; private DatumSpecification datum; private VariableDatum variableDatum; /** * the URL at which the geometry for an entity resides at */ private String geometryURL; /** * the 'byte' information for the geometry of an entity */ private byte geometryURLbyteArray[]; /** * the 'long' information for the geometry of an entity */ private long geometryURLlongArray[]; /** * used to assign IDs to each team */ private long teamid; /** * maximum meters from target for pickup; return range is 2 times larger */ private double maxPermittedDistanceForPickup = 50.0; /** * the x-coordinate for the blue flag's capture point. * corrsponds to the red flag's starting point, AKA the red team 'homebase' */ private double xCaptureBlue = -5000; // The blue flag capture point is the red flag's start point /** * the y-coordinate for the blue flag's capture point */ private double yCaptureBlue = 2000; /** * the z-coordinate for the blue flag's capture point */ private double zCaptureBlue = 39.8; /** * the x-coordinate for the red flag's capture point. * corrsponds to the blue flag's starting point, AKA the blue team 'homebase' */ private double xCaptureRed = 0; // The red flag capture point is the blue flag's start point /** * the y-coordinate for the red flag's capture point */ private double yCaptureRed = 2000; /** * the z-coordinate for the red flag's capture point */ private double zCaptureRed = 35.8; private static boolean winSleep = false; // private double CapturedFlagSecondsDelay = 0.5; // private double UncapturedFlagSecondsDelay = 5.0; /** * the longest delay between 'red flag' PDU transmissions, occurs when * the flag is not moving */ private double RedPduSecondsDelay = 5.0; /** * the longest delay between 'blue flag' PDU transmissions, occurs when * the flag is not moving */ private double BluePduSecondsDelay = 5.0; /** * default simulation sleep time */ private int sleepTimeMilliSeconds = 50; //****************************************************************************** //agent stuff added here /** * the list of the agents on the 'red' team */ private Hashtable redAgents; /** * the list of the agents on the 'blue' team */ private Hashtable blueAgents; /** * When DEBUG is true, console text messages * trace the internals of script operation. */ private boolean DEBUG = false; // diagnostic messages on (true) or off (false) /** * Access DEBUG trace variable. */ public boolean getDEBUG () { debug ("getDEBUG " + DEBUG); return DEBUG; } /** * Modify DEBUG trace variable. */ public void setDEBUG (boolean pDEBUG) { DEBUG = pDEBUG; trace ("setDEBUG " + pDEBUG); // send confirming VRML console trace message } /** * Debugging output routine. Pass in a string, and it gets printed out on the console. * You can pass in strings such as "foo " + bar.getName(). * Text output appears in the Java Console (CosmoPlayer browser) * or in the VRML console (WorldView browser). */ protected void debug (String pDiagnostic) { if (DEBUG) System.out.println("Referee " + pDiagnostic); } /** * Guaranteed trace output routine. Pass in a string, and it gets printed out on the console. * You can pass in strings such as "foo " + bar.getName(). * Text output appears in the Java Console (CosmoPlayer browser) * or in the VRML console (WorldView browser). *
* Can't be static
or all entities look the same.
*/
protected void trace (String pDiagnostic)
{
System.out.println(" Referee: " + pDiagnostic);
}
//=============================================================================================
// Constructors & Start
//=============================================================================================
/**
* Constructor. Instantiates the referee entity that monotors the simulation.
*/
public Referee() // constructor
{
setPlaying(true);
pduSendInterval = 0.5f; // approx 500 ms between pdu sends
df = new DecimalFormat("###.00");
cepdu = new CreateEntityPdu(); // instantiate a cepdu for announcing the creation of an entity
cepdu.setRtpHeaderEnabled(true);
cpdu = new CommentPdu(); // instantiate a cpdu, used to store the URL address
cpdu.setRtpHeaderEnabled(true);
repdu = new RemoveEntityPdu(); // instantiate a repdu, used to remove an entity
repdu.setRtpHeaderEnabled(true);
teamid = 97;
cepdu.setRequestID(teamid);
repdu.setRequestID(teamid);
datum = new DatumSpecification();
variableDatum = new VariableDatum();
geometryURLbyteArray = new byte[120];
geometryURLlongArray = new long[120];
geometryURL = new String ("http://www.web3D.org/WorkingGroups/vrtp/dis-java-vrml/demo/helicopter/helo_main.wrl"); // place URL address here
teamEspdu = new EntityStatePdu();
teamEspdu.setRtpHeaderEnabled(true);
blueEspdu = new EntityStatePdu(); // instantiate an espdu, used as a data structure
blueEspdu.setRtpHeaderEnabled(rtpMatch);
redEspdu = new EntityStatePdu(); // instantiate an espdu, used as a data structure
redEspdu.setRtpHeaderEnabled(rtpMatch);
short[] TeamentityID = new short[3];
TeamentityID[0] = 0;
TeamentityID[1] = 1;
TeamentityID[2] = 97;
teamEspdu.setEntityID(TeamentityID[0], TeamentityID[1], TeamentityID[2]); // set entity id triplet
blueEspdu.setEntityLocationX(xCaptureRed); // set starting location into espdu, all other
blueEspdu.setEntityLocationY(yCaptureRed); // initial quantities are set to zero when the
blueEspdu.setEntityLocationZ(zCaptureRed); // espdu is constructed in the dis-java-vrml code
blueEspdu.setEntityAppearance(0);
short[] BlueentityID = new short[3]; // create entity id triplet for espdu & fire pdu
BlueentityID[0] = 0;
BlueentityID[1] = 1;
BlueentityID[2] = 99;
blueEspdu.setEntityID(BlueentityID[0], BlueentityID[1], BlueentityID[2]); // set entity id triplet
redEspdu.setEntityLocationX(xCaptureBlue); // set starting location into espdu, all other
redEspdu.setEntityLocationY(yCaptureBlue); // initial quantities are set to zero when the
redEspdu.setEntityLocationZ(zCaptureBlue); // espdu is constructed in the dis-java-vrml code
redEspdu.setEntityAppearance(0);
short[] RedentityID = new short[3]; // create entity id triplet for espdu & fire pdu
RedentityID[0] = 0;
RedentityID[1] = 1;
RedentityID[2] = 98;
redEspdu.setEntityID(RedentityID[0], RedentityID[1], RedentityID[2]); // set entity id triplet
geometryURLbyteArray = geometryURL.getBytes();
variableDatum.setVariableDatumID(1);
variableDatum.setVariableDatumLength(120);
for (int counter = 0; counter < geometryURLbyteArray.length ; counter++)
{
geometryURLlongArray[counter] = (long) geometryURLbyteArray[counter];
}
variableDatum.setVariableDatumValue(geometryURLlongArray);
datum.addVariableDatum(variableDatum); // add URL address as variable datum value
cpdu.setDatumSpecification(datum); ///////////////////////////////////////////////////////////////////////////
cpdu.setOriginatingEntityID(teamEspdu.getEntityID());
cpdu.setExemplar(cpdu); // set cpdu fields
cepdu.setOriginatingEntityID(teamEspdu.getEntityID());
cepdu.setExemplar(cepdu); // set cepdu fields
repdu.setOriginatingEntityID(teamEspdu.getEntityID());
repdu.setExemplar(repdu); // set repdu fields
redEspdu.setMarking ("Red Flag");
blueEspdu.setMarking("Blue Flag");
blueWins = 0;
redWins = 0;
redPoint = new ArticulationParameter();
redWinner = new ArticulationParameter();
bluePoint = new ArticulationParameter();
blueWinner = new ArticulationParameter();
// redPoint.setParameterTypeDesignator(ParameterTypeDesignatorField.ARTICULATEDPART); // 0
// redPoint.setChangeIndicator(0); // sequentially increment with each change in value
// redPoint.setArticulationAttachmentID (0); // attached to main entity, not multiply articulated
// redPoint.setParameterType (4096 + 15); // Primary turret number 1 + Rotation
redPoint.setParameterValue((double)redWins); // double
redWinner.setParameterValue((double)redWins); // double
bluePoint.setParameterValue((double)blueWins); // double
blueWinner.setParameterValue((double)blueWins); // double
redEspdu.addArticulationParameter(redPoint);
redEspdu.addArticulationParameter(redWinner);
blueEspdu.addArticulationParameter(bluePoint);
blueEspdu.addArticulationParameter(blueWinner);
// EntityID temp = redEspdu.getEntityID();
// espdu.setMarking("R71-630" + temp.getEntityID());
// instantiate a BehaviorStreamBuffer to handle the network interface, instantiate with
// the multicast IP address and port
ipAddress = "224.2.181.145";
portNumber = 62040;
behaviorStreamBuffer = new BehaviorStreamBufferUDP (ipAddress, portNumber);
Thread pduReader = new Thread(behaviorStreamBuffer);
pduReader.start();
for (int sleepSecondsCount = 0; sleepSecondsCount < 10; sleepSecondsCount++)
{
try
{
Thread.sleep( 1000 ); // ms
}
catch (InterruptedException ie)
{
System.out.println ("fitful sleep: " + ie);
}
if (sleepSecondsCount == 0) System.out.print("Listening 10 seconds for other Referee");
System.out.print(".");
java.util.Vector pdus = behaviorStreamBuffer.receivedPdus();
for (Enumeration enum = pdus.elements(); enum.hasMoreElements(); )
{
ProtocolDataUnit tempPdu = (ProtocolDataUnit) enum.nextElement();
// must check for proper type first
if (tempPdu.getPduType().shortValue() == PduTypeField.ENTITYSTATE)
{
EntityStatePdu tempEntityPdu = (EntityStatePdu) tempPdu;
UnsignedByte pduType = tempPdu.getPduType();
if (pduType.shortValue() == PduTypeField.ENTITYSTATE) //check for red, blue flags
{
if (tempEntityPdu.getEntityID().getEntityID().intValue() == 98 ||
tempEntityPdu.getEntityID().getEntityID().intValue() == 99)
{
System.out.println("Other Referee heard, shutting down now.");
stopRun();
System.exit(0);
}
}
else trace ("non-ESPDU heard, ignoring...");
}
}
}
System.out.println();
System.out.println("No other Referee heard, starting up!");
// read in Fort Irwin Terrain file
terrain = new CollisionDetectionTerrainReader();
terrain.parseFile();
normalHeight = new double [4];
System.out.println("sending CreateEntity PDU...");
behaviorStreamBuffer.sendPdu(cepdu.getExemplar(), ipAddress, portNumber); // send cepdu
System.out.println("sending Comment PDU with URL...");
behaviorStreamBuffer.sendPdu(cpdu.getExemplar(), ipAddress, portNumber); // send cpdu
behaviorStreamBuffer.setTimeToLive (timeToLive);
if (traceCommandLineFlag) behaviorStreamBuffer.setDEBUG(traceCommandLineFlag);
//***********************************************************************************************
//agent stuff added here
redAgents = new Hashtable();
blueAgents = new Hashtable();
} // end constructor
//====================================================================
/**
* Called to begins the Referee thread. initiates the sending of PDUs
*/
public void run() // start sending espdus, called from TestFrame.java
{
startPlaying(); // calls flying which is an infinite espdu-sending loop
}
//=============================================================================================
// Properties
//=============================================================================================
/**
* Used to toggle the 'playing' boolean. True = the simulation is running
*
* @param boolean setValue The new 'playing' status
* @return void
*/
public void setPlaying (boolean setValue)
{
playing = setValue;
}
//=============================================================================================
// Utility Methods
//=============================================================================================
/**
* Called to initiate the running of the simulation.
*
* @return void
*/
public void startPlaying()
{
int RedSleepCount = 0; // each pulse is 50 ms sleep
int BlueSleepCount = 0;
redEspdu.makeTimestampCurrent();
behaviorStreamBuffer.sendPdu(redEspdu, ipAddress, portNumber);
System.out.print ("send initial red Pdu. ");
blueEspdu.makeTimestampCurrent();
behaviorStreamBuffer.sendPdu(blueEspdu, ipAddress, portNumber);
System.out.println("send initial blue pdu.");
while(playing) // loops until mother thread exits thus killing this thread
{
collectPdus();
checkForVictory();
RedSleepCount++;
if ( RedSleepCount*sleepTimeMilliSeconds >= RedPduSecondsDelay * 1000.0) // typically ~5 sec keepAlive; timer would be better!
{
RedSleepCount=0;
if ((redFlagTakenByBlue == false) && (winSleep == false))
{
redEspdu.makeTimestampCurrent();
behaviorStreamBuffer.sendPdu(redEspdu, ipAddress, portNumber);
System.out.print("red keepAlive PDU sent ");
}
else System.out.print("redFlagTakenByBlue Team... ");
}
BlueSleepCount++;
if (BlueSleepCount*sleepTimeMilliSeconds >= BluePduSecondsDelay * 1000.0) // typically ~5 sec keepAlive; timer would be better!
{
BlueSleepCount=0;
if ((blueFlagTakenByRed == false) && (winSleep == false))
{
blueEspdu.makeTimestampCurrent();
behaviorStreamBuffer.sendPdu(blueEspdu, ipAddress, portNumber);
System.out.println("blue keepAlive PDU sent");
}
else System.out.println("blueFlagTakenByRed Team...");
}
try{
Thread.sleep(sleepTimeMilliSeconds); // put thread to sleep
}
catch(InterruptedException ite){
ite.printStackTrace();
}
// System.out.print("\n\nBlue Position ==> ("
// + df.format(blueEspdu.getEntityLocationX()) + ", "
// + df.format(blueEspdu.getEntityLocationY()) + ", "
// + df.format(blueEspdu.getEntityLocationZ()) + ")");
} // end while
} // end startPlaying()
/**
* Terminates the behaviorSreamBuffer
*
* @return void
*/
public void stopRun()
{
behaviorStreamBuffer.shutdown ();
}
//=============================================================================================
// Button Methods - These methods are all called by TestFrame.java
//=============================================================================================
/**
* Resets the simulation for another run
*
* @return void
*/
public void reset()
{
redPoint.setParameterValue(0.0f); // double
bluePoint.setParameterValue(0.0f); // double
redEspdu.setEntityLocationX(xCaptureBlue);
redEspdu.setEntityLocationY(yCaptureBlue);
redEspdu.setEntityLocationZ(zCaptureBlue);
blueEspdu.setEntityLocationX(xCaptureRed);
blueEspdu.setEntityLocationY(yCaptureRed);
blueEspdu.setEntityLocationZ(zCaptureRed);
redEspdu.setEntityLinearVelocityX(0.0f);
redEspdu.setEntityLinearVelocityY(0.0f);
redEspdu.setEntityLinearVelocityZ(0.0f);
blueEspdu.setEntityLinearVelocityX(0.0f);
blueEspdu.setEntityLinearVelocityY(0.0f);
blueEspdu.setEntityLinearVelocityZ(0.0f);
redEspdu.setEntityAngularVelocityX(0.0f);
redEspdu.setEntityAngularVelocityY(0.0f);
redEspdu.setEntityAngularVelocityZ(0.0f);
blueEspdu.setEntityAngularVelocityX(0.0f);
blueEspdu.setEntityAngularVelocityY(0.0f);
blueEspdu.setEntityAngularVelocityZ(0.0f);
redEspdu.setEntityLinearAccelerationX(0.0f);
redEspdu.setEntityLinearAccelerationY(0.0f);
redEspdu.setEntityLinearAccelerationZ(0.0f);
blueEspdu.setEntityLinearAccelerationX(0.0f);
blueEspdu.setEntityLinearAccelerationY(0.0f);
blueEspdu.setEntityLinearAccelerationZ(0.0f);
blueFlagTakenByRed = false;
redFlagTakenByBlue = false;
BlueFlagTakenByRedId = 01;
RedFlagTakenByBlueId = 01;
redWins = 0;
redPoint.setParameterValue(1.0f); // double
redWinner.setParameterValue((double)redWins); // double
blueWins = 0;
bluePoint.setParameterValue(1.0f); // double
blueWinner.setParameterValue((double)blueWins); // double
redEspdu.makeTimestampCurrent();
behaviorStreamBuffer.sendPdu(redEspdu, ipAddress, portNumber);
System.out.println("reset: sent red pdu");
blueEspdu.makeTimestampCurrent();
behaviorStreamBuffer.sendPdu(blueEspdu, ipAddress, portNumber);
System.out.println("reset: sent blue pdu");
playing = true;
System.out.println("\n\nRed Position ==> ("
+ df.format(redEspdu.getEntityLocationX()) + ", "
+ df.format(redEspdu.getEntityLocationY()) + ", "
+ df.format(redEspdu.getEntityLocationZ()) + ")");
System.out.println();
System.out.println("Blue Position ==> ("
+ df.format(blueEspdu.getEntityLocationX()) + ", "
+ df.format(blueEspdu.getEntityLocationY()) + ", "
+ df.format(blueEspdu.getEntityLocationZ()) + ")");
System.out.println();
System.out.println("sending RemoveEntity PDU...");
behaviorStreamBuffer.sendPdu(repdu.getExemplar(), ipAddress, portNumber); // send notification to remove entity
} // end reset()
//=============================================================================================
// Kill Determination Methods
//=============================================================================================
/**
* Called when the red flag is released by a blue entity
*
* @return void
*/
public void redReleaseFlag(){
RedFlagTakenByBlueId = 01;
// get normal and height at current terrain position
terrain.getNormalHeight(redEspdu.getEntityLocationX(), redEspdu.getEntityLocationY(), normalHeight);
redEspdu.setEntityLocationZ(normalHeight[3]); //mls
redEspdu.setEntityLinearVelocityX(0.0f);
redEspdu.setEntityLinearVelocityY(0.0f);
redEspdu.setEntityLinearVelocityZ(0.0f);
redEspdu.setEntityAngularVelocityX(0.0f);
redEspdu.setEntityAngularVelocityY(0.0f);
redEspdu.setEntityAngularVelocityZ(0.0f);
redEspdu.setEntityLinearAccelerationX(0.0f);
redEspdu.setEntityLinearAccelerationY(0.0f);
redEspdu.setEntityLinearAccelerationZ(0.0f);
redEspdu.makeTimestampCurrent();
behaviorStreamBuffer.sendPdu(redEspdu, ipAddress, portNumber);
/*
try{
Thread.sleep(4500);// put thread to sleep for 250 ms, thus when
} // end try // 50ms) is added the pdu send interval will
catch(InterruptedException ite){
ite.printStackTrace();
} // end catch
*/
redFlagTakenByBlue = false;
}//end releaseFlag
/**
* Called when the blue flag is released by a 'red' entity
*
* @return void
*/
public void blueReleaseFlag()
{
BlueFlagTakenByRedId = 01;
// get normal and height at current terrain position
terrain.getNormalHeight(blueEspdu.getEntityLocationX(), blueEspdu.getEntityLocationY(), normalHeight);
blueEspdu.setEntityLocationZ(normalHeight[3]); //mls
blueEspdu.setEntityLinearVelocityX(0.0f);
blueEspdu.setEntityLinearVelocityY(0.0f);
blueEspdu.setEntityLinearVelocityZ(0.0f);
blueEspdu.setEntityAngularVelocityX(0.0f);
blueEspdu.setEntityAngularVelocityY(0.0f);
blueEspdu.setEntityAngularVelocityZ(0.0f);
blueEspdu.setEntityLinearAccelerationX(0.0f);
blueEspdu.setEntityLinearAccelerationY(0.0f);
blueEspdu.setEntityLinearAccelerationZ(0.0f);
blueEspdu.makeTimestampCurrent();
behaviorStreamBuffer.sendPdu(blueEspdu, ipAddress, portNumber);
/*
try{
Thread.sleep(4500);
} // end try
catch(InterruptedException ite){
ite.printStackTrace();
} // end catch
*/
blueFlagTakenByRed = false;
}//end releaseFlag
/**
* Visually updates the current information for any 'red' entity, based upon the
* given PDU
*
* @param EntityStatePdu vehicle the PDU containing the new information
* @return void
*/
public void moveRed(EntityStatePdu vehicle)
{
redEspdu.setEntityLocationX(vehicle.getEntityLocationX());
redEspdu.setEntityLocationY(vehicle.getEntityLocationY());
redEspdu.setEntityLocationZ(vehicle.getEntityLocationZ());
redEspdu.setEntityLinearVelocityX(vehicle.getEntityLinearVelocityX());
redEspdu.setEntityLinearVelocityY(vehicle.getEntityLinearVelocityY());
redEspdu.setEntityLinearVelocityZ(vehicle.getEntityLinearVelocityZ());
redEspdu.setEntityAngularVelocity(vehicle.getEntityAngularVelocity());
redEspdu.setEntityLinearAcceleration(vehicle.getEntityLinearAcceleration());
redEspdu.setTimestamp(vehicle.getTimestamp());
System.out.println("sending Red Flag PDU");
behaviorStreamBuffer.sendPdu(redEspdu, ipAddress, portNumber);
} //end moveRed
/**
* Visually updates the current information for any 'blue' entity, based upon
* the given PDU
*
* @param EntityStatePdu vehicle the PDU containing the new information
* @return void
*/
public void moveBlue(EntityStatePdu vehicle)
{
blueEspdu.setEntityLocationX(vehicle.getEntityLocationX());
blueEspdu.setEntityLocationY(vehicle.getEntityLocationY());
blueEspdu.setEntityLocationZ(vehicle.getEntityLocationZ());
blueEspdu.setEntityLinearVelocityX(vehicle.getEntityLinearVelocityX());
blueEspdu.setEntityLinearVelocityY(vehicle.getEntityLinearVelocityY());
blueEspdu.setEntityLinearVelocityZ(vehicle.getEntityLinearVelocityZ());
blueEspdu.setEntityAngularVelocity(vehicle.getEntityAngularVelocity());
blueEspdu.setEntityLinearAcceleration(vehicle.getEntityLinearAcceleration());
blueEspdu.setTimestamp(vehicle.getTimestamp());
System.out.println("sending Blue Flag PDU");
behaviorStreamBuffer.sendPdu(blueEspdu, ipAddress, portNumber);
} //end moveBlue
/**
* Collects the incoming PDUs and performs the appropriate updates
*
* @return void
*/
public void collectPdus(){
// System.out.println("\nEntering collectFirePdus()");
Vector entityPdus = new Vector();
Vector pdus = behaviorStreamBuffer.receivedPdus();
// System.out.println("\n# of Pdus in the Vector = " + pdus.size());
for (Enumeration enum = pdus.elements(); enum.hasMoreElements();)
{
ProtocolDataUnit tempPdu = (ProtocolDataUnit)enum.nextElement();
UnsignedByte pduType = tempPdu.getPduType();
double xFlagRed = redEspdu.getEntityLocationX();
double yFlagRed = redEspdu.getEntityLocationY();
double zFlagRed = redEspdu.getEntityLocationZ();
double xFlagBlue = blueEspdu.getEntityLocationX();
double yFlagBlue = blueEspdu.getEntityLocationY();
double zFlagBlue = blueEspdu.getEntityLocationZ();
if (pduType.shortValue() == PduTypeField.ENTITYSTATE)
{
//System.out.println("Receive an entity Pdu");
EntityID mover = ((EntityStatePdu)tempPdu).getEntityID();
if (redFlagTakenByBlue == false)
{
checkForPickupRed((EntityStatePdu)tempPdu);
}
if (blueFlagTakenByRed == false)
{
checkForPickupBlue((EntityStatePdu)tempPdu);
}
// see if blue/red dropped it or returned to base...
double xCarrier = ((EntityStatePdu)tempPdu).getEntityLocationX();
double yCarrier = ((EntityStatePdu)tempPdu).getEntityLocationY();
double zCarrier = ((EntityStatePdu)tempPdu).getEntityLocationZ();
double horizontalRange;
if (redFlagTakenByBlue == true && mover.getEntityID().intValue() == RedFlagTakenByBlueId)
{
horizontalRange = Math.sqrt((xCarrier-xFlagRed)*(xCarrier-xFlagRed) +
(yCarrier-yFlagRed)*(yCarrier-yFlagRed));
if ((horizontalRange > 8 * maxPermittedDistanceForPickup) ||
(zCarrier - zFlagRed > 8 * maxPermittedDistanceForPickup))
{
redReleaseFlag ();
System.out.println("Releasing red flag");
}
else
{
// System.out.println("Moving red flag with entity " + mover.getEntityID().intValue());
moveRed((EntityStatePdu)tempPdu);
}
}
if (blueFlagTakenByRed == true && mover.getEntityID().intValue() == BlueFlagTakenByRedId)
{
horizontalRange = Math.sqrt((xCarrier-xFlagBlue)*(xCarrier-xFlagBlue) +
(yCarrier-yFlagBlue)*(yCarrier-yFlagBlue));
if ((horizontalRange > 8 * maxPermittedDistanceForPickup) ||
(zCarrier - zFlagBlue > 8 * maxPermittedDistanceForPickup))
{
blueReleaseFlag ();
System.out.println("Releasing blue flag");
}
else
{
// System.out.println("Moving blue flag with entity " + mover.getEntityID().intValue());
moveBlue((EntityStatePdu)tempPdu);
}
}//end if
//agent stuff added here, we're using the forceID data field in the
//EntityStatePdu to signify that the espdu was sent by an agent
EntityStatePdu agentPdu = (EntityStatePdu)tempPdu;
UnsignedByte forceID = agentPdu.getForceID();
if ( forceID.intValue() > 0 )//we got use an agent!!
{
runAgents(agentPdu);
}
} //end if
else if (pduType.shortValue() == PduTypeField.COLLISION)
{
//System.out.println("Receive a collision Pdu");
EntityID collided = ((CollisionPdu)tempPdu).getIssuingEntityID();
if (redFlagTakenByBlue == true)
{
if (collided.getEntityID().intValue() == RedFlagTakenByBlueId)
{
redReleaseFlag();
System.out.println("Releasing red flag");
}
}//end if
if (blueFlagTakenByRed == true)
{
if (collided.getEntityID().intValue() == BlueFlagTakenByRedId)
{
blueReleaseFlag();
System.out.println("Releasing blue flag");
}
}//end if
} //end else if
else if (pduType.shortValue() == PduTypeField.DETONATION)
{
//System.out.println("Receive a collision Pdu");
EntityID detonated = ((DetonationPdu)tempPdu).getTargetEntityID();
if (redFlagTakenByBlue == true)
{
if (detonated.getEntityID().intValue() == RedFlagTakenByBlueId)
{
System.out.println("Releasing red flag");
redReleaseFlag();
}
}//end if
if (blueFlagTakenByRed == true)
{
if (detonated.getEntityID().intValue() == BlueFlagTakenByRedId)
{
blueReleaseFlag();
System.out.println("Releasing blue flag");
}
}//end if
} //end else if
else if (pduType.shortValue() == PduTypeField.DATA)
{
//do nothing
} //end else if
// Dave stuff here testing for a ReceiverPdu
else if (pduType.shortValue() == PduTypeField.RECEIVER)
{
ReceiverPdu received = (ReceiverPdu)tempPdu;
//System.out.println("In referee, received a receiver PDU, receiver power = " + received.getReceiverPower());
} //end else if
} // end for
} // end collectPdus()
/**
* Determines if the given PDu is from a 'blue' entity. If it is, this method
* checks to see if the entity is 'close enough' to the 'red' flag to consider
* it 'picked-up'
*
* @param EntityStatePdu vehicle the PDU to check
* @return void
*/
public void checkForPickupRed(EntityStatePdu vehicle){
// if target vehicle is part of the *Blue* team continue
if (((vehicle.getEntityID().getEntityID().intValue() >= 30 ) &&
(vehicle.getEntityID().getEntityID().intValue() < 40 )) ||
((vehicle.getEntityID().getEntityID().intValue() > 400 ) &&
(vehicle.getEntityID().getEntityID().intValue() < 406 )))
{
WorldCoordinate carrierLocation = vehicle.getEntityLocation();
double xFlagRed = redEspdu.getEntityLocationX(); // This is the entities
double yFlagRed = redEspdu.getEntityLocationY(); // current location
double zFlagRed = redEspdu.getEntityLocationZ();
double xCarrier = carrierLocation.getX(); // The position of the potential
double yCarrier = carrierLocation.getY(); // carrier
double zCarrier = carrierLocation.getZ();
double horizontalRange =
Math.sqrt((xCarrier-xFlagRed)*(xCarrier-xFlagRed) +
(yCarrier-yFlagRed)*(yCarrier-yFlagRed));
if ((horizontalRange <= maxPermittedDistanceForPickup) &&
(zCarrier - zFlagRed <= maxPermittedDistanceForPickup)) {
RedFlagTakenByBlueId = vehicle.getEntityID().getEntityID().intValue();
redFlagTakenByBlue = true;
}//end if
}//end if
} // end checkForPickupRed()
/**
* Determines if the given PDU is from a 'red' entity. If it is, this method
* checks to see if the entity is 'close enough' to the 'blue' flag to consider
* it 'picked-up'
*
* @param EntityStatePdu vehicle the PDU to check
* @return void
*/
public void checkForPickupBlue(EntityStatePdu vehicle){
// if target vehicle is part of the *Red* team continue
if ((vehicle.getEntityID().getEntityID().intValue() >= 20) &&
(vehicle.getEntityID().getEntityID().intValue() < 30))
{
WorldCoordinate carrierLocation = vehicle.getEntityLocation();
double xFlagBlue = blueEspdu.getEntityLocationX(); // This is the entities
double yFlagBlue = blueEspdu.getEntityLocationY(); // current location
double zFlagBlue = blueEspdu.getEntityLocationZ();
double xCarrier = carrierLocation.getX(); // The position the projectile
double yCarrier = carrierLocation.getY(); // was launched from
double zCarrier = carrierLocation.getZ();
double horizontalRange =
Math.sqrt((xCarrier-xFlagBlue)*(xCarrier-xFlagBlue) +
(yCarrier-yFlagBlue)*(yCarrier-yFlagBlue));
if ((horizontalRange <= maxPermittedDistanceForPickup) &&
(zCarrier - zFlagBlue <= maxPermittedDistanceForPickup)){
BlueFlagTakenByRedId = vehicle.getEntityID().getEntityID().intValue();
blueFlagTakenByRed = true;
}//end if
} // end if
} // end checkForPickupBlue()
/**
* Check to see if either flag is currently taken by the opposing team.
* If it is, the method determines the flags location in relation to the
* opposing team's 'home' base, to determine if a victory has occurred.
* If so, the total number of victories for that team is accumulated.
* If the total is less than two, the simulation is reset and the next attempt
* begins. If the total is equal to two, the simulation is fully reset and the
* game starts over.
*
* @return void
*/
public void checkForVictory()
{
if (blueFlagTakenByRed == true){
double xFlagBlue = blueEspdu.getEntityLocationX(); // This is the entities
double yFlagBlue = blueEspdu.getEntityLocationY(); // current location
double zFlagBlue = blueEspdu.getEntityLocationZ();
double horizontalRangeBlue =
Math.sqrt((xCaptureBlue-xFlagBlue)*(xCaptureBlue-xFlagBlue) +
(yCaptureBlue-yFlagBlue)*(yCaptureBlue-yFlagBlue));
if (horizontalRangeBlue <= 5 * maxPermittedDistanceForPickup){
System.out.println("Red team captured Blue flag! Red team point.");
winSleep = true;
try{
Thread.sleep(1000);
}
catch(InterruptedException ite){
ite.printStackTrace();
}
winSleep = false;
setPlaying(false);
redWins = redWins + 1;
redPoint.setParameterValue(1.0f); // double
redWinner.setParameterValue((double)redWins); // double
// redEspdu.makeTimestampCurrent();
// behaviorStreamBuffer.sendPdu(redEspdu, ipAddress, portNumber);
if (redWins <= 2)
{
reset();
}
else
{
System.out.println("Red team wins!!!");
reset();
return;
// setPlaying(false);
// stopRun();
}
} //endif at home
}//end if bluetaken
if (redFlagTakenByBlue == true)
{
double xFlagRed = redEspdu.getEntityLocationX();
double yFlagRed = redEspdu.getEntityLocationY();
double zFlagRed = redEspdu.getEntityLocationZ();
double horizontalRangeRed =
Math.sqrt((xCaptureRed-xFlagRed)*(xCaptureRed-xFlagRed) +
(yCaptureRed-yFlagRed)*(yCaptureRed-yFlagRed));
if (horizontalRangeRed <= 5 * maxPermittedDistanceForPickup){
System.out.println("Blue team captured Red flag! Blue team point.");
winSleep = true;
try{
Thread.sleep(1000);
}
catch(InterruptedException ite){
ite.printStackTrace();
}
winSleep = false;
blueWins = blueWins + 1;
bluePoint.setParameterValue(1.0f); // double
blueWinner.setParameterValue((double)blueWins); // double
// blueEspdu.makeTimestampCurrent();
// behaviorStreamBuffer.sendPdu(blueEspdu, ipAddress, portNumber);
if (blueWins <= 2){
reset();
}
else
{
System.out.println("Blue team wins!!!");
reset();
return;
// setPlaying(false);
// stopRun();
}
} //end if
}//end if redFlagTakenByBlue
}//end check for victory
//************************************************************************************
//agent stuff runAgents()
//************************************************************************************
/**
* Keep's track of the non-human controlled agent entities. If the given PDU
* is from an agent entity, first it is checked to see if the entity already
* exists. If it doesn't, it is added to the appropriate Hashtable, and
* tested for relationships with other agents. The appropriate relationships
* are then formed.
* Finally, if the agent is in a relationship, and DataPDU is sent
*
* @param EntityStatePdu pEntityStatePdu the passed entity PDU
* @return void
*/
public void runAgents(EntityStatePdu pEntityStatePdu)
{
CTFAgent tempCTFAgent = null;
//boolean to see if we're going to send out a dataPdu
boolean sendIt = false;
//get the ID number of the sending agent
EntityID sender = pEntityStatePdu.getEntityID();
Integer senderID = new Integer(sender.getEntityID().intValue());
if ( senderID.intValue() < 30 )
{//we have a red agent here!
if (!(redAgents.containsKey(senderID)))
{//not in the Hashtable yet
String name = new String("RedAgent" + senderID.intValue());
tempCTFAgent = new CTFAgent(senderID.longValue(), name);
//let the red agent know it needs to form a "RedSquad" relationship
redAgents.put(senderID, tempCTFAgent);
}//end if
//if the red agent is not in the hashtable..he is now!
//lets see if he can join a relationship
//pull out the agent
tempCTFAgent = (CTFAgent)redAgents.get(senderID);
//set his sensedEnvironment to the agents in the hashtable
//(not including himself) this assumes good communication between
//agents and they all know where the good guys are
CTFSensedEnvironment sensedEnvironment = new CTFSensedEnvironment();
Enumeration redEnum = redAgents.keys();
while(redEnum.hasMoreElements())
{
Integer key = (Integer)redEnum.nextElement();
if (!(key.equals((Integer)senderID)))
{
sensedEnvironment.addAgent((CTFAgent)redAgents.get(key));
}//end if
}//end while
tempCTFAgent.setSensedEnvironment(sensedEnvironment);
tempCTFAgent.checkForRelationships( );
}//end if
else
{//we have a blue agent here!
if (!(blueAgents.containsKey(senderID)))
{//not in the Hashtable yet
String name = new String("BlueAgent" + senderID.intValue());
tempCTFAgent = new CTFAgent(senderID.longValue(), name);
blueAgents.put(senderID, tempCTFAgent);
}//end if
//if the blue agent is not in the hashtable..he is now!
//lets see if he can join a relationship
//pull out the agent
tempCTFAgent = (CTFAgent)blueAgents.get(senderID);
//set his sensedEnvironment to the agents in the hashtable
//(not including himself) this assumes good communication between
//agents and they all know where the good guys are
CTFSensedEnvironment sensedEnvironment = new CTFSensedEnvironment();
Enumeration blueEnum = blueAgents.keys();
while(blueEnum.hasMoreElements())
{
Integer key = (Integer)blueEnum.nextElement();
if (!(key.equals((Integer)senderID)))
{
sensedEnvironment.addAgent((CTFAgent)blueAgents.get(key));
}//end if
}//end while
tempCTFAgent.setSensedEnvironment(sensedEnvironment);
tempCTFAgent.checkForRelationships( );
}//end else
//at this point we have received a dataPdu from an Agent. We have added the
//agent to it's correct Hashtable and tested for relationships. If there are
//squad relationships out there to be formed, we have done it.
//Now we check to see if this agent is in a relationship and if so we send
//out a DataPdu
if(tempCTFAgent.inRelationship())
{
//get the data from the Agent and send it if required
tempCTFAgent.step();
DataPdu dataPdu = new DataPdu();
DatumSpecification datum2 = new DatumSpecification();
// identify this pdu as using protocol "0" for actionProtocol
FixedDatum fixedDatum1 = new FixedDatum();
fixedDatum1.setFixedDatumID(1);//use "1" by convention
fixedDatum1.setValue(0);
//this puts these variableDatums into a vector
datum2.addFixedDatum(fixedDatum1);
Vector tempProtocol = tempCTFAgent.getProtocolVector();
//load up the datumSpecification with variabledatum objects
for (int ix = 0; ix < tempProtocol.size(); ix++)
{
FixedDatum fixedDatum2 = new FixedDatum();
fixedDatum2.setFixedDatumID(1);//use "1" by convention
Integer actionValue = (Integer)tempProtocol.get(ix);
UnsignedByte forceID = pEntityStatePdu.getForceID();
int actionValueInt = actionValue.intValue();
int forceIDInt = forceID.intValue();
if (forceIDInt != (actionValueInt + 1))
{
sendIt = true;
}//end if
fixedDatum2.setValue(actionValueInt);
//this puts these variableDatums into a vector
datum2.addFixedDatum(fixedDatum2);
}//end for
if ( sendIt )
{
dataPdu.setDatumInformation(datum2);
//same ID as the flunky
dataPdu.setOriginatingEntityID(sender);
dataPdu.setReceivingEntityID(teamEspdu.getEntityID());
//send this puppy out
behaviorStreamBuffer.sendPdu(dataPdu, ipAddress, portNumber);
}//end if
}//end if
}//end runAgents()
//==============================================================================================
// Main
//==============================================================================================
/**
* The 'Main' method of the simulation. Parses the passes arguments and
* sets the simulation variables based on the provided argumanets.
* A 'Referee' is then instantiated and the simulation is initiated.
*
* The possible arguments are:
* 'rtp'
* 'trace'
* 'ttl' or 'timeToLive' + int (0-127) (eg: ttl 120)
* 'pause' or 'sleep' or 'wait' + int (0-60) (eg: sleep 45)
*
* @param String[] args the passed simulation environment variables
*/
public static void main(String[] args){
boolean ttlMatch = false;
boolean sleepMatch = false;
for (int index = 0; index < args.length; index++)
{
if (!rtpMatch) try
{
rtpMatch = ((args[index].compareToIgnoreCase ( "rtp") == 0) ||
(args[index].compareToIgnoreCase ("-rtp") == 0));
if (rtpMatch) continue;
}
catch (java.lang.NoSuchMethodError nsme) // prior to jdk 1.2
{
rtpMatch = ((args[index].compareTo ( "rtp") == 0) ||
(args[index].compareTo ("-rtp") == 0) ||
(args[index].compareTo ( "RTP") == 0) ||
(args[index].compareTo ("-RTP") == 0));
if (rtpMatch) continue;
}
if (!traceCommandLineFlag) try
{
traceCommandLineFlag = ((args[index].compareToIgnoreCase( "trace") == 0) ||
(args[index].compareToIgnoreCase("-trace") == 0));
if (traceCommandLineFlag) continue;
}
catch (java.lang.NoSuchMethodError nsme) // prior to jdk 1.2
{
traceCommandLineFlag = ((args[index].compareTo( "trace") == 0) ||
(args[index].compareTo("-trace") == 0) ||
(args[index].compareTo ( "TRACE") == 0) ||
(args[index].compareTo ("-TRACE") == 0));
if (traceCommandLineFlag) continue;
}
if (!(ttlMatch) && (args.length - index > 1))
{
try
{
ttlMatch = ((args[index].compareToIgnoreCase ( "ttl") == 0) ||
(args[index].compareToIgnoreCase ("-ttl") == 0) ||
(args[index].compareToIgnoreCase ( "timeToLive") == 0) ||
(args[index].compareToIgnoreCase ("-timeToLive") == 0));
}
catch (java.lang.NoSuchMethodError nsme) // prior to jdk 1.2
{
ttlMatch = ((args[index].compareTo ( "ttl") == 0) ||
(args[index].compareTo ("-ttl") == 0) ||
(args[index].compareTo ( "timeToLive") == 0) ||
(args[index].compareTo ("-timeToLive") == 0));
}
if (ttlMatch)
{
try
{
timeToLive = Integer.parseInt(args[index+1]);
index++;
}
catch(Exception e)
{
System.out.println(e);
System.out.println("illegal timeToLive value, exiting");
System.exit (-1);
}
if ((timeToLive < 0) || (timeToLive > 127))
{
System.out.println ("multicast timeToLive ttl=" + timeToLive +
" is out of range [0..127], exiting");
System.exit (-1);
}
continue;
}
}
if (!(sleepMatch) && (args.length - index > 1))
{
try
{
sleepMatch = ((args[index].compareToIgnoreCase ( "pause") == 0) ||
(args[index].compareToIgnoreCase ("-pause") == 0) ||
(args[index].compareToIgnoreCase ( "sleep") == 0) ||
(args[index].compareToIgnoreCase ("-sleep") == 0) ||
(args[index].compareToIgnoreCase ( "wait") == 0) ||
(args[index].compareToIgnoreCase ("-wait") == 0));
}
catch (java.lang.NoSuchMethodError nsme) // prior to jdk 1.2
{
sleepMatch = ((args[index].compareTo ( "pause") == 0) ||
(args[index].compareTo ("-pause") == 0) ||
(args[index].compareTo ( "sleep") == 0) ||
(args[index].compareTo ("-sleep") == 0) ||
(args[index].compareTo ( "wait") == 0) ||
(args[index].compareTo ("-wait") == 0));
}
if (sleepMatch)
{
try
{
sleepTime = Integer.parseInt(args[index+1]);
index++;
}
catch(Exception e)
{
System.out.println(e);
System.out.println("illegal sleepTime value, exiting");
System.exit (-1);
}
if ((sleepTime < 0) || (sleepTime > 60))
{
System.out.println ("sleepTime=" + sleepTime +
" is out of range (0..60 sec), ignored");
System.exit (-1);
}
else
{
for (int sleepCount = 0; sleepCount < sleepTime; sleepCount++)
{
try
{
Thread.sleep( 1000 ); // ms
}
catch (InterruptedException ie)
{
System.out.println ("fitful sleep: " + ie);
}
if (sleepCount == 0) System.out.print("Pause before starting");
System.out.print(".");
}
System.out.println();
}
continue;
}
}
else
{
System.out.println("Usage: java demo.helicopter.Referee [-ttl