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 ] [-pause ] [-rtp] [-trace]"); System.exit (-1); } } System.out.println ("multicast timeToLive ttl=" + timeToLive); System.out.println ("RTP headers prepended=" + rtpMatch); Referee stripeShirt = new Referee(); stripeShirt.start(); } // end main } // end class Referee