diff --git a/examples/src/OpenDis7Examples/ExampleTrackInterpolation.java b/examples/src/OpenDis7Examples/ExampleTrackInterpolation.java index ad3eea5f969ca33f96d9b02bf7b2926b90c972a8..a4633ec3f1e5b5537cb36444f3721562b86f76c8 100644 --- a/examples/src/OpenDis7Examples/ExampleTrackInterpolation.java +++ b/examples/src/OpenDis7Examples/ExampleTrackInterpolation.java @@ -10,18 +10,33 @@ import edu.nps.moves.dis7.entities.swe.platform.surface._001Poseidon; import edu.nps.moves.dis7.enumerations.ForceID; import edu.nps.moves.dis7.pdus.EntityID; 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.stream.X3dCreateInterpolators; +import edu.nps.moves.dis7.utilities.stream.X3dCreateLineSet; +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 for networked entity tracks and presentation, including - * DIS-capable entities doing tasks and reporting them to the network. Default - * settings include PDU recording turned on by default. + * DIS-capable entities doing tasks and reporting them to the network. + * Default settings include PDU recording turned on by default. + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleTrackInterpolationLog.txt">ExampleTrackInterpolationLog.txt</a> + * @see <a href="https://calhoun.nps.edu/handle/10945/65436">REPEATABLE UNIT TESTING OF DISTRIBUTED INTERACTIVE SIMULATION (DIS) PROTOCOL BEHAVIOR STREAMS USING WEB STANDARDS</a> by Tobias Brennenstuhl, Masters Thesis, Naval Postgraduate School (NPS), June 2020 + * @see <a href="https://gitlab.nps.edu/Savage/SavageTheses/-/tree/master/BrennenstuhlTobias">https://gitlab.nps.edu/Savage/SavageTheses/-/tree/master/BrennenstuhlTobias</a> */ -public class ExampleTrackInterpolation extends ExampleSimulationProgram { - +public class ExampleTrackInterpolation extends ExampleSimulationProgram +{ + // -------------------- 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> pduList = new ArrayList<>(); + /** * This runSimulationLoops() method is a programmer-modifiable method for * defining and running a new simulation of interest. Welcome! Other parts @@ -61,8 +76,19 @@ public class ExampleTrackInterpolation extends ExampleSimulationProgram { espdu_1.clearMarking(); espdu_1.setMarking("track path"); espdu_1.getMarkingString(); // trace - espdu_1.setEntityLocation(new Vector3Double().setX(0).setY(0).setZ(0)); -// espdu_1.setEntityLocation(0, 0, 0); // utility method +// 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; + + // 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); + pduList.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 @@ -77,8 +103,7 @@ public class ExampleTrackInterpolation extends ExampleSimulationProgram { // 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. - EntityStatePdu.Direction directionEntity_1; + // 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) @@ -88,17 +113,13 @@ public class ExampleTrackInterpolation extends ExampleSimulationProgram { else // if (simulationLoopCount <= 40) directionEntity_1 = EntityStatePdu.Direction.WEST; - float speedEntity_1 = 1.0f; // meters/second + // 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); Vector3Double location = espdu_1.getEntityLocation(); - 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()) + ")"); // make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) narrativeMessage1 = "MV3500 TrackSimulationProgram"; @@ -119,7 +140,7 @@ public class ExampleTrackInterpolation extends ExampleSimulationProgram { if (false) // real-time operation or simulation speedup { Thread.sleep((long) (currentTimeStep * 1000)); // seconds * (1000 msec/sec) = milliseconds - System.out.println("... [Pausing for " + currentTimeStep + " seconds]"); + System.out.println(TRACE_PREFIX + "Pausing for " + currentTimeStep + " seconds"); } // OK now send the status PDUs for this loop, and then continue @@ -128,21 +149,24 @@ public class ExampleTrackInterpolation extends ExampleSimulationProgram { sendSinglePdu(espdu_1); sendCommentPdu(currentTimeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3); if (pduRecorder.hasVerboseOutput()) - System.out.println("... [PDUs successfully sent for this loop]"); - + System.out.println(TRACE_PREFIX + "PDUs successfully sent for this loop"); + pduList.add(espdu_1); + reportPdu(simulationLoopCount, location, directionEntity_1); + // =============================== // 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("... [Termination condition met, simulationComplete=" + simulationComplete + "]"); // ", final loopCount=" + loopCount + + 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, pduList.size()=" + pduList.size()); + narrativeMessage2 = "runSimulation() completed successfully"; // all done sendCommentPdu(narrativeComment, narrativeMessage1, narrativeMessage2, narrativeMessage3); if (pduRecorder.hasVerboseOutput()) - System.out.println("... [final CommentPdu successfully sent for simulation]"); + 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! @@ -150,6 +174,23 @@ public class ExampleTrackInterpolation extends ExampleSimulationProgram { Logger.getLogger(ExampleTrackInterpolation.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 + */ + public void 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() + ); + } /* Default constructors used unless otherwise defined/overridden. */ /** diff --git a/examples/src/OpenDis7Examples/ExampleTrackInterpolationLog.txt b/examples/src/OpenDis7Examples/ExampleTrackInterpolationLog.txt index a237a45ff4f6e4348b2071e7b32c759edf859c1c..f045873beef8fc7fe6e72185691ea0120e90c5c4 100644 --- a/examples/src/OpenDis7Examples/ExampleTrackInterpolationLog.txt +++ b/examples/src/OpenDis7Examples/ExampleTrackInterpolationLog.txt @@ -13,59 +13,61 @@ DisThreadedNetworkInterface createThreads() receiveThread.isAlive()=true DisThreadedNetworkInterface createThreads() sendingThread.isAlive()=true Network confirmation: address=239.1.2.3 port=3000 Beginning pdu save to directory ./pduLog -Recorder log file open: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog93.dislog +Recorder log file open: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog112.dislog [DisThreadedNetworkInterface] using network interface Intel(R) Wi-Fi 6E AX210 160MHz [DisThreadedNetworkInterface] datagramSocket.joinGroup address=239.1.2.3 port=3000 isConnected()=false createDatagramSocket() complete. DisThreadedNetworkInterface createThreads() receiveThread.isAlive()=true DisThreadedNetworkInterface createThreads() sendingThread.isAlive()=true [PduRecorder PduRecorder] listening to IP address 239.1.2.3 on port 3000 - 1 Entity location=( 0.0, 1.0, 0.0) - 2 Entity location=( 0.0, 2.0, 0.0) - 3 Entity location=( 0.0, 3.0, 0.0) - 4 Entity location=( 0.0, 4.0, 0.0) - 5 Entity location=( 0.0, 5.0, 0.0) - 6 Entity location=( 0.0, 6.0, 0.0) - 7 Entity location=( 0.0, 7.0, 0.0) - 8 Entity location=( 0.0, 8.0, 0.0) - 9 Entity location=( 0.0, 9.0, 0.0) -10 Entity location=( 0.0, 10.0, 0.0) -11 Entity location=( 1.0, 10.0, 0.0) -12 Entity location=( 2.0, 10.0, 0.0) -13 Entity location=( 3.0, 10.0, 0.0) -14 Entity location=( 4.0, 10.0, 0.0) -15 Entity location=( 5.0, 10.0, 0.0) -16 Entity location=( 6.0, 10.0, 0.0) -17 Entity location=( 7.0, 10.0, 0.0) -18 Entity location=( 8.0, 10.0, 0.0) -19 Entity location=( 9.0, 10.0, 0.0) -20 Entity location=(10.0, 10.0, 0.0) -21 Entity location=(10.0, 9.0, 0.0) -22 Entity location=(10.0, 8.0, 0.0) -23 Entity location=(10.0, 7.0, 0.0) -24 Entity location=(10.0, 6.0, 0.0) -25 Entity location=(10.0, 5.0, 0.0) -26 Entity location=(10.0, 4.0, 0.0) -27 Entity location=(10.0, 3.0, 0.0) -28 Entity location=(10.0, 2.0, 0.0) -29 Entity location=(10.0, 1.0, 0.0) -30 Entity location=(10.0, 0.0, 0.0) -31 Entity location=( 9.0, 0.0, 0.0) -32 Entity location=( 8.0, 0.0, 0.0) -33 Entity location=( 7.0, 0.0, 0.0) -34 Entity location=( 6.0, 0.0, 0.0) -35 Entity location=( 5.0, 0.0, 0.0) -36 Entity location=( 4.0, 0.0, 0.0) -37 Entity location=( 3.0, 0.0, 0.0) -38 Entity location=( 2.0, 0.0, 0.0) -39 Entity location=( 1.0, 0.0, 0.0) -40 Entity location=( 0.0, 0.0, 0.0) -... [Termination condition met, simulationComplete=true] + 0 Entity location=( 0.0, 0.0, 0.0) NORTH + 1 Entity location=( 0.0, 1.0, 0.0) NORTH + 2 Entity location=( 0.0, 2.0, 0.0) NORTH + 3 Entity location=( 0.0, 3.0, 0.0) NORTH + 4 Entity location=( 0.0, 4.0, 0.0) NORTH + 5 Entity location=( 0.0, 5.0, 0.0) NORTH + 6 Entity location=( 0.0, 6.0, 0.0) NORTH + 7 Entity location=( 0.0, 7.0, 0.0) NORTH + 8 Entity location=( 0.0, 8.0, 0.0) NORTH + 9 Entity location=( 0.0, 9.0, 0.0) NORTH +10 Entity location=( 0.0, 10.0, 0.0) NORTH +11 Entity location=( 1.0, 10.0, 0.0) EAST +12 Entity location=( 2.0, 10.0, 0.0) EAST +13 Entity location=( 3.0, 10.0, 0.0) EAST +14 Entity location=( 4.0, 10.0, 0.0) EAST +15 Entity location=( 5.0, 10.0, 0.0) EAST +16 Entity location=( 6.0, 10.0, 0.0) EAST +17 Entity location=( 7.0, 10.0, 0.0) EAST +18 Entity location=( 8.0, 10.0, 0.0) EAST +19 Entity location=( 9.0, 10.0, 0.0) EAST +20 Entity location=(10.0, 10.0, 0.0) EAST +21 Entity location=(10.0, 9.0, 0.0) SOUTH +22 Entity location=(10.0, 8.0, 0.0) SOUTH +23 Entity location=(10.0, 7.0, 0.0) SOUTH +24 Entity location=(10.0, 6.0, 0.0) SOUTH +25 Entity location=(10.0, 5.0, 0.0) SOUTH +26 Entity location=(10.0, 4.0, 0.0) SOUTH +27 Entity location=(10.0, 3.0, 0.0) SOUTH +28 Entity location=(10.0, 2.0, 0.0) SOUTH +29 Entity location=(10.0, 1.0, 0.0) SOUTH +30 Entity location=(10.0, 0.0, 0.0) SOUTH +31 Entity location=( 9.0, 0.0, 0.0) WEST +32 Entity location=( 8.0, 0.0, 0.0) WEST +33 Entity location=( 7.0, 0.0, 0.0) WEST +34 Entity location=( 6.0, 0.0, 0.0) WEST +35 Entity location=( 5.0, 0.0, 0.0) WEST +36 Entity location=( 4.0, 0.0, 0.0) WEST +37 Entity location=( 3.0, 0.0, 0.0) WEST +38 Entity location=( 2.0, 0.0, 0.0) WEST +39 Entity location=( 1.0, 0.0, 0.0) WEST +40 Entity location=( 0.0, 0.0, 0.0) WEST +[OpenDis7Examples.ExampleTrackInterpolation] loop termination condition met, simulationComplete=true +[OpenDis7Examples.ExampleTrackInterpolation] all PDUs successfully sent for this loop, pduList.size()=41 *** setKillSentinelAndInterrupts() killed=true sendingThread.isInterrupted()=true receiveThread.isInterrupted()=true *** DisThreadedNetworkInterface close(): pdus2send.size()=0 baos.size()=0 dos.size()=0 *** killThread() status: sendingThread.isAlive()=false sendingThread.isInterrupted()=true *** killThread() status: receiveThread.isAlive()=false receiveThread.isInterrupted()=true *** Thread close status: sendingThread.isAlive()=false receiveThread.isAlive()=false -Closing recorder log file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog93.dislog +Closing recorder log file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog112.dislog [OpenDis7Examples.ExampleTrackInterpolation] complete. -BUILD SUCCESSFUL (total time: 11 seconds) +BUILD SUCCESSFUL (total time: 12 seconds)