diff --git a/assignments/nbproject/project.properties b/assignments/nbproject/project.properties index 8f08c9c4cf2cb8320053f3fc6b9d231b7f56fc1d..58458faeae7e33494078e93d20fe58c9ab4e9521 100644 --- a/assignments/nbproject/project.properties +++ b/assignments/nbproject/project.properties @@ -70,8 +70,8 @@ javac.modulepath= javac.processormodulepath= javac.processorpath=\ ${javac.classpath} -javac.source=20 -javac.target=20 +javac.source=22 +javac.target=22 javac.test.classpath=\ ${javac.classpath}:\ ${build.classes.dir} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Server_HW2.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Server_HW2.java index 36ed7fa156d1c6f7b6fbc568214f51ce66937633..b54646d3c91cd0a6731e514bf090576fb8379c2e 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Server_HW2.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Server_HW2.java @@ -1,60 +1,63 @@ -package MV3500Cohort2024JulySeptember.homework2.Timberlake; - -import java.net.ServerSocket; -import java.net.Socket; - -/** - * This server program works a bit differently by creating and dispatching a - * new thread to handle multiple incoming socket connections, one after another, all running in parallel. - * This advanced technique is often used in high=performance high=capacity server programs. - * - * @see Client_HW2 - * @see GameHandler - * - * @see <a href="../../../src/TcpExamples/TcpExample4TerminalLog.txt" target="blank">TcpExample4TerminalLog.txt</a> - * @see <a href="../../../src/TcpExamples/TcpExample4SequenceDiagram.png" target="blank">TcpExample4SequenceDiagram.png</a> - * @see <a href="../../../src/TcpExamples/TcpExample4SequenceSketch.png" target="blank">TcpExample4SequenceSketch.png</a> - * - * @author Don McGregor - * @author Don Brutzman - * @author MV3500 class - * @author Jack Timberlake - */ - - -public class Server_HW2 { - public static void main(String[] args) { - ServerSocket serverSocket = null; - - try { - // Create a socket to listen on port 9876 - serverSocket = new ServerSocket(9876); - System.out.println("Server has started, waiting for client..."); - - while (true) { - // Accept client connection - Socket clientSocket = serverSocket.accept(); - System.out.println("Client connected"); - - // Create GameHandler to handle client - GameHandler gameHandler = new GameHandler(clientSocket); - - // Create new thread to handle the game - Thread thread = new Thread(gameHandler); - thread.start(); - } - } catch (Exception e) { - e.printStackTrace(); // Print any exceptions that occur - } finally { - try { - if (serverSocket != null && !serverSocket.isClosed()) { - serverSocket.close(); // Close the server socket to release resources - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } -} - - +package MV3500Cohort2024JulySeptember.homework2.Timberlake; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * This server program works a bit differently by creating and dispatching a + * new thread to handle multiple incoming socket connections, one after another, all running in parallel. + * This advanced technique is often used in high=performance high=capacity server programs. + * + * @see Client_HW2 + * @see GameHandler + * + * @see <a href="../../../src/TcpExamples/TcpExample4TerminalLog.txt" target="blank">TcpExample4TerminalLog.txt</a> + * @see <a href="../../../src/TcpExamples/TcpExample4SequenceDiagram.png" target="blank">TcpExample4SequenceDiagram.png</a> + * @see <a href="../../../src/TcpExamples/TcpExample4SequenceSketch.png" target="blank">TcpExample4SequenceSketch.png</a> + * + * @author Don McGregor + * @author Don Brutzman + * @author MV3500 class + * @author Jack Timberlake + */ + + +public class Server_HW2 { + /** The main method launches the program from the command line, no parameters needed. + * @param args command-line arguments, none needed */ + public static void main(String[] args) { + ServerSocket serverSocket = null; + + try { + // Create a socket to listen on port 9876 + serverSocket = new ServerSocket(9876); + System.out.println("Server has started, waiting for client..."); + + while (true) { + // Accept client connection + Socket clientSocket = serverSocket.accept(); + System.out.println("Client connected"); + + // Create GameHandler to handle client + GameHandler gameHandler = new GameHandler(clientSocket); + + // Create new thread to handle the game + Thread thread = new Thread(gameHandler); + thread.start(); + } + } catch (IOException e) { + e.printStackTrace(); // Print any exceptions that occur + } finally { + try { + if (serverSocket != null && !serverSocket.isClosed()) { + serverSocket.close(); // Close the server socket to release resources + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} + + diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Bavlsik/BavlsikSimulationProgram.java b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Bavlsik/BavlsikSimulationProgram.java index 21463b4b64c6d4eb2a053c2a1898c19a55037271..639f00e31ed161214408f294d8f1df3f942e51b6 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Bavlsik/BavlsikSimulationProgram.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Bavlsik/BavlsikSimulationProgram.java @@ -1,7 +1,9 @@ /** * Copyright (c) 2008-2023, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. * This work is provided under a BSD open-source license, see project license.html or license.txt + * * @author brutzman@nps.edu + * @author timothy.bavlsik@nps.edu */ package MV3500Cohort2024JulySeptember.homework3.Bavlsik; @@ -12,156 +14,194 @@ import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.utilities.DisChannel; import edu.nps.moves.dis7.utilities.PduFactory; import java.time.LocalDateTime; +import java.util.Random; import java.util.logging.Level; import java.util.logging.Logger; -/** The purpose of this inheritable class is to provide an easily modifiable - * example simulation program that includes DIS-capable entities performing - * tasks of interest, and then reporting activity via PDUs to the network. - * Default program initialization includes PDU recording turned on by default. - * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt" target="_blank">ExampleSimulationProgramLog.txt</a> - * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramPduCaptureLog.dislog" target="_blank">ExampleSimulationProgramPduCaptureLog.dislog</a> - * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.pdf" target="_blank">ExampleSimulationProgramFlowDiagram.pdf</a> - * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramWireshark.png" target="_blank">ExampleSimulationProgramWireshark.png</a> - * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png" target="_blank">ExampleSimulationProgramSequenceDiagram.png</a> +/** + * This program runs a simulation that initializes two entities, of which one will + * attempt to find and destroy the other, and one which will flee the other entity. + * Default program initialization includes PDU recording turned on by default. + * + * @see + * <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt" target="_blank">ExampleSimulationProgramLog.txt</a> + * @see + * <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramPduCaptureLog.dislog" target="_blank">ExampleSimulationProgramPduCaptureLog.dislog</a> + * @see + * <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.pdf" target="_blank">ExampleSimulationProgramFlowDiagram.pdf</a> + * @see + * <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramWireshark.png" target="_blank">ExampleSimulationProgramWireshark.png</a> + * @see + * <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png" target="_blank">ExampleSimulationProgramSequenceDiagram.png</a> */ -public class BavlsikSimulationProgram -{ +public class BavlsikSimulationProgram { + /* **************************** infrastructure code, modification is seldom needed ************************* */ - - private String descriptor = this.getClass().getSimpleName(); - /** DIS channel defined by network address/port combination includes multiple utility capabilities */ + + private String descriptor = this.getClass().getSimpleName(); + /** + * DIS channel defined by network address/port combination includes multiple + * utility capabilities + */ protected DisChannel disChannel; - /** Factory object used to create new PDU instances */ + /** + * Factory object used to create new PDU instances + */ protected PduFactory pduFactory; - - /** seconds per loop for real-time or simulation execution */ - private double simulationTimeStepDuration = 1.0; // seconds TODO encapsulate - /** initial simulation time in seconds */ - double simulationTimeInitial = 0.0; - /** current simulation time in seconds */ - double simulationTimeSeconds = simulationTimeInitial; - /** Maximum number of simulation loops */ + + /** + * seconds per loop for real-time or simulation execution + */ + private double simulationTimeStepDuration = 1.0; // seconds TODO encapsulate + /** + * initial simulation time in seconds + */ + double simulationTimeInitial = 0.0; + /** + * current simulation time in seconds + */ + double simulationTimeSeconds = simulationTimeInitial; + /** + * Maximum number of simulation loops + */ int MAX_LOOP_COUNT = 4; - + String narrativeMessage1 = new String(); String narrativeMessage2 = new String(); String narrativeMessage3 = new String(); - - /** 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; - /** ESPDU for entity 2 */ - protected EntityStatePdu entityStatePdu_2; - /** FirePdu for entity 1 first weapon (if any) */ - protected FirePdu firePdu_1a; - /** FirePdu for entity 1 second weapon (if any) */ - protected FirePdu firePdu_1b; - /** MunitionDescriptor for these weapons */ + + /** + * 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; + /** + * ESPDU for entity 2 + */ + protected EntityStatePdu entityStatePdu_2; + /** + * FirePdu for entity 1 first weapon (if any) + */ + protected FirePdu firePdu_1a; + /** + * FirePdu for entity 1 second weapon (if any) + */ + protected FirePdu firePdu_1b; + /** + * MunitionDescriptor for these weapons + */ protected MunitionDescriptor munitionDescriptor1; - + // hey programmer, what other state do you want? this is a good place to declare it... - /** - * Constructor to create an instance of this class. - * Design goal: additional built-in initialization conveniences can go here - * to keep your efforts focused on the runSimulation() method. + * Constructor to create an instance of this class. Design goal: additional + * built-in initialization conveniences can go here to keep your efforts + * focused on the runSimulation() method. */ // base constructor is not invoked automatically by other constructors // https://stackoverflow.com/questions/581873/best-way-to-handle-multiple-constructors-in-java - public BavlsikSimulationProgram() - { + public BavlsikSimulationProgram() { initialize(); } + /** * Constructor to create an instance of this class. - * @param newDescriptor describes this program, useful for logging and debugging + * + * @param newDescriptor describes this program, useful for logging and + * debugging */ - public BavlsikSimulationProgram(String newDescriptor) - { + public BavlsikSimulationProgram(String newDescriptor) { descriptor = newDescriptor; initialize(); } + /** - * Utility Constructor that allows your example simulation program to override default network address and port + * 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 BavlsikSimulationProgram(String address, int port) - { - disChannel.setNetworkAddress (address); - disChannel.setNetworkPort (port); - disChannel.setVerboseComments (true); // TODO rename library method to disambiguate CommentPDU - // TODO still seems really chatty... add silent mode? + public BavlsikSimulationProgram(String address, int port) { + disChannel.setNetworkAddress(address); + disChannel.setNetworkPort(port); + disChannel.setVerboseComments(true); // TODO rename library method to disambiguate CommentPDU + // TODO still seems really chatty... add silent mode? disChannel.setVerboseDisNetworkInterface(true); // Default false - disChannel.setVerbosePduRecorder (true); // default false + disChannel.setVerbosePduRecorder(true); // default false initialize(); } - - /** Initialize channel setup for OpenDis7 and report a test PDU + + /** + * Initialize channel setup for OpenDis7 and report a test PDU + * * @see initializeDisChannel - * @see initializeSimulationEntities */ - private void initialize() - { + * @see initializeSimulationEntities + */ + private void initialize() { initializeDisChannel(); // must come first, uses PduFactory - + initializeSimulationEntities(); // set unchanging parameters - + disChannel.join(); // TODO further functionality expected - + String timeStepMessage = "Simulation timestep duration " + getSimulationTimeStepDuration() + " seconds"; disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_SIMULATION_TIMESTEP, timeStepMessage); // additional constructor initialization can go here } - - /** Initialize channel setup for OpenDis7 and report a test PDU */ - private void initializeDisChannel() - { - if (disChannel == null) + + /** + * Initialize channel setup for OpenDis7 and report a test PDU + */ + private void initializeDisChannel() { + if (disChannel == null) { disChannel = new DisChannel(); - else - { - disChannel.printlnTRACE ("*** warning, duplicate invocation of initializeDisChannel() ignored"); + } else { + disChannel.printlnTRACE("*** warning, duplicate invocation of initializeDisChannel() ignored"); return; } - pduFactory = disChannel.getPduFactory(); + pduFactory = disChannel.getPduFactory(); disChannel.setDescriptor(this.getClass().getSimpleName()); // ExampleSimulationProgram might be a superclass disChannel.setUpNetworkInterface(); - disChannel.printlnTRACE ("just checking: disChannel.getNetworkAddress()=" + disChannel.getNetworkAddress() + - ", getNetworkPort()=" + disChannel.getNetworkPort()); - disChannel.getDisNetworkInterface().setVerbose(true); // sending and receipt - disChannel.printlnTRACE ("just checking: hasVerboseSending()=" + disChannel.getDisNetworkInterface().hasVerboseSending() + - ", hasVerboseReceipt()=" + disChannel.getDisNetworkInterface().hasVerboseReceipt()); - disChannel.getPduRecorder().setVerbose(true); + disChannel.printlnTRACE("just checking: disChannel.getNetworkAddress()=" + disChannel.getNetworkAddress() + + ", getNetworkPort()=" + disChannel.getNetworkPort()); + disChannel.getDisNetworkInterface().setVerbose(false); // sending and receipt + disChannel.printlnTRACE("just checking: hasVerboseSending()=" + disChannel.getDisNetworkInterface().hasVerboseSending() + + ", hasVerboseReceipt()=" + disChannel.getDisNetworkInterface().hasVerboseReceipt()); + disChannel.getPduRecorder().setVerbose(false); // TODO confirm whether recorder is explicitly started by programmer (or not) - // disChannel.sendCommentPdu(VariableRecordType.OTHER, "DisThreadedNetworkInterface.initializeDisChannel() complete"); // hello channel, debug } - - /** Get ready, get set... initialize simulation entities. Who's who in the zoo? + + /** + * Get ready, get set... initialize simulation entities. Who's who in the + * zoo? */ - public void initializeSimulationEntities() - { - if (pduFactory == null) - pduFactory = disChannel.getPduFactory(); - entityStatePdu_1 = pduFactory.makeEntityStatePdu(); - entityStatePdu_2 = pduFactory.makeEntityStatePdu(); - firePdu_1a = pduFactory.makeFirePdu(); - firePdu_1b = pduFactory.makeFirePdu(); + public void initializeSimulationEntities() { + if (pduFactory == null) { + pduFactory = disChannel.getPduFactory(); + } + entityStatePdu_1 = pduFactory.makeEntityStatePdu(); + entityStatePdu_2 = pduFactory.makeEntityStatePdu(); + firePdu_1a = pduFactory.makeFirePdu(); + firePdu_1b = pduFactory.makeFirePdu(); munitionDescriptor1 = new MunitionDescriptor(); - + // 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 declared and instances created, so now set their values. // who is who in our big zoo, sufficient for global participation if we need it entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID; disChannel.addEntity(entityID_1); - + entityID_2.setSiteID(1).setApplicationID(2).setEntityID(4); // made-up example ID; disChannel.addEntity(entityID_2); // TODO someday, use enumerations for sites as part of a SimulationManager object; e.g. is there a unique site triplet for MOVES Institute? @@ -178,181 +218,215 @@ public class BavlsikSimulationProgram entityStatePdu_2.setForceId(ForceID.OPPOSING); entityStatePdu_2.setEntityType(new _002Triton()); // note import statement above entityStatePdu_2.setMarking("Entity #2"); + //Initialize entity2's location to a random spot from (0,0,0) to (10,10,0) + Random random = new Random(); + int randX = random.nextInt(10); + int randY = random.nextInt(10); + entityStatePdu_2.getEntityLocation().setX(randX); + entityStatePdu_2.getEntityLocation().setY(randY); // TODO how should we customize this munition? what are key parameters for your simulation? // more is needed here by scenario authors... munitionDescriptor1.setQuantity(1); - firePdu_1a.setDescriptor(munitionDescriptor1).setRange(1000.0f); + firePdu_1a.setDescriptor(munitionDescriptor1).setRange(3.0f); } - + /** - * 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. + * 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 might 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 for today's date and timestamp to zero, providing consistent outputs for each simulation run - String timeMessage = "Simulation time " + simulationTimeSeconds + " at LocalDateTime " + LocalDateTime.now(); - disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_TIME, timeMessage); - // TODO replace enumeration with disChannel.COMMENTPDU_TIME - // TODO fix VariableRecordType.TIME_AMP_DATE_VALID - - // =================================================================================================== - // 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? - - // are your reading any DIS PDUs from the network? check for them here - - // 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 sure this arrives to user even if other threads somehow become deadlocked - - - // 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 > MAX_LOOP_COUNT) // 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)(getSimulationTimeStepDuration() * 1000)); // units of seconds * (1000 msec/sec) = milliseconds - System.out.println ("... [Pausing for " + getSimulationTimeStepDuration() + " seconds]"); - - // OK now send the status PDUs for this loop, and then continue - System.out.println ("... sending PDUs of interest for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); - System.out.flush(); - - // TODO set timesteps in PDUs - - sendAllPdusForLoopTimestep(simulationTimeSeconds, - entityStatePdu_1, - firePdu_1a, - DisChannel.COMMENTPDU_APPLICATION_STATUS, - narrativeMessage1, narrativeMessage2, narrativeMessage3); - disChannel.sendSinglePdu(simulationTimeSeconds, entityStatePdu_2); // me too i.e. 2! - - System.out.println ("... [PDUs of interest 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 + public void runSimulationLoops() { + Random random = new Random(); + boolean killFlag = false;//updates if the hunter kills its prey. + 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 for today's date and timestamp to zero, providing consistent outputs for each simulation run + String timeMessage = "Simulation time " + simulationTimeSeconds + " at LocalDateTime " + LocalDateTime.now(); + disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_TIME, timeMessage); + // TODO replace enumeration with disChannel.COMMENTPDU_TIME + // TODO fix VariableRecordType.TIME_AMP_DATE_VALID + + // =================================================================================================== + // 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? { - System.out.println ("... [loop termination condition met, simulationComplete=" + simulationComplete + "]"); // ", final loopCount=" + loopCount + + simulationLoopCount++; // good practice: increment loop counter as first action in that loop + + // ============================================================================================= + // * your own simulation code starts here! ***************************************************** + // ============================================================================================= + Vector3Double entity2Location = entityStatePdu_2.getEntityLocation(); + Vector3Double entity1Location = entityStatePdu_1.getEntityLocation(); + System.out.println(entity1Location); + System.out.println(entity2Location); + Double deltaX = entity2Location.getX() - entity1Location.getX(); + Double deltaY = entity2Location.getY() - entity1Location.getY(); + System.out.println("1x: " + entity1Location.getX() + " 1y: " + entity1Location.getY() + " deltaX " + deltaX + " deltaY " + deltaY); + System.out.println("2x: " + entity2Location.getX() + " 2y: " + entity2Location.getY()); + Double magnitude = Math.sqrt((deltaX * deltaX) + (deltaY * deltaY)); + System.out.println(magnitude); + // are there any other variables to modify at the beginning of your loop? + + // are your reading any DIS PDUs from the network? check for them here + // 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 + if (magnitude <= firePdu_1a.getRange()) { + System.out.println(entityStatePdu_1.getEntityID() + " FIRING AT " + entityStatePdu_2.getEntityID() + "...."); + double pKill = 0.5; //probability of a hit + double shot = random.nextDouble(); + System.out.println(shot); + if (shot <= pKill) { + System.out.println("...HIT!"); + killFlag = true; + } else { + System.out.println("...MISS!"); + } + } else { + entityStatePdu_1.getEntityLocation().setX(entityStatePdu_1.getEntityLocation().getX() + (2 * deltaX / magnitude)); + entityStatePdu_1.getEntityLocation().setY(entityStatePdu_1.getEntityLocation().getY() + (2 * deltaY / magnitude)); + } + //Entity2 moves away from entity 1 + entityStatePdu_2.getEntityLocation().setX(entityStatePdu_2.getEntityLocation().getX() + (deltaX / magnitude)); + entityStatePdu_2.getEntityLocation().setY(entityStatePdu_2.getEntityLocation().getY() + (deltaY / magnitude)); + System.out.flush(); // make sure this arrives to user even if other threads somehow become deadlocked + + // 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 (killFlag) { + 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) (getSimulationTimeStepDuration() * 1000)); // units of seconds * (1000 msec/sec) = milliseconds + System.out.println("... [Pausing for " + getSimulationTimeStepDuration() + " seconds]"); + + // OK now send the status PDUs for this loop, and then continue + System.out.println("... sending PDUs of interest for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); System.out.flush(); - break; + + // TODO set timesteps in PDUs + sendAllPdusForLoopTimestep(simulationTimeSeconds, + entityStatePdu_1, + firePdu_1a, + DisChannel.COMMENTPDU_APPLICATION_STATUS, + narrativeMessage1, narrativeMessage2, narrativeMessage3); + disChannel.sendSinglePdu(simulationTimeSeconds, entityStatePdu_2); // me too i.e. 2! + + System.out.println("... [PDUs of interest 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; + } + simulationTimeSeconds += getSimulationTimeStepDuration(); // good practice: increment simulationTime as lastst action in that loop + + } // end of simulation loop, continue until done + // ===================================================================================================// ===================================================================================================// ===================================================================================================// =================================================================================================== + if(simulationComplete){ + System.out.println("Good guys sank the bads guys!"); + } + else{ + System.out.println("Bad guys got away... we'll get em' next time boys."); } - simulationTimeSeconds += getSimulationTimeStepDuration(); // good practice: increment simulationTime as lastst action in that loop - - } // end of simulation loop, continue until done - // ===================================================================================================// ===================================================================================================// ===================================================================================================// =================================================================================================== - - narrativeMessage2 = "runSimulation() completed successfully"; // all done, so tell everyone else on the channel - // TODO better javadoc needs to be autogenerated for VariableRecordType enumerations - disChannel.sendCommentPdu(DisChannel.COMMENTPDU_NARRATIVE, narrativeMessage1, narrativeMessage2, narrativeMessage3); - System.out.println ("... [final=completion CommentPdu successfully sent for simulation]"); - + narrativeMessage2 = "runSimulation() completed successfully"; // all done, so tell everyone else on the channel + // TODO better javadoc needs to be autogenerated for VariableRecordType enumerations + disChannel.sendCommentPdu(DisChannel.COMMENTPDU_NARRATIVE, narrativeMessage1, narrativeMessage2, narrativeMessage3); + System.out.println("... [final=completion CommentPdu successfully sent for simulation]"); + // disChannel.getPduRecorder(). TODO record XML as well - disChannel.leave(); // embedded SimulationManager is expected to send appropriate PDUs for entity, application shutdown - } - catch (InterruptedException iex) // handle any exception that your code might choose to provoke! - { - Logger.getLogger(BavlsikSimulationProgram.class.getSimpleName()).log(Level.SEVERE, null, iex); - } + disChannel.leave(); // embedded SimulationManager is expected to send appropriate PDUs for entity, application shutdown + } catch (InterruptedException iex) // handle any exception that your code might choose to provoke! + { + Logger.getLogger(BavlsikSimulationProgram.class.getSimpleName()).log(Level.SEVERE, null, iex); + } } /** - * Send EntityState, Fire, Comment PDUs that got updated for this loop, reflecting state of current simulation timestep. - * @param simTimeSeconds simulation time in second, applied to PDU as timestamp + * Send EntityState, Fire, Comment PDUs that got updated for this loop, + * reflecting state of current simulation timestep. + * + * @param simTimeSeconds simulation time in second, applied to PDU as + * timestamp * @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 PDU - * @param comments String array of narrative comments - * @see DisChannel -// * @see DisTime // TODO find renamed version - * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html" target="_blank">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments + * @param firePdu the FirePDU to send, if any + * @param commentType enumeration value describing purpose of the narrative + * comment PDU + * @param comments String array of narrative comments + * @see DisChannel // * @see DisTime // TODO find renamed version + * @see + * <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html" target="_blank">Passing + * Information to a Method or a Constructor</a> Arbitrary Number of + * Arguments */ public void sendAllPdusForLoopTimestep(double simTimeSeconds, - EntityStatePdu entityStatePdu, - FirePdu firePdu, - VariableRecordType commentType, - // vararg... variable-length set of String comments can optionally follow - String... comments) - { - if (entityStatePdu != null) + EntityStatePdu entityStatePdu, + FirePdu firePdu, + VariableRecordType commentType, + // vararg... variable-length set of String comments can optionally follow + String... comments) { + if (entityStatePdu != null) { disChannel.sendSinglePdu(simTimeSeconds, entityStatePdu); - - if (firePdu != null) + } + + if (firePdu != null) { disChannel.sendSinglePdu(simTimeSeconds, firePdu); // bang - + } disChannel.sendCommentPdu(simTimeSeconds, commentType, comments); // empty comments are filtered } - + /** - * Initial execution via main() method: handle args array of command-line initialization (CLI) arguments here + * 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 handleArguments (String[] args) - { + protected void handleArguments(String[] args) { // initial execution: handle args array of initialization arguments here - if (args.length == 2) - { - if ((args[0] != null) && !args[0].isEmpty()) + if (args.length == 2) { + if ((args[0] != null) && !args[0].isEmpty()) { thisProgram.disChannel.setNetworkAddress(args[0]); - if ((args[1] != null) && !args[1].isEmpty()) + } + if ((args[1] != null) && !args[1].isEmpty()) { thisProgram.disChannel.setNetworkPort(Integer.parseInt(args[1])); - } - else if (args.length != 0) - { + } + } else if (args.length != 0) { System.err.println("Usage: " + thisProgram.getClass().getSimpleName() + " [address port]"); System.exit(-1); } } /** - * Get simple descriptor (such as parent class name) for this network interface, used in trace statements + * Get simple descriptor (such as parent class name) for this network + * interface, used in trace statements + * * @return simple descriptor name */ public String getDescriptor() { @@ -360,17 +434,21 @@ public class BavlsikSimulationProgram } /** - * Set new simple descriptor (such as parent class name) for this network interface, used in trace statements + * Set new simple descriptor (such as parent class name) for this network + * interface, used in trace statements + * * @param newDescriptor simple descriptor name for this interface */ public void setDescriptor(String newDescriptor) { - if (newDescriptor == null) + if (newDescriptor == null) { newDescriptor = ""; + } this.descriptor = newDescriptor; } /** * parameter accessor method + * * @return the simulationTimeStepDuration in seconds */ public double getSimulationTimeStepDuration() { @@ -379,35 +457,42 @@ public class BavlsikSimulationProgram /** * parameter accessor method - * @param timeStepDurationSeconds the simulationTimeStepDuration in seconds to set + * + * @param timeStepDurationSeconds the simulationTimeStepDuration in seconds + * to set */ public void setSimulationTimeStepDuration(double timeStepDurationSeconds) { this.simulationTimeStepDuration = timeStepDurationSeconds; } - - /** Locally instantiable copy of program, can be subclassed. */ + + /** + * Locally instantiable copy of program, can be subclassed. + */ protected static BavlsikSimulationProgram 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" target="_blank">Java Tutorials: A Closer Look at the "Hello World!" Application</a> + * + * @see + * <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html" target="_blank">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 + * Command-line arguments are an array of optional String parameters that + * are passed from execution environment during invocation */ - public static void main(String[] args) - { + public static void main(String[] args) { thisProgram = new BavlsikSimulationProgram("test constructor"); // create instance of self within static main() method - + thisProgram.disChannel.printlnTRACE("main() started..."); - + thisProgram.handleArguments(args); // process any command-line invocation arguments thisProgram.runSimulationLoops(); // ... your simulation execution code goes in there ... - + thisProgram.disChannel.tearDownNetworkInterface(); // make sure no processes are left lingering - + thisProgram.disChannel.printlnTRACE("complete."); // report successful completion - + System.exit(0); // ensure all threads and sockets released } } diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Bavlsik/README.md b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Bavlsik/README.md index c5aadebfdcbc089649b153eb705bb84c6286336b..4827a529dcbb9d3abb3489df7c217b7def5a9020 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Bavlsik/README.md +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Bavlsik/README.md @@ -1,38 +1,6 @@ ## Homework 3: Example Simulation Recording using OpenDIS Network Streams - -<!-- Viewable at https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/assignments/src/MV3500Cohort2024JulySeptember/homework3/README.md --> - -### Assignment - -1. Adapt the functionality for [OpenDIS ExampleSimulationProgram](../../../../examples/src/OpenDis7Examples/ExampleSimulationProgram.java), modifying provided code -2. Experiment with the enumeration values that set up each entity and PDU. What works for you? What makes sense for your future work? -3. Adapt or replace the UML diagrams to describe what you have going on. -4. Record, save and replay your result stream using [PduRecorder](https://savage.nps.edu/opendis7-java/javadoc/edu/nps/moves/dis7/utilities/stream/PduRecorder.html) or [Wireshark](https://www.wireshark.org) - * see local [assignments/src/pduLog](../../../pduLog) subdirectory for latest opendis log files - * Coming soon, we will also (again have) [X3D-Edit](https://savage.nps.edu/X3D-Edit) for DIS stream recording/replay -5. Observe good-practice conventions in the [assignments README](../../../README.md) and [current-course README](../README.md) instructions. - -This assignment presents a Problem Prototyping opportunity. -While some minimal functionality is expected, the general outline of -a networking problem and proposed solution holds great interest. -Think of it as warmup preparation for your future work. - -This is also a freeplay opportunity. -You have the option to pick one or more of the provided course example programs -and adapt the source to demonstrate a new client-server handshake protocol of interest. - -Be sure to provide a rationale that justifies why the networking choices you made -(TCP/UDP, unicast/multicast, etc.) are the best for the problem you are addressing. - -You may find that the prior [homework2 README](../homework2/README.md) still provides -helpful details on what specific deliverables are expected in each homework assignment. - -Team efforts are encouraged, though if you choose a team approach be sure to justify why. -This is a good warmup prior to final projects. Have fun with Java networking! - -### Prior Assignment, August 2019 - -In 2019, students worked together on a single project to check wireless multicast connectivity recently deployed on NPS campus. - -See their experimental results in the [NPS Multicast Connectivity Report](../../MV3500Cohort2019JulySeptember/homework3). - +This program runs a simulation between two entites. One entity is initialized at +(0,0,0) and the other is randomly placed. The hunter entity moves towards the prey +entity until it is in range. When in range the hunter attempts to shoot the prey. +If successful, the simulation ends. The prey entity constantly attemps to move away +from the hunter. \ No newline at end of file diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Lennon/LennonSimulationProgram.java b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Lennon/LennonSimulationProgram.java index 4e5c65a0b2f97634f6b851f69af48c13eec3e490..7f84d05387171175206d82c547a051e8bc4c5a84 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Lennon/LennonSimulationProgram.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Lennon/LennonSimulationProgram.java @@ -21,9 +21,7 @@ import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; -/** The purpose of this inheritable class is to provide an easily modifiable - * example simulation program that includes DIS-capable entities performing - * tasks of interest, and then reporting activity via PDUs to the network. +/** Modification of the example program; a simple user interactive simulation of navigating a minefield. * Default program initialization includes PDU recording turned on by default. * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt" target="_blank">ExampleSimulationProgramLog.txt</a> * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramPduCaptureLog.dislog" target="_blank">ExampleSimulationProgramPduCaptureLog.dislog</a> diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Matiski/ExampleSimulationProgram.java b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Matiski/ExampleSimulationProgram.java new file mode 100644 index 0000000000000000000000000000000000000000..eef5ed0f8c5e469889870124e37544b97b3c6d19 --- /dev/null +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Matiski/ExampleSimulationProgram.java @@ -0,0 +1,427 @@ +/** + * Copyright (c) 2008-2023, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html or license.txt + * @author brutzman@nps.edu + * @author mm + * Submission for homework 3 + */ +package MV3500Cohort2024JulySeptember.homework3.Matiski; + +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.DisChannel; +import edu.nps.moves.dis7.utilities.PduFactory; +import java.time.LocalDateTime; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** The purpose of this inheritable class is to provide an easily modifiable + * example simulation program that includes DIS-capable entities performing + * tasks of interest, and then reporting activity via PDUs to the network. + * Default program initialization includes PDU recording turned on by default. + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt" target="_blank">ExampleSimulationProgramLog.txt</a> + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramPduCaptureLog.dislog" target="_blank">ExampleSimulationProgramPduCaptureLog.dislog</a> + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.pdf" target="_blank">ExampleSimulationProgramFlowDiagram.pdf</a> + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramWireshark.png" target="_blank">ExampleSimulationProgramWireshark.png</a> + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png" target="_blank">ExampleSimulationProgramSequenceDiagram.png</a> + */ +public class ExampleSimulationProgram +{ + /* **************************** infrastructure code, modification is seldom needed ************************* */ + + private String descriptor = this.getClass().getSimpleName(); + /** DIS channel defined by network address/port combination includes multiple utility capabilities */ + protected DisChannel disChannel; + /** Factory object used to create new PDU instances */ + protected PduFactory pduFactory; + + /** seconds per loop for real-time or simulation execution */ + private double simulationTimeStepDuration = 1.0; // seconds TODO encapsulate + /** initial simulation time in seconds */ + double simulationTimeInitial = 0.0; + /** current simulation time in seconds */ + double simulationTimeSeconds = simulationTimeInitial; + /** Maximum number of simulation loops */ + int MAX_LOOP_COUNT = 4; + + String narrativeMessage1 = new String(); + String narrativeMessage2 = new String(); + String narrativeMessage3 = new String(); + + /** 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; + /** ESPDU for entity 2 */ + protected EntityStatePdu entityStatePdu_2; + /** FirePdu for entity 1 first weapon (if any) */ + protected FirePdu firePdu_1a; + /** FirePdu for entity 1 second weapon (if any) */ + protected FirePdu firePdu_1b; + /** MunitionDescriptor for these weapons */ + protected MunitionDescriptor munitionDescriptor1; + + // hey programmer, what other state do you want? this is a good place to declare it... + + /** + * Constructor to create an instance of this class. + * Design goal: additional built-in initialization conveniences can go here + * to keep your efforts focused on the runSimulation() method. + */ + // base constructor is not invoked automatically by other constructors + // https://stackoverflow.com/questions/581873/best-way-to-handle-multiple-constructors-in-java + public ExampleSimulationProgram() + { + initialize(); + } + /** + * Constructor to create an instance of this class. + * @param newDescriptor describes this program, useful for logging and debugging + */ + public ExampleSimulationProgram(String newDescriptor) + { + descriptor = newDescriptor; + initialize(); + } + /** + * 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 ExampleSimulationProgram(String address, int port) + { + disChannel.setNetworkAddress (address); + disChannel.setNetworkPort (port); + disChannel.setVerboseComments (true); // TODO rename library method to disambiguate CommentPDU + // TODO still seems really chatty... add silent mode? + disChannel.setVerboseDisNetworkInterface(true); // Default false + disChannel.setVerbosePduRecorder (true); // default false + initialize(); + } + + /** Initialize channel setup for OpenDis7 and report a test PDU + * @see initializeDisChannel + * @see initializeSimulationEntities */ + private void initialize() + { + initializeDisChannel(); // must come first, uses PduFactory + + initializeSimulationEntities(); // set unchanging parameters + + disChannel.join(); // TODO further functionality expected + + String timeStepMessage = "Simulation timestep duration " + getSimulationTimeStepDuration() + " seconds"; + disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_SIMULATION_TIMESTEP, timeStepMessage); + // additional constructor initialization can go here + } + + /** Initialize channel setup for OpenDis7 and report a test PDU */ + private void initializeDisChannel() + { + if (disChannel == null) + disChannel = new DisChannel(); + else + { + disChannel.printlnTRACE ("*** warning, duplicate invocation of initializeDisChannel() ignored"); + return; + } + pduFactory = disChannel.getPduFactory(); + disChannel.setDescriptor(this.getClass().getSimpleName()); // ExampleSimulationProgram might be a superclass + disChannel.setUpNetworkInterface(); + disChannel.printlnTRACE ("just checking: disChannel.getNetworkAddress()=" + disChannel.getNetworkAddress() + + ", getNetworkPort()=" + disChannel.getNetworkPort()); + disChannel.getDisNetworkInterface().setVerbose(true); // sending and receipt + disChannel.printlnTRACE ("just checking: hasVerboseSending()=" + disChannel.getDisNetworkInterface().hasVerboseSending() + + ", hasVerboseReceipt()=" + disChannel.getDisNetworkInterface().hasVerboseReceipt()); + disChannel.getPduRecorder().setVerbose(true); + + // TODO confirm whether recorder is explicitly started by programmer (or not) + +// disChannel.sendCommentPdu(VariableRecordType.OTHER, "DisThreadedNetworkInterface.initializeDisChannel() complete"); // hello channel, debug + } + + /** Get ready, get set... initialize simulation entities. Who's who in the zoo? + */ + public void initializeSimulationEntities() + { + if (pduFactory == null) + pduFactory = disChannel.getPduFactory(); + entityStatePdu_1 = pduFactory.makeEntityStatePdu(); + entityStatePdu_2 = pduFactory.makeEntityStatePdu(); + firePdu_1a = pduFactory.makeFirePdu(); + firePdu_1b = pduFactory.makeFirePdu(); + munitionDescriptor1 = new MunitionDescriptor(); + + // 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 declared and instances created, so now set their values. + // who is who in our big zoo, sufficient for global participation if we need it + entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID; + disChannel.addEntity(entityID_1); + + entityID_2.setSiteID(1).setApplicationID(2).setEntityID(4); // made-up example ID; + disChannel.addEntity(entityID_2); + // TODO someday, use enumerations for sites as part of a SimulationManager object; e.g. 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.setEntityType(new edu.nps.moves.dis7.entities.usa.platform.air.MV22B()); // note import statement at top + entityStatePdu_1.setMarking("Entity #53"); + entityStatePdu_1.getMarkingString(); // use Netbeans Debug breakpoint here to check left justified... + + 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 are key parameters for your simulation? + // more is needed here by scenario authors... + munitionDescriptor1.setQuantity(1); + firePdu_1a.setDescriptor(munitionDescriptor1).setRange(1000.0f); + } + + /** + * 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 might 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 for today's date and timestamp to zero, providing consistent outputs for each simulation run + String timeMessage = "Simulation time " + simulationTimeSeconds + " at LocalDateTime " + LocalDateTime.now(); + disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_TIME, timeMessage); + // TODO replace enumeration with disChannel.COMMENTPDU_TIME + // TODO fix VariableRecordType.TIME_AMP_DATE_VALID + + // =================================================================================================== + // 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! ***************************************************** + // ============================================================================================= + // movement in a circular fashion + double radius = 10.0; + double angle = simulationTimeSeconds * Math.PI / 180; + + double newX = radius * Math.cos(angle); + double newY = radius * Math.sin(angle); + + entityStatePdu_1.getEntityLocation().setX(newX); + entityStatePdu_1.getEntityLocation().setY(newY); + + // Print position for debugging purposes + System.out.println("Entity 1 position: X=" + newX + ", Y=" + newY); + + + + // are there any other variables to modify at the beginning of your loop? + + // are your reading any DIS PDUs from the network? check for them here + + // compute a track, update an ESPDU, whatever it is that your model is doing... + + + // 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 sure this arrives to user even if other threads somehow become deadlocked + + + // 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 > MAX_LOOP_COUNT) // 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)(getSimulationTimeStepDuration() * 1000)); // units of seconds * (1000 msec/sec) = milliseconds + System.out.println ("... [Pausing for " + getSimulationTimeStepDuration() + " seconds]"); + + // OK now send the status PDUs for this loop, and then continue + System.out.println ("... sending PDUs of interest for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); + System.out.flush(); + + // TODO set timesteps in PDUs + + sendAllPdusForLoopTimestep(simulationTimeSeconds, + entityStatePdu_1, + firePdu_1a, + DisChannel.COMMENTPDU_APPLICATION_STATUS, + narrativeMessage1, narrativeMessage2, narrativeMessage3); + disChannel.sendSinglePdu(simulationTimeSeconds, entityStatePdu_2); // me too i.e. 2! + + System.out.println ("... [PDUs of interest 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; + } + simulationTimeSeconds += getSimulationTimeStepDuration(); // good practice: increment simulationTime as lastst action in that loop + + } // end of simulation loop, continue until done + // ===================================================================================================// ===================================================================================================// ===================================================================================================// =================================================================================================== + + narrativeMessage2 = "runSimulation() completed successfully"; // all done, so tell everyone else on the channel + // TODO better javadoc needs to be autogenerated for VariableRecordType enumerations + disChannel.sendCommentPdu(DisChannel.COMMENTPDU_NARRATIVE, narrativeMessage1, narrativeMessage2, narrativeMessage3); + System.out.println ("... [final=completion CommentPdu successfully sent for simulation]"); + +// disChannel.getPduRecorder(). TODO record XML as well + disChannel.leave(); // embedded SimulationManager is expected to send appropriate PDUs for entity, application shutdown + } + catch (InterruptedException iex) // handle any exception that your code might choose to provoke! + { + Logger.getLogger(ExampleSimulationProgram.class.getSimpleName()).log(Level.SEVERE, null, iex); + } + } + + /** + * Send EntityState, Fire, Comment PDUs that got updated for this loop, reflecting state of current simulation timestep. + * @param simTimeSeconds simulation time in second, applied to PDU as timestamp + * @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 PDU + * @param comments String array of narrative comments + * @see DisChannel +// * @see DisTime // TODO find renamed version + * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html" target="_blank">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments + */ + public void sendAllPdusForLoopTimestep(double simTimeSeconds, + EntityStatePdu entityStatePdu, + FirePdu firePdu, + VariableRecordType commentType, + // vararg... variable-length set of String comments can optionally follow + String... comments) + { + if (entityStatePdu != null) + disChannel.sendSinglePdu(simTimeSeconds, entityStatePdu); + + if (firePdu != null) + disChannel.sendSinglePdu(simTimeSeconds, firePdu); // bang + + disChannel.sendCommentPdu(simTimeSeconds, commentType, comments); // empty comments are filtered + } + + /** + * 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 handleArguments (String[] args) + { + // initial execution: handle args array of initialization arguments here + if (args.length == 2) + { + if ((args[0] != null) && !args[0].isEmpty()) + thisProgram.disChannel.setNetworkAddress(args[0]); + if ((args[1] != null) && !args[1].isEmpty()) + thisProgram.disChannel.setNetworkPort(Integer.parseInt(args[1])); + } + else if (args.length != 0) + { + System.err.println("Usage: " + thisProgram.getClass().getSimpleName() + " [address port]"); + System.exit(-1); + } + } + + /** + * Get simple descriptor (such as parent class name) for this network interface, used in trace statements + * @return simple descriptor name + */ + public String getDescriptor() { + return descriptor; + } + + /** + * Set new simple descriptor (such as parent class name) for this network interface, used in trace statements + * @param newDescriptor simple descriptor name for this interface + */ + public void setDescriptor(String newDescriptor) { + if (newDescriptor == null) + newDescriptor = ""; + this.descriptor = newDescriptor; + } + + /** + * parameter accessor method + * @return the simulationTimeStepDuration in seconds + */ + public double getSimulationTimeStepDuration() { + return simulationTimeStepDuration; + } + + /** + * parameter accessor method + * @param timeStepDurationSeconds the simulationTimeStepDuration in seconds to set + */ + public void setSimulationTimeStepDuration(double timeStepDurationSeconds) { + this.simulationTimeStepDuration = timeStepDurationSeconds; + } + + /** Locally instantiable copy of program, can be subclassed. */ + protected static ExampleSimulationProgram 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" target="_blank">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) + { + thisProgram = new ExampleSimulationProgram("test constructor"); // create instance of self within static main() method + + thisProgram.disChannel.printlnTRACE("main() started..."); + + thisProgram.handleArguments(args); // process any command-line invocation arguments + + thisProgram.runSimulationLoops(); // ... your simulation execution code goes in there ... + + thisProgram.disChannel.tearDownNetworkInterface(); // make sure no processes are left lingering + + thisProgram.disChannel.printlnTRACE("complete."); // report successful completion + + System.exit(0); // ensure all threads and sockets released + } +} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Matiski/README.md b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Matiski/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6e0e0c3a625afa84214a656281af59f2977b9be5 --- /dev/null +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Matiski/README.md @@ -0,0 +1,24 @@ +## Homework 3: Example Simulation Recording using OpenDIS Network Streams + +<!-- Viewable at https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/assignments/src/MV3500Cohort2024JulySeptember/homework3/README.md --> + +### Assignment + +1. Adapt the functionality for [OpenDIS ExampleSimulationProgram](../../../../examples/src/OpenDis7Examples/ExampleSimulationProgram.java), modifying provided code +2. Experiment with the enumeration values that set up each entity and PDU. What works for you? What makes sense for your future work? + I added movement to the simulation. +3. Adapt or replace the UML diagrams to describe what you have going on. +4. Record, save and replay your result stream using [PduRecorder](https://savage.nps.edu/opendis7-java/javadoc/edu/nps/moves/dis7/utilities/stream/PduRecorder.html) or [Wireshark](https://www.wireshark.org) + * see local [assignments/src/pduLog](../../../pduLog) subdirectory for latest opendis log files + * Coming soon, we will also (again have) [X3D-Edit](https://savage.nps.edu/X3D-Edit) for DIS stream recording/replay +5. Observe good-practice conventions in the [assignments README](../../../README.md) and [current-course README](../README.md) instructions. + +This assignment presents a Problem Prototyping opportunity. +While some minimal functionality is expected, the general outline of +a networking problem and proposed solution holds great interest. +Think of it as warmup preparation for your future work. + + +For assignment 3 I implemented random movement. + + diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Matiski/package-info.java b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Matiski/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..a58b235b2f5d29cdfeeb6d305d4a180a9f904f69 --- /dev/null +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Matiski/package-info.java @@ -0,0 +1,10 @@ +/** + * Final project assignments supporting the NPS MOVES MV3500 Networked Graphics course. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/assignments" target="_blank">networkedGraphicsMV3500 assignments</a> + * @see java.lang.Package + * @see <a href="https://stackoverflow.com/questions/22095487/why-is-package-info-java-useful" target="_blank">StackOverflow: why-is-package-info-java-useful</a> + * @see <a href="https://stackoverflow.com/questions/624422/how-do-i-document-packages-in-java" target="_blank">StackOverflow: how-do-i-document-packages-in-java</a> + */ + +package MV3500Cohort2024JulySeptember.homework3.Matiski; diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Smith/ExampleSimulationProgram.java b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Smith/ExampleSimulationProgram.java index 26419da18ec013dfd0790866944c8d64b44c0020..7f39bed923eb77908c40b639072c7595f8c0168e 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Smith/ExampleSimulationProgram.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Smith/ExampleSimulationProgram.java @@ -17,7 +17,7 @@ public class ExampleSimulationProgram { // Constants for the Battleship game private static final int GRID_SIZE = 10; // 10x10 grid for Battleship - private static final int MAX_TURNS = 100; // Limit turns to avoid infinite games + private static final int MAX_TURNS = 200; // Limit turns to avoid infinite games // Grids for each player private char[][] player1Grid = new char[GRID_SIZE][GRID_SIZE]; @@ -32,11 +32,29 @@ public class ExampleSimulationProgram { // DIS utilities private String descriptor = this.getClass().getSimpleName(); + /** + * DIS Channel to output to + */ protected DisChannel disChannel; - protected PduFactory pduFactory; - protected CommentPdu gridStatusPdu; - protected FirePdu firePduPlayer1; - protected FirePdu firePduPlayer2; + /** + * PDU generator + */ + protected PduFactory pduFactory; // + /** + * Grid Status updating PDU + */ + protected CommentPdu gridStatusPdu; // + /** + * Player 1 PDU + */ + protected FirePdu firePduPlayer1; // + /** + * Player 2 PDU + */ + protected FirePdu firePduPlayer2; // + /** + * Munition Descriptor + */ protected MunitionDescriptor munitionDescriptor1 = new MunitionDescriptor(); // Simulation time settings diff --git a/examples/nbproject/project.properties b/examples/nbproject/project.properties index bb12d3f683a507710517c28cff44c8c0ff5a9892..922c6f375e5e7b9c14acc931abf8ea150d434604 100644 --- a/examples/nbproject/project.properties +++ b/examples/nbproject/project.properties @@ -1,121 +1,121 @@ -annotation.processing.enabled=true -annotation.processing.enabled.in.editor=false -annotation.processing.processors.list= -annotation.processing.run.all.processors=true -annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output -application.desc=Example programs provided as part of NPS course Networked Graphics MV3500. This course is an introduction to network communications in simulation applications. Topics include an introduction to the TCP/IP protocol stack; TCP/IP socket communications, including TCP, UDP, and multicast; and protocol design issues, with emphasis on Distributed Interactive Simulation (DIS) Protocol and High Level Architecture (HLA). Course emphasis is on creation and testing of network programming network code and web-browser applications. -application.homepage=https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples -application.splash=..\\..\\NetworkedGraphicsMV3500\\documentation\\images\\OpenDisSurferDude.png -application.title=NPS Networked Graphics MV3500 examples -application.vendor=Don Brutzman -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.modulepath=\ - ${run.modulepath} -debug.test.classpath=\ - ${run.test.classpath} -debug.test.modulepath=\ - ${run.test.modulepath} -# Files in build.classes.dir which should be excluded from distribution jar -dist.archive.excludes= -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.name=Networked_Graphics_MV3500_examples -dist.jar=${dist.dir}/${dist.name}.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -project.licensePath=../license.txt -viskit.proj.dir=ViskitOpenDis7Examples -viskit.proj.lib.dir=src/${viskit.proj.dir}/lib -opendis.helper=SimkitOpenDis7Examples.run.OpenDisHelper -excludes=ViskitOpenDis7Examples/ -file.reference.dis-enums-1.3.jar=../lib/dis-enums-1.3.jar -file.reference.opendis7-full.jar=../lib/opendis7-full.jar -file.reference.open-dis_4.16.jar=../lib/open-dis_4.16.jar -file.reference.simkit-doc.zip=../lib/simkit-doc.zip -file.reference.simkit-src.zip=../lib/simkit-src.zip -file.reference.simkit.jar=../lib/simkit.jar -#file.reference.opendis7-enumerations-classes.jar=../lib/opendis7-enumerations-classes.jar -#file.reference.opendis7-pdus-classes.jar=../lib/opendis7-pdus-classes.jar -includes=**/*.java -jar.compress=false -javac.classpath=\ - ${file.reference.opendis7-full.jar}:\ - ${file.reference.open-dis_4.16.jar}:\ - ${file.reference.dis-enums-1.3.jar}:\ - ${file.reference.simkit.jar}:\ - ${file.reference.simkit-doc.zip}:\ - ${file.reference.simkit-src.zip} -# ${file.reference.opendis7-enumerations-classes.jar}:\ -# ${file.reference.opendis7-pdus-classes.jar}:\ - -# Space-separated list of extra javac options -javac.compilerargs=-Xlint:deprecation -Xlint:unchecked -javac.deprecation=false -javac.external.vm=true -javac.modulepath= -javac.processormodulepath= -javac.processorpath=\ - ${javac.classpath} -javac.source=21 -javac.target=21 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -javac.test.modulepath=\ - ${javac.modulepath} -javac.test.processorpath=\ - ${javac.test.classpath} -javadoc.additionalparam=-header "NPS Networked Graphics MV3500 Examples" -javadoc.author=true -javadoc.encoding=${source.encoding} -javadoc.html5=false -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -#javadoc.reference.opendis7-enumerations-classes.jar=../lib/opendis7-enumerations-javadoc.jar -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle=MV3500 Examples -jlink.launcher=false -jlink.launcher.name=Networked_Graphics_MV3500_examples -main.class=TcpExamples.TcpExample1Telnet -manifest.file=manifest.mf -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=false -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project. -# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. -# To set system properties for unit tests define test-sys-prop.name=value: -run.jvmargs= -run.modulepath=\ - ${javac.modulepath} -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -run.test.modulepath=\ - ${javac.test.modulepath} -source.encoding=UTF-8 -#source.reference.opendis7-enumerations-classes.jar=../lib/opendis7-enumerations-source.jar -src.dir=src -src.src.dir=otherProjects\\DisDemo\\src -src.src2.dir=otherProjects\\DisShooting\\src -src.src3.dir=otherProjects\\WebSocketGateway\\src -#src.src4.dir=otherProjects\\BasicServletDemo\\src +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.desc=Example programs provided as part of NPS course Networked Graphics MV3500. This course is an introduction to network communications in simulation applications. Topics include an introduction to the TCP/IP protocol stack; TCP/IP socket communications, including TCP, UDP, and multicast; and protocol design issues, with emphasis on Distributed Interactive Simulation (DIS) Protocol and High Level Architecture (HLA). Course emphasis is on creation and testing of network programming network code and web-browser applications. +application.homepage=https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples +application.splash=..\\..\\NetworkedGraphicsMV3500\\documentation\\images\\OpenDisSurferDude.png +application.title=NPS Networked Graphics MV3500 examples +application.vendor=Don Brutzman +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.modulepath=\ + ${run.modulepath} +debug.test.classpath=\ + ${run.test.classpath} +debug.test.modulepath=\ + ${run.test.modulepath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.name=Networked_Graphics_MV3500_examples +dist.jar=${dist.dir}/${dist.name}.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +project.licensePath=../license.txt +viskit.proj.dir=ViskitOpenDis7Examples +viskit.proj.lib.dir=src/${viskit.proj.dir}/lib +opendis.helper=SimkitOpenDis7Examples.run.OpenDisHelper +excludes=ViskitOpenDis7Examples/ +file.reference.dis-enums-1.3.jar=../lib/dis-enums-1.3.jar +file.reference.opendis7-full.jar=../lib/opendis7-full.jar +file.reference.open-dis_4.16.jar=../lib/open-dis_4.16.jar +file.reference.simkit-doc.zip=../lib/simkit-doc.zip +file.reference.simkit-src.zip=../lib/simkit-src.zip +file.reference.simkit.jar=../lib/simkit.jar +#file.reference.opendis7-enumerations-classes.jar=../lib/opendis7-enumerations-classes.jar +#file.reference.opendis7-pdus-classes.jar=../lib/opendis7-pdus-classes.jar +includes=**/*.java +jar.compress=false +javac.classpath=\ + ${file.reference.opendis7-full.jar}:\ + ${file.reference.open-dis_4.16.jar}:\ + ${file.reference.dis-enums-1.3.jar}:\ + ${file.reference.simkit.jar}:\ + ${file.reference.simkit-doc.zip}:\ + ${file.reference.simkit-src.zip} +# ${file.reference.opendis7-enumerations-classes.jar}:\ +# ${file.reference.opendis7-pdus-classes.jar}:\ + +# Space-separated list of extra javac options +javac.compilerargs=-Xlint:deprecation -Xlint:unchecked +javac.deprecation=false +javac.external.vm=true +javac.modulepath= +javac.processormodulepath= +javac.processorpath=\ + ${javac.classpath} +javac.source=22 +javac.target=22 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.modulepath=\ + ${javac.modulepath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam=-header "NPS Networked Graphics MV3500 Examples" +javadoc.author=true +javadoc.encoding=${source.encoding} +javadoc.html5=false +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +#javadoc.reference.opendis7-enumerations-classes.jar=../lib/opendis7-enumerations-javadoc.jar +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle=MV3500 Examples +jlink.launcher=false +jlink.launcher.name=Networked_Graphics_MV3500_examples +main.class=TcpExamples.TcpExample1Telnet +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.modulepath=\ + ${javac.modulepath} +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +run.test.modulepath=\ + ${javac.test.modulepath} +source.encoding=UTF-8 +#source.reference.opendis7-enumerations-classes.jar=../lib/opendis7-enumerations-source.jar +src.dir=src +src.src.dir=otherProjects\\DisDemo\\src +src.src2.dir=otherProjects\\DisShooting\\src +src.src3.dir=otherProjects\\WebSocketGateway\\src +#src.src4.dir=otherProjects\\BasicServletDemo\\src diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgram.java b/examples/src/OpenDis7Examples/ExampleSimulationProgram.java index dbc60b72e1071f77f8f60bc7a7718ae443415f96..f9c25b2e4352085889f6801b74051a45b7fdda0a 100644 --- a/examples/src/OpenDis7Examples/ExampleSimulationProgram.java +++ b/examples/src/OpenDis7Examples/ExampleSimulationProgram.java @@ -1,413 +1,434 @@ -/** - * Copyright (c) 2008-2023, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. - * This work is provided under a BSD open-source license, see project license.html or 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.*; -import edu.nps.moves.dis7.pdus.*; -import edu.nps.moves.dis7.utilities.DisChannel; -import edu.nps.moves.dis7.utilities.PduFactory; -import java.time.LocalDateTime; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** The purpose of this inheritable class is to provide an easily modifiable - * example simulation program that includes DIS-capable entities performing - * tasks of interest, and then reporting activity via PDUs to the network. - * Default program initialization includes PDU recording turned on by default. - * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt" target="_blank">ExampleSimulationProgramLog.txt</a> - * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramPduCaptureLog.dislog" target="_blank">ExampleSimulationProgramPduCaptureLog.dislog</a> - * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.pdf" target="_blank">ExampleSimulationProgramFlowDiagram.pdf</a> - * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramWireshark.png" target="_blank">ExampleSimulationProgramWireshark.png</a> - * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png" target="_blank">ExampleSimulationProgramSequenceDiagram.png</a> - */ -public class ExampleSimulationProgram -{ - /* **************************** infrastructure code, modification is seldom needed ************************* */ - - private String descriptor = this.getClass().getSimpleName(); - /** DIS channel defined by network address/port combination includes multiple utility capabilities */ - protected DisChannel disChannel; - /** Factory object used to create new PDU instances */ - protected PduFactory pduFactory; - - /** seconds per loop for real-time or simulation execution */ - private double simulationTimeStepDuration = 1.0; // seconds TODO encapsulate - /** initial simulation time in seconds */ - double simulationTimeInitial = 0.0; - /** current simulation time in seconds */ - double simulationTimeSeconds = simulationTimeInitial; - /** Maximum number of simulation loops */ - int MAX_LOOP_COUNT = 4; - - String narrativeMessage1 = new String(); - String narrativeMessage2 = new String(); - String narrativeMessage3 = new String(); - - /** 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; - /** ESPDU for entity 2 */ - protected EntityStatePdu entityStatePdu_2; - /** FirePdu for entity 1 first weapon (if any) */ - protected FirePdu firePdu_1a; - /** FirePdu for entity 1 second weapon (if any) */ - protected FirePdu firePdu_1b; - /** MunitionDescriptor for these weapons */ - protected MunitionDescriptor munitionDescriptor1; - - // hey programmer, what other state do you want? this is a good place to declare it... - - /** - * Constructor to create an instance of this class. - * Design goal: additional built-in initialization conveniences can go here - * to keep your efforts focused on the runSimulation() method. - */ - // base constructor is not invoked automatically by other constructors - // https://stackoverflow.com/questions/581873/best-way-to-handle-multiple-constructors-in-java - public ExampleSimulationProgram() - { - initialize(); - } - /** - * Constructor to create an instance of this class. - * @param newDescriptor describes this program, useful for logging and debugging - */ - public ExampleSimulationProgram(String newDescriptor) - { - descriptor = newDescriptor; - initialize(); - } - /** - * 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 ExampleSimulationProgram(String address, int port) - { - disChannel.setNetworkAddress (address); - disChannel.setNetworkPort (port); - disChannel.setVerboseComments (true); // TODO rename library method to disambiguate CommentPDU - // TODO still seems really chatty... add silent mode? - disChannel.setVerboseDisNetworkInterface(true); // Default false - disChannel.setVerbosePduRecorder (true); // default false - initialize(); - } - - /** Initialize channel setup for OpenDis7 and report a test PDU - * @see initializeDisChannel - * @see initializeSimulationEntities */ - private void initialize() - { - initializeDisChannel(); // must come first, uses PduFactory - - initializeSimulationEntities(); // set unchanging parameters - - disChannel.join(); // TODO further functionality expected - - String timeStepMessage = "Simulation timestep duration " + getSimulationTimeStepDuration() + " seconds"; - disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_SIMULATION_TIMESTEP, timeStepMessage); - // additional constructor initialization can go here - } - - /** Initialize channel setup for OpenDis7 and report a test PDU */ - private void initializeDisChannel() - { - if (disChannel == null) - disChannel = new DisChannel(); - else - { - disChannel.printlnTRACE ("*** warning, duplicate invocation of initializeDisChannel() ignored"); - return; - } - pduFactory = disChannel.getPduFactory(); - disChannel.setDescriptor(this.getClass().getSimpleName()); // ExampleSimulationProgram might be a superclass - disChannel.setUpNetworkInterface(); - disChannel.printlnTRACE ("just checking: disChannel.getNetworkAddress()=" + disChannel.getNetworkAddress() + - ", getNetworkPort()=" + disChannel.getNetworkPort()); - disChannel.getDisNetworkInterface().setVerbose(true); // sending and receipt - disChannel.printlnTRACE ("just checking: hasVerboseSending()=" + disChannel.getDisNetworkInterface().hasVerboseSending() + - ", hasVerboseReceipt()=" + disChannel.getDisNetworkInterface().hasVerboseReceipt()); - disChannel.getPduRecorder().setVerbose(true); - - // TODO confirm whether recorder is explicitly started by programmer (or not) - -// disChannel.sendCommentPdu(VariableRecordType.OTHER, "DisThreadedNetworkInterface.initializeDisChannel() complete"); // hello channel, debug - } - - /** Get ready, get set... initialize simulation entities. Who's who in the zoo? - */ - public void initializeSimulationEntities() - { - if (pduFactory == null) - pduFactory = disChannel.getPduFactory(); - entityStatePdu_1 = pduFactory.makeEntityStatePdu(); - entityStatePdu_2 = pduFactory.makeEntityStatePdu(); - firePdu_1a = pduFactory.makeFirePdu(); - firePdu_1b = pduFactory.makeFirePdu(); - munitionDescriptor1 = new MunitionDescriptor(); - - // 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 declared and instances created, so now set their values. - // who is who in our big zoo, sufficient for global participation if we need it - entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID; - disChannel.addEntity(entityID_1); - - entityID_2.setSiteID(1).setApplicationID(2).setEntityID(4); // made-up example ID; - disChannel.addEntity(entityID_2); - // TODO someday, use enumerations for sites as part of a SimulationManager object; e.g. 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.setEntityType(new edu.nps.moves.dis7.entities.usa.platform.air.MV22B()); // note import statement at top - entityStatePdu_1.setMarking("Entity #53"); - entityStatePdu_1.getMarkingString(); // use Netbeans Debug breakpoint here to check left justified... - - 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 are key parameters for your simulation? - // more is needed here by scenario authors... - munitionDescriptor1.setQuantity(1); - firePdu_1a.setDescriptor(munitionDescriptor1).setRange(1000.0f); - } - - /** - * 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 might 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 for today's date and timestamp to zero, providing consistent outputs for each simulation run - String timeMessage = "Simulation time " + simulationTimeSeconds + " at LocalDateTime " + LocalDateTime.now(); - disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_TIME, timeMessage); - // TODO replace enumeration with disChannel.COMMENTPDU_TIME - // TODO fix VariableRecordType.TIME_AMP_DATE_VALID - - // =================================================================================================== - // 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? - - // are your reading any DIS PDUs from the network? check for them here - - // 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 sure this arrives to user even if other threads somehow become deadlocked - - - // 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 > MAX_LOOP_COUNT) // 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)(getSimulationTimeStepDuration() * 1000)); // units of seconds * (1000 msec/sec) = milliseconds - System.out.println ("... [Pausing for " + getSimulationTimeStepDuration() + " seconds]"); - - // OK now send the status PDUs for this loop, and then continue - System.out.println ("... sending PDUs of interest for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); - System.out.flush(); - - // TODO set timesteps in PDUs - - sendAllPdusForLoopTimestep(simulationTimeSeconds, - entityStatePdu_1, - firePdu_1a, - DisChannel.COMMENTPDU_APPLICATION_STATUS, - narrativeMessage1, narrativeMessage2, narrativeMessage3); - disChannel.sendSinglePdu(simulationTimeSeconds, entityStatePdu_2); // me too i.e. 2! - - System.out.println ("... [PDUs of interest 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; - } - simulationTimeSeconds += getSimulationTimeStepDuration(); // good practice: increment simulationTime as lastst action in that loop - - } // end of simulation loop, continue until done - // ===================================================================================================// ===================================================================================================// ===================================================================================================// =================================================================================================== - - narrativeMessage2 = "runSimulation() completed successfully"; // all done, so tell everyone else on the channel - // TODO better javadoc needs to be autogenerated for VariableRecordType enumerations - disChannel.sendCommentPdu(DisChannel.COMMENTPDU_NARRATIVE, narrativeMessage1, narrativeMessage2, narrativeMessage3); - System.out.println ("... [final=completion CommentPdu successfully sent for simulation]"); - -// disChannel.getPduRecorder(). TODO record XML as well - disChannel.leave(); // embedded SimulationManager is expected to send appropriate PDUs for entity, application shutdown - } - catch (InterruptedException iex) // handle any exception that your code might choose to provoke! - { - Logger.getLogger(ExampleSimulationProgram.class.getSimpleName()).log(Level.SEVERE, null, iex); - } - } - - /** - * Send EntityState, Fire, Comment PDUs that got updated for this loop, reflecting state of current simulation timestep. - * @param simTimeSeconds simulation time in second, applied to PDU as timestamp - * @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 PDU - * @param comments String array of narrative comments - * @see DisChannel -// * @see DisTime // TODO find renamed version - * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html" target="_blank">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments - */ - public void sendAllPdusForLoopTimestep(double simTimeSeconds, - EntityStatePdu entityStatePdu, - FirePdu firePdu, - VariableRecordType commentType, - // vararg... variable-length set of String comments can optionally follow - String... comments) - { - if (entityStatePdu != null) - disChannel.sendSinglePdu(simTimeSeconds, entityStatePdu); - - if (firePdu != null) - disChannel.sendSinglePdu(simTimeSeconds, firePdu); // bang - - disChannel.sendCommentPdu(simTimeSeconds, commentType, comments); // empty comments are filtered - } - - /** - * 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 handleArguments (String[] args) - { - // initial execution: handle args array of initialization arguments here - if (args.length == 2) - { - if ((args[0] != null) && !args[0].isEmpty()) - thisProgram.disChannel.setNetworkAddress(args[0]); - if ((args[1] != null) && !args[1].isEmpty()) - thisProgram.disChannel.setNetworkPort(Integer.parseInt(args[1])); - } - else if (args.length != 0) - { - System.err.println("Usage: " + thisProgram.getClass().getSimpleName() + " [address port]"); - System.exit(-1); - } - } - - /** - * Get simple descriptor (such as parent class name) for this network interface, used in trace statements - * @return simple descriptor name - */ - public String getDescriptor() { - return descriptor; - } - - /** - * Set new simple descriptor (such as parent class name) for this network interface, used in trace statements - * @param newDescriptor simple descriptor name for this interface - */ - public void setDescriptor(String newDescriptor) { - if (newDescriptor == null) - newDescriptor = ""; - this.descriptor = newDescriptor; - } - - /** - * parameter accessor method - * @return the simulationTimeStepDuration in seconds - */ - public double getSimulationTimeStepDuration() { - return simulationTimeStepDuration; - } - - /** - * parameter accessor method - * @param timeStepDurationSeconds the simulationTimeStepDuration in seconds to set - */ - public void setSimulationTimeStepDuration(double timeStepDurationSeconds) { - this.simulationTimeStepDuration = timeStepDurationSeconds; - } - - /** Locally instantiable copy of program, can be subclassed. */ - protected static ExampleSimulationProgram 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" target="_blank">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) - { - thisProgram = new ExampleSimulationProgram("test constructor"); // create instance of self within static main() method - - thisProgram.disChannel.printlnTRACE("main() started..."); - - thisProgram.handleArguments(args); // process any command-line invocation arguments - - thisProgram.runSimulationLoops(); // ... your simulation execution code goes in there ... - - thisProgram.disChannel.tearDownNetworkInterface(); // make sure no processes are left lingering - - thisProgram.disChannel.printlnTRACE("complete."); // report successful completion - - System.exit(0); // ensure all threads and sockets released - } -} +/** + * Copyright (c) 2008-2023, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html or 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.*; +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.DisChannel; +import edu.nps.moves.dis7.utilities.PduFactory; +import java.time.LocalDateTime; +import java.util.Random; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** The purpose of this inheritable class is to provide an easily modifiable + * example simulation program that includes DIS-capable entities performing + * tasks of interest, and then reporting activity via PDUs to the network. + * Default program initialization includes PDU recording turned on by default. + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt" target="_blank">ExampleSimulationProgramLog.txt</a> + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramPduCaptureLog.dislog" target="_blank">ExampleSimulationProgramPduCaptureLog.dislog</a> + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.pdf" target="_blank">ExampleSimulationProgramFlowDiagram.pdf</a> + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramWireshark.png" target="_blank">ExampleSimulationProgramWireshark.png</a> + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png" target="_blank">ExampleSimulationProgramSequenceDiagram.png</a> + */ +public class ExampleSimulationProgram +{ + /* **************************** infrastructure code, modification is seldom needed ************************* */ + + private String descriptor = this.getClass().getSimpleName(); + /** DIS channel defined by network address/port combination includes multiple utility capabilities */ + protected DisChannel disChannel; + /** Factory object used to create new PDU instances */ + protected PduFactory pduFactory; + + /** seconds per loop for real-time or simulation execution */ + private double simulationTimeStepDuration = 1.0; // seconds TODO encapsulate + /** initial simulation time in seconds */ + double simulationTimeInitial = 0.0; + /** current simulation time in seconds */ + double simulationTimeSeconds = simulationTimeInitial; + /** Maximum number of simulation loops */ + int MAX_LOOP_COUNT = 4; + + String narrativeMessage1 = new String(); + String narrativeMessage2 = new String(); + String narrativeMessage3 = new String(); + + /** EntityID settings for entity 1 */ + protected EntityID entityID_1 = new EntityID(); + /** EntityID settings for entity 2 */ + protected EntityID entityID_2 = new EntityID(); + /** EntityID settings for entity 3, a potential third-party observer and after-action reporter */ + protected EntityID entityID_3 = new EntityID(); + + /** ESPDU for entity 1 */ + protected EntityStatePdu entityStatePdu_1; + /** ESPDU for entity 2 */ + protected EntityStatePdu entityStatePdu_2; + /** FirePdu for entity 1 first weapon (if any) */ + protected FirePdu firePdu_1a; + /** FirePdu for entity 1 second weapon (if any) */ + protected FirePdu firePdu_1b; + /** MunitionDescriptor for these weapons */ + protected MunitionDescriptor munitionDescriptor1; + + /** TODO DetonationPdu for entity 1 second weapon (if any) */ + protected DetonationPdu detonationPdu_1a; + /** TODO DetonationPdu for entity 1 second weapon (if any) */ + protected DetonationPdu detonationPdu_1b; + + // hey programmer, what other state do you want? this is a good place to declare it... + + /** + * Constructor to create an instance of this class. + * Design goal: additional built-in initialization conveniences can go here + * to keep your efforts focused on the runSimulation() method. + */ + // base constructor is not invoked automatically by other constructors + // https://stackoverflow.com/questions/581873/best-way-to-handle-multiple-constructors-in-java + public ExampleSimulationProgram() + { + initialize(); + } + /** + * Constructor to create an instance of this class. + * @param newDescriptor describes this program, useful for logging and debugging + */ + public ExampleSimulationProgram(String newDescriptor) + { + descriptor = newDescriptor; + initialize(); + } + /** + * 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 ExampleSimulationProgram(String address, int port) + { + disChannel.setNetworkAddress (address); + disChannel.setNetworkPort (port); + disChannel.setVerboseComments (true); // TODO rename library method to disambiguate CommentPDU + // TODO still seems really chatty... add silent mode? + disChannel.setVerboseDisNetworkInterface(true); // Default false + disChannel.setVerbosePduRecorder (true); // default false + initialize(); + } + + /** Initialize channel setup for OpenDis7 and report a test PDU + * @see initializeDisChannel + * @see initializeSimulationEntities */ + private void initialize() + { + initializeDisChannel(); // must come first, uses PduFactory + + initializeSimulationEntities(); // set unchanging parameters + + disChannel.join(); // TODO further functionality expected + + String timeStepMessage = "Simulation timestep duration " + getSimulationTimeStepDuration() + " seconds"; + disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_SIMULATION_TIMESTEP, timeStepMessage); + // additional constructor initialization can go here + } + + /** Initialize channel setup for OpenDis7 and report a test PDU */ + private void initializeDisChannel() + { + if (disChannel == null) + disChannel = new DisChannel(); + else + { + disChannel.printlnTRACE ("*** warning, duplicate invocation of initializeDisChannel() ignored"); + return; + } + pduFactory = disChannel.getPduFactory(); + disChannel.setDescriptor(this.getClass().getSimpleName()); // ExampleSimulationProgram might be a superclass + disChannel.setUpNetworkInterface(); + disChannel.printlnTRACE ("just checking: disChannel.getNetworkAddress()=" + disChannel.getNetworkAddress() + + ", getNetworkPort()=" + disChannel.getNetworkPort()); + disChannel.getDisNetworkInterface().setVerbose(true); // sending and receipt + disChannel.printlnTRACE ("just checking: hasVerboseSending()=" + disChannel.getDisNetworkInterface().hasVerboseSending() + + ", hasVerboseReceipt()=" + disChannel.getDisNetworkInterface().hasVerboseReceipt()); + disChannel.getPduRecorder().setVerbose(true); + + // TODO confirm whether recorder is explicitly started by programmer (or not) + +// disChannel.sendCommentPdu(VariableRecordType.OTHER, "DisThreadedNetworkInterface.initializeDisChannel() complete"); // hello channel, debug + } + + /** Get ready, get set... initialize simulation entities. Who's who in the zoo? + */ + public void initializeSimulationEntities() + { + if (pduFactory == null) + pduFactory = disChannel.getPduFactory(); + entityStatePdu_1 = pduFactory.makeEntityStatePdu(); + entityStatePdu_2 = pduFactory.makeEntityStatePdu(); + firePdu_1a = pduFactory.makeFirePdu(); + firePdu_1b = pduFactory.makeFirePdu(); + munitionDescriptor1 = new MunitionDescriptor(); + + // can a third party report their independent (non-entity) status of a detonation? yes... + // if this is a third-party report, then that third party will need an independent EntityID + detonationPdu_1a = pduFactory.makeDetonationPdu(); + detonationPdu_1a.setSourceEntityID(entityID_3); + + // 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 declared and instances created, so now set their values. + // who is who in our big zoo, sufficient for global participation if we need it + entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID; + disChannel.addEntity(entityID_1); + + entityID_2.setSiteID(1).setApplicationID(2).setEntityID(4); // made-up example ID; + disChannel.addEntity(entityID_2); + // TODO someday, use enumerations for sites as part of a SimulationManager object; e.g. 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.setEntityType(new edu.nps.moves.dis7.entities.usa.platform.air.MV22B()); // note import statement at top + entityStatePdu_1.setMarking("Entity #53"); + entityStatePdu_1.getMarkingString(); // use Netbeans Debug breakpoint here to check left justified... + + 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 are key parameters for your simulation? + // more is needed here by scenario authors... + munitionDescriptor1.setQuantity(1); + firePdu_1a.setDescriptor(munitionDescriptor1).setRange(1000.0f); // TODO if not setting target entity, how to set direction? + } + + /** + * 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 might 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 for today's date and timestamp to zero, providing consistent outputs for each simulation run + String timeMessage = "Simulation time " + simulationTimeSeconds + " at LocalDateTime " + LocalDateTime.now(); + disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_TIME, timeMessage); + // TODO replace enumeration with disChannel.COMMENTPDU_TIME + // TODO fix VariableRecordType.TIME_AMP_DATE_VALID + + // =================================================================================================== + // 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? + + // are your reading any DIS PDUs from the network? check for them here + + // 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 sure this arrives to user even if other threads somehow become deadlocked + + // here are two built-in Java alternatives to generating random numbers + Random randomGenerator = new Random(); + int randomInt = randomGenerator.nextInt(100); // [0, 99] + double randomDouble = Math.random() * 100; // [0.0, 100.0) + + // 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 + narrativeMessage3 = "randomInt=" + randomInt + " randomDouble=" + randomDouble; + + // your loop termination condition goes here + if (simulationLoopCount > MAX_LOOP_COUNT) // 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)(getSimulationTimeStepDuration() * 1000)); // units of seconds * (1000 msec/sec) = milliseconds + System.out.println ("... [Pausing for " + getSimulationTimeStepDuration() + " seconds]"); + + // OK now send the status PDUs for this loop, and then continue + System.out.println ("... sending PDUs of interest for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); + System.out.flush(); + + // TODO set timesteps in PDUs + + sendAllPdusForLoopTimestep(simulationTimeSeconds, + entityStatePdu_1, + firePdu_1a, + DisChannel.COMMENTPDU_APPLICATION_STATUS, + narrativeMessage1, narrativeMessage2, narrativeMessage3); + disChannel.sendSinglePdu(simulationTimeSeconds, entityStatePdu_2); // me too i.e. 2! + + System.out.println ("... [PDUs of interest 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; + } + simulationTimeSeconds += getSimulationTimeStepDuration(); // good practice: increment simulationTime as lastst action in that loop + + } // end of simulation loop, continue until done + // ===================================================================================================// ===================================================================================================// ===================================================================================================// =================================================================================================== + + narrativeMessage2 = "runSimulation() completed successfully"; // all done, so tell everyone else on the channel + // TODO better javadoc needs to be autogenerated for VariableRecordType enumerations + disChannel.sendCommentPdu(DisChannel.COMMENTPDU_NARRATIVE, narrativeMessage1, narrativeMessage2, narrativeMessage3); + System.out.println ("... [final=completion CommentPdu successfully sent for simulation]"); + +// disChannel.getPduRecorder(). TODO record XML as well + disChannel.leave(); // embedded SimulationManager is expected to send appropriate PDUs for entity, application shutdown + } + catch (InterruptedException iex) // handle any exception that your code might choose to provoke! + { + Logger.getLogger(ExampleSimulationProgram.class.getSimpleName()).log(Level.SEVERE, null, iex); + } + } + + /** + * Send EntityState, Fire, Comment PDUs that got updated for this loop, reflecting state of current simulation timestep. + * @param simTimeSeconds simulation time in second, applied to PDU as timestamp + * @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 PDU + * @param comments String array of narrative comments + * @see DisChannel +// * @see DisTime // TODO find renamed version + * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html" target="_blank">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments + */ + public void sendAllPdusForLoopTimestep(double simTimeSeconds, + EntityStatePdu entityStatePdu, + FirePdu firePdu, + VariableRecordType commentType, + // vararg... variable-length set of String comments can optionally follow + String... comments) + { + if (entityStatePdu != null) + disChannel.sendSinglePdu(simTimeSeconds, entityStatePdu); + + if (firePdu != null) + disChannel.sendSinglePdu(simTimeSeconds, firePdu); // bang + + disChannel.sendCommentPdu(simTimeSeconds, commentType, comments); // empty comments are filtered + } + + /** + * 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 handleArguments (String[] args) + { + // initial execution: handle args array of initialization arguments here + if (args.length == 2) + { + if ((args[0] != null) && !args[0].isEmpty()) + thisProgram.disChannel.setNetworkAddress(args[0]); + if ((args[1] != null) && !args[1].isEmpty()) + thisProgram.disChannel.setNetworkPort(Integer.parseInt(args[1])); + } + else if (args.length != 0) + { + System.err.println("Usage: " + thisProgram.getClass().getSimpleName() + " [address port]"); + System.exit(-1); + } + } + + /** + * Get simple descriptor (such as parent class name) for this network interface, used in trace statements + * @return simple descriptor name + */ + public String getDescriptor() { + return descriptor; + } + + /** + * Set new simple descriptor (such as parent class name) for this network interface, used in trace statements + * @param newDescriptor simple descriptor name for this interface + */ + public void setDescriptor(String newDescriptor) { + if (newDescriptor == null) + newDescriptor = ""; + this.descriptor = newDescriptor; + } + + /** + * parameter accessor method + * @return the simulationTimeStepDuration in seconds + */ + public double getSimulationTimeStepDuration() { + return simulationTimeStepDuration; + } + + /** + * parameter accessor method + * @param timeStepDurationSeconds the simulationTimeStepDuration in seconds to set + */ + public void setSimulationTimeStepDuration(double timeStepDurationSeconds) { + this.simulationTimeStepDuration = timeStepDurationSeconds; + } + + /** Locally instantiable copy of program, can be subclassed. */ + protected static ExampleSimulationProgram 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" target="_blank">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) + { + System.out.println("Wireshark filter for listening to these PDUs: (udp.port == 3000) && dis"); // && + + thisProgram = new ExampleSimulationProgram("test constructor"); // create instance of self within static main() method + + thisProgram.disChannel.printlnTRACE("main() started..."); + + thisProgram.handleArguments(args); // process any command-line invocation arguments + + thisProgram.runSimulationLoops(); // ... your simulation execution code goes in there ... + + thisProgram.disChannel.tearDownNetworkInterface(); // make sure no processes are left lingering + + thisProgram.disChannel.printlnTRACE("complete."); // report successful completion + + System.exit(0); // ensure all threads and sockets released + } +} diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt b/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt index 0ce55da0ce509e00ea261673753be263b3403001..9665a4701356d8f8f0a838bb1c2a57add992d104 100644 --- a/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt +++ b/examples/src/OpenDis7Examples/ExampleSimulationProgramLog.txt @@ -1,110 +1,111 @@ -ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/ExampleSimulationProgram.java -Drun.class=OpenDis7Examples.ExampleSimulationProgram run-single -init: -Deleting: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties -deps-jar: -Updating property file: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties -Compiling 1 source file to C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes -compile-single: -run-single: -[DisChannel] thisHostName=IT160907-INFLPP -[DisChannel ExampleSimulationProgram] Beginning pdu save to directory ./pduLog -[PduRecorder ExampleSimulationProgram] Recorder log file open: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog.dislog -[DisThreadedNetworkInterface] using network interface PANGP Virtual Ethernet Adapter Secure #2 -[DisThreadedNetworkInterface] datagramSocket.joinGroup address=239.1.2.3 port=3000 isConnected()=false createDatagramSocket() complete. -[DisThreadedNetworkInterface] createThreads() sendingThread.isAlive()=true -[DisThreadedNetworkInterface] createThreads() receiveThread.isAlive()=true -[PduRecorder ExampleSimulationProgram] listening to IP address 239.1.2.3 on port 3000 -[DisChannel ExampleSimulationProgram] Network confirmation: address=239.1.2.3 port=3000 -[DisChannel ExampleSimulationProgram] just checking: disChannel.getNetworkAddress()=239.1.2.3, getNetworkPort()=3000 -[DisChannel ExampleSimulationProgram] just checking: hasVerboseSending()=true, hasVerboseReceipt()=true -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 1] DisPduType 11 CREATE_ENTITY, size 28 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 2] DisPduType 11 CREATE_ENTITY, size 28 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 1] DisPduType 11 CREATE_ENTITY, size 28 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 3] DisPduType 22 COMMENT, size 80 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 2] DisPduType 11 CREATE_ENTITY, size 28 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 3] DisPduType 22 COMMENT, size 80 bytes) -[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_TIMESTEP] [Simulation timestep duration 1.0 seconds] -[DisChannel ExampleSimulationProgram] main() started... -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 4] DisPduType 22 COMMENT, size 112 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 4] DisPduType 22 COMMENT, size 112 bytes) -[DisChannel ExampleSimulationProgram] *** [CommentPdu TIME] [Simulation time 0.0 at LocalDateTime 2024-08-18T22:14:05.314481400] -... My simulation just did something, no really... -... [Pausing for 1.0 seconds] -... sending PDUs of interest for simulation step 1, monitor loopback to confirm sent -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 5] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 5] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 6] DisPduType 02 FIRE, size 96 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 6] DisPduType 02 FIRE, size 96 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 7] DisPduType 22 COMMENT, size 104 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 7] DisPduType 22 COMMENT, size 104 bytes) -[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_STATUS] [MV3500 ExampleSimulationProgram, runSimulation() loop 1] -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 8] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 8] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) -... [PDUs of interest successfully sent for this loop] -... My simulation just did something, no really... -... [Pausing for 1.0 seconds] -... sending PDUs of interest for simulation step 2, monitor loopback to confirm sent -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 9] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 9] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 10] DisPduType 02 FIRE, size 96 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 10] DisPduType 02 FIRE, size 96 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 11] DisPduType 22 COMMENT, size 104 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 11] DisPduType 22 COMMENT, size 104 bytes) -[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_STATUS] [MV3500 ExampleSimulationProgram, runSimulation() loop 2] -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 12] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 12] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) -... [PDUs of interest successfully sent for this loop] -... My simulation just did something, no really... -... [Pausing for 1.0 seconds] -... sending PDUs of interest for simulation step 3, monitor loopback to confirm sent -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 13] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 13] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 14] DisPduType 02 FIRE, size 96 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 14] DisPduType 02 FIRE, size 96 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 15] DisPduType 22 COMMENT, size 104 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 15] DisPduType 22 COMMENT, size 104 bytes) -[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_STATUS] [MV3500 ExampleSimulationProgram, runSimulation() loop 3] -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 16] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 16] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) -... [PDUs of interest successfully sent for this loop] -... My simulation just did something, no really... -... [Pausing for 1.0 seconds] -... sending PDUs of interest for simulation step 4, monitor loopback to confirm sent -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 17] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 17] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 18] DisPduType 02 FIRE, size 96 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 18] DisPduType 02 FIRE, size 96 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 19] DisPduType 22 COMMENT, size 104 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 19] DisPduType 22 COMMENT, size 104 bytes) -[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_STATUS] [MV3500 ExampleSimulationProgram, runSimulation() loop 4] -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 20] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 20] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) -... [PDUs of interest successfully sent for this loop] -... My simulation just did something, no really... -... [Pausing for 1.0 seconds] -... sending PDUs of interest for simulation step 5, monitor loopback to confirm sent -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 21] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 21] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 22] DisPduType 02 FIRE, size 96 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 22] DisPduType 02 FIRE, size 96 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 23] DisPduType 22 COMMENT, size 104 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 23] DisPduType 22 COMMENT, size 104 bytes) -[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_STATUS] [MV3500 ExampleSimulationProgram, runSimulation() loop 5] -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 24] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 24] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) -... [PDUs of interest successfully sent for this loop] -... [loop termination condition met, simulationComplete=true] -[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 25] DisPduType 22 COMMENT, size 120 bytes) -[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 25] DisPduType 22 COMMENT, size 120 bytes) -[DisChannel ExampleSimulationProgram] *** [CommentPdu COMPLETE_EVENT_REPORT] [MV3500 ExampleSimulationProgram, runSimulation() completed successfully] -... [final=completion CommentPdu successfully sent for simulation] -*** setKillSentinelAndInterrupts() sentinel killed=true sendingThread.isInterrupted()=true receiveThread.isInterrupted()=true -[DisThreadedNetworkInterface ExampleSimulationProgram] datagramSocket.leaveGroup address=239.1.2.3 port=3000 isClosed()=true close() complete. -*** 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 - -PduRecorder.stop() closing recorder log file: - C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog.dislog -[DisChannel ExampleSimulationProgram] complete. -BUILD SUCCESSFUL (total time: 12 seconds) +ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/ExampleSimulationProgram.java -Drun.class=OpenDis7Examples.ExampleSimulationProgram run-single +init: +Deleting: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +Wireshark filter for listening to these PDUs: (udp.port == 3000) && dis +[DisChannel] thisHostName=IT162140-CSCLPP +[DisChannel ExampleSimulationProgram] Beginning pdu save to directory ./pduLog +[PduRecorder ExampleSimulationProgram] Recorder log file open: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog.dislog +[DisThreadedNetworkInterface] using network interface Intel(R) Wi-Fi 6E AX211 160MHz +[DisThreadedNetworkInterface] datagramSocket.joinGroup address=239.1.2.3 port=3000 isConnected()=false createDatagramSocket() complete. +[DisThreadedNetworkInterface] createThreads() sendingThread.isAlive()=true +[DisThreadedNetworkInterface] createThreads() receiveThread.isAlive()=true +[PduRecorder ExampleSimulationProgram] listening to IP address 239.1.2.3 on port 3000 +[DisChannel ExampleSimulationProgram] Network confirmation: address=239.1.2.3 port=3000 +[DisChannel ExampleSimulationProgram] just checking: disChannel.getNetworkAddress()=239.1.2.3, getNetworkPort()=3000 +[DisChannel ExampleSimulationProgram] just checking: hasVerboseSending()=true, hasVerboseReceipt()=true +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 1] DisPduType 11 CREATE_ENTITY, size 28 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 2] DisPduType 11 CREATE_ENTITY, size 28 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 1] DisPduType 11 CREATE_ENTITY, size 28 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 3] DisPduType 22 COMMENT, size 80 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 2] DisPduType 11 CREATE_ENTITY, size 28 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 3] DisPduType 22 COMMENT, size 80 bytes) +[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_TIMESTEP] [Simulation timestep duration 1.0 seconds] +[DisChannel ExampleSimulationProgram] main() started... +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 4] DisPduType 22 COMMENT, size 104 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 4] DisPduType 22 COMMENT, size 104 bytes) +[DisChannel ExampleSimulationProgram] *** [CommentPdu TIME] [Simulation time 0.0 at LocalDateTime 2024-09-04T17:26:50.472502] +... My simulation just did something, no really... +... [Pausing for 1.0 seconds] +... sending PDUs of interest for simulation step 1, monitor loopback to confirm sent +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 5] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 5] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 6] DisPduType 02 FIRE, size 96 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 6] DisPduType 02 FIRE, size 96 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 7] DisPduType 22 COMMENT, size 160 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 7] DisPduType 22 COMMENT, size 160 bytes) +[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_STATUS] [MV3500 ExampleSimulationProgram, runSimulation() loop 1, randomInt=74 randomDouble=33.50178281121777] +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 8] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 8] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) +... [PDUs of interest successfully sent for this loop] +... My simulation just did something, no really... +... [Pausing for 1.0 seconds] +... sending PDUs of interest for simulation step 2, monitor loopback to confirm sent +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 9] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 9] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 10] DisPduType 02 FIRE, size 96 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 10] DisPduType 02 FIRE, size 96 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 11] DisPduType 22 COMMENT, size 160 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 11] DisPduType 22 COMMENT, size 160 bytes) +[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_STATUS] [MV3500 ExampleSimulationProgram, runSimulation() loop 2, randomInt=16 randomDouble=40.130522928043725] +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 12] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 12] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) +... [PDUs of interest successfully sent for this loop] +... My simulation just did something, no really... +... [Pausing for 1.0 seconds] +... sending PDUs of interest for simulation step 3, monitor loopback to confirm sent +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 13] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 13] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 14] DisPduType 02 FIRE, size 96 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 14] DisPduType 02 FIRE, size 96 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 15] DisPduType 22 COMMENT, size 160 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 15] DisPduType 22 COMMENT, size 160 bytes) +[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_STATUS] [MV3500 ExampleSimulationProgram, runSimulation() loop 3, randomInt=50 randomDouble=84.78451008966688] +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 16] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 16] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) +... [PDUs of interest successfully sent for this loop] +... My simulation just did something, no really... +... [Pausing for 1.0 seconds] +... sending PDUs of interest for simulation step 4, monitor loopback to confirm sent +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 17] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 17] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 18] DisPduType 02 FIRE, size 96 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 18] DisPduType 02 FIRE, size 96 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 19] DisPduType 22 COMMENT, size 160 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 19] DisPduType 22 COMMENT, size 160 bytes) +[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_STATUS] [MV3500 ExampleSimulationProgram, runSimulation() loop 4, randomInt=46 randomDouble=47.40264153569124] +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 20] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 20] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) +... [PDUs of interest successfully sent for this loop] +... My simulation just did something, no really... +... [Pausing for 1.0 seconds] +... sending PDUs of interest for simulation step 5, monitor loopback to confirm sent +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 21] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 21] DisPduType 01 ENTITY_STATE Entity #53, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 22] DisPduType 02 FIRE, size 96 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 22] DisPduType 02 FIRE, size 96 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 23] DisPduType 22 COMMENT, size 160 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 23] DisPduType 22 COMMENT, size 160 bytes) +[DisChannel ExampleSimulationProgram] *** [CommentPdu APPLICATION_STATUS] [MV3500 ExampleSimulationProgram, runSimulation() loop 5, randomInt=38 randomDouble=30.883227412112014] +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 24] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 24] DisPduType 01 ENTITY_STATE Entity #2, size 144 bytes) +... [PDUs of interest successfully sent for this loop] +... [loop termination condition met, simulationComplete=true] +[DisThreadedNetworkInterface ExampleSimulationProgram] [sending 25] DisPduType 22 COMMENT, size 176 bytes) +[DisThreadedNetworkInterface ExampleSimulationProgram] [receipt 25] DisPduType 22 COMMENT, size 176 bytes) +[DisChannel ExampleSimulationProgram] *** [CommentPdu COMPLETE_EVENT_REPORT] [MV3500 ExampleSimulationProgram, runSimulation() completed successfully, randomInt=38 randomDouble=30.883227412112014] +... [final=completion CommentPdu successfully sent for simulation] +*** setKillSentinelAndInterrupts() sentinel killed=true sendingThread.isInterrupted()=true receiveThread.isInterrupted()=true +[DisThreadedNetworkInterface ExampleSimulationProgram] datagramSocket.leaveGroup address=239.1.2.3 port=3000 isClosed()=true close() complete. +*** 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 + +PduRecorder.stop() closing recorder log file: + C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog.dislog +[DisChannel ExampleSimulationProgram] complete. +BUILD SUCCESSFUL (total time: 11 seconds) diff --git a/specifications/README.md b/specifications/README.md index 5c0513b70bc69ddb81eb3af7405124a622be7b35..3fea36d3884d3c698a3312da8d9636e3259aaf55 100644 --- a/specifications/README.md +++ b/specifications/README.md @@ -1,91 +1,95 @@ -# Specification Documents, IEEE and SISO -# Distributed Interactive Simulation (DIS) Protocol - -<!-- To properly view Markdown, go the the online web page: - https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/specifications/README.md --> - -*Distributed Interactive Simulation (DIS) is an -[Institute of Electrical and Electronics Engineers (IEEE)](https://www.ieee.org) standard for conducting -real-time platform-level wargaming across multiple host computers and is used worldwide, -especially by military organizations but also by other agencies such as those involved in -space exploration and medicine.* -* Wikipedia: [Distributed Interactive Simulation (DIS)](https://en.wikipedia.org/wiki/Distributed_Interactive_Simulation) IEEE Standard and [RPR FOM](https://en.wikipedia.org/wiki/RPR_FOM) -* [Simulation Interoperability Standards Organization (SISO)](https://www.sisostandards.org): "Simulation Interoperability and Reuse through Standards" -* SISO [DIS / RPR FOM PSG - Distributed Interactive Simulation / Real-time Platform Reference Federation Object Model](https://www.sisostandards.org/StandardsActivities/SupportGroups/DISRPRFOMPSG.aspx) Product Support Group (PSG) -* SISO [Standards Data Files](https://www.sisostandards.org/Schemas.aspx) including various schemas - -## Working-Group Resources - -### DIS/RPR FOM Product Support Group <a href="https://www.sisostandards.org/StandardsActivities/SupportGroups/DISRPRFOMPSG.aspx" target="_blank"><img src="SisoLogo.jpg" width="314" align="right"/></a> -* "The Distributed Interactive Simulation / Real-time Platform Reference Federation Object Model (DIS / RPR FOM) Product Support Group (PSG) is a permanent support group chartered by the SISO Standards Activity Committee to support multiple DIS-related products." -* [Distributed Interactive Simulation / Real-time Platform Reference Federation Object Model (DIS / RPR FOM) Product Support Group (PSG)](https://www.sisostandards.org/StandardsActivities/SupportGroups/DISRPRFOMPSG.aspx) -* [SISO Digital Library](https://www.sisostandards.org/Default.aspx?tabid=105&EntryId=31596) -** [DIS Introduction and Briefings](https://www.sisostandards.org/Default.aspx?tabid=105&EntryId=31596) -** [IEEE 1278 Bibliography Material](https://www.sisostandards.org/Default.aspx?tabid=105&EntryId=31596) -** [DIS PDU data structures](IeeeDisPduColorFigures.pdf) -** [Compressed DIS](2019-SIW-Presentation-039_CompressedDis.pdf) overview, Lance Call, Simulation Interoperability Workshop (SIW), Orlando Florida, February 2019. - -Specification download links follow. For free access, IEEE standards must be downloaded manually while within NPS campus or firewall. - -## Standards Documents - -An IEEEExplore account is required to access or purchase these standards documents. Meanwhile, -NPS personnel can obtain the following standards without charge when accessing via nps.edu networks. - -### 1278.1-2012. IEEE Standard for Distributed Interactive Simulation (DIS) - Application Protocols <a href="https://ieeexplore.ieee.org/document/6387564" target="_blank"><img src="IeeeLogo.jpg" width="120" align="right"/></a> -* https://ieeexplore.ieee.org/document/6387564 -* *Abstract.* -Data messages, known as Protocol Data Units (PDUs), that are exchanged on a network among simulation applications are defined. These PDUs are for interactions that take place within specified domains called protocol families, which include Entity Information/ Interaction, Warfare, Logistics, Simulation Management, Distributed Emission Regeneration, Radio Communications, Entity Management, Minefield, Synthetic Environment, Simulation Management with Reliability, Information Operations, Live Entity Information/Interaction, and Non-Real-Time protocol. -* Date of Publication: 19 Dec. 2012 -* Electronic ISBN: 978-0-7381-7310-8 -* Also [IEEE Std 1278.1-2012 (Revision of IEEE Std 1278.1-1995)](https://standards.ieee.org/findstds/standard/1278.1-2012.html) - ---- - -### 1278.2-2015. IEEE Standard for Distributed Interactive Simulation (DIS) - Communication Services and Profiles <a href="https://ieeexplore.ieee.org/document/7459689" target="_blank"><img src="IeeeLogo.jpg" width="120" align="right"/></a> -* https://ieeexplore.ieee.org/document/7459689 -* *Abstract.* -Communication services to support information exchange between simulation applications participating in the distributed interactive simulation (DIS) environment are defined. These communication services describe a connectionless information transfer that supports real-time, as well as non-real-time, exchange. Several communication profiles specifying communication services are provided. -* *Scope.* -This standard establishes the requirements for the communication services to be used in a DIS simulation. This standard supports IEEE Std 1278.1. -* *Purpose.* -The purpose of this standard is to establish requirements for communication subsystems that support DIS applications. This standard provides service requirements and associated profiles that can be individually selected to meet specific DIS system operational requirements. -* Date of Publication: 6 Nov. 2015 -* Electronic ISBN: 978-0-7381-9909-2 - ---- - -### 1278.3-1996. IEEE Recommended Practice for Distributed Interactive Simulation - Exercise Management and Feedback <a href="https://ieeexplore.ieee.org/document/587529" target="_blank"><img src="IeeeLogo.jpg" width="120" align="right"/></a> -* https://ieeexplore.ieee.org/document/587529 -* *Abstract.* -Guidelines are established for exercise management and feedback in distributed interactive simulation (DIS) exercises. Guidance is provided to sponsors, providers and supporters of DIS-compliant systems and exercises as well as to developers of DIS exercise management and feedback stations. The activities of the organizations involved in a DIS exercise and the top-level processes used to accomplish those activities are addressed. The functional requirements of the exercise management and feedback process are also addressed. This standard is one of a series of standards developed for DIS to assure interoperability between dissimilar simulations for currently installed and future simulations developed by different organizations. -* Date of Publication 1997, Reaffirmed 2002. - ---- - -### 4. 1278.4-1997. IEEE Recommended Practice for Distributed Interactive Simulation - Verification, Validation, and Accreditation <a href="https://ieeexplore.ieee.org/document/8685803" target="_blank"><img src="IeeeLogo.jpg" width="120" align="right"/></a> -* https://ieeexplore.ieee.org/document/8685803 -* *Abstract.* -Guidelines are established for the verification, validation, and accreditation (VV&A) of distributed interactive simulation (DIS) exercises. How-to procedures for planning and conducting DIS exercise VV&A are provided. Intended for use in conjunction with IEEE Std 1278.3-1996, this recommended practice presents data flow and connectivity for all proposed verification and validation activities and provides rationale and justification for each step. VV&A guidance is provided to exercise users/sponsors and developers. -* Date of Publication: 10 Sept. 2013 -* Electronic ISBN: 978-0-7381-6281-2 - ---- - -### 5. SISO-REF-010-2023: Reference for Enumerations for Simulation Interoperability <a href="https://www.sisostandards.org/ProductsPublications/ReferenceDocuments.aspx" target="_blank"><img src="SisoLogo.jpg" width="314" align="right"/></a> -* https://www.sisostandards.org/ProductsPublications/ReferenceDocuments.aspx (scroll down to bottom of page) -* *Abstract.* -SISO-REF-010 specifies numerical values and associated definitions for fields that are identified as enumerations in SISO Standards Products and SISO-sponsored standards published by IEEE for High Level Architecture (HLA) and Distributed Interactive Simulation (DIS). Enumerations for simulations may be applied in other architectures, such as the Test and Training Enabling Architecture (TENA). -* Resources include [SISO-REF-010-2023 distribution](https://www.sisostandards.org/DigitalLibrary.aspx?Command=Core_Download&EntryId=46171), -[enumerations PDF](https://www.sisostandards.org/DigitalLibrary.aspx?Command=Core_Download&EntryId=46172), -[Operations Manual (OPMAN)](https://www.sisostandards.org/DigitalLibrary.aspx?Command=Core_Download&EntryId=47284) and -[latest version of all resources](https://svn.code.sf.net/p/esitools/code/Release_Information/Current_DRAFT) ---- - -### 6. SISO-STD-001-2015: Standard for Guidance, Rationale, and Interoperability Modalities (GRIM) for the Real-time Platform Reference Federation Object Model (RPR FOM) <a href="https://www.sisostandards.org/ProductsPublications/ReferenceDocuments.aspx" target="_blank"><img src="SisoLogo.jpg" width="314" align="right"/></a> -* https://www.sisostandards.org/ProductsPublications/Standards/SISOStandards.aspx (scroll down near bottom of page) -* *Abstract.* -SISO-STD-001-2015 encapsulates guidance in the use of the RPR FOM. It provides descriptions of FOM classes and data types and the relationship between Distributed Interactive Simulation (DIS) and the High Level Architecture (HLA)-based RPR FOM, as well as rules for accomplishing specific distributed simulation tasks. -* Version 2.0 (10 Aug 2015) - ---- +# Specification Documents, IEEE and SISO +# Distributed Interactive Simulation (DIS) Protocol + +<!-- To properly view Markdown, go the the online web page: + https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/specifications/README.md --> + +*Distributed Interactive Simulation (DIS) is an +[Institute of Electrical and Electronics Engineers (IEEE)](https://www.ieee.org) standard for conducting +real-time platform-level wargaming across multiple host computers and is used worldwide, +especially by military organizations but also by other agencies such as those involved in +space exploration and medicine.* +* Wikipedia: [Distributed Interactive Simulation (DIS)](https://en.wikipedia.org/wiki/Distributed_Interactive_Simulation) IEEE Standard and [RPR FOM](https://en.wikipedia.org/wiki/RPR_FOM) +* [Simulation Interoperability Standards Organization (SISO)](https://www.sisostandards.org): "Simulation Interoperability and Reuse through Standards" +* SISO [DIS / RPR FOM PSG - Distributed Interactive Simulation / Real-time Platform Reference Federation Object Model](https://www.sisostandards.org/StandardsActivities/SupportGroups/DISRPRFOMPSG.aspx) Product Support Group (PSG) +* SISO [Standards Data Files](https://www.sisostandards.org/Schemas.aspx) including various schemas + +## Working-Group Resources + +### C2SIM PSG/PDG - Command and Control Systems - Simulationation Systems Interoperability (C2SIM) +* [Library](https://sisostandards.connectedcommunity.org/communities/community-home/librarydocuments?communitykey=e127ad67-6994-466f-808b-e7a1719c2478&LibraryFolderKey=&DefaultView=) + + +### DIS/RPR FOM Product Support Group <a href="https://www.sisostandards.org/StandardsActivities/SupportGroups/DISRPRFOMPSG.aspx" target="_blank"><img src="SisoLogo.jpg" width="314" align="right"/></a> +* "The Distributed Interactive Simulation / Real-time Platform Reference Federation Object Model (DIS / RPR FOM) Product Support Group (PSG) is a permanent support group chartered by the SISO Standards Activity Committee to support multiple DIS-related products." +* [Distributed Interactive Simulation / Real-time Platform Reference Federation Object Model (DIS / RPR FOM) Product Support Group (PSG)](https://www.sisostandards.org/StandardsActivities/SupportGroups/DISRPRFOMPSG.aspx) +* [SISO Digital Library](https://www.sisostandards.org/Default.aspx?tabid=105&EntryId=31596) +** [DIS Introduction and Briefings](https://www.sisostandards.org/Default.aspx?tabid=105&EntryId=31596) +** [IEEE 1278 Bibliography Material](https://www.sisostandards.org/Default.aspx?tabid=105&EntryId=31596) +** [DIS PDU data structures](IeeeDisPduColorFigures.pdf) +** [Compressed DIS](2019-SIW-Presentation-039_CompressedDis.pdf) overview, Lance Call, Simulation Interoperability Workshop (SIW), Orlando Florida, February 2019. +** DISv8 Library](https://sisostandards.connectedcommunity.org/communities/community-home/librarydocuments?communitykey=f63434dd-df8c-4b41-892c-f03f0a2ea4bb&LibraryFolderKey=&DefaultView=) +Specification download links follow. For free access, IEEE standards must be downloaded manually while within NPS campus or firewall. + +## Standards Documents + +An IEEEExplore account is usually required to access or purchase these standards documents. Meanwhile, +NPS personnel can obtain the following standards without charge when accessing via nps.edu networks. + +### 1278.1-2012. IEEE Standard for Distributed Interactive Simulation (DIS) - Application Protocols <a href="https://ieeexplore.ieee.org/document/6387564" target="_blank"><img src="IeeeLogo.jpg" width="120" align="right"/></a> +* https://ieeexplore.ieee.org/document/6387564 +* *Abstract.* +Data messages, known as Protocol Data Units (PDUs), that are exchanged on a network among simulation applications are defined. These PDUs are for interactions that take place within specified domains called protocol families, which include Entity Information/ Interaction, Warfare, Logistics, Simulation Management, Distributed Emission Regeneration, Radio Communications, Entity Management, Minefield, Synthetic Environment, Simulation Management with Reliability, Information Operations, Live Entity Information/Interaction, and Non-Real-Time protocol. +* Date of Publication: 19 Dec. 2012 +* Electronic ISBN: 978-0-7381-7310-8 +* Also [IEEE Std 1278.1-2012 (Revision of IEEE Std 1278.1-1995)](https://standards.ieee.org/findstds/standard/1278.1-2012.html) + +--- + +### 1278.2-2015. IEEE Standard for Distributed Interactive Simulation (DIS) - Communication Services and Profiles <a href="https://ieeexplore.ieee.org/document/7459689" target="_blank"><img src="IeeeLogo.jpg" width="120" align="right"/></a> +* https://ieeexplore.ieee.org/document/7459689 +* *Abstract.* +Communication services to support information exchange between simulation applications participating in the distributed interactive simulation (DIS) environment are defined. These communication services describe a connectionless information transfer that supports real-time, as well as non-real-time, exchange. Several communication profiles specifying communication services are provided. +* *Scope.* +This standard establishes the requirements for the communication services to be used in a DIS simulation. This standard supports IEEE Std 1278.1. +* *Purpose.* +The purpose of this standard is to establish requirements for communication subsystems that support DIS applications. This standard provides service requirements and associated profiles that can be individually selected to meet specific DIS system operational requirements. +* Date of Publication: 6 Nov. 2015 +* Electronic ISBN: 978-0-7381-9909-2 + +--- + +### 1278.3-1996. IEEE Recommended Practice for Distributed Interactive Simulation - Exercise Management and Feedback <a href="https://ieeexplore.ieee.org/document/587529" target="_blank"><img src="IeeeLogo.jpg" width="120" align="right"/></a> +* https://ieeexplore.ieee.org/document/587529 +* *Abstract.* +Guidelines are established for exercise management and feedback in distributed interactive simulation (DIS) exercises. Guidance is provided to sponsors, providers and supporters of DIS-compliant systems and exercises as well as to developers of DIS exercise management and feedback stations. The activities of the organizations involved in a DIS exercise and the top-level processes used to accomplish those activities are addressed. The functional requirements of the exercise management and feedback process are also addressed. This standard is one of a series of standards developed for DIS to assure interoperability between dissimilar simulations for currently installed and future simulations developed by different organizations. +* Date of Publication 1997, Reaffirmed 2002. + +--- + +### 4. 1278.4-1997. IEEE Recommended Practice for Distributed Interactive Simulation - Verification, Validation, and Accreditation <a href="https://ieeexplore.ieee.org/document/8685803" target="_blank"><img src="IeeeLogo.jpg" width="120" align="right"/></a> +* https://ieeexplore.ieee.org/document/8685803 +* *Abstract.* +Guidelines are established for the verification, validation, and accreditation (VV&A) of distributed interactive simulation (DIS) exercises. How-to procedures for planning and conducting DIS exercise VV&A are provided. Intended for use in conjunction with IEEE Std 1278.3-1996, this recommended practice presents data flow and connectivity for all proposed verification and validation activities and provides rationale and justification for each step. VV&A guidance is provided to exercise users/sponsors and developers. +* Date of Publication: 10 Sept. 2013 +* Electronic ISBN: 978-0-7381-6281-2 + +--- + +### 5. SISO-REF-010-2023: Reference for Enumerations for Simulation Interoperability <a href="https://www.sisostandards.org/ProductsPublications/ReferenceDocuments.aspx" target="_blank"><img src="SisoLogo.jpg" width="314" align="right"/></a> +* https://www.sisostandards.org/ProductsPublications/ReferenceDocuments.aspx (scroll down to bottom of page) +* *Abstract.* +SISO-REF-010 specifies numerical values and associated definitions for fields that are identified as enumerations in SISO Standards Products and SISO-sponsored standards published by IEEE for High Level Architecture (HLA) and Distributed Interactive Simulation (DIS). Enumerations for simulations may be applied in other architectures, such as the Test and Training Enabling Architecture (TENA). +* Resources include [SISO-REF-010-2023 distribution](https://www.sisostandards.org/DigitalLibrary.aspx?Command=Core_Download&EntryId=46171), +[enumerations PDF](https://www.sisostandards.org/DigitalLibrary.aspx?Command=Core_Download&EntryId=46172), +[Operations Manual (OPMAN)](https://www.sisostandards.org/DigitalLibrary.aspx?Command=Core_Download&EntryId=47284) and +[latest version of all resources](https://svn.code.sf.net/p/esitools/code/Release_Information/Current_DRAFT) +--- + +### 6. SISO-STD-001-2015: Standard for Guidance, Rationale, and Interoperability Modalities (GRIM) for the Real-time Platform Reference Federation Object Model (RPR FOM) <a href="https://www.sisostandards.org/ProductsPublications/ReferenceDocuments.aspx" target="_blank"><img src="SisoLogo.jpg" width="314" align="right"/></a> +* https://www.sisostandards.org/ProductsPublications/Standards/SISOStandards.aspx (scroll down near bottom of page) +* *Abstract.* +SISO-STD-001-2015 encapsulates guidance in the use of the RPR FOM. It provides descriptions of FOM classes and data types and the relationship between Distributed Interactive Simulation (DIS) and the High Level Architecture (HLA)-based RPR FOM, as well as rules for accomplishing specific distributed simulation tasks. +* Version 2.0 (10 Aug 2015) + +---