Skip to content
Snippets Groups Projects
Commit 9dbfdd3c authored by Brutzman, Don's avatar Brutzman, Don
Browse files

show creation of detonation PDUs, also Java generation of random numbers

parent 745ae316
No related branches found
No related tags found
No related merge requests found
/** /**
* Copyright (c) 2008-2023, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. * Copyright (c) 2008-2023, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved.
* This work is provided under a BSD open-source license, see project license.html or license.txt * This work is provided under a BSD open-source license, see project license.html or license.txt
* @author brutzman@nps.edu * @author brutzman@nps.edu
*/ */
package OpenDis7Examples; package OpenDis7Examples;
import edu.nps.moves.dis7.entities.swe.platform.surface._001Poseidon; import edu.nps.moves.dis7.entities.swe.platform.surface._001Poseidon;
import edu.nps.moves.dis7.entities.swe.platform.surface._002Triton; import edu.nps.moves.dis7.entities.swe.platform.surface._002Triton;
import edu.nps.moves.dis7.enumerations.*; import edu.nps.moves.dis7.enumerations.*;
import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.pdus.*;
import edu.nps.moves.dis7.utilities.DisChannel; import edu.nps.moves.dis7.utilities.DisChannel;
import edu.nps.moves.dis7.utilities.PduFactory; import edu.nps.moves.dis7.utilities.PduFactory;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.logging.Level; import java.util.Random;
import java.util.logging.Logger; import java.util.logging.Level;
import java.util.logging.Logger;
/** The purpose of this inheritable class is to provide an easily modifiable
* example simulation program that includes DIS-capable entities performing /** The purpose of this inheritable class is to provide an easily modifiable
* tasks of interest, and then reporting activity via PDUs to the network. * example simulation program that includes DIS-capable entities performing
* Default program initialization includes PDU recording turned on by default. * tasks of interest, and then reporting activity via PDUs to the network.
* @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt" target="_blank">ExampleSimulationProgramLog.txt</a> * Default program initialization includes PDU recording turned on by default.
* @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramPduCaptureLog.dislog" target="_blank">ExampleSimulationProgramPduCaptureLog.dislog</a> * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt" target="_blank">ExampleSimulationProgramLog.txt</a>
* @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.pdf" target="_blank">ExampleSimulationProgramFlowDiagram.pdf</a> * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramPduCaptureLog.dislog" target="_blank">ExampleSimulationProgramPduCaptureLog.dislog</a>
* @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramWireshark.png" target="_blank">ExampleSimulationProgramWireshark.png</a> * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.pdf" target="_blank">ExampleSimulationProgramFlowDiagram.pdf</a>
* @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png" target="_blank">ExampleSimulationProgramSequenceDiagram.png</a> * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramWireshark.png" target="_blank">ExampleSimulationProgramWireshark.png</a>
*/ * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png" target="_blank">ExampleSimulationProgramSequenceDiagram.png</a>
public class ExampleSimulationProgram */
{ public class ExampleSimulationProgram
/* **************************** infrastructure code, modification is seldom needed ************************* */ {
/* **************************** infrastructure code, modification is seldom needed ************************* */
private String descriptor = this.getClass().getSimpleName();
/** DIS channel defined by network address/port combination includes multiple utility capabilities */ private String descriptor = this.getClass().getSimpleName();
protected DisChannel disChannel; /** DIS channel defined by network address/port combination includes multiple utility capabilities */
/** Factory object used to create new PDU instances */ protected DisChannel disChannel;
protected PduFactory pduFactory; /** Factory object used to create new PDU instances */
protected PduFactory pduFactory;
/** seconds per loop for real-time or simulation execution */
private double simulationTimeStepDuration = 1.0; // seconds TODO encapsulate /** seconds per loop for real-time or simulation execution */
/** initial simulation time in seconds */ private double simulationTimeStepDuration = 1.0; // seconds TODO encapsulate
double simulationTimeInitial = 0.0; /** initial simulation time in seconds */
/** current simulation time in seconds */ double simulationTimeInitial = 0.0;
double simulationTimeSeconds = simulationTimeInitial; /** current simulation time in seconds */
/** Maximum number of simulation loops */ double simulationTimeSeconds = simulationTimeInitial;
int MAX_LOOP_COUNT = 4; /** Maximum number of simulation loops */
int MAX_LOOP_COUNT = 4;
String narrativeMessage1 = new String();
String narrativeMessage2 = new String(); String narrativeMessage1 = new String();
String narrativeMessage3 = new String(); String narrativeMessage2 = new String();
String narrativeMessage3 = new String();
/** EntityID settings for entity 1 */
protected EntityID entityID_1 = new EntityID(); /** EntityID settings for entity 1 */
/** EntityID settings for entity 2 */ protected EntityID entityID_1 = new EntityID();
protected EntityID entityID_2 = new EntityID(); /** EntityID settings for entity 2 */
/** ESPDU for entity 1 */ protected EntityID entityID_2 = new EntityID();
protected EntityStatePdu entityStatePdu_1; /** ESPDU for entity 1 */
/** ESPDU for entity 2 */ protected EntityStatePdu entityStatePdu_1;
protected EntityStatePdu entityStatePdu_2; /** ESPDU for entity 2 */
/** FirePdu for entity 1 first weapon (if any) */ protected EntityStatePdu entityStatePdu_2;
protected FirePdu firePdu_1a; /** FirePdu for entity 1 first weapon (if any) */
/** FirePdu for entity 1 second weapon (if any) */ protected FirePdu firePdu_1a;
protected FirePdu firePdu_1b; /** FirePdu for entity 1 second weapon (if any) */
/** MunitionDescriptor for these weapons */ protected FirePdu firePdu_1b;
protected MunitionDescriptor munitionDescriptor1; /** MunitionDescriptor for these weapons */
protected MunitionDescriptor munitionDescriptor1;
// hey programmer, what other state do you want? this is a good place to declare it...
/** TODO DetonationPdu for entity 1 second weapon (if any) */
/** protected DetonationPdu detonationPdu_1a;
* Constructor to create an instance of this class. /** TODO DetonationPdu for entity 1 second weapon (if any) */
* Design goal: additional built-in initialization conveniences can go here protected DetonationPdu detonationPdu_1b;
* to keep your efforts focused on the runSimulation() method.
*/ // hey programmer, what other state do you want? this is a good place to declare it...
// base constructor is not invoked automatically by other constructors
// https://stackoverflow.com/questions/581873/best-way-to-handle-multiple-constructors-in-java /**
public ExampleSimulationProgram() * Constructor to create an instance of this class.
{ * Design goal: additional built-in initialization conveniences can go here
initialize(); * to keep your efforts focused on the runSimulation() method.
} */
/** // base constructor is not invoked automatically by other constructors
* Constructor to create an instance of this class. // https://stackoverflow.com/questions/581873/best-way-to-handle-multiple-constructors-in-java
* @param newDescriptor describes this program, useful for logging and debugging public ExampleSimulationProgram()
*/ {
public ExampleSimulationProgram(String newDescriptor) initialize();
{ }
descriptor = newDescriptor; /**
initialize(); * Constructor to create an instance of this class.
} * @param newDescriptor describes this program, useful for logging and debugging
/** */
* Utility Constructor that allows your example simulation program to override default network address and port public ExampleSimulationProgram(String newDescriptor)
* @param address network address to use {
* @param port corresponding network port to use descriptor = newDescriptor;
*/ initialize();
public ExampleSimulationProgram(String address, int port) }
{ /**
disChannel.setNetworkAddress (address); * Utility Constructor that allows your example simulation program to override default network address and port
disChannel.setNetworkPort (port); * @param address network address to use
disChannel.setVerboseComments (true); // TODO rename library method to disambiguate CommentPDU * @param port corresponding network port to use
// TODO still seems really chatty... add silent mode? */
disChannel.setVerboseDisNetworkInterface(true); // Default false public ExampleSimulationProgram(String address, int port)
disChannel.setVerbosePduRecorder (true); // default false {
initialize(); disChannel.setNetworkAddress (address);
} disChannel.setNetworkPort (port);
disChannel.setVerboseComments (true); // TODO rename library method to disambiguate CommentPDU
/** Initialize channel setup for OpenDis7 and report a test PDU // TODO still seems really chatty... add silent mode?
* @see initializeDisChannel disChannel.setVerboseDisNetworkInterface(true); // Default false
* @see initializeSimulationEntities */ disChannel.setVerbosePduRecorder (true); // default false
private void initialize() initialize();
{ }
initializeDisChannel(); // must come first, uses PduFactory
/** Initialize channel setup for OpenDis7 and report a test PDU
initializeSimulationEntities(); // set unchanging parameters * @see initializeDisChannel
* @see initializeSimulationEntities */
disChannel.join(); // TODO further functionality expected private void initialize()
{
String timeStepMessage = "Simulation timestep duration " + getSimulationTimeStepDuration() + " seconds"; initializeDisChannel(); // must come first, uses PduFactory
disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_SIMULATION_TIMESTEP, timeStepMessage);
// additional constructor initialization can go here initializeSimulationEntities(); // set unchanging parameters
}
disChannel.join(); // TODO further functionality expected
/** Initialize channel setup for OpenDis7 and report a test PDU */
private void initializeDisChannel() String timeStepMessage = "Simulation timestep duration " + getSimulationTimeStepDuration() + " seconds";
{ disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_SIMULATION_TIMESTEP, timeStepMessage);
if (disChannel == null) // additional constructor initialization can go here
disChannel = new DisChannel(); }
else
{ /** Initialize channel setup for OpenDis7 and report a test PDU */
disChannel.printlnTRACE ("*** warning, duplicate invocation of initializeDisChannel() ignored"); private void initializeDisChannel()
return; {
} if (disChannel == null)
pduFactory = disChannel.getPduFactory(); disChannel = new DisChannel();
disChannel.setDescriptor(this.getClass().getSimpleName()); // ExampleSimulationProgram might be a superclass else
disChannel.setUpNetworkInterface(); {
disChannel.printlnTRACE ("just checking: disChannel.getNetworkAddress()=" + disChannel.getNetworkAddress() + disChannel.printlnTRACE ("*** warning, duplicate invocation of initializeDisChannel() ignored");
", getNetworkPort()=" + disChannel.getNetworkPort()); return;
disChannel.getDisNetworkInterface().setVerbose(true); // sending and receipt }
disChannel.printlnTRACE ("just checking: hasVerboseSending()=" + disChannel.getDisNetworkInterface().hasVerboseSending() + pduFactory = disChannel.getPduFactory();
", hasVerboseReceipt()=" + disChannel.getDisNetworkInterface().hasVerboseReceipt()); disChannel.setDescriptor(this.getClass().getSimpleName()); // ExampleSimulationProgram might be a superclass
disChannel.getPduRecorder().setVerbose(true); disChannel.setUpNetworkInterface();
disChannel.printlnTRACE ("just checking: disChannel.getNetworkAddress()=" + disChannel.getNetworkAddress() +
// TODO confirm whether recorder is explicitly started by programmer (or not) ", getNetworkPort()=" + disChannel.getNetworkPort());
disChannel.getDisNetworkInterface().setVerbose(true); // sending and receipt
// disChannel.sendCommentPdu(VariableRecordType.OTHER, "DisThreadedNetworkInterface.initializeDisChannel() complete"); // hello channel, debug disChannel.printlnTRACE ("just checking: hasVerboseSending()=" + disChannel.getDisNetworkInterface().hasVerboseSending() +
} ", hasVerboseReceipt()=" + disChannel.getDisNetworkInterface().hasVerboseReceipt());
disChannel.getPduRecorder().setVerbose(true);
/** Get ready, get set... initialize simulation entities. Who's who in the zoo?
*/ // TODO confirm whether recorder is explicitly started by programmer (or not)
public void initializeSimulationEntities()
{ // disChannel.sendCommentPdu(VariableRecordType.OTHER, "DisThreadedNetworkInterface.initializeDisChannel() complete"); // hello channel, debug
if (pduFactory == null) }
pduFactory = disChannel.getPduFactory();
entityStatePdu_1 = pduFactory.makeEntityStatePdu(); /** Get ready, get set... initialize simulation entities. Who's who in the zoo?
entityStatePdu_2 = pduFactory.makeEntityStatePdu(); */
firePdu_1a = pduFactory.makeFirePdu(); public void initializeSimulationEntities()
firePdu_1b = pduFactory.makeFirePdu(); {
munitionDescriptor1 = new MunitionDescriptor(); if (pduFactory == null)
pduFactory = disChannel.getPduFactory();
// Your model setup: define participants. who's who in this zoo? entityStatePdu_1 = pduFactory.makeEntityStatePdu();
// Assuming you keep track of entity objects... here is some support for for Entity 1. entityStatePdu_2 = pduFactory.makeEntityStatePdu();
firePdu_1a = pduFactory.makeFirePdu();
// PDU objects are already declared and instances created, so now set their values. firePdu_1b = pduFactory.makeFirePdu();
// who is who in our big zoo, sufficient for global participation if we need it munitionDescriptor1 = new MunitionDescriptor();
entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID;
disChannel.addEntity(entityID_1); // can a third party report their independent (non-entity) status of a detonation? yes...
detonationPdu_1a = pduFactory.makeDetonationPdu();
entityID_2.setSiteID(1).setApplicationID(2).setEntityID(4); // made-up example ID; // if this is a third-party report, then that third party will need an EntityID
disChannel.addEntity(entityID_2); detonationPdu_1a.setSourceEntityID(entityID_1);
// TODO someday, use enumerations for sites as part of a SimulationManager object; e.g. is there a unique site triplet for MOVES Institute?
// Your model setup: define participants. who's who in this zoo?
entityStatePdu_1.setEntityID(entityID_1); // Assuming you keep track of entity objects... here is some support for for Entity 1.
entityStatePdu_1.setForceId(ForceID.FRIENDLY);
entityStatePdu_1.setEntityType(new _001Poseidon()); // note import statement above // PDU objects are already declared and instances created, so now set their values.
// entityStatePdu_1.setMarking("Entity #1"); // who is who in our big zoo, sufficient for global participation if we need it
entityStatePdu_1.setEntityType(new edu.nps.moves.dis7.entities.usa.platform.air.MV22B()); // note import statement at top entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID;
entityStatePdu_1.setMarking("Entity #53"); disChannel.addEntity(entityID_1);
entityStatePdu_1.getMarkingString(); // use Netbeans Debug breakpoint here to check left justified...
entityID_2.setSiteID(1).setApplicationID(2).setEntityID(4); // made-up example ID;
entityStatePdu_2.setEntityID(entityID_2); disChannel.addEntity(entityID_2);
entityStatePdu_2.setForceId(ForceID.OPPOSING); // TODO someday, use enumerations for sites as part of a SimulationManager object; e.g. is there a unique site triplet for MOVES Institute?
entityStatePdu_2.setEntityType(new _002Triton()); // note import statement above
entityStatePdu_2.setMarking("Entity #2"); entityStatePdu_1.setEntityID(entityID_1);
entityStatePdu_1.setForceId(ForceID.FRIENDLY);
// TODO how should we customize this munition? what are key parameters for your simulation? entityStatePdu_1.setEntityType(new _001Poseidon()); // note import statement above
// more is needed here by scenario authors... // entityStatePdu_1.setMarking("Entity #1");
munitionDescriptor1.setQuantity(1); entityStatePdu_1.setEntityType(new edu.nps.moves.dis7.entities.usa.platform.air.MV22B()); // note import statement at top
firePdu_1a.setDescriptor(munitionDescriptor1).setRange(1000.0f); entityStatePdu_1.setMarking("Entity #53");
} entityStatePdu_1.getMarkingString(); // use Netbeans Debug breakpoint here to check left justified...
/** entityStatePdu_2.setEntityID(entityID_2);
* This runSimulationLoops() method is for you, a customizable programmer-modifiable entityStatePdu_2.setForceId(ForceID.OPPOSING);
* code block for defining and running a new simulation of interest. entityStatePdu_2.setEntityType(new _002Triton()); // note import statement above
* entityStatePdu_2.setMarking("Entity #2");
* Welcome! Other parts of this program handle bookkeeping and plumbing tasks so that
* you can focus on your model entities and activities. // TODO how should we customize this munition? what are key parameters for your simulation?
* Expandable support includes DIS EntityStatePdu, FirePdu and CommentPdu all available for // more is needed here by scenario authors...
* modification and sending in a simulation loop. munitionDescriptor1.setQuantity(1);
* Continuous improvement efforts seek to make this program as easy and straightforward firePdu_1a.setDescriptor(munitionDescriptor1).setRange(1000.0f); // TODO if not setting target entity, how to set direction?
* as possible for DIS simulationists to use and adapt. }
* All of the other methods are setup, teardown and configuration that you may find
* interesting, even helpful, but don't really have to worry about. /**
*/ * This runSimulationLoops() method is for you, a customizable programmer-modifiable
@SuppressWarnings("SleepWhileInLoop") // yes we might do that * code block for defining and running a new simulation of interest.
public void runSimulationLoops () *
{ * Welcome! Other parts of this program handle bookkeeping and plumbing tasks so that
try * you can focus on your model entities and activities.
{ * Expandable support includes DIS EntityStatePdu, FirePdu and CommentPdu all available for
final int SIMULATION_MAX_LOOP_COUNT = 10; // be deliberate out there! also avoid infinite loops. * modification and sending in a simulation loop.
int simulationLoopCount = 0; // variable, initialized at 0 * Continuous improvement efforts seek to make this program as easy and straightforward
boolean simulationComplete = false; // sentinel variable as termination condition, are we done yet? * as possible for DIS simulationists to use and adapt.
* All of the other methods are setup, teardown and configuration that you may find
// TODO reset Clock Time for today's date and timestamp to zero, providing consistent outputs for each simulation run * interesting, even helpful, but don't really have to worry about.
String timeMessage = "Simulation time " + simulationTimeSeconds + " at LocalDateTime " + LocalDateTime.now(); */
disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_TIME, timeMessage); @SuppressWarnings("SleepWhileInLoop") // yes we might do that
// TODO replace enumeration with disChannel.COMMENTPDU_TIME public void runSimulationLoops ()
// TODO fix VariableRecordType.TIME_AMP_DATE_VALID {
try
// =================================================================================================== {
// loop the simulation while allowed, programmer can set additional conditions to break out and finish final int SIMULATION_MAX_LOOP_COUNT = 10; // be deliberate out there! also avoid infinite loops.
while (simulationLoopCount < SIMULATION_MAX_LOOP_COUNT) // are we done yet? int simulationLoopCount = 0; // variable, initialized at 0
{ boolean simulationComplete = false; // sentinel variable as termination condition, are we done yet?
simulationLoopCount++; // good practice: increment loop counter as first action in that loop
// TODO reset Clock Time for today's date and timestamp to zero, providing consistent outputs for each simulation run
// ============================================================================================= String timeMessage = "Simulation time " + simulationTimeSeconds + " at LocalDateTime " + LocalDateTime.now();
// * your own simulation code starts here! ***************************************************** disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_TIME, timeMessage);
// ============================================================================================= // TODO replace enumeration with disChannel.COMMENTPDU_TIME
// TODO fix VariableRecordType.TIME_AMP_DATE_VALID
// are there any other variables to modify at the beginning of your loop?
// ===================================================================================================
// are your reading any DIS PDUs from the network? check for them here // loop the simulation while allowed, programmer can set additional conditions to break out and finish
while (simulationLoopCount < SIMULATION_MAX_LOOP_COUNT) // are we done yet?
// compute a track, update an ESPDU, whatever it is that your model is doing... {
simulationLoopCount++; // good practice: increment loop counter as first action in that loop
// Where is my entity? Insert changes in position; this sample only changes X position.
entityStatePdu_1.getEntityLocation().setX(entityStatePdu_1.getEntityLocation().getX() + 1.0); // 1m per timestep // =============================================================================================
// * your own simulation code starts here! *****************************************************
// decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoot at! // =============================================================================================
// etc. etc. your code goes here for your simulation of interest // are there any other variables to modify at the beginning of your loop?
// something happens between my simulation entities, la de da de da... // are your reading any DIS PDUs from the network? check for them here
System.out.println ("... My simulation just did something, no really...");
System.out.flush(); // make sure this arrives to user even if other threads somehow become deadlocked // compute a track, update an ESPDU, whatever it is that your model is doing...
// Where is my entity? Insert changes in position; this sample only changes X position.
// make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) entityStatePdu_1.getEntityLocation().setX(entityStatePdu_1.getEntityLocation().getX() + 1.0); // 1m per timestep
narrativeMessage1 = "MV3500 ExampleSimulationProgram";
narrativeMessage2 = "runSimulation() loop " + simulationLoopCount; // decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoot at!
narrativeMessage3 = ""; // intentionally blank for testing
// etc. etc. your code goes here for your simulation of interest
// your loop termination condition goes here
if (simulationLoopCount > MAX_LOOP_COUNT) // for example // something happens between my simulation entities, la de da de da...
{ System.out.println ("... My simulation just did something, no really...");
simulationComplete = true; System.out.flush(); // make sure this arrives to user even if other threads somehow become deadlocked
}
// ============================================================================================= // here are two built-in Java alternatives to generating random numbers
// * your own simulation code is finished here! ************************************************ Random randomGenerator = new Random();
// ============================================================================================= int randomInt = randomGenerator.nextInt(100); // [0, 99]
double randomDouble = Math.random() * 100; // [0.0, 100.0)
// staying synchronized with timestep: wait duration for elapsed time in this loop
// Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes // make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending)
Thread.sleep((long)(getSimulationTimeStepDuration() * 1000)); // units of seconds * (1000 msec/sec) = milliseconds narrativeMessage1 = "MV3500 ExampleSimulationProgram";
System.out.println ("... [Pausing for " + getSimulationTimeStepDuration() + " seconds]"); narrativeMessage2 = "runSimulation() loop " + simulationLoopCount;
// narrativeMessage3 = ""; // intentionally blank for testing
// OK now send the status PDUs for this loop, and then continue narrativeMessage3 = "randomInt=" + randomInt + " randomDouble=" + randomDouble;
System.out.println ("... sending PDUs of interest for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent");
System.out.flush(); // your loop termination condition goes here
if (simulationLoopCount > MAX_LOOP_COUNT) // for example
// TODO set timesteps in PDUs {
simulationComplete = true;
sendAllPdusForLoopTimestep(simulationTimeSeconds, }
entityStatePdu_1, // =============================================================================================
firePdu_1a, // * your own simulation code is finished here! ************************************************
DisChannel.COMMENTPDU_APPLICATION_STATUS, // =============================================================================================
narrativeMessage1, narrativeMessage2, narrativeMessage3);
disChannel.sendSinglePdu(simulationTimeSeconds, entityStatePdu_2); // me too i.e. 2! // staying synchronized with timestep: wait duration for elapsed time in this loop
// Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes
System.out.println ("... [PDUs of interest successfully sent for this loop]"); Thread.sleep((long)(getSimulationTimeStepDuration() * 1000)); // units of seconds * (1000 msec/sec) = milliseconds
System.out.flush(); System.out.println ("... [Pausing for " + getSimulationTimeStepDuration() + " seconds]");
// =============================== // OK now send the status PDUs for this loop, and then continue
// current loop now finished, check whether to terminate if simulation complete, otherwise continue System.out.println ("... sending PDUs of interest for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent");
if (simulationComplete || (simulationLoopCount > 10000)) // for example; including fail-safe condition is good System.out.flush();
{
System.out.println ("... [loop termination condition met, simulationComplete=" + simulationComplete + "]"); // ", final loopCount=" + loopCount + // TODO set timesteps in PDUs
System.out.flush();
break; sendAllPdusForLoopTimestep(simulationTimeSeconds,
} entityStatePdu_1,
simulationTimeSeconds += getSimulationTimeStepDuration(); // good practice: increment simulationTime as lastst action in that loop firePdu_1a,
DisChannel.COMMENTPDU_APPLICATION_STATUS,
} // end of simulation loop, continue until done narrativeMessage1, narrativeMessage2, narrativeMessage3);
// ===================================================================================================// ===================================================================================================// ===================================================================================================// =================================================================================================== disChannel.sendSinglePdu(simulationTimeSeconds, entityStatePdu_2); // me too i.e. 2!
narrativeMessage2 = "runSimulation() completed successfully"; // all done, so tell everyone else on the channel System.out.println ("... [PDUs of interest successfully sent for this loop]");
// TODO better javadoc needs to be autogenerated for VariableRecordType enumerations System.out.flush();
disChannel.sendCommentPdu(DisChannel.COMMENTPDU_NARRATIVE, narrativeMessage1, narrativeMessage2, narrativeMessage3);
System.out.println ("... [final=completion CommentPdu successfully sent for simulation]"); // ===============================
// current loop now finished, check whether to terminate if simulation complete, otherwise continue
// disChannel.getPduRecorder(). TODO record XML as well if (simulationComplete || (simulationLoopCount > 10000)) // for example; including fail-safe condition is good
disChannel.leave(); // embedded SimulationManager is expected to send appropriate PDUs for entity, application shutdown {
} System.out.println ("... [loop termination condition met, simulationComplete=" + simulationComplete + "]"); // ", final loopCount=" + loopCount +
catch (InterruptedException iex) // handle any exception that your code might choose to provoke! System.out.flush();
{ break;
Logger.getLogger(ExampleSimulationProgram.class.getSimpleName()).log(Level.SEVERE, null, iex); }
} simulationTimeSeconds += getSimulationTimeStepDuration(); // good practice: increment simulationTime as lastst action in that loop
}
} // end of simulation loop, continue until done
/** // ===================================================================================================// ===================================================================================================// ===================================================================================================// ===================================================================================================
* Send EntityState, Fire, Comment PDUs that got updated for this loop, reflecting state of current simulation timestep.
* @param simTimeSeconds simulation time in second, applied to PDU as timestamp narrativeMessage2 = "runSimulation() completed successfully"; // all done, so tell everyone else on the channel
* @param entityStatePdu the ESPDU to send, if any // TODO better javadoc needs to be autogenerated for VariableRecordType enumerations
* @param firePdu the FirePDU to send, if any disChannel.sendCommentPdu(DisChannel.COMMENTPDU_NARRATIVE, narrativeMessage1, narrativeMessage2, narrativeMessage3);
* @param commentType enumeration value describing purpose of the narrative comment PDU System.out.println ("... [final=completion CommentPdu successfully sent for simulation]");
* @param comments String array of narrative comments
* @see DisChannel // disChannel.getPduRecorder(). TODO record XML as well
// * @see DisTime // TODO find renamed version disChannel.leave(); // embedded SimulationManager is expected to send appropriate PDUs for entity, application shutdown
* @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html" target="_blank">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments }
*/ catch (InterruptedException iex) // handle any exception that your code might choose to provoke!
public void sendAllPdusForLoopTimestep(double simTimeSeconds, {
EntityStatePdu entityStatePdu, Logger.getLogger(ExampleSimulationProgram.class.getSimpleName()).log(Level.SEVERE, null, iex);
FirePdu firePdu, }
VariableRecordType commentType, }
// vararg... variable-length set of String comments can optionally follow
String... comments) /**
{ * Send EntityState, Fire, Comment PDUs that got updated for this loop, reflecting state of current simulation timestep.
if (entityStatePdu != null) * @param simTimeSeconds simulation time in second, applied to PDU as timestamp
disChannel.sendSinglePdu(simTimeSeconds, entityStatePdu); * @param entityStatePdu the ESPDU to send, if any
* @param firePdu the FirePDU to send, if any
if (firePdu != null) * @param commentType enumeration value describing purpose of the narrative comment PDU
disChannel.sendSinglePdu(simTimeSeconds, firePdu); // bang * @param comments String array of narrative comments
* @see DisChannel
disChannel.sendCommentPdu(simTimeSeconds, commentType, comments); // empty comments are filtered // * @see DisTime // TODO find renamed version
} * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html" target="_blank">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments
*/
/** public void sendAllPdusForLoopTimestep(double simTimeSeconds,
* Initial execution via main() method: handle args array of command-line initialization (CLI) arguments here EntityStatePdu entityStatePdu,
* @param args command-line parameters: network address and port FirePdu firePdu,
*/ VariableRecordType commentType,
protected void handleArguments (String[] args) // vararg... variable-length set of String comments can optionally follow
{ String... comments)
// initial execution: handle args array of initialization arguments here {
if (args.length == 2) if (entityStatePdu != null)
{ disChannel.sendSinglePdu(simTimeSeconds, entityStatePdu);
if ((args[0] != null) && !args[0].isEmpty())
thisProgram.disChannel.setNetworkAddress(args[0]); if (firePdu != null)
if ((args[1] != null) && !args[1].isEmpty()) disChannel.sendSinglePdu(simTimeSeconds, firePdu); // bang
thisProgram.disChannel.setNetworkPort(Integer.parseInt(args[1]));
} disChannel.sendCommentPdu(simTimeSeconds, commentType, comments); // empty comments are filtered
else if (args.length != 0) }
{
System.err.println("Usage: " + thisProgram.getClass().getSimpleName() + " [address port]"); /**
System.exit(-1); * Initial execution via main() method: handle args array of command-line initialization (CLI) arguments here
} * @param args command-line parameters: network address and port
} */
protected void handleArguments (String[] args)
/** {
* Get simple descriptor (such as parent class name) for this network interface, used in trace statements // initial execution: handle args array of initialization arguments here
* @return simple descriptor name if (args.length == 2)
*/ {
public String getDescriptor() { if ((args[0] != null) && !args[0].isEmpty())
return descriptor; thisProgram.disChannel.setNetworkAddress(args[0]);
} if ((args[1] != null) && !args[1].isEmpty())
thisProgram.disChannel.setNetworkPort(Integer.parseInt(args[1]));
/** }
* Set new simple descriptor (such as parent class name) for this network interface, used in trace statements else if (args.length != 0)
* @param newDescriptor simple descriptor name for this interface {
*/ System.err.println("Usage: " + thisProgram.getClass().getSimpleName() + " [address port]");
public void setDescriptor(String newDescriptor) { System.exit(-1);
if (newDescriptor == null) }
newDescriptor = ""; }
this.descriptor = newDescriptor;
} /**
* Get simple descriptor (such as parent class name) for this network interface, used in trace statements
/** * @return simple descriptor name
* parameter accessor method */
* @return the simulationTimeStepDuration in seconds public String getDescriptor() {
*/ return descriptor;
public double getSimulationTimeStepDuration() { }
return simulationTimeStepDuration;
} /**
* Set new simple descriptor (such as parent class name) for this network interface, used in trace statements
/** * @param newDescriptor simple descriptor name for this interface
* parameter accessor method */
* @param timeStepDurationSeconds the simulationTimeStepDuration in seconds to set public void setDescriptor(String newDescriptor) {
*/ if (newDescriptor == null)
public void setSimulationTimeStepDuration(double timeStepDurationSeconds) { newDescriptor = "";
this.simulationTimeStepDuration = timeStepDurationSeconds; this.descriptor = newDescriptor;
} }
/** Locally instantiable copy of program, can be subclassed. */ /**
protected static ExampleSimulationProgram thisProgram; * parameter accessor method
* @return the simulationTimeStepDuration in seconds
/** */
* Main method is first executed when a program instance is loaded. public double getSimulationTimeStepDuration() {
* @see <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html" target="_blank">Java Tutorials: A Closer Look at the "Hello World!" Application</a> return simulationTimeStepDuration;
* @param args command-line parameters: network address and port. }
* Command-line arguments are an array of optional String parameters that are passed from execution environment during invocation
*/ /**
public static void main(String[] args) * parameter accessor method
{ * @param timeStepDurationSeconds the simulationTimeStepDuration in seconds to set
thisProgram = new ExampleSimulationProgram("test constructor"); // create instance of self within static main() method */
public void setSimulationTimeStepDuration(double timeStepDurationSeconds) {
thisProgram.disChannel.printlnTRACE("main() started..."); this.simulationTimeStepDuration = timeStepDurationSeconds;
}
thisProgram.handleArguments(args); // process any command-line invocation arguments
/** Locally instantiable copy of program, can be subclassed. */
thisProgram.runSimulationLoops(); // ... your simulation execution code goes in there ... protected static ExampleSimulationProgram thisProgram;
thisProgram.disChannel.tearDownNetworkInterface(); // make sure no processes are left lingering /**
* Main method is first executed when a program instance is loaded.
thisProgram.disChannel.printlnTRACE("complete."); // report successful completion * @see <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html" target="_blank">Java Tutorials: A Closer Look at the "Hello World!" Application</a>
* @param args command-line parameters: network address and port.
System.exit(0); // ensure all threads and sockets released * Command-line arguments are an array of optional String parameters that are passed from execution environment during invocation
} */
} public static void main(String[] args)
{
thisProgram = new ExampleSimulationProgram("test constructor"); // create instance of self within static main() method
thisProgram.disChannel.printlnTRACE("main() started...");
thisProgram.handleArguments(args); // process any command-line invocation arguments
thisProgram.runSimulationLoops(); // ... your simulation execution code goes in there ...
thisProgram.disChannel.tearDownNetworkInterface(); // make sure no processes are left lingering
thisProgram.disChannel.printlnTRACE("complete."); // report successful completion
System.exit(0); // ensure all threads and sockets released
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment