diff --git a/assignments/src/MV3500Cohort2022MayJune/homework2/Ashmore/ExampleTrackInterpolationAshmore.java b/assignments/src/MV3500Cohort2022MayJune/homework2/Ashmore/ExampleTrackInterpolationAshmore.java new file mode 100644 index 0000000000000000000000000000000000000000..0a2b26f9b14a6dc7f8987f935dc84241e280164f --- /dev/null +++ b/assignments/src/MV3500Cohort2022MayJune/homework2/Ashmore/ExampleTrackInterpolationAshmore.java @@ -0,0 +1,246 @@ + +package MV3500Cohort2022MayJune.homework2.Ashmore; + +import edu.nps.moves.dis7.entities.swe.platform.surface._001Poseidon; +import edu.nps.moves.dis7.enumerations.ForceID; +import edu.nps.moves.dis7.pdus.EntityStatePdu; +import edu.nps.moves.dis7.pdus.Pdu; +import edu.nps.moves.dis7.pdus.Vector3Double; +import edu.nps.moves.dis7.utilities.DisTime; +import edu.nps.moves.dis7.utilities.stream.X3dCreateInterpolators; +import edu.nps.moves.dis7.utilities.stream.X3dCreateLineSet; +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ExampleTrackInterpolationAshmore extends ExampleSimulationProgramAshmore +{ + // -------------------- Begin Variables for X3D autogenerated code + private X3dCreateInterpolators x3dInterpolators = new X3dCreateInterpolators(); + private X3dCreateLineSet x3dLineSet = new X3dCreateLineSet(); + private byte[] globalByteBufferForX3dInterpolators = null; + // -------------------- End Variables for X3D autogenerated code + + ArrayList<Pdu> pduSentList = new ArrayList<>(); + + /** + * This runSimulationLoops() method is a programmer-modifiable method 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 + @Override // indicates that this method supercedes corresponding superclass method + public void runSimulationLoops() + { + try + { + final int SIMULATION_MAX_LOOP_COUNT = 100; // 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 + DisTime.setEpochLvcNow(); + simulationTime = initialTime - currentTimeStep; // pre-initialization for first loop + + initializeSimulationEntities(); + + // use declared PDU objects and set their values. + entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID; + // TODO someday, use enumerations; is there a unique site triplet for MOVES Institute? + + pduRecorder.setVerbose(false); + pduRecorder.hasVerboseOutput(); // debug check + + EntityStatePdu espdu_1 = pduFactory.makeEntityStatePdu(); + espdu_1.setEntityID(entityID_1); + espdu_1.setForceId(ForceID.FRIENDLY); + espdu_1.setEntityType(new _001Poseidon()); // note import statement above + espdu_1.setMarking("track path"); +// espdu_1.clearMarking(); // test +// espdu_1.getMarkingString(); // trace +// espdu_1.setEntityLocation(new Vector3Double().setX(0).setY(0).setZ(0)); // long form + espdu_1.setEntityLocation(0, 0, 0); // utility method + + float speedEntity_1 = 1.0f; // meters/second + EntityStatePdu.Direction directionEntity_1 = EntityStatePdu.Direction.NORTH; + + PduTrack pduTrack_1 = new PduTrack(); + pduTrack_1.setDescriptor("Ashmore testing 123"); + pduTrack_1.setDefaultWaypointInterval(1.0f); // overrides timestamps + pduTrack_1.setAddLineBreaksWithinKeyValues(true); + pduTrack_1.setAuthor("Michael Ashmore"); + pduTrack_1.setX3dModelName("ExampleTrackInterpolation.x3d"); + pduTrack_1.setX3dModelIdentifier("https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleTrackInterpolation.x3d"); + pduTrack_1.addPdu(espdu_1); // initial location + + // OK send initial PDUs prior to loop + if (pduRecorder.hasVerboseOutput()) + System.out.println("sending PDUs for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); + sendSinglePdu(espdu_1); +// sendCommentPdu(currentTimeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3); + pduSentList.add(espdu_1); + reportPdu(simulationLoopCount, espdu_1.getEntityLocation(), directionEntity_1); + + // TODO simulation management PDUs for startup, planning to design special class support + // =================================================================================================== + // 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 + simulationTime += currentTimeStep; // good practice: update clock along with loop index + + // ============================================================================================= + // * 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... + + // Pick direction, change each 10 seconds, traverse a box. No physics. Walk a box! + if (simulationLoopCount <= 10) + directionEntity_1 = EntityStatePdu.Direction.NORTH; + else if (simulationLoopCount <= 20) + directionEntity_1 = EntityStatePdu.Direction.EAST; + else if (simulationLoopCount <= 30) + directionEntity_1 = EntityStatePdu.Direction.SOUTH; + else // if (simulationLoopCount <= 40) + directionEntity_1 = EntityStatePdu.Direction.WEST; + + // use utility method to simply update velocity vector using speed value and direction + espdu_1.setEntityLinearVelocity(speedEntity_1, directionEntity_1); + + // Where is my entity? Insert changes in position; this sample only changes X position. + espdu_1.advanceEntityLocation(currentTimeStep); + + // make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) + narrativeMessage1 = "MV3500 TrackSimulationProgram"; + narrativeMessage2 = "runSimulation() loop " + simulationLoopCount + " at time " + simulationTime; + narrativeMessage3 = ""; // intentionally blank for testing + + // your loop termination condition goes here + if (simulationLoopCount > 40) // 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 + if (false) // real-time operation or simulation speedup + { + Thread.sleep((long) (currentTimeStep * 1000)); // seconds * (1000 msec/sec) = milliseconds + System.out.println(TRACE_PREFIX + "Pausing for " + currentTimeStep + " seconds"); + } + + // OK now send the status PDUs for this loop, and then continue + if (pduRecorder.hasVerboseOutput()) + System.out.println("sending PDUs for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); + sendSinglePdu(espdu_1); + sendCommentPdu(currentTimeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3); + if (pduRecorder.hasVerboseOutput()) + System.out.println(TRACE_PREFIX + "PDUs successfully sent for this loop"); + pduSentList.add(espdu_1); + pduTrack_1.addPdu(espdu_1); + Vector3Double location = espdu_1.getEntityLocation(); + reportPdu(simulationLoopCount, location, directionEntity_1); + + // =============================== + // 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(TRACE_PREFIX + "loop termination condition met, simulationComplete=" + simulationComplete); // ", final loopCount=" + loopCount + + break; + } + } // end of simulation loop + // =================================================================================================== + System.out.println(TRACE_PREFIX + "all PDUs successfully sent for this loop (pduSentList.size()=" + pduSentList.size() + " total)"); + + // track analysis + System.out.println(TRACE_PREFIX + "pduTrack_1 initialLocation=" + pduTrack_1.getInitialLocation() + ", latestLocation=" + pduTrack_1.getLatestLocation()); + pduTrack_1.sortPdus() + .createRawWaypoints(); + + System.out.println("pduTrack_1 getEspduCount()=" + pduTrack_1.getEspduCount()); + System.out.println("pduTrack_1 duration = " + pduTrack_1.getTotalDurationSeconds() + " seconds = " + + pduTrack_1.getTotalDurationTicks() + " ticks"); + System.out.println("================================="); + System.out.println(pduTrack_1.createX3dModel()); + System.out.println("================================="); + + narrativeMessage2 = "runSimulation() completed successfully"; // all done + sendCommentPdu(narrativeComment, narrativeMessage1, narrativeMessage2, narrativeMessage3); + if (pduRecorder.hasVerboseOutput()) + System.out.println(TRACE_PREFIX + "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(ExampleTrackInterpolationDuran.class.getName()).log(Level.SEVERE, null, iex); + } + } + + /** + * Report current PDU information to console + * @param simulationLoopCount current loop index + * @param location current location + * @param directionEntity current direction + * @return same object to permit progressive setters + */ + public ExampleTrackInterpolationDuran reportPdu(int simulationLoopCount, Vector3Double location, EntityStatePdu.Direction directionEntity) + { + System.out.println (String.format("%2d ", simulationLoopCount) + "Entity location=(" + + String.format("%4.1f", location.getX()) + ", " + + String.format("%4.1f", location.getY()) + ", " + + String.format("%4.1f", location.getZ()) + ") " + + String.format("%-5s", directionEntity.name()) +// + " " + espdu_1.getEntityLinearVelocity().toString() + ); + return this; + } + + /* Default constructors used unless otherwise defined/overridden. */ + /** + * 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) + { + TRACE_PREFIX = "[" + ExampleTrackInterpolationDuran.class.getName() + "] "; + + System.out.println(TRACE_PREFIX + "main() started..."); + + thisProgram = new ExampleTrackInterpolationDuran(); // 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.pduRecorder.setVerbose(false); + thisProgram.setVerboseComments(false); + thisProgram.disNetworkInterface.setVerbose(false); + + 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 + } + +}