From b304c25beaccb296234cb1baf176cb93fdb29305 Mon Sep 17 00:00:00 2001
From: brutzman <brutzman@nps.edu>
Date: Thu, 23 Dec 2021 16:29:04 -0800
Subject: [PATCH] initial stub program subclassing ExampleSimulationProgram

---
 .../ExampleTrackInterpolation.java            | 183 ++++++++++++++++++
 1 file changed, 183 insertions(+)
 create mode 100644 examples/src/OpenDis7Examples/ExampleTrackInterpolation.java

diff --git a/examples/src/OpenDis7Examples/ExampleTrackInterpolation.java b/examples/src/OpenDis7Examples/ExampleTrackInterpolation.java
new file mode 100644
index 0000000000..8c15c558b6
--- /dev/null
+++ b/examples/src/OpenDis7Examples/ExampleTrackInterpolation.java
@@ -0,0 +1,183 @@
+/**
+ * Copyright (c) 2008-2021, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved.
+ * This work is provided under a BSD open-source license, see project license.html and license.txt
+ *
+ * @author brutzman@nps.edu
+ */
+package OpenDis7Examples;
+
+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.ForceID;
+import edu.nps.moves.dis7.pdus.EntityID;
+import edu.nps.moves.dis7.pdus.EntityStatePdu;
+import edu.nps.moves.dis7.pdus.FirePdu;
+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.
+ */
+public class ExampleTrackInterpolation extends ExampleSimulationProgram {
+
+    /**
+     * Output prefix to identify this class (override in subclass), helps with
+     * logging
+     */
+    private final static String TRACE_PREFIX = "[" + ExampleTrackInterpolation.class.getName() + "] ";
+
+    /**
+     * 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 = 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 to zero each time for consistent outputs
+            simulationTime = initialTime - currentTimeStep; // pre-initialization for first loop
+            
+            // 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.
+            // create PDU objects and set their values.
+            EntityID entityID_1 = new EntityID();
+            entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID;
+            // create PDU objects and set their values.
+            EntityID entityID_2 = new EntityID();
+            entityID_1.setSiteID(1).setApplicationID(2).setEntityID(4); // made-up example ID;
+            // TODO someday, use enumerations; is there a unique site triplet for MOVES Institute?
+
+            EntityStatePdu entityStatePdu_1 = pduFactory.makeEntityStatePdu();
+            entityStatePdu_1.setEntityID(entityID_1);
+            entityStatePdu_1.setForceId(ForceID.FRIENDLY);
+            entityStatePdu_1.setEntityType(new _001Poseidon()); // note import statement above
+
+            EntityStatePdu entityStatePdu_2 = pduFactory.makeEntityStatePdu();
+            entityStatePdu_2.setEntityID(entityID_2);
+            entityStatePdu_2.setForceId(ForceID.OPPOSING);
+            entityStatePdu_2.setEntityType(new _002Triton()); // note import statement above
+
+            FirePdu firePdu_1a = pduFactory.makeFirePdu(); // for entity 1 first  weapon (if any)
+//      FirePdu        firePdu_1b       = pduFactory.makeFirePdu(); // for entity 1 second weapon (if any)
+            // should we customize this munition?  what is it for your simulation?
+
+            // 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...
+                // 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
+//                entityStatePdu_1.setTimestamp(simulationTime);
+
+                // 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...");
+
+                // 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 > 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");
+                sendAllPdusForLoopTimestep(entityStatePdu_1, firePdu_1a, timeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
+                sendSinglePdu(entityStatePdu_2); // me too i.e. 2!
+                System.out.println("... [PDUs successfully sent for this loop]");
+
+                // ===============================
+                // 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 +
+                    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
+        } catch (InterruptedException iex) // handle any exception that your code might choose to provoke!
+        {
+            Logger.getLogger(ExampleTrackInterpolation.class.getName()).log(Level.SEVERE, null, iex);
+        }
+    }
+
+    /* 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) {
+        System.out.println(TRACE_PREFIX + "main() started...");
+
+        ExampleTrackInterpolation thisProgram = new ExampleTrackInterpolation(); // creates instance within static main() method
+
+        // 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);
+        }
+        // OK here we go...
+
+        thisProgram.setUpNetworkInterface();
+
+        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
+    }
+
+}
-- 
GitLab