Skip to content
Snippets Groups Projects
Commit d329f53c authored by Frank, Justin (CPT)'s avatar Frank, Justin (CPT)
Browse files

Delete FrankUdpServer.java

parent 1dd4b350
No related branches found
No related tags found
No related merge requests found
package MV3500Cohort2021JulySeptember.homework3.Frank;
import static com.google.common.collect.Multimaps.index;
import edu.nps.moves.dis7.enumerations.VariableRecordType;
import edu.nps.moves.dis7.pdus.CommentPdu;
import edu.nps.moves.dis7.pdus.EntityID;
import edu.nps.moves.dis7.pdus.EntityStatePdu;
import edu.nps.moves.dis7.pdus.FirePdu;
import edu.nps.moves.dis7.pdus.Pdu;
import edu.nps.moves.dis7.pdus.Vector3Double;
import edu.nps.moves.dis7.utilities.CoordinateConversions;
import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface;
import edu.nps.moves.dis7.utilities.PduFactory;
import edu.nps.moves.dis7.utilities.stream.PduRecorder;
import java.net.MulticastSocket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* The purpose of this program is to provide an easily modifiable example
* simulation program that includes DIS-capable entities doing tasks and
* reporting them to the network. Default settings include PDU recording turned
* on by default.
*/
public class FrankUdpServer {
/**
* This runSimulation() method is for you! This block is
* programmer-modifiable method for defining and running a new simulation of
* interest. Support include 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 new simulationists to use and adapt. All of the other
* methods are setup, teardown and configuration that you don't have to
* worry about.
*/
// ICBM coordinates for my office
double latitude = 36.595517;
double longitude = -121.877000;
@SuppressWarnings("SleepWhileInLoop")
public void runSimulation() {
try {
/**
* seconds for real-time execution (not simulation time, which may
* or may not be the same)
*/
// ICBM coordinates for my office
double latitude = 36.595517;
double longitude = -121.877000;
final double LOOP_DURATION_SECONDS = 1.0;
final int MAX_LOOP_COUNT = 10; // be deliberate out out there!
int loopCount = 0; // initialized at 0
boolean simulationComplete = false; // sentinel variable as termination condition,, are we done yet?
// TODO reset clock to zero each time for consistent outputs
// your model setup: who's who in this zoo?
// create PDU objects and set their values
EntityID entityID_1 = new EntityID();
entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID;
// TODO use enumerations; is there a unique site triplet for MOVES Institute?
EntityStatePdu entityStatePdu = pduFactory.makeEntityStatePdu();
entityStatePdu.setEntityID(entityID_1);
FirePdu firePdu = pduFactory.makeFirePdu();
// should we customize this munition? what is it for your simulation?
// TODO simulation management PDUs for startup
// loop the simulation while allowed, programmer can set additional conditions to break out and finish
int port = 3000;
MulticastSocket socket = null; // must be i
socket = new MulticastSocket(port);
while (loopCount < MAX_LOOP_COUNT) // are we done yet?
{
loopCount++; // good practice: increment loop counter as first action
// =============================================================================================
// 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.
entityStatePdu.getEntityLocation().setX(entityStatePdu.getEntityLocation().getX() + 1.0); // 1m per timestep
// decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoort at!
firePdu.setLocationInWorldCoordinates(entityStatePdu.getEntityLocation());
byte[] fireArray = firePdu.marshal();
System.out.println("FirePdu #" + loopCount + " firePdu=[FireMissionIndex=" + firePdu.getFireMissionIndex() + ", descriptor=" + firePdu.getDescriptor() + "]");
// etc. etc. your code goes here
// something happens between my simulation entities, la de da de da...
System.out.println("... My simulation just did something, no really...");
// make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending)
narrativeMessage1 = "MV3500 FrankUdpServer";
narrativeMessage2 = "runSimulation() loop " + loopCount;
narrativeMessage3 = ""; // intentionally blank for testing
// your loop termination condition goes here
if (loopCount > 4) // for example
{
simulationComplete = true;
}
// your own simulation code is finished here!
// =============================================================================================
// keep track of 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) (LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds
System.out.println("... [Pausing for " + LOOP_DURATION_SECONDS + " seconds]");
// send the status PDUs for this loop and continue
System.out.println("sending PDUs for simulation step " + loopCount + ", monitor loopback to confirm sent");
sendAllPdusForLoopTimestep(entityStatePdu, firePdu, timeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
System.out.println("... [PDUs successfully sent for this loop]");
// ===============================
// loop now finished, thus terminate if simulation complete, otherwise send latest PDUs and continue
if (simulationComplete || (loopCount > 10000)) // for example; including fail-safe condition is good
{
System.out.println("... [Termination condition met, simulationComplete=" + simulationComplete + "]"); // ", final loopCount=" + loopCount +
break;
}
} // end of while loop
// all done
narrativeMessage2 = "runSimulation() completed successfully";
sendCommentPdu(narrativeComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
System.out.println("... [final CommentPdu successfully sent for simulation]");
// TODO simulation management PDUs
} catch (InterruptedException iex) // handle any exception that your code might choose to provoke!
{
Logger.getLogger(FrankUdpServer.class.getName()).log(Level.SEVERE, null, iex);
} catch (Exception ex) {
}
}
/* **************************** infrastructure code, modification is seldom needed ************************* */
private boolean verboseComments = true;
String narrativeMessage1 = new String();
String narrativeMessage2 = new String();
String narrativeMessage3 = new String();
/* VariableRecordType enumerations have potential use with CommentPdu logs */
VariableRecordType descriptionComment = VariableRecordType.DESCRIPTION;
VariableRecordType narrativeComment = VariableRecordType.COMPLETE_EVENT_REPORT;
VariableRecordType statusComment = VariableRecordType.APPLICATION_STATUS;
VariableRecordType timeStepComment = VariableRecordType.APPLICATION_TIMESTEP;
VariableRecordType otherComment = VariableRecordType.OTHER;
/**
* Output prefix to identify this class, helps with logging
*/
private final static String TRACE_PREFIX = "[" + FrankUdpServer.class.getName() + "] ";
// class variables
PduFactory pduFactory = new PduFactory();
DisThreadedNetworkInterface disNetworkInterface;
DisThreadedNetworkInterface.PduListener pduListener;
Pdu receivedPdu;
static final String networkAddress_DEFAULT = "239.1.2.3";
static final int networkPort_DEFAULT = 3000;
static String networkAddress = networkAddress_DEFAULT;
static int networkPort = networkPort_DEFAULT;
/**
* Constructor design goal: additional built-in initialization conveniences
* can go here to keep student efforts focused on the runSimulation()
* method.
*/
public FrankUdpServer() {
// Constructor is under consideration. Constructor is not currently needed.
}
/**
* 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 FrankUdpServer(String address, int port) {
setNetworkAddress(address);
setNetworkPort(port);
}
/**
* @return the networkAddress
*/
public String getNetworkAddress() {
return networkAddress;
}
/**
* @param newNetworkAddress the networkAddress to set
*/
public final void setNetworkAddress(String newNetworkAddress) {
FrankUdpServer.networkAddress = newNetworkAddress;
}
/**
* @return the networkPort
*/
public int getNetworkPort() {
return networkPort;
}
/**
* @param newNetworkPort the networkPort to set
*/
public final void setNetworkPort(int newNetworkPort) {
FrankUdpServer.networkPort = newNetworkPort;
}
/**
* Initialize network interface, choosing best available network interface
*/
public void setUpNetworkInterface() {
disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort());
System.out.println("Network confirmation: address=" + disNetworkInterface.getMulticastGroup() + " port=" + disNetworkInterface.getDisPort());
pduListener = new DisThreadedNetworkInterface.PduListener() {
/**
* Callback handler for listener
*/
@Override
public void incomingPdu(Pdu newPdu) {
receivedPdu = newPdu;
}
};
disNetworkInterface.addListener(pduListener);
}
/**
* All done, release network resources
*/
public void tearDownNetworkInterface() {
disNetworkInterface.removeListener(pduListener);
disNetworkInterface.kill();
disNetworkInterface = null;
}
/**
* Send a single Protocol Data Unit (PDU) of any type
*
* @param pdu the pdu to send
*/
private 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 (int i = 0; i < comments.length; i++) {
if (!comments[i].isEmpty()) {
newCommentsList.add(comments[i]); // 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());
}
}
}
}
/**
* 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 arguments are an array of optional String
* parameters that are passed from execution environment during invocation
*/
public static void main(String[] args) {
System.out.println(TRACE_PREFIX + "started...");
FrankUdpServer thisProgram = new FrankUdpServer(); // creates instance
// initial execution: can 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().getName() + " [address port]");
System.exit(-1);
}
// OK here we go...
thisProgram.setUpNetworkInterface();
String DEFAULT_OUTPUT_DIRECTORY = "./pduLog";
String outputDirectory = DEFAULT_OUTPUT_DIRECTORY;
System.out.println("Beginning pdu save to directory " + outputDirectory);
//System.out.println(" latitude, longitude: [" + latitude + ", " + longitude + "]");
PduRecorder pduRecorder = new PduRecorder(outputDirectory, networkAddress, networkPort); // assumes save
thisProgram.runSimulation(); // ... your simulation execution code goes in there ...
pduRecorder.end();
thisProgram.tearDownNetworkInterface(); // make sure no processes are left lingering
System.out.println(TRACE_PREFIX + "complete."); // report successful completion
}
/**
* @return whether verboseComments mode is enabled
*/
public boolean isVerboseComments() {
return verboseComments;
}
/**
* @param newVerboseComments whether verboseComments mode is enabled
*/
public void setVerboseComments(boolean newVerboseComments) {
this.verboseComments = newVerboseComments;
}
}
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