Skip to content
Snippets Groups Projects
Commit faaf6d9b authored by Ashmore, Michael (Capt)'s avatar Ashmore, Michael (Capt)
Browse files

Upload New File

parent 0fdad965
No related branches found
No related tags found
No related merge requests found
package MV3500Cohort2022MayJune.homework2.Ashmore;
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.enumerations.*;
import edu.nps.moves.dis7.pdus.*;
import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface;
import edu.nps.moves.dis7.utilities.DisTime;
import edu.nps.moves.dis7.utilities.PduFactory;
import edu.nps.moves.dis7.utilities.SimulationManager;
import edu.nps.moves.dis7.utilities.stream.PduRecorder;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ExampleSimulationProgramAshmore
{
private boolean verboseComments = true;
static final String NETWORK_ADDRESS_DEFAULT = "239.1.2.3";
static final int NETWORK_PORT_DEFAULT = 3000;
String networkAddress = NETWORK_ADDRESS_DEFAULT;
int networkPort = NETWORK_PORT_DEFAULT;
String thisHostName = "localhost";
String DEFAULT_OUTPUT_DIRECTORY = "./pduLog";
/** seconds for real-time execution (not simulation time, which may or may not be the same) */
double currentTimeStep = 2.0; // seconds
/** initial simulation time */
double initialTime = 0.0;
/** current simulation time */
double simulationTime;
/**
* Output prefix to help with logging by identifying this class (can be overridden in subclass).
*/
protected static String TRACE_PREFIX;
/* Declare DIS Protocol Data Unit (PDU) classes for simulation entities */
DisTime.TimestampStyle timestampStyle = DisTime.TimestampStyle.IEEE_ABSOLUTE;
PduFactory pduFactory = new PduFactory(timestampStyle);
/** EntityID settings for entity 1 */
protected EntityID entityID_1 = new EntityID();
/** EntityID settings for entity 2 */
protected EntityID entityID_2 = new EntityID();
/** ESPDU for entity 1 */
protected EntityStatePdu entityStatePdu_1 = pduFactory.makeEntityStatePdu();
/** ESPDU for entity 2 */
protected EntityStatePdu entityStatePdu_2 = pduFactory.makeEntityStatePdu();
/** FirePdu for entity 1 first weapon (if any) */
protected FirePdu firePdu_1a = pduFactory.makeFirePdu();
/** FirePdu for entity 1 second weapon (if any) */
protected FirePdu firePdu_1b = pduFactory.makeFirePdu();
/** MunitionDescriptor for these weapons */
protected MunitionDescriptor munitionDescriptor1 = new MunitionDescriptor();
/** this class instantiated as an object */
SimulationManager simulationManager = new SimulationManager();
/** Get ready, get set... initialize simulation entities
*/
public void initializeSimulationEntities()
{
// Your model setup: define participants. who's who in this zoo?
// Assuming you keep track of entity objects... here is some support for for Entity 1.
// PDU objects are already created, now set their values.
entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID;
entityID_2.setSiteID(1).setApplicationID(2).setEntityID(4); // made-up example ID;
// TODO someday, use enumerations; is there a unique site triplet for MOVES Institute?
entityStatePdu_1.setEntityID(entityID_1);
entityStatePdu_1.setForceId(ForceID.FRIENDLY);
entityStatePdu_1.setEntityType(new _001Poseidon()); // note import statement above
entityStatePdu_1.setMarking("Entity #1");
entityStatePdu_1.getMarkingString(); // check
entityStatePdu_2.setEntityID(entityID_2);
entityStatePdu_2.setForceId(ForceID.OPPOSING);
entityStatePdu_2.setEntityType(new _002Triton()); // note import statement above
entityStatePdu_2.setMarking("Entity #2");
// TODO how should we customize this munition? what is it for your simulation?
munitionDescriptor1.setQuantity(1);
firePdu_1a.setDescriptor(munitionDescriptor1).setRange(1000.0f);
// TODO simulation management PDUs for startup, planning to design special class support
// simulationManager.addEntity();
simulationManager.setDescriptor("ExampleSimulationProgram");
simulationManager.addHost(thisHostName);
simulationManager.setDisThreadedNetworkInterface(disNetworkInterface);
}
/**
* This runSimulationLoops() method is for you, a customizable programmer-modifiable
* code block for defining and running a new simulation of interest.
*
* Welcome! Other parts of this program handle bookkeeping and plumbing tasks so that
* you can focus on your model entities and activities.
* Expandable support includes DIS EntityStatePdu, FirePdu and CommentPdu all available for
* modification and sending in a simulation loop.
* Continuous improvement efforts seek to make this program as easy and straightforward
* 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.
*/
@SuppressWarnings("SleepWhileInLoop") // yes we do that
public void runSimulationLoops ()
{
try
{
final int SIMULATION_MAX_LOOP_COUNT = 10; // be deliberate out there! also avoid infinite loops.
int simulationLoopCount = 0; // variable, initialized at 0
boolean simulationComplete = false; // sentinel variable as termination condition, are we done yet?
// TODO reset Clock Time to today's date and timestamp to zero, providing consistent outputs for each simulation run
pduRecorder.setVerbose(true);
initializeSimulationEntities();
simulationManager.simulationJoin();
simulationManager.simulationStart();
// ===================================================================================================
// 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?
{
simulationLoopCount++; // good practice: increment loop counter as first action in that loop
// =============================================================================================
// * your own simulation code starts here! *
// =============================================================================================
// are there any other variables to modify at the beginning of your loop?
// 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.
entityStatePdu_1.getEntityLocation().setX(entityStatePdu_1.getEntityLocation().getX() + 1.0); // 1m per timestep
// 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
// something happens between my simulation entities, la de da de da...
System.out.println ("... My simulation just did something, no really...");
System.out.flush();
// make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending)
narrativeMessage1 = "MV3500 ExampleSimulationProgram";
narrativeMessage2 = "runSimulation() loop " + simulationLoopCount;
narrativeMessage3 = ""; // intentionally blank for testing
// your loop termination condition goes here
if (simulationLoopCount > 4) // for example
{
simulationComplete = true;
}
// =============================================================================================
// * your own simulation code is finished here! *
// =============================================================================================
// 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
Thread.sleep((long)(currentTimeStep * 1000)); // seconds * (1000 msec/sec) = milliseconds
System.out.println ("... [Pausing for " + currentTimeStep + " seconds]");
// OK now send the status PDUs for this loop, and then continue
System.out.println ("sending PDUs for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent");
System.out.flush();
sendAllPdusForLoopTimestep(entityStatePdu_1, firePdu_1a, currentTimeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
sendSinglePdu(entityStatePdu_2); // me too i.e. 2!
System.out.println ("... [PDUs successfully sent for this loop]");
System.out.flush();
// ===============================
// current loop now finished, check whether to terminate if simulation complete, otherwise continue
if (simulationComplete || (simulationLoopCount > 10000)) // for example; including fail-safe condition is good
{
System.out.println ("... [loop termination condition met, simulationComplete=" + simulationComplete + "]"); // ", final loopCount=" + loopCount +
System.out.flush();
break;
}
} // end of simulation loop
// ===================================================================================================
narrativeMessage2 = "runSimulation() completed successfully"; // all done
sendCommentPdu(narrativeComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
System.out.println ("... [final CommentPdu successfully sent for simulation]");
// TODO simulation management PDUs
simulationManager.simulationStop();
simulationManager.simulationLeave();
}
catch (InterruptedException iex) // handle any exception that your code might choose to provoke!
{
Logger.getLogger(ExampleSimulationProgramDuran.class.getName()).log(Level.SEVERE, null, iex);
}
}
/* **************************** infrastructure code, modification is seldom needed ************************* */
String narrativeMessage1 = new String();
String narrativeMessage2 = new String();
String narrativeMessage3 = new String();
/* VariableRecordType enumerations have potential use with CommentPdu logs */
/* TODO contrast to EntityType */
VariableRecordType descriptionComment = VariableRecordType.DESCRIPTION;
VariableRecordType narrativeComment = VariableRecordType.COMPLETE_EVENT_REPORT;
VariableRecordType statusComment = VariableRecordType.APPLICATION_STATUS;
VariableRecordType currentTimeStepComment = VariableRecordType.APPLICATION_TIMESTEP;
VariableRecordType otherComment = VariableRecordType.OTHER;
// class variables
DisThreadedNetworkInterface disNetworkInterface;
DisThreadedNetworkInterface.PduListener pduListener;
Pdu receivedPdu;
PduRecorder pduRecorder;
/**
* Constructor design goal: additional built-in initialization conveniences can go here
* to keep student efforts focused on the runSimulation() method.
*/
public ExampleSimulationProgramDuran()
{
DisTime.setTimestampStyle(timestampStyle);
try
{
thisHostName = InetAddress.getLocalHost().getHostName();
System.out.println(TRACE_PREFIX + "thisHostName=" + thisHostName);
}
catch (UnknownHostException uhe)
{
System.out.println(TRACE_PREFIX + thisHostName + "not connected to network: " + uhe.getMessage());
}
}
/**
* Utility Constructor that allows your example simulation program to override default network address and port
* @param address network address to use
* @param port corresponding network port to use
*/
public ExampleSimulationProgramDuran(String address, int port)
{
super();
setNetworkAddress(address);
setNetworkPort(port);
}
/**
* get current networkAddress as a string
* @return the networkAddress
*/
public String getNetworkAddress()
{
return networkAddress;
}
/**
* set current networkAddress using a string
* @param newNetworkAddress the networkAddress to set
*/
public final void setNetworkAddress(String newNetworkAddress)
{
this.networkAddress = newNetworkAddress;
}
/**
* get current networkPort
* @return the networkPort
*/
public int getNetworkPort()
{
return networkPort;
}
/**
* set current networkPort
* @param newNetworkPort the networkPort to set
*/
public final void setNetworkPort(int newNetworkPort)
{
this.networkPort = newNetworkPort;
}
/**
* Get timestampStyle used by PduFactory
* @return current timestampStyle
*/
public DisTime.TimestampStyle getTimestampStyle()
{
return timestampStyle;
}
/**
* Set timestampStyle used by PduFactory
* @param newTimestampStyle the timestampStyle to set
* @return same object to permit progressive setters
*/
public ExampleSimulationProgramDuran setTimestampStyle(DisTime.TimestampStyle newTimestampStyle)
{
timestampStyle = newTimestampStyle;
DisTime.setTimestampStyle(newTimestampStyle);
return this;
}
/**
* Initialize network interface, choosing best available network interface
*/
public void setUpNetworkInterface()
{
disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort());
disNetworkInterface.setDescriptor ("ExampleSimulationProgram pdu looping");
System.out.println("Network confirmation:" +
" address=" + disNetworkInterface.getAddress()+ // disNetworkInterface.getMulticastGroup() +
" port=" + disNetworkInterface.getPort()); // + disNetworkInterface.getDisPort());
pduListener = new DisThreadedNetworkInterface.PduListener()
{
/** Callback handler for listener */
@Override
public void incomingPdu(Pdu newPdu)
{
receivedPdu = newPdu;
}
};
disNetworkInterface.addListener(pduListener);
String outputDirectory = DEFAULT_OUTPUT_DIRECTORY;
System.out.println("Beginning pdu save to directory " + outputDirectory);
pduRecorder = new PduRecorder(outputDirectory, getNetworkAddress(), getNetworkPort()); // assumes save
pduRecorder.setEncodingPduLog(PduRecorder.ENCODING_PLAINTEXT);
pduRecorder.setVerbose(true); // either sending, receiving or both
pduRecorder.start(); // begin running
}
/** All done, release network resources */
public void tearDownNetworkInterface()
{
pduRecorder.stop(); // handles disNetworkInterface.close(), tears down threads and sockets
}
/**
* Send a single Protocol Data Unit (PDU) of any type
* @param pdu the pdu to send
*/
protected void sendSinglePdu(Pdu pdu)
{
try
{
disNetworkInterface.send(pdu);
Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally
}
catch (InterruptedException ex)
{
System.err.println(this.getClass().getName() + " Error sending PDU: " + ex.getLocalizedMessage());
System.exit(1);
}
}
/**
* Send Comment PDU
* @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments
* @param commentType enumeration value describing purpose of the narrative comment
* @param comments String array of narrative comments
*/
public void sendCommentPdu(VariableRecordType commentType,
// vararg... variable-length set of String comments can optionally follow
String... comments)
{
sendAllPdusForLoopTimestep (null, null, commentType, comments);
}
/**
* Send EntityState, Fire, Comment PDUs that got updated for this loop, reflecting state of current simulation timestep.
* @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments
* @param entityStatePdu the ESPDU to send, if any
* @param firePdu the FirePDU to send, if any
* @param commentType enumeration value describing purpose of the narrative comment
* @param comments String array of narrative comments
*/
public void sendAllPdusForLoopTimestep(EntityStatePdu entityStatePdu,
FirePdu firePdu,
VariableRecordType commentType,
// vararg... variable-length set of String comments can optionally follow
String... comments)
{
if (entityStatePdu != null)
sendSinglePdu(entityStatePdu);
if (firePdu != null)
sendSinglePdu(firePdu); // bang
if ((comments != null) && (comments.length > 0))
{
ArrayList<String> newCommentsList = new ArrayList<>();
for (String comment : comments)
{
if (!comment.isEmpty())
{
newCommentsList.add(comment); // OK found something to send
}
}
if (!newCommentsList.isEmpty())
{
if (commentType == null)
commentType = otherComment; // fallback value otherComment
// now build the commentPdu from these string inputs, thus constructing a narrative entry
CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments);
sendSinglePdu(commentPdu);
if (isVerboseComments())
{
System.out.println("*** [Narrative comment sent: " + commentType.name() + "] " + newCommentsList.toString());
System.out.flush();
}
}
}
}
/**
* test for verboseComments mode
* @return whether verboseComments mode is enabled
*/
public boolean isVerboseComments() {
return verboseComments;
}
/**
* set verboseComments mode
* @param newVerboseComments whether verboseComments mode is enabled
*/
public void setVerboseComments(boolean newVerboseComments) {
this.verboseComments = newVerboseComments;
}
/**
* 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 handleArgs (String[] args)
{
// initial execution: handle args array of initialization arguments here
if (args.length == 2)
{
if ((args[0] != null) && !args[0].isEmpty())
thisProgram.setNetworkAddress(args[0]);
if ((args[1] != null) && !args[1].isEmpty())
thisProgram.setNetworkPort(Integer.parseInt(args[1]));
}
else if (args.length != 0)
{
System.err.println("Usage: " + thisProgram.getClass().getSimpleName() + " [address port]");
System.exit(-1);
}
}
/** Locally instantiable copy of program, can be subclassed. */
protected static ExampleSimulationProgramDuran thisProgram;
/**
* Main method is first executed when a program instance is loaded.
* @see <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java Tutorials: A Closer Look at the "Hello World!" Application</a>
* @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)
{
TRACE_PREFIX = "[" + ExampleSimulationProgramDuran.class.getName() + "] ";
System.out.println(TRACE_PREFIX + "main() started...");
thisProgram = new ExampleSimulationProgramDuran(); // creates instance of self within static main() method
thisProgram.handleArgs (args); // process command-line invocation arguments
thisProgram.setUpNetworkInterface();
// thisProgram.pduRecorder.setDescriptor (TRACE_PREFIX.replace("[","").replace("]","") + " pduRecorder");
thisProgram.runSimulationLoops(); // ... your simulation execution code goes in there ...
thisProgram.tearDownNetworkInterface(); // make sure no processes are left lingering
System.out.println(TRACE_PREFIX + "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