diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework1/Romero/Homework.java b/assignments/src/MV3500Cohort2024JulySeptember/homework1/Romero/Homework.java new file mode 100644 index 0000000000000000000000000000000000000000..396d1cfa5ffc06c7de4ad9612cfc1218b13b38a5 --- /dev/null +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework1/Romero/Homework.java @@ -0,0 +1,8 @@ +package MV3500Cohort2024JulySeptember.homework1.Romero; + +public class Homework { + + public static void main(String args[]) { + System.out.println("Hello world!"); + } +} \ No newline at end of file diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework1/Schnitzler/SchnitzlerUnicastNetworking.java b/assignments/src/MV3500Cohort2024JulySeptember/homework1/Schnitzler/SchnitzlerUnicastNetworking.java index 7bdf6b26638e408a8ddb55443d56a53d789cfbbc..82b4a03da98a9caf93bd9bd52e5bd516d174a518 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework1/Schnitzler/SchnitzlerUnicastNetworking.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework1/Schnitzler/SchnitzlerUnicastNetworking.java @@ -8,8 +8,7 @@ import java.net.ServerSocket; import java.net.Socket; /** - * Homework1: Open a socket and waiting for a client to connect to the socket. - * + * * @author simonschnitzler */ public class SchnitzlerUnicastNetworking { diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikClient.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikClient.java index 94fdb5e9a4f38266a166be160b3ac3a896fe3143..58d93d59eba78180cf461467af0017a01fee7e0f 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikClient.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikClient.java @@ -12,7 +12,6 @@ import java.util.Scanner; * @author tbavlsik */ public class BavlsikClient { - public final static String LOCALHOST = "0:0:0:0:0:0:0:1"; //Local host /** @@ -22,36 +21,19 @@ public class BavlsikClient { public static void main(String[] args) throws Exception { Socket socket = new Socket(LOCALHOST, 2317); - Thread readerThread = new Thread(new Reader(socket)); - readerThread.start(); + new Thread(new Reader(socket)).start(); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); Scanner scanner = new Scanner(System.in); while (scanner.hasNextLine()) { - String msg = scanner.nextLine(); - //If the client wants to exit, type quit and close the socket - if(msg.equalsIgnoreCase("quit")){ - socket.close(); - } - //Checks to see if client or server closed socket, if so, end the program - if (socket.isClosed()) { - System.out.println("Connection closed. Exiting..."); - break; - } - else{ - out.println(msg); - } + out.println(scanner.nextLine()); } - readerThread.join(); } private static class Reader implements Runnable { - private BufferedReader in; - private Socket socket; public Reader(Socket socket) throws IOException { - this.socket = socket; in = new BufferedReader(new InputStreamReader(socket.getInputStream())); } @@ -63,15 +45,9 @@ public class BavlsikClient { System.out.println(message); } } catch (IOException e) { - System.out.println("Disconnected from server."); - } finally { - try { - socket.close(); - } catch (IOException e) { - System.out.println("Error closing socket: " + e); - } + System.out.println("Error reading from server: " + e); } } } - + } diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikServer.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikServer.java index ef4978fbe5e757632f5e05033bfe3286abd1cee7..f85726625f3bf3ec0bd29fd59f52f562a67cc2b6 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikServer.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikServer.java @@ -9,18 +9,14 @@ import java.io.PrintWriter; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; -import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; import java.util.Set; /** - * This class establishes a passcode protected chat server. Each client that connects - * is handled by a new thread and messages are broadcast to all connected clients. + * * @author tbavlsik */ public class BavlsikServer { - // the set clientWriters contains form all sockets the active PrintStream private static Set<PrintWriter> clientWriters = new HashSet<>(); @@ -28,40 +24,25 @@ public class BavlsikServer { * @param args the command line arguments */ public static void main(String[] args) { - ArrayList passcodes = new ArrayList<>(Arrays.asList(1, 29, 97));//Very secret passcode, wonder where those numbers came from... System.out.println(BavlsikServer.class.getName() + " has started..."); // it helps debugging to put this on console first - try (ServerSocket listener = new ServerSocket(2317)) { + try (ServerSocket listener = new ServerSocket(2317)) { while (true) { Handler handler = new Handler(listener.accept()); // create a new thread writing and reading to and from the new socket OutputStream os = handler.socket.getOutputStream(); PrintStream ps = new PrintStream(os); - + InetAddress remoteAddress = handler.socket.getInetAddress(); int remotePort = handler.socket.getPort(); - String message = remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " has connected to the server."; System.out.println(message); - BufferedReader reader = new BufferedReader(new InputStreamReader(handler.socket.getInputStream())); - ps.println("Enter a passcode:"); - String passInput = reader.readLine(); // read the entire line as a string - - int pass = Integer.parseInt(passInput.trim()); - - //Validate the client entered passcode - if (passcodes.contains(pass)) { - ps.println("Welcome " + remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " to the group chat!"); - for (PrintWriter writer : clientWriters) { + ps.println("Welcome " + remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " to the group chat!"); + for (PrintWriter writer : clientWriters) { writer.println(message); } - ps.flush(); - handler.start(); - } else {//Kick the client from the server. - ps.println("Not a valid passcode."); - System.out.println(remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " entered an incorrect passcode; disconnecting."); - handler.socket.close(); - } + ps.flush(); + handler.start(); } - } catch (IOException e) { + }catch (IOException e) { System.err.println("Problem with " + BavlsikServer.class.getName() + " networking: " + e); // Provide more helpful information to user if exception occurs due to running twice at one time @@ -69,11 +50,10 @@ public class BavlsikServer { System.err.println("*** Be sure to stop any other running instances of programs using this port!"); } } - + } - + private static class Handler extends Thread { - public final Socket socket; private PrintWriter out; private BufferedReader in; @@ -91,10 +71,10 @@ public class BavlsikServer { synchronized (clientWriters) { clientWriters.add(out); } - //Read in the message sent by the client and then send it to all other connected clients + String message; while ((message = in.readLine()) != null) { - String outputMessage = socket.getInetAddress().getHostName() + "=" + socket.getInetAddress().getHostAddress() + ", " + socket.getPort() + ": " + message; + String outputMessage = socket.getInetAddress().getHostName() + "=" + socket.getInetAddress().getHostAddress() + ", " + socket.getPort()+ ": " + message; System.out.println(outputMessage); for (PrintWriter writer : clientWriters) { writer.println(outputMessage); @@ -103,9 +83,6 @@ public class BavlsikServer { } catch (IOException e) { System.out.println("Error handling client: " + e); } finally { - //if a client disconnects or is kicked from the server, close the socket and broadcast the message to the chat - String disconnectMessage = (socket.getInetAddress().getHostName() + "=" + socket.getInetAddress().getHostAddress() + ", " + socket.getPort() + " has disconnected."); - System.out.println(disconnectMessage); try { socket.close(); } catch (IOException e) { @@ -115,11 +92,8 @@ public class BavlsikServer { synchronized (clientWriters) { clientWriters.remove(out); } - for (PrintWriter writer : clientWriters) { - writer.println(disconnectMessage); - } } } } - + } diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/README.md b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/README.md index 448a0bf1e467203f8eb4e28081fbf90944d841f2..867191babbb74e9d2677211dd49749d6e0b85f91 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/README.md +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/README.md @@ -3,18 +3,8 @@ *** ## Description -Modification of TcpExample3 and adding some code to implement a passcode protected -chat room with multiple clients. +Modification of TcpExample3 and adding some code to implement a chat room with multiple clients. -The 'BavlsikServer' class sets up a server that listens for incoming client connections -on port 2317. When a client connects, the server creates a new handler thread for -managing communication with that client. After the connection is established, -the server prompts the client for a passcode. If the client enters a valid passcode -they are added to teh chat room where each client's messages are broadcast to all -other connected clients. If the passcode is entered incorrectly, they client is -disconnected from the server. If a client enters 'quit' they disconnect from the server. +The 'BavlsikServer' class sets up a server that listens for incoming client connections on port 2317. When a client connects, the server creates a new handler thread for managing communication with that client. Each client's messages are broadcast to all other connected clients. -The 'BavlsikClient' class connects to a server running on localhost at port 2317. -If the client enters a correct passcode, they are added to the chatroom, if it is -incorrect they are disconnecte. The client then sends user input from the console -to the server and displays messages received from the server. \ No newline at end of file +The 'BavlsikClient' class connects to a server running on localhost at port 2317. It sends user input from the console to the server and displays messages received from the server. \ No newline at end of file diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Lennon/LennonHW2DispatchServer.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Lennon/LennonHW2DispatchServer.java deleted file mode 100644 index 4e30d61d856dda68a310bddee84d041f1d3ec33c..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Lennon/LennonHW2DispatchServer.java +++ /dev/null @@ -1,75 +0,0 @@ -package MV3500Cohort2024JulySeptember.homework2.Lennon; - -import java.io.IOException; -import java.net.*; - -/** - * 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 TcpExample4Client - * @see LennonHW2HandlerThread - * - * @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 - */ -public class LennonHW2DispatchServer -{ - /** Default constructor */ - public LennonHW2DispatchServer() - { - // default constructor - } - /** - * Program invocation, execution starts here - * @param args command-line arguments - */ - public static void main(String[] args) - { - try { - ServerSocket serverSocket = new ServerSocket(2317); - Socket clientConnectionSocket; - LennonHW2HandlerThread handlerThread; - - int connectionCount = 0; // state variable - - System.out.println(LennonHW2DispatchServer.class.getName() + " ready to accept socket connections..."); - while (true) // infinite loop - { - clientConnectionSocket = serverSocket.accept(); // block! until connected - - connectionCount++; // unblocked, got another connection - - // TODO option for the student, provide initial message *to the client* - // that we are handing off to a dispatch thread... because that is polite behavior. - // Plenty of code in Example3, we instead let our proxy thread - // TcpExample4HandlerThread introduce itself to the client. - - System.out.println("============================================================="); - System.out.println(LennonHW2DispatchServer.class.getName() + ".handlerThread created for connection #" + connectionCount + "..."); - - // hand off this aready-created and connected socket to constructor - handlerThread = new LennonHW2HandlerThread(clientConnectionSocket); - handlerThread.start();// invokes the run() method in that object - System.out.println(LennonHW2DispatchServer.class.getName() + ".handlerThread is now dispatched and running, using most recent connection..."); - - // while(true) continue looping, serverSocket is still waiting for another customer client - } - } - catch (IOException e) { - System.out.println("Problem with " + LennonHW2DispatchServer.class.getName() + " networking:"); // describe what is happening - System.out.println("Error: " + e); - // Provide more helpful information to user if exception occurs due to running twice at one time - if (e instanceof java.net.BindException) { - System.out.println("*** Be sure to stop any other running instances of programs using this port!"); - } - } - System.out.println("============================================================="); // execution complete - } -} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Lennon/LennonHW2HandlerThread.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Lennon/LennonHW2HandlerThread.java deleted file mode 100644 index 6ca17564c47850c30309094eafb714e80763c370..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Lennon/LennonHW2HandlerThread.java +++ /dev/null @@ -1,117 +0,0 @@ -package MV3500Cohort2024JulySeptember.homework2.Lennon; - -//import TcpExamples.TcpExample4Client; -//import TcpExamples.TcpExample4DispatchServer; -import java.io.*; -import java.net.*; -import java.util.Random; - -/** - * <p> - * This utility class supports the {@link TcpExample4DispatchServer} program, - * handling all programming logic needed for a new socket connection - * to run in a thread of its own. This is the server - * portion as well, so we artificially invent what happens - * if the server can't respond to a connection for several seconds. - * </p> - * <p> - * Warning: do not run this class! It is created and used automatically by {@link TcpExample4DispatchServer} at run time. - * </p> - * - * @see TcpExample4Client - * @see TcpExample4DispatchServer - * - * @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 - */ -public class LennonHW2HandlerThread extends Thread -{ - /** The socket connection to a client */ - Socket socket; - - /** - * The thread constructor creates the socket from a ServerSocket, waiting for the client to connect, - * and passes that socket when constructing the thread responsible for handling the connection. - * - * @param socket The socket connection handled by this thread - */ - LennonHW2HandlerThread(Socket socket) - { - this.socket = socket; - } - /** - * Program invocation and execution starts here - but is illegal and unwanted, so warn the unsuspecting user! - * @param args command-line arguments - */ - public static void main(String[] args) - { - System.out.println ("*** LennonHW2HandlerThread is not a standalone executable progam."); - System.out.println ("*** Please run LennonHW2DispatchServer instead... now exiting."); - } - - /** Handles one connection. We add an artificial slowness - * to handling the connection with a sleep(). This means - * the client won't see a server connection response for ten seconds (default). - */ - // @overriding run() method in Java Thread class is deliberate - @Override - public void run() - { - try - { - System.out.println(LennonHW2HandlerThread.class.getName() + " starting to handle a thread..."); - - // get the connection output stream, then wait a period of time. - Random random = new Random(); - int randNum = random.nextInt(10)+1; - - OutputStream os = socket.getOutputStream(); - PrintStream ps = new PrintStream(os); - - ps.println("I'm thinking of a number between 1 and 10. Can you guess it?" ); - ps.flush(); // make sure that it indeed escapes current process and reaches the client - - InputStream is = socket.getInputStream(); - Reader isr = new InputStreamReader(is); - BufferedReader br = new BufferedReader(isr); - - String userGuess = br.readLine(); // blocks - String serverResponse = null; - try{ - int userNum = Integer.parseInt(userGuess); - if (userNum == randNum){ - serverResponse = "Good job. You got it."; - }else{ - serverResponse = "You're wrong. It was " + randNum; - } - }catch(NumberFormatException e){ - System.out.println("Something went wrong. Guess was not a number" + e); - serverResponse = "Something went wrong. Anyway, my number was " + randNum; - } - final long TIMEOUT = 500; // 2000 milliseconds = 2 seconds, 500 milliseconds = 0.5 seconds - System.out.println(LennonHW2HandlerThread.class.getName() + " pausing for TIMEOUT=" + TIMEOUT + "ms" + - " to emulate computation and avoid server-side overload"); - Thread.sleep(TIMEOUT); - - // ps is the PrintStream is the Java way to use System.print() to pass data along the socket. - ps.println(serverResponse ); - ps.flush(); // make sure that it indeed escapes current process and reaches the client - socket.close(); // all clear, no longer need socket - System.out.println(LennonHW2HandlerThread.class.getName() + " finished handling a thread, now exit."); - } - catch(IOException | InterruptedException e) // either a networking or a threading problem - { - System.out.println("Problem with " + LennonHW2HandlerThread.class.getName() + " networking:"); // describe what is happening - System.out.println("Error: " + e); - - // Provide more helpful information to user if exception occurs due to running twice at one time - if (e instanceof java.net.BindException) - System.out.println("*** Be sure to stop any other running instances of programs using this port!"); - } - } -} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/README.md b/assignments/src/MV3500Cohort2024JulySeptember/homework2/README.md index a119eb2ed8a15fa7741d68ed83e86b98838f50d4..1de5901082acfabc26cf4ecd81969a4bb74908d3 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/README.md +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/README.md @@ -1,4 +1,4 @@ -## Homework 2: TCP Client/Server Networking +## Homework 2: UDP Multicast Client/Server Networking Deliverables: @@ -21,8 +21,4 @@ Approach: 4. Create a simple illustration of the communications exchange in a [UML Sequence Diagram](https://en.wikipedia.org/wiki/Sequence_diagram). Please see the [README.md](../../../README.md) in the parent -[assignments](../../../../assignments) directory for detailed instructions. - -Of special note, produce good Javadoc results through proper documentation of -source code and includion of a package-info.java summary. NetBeans makes it -pretty easy to do so. \ No newline at end of file +[assignments](../../../../assignments) directory for detailed instructions. \ No newline at end of file diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/README.md b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/README.md deleted file mode 100644 index 238484217398adae27c1fef7112dbf676faff40a..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Rene Romero Homework 2 - -*** - -## Description - -Modification to TCPExample4 to show the Message of the day (MOTD), depending on the day of the week. - -The server side sets up a server listening for incoming connectios. - -When a client attempts a connection to the server it sends the day of the week for the current connection. - -Once received the day of the week, the server reply with a message according to the day of the week. - -Phrases taken from - -https://www.divein.com/everyday/monday-motivation-quotes/ - - diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/RomeroClientHW2.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/RomeroClientHW2.java deleted file mode 100644 index e81d0687c433467c9d6b0163969aa345ac16b286..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/RomeroClientHW2.java +++ /dev/null @@ -1,73 +0,0 @@ -package MV3500Cohort2024JulySeptember.homework2.Romero; - -import java.io.*; -import java.net.*; -import java.time.LocalDate; -import java.time.DayOfWeek; -//import java.time.LocalTime; // conversion? - -/** - * This client program establishes a socket connection to the {@link TcpExample4DispatchServer}, - * then checks how long it takes to read the single line it expects as a server response. - * No fancy footwork here, it is pretty simple and similar to {@link TcpExample3Client}. - * - * @see TcpExample4DispatchServer - * @see TcpExample4HandlerThread - * - * @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 - */ -public class RomeroClientHW2 -{ - /** Default constructor */ - public RomeroClientHW2() - { - // default constructor - } - - /** - * Program invocation, execution starts here - * @param args command-line arguments - */ - public static void main(String[] args) { - - DataInputStream in; - DataOutputStream out; - - LocalDate currentDate = LocalDate.now(); - DayOfWeek day = currentDate.getDayOfWeek(); - - System.out.println("Current date: " + currentDate); - System.out.println("Today is: " + day + "\n"); - - System.out.println(RomeroClientHW2.class.getName() + " creating new socket ..."); - - try { - Socket clientConnectionSocket = new Socket("localhost", 2317); - - in = new DataInputStream(clientConnectionSocket.getInputStream()); - out = new DataOutputStream(clientConnectionSocket.getOutputStream()); - - out.writeUTF(day.name()); - - String mensaje = in.readUTF(); - - System.out.println(mensaje); - - clientConnectionSocket.close(); - - } catch (IOException e) { - System.out.println("Problem with " + RomeroClientHW2.class.getName() + " networking:networking:"); // describe what is happening - System.out.println("Error: " + e); - // Provide more helpful information to user if exception occurs due to running twice at one time - if (e instanceof java.net.BindException) { - System.out.println("*** Be sure to stop any other running instances of programs using this port!"); - } - } - } -} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/RomeroServerHW2.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/RomeroServerHW2.java deleted file mode 100644 index 7242113e1d5196fe05ed575b335f9bb0a22c540d..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/RomeroServerHW2.java +++ /dev/null @@ -1,104 +0,0 @@ -package MV3500Cohort2024JulySeptember.homework2.Romero; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.*; - -/** - * 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 TcpExample4Client - * @see TcpExample4HandlerThread - * - * @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 - */ -public class RomeroServerHW2 -{ - /** Default constructor */ - public RomeroServerHW2() - { - // default constructor - } - /** - * Program invocation, execution starts here - * @param args command-line arguments - */ - public static void main(String[] args) - { - DataInputStream in; - DataOutputStream out; - - try { - ServerSocket serverSocket = new ServerSocket(2317); - - System.out.println("Server has been initializated ... "); - System.out.println("Witing for conections ..."); - - Socket clientConnectionSocket; - TcpExample4HandlerThread handlerThread; - - int connectionCount = 0; // state variable - - System.out.println(RomeroServerHW2.class.getName() + " ready to accept socket connections..."); - - while (true) // infinite loop - { - clientConnectionSocket = serverSocket.accept(); // block! until connected - - connectionCount++; // unblocked, got another connection - - in = new DataInputStream(clientConnectionSocket.getInputStream()); - out = new DataOutputStream(clientConnectionSocket.getOutputStream()); - - String messageFromClient = in.readUTF(); - System.out.println("Client connected on: " + messageFromClient); - - String messageOTD = ""; - - switch(messageFromClient) { - case "MONDAY" -> messageOTD = "\n\"Mondays are the start of the work week which offer new beginnings 52 times a year!\"\n \t- David Dweck"; - case "TUESDAY" -> messageOTD = "\n\"May your Tuesday be like your coffee: strong, smooth, and full of warmth.\"\n \t- Unknown"; - case "WEDNESDAY" -> messageOTD = "\n\"Wednesdays will always bring smiles for the second half of the week.\"\n \t- Anthony T. Hincks"; - case "THURSDAY" -> messageOTD = "\n\"Thursday is a day to admit your mistakes and try to improve.\"\n \t- Byron Pulsifer"; - case "FRIDAY" -> messageOTD = "\n\"Every Friday, I like to high five myself for getting through another week\non little more than caffeine, willpower, and inappropriate humor.\"\n \t- Anonymous"; - case "SATURDAY" -> messageOTD = "\n\"Saturday is a time to enjoy the small things in life, and to look back on the week with gratitude.\"\n \t- Unknown"; - case "SUNDAY" -> messageOTD = "\n\"Sunday clears away the rust of the whole week.\"\n \t- Joseph Addison"; - default -> messageOTD = "\nError while getting the day of the week"; - } - - out.writeUTF("\n**********************************************************************\n" - + messageOTD + - "\n\n**********************************************************************\n\n" - + "You are the client numer: " + connectionCount); - - System.out.println("============================================================="); - System.out.println(RomeroServerHW2.class.getName() + ".handlerThread created for connection #" + connectionCount + "..."); - - // hand off this aready-created and connected socket to constructor - handlerThread = new TcpExample4HandlerThread(clientConnectionSocket); - handlerThread.start();// invokes the run() method in that object - System.out.println(RomeroServerHW2.class.getName() + ".handlerThread is now dispatched and running, using most recent connection..."); - - // while(true) continue looping, serverSocket is still waiting for another customer client - } - } - catch (IOException e) { - System.out.println("Problem with " + RomeroServerHW2.class.getName() + " networking:"); // describe what is happening - System.out.println("Error: " + e); - // Provide more helpful information to user if exception occurs due to running twice at one time - if (e instanceof java.net.BindException) { - System.out.println("*** Be sure to stop any other running instances of programs using this port!"); - } - } - System.out.println("============================================================="); // execution complete - } -} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/README.md b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/README.md index 4fd44c62635b1871d50e4fae2243855fd276afa1..38a981a6457b9a74e9733f3c93572b085e78108b 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/README.md +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/README.md @@ -5,6 +5,6 @@ ## Description Modification of TcpExample3 and adding some code to implement a chat room with multiple clients. -The 'SchnitzlerServer' class sets up a server that listens for incoming client connections on port 2317. When a client connects, the server creates a new handler thread for managing communication with that client. For a successful connection a password must be entered. After that each client's messages are broadcast to all other connected clients. +The 'SchnitzlerServer' class sets up a server that listens for incoming client connections on port 2317. When a client connects, the server creates a new handler thread for managing communication with that client. Each client's messages are broadcast to all other connected clients. The 'SchnitzlerClient' class connects to a server running on localhost at port 2317. It sends user input from the console to the server and displays messages received from the server. \ No newline at end of file diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/SchnitzlerClient.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/SchnitzlerClient.java index d1d3b1c85d67098d7be44e3cf1b99a95bcdd751e..82eb4915a5ce1c64fc81d152388f5d8d1dfb1daf 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/SchnitzlerClient.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/SchnitzlerClient.java @@ -8,8 +8,7 @@ import java.net.Socket; import java.util.Scanner; /** - * Homework2: Client which connect to a server and prints all incoming messages of the server to the console. - * + * * @author simonschnitzler */ public class SchnitzlerClient { @@ -22,28 +21,25 @@ public class SchnitzlerClient { public static void main(String[] args) throws Exception { Socket socket = new Socket(LOCALHOST, 2317); - Thread connection = new Thread(new Reader(socket)); - connection.start(); + new Thread(new Reader(socket)).start(); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); Scanner scanner = new Scanner(System.in); - while (scanner.hasNextLine() && connection.isAlive()) { + while (scanner.hasNextLine()) { out.println(scanner.nextLine()); } } private static class Reader implements Runnable { private BufferedReader in; - private final Socket socket; public Reader(Socket socket) throws IOException { - this.socket = socket; - in = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); + in = new BufferedReader(new InputStreamReader(socket.getInputStream())); } @Override public void run() { - try (socket){ + try { String message; while ((message = in.readLine()) != null) { System.out.println(message); diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/SchnitzlerServer.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/SchnitzlerServer.java index 47cc363f2d1b7e8e2cea4178dc612913d39ddedb..2f2323f5b3068b963cad413bf7ee3ecf1145723e 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/SchnitzlerServer.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Schnitzler/SchnitzlerServer.java @@ -3,6 +3,8 @@ package MV3500Cohort2024JulySeptember.homework2.Schnitzler; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; import java.io.PrintWriter; import java.net.InetAddress; import java.net.ServerSocket; @@ -11,8 +13,7 @@ import java.util.HashSet; import java.util.Set; /** - * Homework2: Chatserver, which is waiting for clients to connect. The clients need to enter a password for a successfull connection. After a successfull connection all messages will be sent to all clients. - * + * * @author simonschnitzler */ public class SchnitzlerServer { @@ -26,15 +27,20 @@ public class SchnitzlerServer { System.out.println(SchnitzlerServer.class.getName() + " has started..."); // it helps debugging to put this on console first try (ServerSocket listener = new ServerSocket(2317)) { while (true) { - Socket socket = listener.accept(); - int remotePort = socket.getPort(); - InetAddress remoteAddress = socket.getInetAddress(); - String message = remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " tries to connect to the server."; - System.out.println(message); - Handler handler = new Handler(socket); - handler.start(); - + Handler handler = new Handler(listener.accept()); // create a new thread writing and reading to and from the new socket + OutputStream os = handler.socket.getOutputStream(); + PrintStream ps = new PrintStream(os); + InetAddress remoteAddress = handler.socket.getInetAddress(); + int remotePort = handler.socket.getPort(); + String message = remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " has connected to the server."; + System.out.println(message); + ps.println("Welcome " + remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " to the group chat!"); + for (PrintWriter writer : clientWriters) { + writer.println(message); + } + ps.flush(); + handler.start(); } }catch (IOException e) { System.err.println("Problem with " + SchnitzlerServer.class.getName() + " networking: " + e); @@ -61,49 +67,19 @@ public class SchnitzlerServer { try { in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); - - InetAddress remoteAddress = socket.getInetAddress(); - int remotePort = socket.getPort(); - out.println("Speak, friend, and enter!"); - String answer = in.readLine(); - if("Mellon".equals(answer)){ - String message = remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " has connected to the server."; - System.out.println(message); - out.println("Welcome " + remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " to the group chat!"); - for (PrintWriter writer : clientWriters) { - writer.println(message); - } - out.flush(); - synchronized (clientWriters) { + + synchronized (clientWriters) { clientWriters.add(out); - } + } - while ((message = in.readLine()) != null) { - String outputMessage = socket.getInetAddress().getHostName() + "=" + socket.getInetAddress().getHostAddress() + ", " + socket.getPort()+ ": " + message; - System.out.println(outputMessage); - for (PrintWriter writer : clientWriters) { - writer.println(outputMessage); - } - } - String outputMessage = socket.getInetAddress().getHostName() + "=" + socket.getInetAddress().getHostAddress() + ", " + socket.getPort()+ " has disconnected!"; + String message; + while ((message = in.readLine()) != null) { + String outputMessage = socket.getInetAddress().getHostName() + "=" + socket.getInetAddress().getHostAddress() + ", " + socket.getPort()+ ": " + message; System.out.println(outputMessage); for (PrintWriter writer : clientWriters) { writer.println(outputMessage); } - } - else{ - try (socket) { - String message = remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + ": Connection denied!"; - System.out.println(message); - out.println(message); - socket.close(); - }catch (IOException e) { - System.out.println("Couldn't close a socket, what's going on?"); - } - } - - } catch (IOException e) { System.out.println("Error handling client: " + e); } finally { diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Smith/Server.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Smith/Server.java index 09a08b2a969b78b6816ad430378de98872d09004..dda4bc4f09157728d643d3d5ec23a4e1b1307a67 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Smith/Server.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Smith/Server.java @@ -5,6 +5,7 @@ import java.net.*; import java.util.Random; public class Server { + private static int runningTotal = 0; // Initialize running total public Server() { @@ -30,49 +31,52 @@ public class Server { // Read the number sent by the client BufferedReader br = new BufferedReader(new InputStreamReader(clientConnectionSocket.getInputStream())); String clientChoice = br.readLine(); - + + if ((!"rock".equals(clientChoice)) && (!"scissors".equals(clientChoice)) && (!"paper".equals(clientChoice))) { + ps.println("Invalid Choice"); + continue; + } + Random rand = new Random(); - int serverChoiceInt = rand.nextInt(0,3); + int serverChoiceInt = rand.nextInt(0, 3); String serverChoiceStr; - + serverChoiceStr = switch (serverChoiceInt) { - case 0 -> "rock"; - case 1 -> "paper"; - case 2 -> "scissors"; - default -> "Error"; + case 0 -> + "rock"; + case 1 -> + "paper"; + case 2 -> + "scissors"; + default -> + "Error"; }; - - - if ("rock".equals(serverChoiceStr) & "paper".equals(clientChoice)){ + + if ("rock".equals(serverChoiceStr) & "paper".equals(clientChoice)) { losses++; - } - else if ("paper".equals(serverChoiceStr) & "scissors".equals(clientChoice)){ + } else if ("paper".equals(serverChoiceStr) & "scissors".equals(clientChoice)) { losses++; - } - else if ("scissors".equals(serverChoiceStr) & "rock".equals(clientChoice)){ + } else if ("scissors".equals(serverChoiceStr) & "rock".equals(clientChoice)) { losses++; - } - else if ("rock".equals(serverChoiceStr) & "scissors".equals(clientChoice)){ + } else if ("rock".equals(serverChoiceStr) & "scissors".equals(clientChoice)) { wins++; - } - else if ("scissors".equals(serverChoiceStr) & "paper".equals(clientChoice)){ + } else if ("scissors".equals(serverChoiceStr) & "paper".equals(clientChoice)) { wins++; - } - else if ("paper".equals(serverChoiceStr) & "rock".equals(clientChoice)){ + } else if ("paper".equals(serverChoiceStr) & "rock".equals(clientChoice)) { wins++; } // Send back the updated total - ps.println("Client chose: " + clientChoice + "/ Server Chose: "+ serverChoiceStr + "/ Wins: "+wins+"/ loses: "+ losses); + ps.println("Client chose: " + clientChoice + "/ Server Chose: " + serverChoiceStr + "/ Wins: " + wins + "/ loses: " + losses); ps.println("Please wait for server to choose"); - + System.out.println("Client chose: " + clientChoice); localAddress = clientConnectionSocket.getLocalAddress(); remoteAddress = clientConnectionSocket.getInetAddress(); localPort = clientConnectionSocket.getLocalPort(); remotePort = clientConnectionSocket.getPort(); - + ps.flush(); } } @@ -84,4 +88,4 @@ public class Server { } } } -} \ No newline at end of file +} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Smith/package-info.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Smith/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..194b250d511cd953662daf6870f44b969e443cb3 --- /dev/null +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Smith/package-info.java @@ -0,0 +1,10 @@ +/** + * TCP Unicast homework 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.homework2.Smith; diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Client_HW2.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Client_HW2.java index 806d4bee9ad3e4f909819bf3d1a87053f755be23..7eb81b34a1c8e0c845047514f151377197cd86cc 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Client_HW2.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Client_HW2.java @@ -1,58 +1,42 @@ package MV3500Cohort2024JulySeptember.homework2.Timberlake; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.Socket; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; import java.util.Scanner; -import java.io.PrintWriter; /** * * @author Jack */ - - public class Client_HW2 { public static void main(String[] args) { - Socket socket = null; + DatagramSocket socket = null; Scanner scanner = new Scanner(System.in); try { // Create a socket to communicate with the server - socket = new Socket("192.168.56.1", 9876); // change IP depending on server machine - - PrintWriter outputWriter = new PrintWriter(socket.getOutputStream(), true); - BufferedReader inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); - - // Receive and display server messages - System.out.println(inputReader.readLine()); // Enter name - String name = scanner.nextLine(); - outputWriter.println(name); // Send name - outputWriter.flush(); + socket = new DatagramSocket(); + InetAddress serverAddress = InetAddress.getByName("localhost"); // Server address (localhost for testing) + byte[] sendData = new byte[1024]; // Buffer to store data to send + byte[] receiveData = new byte[1024]; // Buffer to store received data - System.out.println(inputReader.readLine()); // Enter fav color - String color = scanner.nextLine(); - outputWriter.println(color); // Send fav color - outputWriter.flush(); - - // Receive and display initial messages from the server - // Empty string means init messages over - String serverMessage; - while (!(serverMessage = inputReader.readLine()).isEmpty()) { - System.out.println(serverMessage); - } - + System.out.print("Let's play a game!!\n"); + System.out.print("Try guessing a number between 1-100\n"); while(true) { System.out.print("Enter your guess: "); String guess = scanner.nextLine(); //Read user input - outputWriter.println(guess); //Send guess to server - outputWriter.flush(); + sendData = guess.getBytes(); // Convert message to bytes + // Send guess to the server + DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverAddress, 9876); + socket.send(sendPacket); // Send packet to server + // Receive response from server - String response = inputReader.readLine(); - System.out.println("Server Said: " + response); // print server response + DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); + socket.receive(receivePacket); // Blocking call until a packet is received + String response = new String(receivePacket.getData(), 0, receivePacket.getLength()); + System.out.println("Server Said: " + response); // Print received response - // End game if (response.startsWith ("Good")) { break; //End the game } @@ -65,11 +49,7 @@ public class Client_HW2 { scanner.close(); // Close scanner } if (socket != null && !socket.isClosed()) { - try { - socket.close(); // Close the socket to release resources - } catch (Exception e) { - e.printStackTrace(); - } + socket.close(); // Close the socket to release resources } } } diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/GameHandler.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/GameHandler.java deleted file mode 100644 index 9403aa23e5602254321633278d8e3ceb1a6dca8f..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/GameHandler.java +++ /dev/null @@ -1,102 +0,0 @@ -package MV3500Cohort2024JulySeptember.homework2.Timberlake; - -/** - * - * @author Jack - */ - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.Socket; -import java.util.Random; -import java.util.HashMap; -import java.util.Map; - -public class GameHandler implements Runnable { - private Socket clientSocket; - private int numToGuess; - private static final Map<String, String> userCredentials = new HashMap<>(); - - static { - // User credentials dictionary - userCredentials.put("Jack", "blue"); - userCredentials.put("Stephen", "green"); - userCredentials.put("Don", "red"); - - } - - public GameHandler(Socket clientSocket) { - this.clientSocket = clientSocket; - Random random = new Random(); - this.numToGuess = random.nextInt(100) + 1; // Initialize random number 1-100 - } - - @Override - public void run() { - try (BufferedReader inputReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); - PrintWriter outputWriter = new PrintWriter(clientSocket.getOutputStream(), true)) { - - // Request name from client - outputWriter.println("Enter your name:"); - outputWriter.flush(); - String name = inputReader.readLine(); - - // Request favorite color from client - outputWriter.println("Enter your favorite color:"); - outputWriter.flush(); - String color = inputReader.readLine(); - - // Check credentials and start game - // Kill connection if credentials are wrong - if (!(userCredentials.containsKey(name) && userCredentials.get(name).equalsIgnoreCase(color))) { - outputWriter.println("INTRUDER! INTRUDER! TERMINATING CONNECTION."); - clientSocket.close(); - } else { - outputWriter.println("Authentication successful! Welcome, " + name + "."); - outputWriter.println("Let's play a game!!"); - outputWriter.println("Try guessing a number between 1-100"); - outputWriter.println(""); // Send an empty line to signal the end of initial messages - } - - int count = 1; - boolean isRunning = true; - - while (isRunning) { - // Read message from client - String message = inputReader.readLine(); - System.out.println("Client sent: " + message); // Print received message - - String response; - try { - int guess = Integer.parseInt(message.trim()); - if (guess < numToGuess) { - response = "Guess Higher"; - count++; - } else if (guess > numToGuess) { - response = "Guess Lower"; - count++; - } else { - response = "Good Job " + name + "!! That took you " + count + " tries!"; - isRunning = false; - } - } catch (NumberFormatException e) { - response = "Invalid input. Enter a number."; - } - - // Send response to client - outputWriter.println(response); - } - } catch (Exception e) { - e.printStackTrace(); // Print any exceptions that occur - } finally { - try { - if (clientSocket != null && !clientSocket.isClosed()) { - clientSocket.close(); // Close the client socket to release resources - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } -} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Server_HW2.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Server_HW2.java index 987e79ec35af26cddb82cc8c5b53a889101993a3..3d9df86269f2a5b72d39e8845dc6522508f1d80c 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Server_HW2.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Timberlake/Server_HW2.java @@ -1,44 +1,69 @@ package MV3500Cohort2024JulySeptember.homework2.Timberlake; -import java.net.ServerSocket; -import java.net.Socket; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.util.Random; /** * * @author Jack */ - - public class Server_HW2 { public static void main(String[] args) { - ServerSocket serverSocket = null; + DatagramSocket socket = null; + Random random = new Random(); + int numToGuess = random.nextInt(100) + 1; + //System.out.println("Magic Number Is: " + numToGuess); try { // Create a socket to listen on port 9876 - serverSocket = new ServerSocket(9876); + socket = new DatagramSocket(9876); + byte[] receiveData = new byte[1024]; // Buffer to store incoming data + byte[] sendData = new byte[1024]; // Buffer to store outgoing data + int count = 1; 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); + boolean isRunning = true; + while (isRunning) { + // Receive packet from client + DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); + socket.receive(receivePacket); // Blocking call until a packet is received + + String message = new String(receivePacket.getData(), 0, receivePacket.getLength()); //Receive packet + InetAddress clientAddress = receivePacket.getAddress(); //Save IP for response + int clientPort = receivePacket.getPort(); //Save port for response + + System.out.println("Client sent: " + message); // Print received message - // Create new thread to handle the game - Thread thread = new Thread(gameHandler); - thread.start(); + String response; + try { + int guess = Integer.parseInt(message.trim()); + if (guess < numToGuess) { + response = "Guess Higher"; + count++; + } else if (guess > numToGuess) { + response = "Guess Lower"; + count++; + } else { + response = "Good Job!! That took you " + count + " tries!"; + isRunning = false; + } + } catch (NumberFormatException e) { + response = "Invalid input. Enter a number."; + } + + // Prepare response to client + sendData = response.getBytes(); // Convert response message to bytes + DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, clientAddress, clientPort); + socket.send(sendPacket); // Send response packet to client + } } 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(); + if (socket != null && !socket.isClosed()) { + socket.close(); // Close the socket to release resources } } } diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/README.md b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/README.md deleted file mode 100644 index 6989b20b1a73e709e3d7df177c7c2bbf5702d801..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## Homework 2: - -For this assignment, I utilized the framework classes from the example 4 we disected in class. - -The three files—HW2Client, HW2Server, HW2Thread— work together to create a simple client-server application. -The server class is the main server program, listening for incoming client connections on a specified -port 2317. When the client connects, the server runs HW2Thread to handle the communication with that client, -allowing the server to manage multiple clients concurrently. The thread class is responsible for processing the client's -input and sending an appropriate response back, after which it closes the connection. On the client side, -the client class connects to the server, sends a message "Ethan", and receives a response. The client measures -the time taken for the interaction and handles multiple iterations if specified. Overall, the server/client interact -through a series of messages, with the server capable of handling multiple clients simultaneously through threading. \ No newline at end of file diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Client.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Client.java deleted file mode 100644 index ae3a4db744843ca3e6c87589399136bfa8698f59..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Client.java +++ /dev/null @@ -1,79 +0,0 @@ -package MV3500Cohort2024JulySeptember.homework2.Yu; - -import java.io.*; -import java.net.*; -//import java.time.LocalTime; // conversion? - -/** - * @author Jin Hong Yu - */ -public class YuHW2Client { - - /** - * Default constructor - */ - public YuHW2Client() { - // default constructor - } - static String DESTINATION_HOST = "localhost"; - static int MAX_LOOP_COUNT = 4; - - /** - * Program invocation, execution starts here - * - * @param args command-line arguments - */ - public static void main(String[] args) { - try { - System.out.println(YuHW2Client.class.getName() + " start, loop " + MAX_LOOP_COUNT + " times"); - System.out.println("======================================================="); - for (int loopCount = 1; loopCount <= MAX_LOOP_COUNT; loopCount++) { - System.out.println(YuHW2Client.class.getName() + " creating new socket #" + loopCount + "..."); - - long startTime = System.currentTimeMillis(); - - Socket socket = new Socket(DESTINATION_HOST, 2317); - - PrintStream ps = new PrintStream(socket.getOutputStream()); - BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); - - // Knock Knock joke sequence - ps.println("Knock Knock"); - ps.flush(); - System.out.println("Client: Knock Knock"); - - String serverResponse = br.readLine(); // blocks - System.out.println("Server: " + serverResponse); - - if ("Who's there?".equals(serverResponse)) { - ps.println("Hatch"); - ps.flush(); - System.out.println("Client: Hatch"); - } - - serverResponse = br.readLine(); - System.out.println("Server: " + serverResponse); - - if ("Hatch who?".equals(serverResponse)) { - ps.println("God Bless You!"); - ps.flush(); - System.out.println("Client: God Bless You!"); - } - - long readTime = System.currentTimeMillis(); - long timeLength = readTime - startTime; - - System.out.println(YuHW2Client.class.getName() + ": time msec required for sequence=" + timeLength); - System.out.println("======================================================="); - socket.close(); - } - System.out.println(YuHW2Client.class.getName() + " complete"); - } catch (IOException e) { - System.out.println("Problem with " + YuHW2Client.class.getName() + " networking:"); - System.out.println("Error: " + e); - if (e instanceof java.net.BindException) { - System.out.println("*** Be sure to stop any other running instances of programs using this port!"); - } - } - } -} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2HandlerThread.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2HandlerThread.java deleted file mode 100644 index ac93fcfd4ac848915bfe78149c4cbfb9427f4826..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2HandlerThread.java +++ /dev/null @@ -1,82 +0,0 @@ -package MV3500Cohort2024JulySeptember.homework2.Yu; - -import java.io.*; -import java.net.*; - -/** - * @author Jin Hong Yu - */ -public class YuHW2HandlerThread extends Thread -{ - /** The socket connection to a client */ - Socket socket; - - /** - * The thread constructor creates the socket from a ServerSocket, waiting for the client to connect, - * and passes that socket when constructing the thread responsible for handling the connection. - * - * @param socket The socket connection handled by this thread - */ - YuHW2HandlerThread(Socket socket) - { - this.socket = socket; - } - /** - * Program invocation and execution starts here - but is illegal and unwanted, so warn the unsuspecting user! - * @param args command-line arguments - */ - public static void main(String[] args) - { - System.out.println ("*** YuHW2HandlerThread is not a standalone executable progam."); - System.out.println ("*** Please run TcpExample4DispatchServer instead... now exiting."); - } - - /** Handles one connection. We add an artificial slowness - * to handling the connection with a sleep(). This means - * the client won't see a server connection response for ten seconds (default). - */ - // @overriding run() method in Java Thread class is deliberate - @Override - public void run() - { - try { - System.out.println(YuHW2HandlerThread.class.getName() + " starting to handle a thread..."); - - BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); - PrintStream ps = new PrintStream(socket.getOutputStream()); - - // Sequence of the Knock Knock joke - String clientMessage = in.readLine(); - System.out.println("Client: " + clientMessage); - - if ("Knock Knock".equals(clientMessage)) { - ps.println("Who's there?"); - ps.flush(); - } - - clientMessage = in.readLine(); - System.out.println("Client: " + clientMessage); - - if ("Hatch".equals(clientMessage)) { - ps.println("Hatch who?"); - ps.flush(); - } - - clientMessage = in.readLine(); - System.out.println("Client: " + clientMessage); - - if ("God Bless You!".equals(clientMessage)) { - System.out.println("Joke sequence complete."); - } - - socket.close(); // all clear, no longer need socket - System.out.println(YuHW2HandlerThread.class.getName() + " finished handling a thread, now exit."); - } catch(IOException e) { - System.out.println("Problem with " + YuHW2HandlerThread.class.getName() + " networking:"); - System.out.println("Error: " + e); - if (e instanceof java.net.BindException) { - System.out.println("*** Be sure to stop any other running instances of programs using this port!"); - } - } - } -} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Server.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Server.java deleted file mode 100644 index 28d5a3d8a0d6411768990b360679407f8803506f..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Server.java +++ /dev/null @@ -1,58 +0,0 @@ -package MV3500Cohort2024JulySeptember.homework2.Yu; - -import java.io.IOException; -import java.net.*; - -/** - * @author Jin Hong Yu - */ -public class YuHW2Server -{ - /** Default constructor */ - public YuHW2Server() - { - // default constructor - } - /** - * Program invocation, execution starts here - * @param args command-line arguments - */ - public static void main(String[] args) - { - try { - ServerSocket serverSocket = new ServerSocket(2317); - Socket clientConnectionSocket; - YuHW2HandlerThread handlerThread; - - int connectionCount = 0; // state variable - - //System.out.println(TcpExample4DispatchServer.class.getName() + " ready to accept socket connections..."); - while (true) // infinite loop - { - clientConnectionSocket = serverSocket.accept(); // block! until connected - - connectionCount++; // unblocked, got another connection - - - System.out.println("============================================================="); - //System.out.println(TcpExample4DispatchServer.class.getName() + ".handlerThread created for connection #" + connectionCount + "..."); - - // hand off this aready-created and connected socket to constructor - handlerThread = new YuHW2HandlerThread(clientConnectionSocket); - handlerThread.start();// invokes the run() method in that object - //System.out.println(TcpExample4DispatchServer.class.getName() + ".handlerThread is now dispatched and running, using most recent connection..."); - - // while(true) continue looping, serverSocket is still waiting for another customer client - } - } - catch (IOException e) { - //System.out.println("Problem with " + TcpExample4DispatchServer.class.getName() + " networking:"); // describe what is happening - System.out.println("Error: " + e); - // Provide more helpful information to user if exception occurs due to running twice at one time - if (e instanceof java.net.BindException) { - System.out.println("*** Be sure to stop any other running instances of programs using this port!"); - } - } - System.out.println("============================================================="); // execution complete - } -} diff --git a/assignments/src/src/HttpServletExamples/DisServletPagesConceptDrawings.pdf b/assignments/src/src/HttpServletExamples/DisServletPagesConceptDrawings.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b3309aa7ee49408e8983e938422cd50d33fbef76 Binary files /dev/null and b/assignments/src/src/HttpServletExamples/DisServletPagesConceptDrawings.pdf differ diff --git a/assignments/src/src/HttpServletExamples/DisServletPagesConceptDrawings.vsdx b/assignments/src/src/HttpServletExamples/DisServletPagesConceptDrawings.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..f60d7580230cd54ec24444ca30922de65a96fcd7 Binary files /dev/null and b/assignments/src/src/HttpServletExamples/DisServletPagesConceptDrawings.vsdx differ diff --git a/assignments/src/src/HttpServletExamples/HttpWebPageSource.java b/assignments/src/src/HttpServletExamples/HttpWebPageSource.java new file mode 100644 index 0000000000000000000000000000000000000000..6ff19a0987be920e4491f995b5b8093b0769640a --- /dev/null +++ b/assignments/src/src/HttpServletExamples/HttpWebPageSource.java @@ -0,0 +1,85 @@ +package HttpServletExamples; + +import java.io.*; +import java.net.*; + +/** + * A very simple http web-page reading example that won't work in some circumstances. + * But it will in some others. + * + * @author mcgredo + * @author brutzman@nps.edu + */ +public class HttpWebPageSource +{ + /** Default constructor */ + public HttpWebPageSource() + { + // default constructor + } + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String[] args) + { + try + { + System.out.println("HttpWebPageSource: create http connection and retrieve default page"); + System.out.println("Reference: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"); + System.out.println("Reference: https://tools.ietf.org/html/rfc7230"); + System.out.println("Reference: https://en.wikipedia.org/wiki/CURL"); + System.out.println(); + + // We request an IP to connect to a web server running on default http port 80. + + String WEB_SERVER_ADDRESS = "www.nps.edu"; + int WEB_SERVER_PORT_HTTP = 80; + int WEB_SERVER_PORT_HTTPS = 443; // does this work too? + System.out.println("New socket WEB_ADDRESS=" + WEB_SERVER_ADDRESS); + + // this Java construct will work for HTTP but not HTTPS + Socket socket = new Socket(WEB_SERVER_ADDRESS, WEB_SERVER_PORT_HTTPS); // compare alternative: https on port 443 + + // we send a command to the web server, asking for what + // we want. Note that the format for the command is very + // specific and documented. + OutputStream os = socket.getOutputStream(); + PrintStream ps = new PrintStream(os); + + String message = "GET /index.html HTTP/1.0"; + ps.print(message); // to socket + System.out.println(message); + System.out.println(); + + // Commands have to terminate with "carriage return/line feed" + // twice to end the request. Those are the special characters + // to have the control characters printed. Part of the http protocol! + ps.print("\r\n\r\n"); + ps.flush(); + + // Up until now we have been reading one line only. + // But a web server will write an unknown number of lines. + // So now we read until the transmisson ends. + + InputStream is = socket.getInputStream(); + Reader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + + String line; + int count = 0; + + while((line = br.readLine()) != null) // read from BufferedReader br one line at a time + { + count++; + System.out.println(count + ": " + line); + } + System.out.println("HttpWebPageSource: response finished"); + } + catch(IOException e) + { + System.err.println("HttpWebPageSource: problem with client"); + System.err.println(e); + } + } +} diff --git a/assignments/src/src/HttpServletExamples/HttpWebPageSourceTerminalLog.txt b/assignments/src/src/HttpServletExamples/HttpWebPageSourceTerminalLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..9deeef11d9aede321dc7ed17c0795449fbb134d7 --- /dev/null +++ b/assignments/src/src/HttpServletExamples/HttpWebPageSourceTerminalLog.txt @@ -0,0 +1,64 @@ +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=HttpServletExamples/HttpWebPageSource.java -Drun.class=HttpServletExamples.HttpWebPageSource run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +HttpWebPageSource: create http connection and retrieve default page +Reference: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol +Reference: https://tools.ietf.org/html/rfc7230 +Reference: https://en.wikipedia.org/wiki/CURL + +New socket WEB_ADDRESS=www.nps.edu +GET /index.html HTTP/1.0 + +1: HTTP/1.1 301 Moved Permanently +2: Date: Wed, 12 Aug 2020 01:19:20 GMT +3: Server: Apache +4: Location: https://instituteforsecuritygovernance.org/index.html +5: Content-Length: 261 +6: Connection: close +7: Content-Type: text/html; charset=iso-8859-1 +8: +9: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> +10: <html><head> +11: <title>301 Moved Permanently</title> +12: </head><body> +13: <h1>Moved Permanently</h1> +14: <p>The document has moved <a href="https://instituteforsecuritygovernance.org/index.html">here</a>.</p> +15: </body></html> +HttpWebPageSource: response finished +BUILD SUCCESSFUL (total time: 2 seconds) + +now using https to port 443: + +run-single: +HttpWebPageSource: create http connection and retrieve default page +Reference: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol +Reference: https://tools.ietf.org/html/rfc7230 +Reference: https://en.wikipedia.org/wiki/CURL + +New socket WEB_ADDRESS=www.nps.edu +GET /index.html HTTP/1.0 + +1: HTTP/1.1 400 Bad Request +2: Date: Mon, 17 Aug 2020 18:25:20 GMT +3: Server: Apache +4: Content-Length: 362 +5: Connection: close +6: Content-Type: text/html; charset=iso-8859-1 +7: +8: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> +9: <html><head> +10: <title>400 Bad Request</title> +11: </head><body> +12: <h1>Bad Request</h1> +13: <p>Your browser sent a request that this server could not understand.<br /> +14: Reason: You're speaking plain HTTP to an SSL-enabled server port.<br /> +15: Instead use the HTTPS scheme to access this URL, please.<br /> +16: </p> +17: </body></html> +HttpWebPageSource: response finished +BUILD SUCCESSFUL (total time: 2 seconds) diff --git a/assignments/src/src/HttpServletExamples/JavaServletArchitecture.pdf b/assignments/src/src/HttpServletExamples/JavaServletArchitecture.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b4471ff80a3cb8f629f2181894c5d8ea46f07aec Binary files /dev/null and b/assignments/src/src/HttpServletExamples/JavaServletArchitecture.pdf differ diff --git a/assignments/src/src/HttpServletExamples/JavaServletArchitecture.png b/assignments/src/src/HttpServletExamples/JavaServletArchitecture.png new file mode 100644 index 0000000000000000000000000000000000000000..b0b336460bdcf2e0a7bebf6e3d07f570034f19f8 Binary files /dev/null and b/assignments/src/src/HttpServletExamples/JavaServletArchitecture.png differ diff --git a/assignments/src/src/HttpServletExamples/JavaServletArchitecture.vsdx b/assignments/src/src/HttpServletExamples/JavaServletArchitecture.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..5492753a1ceaf505e0d7837434ff9ff0011a8324 Binary files /dev/null and b/assignments/src/src/HttpServletExamples/JavaServletArchitecture.vsdx differ diff --git a/assignments/src/src/HttpServletExamples/package-info.java b/assignments/src/src/HttpServletExamples/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..3105b0ca207babfc94fe17bb00a04efacea46507 --- /dev/null +++ b/assignments/src/src/HttpServletExamples/package-info.java @@ -0,0 +1,10 @@ +/** + * opendis7 Http Servlet Java examples supporting the NPS MOVES MV3500 Networked Graphics course. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples/src/HttpServletExamples" target="blank">NetworkedGraphicsMV3500 examples: HttpServletExamples</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 HttpServletExamples; diff --git a/assignments/src/src/OpenDis4Examples/EspduReceiver.java b/assignments/src/src/OpenDis4Examples/EspduReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..2a327c29fd6e1860467f1b5a8a2481c068cf95b1 --- /dev/null +++ b/assignments/src/src/OpenDis4Examples/EspduReceiver.java @@ -0,0 +1,93 @@ +package OpenDis4Examples; + +import java.net.*; +import java.util.*; + +import edu.nps.moves.disutil.*; + +import edu.nps.moves.dis.*; +import java.io.IOException; + +/** + * Receives PDUs from the network in IEEE DIS format. + * Adapted from OpenDIS library example package edu.nps.moves.examples + * + * @author DMcG + * @version $Id:$ + */ +public class EspduReceiver +{ + /** Default constructor */ + public EspduReceiver() + { + // default constructor + } + /** Max size of a PDU in binary format that we can receive. This is actually + * somewhat outdated--PDUs can be larger--but this is a reasonable starting point. + */ + private static final int MAX_PDU_SIZE = 8192; + + /** Default multicast group address we send on. + * @see <a href="https://en.wikipedia.org/wiki/Multicast_address" target="_blank">https://en.wikipedia.org/wiki/Multicast_address</a> */ + private static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3"; + + /** Default multicast port used, matches Wireshark DIS capture default + * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)" target="_blank">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> */ + private static final int DEFAULT_MULTICAST_PORT = 3000; + + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String args[]) + { + System.out.println("OpenDis4Examples.EspduReceiver started..."); + + MulticastSocket socket; + DatagramPacket packet; + InetAddress address; + PduFactory pduFactory = new PduFactory(); + + try { + // Specify the socket to receive data + socket = new MulticastSocket(DEFAULT_MULTICAST_PORT); + socket.setBroadcast(true); + + // address = InetAddress.getByName(EspduSender.DEFAULT_MULTICAST_GROUP); + // socket.joinGroup(address); + + while (true) // Loop infinitely, receiving datagrams + { + byte buffer[] = new byte[MAX_PDU_SIZE]; + packet = new DatagramPacket(buffer, buffer.length); + + socket.receive(packet); + + List<Pdu> pduBundle = pduFactory.getPdusFromBundle(packet.getData()); + System.out.println("Bundle size is " + pduBundle.size()); + + Iterator iterator = pduBundle.iterator(); + + while(iterator.hasNext()) + { + Pdu aPdu = (Pdu)iterator.next(); + + System.out.print("got PDU of type: " + aPdu.getClass().getSimpleName()); + if(aPdu instanceof EntityStatePdu) + { + EntityID eid = ((EntityStatePdu)aPdu).getEntityID(); + Vector3Double position = ((EntityStatePdu)aPdu).getEntityLocation(); + System.out.print(" EID:[" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "] "); + System.out.print(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); + } + System.out.println(); + } // end trop through PDU bundle + } // end while + } // End try + catch (IOException e) + { + System.out.println("Problem with OpenDis4Examples.EspduReceiver, see exception trace:"); + System.out.println(e); + } + } // end main +} // end class diff --git a/assignments/src/src/OpenDis4Examples/EspduSender.java b/assignments/src/src/OpenDis4Examples/EspduSender.java new file mode 100644 index 0000000000000000000000000000000000000000..aad548af9310391a0ad68c3c1f1ed9c2885c624c --- /dev/null +++ b/assignments/src/src/OpenDis4Examples/EspduSender.java @@ -0,0 +1,350 @@ +package OpenDis4Examples; + +import java.io.*; +import java.net.*; +import java.util.*; + +import edu.nps.moves.dis.*; +import edu.nps.moves.disutil.CoordinateConversions; +import edu.nps.moves.disutil.DisTime; + +/** + * Creates and sends ESPDUs in IEEE binary format. Adapted from OpenDIS library + * example package edu.nps.moves.examples + * + * @author DMcG + */ +public class EspduSender +{ + /** Default constructor */ + public EspduSender() + { + // default constructor + } + /** Defining number of packets to send is superior to infinite loops + * which have possible hazard of unstoppably sending packets as a zombie process */ + public static final int NUMBER_TO_SEND = 5; // 5000; + + /** Type of network connection */ + public enum NetworkMode { + /** Unicast network mode + * @see <a href="https://en.wikipedia.org/wiki/Unicast" target="_blank">https://en.wikipedia.org/wiki/Unicast</a> */ + UNICAST, + /** Multicast network mode + * @see <a href="https://en.wikipedia.org/wiki/Multicast" target="_blank">https://en.wikipedia.org/wiki/Multicast</a> */ + MULTICAST, + /** Broadcast network mode + * @see <a href="https://en.wikipedia.org/wiki/Broadcasting_(networking)" target="_blank">https://en.wikipedia.org/wiki/Broadcasting_(networking)</a> */ + BROADCAST + }; + + /** + * Default multicast group address we send on. + */ + public static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3"; + + /** + * Default multicast port used, matches Wireshark DIS capture default + * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)" target="_blank">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> + */ + public static final int DEFAULT_MULTICAST_PORT = 3000; + + /** + * Possible system properties, passed in via -Dattr=val networkMode: + * unicast, broadcast, multicast destinationIp: where to send the packet. If + * in multicast mode, this can be multicast. To determine broadcast + * destination IP, use an online broadcast address calculator, for example + * http://www.remotemonitoringsystems.ca/broadcast.php If in multicast mode, + * a join() will be done on the multicast address. port: port used for both + * source and destination. + * + * @param args command-line arguments + */ + public static void main(String args[]) + { + System.out.println("OpenDis4Examples.EspduSender started... send " + NUMBER_TO_SEND + " ESPDUs, initial index=0"); + /** + * an entity state pdu + */ + EntityStatePdu espdu = new EntityStatePdu(); + MulticastSocket socket = null; // must be initialized, even if null + DisTime disTime = DisTime.getInstance(); // TODO explain + int alternator = -1; + + // ICBM coordinates for my office + double lat = 36.595517; + double lon = -121.877000; + + // Default settings. These are used if no system properties are set. + // If system properties are passed in, these are over ridden. + int port = DEFAULT_MULTICAST_PORT; + NetworkMode mode = NetworkMode.BROADCAST; + InetAddress destinationIp = null; // must be initialized, even if null + + try { + destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); + } catch (UnknownHostException e) { + System.out.println(e + " Cannot create multicast address"); + System.exit(0); + } + + // All system properties, passed in on the command line via -Dattribute=value + Properties systemProperties = System.getProperties(); + + // IP address we send to + String destinationIpString = systemProperties.getProperty("destinationIp"); + + // Port we send to, and local port we open the socket on + String portString = systemProperties.getProperty("port"); + + // Network mode: unicast, multicast, broadcast + String networkModeString = systemProperties.getProperty("networkMode"); // unicast or multicast or broadcast + + // Set up a socket to send information + try { + // Port we send to + if (portString != null) + { + System.out.println("Using systemProperties port=" + portString); + port = Integer.parseInt(portString); + } + + socket = new MulticastSocket(port); + + // Where we send packets to, the destination IP address + if (destinationIpString != null) + { + destinationIp = InetAddress.getByName(destinationIpString); + } + + // Type of transport: unicast, broadcast, or multicast + // TODO convert to String constants + if (networkModeString != null) { + if (networkModeString.equalsIgnoreCase("unicast")) + { + mode = NetworkMode.UNICAST; + } + else if (networkModeString.equalsIgnoreCase("broadcast")) { + mode = NetworkMode.BROADCAST; + } + else if (networkModeString.equalsIgnoreCase("multicast")) { + mode = NetworkMode.MULTICAST; + if (!destinationIp.isMulticastAddress()) + { + throw new RuntimeException("Sending to multicast address, but destination address " + destinationIp.toString() + "is not multicast"); + } +// socket.joinGroup(destinationIp); // deprecated, TODO select correct NetworkInterface + // ======================================================================= + // updated approach using NetworkInterface + NetworkInterface networkInterface = NetworkInterface.getByInetAddress(destinationIp); + if (networkInterface != null) + System.out.println("networkInterface=" + networkInterface.getDisplayName()); // typically null if loopback + SocketAddress localMulticastSocketAddress = new InetSocketAddress(destinationIp, DEFAULT_MULTICAST_PORT); + MulticastSocket multicastSocket = new MulticastSocket(DEFAULT_MULTICAST_PORT); + multicastSocket.joinGroup(localMulticastSocketAddress, networkInterface); + // ======================================================================= + } + } // end networkModeString + } + catch (IOException | RuntimeException e) + { + System.out.println("Unable to initialize networking. Exiting."); + System.out.println(e); + System.exit(-1); + } + + // Initialize values in the Entity State PDU object. The exercise ID is + // a way to differentiate between different virtual worlds on one network. + // Note that some values (such as the PDU type and PDU family) are set + // automatically when you create the ESPDU. + espdu.setExerciseID((short) 1); + + // The EID is the unique identifier for objects in the world. This + // EID should match up with the ID for the object specified in the + // VMRL/x3d/virtual world. + EntityID entityID = espdu.getEntityID(); + entityID.setSite(1); // 0 is apparently not a valid site number, per the spec + entityID.setApplication(1); + entityID.setEntity(2); + + // Set the entity type. SISO has a big list of enumerations, so that by + // specifying various numbers we can say this is an M1A2 American tank, + // the USS Enterprise, and so on. We'll make this a tank. There is a + // separate project elsehwhere in this project that implements DIS + // enumerations in C++ and Java, but to keep things simple we just use + // numbers here. + EntityType entityType = espdu.getEntityType(); + entityType.setEntityKind((short) 1); // Platform (vs lifeform, munition, sensor, etc.) + entityType.setCountry(225); // USA + entityType.setDomain((short) 1); // Land (vs air, surface, subsurface, space) + entityType.setCategory((short) 1); // Tank + entityType.setSubcategory((short) 1); // M1 Abrams + entityType.setSpec((short) 3); // M1A2 Abrams + + Set<InetAddress> broadcastAddresses; + // Loop through sending N ESPDUs + try + { + System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString()); + + for (int index = 0; index < NUMBER_TO_SEND; index++) { + // DIS time is a pain in the uh, neck. DIS time units are 2^31-1 units per + // hour, and time is set to DIS time units from the top of the hour. + // This means that if you start sending just before the top of the hour + // the time units can roll over to zero as you are sending. The receivers + // (escpecially homegrown ones) are often not able to detect rollover + // and may start discarding packets as dupes or out of order. We use + // an NPS timestamp here, hundredths of a second since the start of the + // year. The DIS standard for time is often ignored in the wild; I've seen + // people use Unix time (seconds since 1970) and more. Or you can + // just stuff idx into the timestamp field to get something that is monotonically + // increasing. + + // Note that timestamp is used to detect duplicate and out of order packets. + // That means if you DON'T change the timestamp, many implementations will simply + // discard subsequent packets that have an identical timestamp. Also, if they + // receive a PDU with an timestamp lower than the last one they received, they + // may discard it as an earlier, out-of-order PDU. So it is a good idea to + // update the timestamp on ALL packets sent. + // An alterative approach: actually follow the standard. It's a crazy concept, + // but it might just work. + int timestamp = disTime.getDisAbsoluteTimestamp(); + espdu.setTimestamp(timestamp); + + // Set the position of the entity in the world. DIS uses a cartesian + // coordinate system with the origin at the center of the earth, the x + // axis out at the equator and prime meridian, y out at the equator and + // 90 deg east, and z up and out the north pole. To place an object on + // the earth's surface you also need a model for the shape of the earth + // (it's not a sphere.) All the fancy math necessary to do this is in + // the SEDRIS SRM package. There are also some one-off formulas for + // doing conversions from, for example, lat/lon/altitude to DIS coordinates. + // Here we use those one-off formulas. + // Modify the position of the object. This will send the object a little + // due east by adding some to the longitude every iteration. Since we + // are on the Pacific coast, this sends the object east. Assume we are + // at zero altitude. In other worlds you'd use DTED to determine the + // local ground altitude at that lat/lon, or you'd just use ground clamping. + // The x and y values will change, but the z value should not. + //lon = lon + (double)((double)idx / 100000.0); + //System.out.println("lla=" + lat + "," + lon + ", 0.0"); + double direction = Math.pow((double) (-1.0), (double) (index)); + lon = lon + (direction * 0.00006); + System.out.println(lon); + + double disCoordinates[] = CoordinateConversions.getXYZfromLatLonDegrees(lat, lon, 1.0); + Vector3Double location = espdu.getEntityLocation(); + location.setX(disCoordinates[0]); + location.setY(disCoordinates[1]); + location.setZ(disCoordinates[2]); + System.out.println("lat, lon:" + lat + ", " + lon); + System.out.println("DIS coord:" + disCoordinates[0] + ", " + disCoordinates[1] + ", " + disCoordinates[2]); + + // Optionally, we can do some rotation of the entity + /* + Orientation orientation = espdu.getEntityOrientation(); + float psi = orientation.getPsi(); + psi = psi + idx; + orientation.setPsi(psi); + orientation.setTheta((float)(orientation.getTheta() + idx /2.0)); + */ + // You can set other ESPDU values here, such as the velocity, acceleration, + // and so on. + // Marshal out the espdu object to a byte array, then send a datagram + // packet with that data in it. + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + espdu.marshal(dos); + + FirePdu fire = new FirePdu(); + byte[] fireArray = fire.marshal(); + + // The byte array here is the packet in DIS format. We put that into a + // datagram and send it. + byte[] data = baos.toByteArray(); + + broadcastAddresses = getBroadcastAddresses(); + Iterator iterator = broadcastAddresses.iterator(); + while (iterator.hasNext()) + { + InetAddress broadcast = (InetAddress) iterator.next(); + System.out.println("Sending broadcast datagram packet to " + broadcast); + DatagramPacket packet = new DatagramPacket(data, data.length, broadcast, port); + socket.send(packet); + // TODO experiment with these! 8) + packet = new DatagramPacket(fireArray, fireArray.length, broadcast, port); // alternate + socket.send(packet); + } + + // Send every 1 sec. Otherwise all this will be all over in a fraction of a second. + Thread.sleep(1000); // msec + + location = espdu.getEntityLocation(); + + System.out.println("Espdu #" + index + " EID=[" + entityID.getSite() + "," + entityID.getApplication() + "," + entityID.getEntity() + "]"); + System.out.println(" DIS coordinates location=[" + location.getX() + "," + location.getY() + "," + location.getZ() + "]"); + double c[] = {location.getX(), location.getY(), location.getZ()}; + double lla[] = CoordinateConversions.xyzToLatLonDegrees(c); +// debug: System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]"); + } + } + catch (IOException | InterruptedException e) + { + System.out.println("Problem with OpenDis4Examples.EspduSender, see exception trace:"); + System.out.println(e); + } + } + + /** + * A number of sites get all snippy about using 255.255.255.255 for a + * broadcast address; it trips their security software and they kick you off + * their network. (Comcast, NPS.) This determines the broadcast address for + * all connected interfaces, based on the IP and subnet mask. If you have a + * dual-homed host it will return a broadcast address for both. If you have + * some VMs running on your host this will pick up the addresses for those + * as well--e.g. running VMWare on your laptop with a local IP this will also + * pick up a 192.168 address assigned to the VM by the host OS. + * + * @return set of all broadcast addresses + */ + public static Set<InetAddress> getBroadcastAddresses() + { + Set<InetAddress> broadcastAddresses = new HashSet<>(); + Enumeration interfaces; + + try { + interfaces = NetworkInterface.getNetworkInterfaces(); + + while (interfaces.hasMoreElements()) + { + NetworkInterface anInterface = (NetworkInterface) interfaces.nextElement(); + + if (anInterface.isUp()) + { + Iterator iterator = anInterface.getInterfaceAddresses().iterator(); + while (iterator.hasNext()) + { + InterfaceAddress anAddress = (InterfaceAddress) iterator.next(); + if ((anAddress == null || anAddress.getAddress().isLinkLocalAddress())) + { + continue; + } + + //System.out.println("Getting broadcast address for " + anAddress); + InetAddress broadcastAddress = anAddress.getBroadcast(); + if (broadcastAddress != null) + { + broadcastAddresses.add(broadcastAddress); + } + } + } + } + } + catch (SocketException e) + { + System.out.println("Problem with OpenDis4Examples.EspduSender.getBroadcastAddresses(), see exception trace:"); + System.out.println(e); + } + return broadcastAddresses; + } +} diff --git a/assignments/src/src/OpenDis4Examples/EspduSenderWireshark.png b/assignments/src/src/OpenDis4Examples/EspduSenderWireshark.png new file mode 100644 index 0000000000000000000000000000000000000000..8fedce0aacc3fcdb97f895ecc8176890aa104e8c Binary files /dev/null and b/assignments/src/src/OpenDis4Examples/EspduSenderWireshark.png differ diff --git a/assignments/src/src/OpenDis4Examples/EspduTerminalLog.txt b/assignments/src/src/OpenDis4Examples/EspduTerminalLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..cfa5e53f475063a3d869e359bee1f495ba4851e3 --- /dev/null +++ b/assignments/src/src/OpenDis4Examples/EspduTerminalLog.txt @@ -0,0 +1,117 @@ +Invocation instructions: +1. run/debug EspduReceiver.java (since sender does not block, must first be ready to listen) +2. run/debug EspduSender.java + +Program responses for sender and receiver: + +=================================================== +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis4Examples/EspduSender.java -Drun.class=OpenDis4Examples.EspduSender run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +OpenDis4Examples.EspduSender started... send 5 ESPDUs, initial index=0 +Sending 5 ESPDU packets to /239.1.2.3 +-121.87693999999999 +lat, lon:36.595517, -121.87693999999999 +DIS coord:-2707488.3677768684, -4353666.735244378, 3781450.3202754413 +Sending broadcast datagram packet to /127.255.255.255 +Sending broadcast datagram packet to /172.23.143.255 +Sending broadcast datagram packet to /172.16.0.255 +Sending broadcast datagram packet to /172.20.209.219 +Espdu #0 EID=[1,1,2] + DIS coordinates location=[-2707488.3677768684,-4353666.735244378,3781450.3202754413] +-121.877 +lat, lon:36.595517, -121.877 +DIS coord:-2707492.9269245286, -4353663.899966802, 3781450.3202754413 +Sending broadcast datagram packet to /127.255.255.255 +Sending broadcast datagram packet to /172.23.143.255 +Sending broadcast datagram packet to /172.16.0.255 +Sending broadcast datagram packet to /172.20.209.219 +Espdu #1 EID=[1,1,2] + DIS coordinates location=[-2707492.9269245286,-4353663.899966802,3781450.3202754413] +-121.87693999999999 +lat, lon:36.595517, -121.87693999999999 +DIS coord:-2707488.3677768684, -4353666.735244378, 3781450.3202754413 +Sending broadcast datagram packet to /127.255.255.255 +Sending broadcast datagram packet to /172.23.143.255 +Sending broadcast datagram packet to /172.16.0.255 +Sending broadcast datagram packet to /172.20.209.219 +Espdu #2 EID=[1,1,2] + DIS coordinates location=[-2707488.3677768684,-4353666.735244378,3781450.3202754413] +-121.877 +lat, lon:36.595517, -121.877 +DIS coord:-2707492.9269245286, -4353663.899966802, 3781450.3202754413 +Sending broadcast datagram packet to /127.255.255.255 +Sending broadcast datagram packet to /172.23.143.255 +Sending broadcast datagram packet to /172.16.0.255 +Sending broadcast datagram packet to /172.20.209.219 +Espdu #3 EID=[1,1,2] + DIS coordinates location=[-2707492.9269245286,-4353663.899966802,3781450.3202754413] +-121.87693999999999 +lat, lon:36.595517, -121.87693999999999 +DIS coord:-2707488.3677768684, -4353666.735244378, 3781450.3202754413 +Sending broadcast datagram packet to /127.255.255.255 +Sending broadcast datagram packet to /172.23.143.255 +Sending broadcast datagram packet to /172.16.0.255 +Sending broadcast datagram packet to /172.20.209.219 +Espdu #4 EID=[1,1,2] + DIS coordinates location=[-2707488.3677768684,-4353666.735244378,3781450.3202754413] +BUILD SUCCESSFUL (total time: 12 seconds) + +=================================================== +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis4Examples/EspduReceiver.java -Drun.class=OpenDis4Examples.EspduReceiver run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +OpenDis4Examples.EspduReceiver started... +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.EntityStatePdu EID:[1, 1, 2] Location in DIS coordinates: [-2707488.3677768684, -4353666.735244378, 3781450.3202754413] +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.FirePdu +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.EntityStatePdu EID:[1, 1, 2] Location in DIS coordinates: [-2707488.3677768684, -4353666.735244378, 3781450.3202754413] +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.FirePdu +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.EntityStatePdu EID:[1, 1, 2] Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.FirePdu +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.EntityStatePdu EID:[1, 1, 2] Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.FirePdu +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.EntityStatePdu EID:[1, 1, 2] Location in DIS coordinates: [-2707488.3677768684, -4353666.735244378, 3781450.3202754413] +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.FirePdu +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.EntityStatePdu EID:[1, 1, 2] Location in DIS coordinates: [-2707488.3677768684, -4353666.735244378, 3781450.3202754413] +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.FirePdu +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.EntityStatePdu EID:[1, 1, 2] Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.FirePdu +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.EntityStatePdu EID:[1, 1, 2] Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.FirePdu +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.EntityStatePdu EID:[1, 1, 2] Location in DIS coordinates: [-2707488.3677768684, -4353666.735244378, 3781450.3202754413] +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.FirePdu +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.EntityStatePdu EID:[1, 1, 2] Location in DIS coordinates: [-2707488.3677768684, -4353666.735244378, 3781450.3202754413] +Bundle size is 1 +got PDU of type: edu.nps.moves.dis.FirePdu + +=================================================== + diff --git a/assignments/src/src/OpenDis4Examples/PduReceiver.java b/assignments/src/src/OpenDis4Examples/PduReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..63d7e99577526bcdf0dc32c57bc6da870be55c14 --- /dev/null +++ b/assignments/src/src/OpenDis4Examples/PduReceiver.java @@ -0,0 +1,88 @@ +package OpenDis4Examples; + +// originally edu.nps.moves.examples.ReceiverPerformance + +import java.net.*; + +import edu.nps.moves.dis.*; +import edu.nps.moves.disutil.PduFactory; +import java.io.IOException; + +/** Listen for IEEE DIS Protocol Data Units (PDUs) */ +public class PduReceiver +{ + /** Default constructor */ + public PduReceiver() + { + // default constructor + } + private static final int MULTICAST_PORT = 3000; + private static final String MULTICAST_GROUP = "239.1.2.3"; + private static final boolean USE_FAST_ESPDU = false; + + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String args[]) + { + PduFactory factory; + MulticastSocket socket; + InetAddress address; + DatagramPacket packet; + + try + { + System.out.println("OpenDis4Examples.PduReceiver started..."); + socket = new MulticastSocket (MULTICAST_PORT); + address = InetAddress.getByName(MULTICAST_GROUP); +// socket.joinGroup(address); // deprecated + // ======================================================================= + // new approach using interface + NetworkInterface networkInterface = NetworkInterface.getByInetAddress(address); + SocketAddress localMulticastSocketAddress = new InetSocketAddress(address, MULTICAST_PORT); + socket.joinGroup(localMulticastSocketAddress, networkInterface); + // ======================================================================= + + factory = new PduFactory(); + + while (true) // Loop infinitely, receiving datagrams + { + byte buffer[] = new byte[1500]; // typical MTU size + + packet = new DatagramPacket(buffer, buffer.length); // reset + + socket.receive(packet); + + Pdu pdu = factory.createPdu (packet.getData()); + if (pdu != null) + { + short currentPduType = pdu.getPduType(); + String currentPduTypeName = pdu.getClass().getSimpleName(); + short currentProtocolFamilyID = pdu.getProtocolFamily(); + String currentPduFamilyName = pdu.getClass().getSuperclass().getSimpleName(); + + StringBuilder message = new StringBuilder(); + message.append("received DIS PDU: "); + message.append("pduType "); + if (currentPduType < 10) + message.append(" "); + message.append(currentPduType).append(" ").append(currentPduTypeName); + message.append(", protocolFamily ").append(currentProtocolFamilyID); + message.append(" ").append(currentPduFamilyName); + System.out.println(message.toString()); + } + else System.out.println("received packet but pdu is null, packet.getData().length=" + packet.getData().length + ", error..."); + } + } + catch (IOException e) + { + System.out.println("Problem with OpenDis4Examples.PduReceiver, see exception trace:"); + System.out.println(e); + } + finally + { + System.out.println("OpenDis4Examples.PduReceiver complete."); + } + } +} diff --git a/assignments/src/src/OpenDis4Examples/PduReceiverTerminalLog.txt b/assignments/src/src/OpenDis4Examples/PduReceiverTerminalLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..88dc4affa0a0426ced004f094bcf45c8370b2d19 --- /dev/null +++ b/assignments/src/src/OpenDis4Examples/PduReceiverTerminalLog.txt @@ -0,0 +1,26 @@ +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis4Examples/PduReceiver.java -Drun.class=OpenDis4Examples.PduReceiver run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +OpenDis4Examples.PduReceiver started... +received DIS PDU: pduType 1 edu.nps.moves.dis.EntityStatePdu, protocolFamily 1 EntityInformationFamilyPdu +received DIS PDU: pduType 2 edu.nps.moves.dis.FirePdu, protocolFamily 2 WarfareFamilyPdu +received DIS PDU: pduType 3 edu.nps.moves.dis.DetonationPdu, protocolFamily 2 WarfareFamilyPdu +received DIS PDU: pduType 4 edu.nps.moves.dis.CollisionPdu, protocolFamily 1 EntityInformationFamilyPdu +received DIS PDU: pduType 5 edu.nps.moves.dis.ServiceRequestPdu, protocolFamily 3 LogisticsFamilyPdu +received DIS PDU: pduType 6 edu.nps.moves.dis.ResupplyOfferPdu, protocolFamily 3 LogisticsFamilyPdu +received packet but pdu is null, packet.getData().length=1500, error... +received DIS PDU: pduType 8 edu.nps.moves.dis.ResupplyCancelPdu, protocolFamily 3 LogisticsFamilyPdu +received DIS PDU: pduType 9 edu.nps.moves.dis.RepairCompletePdu, protocolFamily 3 LogisticsFamilyPdu +received DIS PDU: pduType 10 edu.nps.moves.dis.RepairResponsePdu, protocolFamily 3 LogisticsFamilyPdu +received DIS PDU: pduType 11 edu.nps.moves.dis.CreateEntityPdu, protocolFamily 5 SimulationManagementFamilyPdu +received DIS PDU: pduType 12 edu.nps.moves.dis.RemoveEntityPdu, protocolFamily 5 SimulationManagementFamilyPdu +received DIS PDU: pduType 13 edu.nps.moves.dis.StartResumePdu, protocolFamily 5 SimulationManagementFamilyPdu +received DIS PDU: pduType 14 edu.nps.moves.dis.StopFreezePdu, protocolFamily 5 SimulationManagementFamilyPdu +received DIS PDU: pduType 15 edu.nps.moves.dis.AcknowledgePdu, protocolFamily 5 SimulationManagementFamilyPdu +received DIS PDU: pduType 16 edu.nps.moves.dis.ActionRequestPdu, protocolFamily 5 SimulationManagementFamilyPdu +received DIS PDU: pduType 22 edu.nps.moves.dis.CommentPdu, protocolFamily 5 SimulationManagementFamilyPdu diff --git a/assignments/src/src/OpenDis4Examples/PduSender.java b/assignments/src/src/OpenDis4Examples/PduSender.java new file mode 100644 index 0000000000000000000000000000000000000000..0417dd23777a3c33f5888667b9691f3c0e237dc9 --- /dev/null +++ b/assignments/src/src/OpenDis4Examples/PduSender.java @@ -0,0 +1,215 @@ +package OpenDis4Examples; + +import java.io.*; +import java.net.*; +import java.util.*; + +import edu.nps.moves.dis.*; +import edu.nps.moves.disenum.*; +import edu.nps.moves.examples.ClassNameComparator; + +/** + * This is an example that sends many/most types of PDUs. Useful for testing standards + * compliance or getting a full set of PDUs. It also writes the generated PDUs to an XML file. + * Adapted from OpenDIS library example package edu.nps.moves.examples + * + * @author DMcG + * @version $Id:$ + */ +public class PduSender +{ + /** Default multicast group address we send on. + * @see <a href="https://en.wikipedia.org/wiki/Multicast_address" target="_blank">https://en.wikipedia.org/wiki/Multicast_address</a> */ + private static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3"; + + /** Default multicast port used, matches Wireshark DIS capture default + * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)" target="_blank">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> */ + private static final int DEFAULT_MULTICAST_PORT = 3000; + + private int port; + InetAddress multicastAddress; + + /** Object constructor + * @param port port of interest + * @param multicast address of interest */ + public PduSender(int port, String multicast) { + try + { + this.port = port; + multicastAddress = InetAddress.getByName(multicast); + if (!multicastAddress.isMulticastAddress()) + { + System.out.println("Not a multicast address: " + multicast); + } + } + catch (UnknownHostException e) { + System.out.println("Unable to open socket: " + e); + } + } + + /** Begin operations */ + public void run() + { + System.out.println("OpenDis4Examples.PduSender started..."); + try { + List<Pdu> generatedPdusList = new ArrayList<>(); + + // Loop through all the enumerated PDU types, create a PDU for each type, + // add that PDU to generatedPdusList, and send each one + for (PduType pdu : PduType.values()) + { + Pdu aPdu = null; // edu.​nps.​moves.​dis,PDU superclass for all PDUs, + + switch (pdu) // using enumeration values from edu.nps.moves.disenum.* + { + case ENTITY_STATE: + aPdu = new EntityStatePdu(); + EntityStatePdu espdu = (EntityStatePdu) aPdu; + Marking marking = new Marking (); + marking.setCharactersString("PduSender"); // 11 characters max + espdu.setMarking(marking); + Vector3Double espduLocation = new Vector3Double(); + espduLocation.setX(1.0); + espduLocation.setY(2.0); + espduLocation.setZ(3.0); + espdu.setEntityLocation(espduLocation); + // it is important to identify questions as you think of them + // TODO how to set azimuth, i.e. course direction over ground? + break; + + case COMMENT: + aPdu = new CommentPdu(); + CommentPdu newCommentPdu = (CommentPdu)aPdu; + VariableDatum newVariableDatum = new VariableDatum(); + // etc. see Garrett and Pete's code + break; + + case FIRE: + aPdu = new FirePdu(); + break; + + case DETONATION: + aPdu = new DetonationPdu(); + break; + + case COLLISION: + aPdu = new CollisionPdu(); + break; + + case SERVICE_REQUEST: + aPdu = new ServiceRequestPdu(); + break; + + case RESUPPLY_OFFER: + aPdu = new ResupplyOfferPdu(); + break; + + case RESUPPLY_RECEIVED: + aPdu = new ResupplyReceivedPdu(); + break; + + case RESUPPLY_CANCEL: + aPdu = new ResupplyCancelPdu(); + break; + + case REPAIR_COMPLETE: + aPdu = new RepairCompletePdu(); + break; + + case REPAIR_RESPONSE: + aPdu = new RepairResponsePdu(); + break; + + case CREATE_ENTITY: + aPdu = new CreateEntityPdu(); + break; + + case REMOVE_ENTITY: + aPdu = new RemoveEntityPdu(); + break; + + case START_RESUME: + aPdu = new StartResumePdu(); + break; + + case STOP_FREEZE: + aPdu = new StopFreezePdu(); + break; + + case ACKNOWLEDGE: + aPdu = new AcknowledgePdu(); + break; + + case ACTION_REQUEST: + aPdu = new ActionRequestPdu(); + break; + + default: + System.out.print("PDU of type " + pdu + " not supported, created or sent "); + System.out.println(); + } + if (aPdu != null) + { + generatedPdusList.add(aPdu); + } + } + + // Sort the created PDUs by class name, if desired +// Collections.sort(generatedPdusList, new ClassNameComparator()); + + System.out.println("Send the " + generatedPdusList.size() + " PDUs we created..."); + + // Send the PDUs we created + InetAddress localMulticastAddress = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); + MulticastSocket socket = new MulticastSocket(DEFAULT_MULTICAST_PORT); +// socket.joinGroup(localMulticastAddress); // deprecated, TODO select correct NetworkInterface + // ======================================================================= + // updated approach using NetworkInterface + NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localMulticastAddress); + if (networkInterface != null) + System.out.println("networkInterface=" + networkInterface.getDisplayName()); // typically null if loopback + SocketAddress localMulticastSocketAddress = new InetSocketAddress(localMulticastAddress, DEFAULT_MULTICAST_PORT); + socket.joinGroup(localMulticastSocketAddress, networkInterface); + // ======================================================================= + + for (int idx = 0; idx < generatedPdusList.size(); idx++) + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + byte[] buffer; + + Pdu aPdu = generatedPdusList.get(idx); + aPdu.marshal(dos); + + buffer = baos.toByteArray(); + DatagramPacket packet = new DatagramPacket(buffer, buffer.length, localMulticastAddress, DEFAULT_MULTICAST_PORT); + socket.send(packet); + System.out.println("Sent PDU of type " + aPdu.getClass().getSimpleName()); + } + // write the PDUs out to an XML file. + //PduContainer container = new PduContainer(); + //container.setPdus(generatedPdus); + //container.marshallToXml("examplePdus.xml"); + } catch (IOException e) + { + System.out.println(e); + } + } + + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String args[]) + { + if (args.length == 2) { + PduSender sender = new PduSender(Integer.parseInt(args[0]), args[1]); + sender.run(); + } else { + System.out.println("Usage: PduSender <port> <multicast group>"); + System.out.println("Default: PduSender " + DEFAULT_MULTICAST_PORT + " " + DEFAULT_MULTICAST_ADDRESS); + PduSender sender = new PduSender(DEFAULT_MULTICAST_PORT, DEFAULT_MULTICAST_ADDRESS); + sender.run(); + } + } +} diff --git a/assignments/src/src/OpenDis4Examples/PduSenderTerminalLog.txt b/assignments/src/src/OpenDis4Examples/PduSenderTerminalLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..e9d69b91e924154dabf6132a952fe563d9fa7b8c --- /dev/null +++ b/assignments/src/src/OpenDis4Examples/PduSenderTerminalLog.txt @@ -0,0 +1,81 @@ +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis4Examples/PduSender.java -Drun.class=OpenDis4Examples.PduSender run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +Usage: PduSender <port> <multicast group> +Default: PduSender 3000 239.1.2.3 +OpenDis4Examples.PduSender started... +PDU of type OTHER not supported, created or sent +PDU of type ACTION_RESPONSE not supported, created or sent +PDU of type DATA_QUERY not supported, created or sent +PDU of type SET_DATA not supported, created or sent +PDU of type DATA not supported, created or sent +PDU of type EVENT_REPORT not supported, created or sent +PDU of type ELECTROMAGNETIC_EMISSION not supported, created or sent +PDU of type DESIGNATOR not supported, created or sent +PDU of type TRANSMITTER not supported, created or sent +PDU of type SIGNAL not supported, created or sent +PDU of type RECEIVER not supported, created or sent +PDU of type IFF_ATC_NAVAIDS not supported, created or sent +PDU of type UNDERWATER_ACOUSTIC not supported, created or sent +PDU of type SUPPLEMENTAL_EMISSION_ENTITY_STATE not supported, created or sent +PDU of type INTERCOM_SIGNAL not supported, created or sent +PDU of type INTERCOM_CONTROL not supported, created or sent +PDU of type AGGREGATE_STATE not supported, created or sent +PDU of type ISGROUPOF not supported, created or sent +PDU of type TRANSFER_CONTROL not supported, created or sent +PDU of type ISPARTOF not supported, created or sent +PDU of type MINEFIELD_STATE not supported, created or sent +PDU of type MINEFIELD_QUERY not supported, created or sent +PDU of type MINEFIELD_DATA not supported, created or sent +PDU of type MINEFIELD_RESPONSE_NAK not supported, created or sent +PDU of type ENVIRONMENTAL_PROCESS not supported, created or sent +PDU of type GRIDDED_DATA not supported, created or sent +PDU of type POINT_OBJECT_STATE not supported, created or sent +PDU of type LINEAR_OBJECT_STATE not supported, created or sent +PDU of type AREAL_OBJECT_STATE not supported, created or sent +PDU of type TSPI not supported, created or sent +PDU of type APPEARANCE not supported, created or sent +PDU of type ARTICULATED_PARTS not supported, created or sent +PDU of type LE_FIRE not supported, created or sent +PDU of type LE_DETONATION not supported, created or sent +PDU of type CREATE_ENTITY_R not supported, created or sent +PDU of type REMOVE_ENTITY_R not supported, created or sent +PDU of type START_RESUME_R not supported, created or sent +PDU of type STOP_FREEZE_R not supported, created or sent +PDU of type ACKNOWLEDGE_R not supported, created or sent +PDU of type ACTION_REQUEST_R not supported, created or sent +PDU of type ACTION_RESPONSE_R not supported, created or sent +PDU of type DATA_QUERY_R not supported, created or sent +PDU of type SET_DATA_R not supported, created or sent +PDU of type DATA_R not supported, created or sent +PDU of type EVENT_REPORT_R not supported, created or sent +PDU of type COMMENT_R not supported, created or sent +PDU of type RECORD_R not supported, created or sent +PDU of type SET_RECORD_R not supported, created or sent +PDU of type RECORD_QUERY_R not supported, created or sent +PDU of type COLLISION_ELASTIC not supported, created or sent +PDU of type ENTITY_STATE_UPDATE not supported, created or sent +Send the 17 PDUs we created... +Sent PDU of type edu.nps.moves.dis.EntityStatePdu +Sent PDU of type edu.nps.moves.dis.FirePdu +Sent PDU of type edu.nps.moves.dis.DetonationPdu +Sent PDU of type edu.nps.moves.dis.CollisionPdu +Sent PDU of type edu.nps.moves.dis.ServiceRequestPdu +Sent PDU of type edu.nps.moves.dis.ResupplyOfferPdu +Sent PDU of type edu.nps.moves.dis.ResupplyReceivedPdu +Sent PDU of type edu.nps.moves.dis.ResupplyCancelPdu +Sent PDU of type edu.nps.moves.dis.RepairCompletePdu +Sent PDU of type edu.nps.moves.dis.RepairResponsePdu +Sent PDU of type edu.nps.moves.dis.CreateEntityPdu +Sent PDU of type edu.nps.moves.dis.RemoveEntityPdu +Sent PDU of type edu.nps.moves.dis.StartResumePdu +Sent PDU of type edu.nps.moves.dis.StopFreezePdu +Sent PDU of type edu.nps.moves.dis.AcknowledgePdu +Sent PDU of type edu.nps.moves.dis.ActionRequestPdu +Sent PDU of type edu.nps.moves.dis.CommentPdu +BUILD SUCCESSFUL (total time: 2 seconds) diff --git a/assignments/src/src/OpenDis4Examples/PduSenderWireshark.png b/assignments/src/src/OpenDis4Examples/PduSenderWireshark.png new file mode 100644 index 0000000000000000000000000000000000000000..2991771d646657e5803b2aa58758a417296ba26b Binary files /dev/null and b/assignments/src/src/OpenDis4Examples/PduSenderWireshark.png differ diff --git a/assignments/src/src/OpenDis4Examples/README.md b/assignments/src/src/OpenDis4Examples/README.md new file mode 100644 index 0000000000000000000000000000000000000000..538a10cd70b2988ff1a85cc7e6ca061d4696c953 --- /dev/null +++ b/assignments/src/src/OpenDis4Examples/README.md @@ -0,0 +1,10 @@ +# DIS Protocol Examples using Open-DIS-4 Java Library + +*Note:* these archived examples demonstrate an earlier version of Open-DIS-Java Library. +Please work with current version [OpenDis7Examples](../OpenDis7Examples) instead. + +--- + +Course examples using the [Open-DIS-Java](https://github.com/open-dis/open-dis-java) library are presented in this package. + +See [specifications](../../../specifications) directory to obtain reference copies of DIS and RPRFOM standards. diff --git a/assignments/src/src/OpenDis4Examples/package-info.java b/assignments/src/src/OpenDis4Examples/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..acf568a652b70cfb93425f08706f73d34f79f9d7 --- /dev/null +++ b/assignments/src/src/OpenDis4Examples/package-info.java @@ -0,0 +1,10 @@ +/** + * open-dis library version 4: Java examples supporting the NPS MOVES MV3500 Networked Graphics course. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples/src/OpenDis4Examples" target="blank">NetworkedGraphicsMV3500 examples: OpenDis4Examples</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 OpenDis4Examples; diff --git a/assignments/src/src/OpenDis7Examples/AllPduReceiver.java b/assignments/src/src/OpenDis7Examples/AllPduReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..424ab01244d066a36803ca2b3ae0e425b4eb07cf --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/AllPduReceiver.java @@ -0,0 +1,137 @@ +package OpenDis7Examples; + +import edu.nps.moves.dis7.enumerations.*; +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.DisTime; +import edu.nps.moves.dis7.utilities.PduFactory; +import java.io.*; +import java.net.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** Listen to all kinds of PDUs and report them */ +public class AllPduReceiver +{ + /** Default constructor */ + public AllPduReceiver() + { + // default constructor + } + /** default multicast address + * @see <a href="https://en.wikipedia.org/wiki/Multicast_address" target="_blank">https://en.wikipedia.org/wiki/Multicast_address</a> */ + public static final String DEFAULT_MULTICAST_ADDRESS = AllPduSender.DEFAULT_MULTICAST_ADDRESS; + /** default multicast port + * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)" target="_blank">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> */ + public static final int DEFAULT_MULTICAST_PORT = AllPduSender.DEFAULT_MULTICAST_PORT; + /** TODO whether to use Fast ESPDU */ + public static final boolean USE_FAST_ESPDU = false; + + /** Output prefix to identify this class */ + private final static String TRACE_PREFIX = "[" + AllPduReceiver.class.getName() + "] "; + + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String args[]) + { + MulticastSocket multicastSocket; + InetAddress multicastInetAddress; + PduFactory pduFactory = new PduFactory(); + DisTime.TimestampStyle timestampStyle = DisTime.TimestampStyle.IEEE_ABSOLUTE; + DisTime.setTimestampStyle(timestampStyle); + + System.out.println(TRACE_PREFIX + "started..."); + + try { + if (args.length == 2) + { + multicastInetAddress = InetAddress.getByName(args[0]); + multicastSocket = new MulticastSocket(Integer.parseInt(args[1])); + } + else + { + System.out.println("Usage: AllPduReceiver <multicast group> <port>"); + System.out.println("Default: AllPduReceiver " + DEFAULT_MULTICAST_ADDRESS + " " + DEFAULT_MULTICAST_PORT); + multicastSocket = new MulticastSocket(DEFAULT_MULTICAST_PORT); + multicastInetAddress = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); + } + System.out.println("To quit: stop or kill this process"); + // multicastSocket.joinGroup(multicastInetAddress); // deprecated + + // ======================================================================= + // new approach using interface + NetworkInterface networkInterface = NetworkInterface.getByInetAddress(multicastInetAddress); + SocketAddress localMulticastSocketAddress = new InetSocketAddress(multicastInetAddress, DEFAULT_MULTICAST_PORT); + multicastSocket.joinGroup(localMulticastSocketAddress, networkInterface); + // ======================================================================= + + byte buffer[] = new byte[1500]; // typical MTU size in bytes + + while (true) // Loop indefinitely, receiving datagrams + { + Arrays.fill(buffer, (byte)0); + DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length); // reset packet each time + multicastSocket.receive(datagramPacket); // process blocks here until receipt of network packet with PDU + // datagramPacket.setLength(buffer.length); + + // Pdu pdu = pduFactory.createPdu(packet.getData()); // packet.getData() returns byte[] array data buffer + + List<Pdu> pduBundle = pduFactory.getPdusFromBundle(datagramPacket.getData(),datagramPacket.getLength()); + + if (pduBundle.isEmpty()) + System.out.println("Received PDU bundle is empty, packet.getData().length=" + datagramPacket.getData().length + ", error..."); + // else if (pduBundle.size() == 1)// common case, typically unremarkable + // System.out.println("Received PDU bundle size is " + pduBundle.size()); + else if (pduBundle.size() > 1) + System.out.println("Received PDU bundle size is " + pduBundle.size()); + + for (Pdu nextPdu : pduBundle) // iterator loop through PDU bundle + { + DisPduType currentPduType = nextPdu.getPduType(); //short currentPduType = nextPdu.getPduType(); + String currentPduTypeName = nextPdu.getClass().getSimpleName(); + String currentPduFamilyName = nextPdu.getClass().getSuperclass().getSimpleName(); + DISProtocolFamily currentProtocolFamilyID = nextPdu.getProtocolFamily(); //short currentProtocolFamilyID = nextPdu.getProtocolFamily(); + + StringBuilder message = new StringBuilder(); + message.append(DisTime.convertToString(nextPdu.getTimestamp())).append(" "); + message.append("received new DIS PDU "); + String currentPduTypePadded = String.format("%-48s", currentPduType); // - indicates right padding of whitespace + message.append(currentPduTypePadded); + // optional, verbose + // String currentPduTypeNamePadded = String.format("%-49s", currentPduTypeName); // - indicates right padding of whitespace + // message.append(" of type ").append(currentPduTypeNamePadded); // package.class name + message.append(" (").append(currentProtocolFamilyID); + // message.append(" ").append(currentPduFamilyName); // class name is also available + message.append(")"); + System.out.println(message.toString()); // diagnostic information helps + + // additional message information of interest, if any + switch (currentPduType) // using enumeration values from edu.​nps.​moves.​dis7.​enumerations.​DisPduType + { + case COMMENT: + CommentPdu commentPdu = (CommentPdu)nextPdu; // cast to precise type + ArrayList<VariableDatum> payloadList = (ArrayList<VariableDatum>)commentPdu.getVariableDatums(); + if (!payloadList.isEmpty()) + System.out.print (" messages: "); + for (VariableDatum variableDatum : payloadList) + { + String nextComment = new String(variableDatum.getVariableDatumValue()); // convert byte[] to String + System.out.print (" \"" + nextComment + "\""); + } + System.out.println(); + } + } + pduBundle.clear(); + } + } + catch (IOException e) { + System.out.println("Problem with OpenDis7Examples.AllPduReceiver, see exception trace:"); + System.out.println(e); + } + finally { + System.out.println("OpenDis7Examples.AllPduReceiver complete."); + } + } +} diff --git a/assignments/src/src/OpenDis7Examples/AllPduReceiverLog.txt b/assignments/src/src/OpenDis7Examples/AllPduReceiverLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..b8e370319696e6f2a140ff6c56c1a05801f1c528 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/AllPduReceiverLog.txt @@ -0,0 +1,87 @@ +ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/AllPduReceiver.java -Drun.class=OpenDis7Examples.AllPduReceiver 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 +warning: [options] system modules path not set in conjunction with -source 17 +1 warning +compile-single: +run-single: +[OpenDis7Examples.AllPduReceiver] started... +Usage: AllPduReceiver <multicast group> <port> +Default: AllPduReceiver 239.1.2.3 3000 +To quit: stop or kill this process +1969-00-31 16:00:00 received new DIS PDU DisPduType 01 ENTITY_STATE (DISProtocolFamily 1 ENTITY_INFORMATION_INTERACTION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 02 FIRE (DISProtocolFamily 2 WARFARE) +1969-00-31 16:00:00 received new DIS PDU DisPduType 03 DETONATION (DISProtocolFamily 2 WARFARE) +1969-00-31 16:00:00 received new DIS PDU DisPduType 04 COLLISION (DISProtocolFamily 1 ENTITY_INFORMATION_INTERACTION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 05 SERVICE_REQUEST (DISProtocolFamily 3 LOGISTICS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 06 RESUPPLY_OFFER (DISProtocolFamily 3 LOGISTICS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 07 RESUPPLY_RECEIVED (DISProtocolFamily 3 LOGISTICS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 08 RESUPPLY_CANCEL (DISProtocolFamily 3 LOGISTICS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 09 REPAIR_COMPLETE (DISProtocolFamily 3 LOGISTICS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 10 REPAIR_RESPONSE (DISProtocolFamily 3 LOGISTICS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 11 CREATE_ENTITY (DISProtocolFamily 5 SIMULATION_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 12 REMOVE_ENTITY (DISProtocolFamily 5 SIMULATION_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 13 START_RESUME (DISProtocolFamily 5 SIMULATION_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 14 STOP_FREEZE (DISProtocolFamily 5 SIMULATION_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 15 ACKNOWLEDGE (DISProtocolFamily 5 SIMULATION_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 16 ACTION_REQUEST (DISProtocolFamily 5 SIMULATION_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 17 ACTION_RESPONSE (DISProtocolFamily 5 SIMULATION_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 18 DATA_QUERY (DISProtocolFamily 5 SIMULATION_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 19 SET_DATA (DISProtocolFamily 5 SIMULATION_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 20 DATA (DISProtocolFamily 5 SIMULATION_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 21 EVENT_REPORT (DISProtocolFamily 5 SIMULATION_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 22 COMMENT (DISProtocolFamily 5 SIMULATION_MANAGEMENT) + messages: "Hello CommentPDU" "Here is a second line of text in this comment." +1969-00-31 16:00:00 received new DIS PDU DisPduType 23 ELECTROMAGNETIC_EMISSION (DISProtocolFamily 6 DISTRIBUTED_EMISSION_REGENERATION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 24 DESIGNATOR (DISProtocolFamily 6 DISTRIBUTED_EMISSION_REGENERATION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 25 TRANSMITTER (DISProtocolFamily 4 RADIO_COMMUNICATIONS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 26 SIGNAL (DISProtocolFamily 4 RADIO_COMMUNICATIONS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 27 RECEIVER (DISProtocolFamily 4 RADIO_COMMUNICATIONS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 28 IDENTIFICATION_FRIEND_OR_FOE (DISProtocolFamily 6 DISTRIBUTED_EMISSION_REGENERATION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 29 UNDERWATER_ACOUSTIC (DISProtocolFamily 6 DISTRIBUTED_EMISSION_REGENERATION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 30 SUPPLEMENTAL_EMISSION_ENTITY_STATE (DISProtocolFamily 6 DISTRIBUTED_EMISSION_REGENERATION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 31 INTERCOM_SIGNAL (DISProtocolFamily 4 RADIO_COMMUNICATIONS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 32 INTERCOM_CONTROL (DISProtocolFamily 4 RADIO_COMMUNICATIONS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 33 AGGREGATE_STATE (DISProtocolFamily 7 ENTITY_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 34 ISGROUPOF (DISProtocolFamily 7 ENTITY_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 35 TRANSFER_OWNERSHIP (DISProtocolFamily 7 ENTITY_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 36 ISPARTOF (DISProtocolFamily 7 ENTITY_MANAGEMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 37 MINEFIELD_STATE (DISProtocolFamily 8 MINEFIELD) +1969-00-31 16:00:00 received new DIS PDU DisPduType 38 MINEFIELD_QUERY (DISProtocolFamily 8 MINEFIELD) +1969-00-31 16:00:00 received new DIS PDU DisPduType 39 MINEFIELD_DATA (DISProtocolFamily 8 MINEFIELD) +1969-00-31 16:00:00 received new DIS PDU DisPduType 40 MINEFIELD_RESPONSE_NACK (DISProtocolFamily 8 MINEFIELD) +1969-00-31 16:00:00 received new DIS PDU DisPduType 41 ENVIRONMENTAL_PROCESS (DISProtocolFamily 9 SYNTHETIC_ENVIRONMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 42 GRIDDED_DATA (DISProtocolFamily 9 SYNTHETIC_ENVIRONMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 43 POINT_OBJECT_STATE (DISProtocolFamily 9 SYNTHETIC_ENVIRONMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 44 LINEAR_OBJECT_STATE (DISProtocolFamily 9 SYNTHETIC_ENVIRONMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 45 AREAL_OBJECT_STATE (DISProtocolFamily 9 SYNTHETIC_ENVIRONMENT) +1969-00-31 16:00:00 received new DIS PDU DisPduType 46 TIME_SPACE_POSITION_INFORMATION (DISProtocolFamily 11 LIVE_ENTITY_LE_INFORMATION_INTERACTION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 47 APPEARANCE (DISProtocolFamily 11 LIVE_ENTITY_LE_INFORMATION_INTERACTION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 48 ARTICULATED_PARTS (DISProtocolFamily 11 LIVE_ENTITY_LE_INFORMATION_INTERACTION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 49 LIVE_ENTITY_FIRE (DISProtocolFamily 11 LIVE_ENTITY_LE_INFORMATION_INTERACTION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 50 LIVE_ENTITY_DETONATION (DISProtocolFamily 11 LIVE_ENTITY_LE_INFORMATION_INTERACTION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 51 CREATE_ENTITY_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 52 REMOVE_ENTITY_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 53 START_RESUME_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 54 STOP_FREEZE_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 55 ACKNOWLEDGE_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 56 ACTION_REQUEST_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 57 ACTION_RESPONSE_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 58 DATA_QUERY_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 59 SET_DATA_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 60 DATA_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 61 EVENT_REPORT_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 62 COMMENT_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 63 RECORD_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 64 SET_RECORD_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 65 RECORD_QUERY_RELIABLE (DISProtocolFamily 10 SIMULATION_MANAGEMENT_WITH_RELIABILITY) +1969-00-31 16:00:00 received new DIS PDU DisPduType 66 COLLISION_ELASTIC (DISProtocolFamily 1 ENTITY_INFORMATION_INTERACTION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 67 ENTITY_STATE_UPDATE (DISProtocolFamily 1 ENTITY_INFORMATION_INTERACTION) +1969-00-31 16:00:00 received new DIS PDU DisPduType 68 DIRECTED_ENERGY_FIRE (DISProtocolFamily 2 WARFARE) +1969-00-31 16:00:00 received new DIS PDU DisPduType 69 ENTITY_DAMAGE_STATUS (DISProtocolFamily 2 WARFARE) +1969-00-31 16:00:00 received new DIS PDU DisPduType 70 INFORMATION_OPERATIONS_ACTION (DISProtocolFamily 13 INFORMATION_OPERATIONS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 71 INFORMATION_OPERATIONS_REPORT (DISProtocolFamily 13 INFORMATION_OPERATIONS) +1969-00-31 16:00:00 received new DIS PDU DisPduType 72 ATTRIBUTE (DISProtocolFamily 1 ENTITY_INFORMATION_INTERACTION) diff --git a/assignments/src/src/OpenDis7Examples/AllPduSender.java b/assignments/src/src/OpenDis7Examples/AllPduSender.java new file mode 100755 index 0000000000000000000000000000000000000000..441f9c1006c4c88eb6039de6f44e01a8e09b7594 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/AllPduSender.java @@ -0,0 +1,557 @@ +package OpenDis7Examples; + +import java.io.*; +import java.net.*; +import java.util.*; + +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.enumerations.*; + +/** + * This is an application example that sends every type of PDU defined + * by the IEEE Distributed Interactive Simulation (DIS) Protocol. + * This example program is useful for testing standards compliance by applications, or + * producing a full set of PDUs. It also writes the generated PDUs to an XML file. + * Adapted from OpenDIS library example package edu.nps.moves.examples + * + * @author brutzman + * @author DMcG + * @version $Id:$ + */ +public class AllPduSender +{ + /** Default multicast group address we send on. + * @see <a href="https://en.wikipedia.org/wiki/Multicast_address" target="_blank">https://en.wikipedia.org/wiki/Multicast_address</a> */ + public static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3"; // PduRecorder "225.4.5.6"; // + + /** Default multicast port used, matches Wireshark DIS capture default + * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)" target="_blank">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> */ + public static final int DEFAULT_MULTICAST_PORT = 3000; + + /** Duration in milliseconds, set to 0 to avoid pausing between PDU sends */ + private long THREAD_SLEEP_INTERVAL = 0; + + /** Number of complete loops to perform. + * Putting any upper limit on # packets sent avoids possibility of non-terminating infinite loops that continue sending packets. */ + private int SEND_LOOPS_TO_PERFORM = 1; + + private static InetAddress multicastInetAddress; + private static int port; + + /** Object constructor + * @param newMulticastAddress address of interest + * @param newMulticastPort port of interest */ + public AllPduSender(String newMulticastAddress, int newMulticastPort) + { + this.port = DEFAULT_MULTICAST_PORT; + try + { + multicastInetAddress = InetAddress.getByName(newMulticastAddress); + if (!multicastInetAddress.isMulticastAddress()) + { + System.out.println("Not a multicast address: " + newMulticastAddress); + } + this.port = newMulticastPort; + } + catch (UnknownHostException e) { + System.out.println("Unable to open socket: " + e); + } + } + + /** Begin operations + * @return number of PDUs received, -1 if exception occurs */ + @SuppressWarnings("SleepWhileInLoop") + public int run() + { + System.out.println("OpenDis7Examples.AllPduSender started..."); + if (SEND_LOOPS_TO_PERFORM != 1) + { + float waitIntervalSeconds = ((float)THREAD_SLEEP_INTERVAL / 1000); + float loopIntervalSeconds = ((float)THREAD_SLEEP_INTERVAL / 1000) * 72; // 72 PDUs + float totalDurationSeconds = loopIntervalSeconds * SEND_LOOPS_TO_PERFORM ; + System.out.println("... THREAD_SLEEP_INTERVAL = " + THREAD_SLEEP_INTERVAL + " milliseconds = " + waitIntervalSeconds + " seconds"); + System.out.print ("... running for "); + if (SEND_LOOPS_TO_PERFORM > 1) + System.out.print (SEND_LOOPS_TO_PERFORM + " loops, "); + if (THREAD_SLEEP_INTERVAL > 0) + System.out.println("expected loop interval = " + loopIntervalSeconds + " seconds, total duration = " + + totalDurationSeconds + " seconds = " + (totalDurationSeconds/60.0) + " minutes"); + } + + System.out.println("Generate list of all PDU types and note issues, if any..."); + List<Pdu> generatedPdusList = new ArrayList<>(); + + for (int i = 0; i < SEND_LOOPS_TO_PERFORM; i++) { + + try { + + // Loop through all the enumerated PDU types, create a PDU for each type, + // add that PDU to generatedPdusList, then send each one + for (DisPduType pduTypeValue : DisPduType.values()) + { + // System.out.println("PDU " + pdu.getValue() + " " + pdu.name() + " " + pdu.getDescription()); // diagnostic + + Pdu aPdu = null; // edu.​nps.​moves7.​dis.PDU superclass for all PDUs, in preparation for custom assignment + + try { + switch (pduTypeValue) // using enumeration values from edu.​nps.​moves.​dis7.​enumerations.​DisPduType + { + // each case value is DisPduType + case OTHER: // 0 + System.out.println ("*** Note: DisPduType." + pduTypeValue.name() + "=" + pduTypeValue.getValue() + " not supported"); // TODO why was this received? + break; // nothing to send + + case ENTITY_STATE: // 1 + aPdu = new EntityStatePdu(); + + EntityStatePdu espdu = (EntityStatePdu) aPdu; + EntityMarking entityMarking = new EntityMarking (); + entityMarking.setCharacters("AllPduSender".getBytes()); //entityMarking.setCharacters(Byte.valueOf("0")); // 11 characters max? + + espdu.setMarking(entityMarking); + Vector3Double espduLocation = new Vector3Double(); + espduLocation.setX(1.0); + espduLocation.setY(2.0); + espduLocation.setZ(3.0); + espdu.setEntityLocation(espduLocation); + // it is important to identify questions as you think of them + // TODO how to set azimuth, i.e. course direction over ground? + break; + + case FIRE: // 2 + aPdu = new FirePdu(); + break; + + case DETONATION: // 3 + aPdu = new DetonationPdu(); + break; + + case COLLISION: // 4 + aPdu = new CollisionPdu(); + break; + + case SERVICE_REQUEST: // 5 + aPdu = new ServiceRequestPdu(); + break; + + case RESUPPLY_OFFER: // 6 + aPdu = new ResupplyOfferPdu(); + break; + + case RESUPPLY_RECEIVED: // 7 + aPdu = new ResupplyReceivedPdu(); + break; + + case RESUPPLY_CANCEL: //8 + aPdu = new ResupplyCancelPdu(); + break; + + case REPAIR_COMPLETE: // 9 + aPdu = new RepairCompletePdu(); + break; + + case REPAIR_RESPONSE: // 10 + aPdu = new RepairResponsePdu(); + break; + + case CREATE_ENTITY: // 11 + aPdu = new CreateEntityPdu(); + break; + + case REMOVE_ENTITY: // 12 + aPdu = new RemoveEntityPdu(); + break; + + case START_RESUME: // 13 + aPdu = new StartResumePdu(); + break; + + case STOP_FREEZE: // 14 + aPdu = new StopFreezePdu(); + break; + + case ACKNOWLEDGE: // 15 + aPdu = new AcknowledgePdu(); + break; + + case ACTION_REQUEST: // 16 + aPdu = new ActionRequestPdu(); + break; + + case ACTION_RESPONSE: // 17 + aPdu = new ActionResponsePdu(); + break; + + case DATA_QUERY: // 18 + aPdu = new DataQueryPdu(); + break; + + case SET_DATA: // 19 + aPdu = new SetDataPdu(); + break; + + case DATA: // 20 + aPdu = new DataPdu(); + break; + + case EVENT_REPORT: // 21 + aPdu = new EventReportPdu(); + break; + + case ELECTROMAGNETIC_EMISSION: // 23 + aPdu = new ElectromagneticEmissionPdu(); + break; + + case DESIGNATOR: // 24 + aPdu = new DesignatorPdu(); + break; + + case TRANSMITTER: // 25 + aPdu = new TransmitterPdu(); + break; + + case SIGNAL: // 26 + aPdu = new SignalPdu(); + break; + + case RECEIVER: // 27 + aPdu = new ReceiverPdu(); + break; + + case IDENTIFICATION_FRIEND_OR_FOE: // 28 + aPdu = new IdentificationFriendOrFoePdu(); + break; + + case UNDERWATER_ACOUSTIC: // 29 + aPdu = new UnderwaterAcousticPdu(); + break; + + case SUPPLEMENTAL_EMISSION_ENTITY_STATE: // 30 + aPdu = new SupplementalEmissionEntityStatePdu(); + break; + + case INTERCOM_SIGNAL: // 31 + aPdu = new IntercomSignalPdu(); + break; + + case INTERCOM_CONTROL: // 32 + aPdu = new IntercomControlPdu(); + break; + + case AGGREGATE_STATE: // 33 + aPdu = new AggregateStatePdu(); + break; + + case ISGROUPOF: // 34 + aPdu = new IsGroupOfPdu(); + break; + + case TRANSFER_OWNERSHIP: // 35 + aPdu = new TransferOwnershipPdu(); + break; + + case ISPARTOF: // 36 + aPdu = new IsPartOfPdu(); + break; + + case MINEFIELD_STATE: // 37 + aPdu = new MinefieldStatePdu(); + break; + + case MINEFIELD_QUERY: // 38 + aPdu = new MinefieldQueryPdu(); + break; + + case MINEFIELD_DATA: // 39 + aPdu = new MinefieldDataPdu(); + break; + + case MINEFIELD_RESPONSE_NACK: // 40 + aPdu = new MinefieldResponseNACKPdu(); + break; + + case ENVIRONMENTAL_PROCESS: // 41 + aPdu = new EnvironmentalProcessPdu(); + break; + + case GRIDDED_DATA: // 42 + aPdu = new GriddedDataPdu(); + break; + + case POINT_OBJECT_STATE: // 43 + aPdu = new PointObjectStatePdu(); + break; + + case LINEAR_OBJECT_STATE: // 44 + aPdu = new LinearObjectStatePdu(); + break; + + case AREAL_OBJECT_STATE: // 45 + aPdu = new ArealObjectStatePdu(); + break; + + case TIME_SPACE_POSITION_INFORMATION: // 46 + aPdu = new TimeSpacePositionInformationPdu(); + break; + + case APPEARANCE: // 47 + aPdu = new AppearancePdu(); + break; + + case ARTICULATED_PARTS: // 48 + aPdu = new ArticulatedPartsPdu(); + break; + + case LIVE_ENTITY_FIRE: // 49 + aPdu = new LiveEntityFirePdu(); + break; + + case LIVE_ENTITY_DETONATION: // 50 + aPdu = new LiveEntityDetonationPdu(); + break; + + case CREATE_ENTITY_RELIABLE: // 51 + aPdu = new CreateEntityReliablePdu(); + break; + + case REMOVE_ENTITY_RELIABLE: // 52 + aPdu = new RemoveEntityReliablePdu(); + break; + + case START_RESUME_RELIABLE: // 53 + aPdu = new StartResumeReliablePdu(); + break; + + case STOP_FREEZE_RELIABLE: // 54 + aPdu = new StopFreezeReliablePdu(); + break; + + case ACKNOWLEDGE_RELIABLE: // 55 + aPdu = new AcknowledgeReliablePdu(); + break; + + case ACTION_REQUEST_RELIABLE: // 56 + aPdu = new ActionRequestReliablePdu(); + break; + + case ACTION_RESPONSE_RELIABLE: // 57 + aPdu = new ActionResponseReliablePdu(); + break; + + case DATA_QUERY_RELIABLE: // 58 + aPdu = new DataQueryReliablePdu(); + break; + + case SET_DATA_RELIABLE: // 59 + aPdu = new SetDataReliablePdu(); + break; + + case DATA_RELIABLE: // 60 + aPdu = new DataReliablePdu(); + break; + + case EVENT_REPORT_RELIABLE: // 61 + aPdu = new EventReportReliablePdu(); + break; + + case COMMENT_RELIABLE: // 62 + aPdu = new CommentReliablePdu(); + break; + + case RECORD_RELIABLE: // 63 + aPdu = new RecordReliablePdu(); + break; + + case SET_RECORD_RELIABLE: // 64 + aPdu = new SetRecordReliablePdu(); + break; + + case RECORD_QUERY_RELIABLE: // 65 + aPdu = new RecordQueryReliablePdu(); + break; + + case COLLISION_ELASTIC: // 66 + aPdu = new CollisionElasticPdu(); + break; + + case ENTITY_STATE_UPDATE: // 67 + aPdu = new EntityStateUpdatePdu(); + break; + + case DIRECTED_ENERGY_FIRE: // 68 + aPdu = new DirectedEnergyFirePdu(); + break; + + case ENTITY_DAMAGE_STATUS: // 69 + aPdu = new EntityDamageStatusPdu(); + break; + + case INFORMATION_OPERATIONS_ACTION: // 70 + aPdu = new InformationOperationsActionPdu(); + break; + + case INFORMATION_OPERATIONS_REPORT: // 71 + aPdu = new InformationOperationsReportPdu(); + break; + + case ATTRIBUTE: // 72 + aPdu = new AttributePdu(); + break; + + case COMMENT: + // aPdu = new CommentPdu(); // default for this switch logic + + // see Garrett Loffelman and Pete Severson's code for OpenDis version 4 example + // https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/tree/master/assignments/src/MV3500Cohort2018JulySeptember/projects/LoeffelmanSeverson + + CommentPdu newCommentPdu = new CommentPdu(); + ArrayList<VariableDatum> payloadList = new ArrayList<>(); + ArrayList<String> commentsList = new ArrayList<>(); + commentsList.add("Hello CommentPDU"); + commentsList.add("Here is a second line of text in this comment."); + if (!commentsList.isEmpty()) + System.out.println("Preparing CommentPDU:"); + + for (String comment : commentsList) + { + VariableDatum newVariableDatum = new VariableDatum(); + newVariableDatum.setVariableDatumValue (comment.getBytes()); // conversion + // TODO confirm whether method overloading is appropriate +// newVariableDatum.setVariableDatumLength(comment.getBytes().length); + newVariableDatum.setVariableDatumLengthInBytes(comment.getBytes().length); // also available in bits, see spec and javadoc + // alternatively, you do not need to set this and the marshaller will figure it out from the byte array + // (see javadoc for VariableDatum.setVariableDatumLength()) + payloadList.add(newVariableDatum); + System.out.println(" \"" + comment + "\""); + } + newCommentPdu.setVariableDatums(payloadList); + + aPdu = newCommentPdu; // hand off for sending + break; + + default: + System.out.println("*** Warning: PDU " + pduTypeValue.getValue() + " " + pduTypeValue + " not supported, created or sent "); + + // code generation block for this class follows: + // System.out.println(" case " + pdu + ": // " + pdu.getValue()); + // System.out.println(" aPdu = new " + pdu.getDescription().replace(" ","").replace("-","").replace("/","") + + // "Pdu();"); + // System.out.println(" break;"); + // System.out.println(); + } + if (aPdu != null) + { + // leave aPdu timestamp at default value for consistency of output unit tests + generatedPdusList.add(aPdu); + } + } + catch (Exception e) + { + System.out.print("Exception thrown for PDU " + pduTypeValue.getValue() + " " + pduTypeValue); + System.out.print(Arrays.toString(e.getStackTrace())); + // continue looping + } + } + if (generatedPdusList.size() != 72) // TODO create an enumeration DISType.TOTAL_PDU_TYPES + System.out.println("Error: " + generatedPdusList.size() + " PDUs generated, but 72 PDUs expected."); + + // Send the PDUs we created + System.out.println("Send the " + generatedPdusList.size() + " PDUs we created..."); + + // ======================================================================= + // prior appproach +// InetAddress localMulticastAddress = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); +// MulticastSocket multicastSocket = new MulticastSocket(DEFAULT_MULTICAST_PORT); +// if (!localMulticastAddress.isMulticastAddress()) +// { +// throw new RuntimeException("*** Error: sending to multicast address, but destination address " + localMulticastAddress.toString() + "is not multicast"); +// } +// multicastSocket.joinGroup(localMulticastAddress); // deprecated + // ======================================================================= + // updated approach using NetworkInterface + NetworkInterface networkInterface = NetworkInterface.getByInetAddress(multicastInetAddress); + if (networkInterface != null) + System.out.println("networkInterface=" + networkInterface.getDisplayName()); // typically null if loopback + SocketAddress localMulticastSocketAddress = new InetSocketAddress(multicastInetAddress, DEFAULT_MULTICAST_PORT); + MulticastSocket multicastSocket = new MulticastSocket(DEFAULT_MULTICAST_PORT); + multicastSocket.joinGroup(localMulticastSocketAddress, networkInterface); + // ======================================================================= + + byte[] buffer; + Pdu aPdu; + DatagramPacket packet; + + for (int idx = 0; idx < generatedPdusList.size(); idx++) + { + // careful here! keep object instantiations inside of loop to avoid endless array and packet growth + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + + aPdu = generatedPdusList.get(idx); + try + { + aPdu.marshal(dos); // dos is DataOutputStream connected to ByteArrayOutputStrea + + buffer = baos.toByteArray(); + packet = new DatagramPacket(buffer, buffer.length, multicastInetAddress, DEFAULT_MULTICAST_PORT); + multicastSocket.send(packet); + + DisPduType disPduType= aPdu.getPduType(); +// disPduType.setTRACE(true); + String currentIndexPadded = String.format("%2s", (idx + 1)); + String currentPduTypeValuePadded = String.format("%2s", disPduType.getValue()); + String currentPduTypePadded = String.format("%-49s", aPdu.getPduType().toString()); // - indicates right padding of whitespace + String packetLengthPadded = String.format("%3s", packet.getLength()); + + System.out.println ("Sent packet #" + currentIndexPadded + ", " + +// currentPduTypeValuePadded + " " + + currentPduTypePadded + + "(packet.getLength()=" + packetLengthPadded + ")" + // diagnostic, beware of ever-growing packet size! + " of type " + aPdu.getClass().getSimpleName()); + + Thread.sleep(THREAD_SLEEP_INTERVAL); // pause for debugging, if zero this process still yields + } + catch (Exception ex) { + System.out.println("Marshaling error" + ex); + } + } + } + catch (IOException e) + { + System.out.println(e); + return -1; // error condition + } + } // end repetion loop + + // TODO write the PDUs out to an XML file. + //PduContainer container = new PduContainer(); + //container.setPdus(generatedPdus); + //container.marshallToXml("examplePdus.xml"); + return generatedPdusList.size(); + } + + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String args[]) + { + AllPduSender allPduSender; + int totalSentPdus; + + if (args.length == 2) + { + System.out.println("Usage: AllPduSender <multicast group> <port>"); + System.out.println("Actual: AllPduSender " + multicastInetAddress.getHostAddress() + " " + port); + allPduSender = new AllPduSender(args[0], Integer.parseInt(args[1])); + } + else + { + System.out.println("Usage: AllPduSender <multicast group> <port>"); + System.out.println("Default: AllPduSender " + DEFAULT_MULTICAST_ADDRESS + " " + DEFAULT_MULTICAST_PORT); + allPduSender = new AllPduSender(DEFAULT_MULTICAST_ADDRESS, DEFAULT_MULTICAST_PORT); + } + totalSentPdus = allPduSender.run(); // do it to it + System.out.println("OpenDis7Examples.AllPduSender complete, sent " + totalSentPdus + " PDUs total."); + } +} diff --git a/assignments/src/src/OpenDis7Examples/AllPduSenderLog.txt b/assignments/src/src/OpenDis7Examples/AllPduSenderLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..d4859b8653fed4b92eeb1cc0af6d23f201fcc2dc --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/AllPduSenderLog.txt @@ -0,0 +1,93 @@ +ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/AllPduSender.java -Drun.class=OpenDis7Examples.AllPduSender 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 +warning: [options] system modules path not set in conjunction with -source 17 +1 warning +compile-single: +run-single: +Usage: AllPduSender <multicast group> <port> +Default: AllPduSender 239.1.2.3 3000 +OpenDis7Examples.AllPduSender started... +Generate list of all PDU types and note issues, if any... +*** Note: DisPduType.OTHER=0 not supported +Preparing CommentPDU: + "Hello CommentPDU" + "Here is a second line of text in this comment." +Send the 72 PDUs we created... +Sent packet # 1, DisPduType 01 ENTITY_STATE (packet.getLength()=144) of type EntityStatePdu +Sent packet # 2, DisPduType 02 FIRE (packet.getLength()= 96) of type FirePdu +Sent packet # 3, DisPduType 03 DETONATION (packet.getLength()=104) of type DetonationPdu +Sent packet # 4, DisPduType 04 COLLISION (packet.getLength()= 60) of type CollisionPdu +Sent packet # 5, DisPduType 05 SERVICE_REQUEST (packet.getLength()= 28) of type ServiceRequestPdu +Sent packet # 6, DisPduType 06 RESUPPLY_OFFER (packet.getLength()= 28) of type ResupplyOfferPdu +Sent packet # 7, DisPduType 07 RESUPPLY_RECEIVED (packet.getLength()= 28) of type ResupplyReceivedPdu +Sent packet # 8, DisPduType 08 RESUPPLY_CANCEL (packet.getLength()= 24) of type ResupplyCancelPdu +Sent packet # 9, DisPduType 09 REPAIR_COMPLETE (packet.getLength()= 28) of type RepairCompletePdu +Sent packet #10, DisPduType 10 REPAIR_RESPONSE (packet.getLength()= 28) of type RepairResponsePdu +Sent packet #11, DisPduType 11 CREATE_ENTITY (packet.getLength()= 28) of type CreateEntityPdu +Sent packet #12, DisPduType 12 REMOVE_ENTITY (packet.getLength()= 28) of type RemoveEntityPdu +Sent packet #13, DisPduType 13 START_RESUME (packet.getLength()= 44) of type StartResumePdu +Sent packet #14, DisPduType 14 STOP_FREEZE (packet.getLength()= 40) of type StopFreezePdu +Sent packet #15, DisPduType 15 ACKNOWLEDGE (packet.getLength()= 32) of type AcknowledgePdu +Sent packet #16, DisPduType 16 ACTION_REQUEST (packet.getLength()= 40) of type ActionRequestPdu +Sent packet #17, DisPduType 17 ACTION_RESPONSE (packet.getLength()= 40) of type ActionResponsePdu +Sent packet #18, DisPduType 18 DATA_QUERY (packet.getLength()= 40) of type DataQueryPdu +Sent packet #19, DisPduType 19 SET_DATA (packet.getLength()= 40) of type SetDataPdu +Sent packet #20, DisPduType 20 DATA (packet.getLength()= 40) of type DataPdu +Sent packet #21, DisPduType 21 EVENT_REPORT (packet.getLength()= 40) of type EventReportPdu +Sent packet #22, DisPduType 22 COMMENT (packet.getLength()=112) of type CommentPdu +Sent packet #23, DisPduType 23 ELECTROMAGNETIC_EMISSION (packet.getLength()= 28) of type ElectromagneticEmissionPdu +Sent packet #24, DisPduType 24 DESIGNATOR (packet.getLength()= 88) of type DesignatorPdu +Sent packet #25, DisPduType 25 TRANSMITTER (packet.getLength()=104) of type TransmitterPdu +Sent packet #26, DisPduType 26 SIGNAL (packet.getLength()= 36) of type SignalPdu +Sent packet #27, DisPduType 27 RECEIVER (packet.getLength()= 36) of type ReceiverPdu +Sent packet #28, DisPduType 28 IDENTIFICATION_FRIEND_OR_FOE (packet.getLength()= 60) of type IdentificationFriendOrFoePdu +Sent packet #29, DisPduType 29 UNDERWATER_ACOUSTIC (packet.getLength()= 32) of type UnderwaterAcousticPdu +Sent packet #30, DisPduType 30 SUPPLEMENTAL_EMISSION_ENTITY_STATE (packet.getLength()= 28) of type SupplementalEmissionEntityStatePdu +Sent packet #31, DisPduType 31 INTERCOM_SIGNAL (packet.getLength()= 36) of type IntercomSignalPdu +Sent packet #32, DisPduType 32 INTERCOM_CONTROL (packet.getLength()= 40) of type IntercomControlPdu +Sent packet #33, DisPduType 33 AGGREGATE_STATE (packet.getLength()=136) of type AggregateStatePdu +Sent packet #34, DisPduType 34 ISGROUPOF (packet.getLength()= 40) of type IsGroupOfPdu +Sent packet #35, DisPduType 35 TRANSFER_OWNERSHIP (packet.getLength()= 40) of type TransferOwnershipPdu +Sent packet #36, DisPduType 36 ISPARTOF (packet.getLength()= 52) of type IsPartOfPdu +Sent packet #37, DisPduType 37 MINEFIELD_STATE (packet.getLength()= 72) of type MinefieldStatePdu +Sent packet #38, DisPduType 38 MINEFIELD_QUERY (packet.getLength()= 40) of type MinefieldQueryPdu +Sent packet #39, DisPduType 39 MINEFIELD_DATA (packet.getLength()= 44) of type MinefieldDataPdu +Sent packet #40, DisPduType 40 MINEFIELD_RESPONSE_NACK (packet.getLength()= 26) of type MinefieldResponseNACKPdu +Sent packet #41, DisPduType 41 ENVIRONMENTAL_PROCESS (packet.getLength()= 32) of type EnvironmentalProcessPdu +Sent packet #42, DisPduType 42 GRIDDED_DATA (packet.getLength()= 64) of type GriddedDataPdu +Sent packet #43, DisPduType 43 POINT_OBJECT_STATE (packet.getLength()= 91) of type PointObjectStatePdu +Sent packet #44, DisPduType 44 LINEAR_OBJECT_STATE (packet.getLength()= 40) of type LinearObjectStatePdu +Sent packet #45, DisPduType 45 AREAL_OBJECT_STATE (packet.getLength()= 49) of type ArealObjectStatePdu +Sent packet #46, DisPduType 46 TIME_SPACE_POSITION_INFORMATION (packet.getLength()= 54) of type TimeSpacePositionInformationPdu +Sent packet #47, DisPduType 47 APPEARANCE (packet.getLength()= 67) of type AppearancePdu +Sent packet #48, DisPduType 48 ARTICULATED_PARTS (packet.getLength()= 17) of type ArticulatedPartsPdu +Sent packet #49, DisPduType 49 LIVE_ENTITY_FIRE (packet.getLength()= 67) of type LiveEntityFirePdu +Sent packet #50, DisPduType 50 LIVE_ENTITY_DETONATION (packet.getLength()= 79) of type LiveEntityDetonationPdu +Sent packet #51, DisPduType 51 CREATE_ENTITY_RELIABLE (packet.getLength()= 32) of type CreateEntityReliablePdu +Sent packet #52, DisPduType 52 REMOVE_ENTITY_RELIABLE (packet.getLength()= 32) of type RemoveEntityReliablePdu +Sent packet #53, DisPduType 53 START_RESUME_RELIABLE (packet.getLength()= 48) of type StartResumeReliablePdu +Sent packet #54, DisPduType 54 STOP_FREEZE_RELIABLE (packet.getLength()= 40) of type StopFreezeReliablePdu +Sent packet #55, DisPduType 55 ACKNOWLEDGE_RELIABLE (packet.getLength()= 32) of type AcknowledgeReliablePdu +Sent packet #56, DisPduType 56 ACTION_REQUEST_RELIABLE (packet.getLength()= 44) of type ActionRequestReliablePdu +Sent packet #57, DisPduType 57 ACTION_RESPONSE_RELIABLE (packet.getLength()= 40) of type ActionResponseReliablePdu +Sent packet #58, DisPduType 58 DATA_QUERY_RELIABLE (packet.getLength()= 44) of type DataQueryReliablePdu +Sent packet #59, DisPduType 59 SET_DATA_RELIABLE (packet.getLength()= 40) of type SetDataReliablePdu +Sent packet #60, DisPduType 60 DATA_RELIABLE (packet.getLength()= 40) of type DataReliablePdu +Sent packet #61, DisPduType 61 EVENT_REPORT_RELIABLE (packet.getLength()= 40) of type EventReportReliablePdu +Sent packet #62, DisPduType 62 COMMENT_RELIABLE (packet.getLength()= 32) of type CommentReliablePdu +Sent packet #63, DisPduType 63 RECORD_RELIABLE (packet.getLength()= 36) of type RecordReliablePdu +Sent packet #64, DisPduType 64 SET_RECORD_RELIABLE (packet.getLength()= 40) of type SetRecordReliablePdu +Sent packet #65, DisPduType 65 RECORD_QUERY_RELIABLE (packet.getLength()= 40) of type RecordQueryReliablePdu +Sent packet #66, DisPduType 66 COLLISION_ELASTIC (packet.getLength()=100) of type CollisionElasticPdu +Sent packet #67, DisPduType 67 ENTITY_STATE_UPDATE (packet.getLength()= 72) of type EntityStateUpdatePdu +Sent packet #68, DisPduType 68 DIRECTED_ENERGY_FIRE (packet.getLength()= 88) of type DirectedEnergyFirePdu +Sent packet #69, DisPduType 69 ENTITY_DAMAGE_STATUS (packet.getLength()= 24) of type EntityDamageStatusPdu +Sent packet #70, DisPduType 70 INFORMATION_OPERATIONS_ACTION (packet.getLength()= 56) of type InformationOperationsActionPdu +Sent packet #71, DisPduType 71 INFORMATION_OPERATIONS_REPORT (packet.getLength()= 40) of type InformationOperationsReportPdu +Sent packet #72, DisPduType 72 ATTRIBUTE (packet.getLength()= 32) of type AttributePdu +OpenDis7Examples.AllPduSender complete, sent 72 PDUs total. +BUILD SUCCESSFUL (total time: 3 seconds) diff --git a/assignments/src/src/OpenDis7Examples/AllPduSenderWireshark.png b/assignments/src/src/OpenDis7Examples/AllPduSenderWireshark.png new file mode 100644 index 0000000000000000000000000000000000000000..41308ac879a6c4820e7221193006d47f724811fc Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/AllPduSenderWireshark.png differ diff --git a/assignments/src/src/OpenDis7Examples/AllPduSenderWiresharkCapture.pcapng b/assignments/src/src/OpenDis7Examples/AllPduSenderWiresharkCapture.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..9f19fb108d4950d9fc61b86d0704754c31784adc Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/AllPduSenderWiresharkCapture.pcapng differ diff --git a/assignments/src/src/OpenDis7Examples/EspduReceiver.java b/assignments/src/src/OpenDis7Examples/EspduReceiver.java new file mode 100755 index 0000000000000000000000000000000000000000..809f88a1f485432f81c004f387cf6e7c03cf4c0b --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/EspduReceiver.java @@ -0,0 +1,118 @@ +package OpenDis7Examples; + +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; +import java.io.*; +import java.net.*; +import java.util.*; + +/** + * Receives PDUs from the network in IEEE DIS format. + * Adapted from OpenDIS library example package edu.nps.moves.examples + * + * @author DMcG + * @version $Id:$ + */ +public class EspduReceiver +{ + /** Default constructor */ + public EspduReceiver() + { + // default constructor + } + /** Max size of a PDU in binary format that we can receive. This is actually + * somewhat outdated--PDUs can be larger--but this is a reasonable starting point. + */ + private static final int MAX_PDU_SIZE = 8192; + + /** Default multicast group address we send on. + * @see <a href="https://en.wikipedia.org/wiki/Multicast_address" target="_blank">https://en.wikipedia.org/wiki/Multicast_address</a> */ + public static final String DEFAULT_MULTICAST_ADDRESS = EspduSender.DEFAULT_MULTICAST_ADDRESS; + + /** Default multicast port used, matches Wireshark DIS capture default + * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)" target="_blank">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> */ + public static final int DEFAULT_MULTICAST_PORT = EspduSender.DEFAULT_MULTICAST_PORT; + + /** Output prefix to identify this class */ + private final static String TRACE_PREFIX = "[" + EspduReceiver.class.getName() + "] "; + + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String args[]) + { + MulticastSocket multicastSocket; + InetAddress multicastInetAddress; + DatagramPacket packet; + PduFactory pduFactory = new PduFactory(); + DisTime.TimestampStyle timestampStyle = DisTime.TimestampStyle.IEEE_ABSOLUTE; + DisTime.setTimestampStyle(timestampStyle); + int pduCount = 0; + + System.out.println(TRACE_PREFIX + "started..."); + + try { + // Specify the socket to receive data + multicastSocket = new MulticastSocket(DEFAULT_MULTICAST_PORT); +// socket.setBroadcast(true); + + multicastInetAddress = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); +// socket.joinGroup(address); // deprecated + // ======================================================================= + // new approach using interface + NetworkInterface networkInterface = NetworkInterface.getByInetAddress(multicastInetAddress); + SocketAddress localMulticastSocketAddress = new InetSocketAddress(multicastInetAddress, DEFAULT_MULTICAST_PORT); + multicastSocket.joinGroup(localMulticastSocketAddress, networkInterface); + // ======================================================================= + + System.out.println(TRACE_PREFIX + "listening for PDU packets on " + multicastInetAddress.getHostAddress() + " port " + DEFAULT_MULTICAST_PORT); + System.out.println("To quit: stop or kill this process"); + System.out.println("==============="); + + while (true) // Loop infinitely, receiving datagrams + { + byte buffer[] = new byte[MAX_PDU_SIZE]; + packet = new DatagramPacket(buffer, buffer.length); // reset packet each time + + multicastSocket.receive(packet); // process blocks here until receipt of network packet with PDU + + List<Pdu> pduBundle = pduFactory.getPdusFromBundle(packet.getData(),packet.getLength()); + if (pduBundle.size() > 1) + System.out.println("Received PDU bundle size is " + pduBundle.size()); + + for (Pdu nextPdu : pduBundle) // iterator loop through PDU bundle + { + pduCount++; + String receiptMessage = String.format("%3s", pduCount) // right justify, 3 characters + + ". received PDU type " + nextPdu.getPduType().getValue() + "=" + nextPdu.getPduType().name() + " " + nextPdu.getClass().getSimpleName(); + if (nextPdu instanceof EntityStatePdu) + { + System.out.println(receiptMessage); + EntityID entityID = ((EntityStatePdu)nextPdu).getEntityID(); + Vector3Double position = ((EntityStatePdu)nextPdu).getEntityLocation(); + System.out.println(" entityID triplet: [" + entityID.getSiteID()+ ", " + entityID.getApplicationID()+ ", " + entityID.getEntityID()+ "] "); + System.out.println(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); + } + else if (nextPdu instanceof FirePdu) + { + System.out.println(receiptMessage); + Vector3Double position = ((FirePdu)nextPdu).getLocationInWorldCoordinates(); + System.out.println(" FirePdu locationInWorldCoordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); + System.out.println("==============="); + } + else + { + System.out.println(receiptMessage); + } + } // end of bundle loop + } // end of while loop + } // end try block + catch (IOException ioe) + { + System.out.println(TRACE_PREFIX + "Problem with input/output, see exception trace:"); + System.out.println(ioe); + } + System.out.println(TRACE_PREFIX + "complete."); + } // end main +} // end class diff --git a/assignments/src/src/OpenDis7Examples/EspduReceiverLog.txt b/assignments/src/src/OpenDis7Examples/EspduReceiverLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..f1c451e9b593beba0715cbedf10d48f7b9e64f6a --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/EspduReceiverLog.txt @@ -0,0 +1,74 @@ +ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/EspduReceiver.java -Drun.class=OpenDis7Examples.EspduReceiver 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 +warning: [options] system modules path not set in conjunction with -source 17 +1 warning +compile-single: +run-single: +[OpenDis7Examples.EspduReceiver] started... +[OpenDis7Examples.EspduReceiver] listening for PDU packets on 239.1.2.3 port 3000 +To quit: stop or kill this process +=============== + 1. received PDU type 1=ENTITY_STATE EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 2. received PDU type 2=FIRE FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== + 3. received PDU type 1=ENTITY_STATE EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 4. received PDU type 2=FIRE FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== + 5. received PDU type 1=ENTITY_STATE EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] + 6. received PDU type 2=FIRE FirePdu + FirePdu locationInWorldCoordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +=============== + 7. received PDU type 1=ENTITY_STATE EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] + 8. received PDU type 2=FIRE FirePdu + FirePdu locationInWorldCoordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +=============== + 9. received PDU type 1=ENTITY_STATE EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 10. received PDU type 2=FIRE FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== + 11. received PDU type 1=ENTITY_STATE EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 12. received PDU type 2=FIRE FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== + 13. received PDU type 1=ENTITY_STATE EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] + 14. received PDU type 2=FIRE FirePdu + FirePdu locationInWorldCoordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +=============== + 15. received PDU type 1=ENTITY_STATE EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] + 16. received PDU type 2=FIRE FirePdu + FirePdu locationInWorldCoordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +=============== + 17. received PDU type 1=ENTITY_STATE EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 18. received PDU type 2=FIRE FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== + 19. received PDU type 1=ENTITY_STATE EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 20. received PDU type 2=FIRE FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== diff --git a/assignments/src/src/OpenDis7Examples/EspduSender.java b/assignments/src/src/OpenDis7Examples/EspduSender.java new file mode 100644 index 0000000000000000000000000000000000000000..96862776150dd18d7595caac03a51f0ed7d9e94f --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/EspduSender.java @@ -0,0 +1,435 @@ +package OpenDis7Examples; + +import edu.nps.moves.dis7.entities.usa.platform.land.M1A2; +import edu.nps.moves.dis7.enumerations.Country; +import edu.nps.moves.dis7.enumerations.EntityKind; +import edu.nps.moves.dis7.enumerations.PlatformDomain; +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; +import java.io.*; +import java.net.*; +import java.util.*; + +/** + * Creates and sends ESPDUs in IEEE binary format. Adapted from OpenDIS library + * example package edu.nps.moves.examples + * + * @author Don McGregor + * @author Don Brutzman + */ +public class EspduSender +{ + /** Default constructor */ + public EspduSender() + { + // default constructor + } + /** + * Number of complete loops to perform. + * Putting any upper limit on # packets sent avoids possibility of non-terminating infinite loops that continue sending packets. */ + public static final int SEND_LOOPS_TO_PERFORM = 5; // 5 + + /** + * Default multicast group address we send on. + * @see <a href="https://en.wikipedia.org/wiki/Multicast_address" target="_blank">https://en.wikipedia.org/wiki/Multicast_address</a> */ + public static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3"; + + /** + * Default multicast port used, matches Wireshark DIS capture default + * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)" target="_blank">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> */ + public static final int DEFAULT_MULTICAST_PORT = 3000; + + /** Type of network connection: + * Point to point <a href="https://en.wikipedia.org/wiki/Unicast" target="_blank">UNICAST</a>, + * Many to many <a href="https://en.wikipedia.org/wiki/Multicast" target="_blank">MULTICAST</a>, or + * (rarely used, potentially harmful) <a href="https://en.wikipedia.org/wiki/Broadcasting_(networking)" target="_blank">BROADCAST</a> + */ + public enum NetworkMode { + /** Point to point @see <a href="https://en.wikipedia.org/wiki/Unicast" target="_blank">https://en.wikipedia.org/wiki/Unicast</a> */ + UNICAST, + /** Many to many @see <a href="https://en.wikipedia.org/wiki/Multicast" target="_blank">https://en.wikipedia.org/wiki/Multicast</a> */ + MULTICAST, + /** (rarely used, potentially harmful) @see <a href="https://en.wikipedia.org/wiki/Broadcasting_(networking)" target="_blank">https://en.wikipedia.org/wiki/Broadcasting_(networking)</a> */ + BROADCAST + }; + + /** + * Output prefix to identify this class, helps with logging + */ + private final static String TRACE_PREFIX = "[" + EspduSender.class.getName() + "] "; + + /** + * Possible system properties, passed in via -Dattr=val networkMode: + * unicast, broadcast, multicast destinationIp: where to send the packet. If + * in multicast mode, this can be multicast. To determine broadcast + * destination IP, use an online broadcast address calculator, for example + * http://www.remotemonitoringsystems.ca/broadcast.php If in multicast mode, + * a join() will be done on the multicast address. port: port used for both + * source and destination. + * + * @param args command-line arguments + */ + @SuppressWarnings("SleepWhileInLoop") // allows Thread.sleep(value) without warning in code + public static void main(String args[]) + { + System.out.println(TRACE_PREFIX + " started..."); + + // Default settings. These are used if no system properties are set. + // If system properties are passed in, these are overridden later. + NetworkMode networkMode = NetworkMode.MULTICAST; + InetAddress multicastInetAddress = null; // must be initialized, even if null + int port = DEFAULT_MULTICAST_PORT; + MulticastSocket socket = null; // must be initialized to avoid later error, even if null; + EntityStatePdu espdu = new EntityStatePdu(); +// DisTime disTime = new DisTime(); + + // ICBM coordinates for my office + double latitude = 36.595517; + double longitude = -121.877000; + try + { + multicastInetAddress = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); + } + catch (UnknownHostException e) + { + System.out.println(TRACE_PREFIX + e + " Cannot create multicast address"); + System.exit(0); + } + + // All system properties, passed in on the command line via -Dattribute=value + Properties systemProperties = System.getProperties(); + + // IP address we send to + String destinationIpString = systemProperties.getProperty("destinationIp"); + + // Port we send to, and local port we open the socket on + String portString = systemProperties.getProperty("port"); + + // Network mode: unicast, multicast, broadcast + String networkModeString = systemProperties.getProperty("networkMode"); // unicast or multicast or broadcast + + // Set up socket to send information + try + { + if (portString != null) // Update port we send to, if provided + { + port = Integer.parseInt(portString); + } + socket = new MulticastSocket(port); + + // Where we send packets to, the destination IP address + if (destinationIpString != null) + { + multicastInetAddress = InetAddress.getByName(destinationIpString); + } + + // Type of transport: unicast, broadcast, or multicast + if (networkModeString != null) + { + if (networkModeString.equalsIgnoreCase("unicast")) + { + networkMode = NetworkMode.UNICAST; + } + else if (networkModeString.equalsIgnoreCase("broadcast")) + { + networkMode = NetworkMode.BROADCAST; + } + else if (networkModeString.equalsIgnoreCase("multicast")) + { + networkMode = NetworkMode.MULTICAST; + if (!multicastInetAddress.isMulticastAddress()) + { + throw new RuntimeException("*** Error: sending to multicast address, but destination address " + multicastInetAddress.toString() + "is not multicast"); + } +// socket.joinGroup(multicastInetAddress); // deprecated, TODO select correct NetworkInterface + // ======================================================================= + // updated approach using NetworkInterface + NetworkInterface networkInterface = NetworkInterface.getByInetAddress(multicastInetAddress); + if (networkInterface != null) + System.out.println("networkInterface=" + networkInterface.getDisplayName()); // typically null if loopback + SocketAddress localMulticastSocketAddress = new InetSocketAddress(multicastInetAddress, DEFAULT_MULTICAST_PORT); + MulticastSocket multicastSocket = new MulticastSocket(DEFAULT_MULTICAST_PORT); + multicastSocket.joinGroup(localMulticastSocketAddress, networkInterface); + // ======================================================================= + } + } // end networkModeString + else if (networkMode == NetworkMode.MULTICAST) + { + networkModeString = "multicast"; + } + else if (networkMode == NetworkMode.UNICAST) + { + networkModeString = "unicast"; + } + else if (networkMode == NetworkMode.BROADCAST) + { + networkModeString = "broadcast"; + } + } + catch (IOException | RuntimeException e) + { + System.out.println(TRACE_PREFIX + "Unable to initialize network correctly, exiting."); + System.out.println(e); + System.exit(-1); // outta here + } + System.out.println(TRACE_PREFIX + " sending " + networkModeString + " ESPDU packets to " + + multicastInetAddress.getHostAddress() + " port " + port); + + // Initialize values in the Entity State PDU object. The exercise ID is + // a way to differentiate between different virtual worlds on one network. + // Note that some values (such as the PDU type and PDU family) are set + // automatically when you create the ESPDU. + espdu.setExerciseID((byte)1); //(short) 1); + + // The EID is the unique identifier for objects in the world. This + // EID should match up with the ID for the object specified in the + // VMRL/x3d/virtual world. + + EntityID entityID = espdu.getEntityID(); // initialize, reset, override + // TODO check: 0 is apparently not a valid site number, per DIS specification + entityID.setSiteID ((short)1); // TODO utility method to allow int values + entityID.setApplicationID((short)2); + entityID.setEntityID ((short)3); + espdu.setEntityID(entityID); // TODO utility method to allow setting all three at once + + // Set the entity type. SISO has a big list of enumerations, so that by + // specifying various numbers we can say this is an M1A2 American tank, + // the USS Enterprise, and so on. We'll make this a tank. There is a + // separate project elsehwhere in this project that implements DIS + // enumerations in C++ and Java, but to keep things simple we just use + // numbers here. + + // Manual way to override platform information: + EntityType entityType = espdu.getEntityType() + .setEntityKind (EntityKind.PLATFORM).setEntityKind (EntityKind.PLATFORM) //(short) 1); // Platform (vs lifeform, munition, sensor, etc.); //(short) 1); // Platform (vs lifeform, munition, sensor, etc.) + .setCountry (Country.UNITED_STATES_OF_AMERICA_USA) // 225 USA + .setDomain (Domain.inst(PlatformDomain.LAND)) // Land (vs air, surface, subsurface, space) + .setCategory ((byte) 1) // Tank + .setSubCategory((byte) 1) // M1 Abrams + .setSpecific ((byte) 3); // M1A2 Abrams + + // New way using entity jar(s) + espdu.setEntityType(new edu.nps.moves.dis7.entities.usa.platform.land.M1A2()); + // or simply use an enumeration by name, with accompanying import statement at top of file + espdu.setEntityType(new M1A2()); + + // Inspecting an enumeration + System.out.println("==============="); + System.out.println("espdu entityType information:"); + System.out.println(" EntityKind =" + espdu.getEntityType().getEntityKind()); + System.out.println(" Country =" + espdu.getEntityType().getCountry()); + System.out.println(" Domain =" + espdu.getEntityType().getDomain()); + System.out.println(" Category =" + espdu.getEntityType().getCategory()); + System.out.println(" SubCategory=" + espdu.getEntityType().getSubCategory()); + System.out.println(" Specific =" + espdu.getEntityType().getCountry()); + // TODO round trip lookup + + Set<InetAddress> localNetworkAddresses; + + try // Loop through sending N ESPDUs + { + System.out.println(TRACE_PREFIX + "sending " + SEND_LOOPS_TO_PERFORM + " sets of packets:"); // + address.toString() + + for (int index = 1; index <= SEND_LOOPS_TO_PERFORM; index++) + { + // DIS time is a pain in the uh, neck. DIS time units are 2^31-1 units per + // hour, and time is set to DIS time units from the top of the hour. + // This means that if you start sending just before the top of the hour + // the time units can roll over to zero as you are sending. The receivers + // (escpecially homegrown ones) are often not able to detect rollover + // and may start discarding packets as dupes or out of order. We use + // an NPS timestamp here, hundredths of a second since the start of the + // year. The DIS standard for time is often ignored in the wild; I've seen + // people use Unix time (seconds since 1970) and more. Or you can + // just stuff idx into the timestamp field to get something that is monotonically + // increasing. + + // Note that timestamp is used to detect duplicate and out of order packets. + // That means if you DON'T change the timestamp, many implementations will simply + // discard subsequent packets that have an identical timestamp. Also, if they + // receive a PDU with an timestamp lower than the last one they received, they + // may discard it as an earlier, out-of-order PDU. So it is a good idea to + // update the timestamp on ALL packets sent. + // An alterative approach: actually follow the standard. It's a crazy concept, + // but it might just work. + int timestamp = DisTime.getCurrentDisTimestamp(); + espdu.setTimestamp(timestamp); + + // Set the position of the entity in the world. DIS uses a cartesian + // coordinate system with the origin at the center of the earth, the x + // axis out at the equator and prime meridian, y out at the equator and + // 90 deg east, and z up and out the north pole. To place an object on + // the earth's surface you also need a model for the shape of the earth + // (it's not a sphere.) All the fancy math necessary to do this is in + // the SEDRIS SRM package. There are also some one-off formulas for + // doing conversions from, for example, lat/lon/altitude to DIS coordinates. + // Here we use those one-off formulas. + // Modify the position of the object. This will send the object a little + // due east by adding some to the longitude every iteration. Since we + // are on the Pacific coast, this sends the object east. Assume we are + // at zero altitude. In other worlds you'd use DTED to determine the + // local ground altitude at that lat/lon, or you'd just use ground clamping. + // The x and y values will change, but the z value should not. + //lon = lon + (double)((double)idx / 100000.0); + //System.out.println("lla=" + lat + "," + lon + ", 0.0"); + double direction = Math.pow(-1.0, index); + longitude = longitude + (direction * 0.00006); + + double disCoordinates[] = CoordinateConversions.getXYZfromLatLonDegrees(latitude, longitude, 1.0); + Vector3Double location = espdu.getEntityLocation(); + location.setX(disCoordinates[0]); + location.setY(disCoordinates[1]); + location.setZ(disCoordinates[2]); + System.out.println("==============="); + System.out.println("Create new PDUs"); + System.out.println(" latitude, longitude: [" + latitude + ", " + longitude + "]"); + System.out.println(" coordinate conversion: [" + disCoordinates[0] + ", " + disCoordinates[1] + ", " + disCoordinates[2] + "]"); + + location = espdu.getEntityLocation(); + + System.out.println("Espdu #" + index + " entityID=[" + entityID.getSiteID()+ "," + entityID.getApplicationID()+ "," + entityID.getEntityID()+ "]"); + double c[] = {location.getX(), location.getY(), location.getZ()}; + double lla[] = CoordinateConversions.xyzToLatLonDegrees(c); +// System.out.println(" DIS entityLocation: [" + location.getX() + "," + location.getY() + "," + location.getZ() + "]"); + String debugString = " Location (latitude/longitude/altitude): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]"; +// System.out.println(debugString); + + // Optionally, we can do some rotation of the entity + /* + Orientation orientation = espdu.getEntityOrientation(); + float psi = orientation.getPsi(); + psi = psi + idx; + orientation.setPsi(psi); + orientation.setTheta((float)(orientation.getTheta() + idx /2.0)); + */ + // You can set other ESPDU values here, such as the velocity, acceleration, + // and so on. + // Marshal out the espdu object to a byte array, then send a datagram + // packet with that data in it. + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + DatagramPacket packet; + + // The byte array here is the packet in DIS format. We put that into a + // datagram and send it. + espdu.marshal(dos); + byte[] espduArray = baos.toByteArray(); + + FirePdu firePdu = new FirePdu(); + firePdu.setLocationInWorldCoordinates(espdu.getEntityLocation()); + byte[] fireArray = firePdu.marshal().array(); // can also use ByteBuffer + + System.out.println("FirePdu #" + index + " firePdu=[FireMissionIndex=" + firePdu.getFireMissionIndex() + ", descriptor=" + firePdu.getDescriptor()+ "]"); + +// CommentPdu newCommentPdu = new CommentPdu(); +// ArrayList<VariableDatum> payloadList = new ArrayList<>(); +// ArrayList<String> commentsList = new ArrayList<>(); +// commentsList.add("Hello CommentPDU"); +// commentsList.add("Here is a second line of text in this comment."); +// if (!commentsList.isEmpty()) +// System.out.println("Preparing CommentPDU:"); +// +// for (String comment : commentsList) +// { +// VariableDatum newVariableDatum = new VariableDatum(); +// newVariableDatum.setVariableDatumValue (comment.getBytes()); // conversion +// newVariableDatum.setVariableDatumLengthInBytes(comment.getBytes().length); // also available in bits, see spec and javadoc +// // alternatively, you do not need to set this and the marshaller will figure it out from the byte array +// // (see javadoc for VariableDatum.setVariableDatumLength()) +// payloadList.add(newVariableDatum); +// System.out.println(" \"" + comment + "\""); +// } +// newCommentPdu.setVariableDatums(payloadList); +// byte[] commentArray = newCommentPdu.marshal(); + + localNetworkAddresses = getBroadcastAddresses(); + for (InetAddress networkAddress : localNetworkAddresses) { + if (espduArray.length > 0) + { + packet = new DatagramPacket(espduArray, espduArray.length, networkAddress, port); + System.out.println(TRACE_PREFIX + "sending datagram packet [" + espdu.getPduType().toString() + "] " + + "packet.getLength()=" + packet.getLength() + ", " + // diagnostic, beware of ever-growing packet size + String.format("to %-15s", networkAddress.getHostAddress()) + " port " + port); + socket.send(packet); + } + // TODO experiment with these! 8) + if (fireArray.length > 0) + { + packet = new DatagramPacket(fireArray, fireArray.length, networkAddress, port); // alternate + System.out.println(TRACE_PREFIX + "sending datagram packet [" + firePdu.getPduType().toString() + " ] " + + "packet.getLength()= " + packet.getLength() + ", " + // diagnostic, beware of ever-growing packet size + String.format("to %-15s", networkAddress.getHostAddress()) + " port " + port); + socket.send(packet); + } +// // TODO experiment with these! 8) +// if (newCommentPdu != null) +// { +// System.out.println(TRACE_PREFIX + "sending datagram packet [" + newCommentPdu.getPduType().toString() + " ] to " + +// String.format("%-15s", networkAddress.getHostAddress()) + " port " + port); +// packet = new DatagramPacket(commentArray, commentArray.length, networkAddress, port); // alternate +// socket.send(packet); +// } + } + // Send every 1 second within loop. Otherwise all this will be all over in a fraction of a second. + Thread.sleep(1000); // msec + } + } + catch (Exception e) + { + System.out.println(TRACE_PREFIX + "Problem with " + e + ", see exception trace:"); + System.out.println(e); + } + System.out.println("==============="); + System.out.println(TRACE_PREFIX + "complete."); + } + + /** + * A number of sites get all snippy about using 255.255.255.255 for a + * broadcast address; it trips their security software and they kick you off + * their network. (Comcast, NPS, etc.) This determines the broadcast address for + * all connected interfaces, based on the IP and subnet mask. If you have a + * dual-homed host it will return a broadcast address for both. If you have + * some VMs running on your host this will pick up the addresses for those + * as well--e.g. running VMWare on your laptop with a local IP this will also + * pick up a 192.168 address assigned to the VM by the host OS. + * + * @return set of all broadcast addresses + */ + public static Set<InetAddress> getBroadcastAddresses() + { + Set<InetAddress> broadcastAddresses = new HashSet<>(); + Enumeration<NetworkInterface> interfaces; + + try { + interfaces = NetworkInterface.getNetworkInterfaces(); + + while (interfaces.hasMoreElements()) + { + NetworkInterface anInterface = interfaces.nextElement(); + + if (anInterface.isUp()) + { + for (InterfaceAddress anAddress : anInterface.getInterfaceAddresses()) { + if ((anAddress == null || anAddress.getAddress().isLinkLocalAddress())) + { + continue; + } + + //System.out.println("Getting broadcast address for " + anAddress); + InetAddress broadcastAddress = anAddress.getBroadcast(); + if (broadcastAddress != null) + { + broadcastAddresses.add(broadcastAddress); + } + } + } + } + } + catch (SocketException e) + { + System.out.println(TRACE_PREFIX + "Problem with .getBroadcastAddresses(), see exception trace:" + e); + System.out.println(e); + } + return broadcastAddresses; + } +} diff --git a/assignments/src/src/OpenDis7Examples/EspduSenderLog.txt b/assignments/src/src/OpenDis7Examples/EspduSenderLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..5e5a864097d7760f40b02f020abf17f84744b6dd --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/EspduSenderLog.txt @@ -0,0 +1,84 @@ +ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/EspduSender.java -Drun.class=OpenDis7Examples.EspduSender 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 +warning: [options] system modules path not set in conjunction with -source 17 +1 warning +compile-single: +run-single: +[OpenDis7Examples.EspduSender] started... +[OpenDis7Examples.EspduSender] sending multicast ESPDU packets to 239.1.2.3 port 3000 +=============== +espdu entityType information: + EntityKind =EntityKind 1 PLATFORM + Country =Country 225 UNITED_STATES_OF_AMERICA_USA + Domain =Land + Category =1 + SubCategory=1 + Specific =Country 225 UNITED_STATES_OF_AMERICA_USA +[OpenDis7Examples.EspduSender] sending 5 sets of packets: +=============== +Create new PDUs + latitude, longitude: [36.595517, -121.87706] + coordinate conversion: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +Espdu #1 entityID=[1,2,3] +FirePdu #1 firePdu=[FireMissionIndex=0, descriptor=MunitionDescriptor munitionType:EntityType entityKind:EntityKind 0 OTHER domain:Other country:Country 0 OTHER category:0 subCategory:0 specific:0 extra:0 warhead:MunitionDescriptorWarhead 0 OTHER fuse:MunitionDescriptorFuse 0 OTHER quantity:0 rate:0] +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 192.168.1.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 192.168.1.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.20.209.15 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 172.20.209.15 port 3000 +=============== +Create new PDUs + latitude, longitude: [36.595517, -121.877] + coordinate conversion: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +Espdu #2 entityID=[1,2,3] +FirePdu #2 firePdu=[FireMissionIndex=0, descriptor=MunitionDescriptor munitionType:EntityType entityKind:EntityKind 0 OTHER domain:Other country:Country 0 OTHER category:0 subCategory:0 specific:0 extra:0 warhead:MunitionDescriptorWarhead 0 OTHER fuse:MunitionDescriptorFuse 0 OTHER quantity:0 rate:0] +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 192.168.1.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 192.168.1.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.20.209.15 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 172.20.209.15 port 3000 +=============== +Create new PDUs + latitude, longitude: [36.595517, -121.87706] + coordinate conversion: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +Espdu #3 entityID=[1,2,3] +FirePdu #3 firePdu=[FireMissionIndex=0, descriptor=MunitionDescriptor munitionType:EntityType entityKind:EntityKind 0 OTHER domain:Other country:Country 0 OTHER category:0 subCategory:0 specific:0 extra:0 warhead:MunitionDescriptorWarhead 0 OTHER fuse:MunitionDescriptorFuse 0 OTHER quantity:0 rate:0] +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 192.168.1.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 192.168.1.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.20.209.15 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 172.20.209.15 port 3000 +=============== +Create new PDUs + latitude, longitude: [36.595517, -121.877] + coordinate conversion: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +Espdu #4 entityID=[1,2,3] +FirePdu #4 firePdu=[FireMissionIndex=0, descriptor=MunitionDescriptor munitionType:EntityType entityKind:EntityKind 0 OTHER domain:Other country:Country 0 OTHER category:0 subCategory:0 specific:0 extra:0 warhead:MunitionDescriptorWarhead 0 OTHER fuse:MunitionDescriptorFuse 0 OTHER quantity:0 rate:0] +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 192.168.1.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 192.168.1.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.20.209.15 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 172.20.209.15 port 3000 +=============== +Create new PDUs + latitude, longitude: [36.595517, -121.87706] + coordinate conversion: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +Espdu #5 entityID=[1,2,3] +FirePdu #5 firePdu=[FireMissionIndex=0, descriptor=MunitionDescriptor munitionType:EntityType entityKind:EntityKind 0 OTHER domain:Other country:Country 0 OTHER category:0 subCategory:0 specific:0 extra:0 warhead:MunitionDescriptorWarhead 0 OTHER fuse:MunitionDescriptorFuse 0 OTHER quantity:0 rate:0] +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 192.168.1.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 192.168.1.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.20.209.15 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 1500, to 172.20.209.15 port 3000 +=============== +[OpenDis7Examples.EspduSender] complete. +BUILD SUCCESSFUL (total time: 8 seconds) diff --git a/assignments/src/src/OpenDis7Examples/EspduSenderWireshark.png b/assignments/src/src/OpenDis7Examples/EspduSenderWireshark.png new file mode 100644 index 0000000000000000000000000000000000000000..209629a1a0fe7c5f804efe32b5ab36ba7645e722 Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/EspduSenderWireshark.png differ diff --git a/assignments/src/src/OpenDis7Examples/EspduSenderWiresharkCapture.pcapng b/assignments/src/src/OpenDis7Examples/EspduSenderWiresharkCapture.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..5615b7f12f140a50082049eadb7076a73bb80da7 Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/EspduSenderWiresharkCapture.pcapng differ diff --git a/assignments/src/src/OpenDis7Examples/EspduTerminalLog.txt b/assignments/src/src/OpenDis7Examples/EspduTerminalLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..aa29451610ecf5f3884d99c4a5f5f74eff878516 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/EspduTerminalLog.txt @@ -0,0 +1,245 @@ +Invocation instructions: +1. run/debug EspduReceiver.java (since sender does not block, first be ready to listen) +2. run/debug EspduSender.java + +Program responses follow for sender and receiver: + +=================================================== +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/EspduSender.java -Drun.class=OpenDis7Examples.EspduSender run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +[OpenDis7Examples.EspduSender] started... +[OpenDis7Examples.EspduSender] sending multicast ESPDU packets to 239.1.2.3 port 3000 +=============== +espdu entityType information: + EntityKind =DisPduType 1 PLATFORM + Country =Country 225 UNITED_STATES_OF_AMERICA_USA + Domain =Land + Category =1 + SubCategory=1 + Specific =Country 225 UNITED_STATES_OF_AMERICA_USA +[OpenDis7Examples.EspduSender] sending 5 sets of packets: +=============== +Create new PDUs + latitude, longitude: [36.595517, -121.87706] + coordinate conversion: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +Espdu #1 entityID=[1,2,3] +FirePdu #1 firePdu=[FireMissionIndex=0, descriptor=MunitionDescriptor: + munitionType: EntityType: + entityKind: DisPduType 0 OTHER + domain: Other + country: Country 0 OTHER + category: 0 + subCategory: 0 + specific: 0 + extra: 0 + + warhead: MunitionDescriptorWarhead 0 OTHER + fuse: MunitionDescriptorFuse 0 OTHER + quantity: 0 + rate: 0 +] +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.28.239.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.28.239.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.16.0.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.16.0.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.20.209.219 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.20.209.219 port 3000 +=============== +Create new PDUs + latitude, longitude: [36.595517, -121.877] + coordinate conversion: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +Espdu #2 entityID=[1,2,3] +FirePdu #2 firePdu=[FireMissionIndex=0, descriptor=MunitionDescriptor: + munitionType: EntityType: + entityKind: DisPduType 0 OTHER + domain: Other + country: Country 0 OTHER + category: 0 + subCategory: 0 + specific: 0 + extra: 0 + + warhead: MunitionDescriptorWarhead 0 OTHER + fuse: MunitionDescriptorFuse 0 OTHER + quantity: 0 + rate: 0 +] +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.28.239.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.28.239.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.16.0.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.16.0.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.20.209.219 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.20.209.219 port 3000 +=============== +Create new PDUs + latitude, longitude: [36.595517, -121.87706] + coordinate conversion: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +Espdu #3 entityID=[1,2,3] +FirePdu #3 firePdu=[FireMissionIndex=0, descriptor=MunitionDescriptor: + munitionType: EntityType: + entityKind: DisPduType 0 OTHER + domain: Other + country: Country 0 OTHER + category: 0 + subCategory: 0 + specific: 0 + extra: 0 + + warhead: MunitionDescriptorWarhead 0 OTHER + fuse: MunitionDescriptorFuse 0 OTHER + quantity: 0 + rate: 0 +] +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.28.239.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.28.239.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.16.0.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.16.0.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.20.209.219 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.20.209.219 port 3000 +=============== +Create new PDUs + latitude, longitude: [36.595517, -121.877] + coordinate conversion: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +Espdu #4 entityID=[1,2,3] +FirePdu #4 firePdu=[FireMissionIndex=0, descriptor=MunitionDescriptor: + munitionType: EntityType: + entityKind: DisPduType 0 OTHER + domain: Other + country: Country 0 OTHER + category: 0 + subCategory: 0 + specific: 0 + extra: 0 + + warhead: MunitionDescriptorWarhead 0 OTHER + fuse: MunitionDescriptorFuse 0 OTHER + quantity: 0 + rate: 0 +] +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.28.239.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.28.239.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.16.0.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.16.0.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.20.209.219 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.20.209.219 port 3000 +=============== +Create new PDUs + latitude, longitude: [36.595517, -121.87706] + coordinate conversion: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +Espdu #5 entityID=[1,2,3] +FirePdu #5 firePdu=[FireMissionIndex=0, descriptor=MunitionDescriptor: + munitionType: EntityType: + entityKind: DisPduType 0 OTHER + domain: Other + country: Country 0 OTHER + category: 0 + subCategory: 0 + specific: 0 + extra: 0 + + warhead: MunitionDescriptorWarhead 0 OTHER + fuse: MunitionDescriptorFuse 0 OTHER + quantity: 0 + rate: 0 +] +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 127.255.255.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.28.239.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.28.239.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.16.0.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.16.0.255 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 01 ENTITY_STATE] packet.getLength()=144, to 172.20.209.219 port 3000 +[OpenDis7Examples.EspduSender] sending datagram packet [DisPduType 02 FIRE ] packet.getLength()= 96, to 172.20.209.219 port 3000 +=============== +[OpenDis7Examples.EspduSender] complete. +BUILD SUCCESSFUL (total time: 11 seconds) + + +=================================================== + +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/EspduReceiver.java -Drun.class=OpenDis7Examples.EspduReceiver run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +[OpenDis7Examples.EspduReceiver] started... +[OpenDis7Examples.EspduReceiver] listening for PDU packets on 239.1.2.3 port 3000 +To quit: stop or kill this process +=============== + 1. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 2. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== + 3. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 4. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== + 5. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] + 6. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu + FirePdu locationInWorldCoordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +=============== + 7. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] + 8. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu + FirePdu locationInWorldCoordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +=============== + 9. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 10. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== + 11. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 12. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== + 13. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] + 14. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu + FirePdu locationInWorldCoordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +=============== + 15. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] + 16. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu + FirePdu locationInWorldCoordinates: [-2707492.9269245286, -4353663.899966802, 3781450.3202754413] +=============== + 17. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 18. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== + 19. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu + entityID triplet: [1, 2, 3] + Location in DIS coordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] + 20. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu + FirePdu locationInWorldCoordinates: [-2707497.4860692197, -4353661.0646844525, 3781450.3202754413] +=============== \ No newline at end of file diff --git a/assignments/src/src/OpenDis7Examples/ExampleSimulationProgram.java b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgram.java new file mode 100644 index 0000000000000000000000000000000000000000..dbc60b72e1071f77f8f60bc7a7718ae443415f96 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgram.java @@ -0,0 +1,413 @@ +/** + * 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 + } +} diff --git a/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.pdf b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1092d26a408a96a754f0bae07e2b0315e0815e89 Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.pdf differ diff --git a/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.png b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..1917aa4ef9e4a994d8b4057c7c033f2ab73b78a6 Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.png differ diff --git a/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.vsdx b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..439a854c826923f7f83f705be0a76139f141d2af Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramFlowDiagram.vsdx differ diff --git a/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramLog.txt b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..af7439f5d53e94b1cbb8fde885ac5dda59eb9a4e --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramLog.txt @@ -0,0 +1,112 @@ +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 +warning: [options] system modules path not set in conjunction with -source 17 +1 warning +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 +[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 2023-12-30T22:00:00.559852600] +... 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: 13 seconds) diff --git a/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramPduCaptureLog.dislog b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramPduCaptureLog.dislog new file mode 100644 index 0000000000000000000000000000000000000000..d81f59667f239a2e1339da417e1b44c2e06f3721 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramPduCaptureLog.dislog @@ -0,0 +1,54 @@ +# Start, ENCODING_PLAINTEXT, [PduRecorder] 20220625_204652, DIS capture file, .\pduLog\PduCaptureLog.dislog +# Timestamp(8 bytes),ProtocolVersion,CompatibilityVersion,ExerciseID,PduType,PduStatus,HeaderLength,PduLength,then PDU-specific data +# ============================================= +# DisPduType 11 CREATE_ENTITY, Session time 20:46:52.8, session duration 00:00:00.0, Pdu timestamp -939161411 01:49:49.0, simulation stream interval 0 00:00:00.0 +0,0,68,10,-73,22,-97,-7,7,4,11,5,-56,5,-120,-67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 11 CREATE_ENTITY, Session time 20:46:52.8, session duration 00:00:00.0, Pdu timestamp -939161411 01:49:49.0, simulation stream interval 0 00:00:00.0 +0,0,0,0,0,-126,88,92,7,4,11,5,-56,5,-120,-67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:46:52.8, session duration 00:00:00.0, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,0,-126,88,92,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-81,-46,0,0,1,64,83,105,109,117,108,97,116,105,111,110,32,116,105,109,101,115,116,101,112,32,100,117,114,97,116,105,111,110,32,49,46,48,32,115,101,99,111,110,100,115 +# DisPduType 22 COMMENT, Session time 20:46:52.9, session duration 00:00:00.1, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,6,-115,-34,-60,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-53,32,0,0,2,16,83,105,109,117,108,97,116,105,111,110,32,116,105,109,101,32,48,46,48,32,97,116,32,76,111,99,97,108,68,97,116,101,84,105,109,101,32,50,48,50,50,45,48,54,45,50,53,84,50,48,58,52,54,58,53,50,46,57,49,56,52,54,50,50,48,48,0,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:46:54.0, session duration 00:00:01.2, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,72,-50,23,44,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,23,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0 +# DisPduType 02 FIRE, Session time 20:46:54.1, session duration 00:00:01.3, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,79,64,-127,-48,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0 +# DisPduType 22 COMMENT, Session time 20:46:54.2, session duration 00:00:01.4, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,85,-47,-118,-68,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:46:54.3, session duration 00:00:01.5, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,92,49,69,0,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:46:55.4, session duration 00:00:02.6, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,-98,-85,-33,28,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,23,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0 +# DisPduType 02 FIRE, Session time 20:46:55.5, session duration 00:00:02.7, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,-91,11,-57,-36,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0 +# DisPduType 22 COMMENT, Session time 20:46:55.6, session duration 00:00:02.8, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,-85,-89,-120,-20,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:46:55.7, session duration 00:00:02.9, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,-78,21,-112,32,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:46:56.9, session duration 00:00:04.1, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,-12,-17,23,4,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,23,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0 +# DisPduType 02 FIRE, Session time 20:46:57.0, session duration 00:00:04.2, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,0,-5,98,-81,-100,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0 +# DisPduType 22 COMMENT, Session time 20:46:57.1, session duration 00:00:04.3, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,1,1,-14,91,-76,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:46:57.2, session duration 00:00:04.4, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,1,8,89,25,72,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:46:58.3, session duration 00:00:05.5, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,1,74,-66,108,-24,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,23,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0 +# DisPduType 02 FIRE, Session time 20:46:58.4, session duration 00:00:05.6, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,1,81,99,-111,-32,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0 +# DisPduType 22 COMMENT, Session time 20:46:58.5, session duration 00:00:05.7, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,1,87,-39,103,32,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,52,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:46:58.6, session duration 00:00:05.8, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,1,94,99,-18,8,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:46:59.8, session duration 00:00:07.0, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,1,-95,61,-111,-44,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,23,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0 +# DisPduType 02 FIRE, Session time 20:46:59.9, session duration 00:00:07.1, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,1,-89,-76,41,56,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0 +# DisPduType 22 COMMENT, Session time 20:47:00.0, session duration 00:00:07.2, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,1,-82,82,31,32,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,53,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:00.1, session duration 00:00:07.3, Pdu timestamp 0 00:00:00.0, simulation stream interval 939161411 22:10:11.0 +0,0,0,1,-76,-71,-33,-80,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:00.2, session duration 00:00:07.4, Pdu timestamp -1559 23:34:01.0, simulation stream interval 939159852 21:44:12.0 +0,0,0,1,-69,116,86,20,7,1,22,5,-1,-1,-7,-23,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,9,90,-90,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,9,90,-90,0,0,1,48,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,99,111,109,112,108,101,116,101,100,32,115,117,99,99,101,115,115,102,117,108,108,121,0,0 +# Finish, ENCODING_PLAINTEXT, [PduRecorder] 20220625_204702, DIS capture file, .\pduLog\PduCaptureLog.dislog diff --git a/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..da2290863bec43303a3f377ce9442e747e116f29 Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.png differ diff --git a/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.vsdx b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..9c12e5d7c5cdcc9d670f0288bdc6002bf541a9b8 Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramSequenceDiagram.vsdx differ diff --git a/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramWireshark.png b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramWireshark.png new file mode 100644 index 0000000000000000000000000000000000000000..34e2b468ea32b01f0d057110ff464973d7490df0 Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/ExampleSimulationProgramWireshark.png differ diff --git a/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolation.java b/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolation.java new file mode 100644 index 0000000000000000000000000000000000000000..d2e9adb829a8c4b3e0de3ad79f91b47d1f26209f --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolation.java @@ -0,0 +1,260 @@ +/** + * Copyright (c) 2008-2022, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html and license.txt + * + * @author brutzman@nps.edu + */ +package OpenDis7Examples; + +import edu.nps.moves.dis7.entities.swe.platform.surface._001Poseidon; +import edu.nps.moves.dis7.enumerations.ForceID; +import edu.nps.moves.dis7.pdus.EntityStatePdu; +import edu.nps.moves.dis7.pdus.Pdu; +import edu.nps.moves.dis7.pdus.Vector3Double; +import edu.nps.moves.dis7.utilities.DisChannel; +import edu.nps.moves.dis7.utilities.DisTime; +import edu.nps.moves.dis7.utilities.stream.X3dCreateInterpolators; +import edu.nps.moves.dis7.utilities.stream.X3dCreateLineSet; +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * The purpose of this program is to provide an easily modifiable example + * simulation for networked entity tracks and presentation, including + * DIS-capable entities doing tasks and reporting them to the network. + * Default settings include PDU recording turned on by default. + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleTrackInterpolationLog.txt" target="_blank">ExampleTrackInterpolationLog.txt</a> + * @see <a href="https://calhoun.nps.edu/handle/10945/65436" target="_blank">REPEATABLE UNIT TESTING OF DISTRIBUTED INTERACTIVE SIMULATION (DIS) PROTOCOL BEHAVIOR STREAMS USING WEB STANDARDS</a> by Tobias Brennenstuhl, Masters Thesis, Naval Postgraduate School (NPS), June 2020 + * @see <a href="https://gitlab.nps.edu/Savage/SavageTheses/-/tree/master/BrennenstuhlTobias" target="_blank">https://gitlab.nps.edu/Savage/SavageTheses/-/tree/master/BrennenstuhlTobias</a> + */ +public class ExampleTrackInterpolation extends ExampleSimulationProgram +{ + /** Default constructor */ + public ExampleTrackInterpolation() + { + // default constructor + } + // -------------------- Begin Variables for X3D autogenerated code + private X3dCreateInterpolators x3dInterpolators = new X3dCreateInterpolators(); + private X3dCreateLineSet x3dLineSet = new X3dCreateLineSet(); + private byte[] globalByteBufferForX3dInterpolators = null; + // -------------------- End Variables for X3D autogenerated code + + ArrayList<Pdu> pduSentList = new ArrayList<>(); + + /** + * This runSimulationLoops() method is a programmer-modifiable method for + * defining and running a new simulation of interest. Welcome! Other parts + * of this program handle bookkeeping and plumbing tasks so that you can + * focus on your model entities and activities. Expandable support includes + * DIS EntityStatePdu, FirePdu and CommentPdu all available for modification + * and sending in a simulation loop. Continuous improvement efforts seek to + * make this program as easy and straightforward as possible for DIS + * simulationists to use and adapt. All of the other methods are setup, + * teardown and configuration that you may find interesting, even helpful, + * but don't really have to worry about. + */ + @SuppressWarnings("SleepWhileInLoop") // yes we do that + @Override // indicates that this method supercedes corresponding superclass method + public void runSimulationLoops() + { + try + { + final int SIMULATION_MAX_LOOP_COUNT = 50; // be deliberate out there! also avoid infinite loops. + int simulationLoopCount = 0; // variable, initialized at 0 + boolean simulationComplete = false; // sentinel variable as termination condition, are we done yet? + + // TODO reset Clock Time to today's date and timestamp to zero, providing consistent outputs for each simulation run + DisTime.setEpochLvcNow(); + simulationTimeSeconds = simulationTimeInitial - getSimulationTimeStepDuration(); // pre-initialization for first loop + + initializeSimulationEntities(); + + // use declared PDU objects and set their values. + entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID; + // TODO someday, use enumerations; is there a unique site triplet for MOVES Institute? + + disChannel.getPduRecorder().setVerbose(false); + disChannel.getPduRecorder().hasVerboseOutput(); // debug check + + EntityStatePdu espdu_1 = pduFactory.makeEntityStatePdu(); + espdu_1.setEntityID(entityID_1); + espdu_1.setForceId(ForceID.FRIENDLY); + espdu_1.setEntityType(new _001Poseidon()); // note import statement above + espdu_1.setMarking("track path"); +// espdu_1.clearMarking(); // test +// espdu_1.getMarkingString(); // trace +// espdu_1.setEntityLocation(new Vector3Double().setX(0).setY(0).setZ(0)); // long form + espdu_1.setEntityLocation(0, 0, 0); // utility method + + float speedEntity_1 = 1.0f; // meters/second + EntityStatePdu.Direction directionEntity_1 = EntityStatePdu.Direction.NORTH; + + PduTrack pduTrack_1 = new PduTrack(); + pduTrack_1.setDescriptor("testing 123"); + pduTrack_1.setDefaultWaypointInterval(1.0f); // overrides timestamps + pduTrack_1.setAddLineBreaksWithinKeyValues(true); + pduTrack_1.setAuthor("Don Brutzman"); + pduTrack_1.setX3dModelName("ExampleTrackInterpolation.x3d"); + pduTrack_1.setX3dModelIdentifier("https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleTrackInterpolation.x3d"); + pduTrack_1.addPdu(espdu_1); // initial location + + // OK send initial PDUs prior to loop + if (disChannel.getPduRecorder().hasVerboseOutput()) + System.out.println("sending PDUs for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); + disChannel.sendSinglePdu(espdu_1); +// sendCommentPdu(timeStepDurationCommentType, narrativeMessage1, narrativeMessage2, narrativeMessage3); + pduSentList.add(espdu_1); + reportPdu(simulationLoopCount, espdu_1.getEntityLocation(), directionEntity_1); + + // TODO simulation management PDUs for startup, planning to design special class support + // =================================================================================================== + // loop the simulation while allowed, programmer can set additional conditions to break out and finish + while (simulationLoopCount < SIMULATION_MAX_LOOP_COUNT) // are we done yet? + { + simulationLoopCount++; // good practice: increment loop counter as first action in that loop + simulationTimeSeconds += getSimulationTimeStepDuration(); // good practice: update clock along with loop index + + // ============================================================================================= + // * your own simulation code starts here! ***************************************************** + // ============================================================================================= + // are there any other variables to modify at the beginning of your loop? + // compute a track, update an ESPDU, whatever it is that your model is doing... + + // Pick direction, change each 10 seconds, traverse a box. No physics. Walk a box! + if (simulationLoopCount <= 10) + directionEntity_1 = EntityStatePdu.Direction.NORTH; + else if (simulationLoopCount <= 20) + directionEntity_1 = EntityStatePdu.Direction.EAST; + else if (simulationLoopCount <= 30) + directionEntity_1 = EntityStatePdu.Direction.SOUTH; + else // if (simulationLoopCount <= 40) + directionEntity_1 = EntityStatePdu.Direction.WEST; + + // use utility method to simply update velocity vector using speed value and direction + espdu_1.setEntityLinearVelocity(speedEntity_1, directionEntity_1); + + // Where is my entity? Insert changes in position; this sample only changes X position. + espdu_1.advanceEntityLocation(getSimulationTimeStepDuration()); + + // make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) + narrativeMessage1 = "MV3500 TrackSimulationProgram"; + narrativeMessage2 = "runSimulation() loop " + simulationLoopCount + " at time " + simulationTimeSeconds; + narrativeMessage3 = ""; // intentionally blank for testing + + // your loop termination condition goes here + if (simulationLoopCount > 40) // for example + { + simulationComplete = true; + } + // ============================================================================================= + // * your own simulation code is finished here! ************************************************ + // ============================================================================================= + + // staying synchronized with timestep: wait duration for elapsed time in this loop + // Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes + if (false) // real-time operation or simulation speedup + { + Thread.sleep((long) (getSimulationTimeStepDuration() * 1000)); // seconds * (1000 msec/sec) = milliseconds + System.out.println(disChannel.getTRACE_PREFIX() + "Pausing for " + getSimulationTimeStepDuration() + " seconds"); + } + + // OK now send the status PDUs for this loop, and then continue + if (disChannel.getPduRecorder().hasVerboseOutput()) + System.out.println("sending PDUs for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); + disChannel.sendSinglePdu(espdu_1); + disChannel.sendCommentPdu(DisChannel.COMMENTPDU_SIMULATION_TIMESTEP, narrativeMessage1, narrativeMessage2, narrativeMessage3); + if (disChannel.getPduRecorder().hasVerboseOutput()) + System.out.println(disChannel.getTRACE_PREFIX() + "PDUs successfully sent for this loop"); + pduSentList.add(espdu_1); + pduTrack_1.addPdu(espdu_1); + Vector3Double location = espdu_1.getEntityLocation(); + reportPdu(simulationLoopCount, location, directionEntity_1); + + // =============================== + // current loop now finished, check whether to terminate if simulation complete, otherwise continue + if (simulationComplete || (simulationLoopCount > 10000)) // for example; including fail-safe condition is good + { + System.out.println(disChannel.getTRACE_PREFIX() + "loop termination condition met, simulationComplete=" + simulationComplete); // ", final loopCount=" + loopCount + + break; + } + } // end of simulation loop + // =================================================================================================== + System.out.println(disChannel.getTRACE_PREFIX() + "all PDUs successfully sent for this loop (pduSentList.size()=" + pduSentList.size() + " total)"); + + // track analysis + System.out.println(disChannel.getTRACE_PREFIX() + "pduTrack_1 initialLocation=" + pduTrack_1.getInitialLocation() + ", latestLocation=" + pduTrack_1.getLatestLocation()); + pduTrack_1.sortPdus() + .createRawWaypoints(); + + System.out.println("pduTrack_1 getEspduCount()=" + pduTrack_1.getEspduCount()); + System.out.println("pduTrack_1 duration = " + pduTrack_1.getTotalDurationSeconds() + " seconds = " + + pduTrack_1.getTotalDurationTicks() + " ticks"); + System.out.println("================================="); + System.out.println(pduTrack_1.createX3dModel()); + System.out.println("================================="); + + narrativeMessage2 = "runSimulation() completed successfully"; // all done + disChannel.sendCommentPdu(DisChannel.COMMENTPDU_NARRATIVE, narrativeMessage1, narrativeMessage2, narrativeMessage3); + if (disChannel.getPduRecorder().hasVerboseOutput()) + disChannel.printlnTRACE("final CommentPdu successfully sent for simulation"); + // TODO simulation management PDUs + } + catch (InterruptedException iex) // handle any exception that your code might choose to provoke! + { + Logger.getLogger(ExampleTrackInterpolation.class.getSimpleName()).log(Level.SEVERE, null, iex); + } + } + + /** + * Report current PDU information to console + * @param simulationLoopCount current loop index + * @param location current location + * @param directionEntity current direction + * @return same object to permit progressive setters + */ + public ExampleTrackInterpolation reportPdu(int simulationLoopCount, Vector3Double location, EntityStatePdu.Direction directionEntity) + { + System.out.println (String.format("%2d ", simulationLoopCount) + "Entity location=(" + + String.format("%4.1f", location.getX()) + ", " + + String.format("%4.1f", location.getY()) + ", " + + String.format("%4.1f", location.getZ()) + ") " + + String.format("%-5s", directionEntity.name()) +// + " " + espdu_1.getEntityLinearVelocity().toString() + ); + return this; + } + + /* Default constructors used unless otherwise defined/overridden. */ + /** + * Main method is first executed when a program instance is loaded. + * + * @see + * <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html" target="_blank">Java + * Tutorials: A Closer Look at the "Hello World!" Application</a> + * @param args command-line arguments are an array of optional String + * parameters that are passed from execution environment during invocation + */ + public static void main(String[] args) + { + thisProgram = new ExampleTrackInterpolation(); // create instance of self within static main() method + + thisProgram.disChannel.printlnTRACE("main() started..."); + + thisProgram.handleArguments (args); // process command-line invocation arguments + +// thisProgram.disChannel.getPduRecorder().setVerbose(false); +// thisProgram.disChannel.setVerboseComments(false); +// thisProgram.disChannel.getDisNetworkInterface().setVerbose(false); + + 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/src/OpenDis7Examples/ExampleTrackInterpolation.x3d b/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolation.x3d new file mode 100644 index 0000000000000000000000000000000000000000..c275c77bb468fa03002f3911e343b512d2fc56dd --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolation.x3d @@ -0,0 +1,169 @@ +<X3D profile='Interchange' version='4.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.0.xsd'> + <head> + <meta content='ExampleTrackInterpolation.x3d' name='title'/> + <meta content='Conversion of ESPDU track into X3D animation interpolators and LineSet.' name='description'/> + <meta content='1 January 2022' name='created'/> + <meta content='30 May 2022' name='modified'/> + <meta content='Don Brutzman' name='creator'/> + <meta content='https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleTrackInterpolation.x3d' name='identifier'/> + <meta content='PduTrack utility, opendis7-java Library https://github.com/open-dis/opendis7-java' name='generator'/> + <meta content='NPS MOVES MV3500 Networked Graphics https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500' name='reference'/> + <meta content='X3D Resources https://www.web3d.org/x3d/content/examples/X3dResources.html' name='reference'/> + <meta content='X3D Scene Authoring Hints https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html' name='reference'/> + <meta content='X3D Tooltips https://www.web3d.org/x3d/tooltips/X3dTooltips.html' name='reference'/> + <meta content='X3D Validator https://savage.nps.edu/X3dValidator' name='reference'/> + <meta content='Open source https://raw.githubusercontent.com/open-dis/opendis7-java/master/license.html' name='license'/> + </head> + <Scene> + <WorldInfo title='PduTrackInterpolation.x3d'/> + <TimeSensor DEF='testing123Clock' cycleInterval='42.0' loop='true'/> + <PositionInterpolator DEF='testing123Positions' key='0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0 17.0 18.0 19.0 20.0 21.0 22.0 23.0 24.0 25.0 26.0 27.0 28.0 29.0 30.0 31.0 32.0 33.0 34.0 35.0 36.0 37.0 38.0 39.0 40.0 41.0' keyValue=' +0.0 0.0 0.0, +0.0 1.0 0.0, +0.0 2.0 0.0, +0.0 3.0 0.0, +0.0 4.0 0.0, +0.0 5.0 0.0, +0.0 6.0 0.0, +0.0 7.0 0.0, +0.0 8.0 0.0, +0.0 9.0 0.0, +0.0 10.0 0.0, +1.0 10.0 0.0, +2.0 10.0 0.0, +3.0 10.0 0.0, +4.0 10.0 0.0, +5.0 10.0 0.0, +6.0 10.0 0.0, +7.0 10.0 0.0, +8.0 10.0 0.0, +9.0 10.0 0.0, +10.0 10.0 0.0, +10.0 9.0 0.0, +10.0 8.0 0.0, +10.0 7.0 0.0, +10.0 6.0 0.0, +10.0 5.0 0.0, +10.0 4.0 0.0, +10.0 3.0 0.0, +10.0 2.0 0.0, +10.0 1.0 0.0, +10.0 0.0 0.0, +9.0 0.0 0.0, +8.0 0.0 0.0, +7.0 0.0 0.0, +6.0 0.0 0.0, +5.0 0.0 0.0, +4.0 0.0 0.0, +3.0 0.0 0.0, +2.0 0.0 0.0, +1.0 0.0 0.0, +0.0 0.0 0.0, +-1.0 0.0 0.0'/> + <OrientationInterpolator DEF='testing123Orientations' key='0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0 17.0 18.0 19.0 20.0 21.0 22.0 23.0 24.0 25.0 26.0 27.0 28.0 29.0 30.0 31.0 32.0 33.0 34.0 35.0 36.0 37.0 38.0 39.0 40.0 41.0' keyValue=' +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0'/> + <ROUTE fromField='fraction_changed' fromNode='testing123Clock' toField='set_fraction' toNode='testing123Positions'/> + <ROUTE fromField='fraction_changed' fromNode='testing123Clock' toField='set_fraction' toNode='testing123Orientations'/> + <Shape> + <Appearance DEF='TrackAppearance'> + <Material emissiveColor='0.2 0.8 0.8'/> + </Appearance> + <LineSet vertexCount='42'> + <Coordinate point=' +0.0 0.0 0.0, +0.0 1.0 0.0, +0.0 2.0 0.0, +0.0 3.0 0.0, +0.0 4.0 0.0, +0.0 5.0 0.0, +0.0 6.0 0.0, +0.0 7.0 0.0, +0.0 8.0 0.0, +0.0 9.0 0.0, +0.0 10.0 0.0, +1.0 10.0 0.0, +2.0 10.0 0.0, +3.0 10.0 0.0, +4.0 10.0 0.0, +5.0 10.0 0.0, +6.0 10.0 0.0, +7.0 10.0 0.0, +8.0 10.0 0.0, +9.0 10.0 0.0, +10.0 10.0 0.0, +10.0 9.0 0.0, +10.0 8.0 0.0, +10.0 7.0 0.0, +10.0 6.0 0.0, +10.0 5.0 0.0, +10.0 4.0 0.0, +10.0 3.0 0.0, +10.0 2.0 0.0, +10.0 1.0 0.0, +10.0 0.0 0.0, +9.0 0.0 0.0, +8.0 0.0 0.0, +7.0 0.0 0.0, +6.0 0.0 0.0, +5.0 0.0 0.0, +4.0 0.0 0.0, +3.0 0.0 0.0, +2.0 0.0 0.0, +1.0 0.0 0.0, +0.0 0.0 0.0, +-1.0 0.0 0.0'/> + </LineSet> + </Shape> + <Transform DEF='AnimationTransform'> + <Transform rotation='0 0 1 1.57'> + <Shape> + <Appearance USE='TrackAppearance'/> + <Cone bottomRadius='0.5'/> + </Shape> + </Transform> + </Transform> + <ROUTE fromField='value_changed' fromNode='testing123Positions' toField='translation' toNode='AnimationTransform'/> + <ROUTE fromField='value_changed' fromNode='testing123Orientations' toField='rotation' toNode='AnimationTransform'/> + </Scene> +</X3D> \ No newline at end of file diff --git a/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolationFlowchart.png b/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolationFlowchart.png new file mode 100644 index 0000000000000000000000000000000000000000..f8898ecf8bf05b20d6cd516cc8b5f666aa9c0d22 Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolationFlowchart.png differ diff --git a/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolationLog.txt b/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolationLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..eb51d89da8f07c787f0ab9224ce4da220199c85c --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolationLog.txt @@ -0,0 +1,297 @@ +ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/ExampleTrackInterpolation.java -Drun.class=OpenDis7Examples.ExampleTrackInterpolation 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 +warning: [options] system modules path not set in conjunction with -source 17 +1 warning +compile-single: +run-single: +[DisChannel] thisHostName=IT160907-INFLPP +[DisChannel ExampleTrackInterpolation] Beginning pdu save to directory ./pduLog +[PduRecorder ExampleTrackInterpolation] Recorder log file open: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog.dislog +[DisThreadedNetworkInterface] using network interface PANGP Virtual Ethernet Adapter Secure +[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 ExampleTrackInterpolation] listening to IP address 239.1.2.3 on port 3000 +[DisChannel ExampleTrackInterpolation] Network confirmation: address=239.1.2.3 port=3000 +[DisChannel ExampleTrackInterpolation] just checking: disChannel.getNetworkAddress()=239.1.2.3, getNetworkPort()=3000 +[DisChannel ExampleTrackInterpolation] just checking: hasVerboseSending()=true, hasVerboseReceipt()=true +[DisThreadedNetworkInterface ExampleTrackInterpolation] [sending 1] DisPduType 11 CREATE_ENTITY, size 28 bytes) +[DisThreadedNetworkInterface ExampleTrackInterpolation] [sending 2] DisPduType 11 CREATE_ENTITY, size 28 bytes) +[DisThreadedNetworkInterface ExampleTrackInterpolation] [receipt 1] DisPduType 11 CREATE_ENTITY, size 28 bytes) +[DisThreadedNetworkInterface ExampleTrackInterpolation] [sending 3] DisPduType 22 COMMENT, size 80 bytes) +[DisThreadedNetworkInterface ExampleTrackInterpolation] [receipt 2] DisPduType 11 CREATE_ENTITY, size 28 bytes) +[DisThreadedNetworkInterface ExampleTrackInterpolation] [receipt 3] DisPduType 22 COMMENT, size 80 bytes) +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [Simulation timestep duration 1.0 seconds] +[DisChannel ExampleTrackInterpolation] main() started... + 0 Entity location=( 0.0, 0.0, 0.0) NORTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 1 at time 0.0] + 1 Entity location=( 0.0, 1.0, 0.0) NORTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 2 at time 1.0] + 2 Entity location=( 0.0, 2.0, 0.0) NORTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 3 at time 2.0] + 3 Entity location=( 0.0, 3.0, 0.0) NORTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 4 at time 3.0] + 4 Entity location=( 0.0, 4.0, 0.0) NORTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 5 at time 4.0] + 5 Entity location=( 0.0, 5.0, 0.0) NORTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 6 at time 5.0] + 6 Entity location=( 0.0, 6.0, 0.0) NORTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 7 at time 6.0] + 7 Entity location=( 0.0, 7.0, 0.0) NORTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 8 at time 7.0] + 8 Entity location=( 0.0, 8.0, 0.0) NORTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 9 at time 8.0] + 9 Entity location=( 0.0, 9.0, 0.0) NORTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 10 at time 9.0] +10 Entity location=( 0.0, 10.0, 0.0) NORTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 11 at time 10.0] +11 Entity location=( 1.0, 10.0, 0.0) EAST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 12 at time 11.0] +12 Entity location=( 2.0, 10.0, 0.0) EAST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 13 at time 12.0] +13 Entity location=( 3.0, 10.0, 0.0) EAST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 14 at time 13.0] +14 Entity location=( 4.0, 10.0, 0.0) EAST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 15 at time 14.0] +15 Entity location=( 5.0, 10.0, 0.0) EAST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 16 at time 15.0] +16 Entity location=( 6.0, 10.0, 0.0) EAST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 17 at time 16.0] +17 Entity location=( 7.0, 10.0, 0.0) EAST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 18 at time 17.0] +18 Entity location=( 8.0, 10.0, 0.0) EAST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 19 at time 18.0] +19 Entity location=( 9.0, 10.0, 0.0) EAST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 20 at time 19.0] +20 Entity location=(10.0, 10.0, 0.0) EAST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 21 at time 20.0] +21 Entity location=(10.0, 9.0, 0.0) SOUTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 22 at time 21.0] +22 Entity location=(10.0, 8.0, 0.0) SOUTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 23 at time 22.0] +23 Entity location=(10.0, 7.0, 0.0) SOUTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 24 at time 23.0] +24 Entity location=(10.0, 6.0, 0.0) SOUTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 25 at time 24.0] +25 Entity location=(10.0, 5.0, 0.0) SOUTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 26 at time 25.0] +26 Entity location=(10.0, 4.0, 0.0) SOUTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 27 at time 26.0] +27 Entity location=(10.0, 3.0, 0.0) SOUTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 28 at time 27.0] +28 Entity location=(10.0, 2.0, 0.0) SOUTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 29 at time 28.0] +29 Entity location=(10.0, 1.0, 0.0) SOUTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 30 at time 29.0] +30 Entity location=(10.0, 0.0, 0.0) SOUTH +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 31 at time 30.0] +31 Entity location=( 9.0, 0.0, 0.0) WEST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 32 at time 31.0] +32 Entity location=( 8.0, 0.0, 0.0) WEST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 33 at time 32.0] +33 Entity location=( 7.0, 0.0, 0.0) WEST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 34 at time 33.0] +34 Entity location=( 6.0, 0.0, 0.0) WEST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 35 at time 34.0] +35 Entity location=( 5.0, 0.0, 0.0) WEST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 36 at time 35.0] +36 Entity location=( 4.0, 0.0, 0.0) WEST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 37 at time 36.0] +37 Entity location=( 3.0, 0.0, 0.0) WEST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 38 at time 37.0] +38 Entity location=( 2.0, 0.0, 0.0) WEST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 39 at time 38.0] +39 Entity location=( 1.0, 0.0, 0.0) WEST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 40 at time 39.0] +40 Entity location=( 0.0, 0.0, 0.0) WEST +[DisChannel ExampleTrackInterpolation] *** [CommentPdu APPLICATION_TIMESTEP] [MV3500 TrackSimulationProgram, runSimulation() loop 41 at time 40.0] +41 Entity location=(-1.0, 0.0, 0.0) WEST +[DisChannel ExampleTrackInterpolation] loop termination condition met, simulationComplete=true +[DisChannel ExampleTrackInterpolation] all PDUs successfully sent for this loop (pduSentList.size()=42 total) +[DisChannel ExampleTrackInterpolation] pduTrack_1 initialLocation=Vector3Double x:0.0 y:0.0 z:0.0, latestLocation=Vector3Double x:-1.0 y:0.0 z:0.0 +pduTrack_1 getEspduCount()=42 +pduTrack_1 duration = 42.0 seconds = 0 ticks +================================= +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd"> +<X3D profile='Interchange' version='4.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.0.xsd'> + <head> + <meta content='ExampleTrackInterpolation.x3d' name='title'/> + <meta content='Conversion of ESPDU track into X3D animation interpolators and LineSet.' name='description'/> + <meta content='1 January 2022' name='created'/> + <meta content='21 December 2023' name='modified'/> + <meta content='Don Brutzman' name='creator'/> + <meta content='https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/ExampleTrackInterpolation.x3d' name='identifier'/> + <meta content='PduTrack utility, opendis7-java Library https://github.com/open-dis/opendis7-java' name='generator'/> + <meta content='NPS MOVES MV3500 Networked Graphics https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500' name='reference'/> + <meta content='X3D Resources https://www.web3d.org/x3d/content/examples/X3dResources.html' name='reference'/> + <meta content='X3D Scene Authoring Hints https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html' name='reference'/> + <meta content='X3D Tooltips https://www.web3d.org/x3d/tooltips/X3dTooltips.html' name='reference'/> + <meta content='X3D Validator https://savage.nps.edu/X3dValidator' name='reference'/> + <meta content='Open source https://raw.githubusercontent.com/open-dis/opendis7-java/master/license.html' name='license'/> + </head> + <Scene> + <WorldInfo title='PduTrackInterpolation.x3d'/> + <TimeSensor DEF='testing123Clock' cycleInterval='42.0' loop='true'/> + <PositionInterpolator DEF='testing123Positions' key='0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0 17.0 18.0 19.0 20.0 21.0 22.0 23.0 24.0 25.0 26.0 27.0 28.0 29.0 30.0 31.0 32.0 33.0 34.0 35.0 36.0 37.0 38.0 39.0 40.0 41.0' keyValue=' +0.0 0.0 0.0, +0.0 1.0 0.0, +0.0 2.0 0.0, +0.0 3.0 0.0, +0.0 4.0 0.0, +0.0 5.0 0.0, +0.0 6.0 0.0, +0.0 7.0 0.0, +0.0 8.0 0.0, +0.0 9.0 0.0, +0.0 10.0 0.0, +1.0 10.0 0.0, +2.0 10.0 0.0, +3.0 10.0 0.0, +4.0 10.0 0.0, +5.0 10.0 0.0, +6.0 10.0 0.0, +7.0 10.0 0.0, +8.0 10.0 0.0, +9.0 10.0 0.0, +10.0 10.0 0.0, +10.0 9.0 0.0, +10.0 8.0 0.0, +10.0 7.0 0.0, +10.0 6.0 0.0, +10.0 5.0 0.0, +10.0 4.0 0.0, +10.0 3.0 0.0, +10.0 2.0 0.0, +10.0 1.0 0.0, +10.0 0.0 0.0, +9.0 0.0 0.0, +8.0 0.0 0.0, +7.0 0.0 0.0, +6.0 0.0 0.0, +5.0 0.0 0.0, +4.0 0.0 0.0, +3.0 0.0 0.0, +2.0 0.0 0.0, +1.0 0.0 0.0, +0.0 0.0 0.0, +-1.0 0.0 0.0'/> + <OrientationInterpolator DEF='testing123Orientations' key='0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0 17.0 18.0 19.0 20.0 21.0 22.0 23.0 24.0 25.0 26.0 27.0 28.0 29.0 30.0 31.0 32.0 33.0 34.0 35.0 36.0 37.0 38.0 39.0 40.0 41.0' keyValue=' +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0, +0.0 1.0 0.0 0.0'/> + <ROUTE fromField='fraction_changed' fromNode='testing123Clock' toField='set_fraction' toNode='testing123Positions'/> + <ROUTE fromField='fraction_changed' fromNode='testing123Clock' toField='set_fraction' toNode='testing123Orientations'/> + <Shape> + <Appearance DEF='TrackAppearance'> + <Material emissiveColor='0.2 0.8 0.8'/> + </Appearance> + <LineSet vertexCount='42'> + <Coordinate point=' +0.0 0.0 0.0, +0.0 1.0 0.0, +0.0 2.0 0.0, +0.0 3.0 0.0, +0.0 4.0 0.0, +0.0 5.0 0.0, +0.0 6.0 0.0, +0.0 7.0 0.0, +0.0 8.0 0.0, +0.0 9.0 0.0, +0.0 10.0 0.0, +1.0 10.0 0.0, +2.0 10.0 0.0, +3.0 10.0 0.0, +4.0 10.0 0.0, +5.0 10.0 0.0, +6.0 10.0 0.0, +7.0 10.0 0.0, +8.0 10.0 0.0, +9.0 10.0 0.0, +10.0 10.0 0.0, +10.0 9.0 0.0, +10.0 8.0 0.0, +10.0 7.0 0.0, +10.0 6.0 0.0, +10.0 5.0 0.0, +10.0 4.0 0.0, +10.0 3.0 0.0, +10.0 2.0 0.0, +10.0 1.0 0.0, +10.0 0.0 0.0, +9.0 0.0 0.0, +8.0 0.0 0.0, +7.0 0.0 0.0, +6.0 0.0 0.0, +5.0 0.0 0.0, +4.0 0.0 0.0, +3.0 0.0 0.0, +2.0 0.0 0.0, +1.0 0.0 0.0, +0.0 0.0 0.0, +-1.0 0.0 0.0'/> + </LineSet> + </Shape> + <Transform DEF='AnimationTransform'> + <Transform rotation='0 0 1 1.57'> + <Shape> + <Appearance USE='TrackAppearance'/> + <Cone bottomRadius='0.5'/> + </Shape> + </Transform> + </Transform> + <ROUTE fromField='value_changed' fromNode='testing123Positions' toField='translation' toNode='AnimationTransform'/> + <ROUTE fromField='value_changed' fromNode='testing123Orientations' toField='rotation' toNode='AnimationTransform'/> + </Scene> +</X3D> + +================================= +[DisChannel ExampleTrackInterpolation] *** [CommentPdu COMPLETE_EVENT_REPORT] [MV3500 TrackSimulationProgram, runSimulation() completed successfully] + +PduRecorder.stop() closing recorder log file: + C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog.dislog +[DisChannel ExampleTrackInterpolation] complete. +BUILD SUCCESSFUL (total time: 14 seconds) diff --git a/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolationPduCaptureLog.dislog b/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolationPduCaptureLog.dislog new file mode 100644 index 0000000000000000000000000000000000000000..91da4fe59543b1dede936ac1c9c2e76af040f476 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/ExampleTrackInterpolationPduCaptureLog.dislog @@ -0,0 +1,178 @@ +# Start, ENCODING_PLAINTEXT, [PduRecorder] 20220625_204753, DIS capture file, .\pduLog\PduCaptureLog.dislog +# Timestamp(8 bytes),ProtocolVersion,CompatibilityVersion,ExerciseID,PduType,PduStatus,HeaderLength,PduLength,then PDU-specific data +# ============================================= +# DisPduType 11 CREATE_ENTITY, Session time 20:47:53.3, session duration 00:00:00.0, Pdu timestamp -866966591 15:56:49.0, simulation stream interval 0 00:00:00.0 +0,0,68,24,-51,-31,-114,-59,7,4,11,5,-52,83,35,-63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 11 CREATE_ENTITY, Session time 20:47:53.3, session duration 00:00:00.0, Pdu timestamp -866966591 15:56:49.0, simulation stream interval 0 00:00:00.0 +0,0,0,0,0,94,-65,-36,7,4,11,5,-52,83,35,-63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:53.3, session duration 00:00:00.0, Pdu timestamp 0 00:00:00.0, simulation stream interval 866966591 08:03:11.0 +0,0,0,0,0,110,-124,-108,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-81,-46,0,0,1,64,83,105,109,117,108,97,116,105,111,110,32,116,105,109,101,115,116,101,112,32,100,117,114,97,116,105,111,110,32,49,46,48,32,115,101,99,111,110,100,115 +# DisPduType 01 ENTITY_STATE, Session time 20:47:53.4, session duration 00:00:00.1, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,8,49,-107,64,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:53.5, session duration 00:00:00.2, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,14,-56,97,-112,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:53.6, session duration 00:00:00.3, Pdu timestamp 0 00:00:00.0, simulation stream interval 866966591 08:03:11.0 +0,0,0,0,21,-92,-118,-124,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,16,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,32,97,116,32,116,105,109,101,32,48,46,48,0,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:53.7, session duration 00:00:00.4, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,28,47,-72,56,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:53.9, session duration 00:00:00.5, Pdu timestamp 0 00:00:00.0, simulation stream interval 866966591 08:03:11.0 +0,0,0,0,34,-107,-119,20,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,16,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,32,97,116,32,116,105,109,101,32,49,46,48,0,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:54.0, session duration 00:00:00.6, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,41,31,112,56,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:54.1, session duration 00:00:00.7, Pdu timestamp 1 00:00:01.0, simulation stream interval 866966592 08:03:12.0 +0,0,0,0,47,125,125,-8,7,1,22,5,0,0,0,1,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,16,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,32,97,116,32,116,105,109,101,32,50,46,48,0,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:54.2, session duration 00:00:00.9, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,54,11,26,84,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:54.3, session duration 00:00:01.0, Pdu timestamp 1 00:00:01.0, simulation stream interval 866966592 08:03:12.0 +0,0,0,0,60,98,-17,-128,7,1,22,5,0,0,0,1,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,16,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,52,32,97,116,32,116,105,109,101,32,51,46,48,0,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:54.4, session duration 00:00:01.1, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,66,-26,43,56,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:54.5, session duration 00:00:01.2, Pdu timestamp 2 00:00:02.0, simulation stream interval 866966593 08:03:13.0 +0,0,0,0,73,95,-44,-116,7,1,22,5,0,0,0,2,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,16,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,53,32,97,116,32,116,105,109,101,32,52,46,48,0,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:54.6, session duration 00:00:01.3, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,79,-5,107,8,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:54.7, session duration 00:00:01.4, Pdu timestamp 2 00:00:02.0, simulation stream interval 866966593 08:03:13.0 +0,0,0,0,86,113,-29,-12,7,1,22,5,0,0,0,2,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,16,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,54,32,97,116,32,116,105,109,101,32,53,46,48,0,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:54.8, session duration 00:00:01.5, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,92,-20,94,68,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:54.9, session duration 00:00:01.6, Pdu timestamp 3 00:00:03.0, simulation stream interval 866966594 08:03:14.0 +0,0,0,0,99,87,-26,104,7,1,22,5,0,0,0,3,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,16,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,55,32,97,116,32,116,105,109,101,32,54,46,48,0,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:55.1, session duration 00:00:01.7, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,106,8,-31,16,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:55.2, session duration 00:00:01.8, Pdu timestamp 3 00:00:03.0, simulation stream interval 866966594 08:03:14.0 +0,0,0,0,112,99,126,-68,7,1,22,5,0,0,0,3,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,16,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,56,32,97,116,32,116,105,109,101,32,55,46,48,0,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:55.3, session duration 00:00:01.9, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,119,0,-33,-48,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:55.4, session duration 00:00:02.1, Pdu timestamp 3 00:00:03.0, simulation stream interval 866966594 08:03:14.0 +0,0,0,0,125,-120,-29,-64,7,1,22,5,0,0,0,3,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,16,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,57,32,97,116,32,116,105,109,101,32,56,46,48,0,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:55.5, session duration 00:00:02.2, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,-124,9,15,124,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:55.6, session duration 00:00:02.3, Pdu timestamp 4 00:00:04.0, simulation stream interval 866966595 08:03:15.0 +0,0,0,0,-118,108,83,56,7,1,22,5,0,0,0,4,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,24,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,48,32,97,116,32,116,105,109,101,32,57,46,48,0,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:55.7, session duration 00:00:02.4, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,-112,-22,97,40,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:55.8, session duration 00:00:02.5, Pdu timestamp 4 00:00:04.0, simulation stream interval 866966595 08:03:15.0 +0,0,0,0,-105,100,-125,48,7,1,22,5,0,0,0,4,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,49,32,97,116,32,116,105,109,101,32,49,48,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:55.9, session duration 00:00:02.6, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,-99,-48,47,-88,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:56.0, session duration 00:00:02.7, Pdu timestamp 5 00:00:05.0, simulation stream interval 866966596 08:03:16.0 +0,0,0,0,-92,78,42,-40,7,1,22,5,0,0,0,5,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,50,32,97,116,32,116,105,109,101,32,49,49,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:56.1, session duration 00:00:02.8, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,-86,-50,21,-68,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,64,8,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:56.3, session duration 00:00:02.9, Pdu timestamp 5 00:00:05.0, simulation stream interval 866966596 08:03:16.0 +0,0,0,0,-79,103,10,100,7,1,22,5,0,0,0,5,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,51,32,97,116,32,116,105,109,101,32,49,50,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:56.4, session duration 00:00:03.0, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,-73,-47,81,112,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,64,16,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:56.5, session duration 00:00:03.1, Pdu timestamp 6 00:00:06.0, simulation stream interval 866966597 08:03:17.0 +0,0,0,0,-66,38,14,108,7,1,22,5,0,0,0,6,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,52,32,97,116,32,116,105,109,101,32,49,51,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:56.6, session duration 00:00:03.2, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,-60,-97,-21,-76,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,64,20,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:56.7, session duration 00:00:03.4, Pdu timestamp 6 00:00:06.0, simulation stream interval 866966597 08:03:17.0 +0,0,0,0,-53,8,109,60,7,1,22,5,0,0,0,6,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,53,32,97,116,32,116,105,109,101,32,49,52,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:56.8, session duration 00:00:03.5, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,-47,-82,-117,108,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,64,24,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:56.9, session duration 00:00:03.6, Pdu timestamp 7 00:00:07.0, simulation stream interval 866966598 08:03:18.0 +0,0,0,0,-40,6,-105,-84,7,1,22,5,0,0,0,7,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,54,32,97,116,32,116,105,109,101,32,49,53,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:57.0, session duration 00:00:03.7, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,-34,-79,-85,0,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,64,28,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:57.1, session duration 00:00:03.8, Pdu timestamp 7 00:00:07.0, simulation stream interval 866966598 08:03:18.0 +0,0,0,0,-27,58,-119,76,7,1,22,5,0,0,0,7,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,55,32,97,116,32,116,105,109,101,32,49,54,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:57.2, session duration 00:00:03.9, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,-21,-80,78,36,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,64,32,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:57.3, session duration 00:00:04.0, Pdu timestamp 7 00:00:07.0, simulation stream interval 866966598 08:03:18.0 +0,0,0,0,-14,29,-38,76,7,1,22,5,0,0,0,7,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,56,32,97,116,32,116,105,109,101,32,49,55,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:57.4, session duration 00:00:04.1, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,0,-8,-97,-104,-60,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,64,34,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:57.6, session duration 00:00:04.2, Pdu timestamp 8 00:00:08.0, simulation stream interval 866966599 08:03:19.0 +0,0,0,0,-1,39,-49,24,7,1,22,5,0,0,0,8,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,57,32,97,116,32,116,105,109,101,32,49,56,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:57.7, session duration 00:00:04.3, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,5,-72,-92,16,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,63,-128,0,0,0,0,0,0,0,0,0,0,64,36,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:57.8, session duration 00:00:04.5, Pdu timestamp 8 00:00:08.0, simulation stream interval 866966599 08:03:19.0 +0,0,0,1,12,67,-53,-24,7,1,22,5,0,0,0,8,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,48,32,97,116,32,116,105,109,101,32,49,57,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:57.9, session duration 00:00:04.6, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,18,-34,101,68,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,-65,-128,0,0,0,0,0,0,64,36,0,0,0,0,0,0,64,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:58.0, session duration 00:00:04.7, Pdu timestamp 9 00:00:09.0, simulation stream interval 866966600 08:03:20.0 +0,0,0,1,25,103,79,-84,7,1,22,5,0,0,0,9,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,49,32,97,116,32,116,105,109,101,32,50,48,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:58.1, session duration 00:00:04.8, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,32,31,86,60,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,-65,-128,0,0,0,0,0,0,64,36,0,0,0,0,0,0,64,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:58.2, session duration 00:00:04.9, Pdu timestamp 9 00:00:09.0, simulation stream interval 866966600 08:03:20.0 +0,0,0,1,38,-86,23,-68,7,1,22,5,0,0,0,9,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,50,32,97,116,32,116,105,109,101,32,50,49,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:58.3, session duration 00:00:05.0, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,45,53,-119,104,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,-65,-128,0,0,0,0,0,0,64,36,0,0,0,0,0,0,64,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:58.4, session duration 00:00:05.1, Pdu timestamp 10 00:00:10.0, simulation stream interval 866966601 08:03:21.0 +0,0,0,1,51,-81,63,-96,7,1,22,5,0,0,0,10,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,51,32,97,116,32,116,105,109,101,32,50,50,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:58.5, session duration 00:00:05.2, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,58,71,62,48,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,-65,-128,0,0,0,0,0,0,64,36,0,0,0,0,0,0,64,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:58.7, session duration 00:00:05.3, Pdu timestamp 10 00:00:10.0, simulation stream interval 866966601 08:03:21.0 +0,0,0,1,64,-59,-10,112,7,1,22,5,0,0,0,10,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,52,32,97,116,32,116,105,109,101,32,50,51,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:58.8, session duration 00:00:05.4, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,71,39,-68,36,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,-65,-128,0,0,0,0,0,0,64,36,0,0,0,0,0,0,64,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:58.9, session duration 00:00:05.5, Pdu timestamp 10 00:00:10.0, simulation stream interval 866966601 08:03:21.0 +0,0,0,1,77,-60,98,-128,7,1,22,5,0,0,0,10,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,53,32,97,116,32,116,105,109,101,32,50,52,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:59.0, session duration 00:00:05.7, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,84,99,92,-112,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,-65,-128,0,0,0,0,0,0,64,36,0,0,0,0,0,0,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:59.1, session duration 00:00:05.8, Pdu timestamp 11 00:00:11.0, simulation stream interval 866966602 08:03:22.0 +0,0,0,1,90,-51,-125,48,7,1,22,5,0,0,0,11,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,54,32,97,116,32,116,105,109,101,32,50,53,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:59.2, session duration 00:00:05.9, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,97,60,104,-88,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,-65,-128,0,0,0,0,0,0,64,36,0,0,0,0,0,0,64,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:59.3, session duration 00:00:06.0, Pdu timestamp 11 00:00:11.0, simulation stream interval 866966602 08:03:22.0 +0,0,0,1,103,-94,95,4,7,1,22,5,0,0,0,11,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,55,32,97,116,32,116,105,109,101,32,50,54,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:59.4, session duration 00:00:06.1, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,110,34,-40,-32,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,-65,-128,0,0,0,0,0,0,64,36,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:59.5, session duration 00:00:06.2, Pdu timestamp 12 00:00:12.0, simulation stream interval 866966603 08:03:23.0 +0,0,0,1,116,-85,-76,12,7,1,22,5,0,0,0,12,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,56,32,97,116,32,116,105,109,101,32,50,55,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:59.6, session duration 00:00:06.3, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,123,71,-126,0,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,-65,-128,0,0,0,0,0,0,64,36,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:47:59.7, session duration 00:00:06.4, Pdu timestamp 12 00:00:12.0, simulation stream interval 866966603 08:03:23.0 +0,0,0,1,-127,-43,35,-44,7,1,22,5,0,0,0,12,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,57,32,97,116,32,116,105,109,101,32,50,56,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:47:59.9, session duration 00:00:06.5, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,-120,111,23,-112,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,-65,-128,0,0,0,0,0,0,64,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:00.0, session duration 00:00:06.6, Pdu timestamp 13 00:00:13.0, simulation stream interval 866966604 08:03:24.0 +0,0,0,1,-114,-32,-86,-108,7,1,22,5,0,0,0,13,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,48,32,97,116,32,116,105,109,101,32,50,57,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:48:00.1, session duration 00:00:06.8, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,-107,102,-7,104,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,-65,-128,0,0,0,0,0,0,0,0,0,0,64,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:00.2, session duration 00:00:06.9, Pdu timestamp 13 00:00:13.0, simulation stream interval 866966604 08:03:24.0 +0,0,0,1,-101,-21,59,-96,7,1,22,5,0,0,0,13,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,49,32,97,116,32,116,105,109,101,32,51,48,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:48:00.3, session duration 00:00:07.0, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,-94,125,49,-88,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,-65,-128,0,0,0,0,0,0,0,0,0,0,64,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:00.4, session duration 00:00:07.1, Pdu timestamp 14 00:00:14.0, simulation stream interval 866966605 08:03:25.0 +0,0,0,1,-88,-11,-19,-32,7,1,22,5,0,0,0,14,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,50,32,97,116,32,116,105,109,101,32,51,49,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:48:00.5, session duration 00:00:07.2, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,-81,-121,11,-128,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,-65,-128,0,0,0,0,0,0,0,0,0,0,64,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:00.6, session duration 00:00:07.3, Pdu timestamp 14 00:00:14.0, simulation stream interval 866966605 08:03:25.0 +0,0,0,1,-74,17,5,0,7,1,22,5,0,0,0,14,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,51,32,97,116,32,116,105,109,101,32,51,50,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:48:00.7, session duration 00:00:07.4, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,-68,-97,-18,-12,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,-65,-128,0,0,0,0,0,0,0,0,0,0,64,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:00.8, session duration 00:00:07.5, Pdu timestamp 14 00:00:14.0, simulation stream interval 866966605 08:03:25.0 +0,0,0,1,-61,26,-52,124,7,1,22,5,0,0,0,14,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,52,32,97,116,32,116,105,109,101,32,51,51,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:48:01.0, session duration 00:00:07.6, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,-55,-84,45,76,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,-65,-128,0,0,0,0,0,0,0,0,0,0,64,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:01.1, session duration 00:00:07.7, Pdu timestamp 15 00:00:15.0, simulation stream interval 866966606 08:03:26.0 +0,0,0,1,-48,10,49,72,7,1,22,5,0,0,0,15,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,53,32,97,116,32,116,105,109,101,32,51,52,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:48:01.2, session duration 00:00:07.8, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,-42,-123,87,-36,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,-65,-128,0,0,0,0,0,0,0,0,0,0,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:01.3, session duration 00:00:08.0, Pdu timestamp 15 00:00:15.0, simulation stream interval 866966606 08:03:26.0 +0,0,0,1,-35,19,10,124,7,1,22,5,0,0,0,15,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,54,32,97,116,32,116,105,109,101,32,51,53,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:48:01.4, session duration 00:00:08.1, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,-29,-128,86,48,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,-65,-128,0,0,0,0,0,0,0,0,0,0,64,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:01.5, session duration 00:00:08.2, Pdu timestamp 16 00:00:16.0, simulation stream interval 866966607 08:03:27.0 +0,0,0,1,-23,-3,-42,84,7,1,22,5,0,0,0,16,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,55,32,97,116,32,116,105,109,101,32,51,54,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:48:01.6, session duration 00:00:08.3, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,-16,-82,48,12,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,-65,-128,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:01.7, session duration 00:00:08.4, Pdu timestamp 16 00:00:16.0, simulation stream interval 866966607 08:03:27.0 +0,0,0,1,-9,54,-27,-72,7,1,22,5,0,0,0,16,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,56,32,97,116,32,116,105,109,101,32,51,55,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:48:01.8, session duration 00:00:08.5, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,1,-3,-66,3,-8,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,-65,-128,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:01.9, session duration 00:00:08.6, Pdu timestamp 17 00:00:17.0, simulation stream interval 866966608 08:03:28.0 +0,0,0,2,4,57,-79,-76,7,1,22,5,0,0,0,17,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,57,32,97,116,32,116,105,109,101,32,51,56,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:48:02.0, session duration 00:00:08.7, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,2,10,-31,-20,-124,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,-65,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:02.2, session duration 00:00:08.8, Pdu timestamp 17 00:00:17.0, simulation stream interval 866966608 08:03:28.0 +0,0,0,2,17,60,-68,-8,7,1,22,5,0,0,0,17,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,52,48,32,97,116,32,116,105,109,101,32,51,57,46,48,0,0,0,0 +# DisPduType 01 ENTITY_STATE, Session time 20:48:02.3, session duration 00:00:08.9, Pdu timestamp 1193 00:19:53.0, simulation stream interval 866967784 08:23:04.0 +0,0,0,2,23,-62,-7,-44,7,1,1,1,0,0,4,-87,0,-112,40,0,0,1,0,2,0,3,1,0,1,3,0,-51,62,2,1,0,0,0,0,-31,0,0,0,0,-65,-128,0,0,0,0,0,0,0,0,0,0,-65,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,116,114,97,99,107,32,112,97,116,104,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:02.4, session duration 00:00:09.0, Pdu timestamp 17 00:00:17.0, simulation stream interval 866966608 08:03:28.0 +0,0,0,2,30,60,-95,-104,7,1,22,5,0,0,0,17,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,-81,-46,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,0,-81,-46,0,0,1,32,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,52,49,32,97,116,32,116,105,109,101,32,52,48,46,48,0,0,0,0 +# DisPduType 22 COMMENT, Session time 20:48:02.5, session duration 00:00:09.2, Pdu timestamp 18 00:00:18.0, simulation stream interval 866966609 08:03:29.0 +0,0,0,2,37,111,-20,104,7,1,22,5,0,0,0,18,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,9,90,-90,0,0,0,-24,77,86,51,53,48,48,32,84,114,97,99,107,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,0,0,9,90,-90,0,0,1,48,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,99,111,109,112,108,101,116,101,100,32,115,117,99,99,101,115,115,102,117,108,108,121,0,0 +# Finish, ENCODING_PLAINTEXT, [PduRecorder] 20220625_204804, DIS capture file, .\pduLog\PduCaptureLog.dislog diff --git a/assignments/src/src/OpenDis7Examples/PduListenerSaver.java b/assignments/src/src/OpenDis7Examples/PduListenerSaver.java new file mode 100644 index 0000000000000000000000000000000000000000..c70305435c72512a91d9e52f68f569c0969a215e --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/PduListenerSaver.java @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2008-2022, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html and license.txt + */ +package OpenDis7Examples; + +import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface; +import edu.nps.moves.dis7.utilities.stream.PduRecorder; +import java.util.Scanner; + +/** Class to leverage the {@link edu.nps.moves.dis7.utilities.stream.PduRecorder} + * with PDU log saving console controls for resume, pause and quit. + * + * PduSaver.java created on Aug 21, 2019 + * Renamed PduListenerSaver + * MOVES Institute Naval Postgraduate School, Monterey, CA, USA www.nps.edu + * + * @author Mike Bailey, jmbailey@nps.edu + * @version $Id$ + */ +public class PduListenerSaver +{ + private final static String DEFAULT_OUTPUT_DIRECTORY = "pduLog"; + + /** Default multicast group address <code>229.1.2.3</code> for send and receive connections. + * @see <a href="https://en.wikipedia.org/wiki/Multicast_address" target="_blank">https://en.wikipedia.org/wiki/Multicast_address</a> */ + public static String DEFAULT_DIS_ADDRESS = DisThreadedNetworkInterface.DEFAULT_DIS_ADDRESS; + + /** Default socket port <code>3000</code>, matches Wireshark DIS capture default + * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)" target="_blank">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> */ + public static int DEFAULT_DIS_PORT = DisThreadedNetworkInterface.DEFAULT_DIS_PORT; + + private enum mystate + { + RUNNING, + PAUSED; + } + private String disAddress; + private int disPort; + + /** + * Object constructor using default multicast address and port + */ + public PduListenerSaver() + { + this(DEFAULT_DIS_ADDRESS, DEFAULT_DIS_PORT); + } + + /** + * Object constructor using specified multicast address and port + * @param address the multicast group or unicast address to utilize + * @param port the multicast port to utilize + */ + public PduListenerSaver(String address, int port) + { + disAddress = address; + disPort = port; + } + + /** + * Command-line invocation (CLI), execution starts here + * @param args command-line arguments + */ + public static void main(String[] args) + { + String outputDirectory = DEFAULT_OUTPUT_DIRECTORY; + String multicastAddress = DEFAULT_DIS_ADDRESS; + int port = DEFAULT_DIS_PORT; + + System.out.println("OpenDis7Examples.PduListenerSaver started..."); + + switch (args.length) + { + case 0: + // use default values + break; + case 1: + outputDirectory = args[0]; + break; + case 3: + outputDirectory = args[0]; + multicastAddress = args[1]; + port = Integer.parseInt(args[2]); + break; + default: + // Common-sense practice is to print help message if invocation is problematic + System.err.println("Usage: PduListenerSaver() or PduListenerSaver(\"outputdir\") or PduListenerSaver(\"outputDirectory\",\"multicastAddress\", port"); + System.exit(1); + } + System.out.println("Beginning PduListenerSaver (" + multicastAddress + ":" + port + ") to directory " + outputDirectory); + + mystate state = mystate.RUNNING; + Scanner terminalKeyboardScanner = new Scanner(System.in); + PduRecorder pduRecorder = new PduRecorder(outputDirectory, multicastAddress, port); // assumes save + pduRecorder.setDescriptor("PduListenerSaver"); + pduRecorder.setVerbose(true); + pduRecorder.start(); // begin running + + while (true) // monitor user input via keyboard + { + System.out.println("Type p/enter to pause, r/enter to resume, q/enter to quit"); + String line = terminalKeyboardScanner.nextLine(); + if (line.equalsIgnoreCase("p") && state == mystate.RUNNING) + { + pduRecorder.pause(); + state = mystate.PAUSED; + System.out.println("... state is now PAUSED"); + } + else if (line.equalsIgnoreCase("p")) + { + pduRecorder.pause(); + state = mystate.PAUSED; + System.out.println("... state is still PAUSED"); + } + else if (line.equalsIgnoreCase("r") && state == mystate.PAUSED) + { + pduRecorder.resume(); + state = mystate.RUNNING; + System.out.println("... state is now RUNNING"); + } + else if (line.equalsIgnoreCase("r")) + { + pduRecorder.resume(); + state = mystate.RUNNING; + System.out.println("... state is still RUNNING"); + } + else if (line.equalsIgnoreCase("q")) + { + pduRecorder.stop(); + System.out.println("... QUIT"); + break; + } + } + System.out.println("Finished PduListenerSaver pdu recording, saved to file:"); + System.out.println(pduRecorder.getLogFilePath()); + } +} diff --git a/assignments/src/src/OpenDis7Examples/PduListenerSaverCaptureLog.dislog b/assignments/src/src/OpenDis7Examples/PduListenerSaverCaptureLog.dislog new file mode 100644 index 0000000000000000000000000000000000000000..f588b215e5f48a026c97ea42e4660d8a7b3dcc32 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/PduListenerSaverCaptureLog.dislog @@ -0,0 +1,149 @@ +# Start, ENCODING_PLAINTEXT, [PduRecorder PduListenerSaver] 20220620_132825, DIS capture file, pduLog\PduCaptureLog.dislog +# DisPduType,ReceiptDate,ReceiptTime +# Timestamp(8 bytes),ProtocolVersion,CompatibilityVersion,ExcerciseID,PduType,PduStatus,HeaderLength,PduLength,then PDU-specific data +# ============================================= +# DisPduType 01 ENTITY_STATE,undated,00:00:00.0 +0,0,0,0,0,0,0,0,7,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,64,0,0,0,0,0,0,0,64,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65,108,108,80,100,117,83,101,110,100,101,0,0,0,0 +# DisPduType 02 FIRE,undated,00:00:00.0 +0,0,0,0,1,69,-16,60,7,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 03 DETONATION,undated,00:00:00.0 +0,0,0,0,1,106,-90,72,7,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 04 COLLISION,undated,00:00:00.0 +0,0,0,0,1,118,45,-40,7,0,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 05 SERVICE_REQUEST,undated,00:00:00.0 +0,0,0,0,1,118,45,-40,7,0,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 06 RESUPPLY_OFFER,undated,00:00:00.0 +0,0,0,0,1,-126,-93,-80,7,0,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 07 RESUPPLY_RECEIVED,undated,00:00:00.0 +0,0,0,0,1,-120,7,-60,7,0,7,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 08 RESUPPLY_CANCEL,undated,00:00:00.0 +0,0,0,0,1,-120,7,-60,7,0,8,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 09 REPAIR_COMPLETE,undated,00:00:00.0 +0,0,0,0,1,-113,91,-16,7,0,9,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 10 REPAIR_RESPONSE,undated,00:00:00.0 +0,0,0,0,1,-105,25,48,7,0,10,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 11 CREATE_ENTITY,undated,00:00:00.0 +0,0,0,0,1,-105,25,48,7,0,11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 12 REMOVE_ENTITY,undated,00:00:00.0 +0,0,0,0,1,-105,25,48,7,0,12,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 13 START_RESUME,undated,00:00:00.0 +0,0,0,0,1,-105,25,48,7,0,13,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 14 STOP_FREEZE,undated,00:00:00.0 +0,0,0,0,1,-105,25,48,7,0,14,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 15 ACKNOWLEDGE,undated,00:00:00.0 +0,0,0,0,1,-75,-83,80,7,0,15,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 +# DisPduType 16 ACTION_REQUEST,undated,00:00:00.0 +0,0,0,0,1,-56,-114,-24,7,0,16,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 17 ACTION_RESPONSE,undated,00:00:00.0 +0,0,0,0,1,-56,-114,-24,7,0,17,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 18 DATA_QUERY,undated,00:00:00.0 +0,0,0,0,1,-41,-59,12,7,0,18,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 19 SET_DATA,undated,00:00:00.0 +0,0,0,0,1,-41,-59,12,7,0,19,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 20 DATA,undated,00:00:00.0 +0,0,0,0,1,-41,-59,12,7,0,20,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 21 EVENT_REPORT,undated,00:00:00.0 +0,0,0,0,1,-24,-84,100,7,0,21,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 22 COMMENT,undated,00:00:00.0 +0,0,0,0,1,-19,-56,-4,7,0,22,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,-128,72,101,108,108,111,32,67,111,109,109,101,110,116,80,68,85,0,0,0,1,0,0,1,112,72,101,114,101,32,105,115,32,97,32,115,101,99,111,110,100,32,108,105,110,101,32,111,102,32,116,101,120,116,32,105,110,32,116,104,105,115,32,99,111,109,109,101,110,116,46,0,0 +# DisPduType 23 ELECTROMAGNETIC_EMISSION,undated,00:00:00.0 +0,0,0,0,2,-102,82,-124,7,0,23,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 24 DESIGNATOR,undated,00:00:00.0 +0,0,0,0,2,-101,58,-16,7,0,24,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 25 TRANSMITTER,undated,00:00:00.0 +0,0,0,0,2,-72,105,-92,7,0,25,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 26 SIGNAL,undated,00:00:00.0 +0,0,0,0,2,-13,-83,-24,7,0,26,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0 +# DisPduType 27 RECEIVER,undated,00:00:00.0 +0,0,0,0,3,8,127,-104,7,0,27,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 28 IDENTIFICATION_FRIEND_OR_FOE,undated,00:00:00.0 +0,0,0,0,3,8,127,-104,7,0,28,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 29 UNDERWATER_ACOUSTIC,undated,00:00:00.0 +0,0,0,0,3,49,102,-80,7,0,29,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 30 SUPPLEMENTAL_EMISSION_ENTITY_STATE,undated,00:00:00.0 +0,0,0,0,3,49,102,-80,7,0,30,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 31 INTERCOM_SIGNAL,undated,00:00:00.0 +0,0,0,0,3,64,-98,100,7,0,31,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0 +# DisPduType 32 INTERCOM_CONTROL,undated,00:00:00.0 +0,0,0,0,3,75,-20,-120,7,0,32,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 33 AGGREGATE_STATE,undated,00:00:00.0 +0,0,0,0,3,83,-58,-80,7,0,33,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 34 ISGROUPOF,undated,00:00:00.0 +0,0,0,0,3,119,-100,-124,7,0,34,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 35 TRANSFER_OWNERSHIP,undated,00:00:00.0 +0,0,0,0,3,-123,-92,80,7,0,35,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 36 ISPARTOF,undated,00:00:00.0 +0,0,0,0,3,-107,45,68,7,0,36,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 37 MINEFIELD_STATE,undated,00:00:00.0 +0,0,0,0,3,-91,66,-40,7,0,37,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 38 MINEFIELD_QUERY,undated,00:00:00.0 +0,0,0,0,3,-58,100,-32,7,0,38,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 39 MINEFIELD_DATA,undated,00:00:00.0 +0,0,0,0,3,-53,92,-64,7,0,39,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 40 MINEFIELD_RESPONSE_NACK,undated,00:00:00.0 +0,0,0,0,3,-53,92,-64,7,0,40,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 41 ENVIRONMENTAL_PROCESS,undated,00:00:00.0 +0,0,0,0,3,-39,43,-124,7,0,41,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 42 GRIDDED_DATA,undated,00:00:00.0 +0,0,0,0,3,-23,-67,-76,7,0,42,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 43 POINT_OBJECT_STATE,undated,00:00:00.0 +0,0,0,0,3,-8,75,124,7,0,43,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 44 LINEAR_OBJECT_STATE,undated,00:00:00.0 +0,0,0,0,4,26,43,-64,7,0,44,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 45 AREAL_OBJECT_STATE,undated,00:00:00.0 +0,0,0,0,4,45,-103,-8,7,0,45,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 46 TIME_SPACE_POSITION_INFORMATION,undated,00:00:00.0 +0,0,0,0,4,53,115,88,7,0,46,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 47 APPEARANCE,undated,00:00:00.0 +0,0,0,0,4,90,-51,-40,7,0,47,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 48 ARTICULATED_PARTS,undated,00:00:00.0 +0,0,0,0,4,109,44,-108,7,0,48,11,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 49 LIVE_ENTITY_FIRE,undated,00:00:00.0 +0,0,0,0,4,111,121,-92,7,0,49,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 50 LIVE_ENTITY_DETONATION,undated,00:00:00.0 +0,0,0,0,4,111,121,-92,7,0,50,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 51 CREATE_ENTITY_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,111,121,-92,7,0,51,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 52 REMOVE_ENTITY_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-126,-22,-104,7,0,52,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 53 START_RESUME_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-124,99,-16,7,0,53,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 54 STOP_FREEZE_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-124,99,-16,7,0,54,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 55 ACKNOWLEDGE_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-124,99,-16,7,0,55,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 +# DisPduType 56 ACTION_REQUEST_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-124,99,-16,7,0,56,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 57 ACTION_RESPONSE_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-112,-38,44,7,0,57,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 58 DATA_QUERY_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-107,40,-124,7,0,58,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 59 SET_DATA_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-107,40,-124,7,0,59,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 60 DATA_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-107,40,-124,7,0,60,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 61 EVENT_REPORT_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-107,40,-124,7,0,61,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 62 COMMENT_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-107,40,-124,7,0,62,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 63 RECORD_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-92,99,88,7,0,63,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 64 SET_RECORD_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-84,121,68,7,0,64,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 65 RECORD_QUERY_RELIABLE,undated,00:00:00.0 +0,0,0,0,4,-84,121,68,7,0,65,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 66 COLLISION_ELASTIC,undated,00:00:00.0 +0,0,0,0,4,-72,68,104,7,0,66,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 67 ENTITY_STATE_UPDATE,undated,00:00:00.0 +0,0,0,0,4,-65,11,-12,7,0,67,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 68 DIRECTED_ENERGY_FIRE,undated,00:00:00.0 +0,0,0,0,4,-62,-57,8,7,0,68,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 69 ENTITY_DAMAGE_STATUS,undated,00:00:00.0 +0,0,0,0,4,-44,79,80,7,0,69,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 70 INFORMATION_OPERATIONS_ACTION,undated,00:00:00.0 +0,0,0,0,4,-30,-123,-4,7,0,70,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 71 INFORMATION_OPERATIONS_REPORT,undated,00:00:00.0 +0,0,0,0,4,-5,-4,-68,7,0,71,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# DisPduType 72 ATTRIBUTE,undated,00:00:00.0 +0,0,0,0,4,-4,-111,44,7,0,72,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0 +# Finish, ENCODING_PLAINTEXT, [PduRecorder PduListenerSaver] 20220620_132833, DIS capture file, pduLog\PduCaptureLog.dislog diff --git a/assignments/src/src/OpenDis7Examples/PduListenerSaverLog.txt b/assignments/src/src/OpenDis7Examples/PduListenerSaverLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..79f44b30cc3568fa611e96f4606179495373e0bc Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/PduListenerSaverLog.txt differ diff --git a/assignments/src/src/OpenDis7Examples/PduReaderPlayer.java b/assignments/src/src/OpenDis7Examples/PduReaderPlayer.java new file mode 100644 index 0000000000000000000000000000000000000000..533dd336c1790f2b07203d98e58ab8dfff8be665 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/PduReaderPlayer.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2008-2022, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html and license.txt + */ +package OpenDis7Examples; + +import edu.nps.moves.dis7.utilities.stream.PduPlayer; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Scanner; + +/** Class to leverage the {@link edu.nps.moves.dis7.utilities.stream.PduPlayer} + * with PDU log playback console controls for resume, pause and quit. + * + * PduSaver.java created on Aug 21, 2019 + * Renamed PduReaderPlayer + * MOVES Institute Naval Postgraduate School, Monterey, CA, USA www.nps.edu + * + * @author Mike Bailey, jmbailey@nps.edu + * @version $Id$ + */ +public class PduReaderPlayer +{ + /** Default constructor */ + public PduReaderPlayer() + { + // default constructor + } + private final static String DEFAULT_OUTPUT_DIRECTORY = "pduLog"; + /** Default multicast group address we send on. + * @see <a href="https://en.wikipedia.org/wiki/Multicast_address" target="_blank">https://en.wikipedia.org/wiki/Multicast_address</a> */ + public static final String DEFAULT_MULTICAST_ADDRESS = AllPduSender.DEFAULT_MULTICAST_ADDRESS; + /** Default multicast port + * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)" target="_blank">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> */ + public static final int DEFAULT_MULTICAST_PORT = AllPduSender.DEFAULT_MULTICAST_PORT; + + private enum mystate + { + RUNNING, + PAUSED; + } + + /** Command-line invocation (CLI) of program, execution starts here + * @param args command-line arguments + */ + public static void main(String[] args) + { + String outputDirectory = DEFAULT_OUTPUT_DIRECTORY; + String multicastAddress = DEFAULT_MULTICAST_ADDRESS; + int multicastPort = DEFAULT_MULTICAST_PORT; + boolean sendToNet = true; + + System.out.println("OpenDis7Examples.PduReaderPlayer started..."); + + switch (args.length) { + case 0: + break; + case 1: + outputDirectory = args[0]; + sendToNet = Boolean.valueOf(args[1]); + break; + case 3: + outputDirectory = args[0]; + multicastAddress = args[1]; + multicastPort = Integer.parseInt(args[2]); + sendToNet = Boolean.valueOf(args[3]); + break; + default: + System.err.println("Usage: PduReaderPlayer() or \n" + + "PduReaderPlayer(\"outputdir\", \"sendToNet true/false\") or \n" + + "PduReaderPlayer(\"outputdir\", \"ipPort\", \"sendToNet true/false\") or \n" + + "PduReaderPlayer(\"outputdir\", \"multicast address\", \"ipPort\", \"sendToNet true/false\""); + System.exit(1); + } + + System.out.println("Beginning PduReaderPlayer (" + multicastAddress + ":" + multicastPort + ") to directory " + outputDirectory); + try + { + mystate state = mystate.RUNNING; + Scanner terminalKeyboardScanner = new Scanner(System.in); + PduPlayer pduPlayer = new PduPlayer(multicastAddress, multicastPort, Path.of(outputDirectory), sendToNet); + pduPlayer.begin(); + + while (true) // monitor user input via keyboard + { + System.out.println("Type p/enter to pause, r/enter to resume, q/enter to quit"); + String line = terminalKeyboardScanner.nextLine(); + if (line.equalsIgnoreCase("p") && state == mystate.RUNNING) { + pduPlayer.stopPause(); + state = mystate.PAUSED; + } + else if (line.equalsIgnoreCase("r") && state == mystate.PAUSED) { + pduPlayer.startResume(); + state = mystate.RUNNING; + } + else if (line.equalsIgnoreCase("q")) { + System.out.println("... QUIT"); + pduPlayer.end(); + break; + } + } + System.out.println("Ending pdu files playback for directory " + outputDirectory); + System.out.println("OpenDis7Examples.PduReaderPlayer complete."); + System.exit(0); // TODO not sure why this is necessary with Netbeans... + } + catch (IOException ex) { + System.err.println("Exception: " + ex.getClass().getSimpleName() + ": " + ex.getLocalizedMessage()); + } + } +} diff --git a/assignments/src/src/OpenDis7Examples/PduReaderPlayerLog.txt b/assignments/src/src/OpenDis7Examples/PduReaderPlayerLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..a4b3a9b5f631fcd4680468458cd95f461ed2748a --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/PduReaderPlayerLog.txt @@ -0,0 +1,93 @@ +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/PduReaderPlayer.java -Drun.class=OpenDis7Examples.PduReaderPlayer run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +OpenDis7Examples.PduReaderPlayer started... +Beginning PduReaderPlayer (239.1.2.3:3000) to directory pduLog +PduPlayer begin() playing DIS logs found in ancestor pduLog directory. +ENCODING_PLAINTEXT +Replaying PDU log file with ENCODING_PLAINTEXT: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog.dislog +Sent PDU: DisPduType 01 ENTITY_STATE +Sent PDU: DisPduType 02 FIRE +Sent PDU: DisPduType 03 DETONATION +Sent PDU: DisPduType 04 COLLISION +Sent PDU: DisPduType 05 SERVICE_REQUEST +Sent PDU: DisPduType 06 RESUPPLY_OFFER +Sent PDU: DisPduType 07 RESUPPLY_RECEIVED +Sent PDU: DisPduType 08 RESUPPLY_CANCEL +Sent PDU: DisPduType 09 REPAIR_COMPLETE +Sent PDU: DisPduType 10 REPAIR_RESPONSE +Sent PDU: DisPduType 11 CREATE_ENTITY +Sent PDU: DisPduType 12 REMOVE_ENTITY +Sent PDU: DisPduType 13 START_RESUME +Sent PDU: DisPduType 14 STOP_FREEZE +Sent PDU: DisPduType 15 ACKNOWLEDGE +Sent PDU: DisPduType 16 ACTION_REQUEST +Sent PDU: DisPduType 17 ACTION_RESPONSE +Sent PDU: DisPduType 18 DATA_QUERY +Sent PDU: DisPduType 19 SET_DATA +Sent PDU: DisPduType 20 DATA +Sent PDU: DisPduType 21 EVENT_REPORT +Sent PDU: DisPduType 22 COMMENT +Sent PDU: DisPduType 23 ELECTROMAGNETIC_EMISSION +Sent PDU: DisPduType 24 DESIGNATOR +Sent PDU: DisPduType 25 TRANSMITTER +Sent PDU: DisPduType 26 SIGNAL +Sent PDU: DisPduType 27 RECEIVER +Sent PDU: DisPduType 28 IDENTIFICATION_FRIEND_OR_FOE +Sent PDU: DisPduType 29 UNDERWATER_ACOUSTIC +Sent PDU: DisPduType 30 SUPPLEMENTAL_EMISSION_ENTITY_STATE +Sent PDU: DisPduType 31 INTERCOM_SIGNAL +Sent PDU: DisPduType 32 INTERCOM_CONTROL +Sent PDU: DisPduType 33 AGGREGATE_STATE +Sent PDU: DisPduType 34 ISGROUPOF +Sent PDU: DisPduType 35 TRANSFER_OWNERSHIP +Sent PDU: DisPduType 36 ISPARTOF +Sent PDU: DisPduType 37 MINEFIELD_STATE +Sent PDU: DisPduType 38 MINEFIELD_QUERY +Sent PDU: DisPduType 39 MINEFIELD_DATA +Sent PDU: DisPduType 40 MINEFIELD_RESPONSE_NACK +Sent PDU: DisPduType 41 ENVIRONMENTAL_PROCESS +Sent PDU: DisPduType 42 GRIDDED_DATA +Sent PDU: DisPduType 43 POINT_OBJECT_STATE +Sent PDU: DisPduType 44 LINEAR_OBJECT_STATE +Sent PDU: DisPduType 45 AREAL_OBJECT_STATE +Sent PDU: DisPduType 46 TIME_SPACE_POSITION_INFORMATION +Sent PDU: DisPduType 47 APPEARANCE +Sent PDU: DisPduType 48 ARTICULATED_PARTS +Sent PDU: DisPduType 49 LIVE_ENTITY_FIRE +Sent PDU: DisPduType 50 LIVE_ENTITY_DETONATION +Sent PDU: DisPduType 51 CREATE_ENTITY_RELIABLE +Sent PDU: DisPduType 52 REMOVE_ENTITY_RELIABLE +Sent PDU: DisPduType 53 START_RESUME_RELIABLE +Sent PDU: DisPduType 54 STOP_FREEZE_RELIABLE +Sent PDU: DisPduType 55 ACKNOWLEDGE_RELIABLE +Sent PDU: DisPduType 56 ACTION_REQUEST_RELIABLE +Sent PDU: DisPduType 57 ACTION_RESPONSE_RELIABLE +Sent PDU: DisPduType 58 DATA_QUERY_RELIABLE +Sent PDU: DisPduType 59 SET_DATA_RELIABLE +Sent PDU: DisPduType 60 DATA_RELIABLE +Sent PDU: DisPduType 61 EVENT_REPORT_RELIABLE +Sent PDU: DisPduType 62 COMMENT_RELIABLE +Sent PDU: DisPduType 63 RECORD_RELIABLE +Sent PDU: DisPduType 64 SET_RECORD_RELIABLE +Sent PDU: DisPduType 65 RECORD_QUERY_RELIABLE +Sent PDU: DisPduType 66 COLLISION_ELASTIC +Sent PDU: DisPduType 67 ENTITY_STATE_UPDATE +Sent PDU: DisPduType 68 DIRECTED_ENERGY_FIRE +Sent PDU: DisPduType 69 ENTITY_DAMAGE_STATUS +Sent PDU: DisPduType 70 INFORMATION_OPERATIONS_ACTION +Sent PDU: DisPduType 71 INFORMATION_OPERATIONS_REPORT +Sent PDU: DisPduType 72 ATTRIBUTE +Total PDUs: 72 +PduPlayer handleComment() found FINISH_COMMENT_MARKER, end of replay from log file PduCaptureLog.dislog +Type p/enter to pause, r/enter to resume, q/enter to quit +q +... QUIT +Ending pdu files playback for directory pduLog +OpenDis7Examples.PduReaderPlayer complete. +BUILD SUCCESSFUL (total time: 2 seconds) diff --git a/assignments/src/src/OpenDis7Examples/PduReaderPlayerWireshark.png b/assignments/src/src/OpenDis7Examples/PduReaderPlayerWireshark.png new file mode 100644 index 0000000000000000000000000000000000000000..fe642633248c7935d6aeb5ed7f0e0f8b4e43a13f Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/PduReaderPlayerWireshark.png differ diff --git a/assignments/src/src/OpenDis7Examples/PduTrack.java b/assignments/src/src/OpenDis7Examples/PduTrack.java new file mode 100644 index 0000000000000000000000000000000000000000..59d91939421f3b1bf409dd26ef7d797e61373726 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/PduTrack.java @@ -0,0 +1,1042 @@ +/* +Copyright (c) 1995-2022 held by the author(s). All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the names of the Naval Postgraduate School (NPS) + Modeling Virtual Environments and Simulation (MOVES) Institute + https://www.nps.edu and https://www.nps.edu/web/moves + nor the names of its contributors may be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +// TODO move into opendis7 distribution tree in package edu.nps.moves.dis7.utilities.stream; + +package OpenDis7Examples; + +import edu.nps.moves.dis7.entities.swe.platform.surface._001Poseidon; +import edu.nps.moves.dis7.enumerations.DisPduType; +import edu.nps.moves.dis7.enumerations.ForceID; +import edu.nps.moves.dis7.pdus.EntityID; +import edu.nps.moves.dis7.pdus.EntityStatePdu; +import edu.nps.moves.dis7.pdus.EulerAngles; +import edu.nps.moves.dis7.pdus.Pdu; +import edu.nps.moves.dis7.pdus.Vector3Double; +import edu.nps.moves.dis7.utilities.DisTime; +import edu.nps.moves.dis7.utilities.PduFactory; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * Create a track from DIS ESPDUs + * @author brutzman@nps.edu + */ +public class PduTrack +{ + private String descriptor = new String(); + private ArrayList<Pdu> pduList = new ArrayList<>(); + private EntityStatePdu initialEspdu; + private EntityStatePdu latestEspdu; + private Vector3Double initialLocation; + private Vector3Double latestLocation; + + /** waypoint timelineList in seconds */ + private ArrayList<Float> timelineList = new ArrayList<>(); + private ArrayList<Vector3Double> waypointsList = new ArrayList<>(); + private ArrayList<EulerAngles> eulerAnglesList = new ArrayList<>(); + + private String author = new String(); + private String x3dModelIdentifier = new String(); + private String x3dModelName = "PduTrackInterpolation.x3d"; + private float defaultWaypointInterval = -1; + private float durationSeconds = -1; + private String x3dTimeSensorDEF = new String(); + private String x3dPositionInterpolatorDEF = new String(); + private String x3dOrientationInterpolatorDEF = new String(); + private boolean addLineBreaksWithinKeyValues = false; + /** what kind of timestamp is being used */ + public DisTime.TimestampStyle timestampStyle = DisTime.TimestampStyle.IEEE_ABSOLUTE; + /** direct access to pduFactory for creating new PDU instances */ + protected PduFactory pduFactory = new PduFactory(timestampStyle); + private LocalDateTime recordingStart; + private LocalDateTime recordingStop; + private String todaysDateString = new String(); + + /** direct access to byteArrayOutputStream */ + protected ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + /** direct access to DataOutputStream */ + protected DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); + private String TRACE_PREFIX = "[" + (PduTrack.class.getSimpleName()) + "] "; + + /** + * Constructor for PduTrack + */ + public PduTrack() + { + // initialization code here + + // https://docs.oracle.com/javase/tutorial/datetime/TOC.html + // https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/time/package-summary.html + // https://stackoverflow.com/questions/5175728/how-to-get-the-current-date-time-in-java/5175900 (scroll down to java.time) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM yyyy"); + todaysDateString = LocalDate.now().format(formatter); +// System.out.println(TRACE_PREFIX + "today=" + todayString); + } + + /** + * Set timestampStyle used by PduFactory + * @param newTimestampStyle new value to set + */ + public PduTrack(DisTime.TimestampStyle newTimestampStyle) + { + timestampStyle = newTimestampStyle; + DisTime.setTimestampStyle(newTimestampStyle); + // automatic super invocation: return PduTrack(); + } + + /** + * Get simple descriptor (such as parent class name) for this SimulationManager, used in trace statements + * @return simple descriptor name + */ + public String getDescriptor() + { + return descriptor; + } + /** + * Set new simple descriptor (such as parent class name) for this SimulationManager, used in trace statements + * @param newDescriptor simple descriptor name for this interface + * @return same object to permit progressive setters */ + public PduTrack setDescriptor(String newDescriptor) + { + if (newDescriptor != null) + this.descriptor = newDescriptor.trim(); + TRACE_PREFIX = "[" + (PduTrack.class.getSimpleName() + " " + descriptor) + "] "; + return this; + } + /** + * Get timestampStyle used by PduFactory + * @return current timestampStyle + */ + public DisTime.TimestampStyle getTimestampStyle() + { + return timestampStyle; + } + /** + * Set timestampStyle used by PduFactory + * @param newTimestampStyle the timestampStyle to set + * @return same object to permit progressive setters + */ + public PduTrack setTimestampStyle(DisTime.TimestampStyle newTimestampStyle) + { + this.timestampStyle = newTimestampStyle; + DisTime.setTimestampStyle(newTimestampStyle); + return this; + } + + /** + * Determine initial location, reset to (0 0 0) if not found + * @return current initialLocation + */ + public Vector3Double getInitialLocation() { + if (initialLocation == null) + { + System.out.println (TRACE_PREFIX + "getInitialLocation() not found, isTrackEmpty()=" + isTrackEmpty() + ", returning 0 0 0"); + return new Vector3Double(); + } + return initialLocation; + } + /** + * Determine current location, reset to (0 0 0) if not found + * @return current latestLocation + */ + public Vector3Double getLatestLocation() { + if (latestLocation == null) + { + System.out.println (TRACE_PREFIX + "getLatestLocation() not found, isTrackEmpty()=" + isTrackEmpty() + ", returning 0 0 0"); + return new Vector3Double(); + } + return latestLocation; + } + /** + * Get individual Pdu from pduList, index must not exceed existing pduList size + * @param index for pdu of interest + * @return pdu of interest + */ + public Pdu getPdu(int index) throws IndexOutOfBoundsException + { + if ((index >= pduList.size()) || (index < 0)) + { + System.out.println (TRACE_PREFIX + "getPdu(" + index + ") out of bounds, pduList.size()=" + pduList.size()); + // then throw exception + } + return pduList.get(index); + } + /** + * get current pduList + * @return current pduList + */ + public ArrayList<Pdu> getPduList() { + return pduList; + } + /** + * get current waypointsList + * @return current waypointsList + */ + public ArrayList<Vector3Double> getWaypointsList() { + return waypointsList; + } + /** + * current eulerAnglesList + * @return current eulerAnglesList + */ + public ArrayList<EulerAngles> getEulerAnglesList() { + return eulerAnglesList; + } + /** + * Time in seconds corresponding to each PDU + * @return current timelineList + */ + public ArrayList<Float> getTimelineList() { + return timelineList; + } + /** + * Add PDU, typically ESPDU + * @param newPdu new Pdu to add, typically ESPDU + * @return same object to permit progressive setters + */ + public PduTrack addPdu(Pdu newPdu) + { + if (newPdu.getPduType() == DisPduType.ENTITY_STATE) + { +//// EntityStatePdu deepCopyEspdu = new EntityStatePdu(); +// EntityStatePdu deepCopyEspdu = pduFactory.makeEntityStatePdu(); +// deepCopyEspdu.setTimestamp (((EntityStatePdu)newPdu).getTimestamp()); +// deepCopyEspdu.setMarking (((EntityStatePdu)newPdu).getMarking()); +// deepCopyEspdu.setEntityID (((EntityStatePdu)newPdu).getEntityID()); +// deepCopyEspdu.setForceId (((EntityStatePdu)newPdu).getForceId()); +// deepCopyEspdu.setEntityType (((EntityStatePdu)newPdu).getEntityType()); +// deepCopyEspdu.setEntityLocation (((EntityStatePdu)newPdu).getEntityLocation()); +// deepCopyEspdu.setEntityOrientation(((EntityStatePdu)newPdu).getEntityOrientation()); + + EntityStatePdu deepCopyEspdu = ((EntityStatePdu)newPdu).copy(); + pduList.add(deepCopyEspdu); +// alternative trials: +// pduList.add(((EntityStatePdu)newPdu).copyDataOutputStream()); +// pduList.add(((EntityStatePdu)newPdu).copy()); + + if (initialLocation == null) + { + initialEspdu = deepCopyEspdu; // must save object since pduList might contain more than ESPDUs + initialLocation = deepCopyEspdu.getEntityLocation(); + } + latestEspdu = deepCopyEspdu; // must save object since pduList might contain more than ESPDUs + latestLocation = deepCopyEspdu.getEntityLocation(); + } + else pduList.add(newPdu); // TODO copy() - careful, must be a new object and not a reference + return this; + } + /** + * clear all PDUs + * @return same object to permit progressive setters + */ + public PduTrack clearPduLists() + { + getPduList().clear(); + waypointsList.clear(); + eulerAnglesList.clear(); + timelineList.clear(); + initialEspdu = null; + latestEspdu = null; + initialLocation = null; + latestLocation = null; + return this; + } + + private String normalizeNameToken(String candidateDEF) + { + return candidateDEF.replace(" ", "").replace("-", "") + .replace("(", "").replace(")", "") + .replace("[", "").replace("])", ""); + } + + /** + * Provide DEF value if not defined by program + * @return current x3dTimeSensorDEF + */ + public String getX3dTimeSensorDEF() { + if (x3dTimeSensorDEF.isEmpty()) + x3dTimeSensorDEF = normalizeNameToken(getDescriptor()) + "Clock"; + return x3dTimeSensorDEF; + } + + /** + * Set DEF value for X3D node + * @param x3dTimeSensorDEF the x3dTimeSensorDEF to set + */ + public void setX3dTimeSensorDEF(String x3dTimeSensorDEF) { + this.x3dTimeSensorDEF = normalizeNameToken(x3dTimeSensorDEF); + } + + /** + * Provide DEF value if not defined by program + * @return current x3dPositionInterpolatorDEF + */ + public String getX3dPositionInterpolatorDEF() { + if (x3dPositionInterpolatorDEF.isEmpty()) + x3dPositionInterpolatorDEF = normalizeNameToken(getDescriptor()) + "Positions"; + return x3dPositionInterpolatorDEF; + } + + /** + * Set DEF value for X3D node + * @param x3dPositionInterpolatorDEF the x3dPositionInterpolatorDEF to set + */ + public void setX3dPositionInterpolatorDEF(String x3dPositionInterpolatorDEF) { + this.x3dPositionInterpolatorDEF = normalizeNameToken(x3dPositionInterpolatorDEF); + } + + /** + * Provide DEF value if not defined by program + * @return current x3dOrientationInterpolatorDEF + */ + public String getX3dOrientationInterpolatorDEF() { + if (x3dOrientationInterpolatorDEF.isEmpty()) + x3dOrientationInterpolatorDEF = normalizeNameToken(getDescriptor()) + "Orientations"; + return x3dOrientationInterpolatorDEF; + } + + /** + * Set DEF value for X3D node + * @param x3dOrientationInterpolatorDEF the x3dOrientationInterpolatorDEF to set + */ + public void setX3dOrientationInterpolatorDEF(String x3dOrientationInterpolatorDEF) { + this.x3dOrientationInterpolatorDEF = normalizeNameToken(x3dOrientationInterpolatorDEF); + } + + /** + * Sort all PDUs by timestamp + * @see <a href="https://stackoverflow.com/questions/16252269/how-to-sort-an-arraylist" target="_blank">StackOverflow: How to sort an ArrayList?</a> + * @see <a href="https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/doc-files/coll-overview.html" target="_blank">Collections Framework Overview</a> + * @return same object to permit progressive setters + */ + public PduTrack sortPdus() + { + Collections.sort(pduList, new Comparator<Pdu>() { + @Override + public int compare(Pdu lhs, Pdu rhs) + { + // -1 less than, 1 greater than, 0 equal + if (lhs.occursBefore(rhs)) + return -1; + else if (lhs.occursSameTime(rhs)) + return 0; + else return 1; + } + }); + return this; + } + /** + * Reverse order of PDU list + * @see <a href="https://stackoverflow.com/questions/10766492/what-is-the-simplest-way-to-reverse-an-arraylist" target="_blank">StackOverflow: What is the Simplest Way to Reverse an ArrayList?</a> + * @see <a href="https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/doc-files/coll-overview.html" target="_blank">Collections Framework Overview</a> + * @return same object to permit progressive setters + */ + public PduTrack reversePdus() + { + Collections.reverse(pduList); + return this; + } + + /** + * Determine whether any ESPDUs have been received by this track + * @return whether track is empty + */ + public boolean isTrackEmpty() + { + return (getEspduCount() == 0); + } + /** + * Count ESPDUs in pduList + * @return number of ESPDUs in pduList + */ + public int getEspduCount() + { + int counter = 0; + for (Pdu nextPdu : getPduList()) + { + if (nextPdu.getPduType() == DisPduType.ENTITY_STATE) + counter += 1; + } + return counter; + } + /** + * Compute track duration in timestamp ticks + * @return duration in timestamp ticks between initial and final ESPDU timestamps in waypointList + */ + public int getTotalDurationTicks() + { + int initialTime = -1; + int finalTime = -1; + int durationTicks = -1; // used if pduList is empty + + // must skip through pduList since non-ESPDU PDUs may be present + for (Pdu nextPdu : getPduList()) + { + if (nextPdu.getPduType() == DisPduType.ENTITY_STATE) + { + if (initialTime == -1) + initialTime = nextPdu.getTimestamp(); + finalTime = nextPdu.getTimestamp(); + } + } + if ((initialTime >= 0) && (finalTime >= 0)) + durationTicks = (finalTime - initialTime); + if (getPduList().isEmpty()) + { + System.out.println(TRACE_PREFIX + "getTrackDuration() computed illegal duration=" + durationTicks + " due to empty pdu list"); + } + else if ((durationTicks <= 0) && (defaultWaypointInterval <= 0)) + { + System.out.println(TRACE_PREFIX + "getTrackDuration() computed illegal duration=" + durationTicks + " due to illegal pdu list"); + } + return durationTicks; + } + /** + * Compute track duration in seconds + * @return duration in seconds between initial and final ESPDU timestamps in waypointList + */ + public float getTotalDurationSeconds() + { + if (defaultWaypointInterval > 0) + { + return getEspduCount() * defaultWaypointInterval; + } + else if (getTotalDurationTicks() < 0) + durationSeconds = getTotalDurationTicks() * 1.0f; // TODO convert + return durationSeconds; + } + /** + * Create waypoints and angles using all ESPDU points, with no linear regression or array reduction. + * @return same object to permit progressive setters + */ + public PduTrack createRawWaypoints() + { + // https://stackoverflow.com/questions/6536094/java-arraylist-copy + + timelineList.clear(); + waypointsList.clear(); + eulerAnglesList.clear(); + float clock = 0.0f; + for (int i = 0; i < pduList.size(); i++) + { + Pdu nextPdu = pduList.get(i); + if (nextPdu.getPduType() == DisPduType.ENTITY_STATE) + { + EntityStatePdu espdu = (EntityStatePdu)nextPdu; + if (defaultWaypointInterval > 0) + { + timelineList.add(clock); + clock += defaultWaypointInterval; + } + else + { + timelineList.add(espdu.getTimestamp() * 1.0f); // TODO convert + } + waypointsList.add(espdu.getEntityLocation()); + eulerAnglesList.add(espdu.getEntityOrientation()); + } + } + return this; + } + /** + * Utility method to create TimeSensor + * @return TimeSensor string in XML format + */ + public String createX3dTimeSensorString() + { + StringBuilder sb = new StringBuilder(); + sb.append(" <TimeSensor"); + sb.append(" DEF='").append(getX3dTimeSensorDEF()).append("'"); + sb.append(" cycleInterval='").append(String.valueOf(getTotalDurationSeconds())).append("'"); + sb.append(" loop='true'"); + sb.append("/>").append("\n"); + + return sb.toString(); + } + /** + * Create PositionInterpolator from Pdu list + * @return X3D PositionInterpolator as string + */ + public String createX3dPositionInterpolatorString() + { + StringBuilder sb = new StringBuilder(); + sb.append(" <PositionInterpolator"); + sb.append(" DEF='").append(getX3dPositionInterpolatorDEF()).append("'"); + sb.append(" key='"); + for (int i = 0; i < timelineList.size(); i++) + { + float nextDuration = timelineList.get(i) * 1.0f; // TODO convert + sb.append(String.valueOf(nextDuration)); + if (i < timelineList.size() - 1) + sb.append(" "); + } + sb.append("'"); + sb.append(" keyValue='"); + for (int i = 0; i < waypointsList.size(); i++) + { + if (hasAddLineBreaksWithinKeyValues()) + sb.append("\n"); + Vector3Double nextPosition = waypointsList.get(i); + sb.append(String.valueOf(nextPosition.getX())).append(" ") + .append(String.valueOf(nextPosition.getY())).append(" ") + .append(String.valueOf(nextPosition.getZ())); + if (i < waypointsList.size() - 1) + sb.append(","); + } + sb.append("'"); + sb.append("/>").append("\n"); + + return sb.toString(); + } + /** + * Create OrientationInterpolator from Pdu list + * TODO preliminary support only includes horizontal rotation. + * @return X3D OrientationInterpolator as string + */ + public String createX3dOrientationInterpolatorString() + { + StringBuilder sb = new StringBuilder(); + sb.append(" <OrientationInterpolator"); + sb.append(" DEF='").append(getX3dOrientationInterpolatorDEF()).append("'"); + sb.append(" key='"); + for (int i = 0; i < timelineList.size(); i++) + { + float nextDuration = timelineList.get(i) * 1.0f; // TODO convert + sb.append(String.valueOf(nextDuration)); + if (i < timelineList.size() - 1) + sb.append(" "); + } + sb.append("'"); + sb.append(" keyValue='"); + for (int i = 0; i < eulerAnglesList.size(); i++) + { + if (hasAddLineBreaksWithinKeyValues()) + sb.append("\n"); + EulerAngles nextEulerAngle = new EulerAngles(); + float axisX = 0.0f; + float axisY = 1.0f; + float axisZ = 0.0f; + float angle = 0.0f; // radians + + nextEulerAngle = eulerAnglesList.get(i); + angle = nextEulerAngle.getTheta(); + + sb.append(String.valueOf(axisX)).append(" ") + .append(String.valueOf(axisY)).append(" ") + .append(String.valueOf(axisZ)).append(" ") + .append(String.valueOf(angle)); + if (i < eulerAnglesList.size() - 1) + sb.append(","); + } + sb.append("'"); + sb.append("/>").append("\n"); + + return sb.toString(); + } + + /** + * Get name of author used as creator of X3D model + * @return current author + */ + public String getAuthor() { + return author; + } + + /** + * Set name of author used as creator of X3D model + * @param author the author to set + */ + public void setAuthor(String author) { + if (author == null) + author = new String(); + author = author.trim(); + this.author = author; + } + + /** + * Get name of online url identifier for X3D model + * @return current x3dModelIdentifier + */ + public String getX3dModelIdentifier() { + return x3dModelIdentifier; + } + + /** + * Set name of online url identifier for X3D model + * @param x3dModelIdentifier the x3dModelIdentifier to set + */ + public void setX3dModelIdentifier(String x3dModelIdentifier) { + if (x3dModelIdentifier == null) + x3dModelIdentifier = new String(); + x3dModelIdentifier = x3dModelIdentifier.trim(); + if (!x3dModelIdentifier.startsWith("http://") && !x3dModelIdentifier.startsWith("https://")) + System.out.println(TRACE_PREFIX + "warning, identifier typically begins with https:// or http://"); + else this.x3dModelIdentifier = x3dModelIdentifier; + } + + /** + * File name for X3D model production + * @return current x3dModelName + */ + public String getX3dModelName() { + return x3dModelName; + } + /** + * File name for X3D model production + * @param x3dModelName the x3dModelName to set + */ + public void setX3dModelName(String x3dModelName) { + if (x3dModelName == null) + x3dModelName = new String(); + x3dModelName = x3dModelName.trim(); + this.x3dModelName = x3dModelName; + } + + /** + * Verbose (but more readable) output of numeric arrays in X3D model + * @return current addLineBreaksWithinKeyValues + */ + public boolean hasAddLineBreaksWithinKeyValues() { + return addLineBreaksWithinKeyValues; + } + + /** + * Verbose (but more readable) output of numeric arrays in X3D model + * @param addLineBreaksWithinKeyValues the addLineBreaksWithinKeyValues to set + */ + public void setAddLineBreaksWithinKeyValues(boolean addLineBreaksWithinKeyValues) { + this.addLineBreaksWithinKeyValues = addLineBreaksWithinKeyValues; + } + /** + * Create full X3D interpolator model from Pdu list, assembling sections of scene graph + * @return X3D model as string + */ + public String createX3dModel() + { + StringBuilder sb = new StringBuilder(); + sb.append(createX3dModelHeaderString()); + sb.append(createX3dTimeSensorString()); + sb.append(createX3dPositionInterpolatorString()); + sb.append(createX3dOrientationInterpolatorString()); + sb.append(createX3dRoutesGeometryFooterString()); + return sb.toString(); + } + /** + * Create PositionInterpolator from Pdu list + * @return X3D PositionInterpolator as string + */ + public String createX3dModelHeaderString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append("\n"); + sb.append("<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 4.0//EN\" \"https://www.web3d.org/specifications/x3d-4.0.dtd\">").append("\n"); + sb.append("<X3D profile='Interchange' version='4.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.0.xsd'>").append("\n"); + sb.append(" <head>").append("\n"); + if (!getX3dModelName().isEmpty()) + sb.append(" <meta content='").append(getX3dModelName()).append("' name='title'/>").append("\n"); + sb.append(" <meta content='Conversion of ESPDU track into X3D animation interpolators and LineSet.' name='description'/>").append("\n"); + + sb.append(" <meta content='1 January 2022' name='created'/>").append("\n"); + sb.append(" <meta content='").append(todaysDateString).append("' name='modified'/>").append("\n"); + if (!getAuthor().isEmpty()) + sb.append(" <meta content='").append(getAuthor()).append("' name='creator'/>").append("\n"); + if (!getX3dModelIdentifier().isEmpty()) + sb.append(" <meta content='").append(getX3dModelIdentifier()).append("' name='identifier'/>").append("\n"); + + sb.append(" <meta content='PduTrack utility, opendis7-java Library https://github.com/open-dis/opendis7-java' name='generator'/>").append("\n"); + sb.append(" <meta content='NPS MOVES MV3500 Networked Graphics https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500' name='reference'/>").append("\n"); + sb.append(" <meta content='X3D Resources https://www.web3d.org/x3d/content/examples/X3dResources.html' name='reference'/>").append("\n"); + sb.append(" <meta content='X3D Scene Authoring Hints https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html' name='reference'/>").append("\n"); + sb.append(" <meta content='X3D Tooltips https://www.web3d.org/x3d/tooltips/X3dTooltips.html' name='reference'/>").append("\n"); + sb.append(" <meta content='X3D Validator https://savage.nps.edu/X3dValidator' name='reference'/>").append("\n"); + sb.append(" <meta content='Open source https://raw.githubusercontent.com/open-dis/opendis7-java/master/license.html' name='license'/>").append("\n"); + sb.append(" </head>").append("\n"); + sb.append(" <Scene>").append("\n"); + sb.append(" <WorldInfo title='PduTrackInterpolation.x3d'/>").append("\n"); + + return sb.toString(); + } + /** + * Create X3D ROUTEs and footer to connect TimeSensor to interpolators + * @return X3D PositionInterpolator as string + */ + public String createX3dRoutesGeometryFooterString() + { + StringBuilder sb = new StringBuilder(); + + sb.append(" <ROUTE fromField='fraction_changed' fromNode='") + .append(getX3dTimeSensorDEF()) + .append("' toField='set_fraction' toNode='") + .append(getX3dPositionInterpolatorDEF()) + .append("'/>").append("\n"); + sb.append(" <ROUTE fromField='fraction_changed' fromNode='") + .append(getX3dTimeSensorDEF()) + .append("' toField='set_fraction' toNode='") + .append(getX3dOrientationInterpolatorDEF()) + .append("'/>").append("\n"); + + sb.append(" <Shape>").append("\n"); + sb.append(" <Appearance DEF='TrackAppearance'>").append("\n"); + sb.append(" <Material emissiveColor='0.2 0.8 0.8'/>").append("\n"); + sb.append(" </Appearance>").append("\n"); + sb.append(" <LineSet vertexCount='").append(waypointsList.size()).append("'>").append("\n"); + sb.append(" <Coordinate point='"); + for (int i = 0; i < waypointsList.size(); i++) + { + if (hasAddLineBreaksWithinKeyValues()) + sb.append("\n"); + Vector3Double nextPosition = waypointsList.get(i); + sb.append(String.valueOf(nextPosition.getX())).append(" ") + .append(String.valueOf(nextPosition.getY())).append(" ") + .append(String.valueOf(nextPosition.getZ())); + if (i < waypointsList.size() - 1) + sb.append(","); + } + sb.append("'/>").append("\n"); + sb.append(" </LineSet>").append("\n"); + sb.append(" </Shape>").append("\n"); + sb.append(" <Transform DEF='AnimationTransform'>").append("\n"); + sb.append(" <Transform rotation='0 0 1 1.57'>").append("\n"); + sb.append(" <Shape>").append("\n"); + sb.append(" <Appearance USE='TrackAppearance'/>").append("\n"); + sb.append(" <Cone bottomRadius='0.5'/>").append("\n"); + sb.append(" </Shape>").append("\n"); + sb.append(" </Transform>").append("\n"); + sb.append(" </Transform>").append("\n"); + sb.append(" <ROUTE fromField='value_changed' fromNode='") + .append(getX3dPositionInterpolatorDEF()) + .append("' toField='translation' toNode='AnimationTransform'/>").append("\n"); + sb.append(" <ROUTE fromField='value_changed' fromNode='") + .append(getX3dOrientationInterpolatorDEF()) + .append("' toField='rotation' toNode='AnimationTransform'/>").append("\n"); + + sb.append(" </Scene>").append("\n"); + sb.append("</X3D>").append("\n"); + + return sb.toString(); + } + + /** + * get defaultWaypointInterval + * @return current wayPointInterval + */ + public float getDefaultWaypointInterval() { + return defaultWaypointInterval; + } + + /** + * Set uniform waypoint interval (currently for testing) + * @param newWaypointInterval the wayPointInterval to set, in seconds, must be greater than zero + * @return same object to permit progressive setters */ + public PduTrack setDefaultWaypointInterval(float newWaypointInterval) { + if (newWaypointInterval > 0.0) + this.defaultWaypointInterval = newWaypointInterval; + else + { + System.out.println(TRACE_PREFIX + "error in setWaypointInterval(newWaypointInterval=" + newWaypointInterval + ") must be greater than zero"); + return this; + } + + float clock = 0.0f; + if (!timelineList.isEmpty()) + { + ArrayList<Float> newTimelineList = new ArrayList<>(); + for (int i = 0; i < getEspduCount(); i++) + { + newTimelineList.add(clock); + clock += defaultWaypointInterval; + } + timelineList = newTimelineList; // TO Array copy? + } + return this; + } + /** whether or not to insert commas between hex values */ + private boolean insertCommas = true; + /** + * determine whether comma insertion is turned on + * @return whether or not to insert commas between hex values + */ + public boolean hasInsertCommas() { + return insertCommas; + } + /** + * set whether comma insertion is turned on + * @param insertCommas the insertCommas value to set + */ + public void setInsertCommas(boolean insertCommas) { + this.insertCommas = insertCommas; + } + /** + * Convert byte array to hex string + * @param bytes input data + * @param insertCommas whether to insert commas between hex values + * @return hex string + */ + public String bytesToHex(byte[] bytes, boolean insertCommas) + { + this.setInsertCommas(insertCommas); + return bytesToHex(bytes); + } + /** + * Convert byte array to hex string + * @param bytes input data + * @see <a href="https://stackoverflow.com/questions/9655181/how-to-convert-a-byte-array-to-a-hex-string-in-java" target="_blank">https://stackoverflow.com/questions/9655181/how-to-convert-a-byte-array-to-a-hex-string-in-java</a> + * @return hex string + */ + public static String bytesToHex(byte[] bytes) + { + boolean insertCommas = true; + final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); + char[] hexChars = new char[bytes.length * 2]; + StringBuilder sb = new StringBuilder(); + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = HEX_ARRAY[v >>> 4]; + hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; +// if (!(hexChars[j * 2] == '0')) // omit leading zero + sb.append(hexChars[j * 2]); + sb.append(hexChars[j * 2 + 1]); + if (insertCommas && (j < bytes.length - 1)) + sb.append(", "); + } + return sb.toString(); + } + /** + * Report current PDU information to console + * @param anEspdu EntityStatePdu of interest + * @return same object to permit progressive setters + */ + public PduTrack reportPdu(EntityStatePdu anEspdu) + { + System.out.println ( + String.format("%s", anEspdu.getMarkingString().trim()) + ", " + + DisTime.convertToString(anEspdu.getTimestamp()) + " (" + + String.format("%08d", anEspdu.getTimestamp()) + "), " + + "EntityID=(" + + anEspdu.getEntityID().getSiteID() + ", " + + anEspdu.getEntityID().getApplicationID() + ", " + + anEspdu.getEntityID().getEntityID() + "), " + + "location=(" + + String.format("%4.1f", anEspdu.getEntityLocation().getX()) + ", " + + String.format("%4.1f", anEspdu.getEntityLocation().getY()) + ", " + + String.format("%4.1f", anEspdu.getEntityLocation().getZ()) + ")" +// + " " + espdu_1.getEntityLinearVelocity().toString() + ); + return this; + } + + /** Flush all buffers to reduce console scrambling while threaded + */ + protected void flushBuffers() + { + try + { + dataOutputStream.flush(); + byteArrayOutputStream.flush(); + byteArrayOutputStream.reset(); + System.err.flush(); + System.out.flush(); + } + catch (IOException ioe) + { + System.out.println(TRACE_PREFIX + "flushBuffers() IOException: " + ioe.getMessage()); + } + } + + /** Self test to check basic operation, invoked by main() + */ + @SuppressWarnings("SleepWhileInLoop") + public void selfTest() + { + final int TOTAL_PDUS = 5; + System.out.println(TRACE_PREFIX + "selfTest() start..."); + + PduTrack pduTrack = new PduTrack(); + pduTrack.setDescriptor("PduTrack Self Test"); + pduTrack.setAuthor("Don Brutzman"); + pduTrack.setX3dModelIdentifier("https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/PduTrackInterpolation.x3d"); + pduTrack.setDefaultWaypointInterval(1.0f); // experimentation with timestamp values + + DisTime.setEpochLvcNow(); + recordingStart = LocalDateTime.now(); + Instant epoch = DisTime.getEpochLvc(); + System.out.println(TRACE_PREFIX + "DisTime.hasEpochLvc()=" + DisTime.hasEpochLvc() + + ", DisTime.getEpochLvc()=" + epoch + + ", Instant.now()=" + Instant.now()); + + EntityID entityID_123 = new EntityID(); + entityID_123.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID; + // TODO someday, use enumerations; is there a unique site triplet for MOVES Institute? + + for (int i = 0; i < TOTAL_PDUS; i++) // create espdus and add each to track pduList + { +// EntityStatePdu espdu = new EntityStatePdu(); + EntityStatePdu espdu = pduFactory.makeEntityStatePdu(); // TODO check Pdu.Type + espdu.setTimestamp(DisTime.getCurrentDisTimestamp()); // chooses appropriate version + espdu.setMarking("ESPDU " + i); + espdu.setEntityLocation(i, i, i); + espdu.setEntityOrientation(0, (float)(45.0 * Math.PI / 180.0), 0); + espdu.setEntityID(entityID_123); + espdu.setForceId(ForceID.FRIENDLY); + espdu.setEntityType(new _001Poseidon()); // note import statement above + pduTrack.addPdu(espdu); // create copy + reportPdu(espdu); + try + { + Thread.sleep(100l); + } + catch (InterruptedException ie) + { + System.out.println(TRACE_PREFIX + "exceptional sleep dulay when generating ESPDUs: " + ie.getMessage()); + } + } +// System.out.println(TRACE_PREFIX + "reversePdus() then sortPdus() to test track operations"); +// pduTrack.reversePdus(); // test +// pduTrack.sortPdus(); // restore + pduTrack.createRawWaypoints(); // copies all ESPDU points to waypoints + + System.out.println(TRACE_PREFIX + "getEspduCount()=" + pduTrack.getEspduCount()); + System.out.println(TRACE_PREFIX + "getDefaultWaypointInterval()=" + pduTrack.getDefaultWaypointInterval()); + System.out.println(TRACE_PREFIX + "getTotalDurationSeconds()=" + pduTrack.getTotalDurationSeconds()); + + System.out.println("================================="); + System.out.println("PduTrack pduList marshalling checks"); + System.out.println("= = = = = = = = = = = = = = = = ="); + try + { +// int BYTE_BUFFER_SIZE = 400; // TODO what is expected max buffer size? + for (int i = 0; i < TOTAL_PDUS; i++) + { + Pdu pdu = pduTrack.getPduList().get(i); + if (!(pdu instanceof EntityStatePdu)) + continue; // skip remainder of this loop + EntityStatePdu espdu = (EntityStatePdu) pdu; + System.out.println("espdu from pduTrack pduList"); + reportPdu(espdu); + byte[] byteArray = espdu.marshal().array(); // can also use ByteBuffer + System.out.println("espdu.marshal() byteArray: " + bytesToHex(byteArray)); + flushBuffers(); + + ByteBuffer byteBuffer = ByteBuffer.allocate(byteArray.length); + espdu.marshal(byteBuffer); + System.out.println("espdu.marshal(byteBuffer): " + bytesToHex(byteBuffer.array())); + flushBuffers(); + + espdu.marshal(dataOutputStream); + byte[] byteArrayDOS = byteArrayOutputStream.toByteArray(); + System.out.println("espdu.marshal(dataOutputStream): " + bytesToHex(byteArrayDOS)); + flushBuffers(); + + System.out.println(); // - - - - - - - - - - - - - - - - - + + System.out.println("espdu.copyByteBuffer()"); + reportPdu(espdu.copyByteBuffer()); + byte[] byteArrayCopy = espdu.copyByteBuffer().marshal().array(); // can also use ByteBuffer + System.out.println("espdu.copyByteBuffer().marshal() byteArray: " + bytesToHex(byteArrayCopy)); + flushBuffers(); + + ByteBuffer byteBufferCopy = ByteBuffer.allocate(byteArray.length); // TODO is there a better way to reset? + espdu.copyByteBuffer().marshal(byteBufferCopy); + System.out.println("espdu.copyByteBuffer().marshal(byteBufferCopy): " + bytesToHex(byteBufferCopy.array())); + flushBuffers(); + + espdu.copyByteBuffer().marshal(dataOutputStream); + byte[] byteArrayDosCopy = byteArrayOutputStream.toByteArray(); + System.out.println("espdu.copyByteBuffer().marshal(dataOutputStream): " + bytesToHex(byteArrayDosCopy)); + flushBuffers(); + + System.out.println(); // - - - - - - - - - - - - - - - - - + + System.out.println("espdu.copyDataOutputStream()"); + reportPdu(espdu.copyDataOutputStream()); + byte[] byteArrayCopyDOS = espdu.copyDataOutputStream().marshal().array(); // can also use ByteBuffer + System.out.println("espdu.copyDataOutputStream().marshal() byteArray: " + bytesToHex(byteArrayCopyDOS)); + flushBuffers(); + + ByteBuffer byteBufferCopyDOS = ByteBuffer.allocate(byteArray.length); // TODO is there a better way to reset? + espdu.copyDataOutputStream().marshal(byteBufferCopyDOS); + System.out.println("espdu.copyDataOutputStream().marshal(byteBufferCopy): " + bytesToHex(byteBufferCopyDOS.array())); + flushBuffers(); + + espdu.copyDataOutputStream().marshal(dataOutputStream); + byte[] byteArrayDosCopy2 = byteArrayOutputStream.toByteArray(); + System.out.println("espdu.copyDataOutputStream().marshal(dataOutputStream): " + bytesToHex(byteArrayDosCopy2)); + flushBuffers(); + System.out.println(); + + System.out.println("= = = = = = = = = = = = = = = = ="); + } + } + catch(Exception e) + { + System.out.println(TRACE_PREFIX + "Marshalling test exception: " + e.getMessage()); + } + System.out.println("================================="); + pduTrack.setAddLineBreaksWithinKeyValues(true); + System.out.println(pduTrack.createX3dModel()); // + System.out.println("================================="); + + recordingStop = LocalDateTime.now(); + System.out.println(TRACE_PREFIX + "selfTest() complete."); + } + + /** + * Main method for testing. + * @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 [address, port, descriptor] 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("*** PduTrack.main() self test started..."); + + PduTrack pduTrack = new PduTrack(); + + pduTrack.setDescriptor("main() self test"); + + pduTrack.selfTest(); + + System.out.println("*** PduTrack.main() self test complete."); + } + +} diff --git a/assignments/src/src/OpenDis7Examples/PduTrackInterpolation.x3d b/assignments/src/src/OpenDis7Examples/PduTrackInterpolation.x3d new file mode 100644 index 0000000000000000000000000000000000000000..f9a4dafc84b2998ec60c537b208ee92a10e9a8e0 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/PduTrackInterpolation.x3d @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd"> +<X3D profile='Interchange' version='4.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.0.xsd'> + <head> + <meta content='PduTrackInterpolation.x3d' name='title'/> + <meta content='Conversion of ESPDU track into X3D animation interpolators and LineSet.' name='description'/> + <meta content='1 January 2022' name='created'/> + <meta content='30 May 2022' name='modified'/> + <meta content='Don Brutzman' name='creator'/> + <meta content='https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/PduTrackInterpolation.x3d' name='identifier'/> + <meta content='PduTrack utility, opendis7-java Library https://github.com/open-dis/opendis7-java' name='generator'/> + <meta content='NPS MOVES MV3500 Networked Graphics https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500' name='reference'/> + <meta content='X3D Resources https://www.web3d.org/x3d/content/examples/X3dResources.html' name='reference'/> + <meta content='X3D Scene Authoring Hints https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html' name='reference'/> + <meta content='X3D Tooltips https://www.web3d.org/x3d/tooltips/X3dTooltips.html' name='reference'/> + <meta content='X3D Validator https://savage.nps.edu/X3dValidator' name='reference'/> + <meta content='Open source https://raw.githubusercontent.com/open-dis/opendis7-java/master/license.html' name='license'/> + </head> + <Scene> + <WorldInfo title='PduTrackInterpolation.x3d'/> + <TimeSensor DEF='PduTrackSelfTestClock' cycleInterval='5.0' loop='true'/> + <PositionInterpolator DEF='PduTrackSelfTestPositions' key='0.0 1.0 2.0 3.0 4.0' keyValue=' +0.0 0.0 0.0, +1.0 1.0 1.0, +2.0 2.0 2.0, +3.0 3.0 3.0, +4.0 4.0 4.0'/> + <OrientationInterpolator DEF='PduTrackSelfTestOrientations' key='0.0 1.0 2.0 3.0 4.0' keyValue=' +0.0 1.0 0.0 0.7853982, +0.0 1.0 0.0 0.7853982, +0.0 1.0 0.0 0.7853982, +0.0 1.0 0.0 0.7853982, +0.0 1.0 0.0 0.7853982'/> + <ROUTE fromField='fraction_changed' fromNode='PduTrackSelfTestClock' toField='set_fraction' toNode='PduTrackSelfTestPositions'/> + <ROUTE fromField='fraction_changed' fromNode='PduTrackSelfTestClock' toField='set_fraction' toNode='PduTrackSelfTestOrientations'/> + <Shape> + <Appearance DEF='TrackAppearance'> + <Material emissiveColor='0.2 0.8 0.8'/> + </Appearance> + <LineSet vertexCount='5'> + <Coordinate point=' +0.0 0.0 0.0, +1.0 1.0 1.0, +2.0 2.0 2.0, +3.0 3.0 3.0, +4.0 4.0 4.0'/> + </LineSet> + </Shape> + <Transform DEF='AnimationTransform'> + <Transform rotation='0 0 1 1.57'> + <Shape> + <Appearance USE='TrackAppearance'/> + <Cone bottomRadius='0.5'/> + </Shape> + </Transform> + </Transform> + <ROUTE fromField='value_changed' fromNode='PduTrackSelfTestPositions' toField='translation' toNode='AnimationTransform'/> + <ROUTE fromField='value_changed' fromNode='PduTrackSelfTestOrientations' toField='rotation' toNode='AnimationTransform'/> + </Scene> +</X3D> \ No newline at end of file diff --git a/assignments/src/src/OpenDis7Examples/PduTrackLog.txt b/assignments/src/src/OpenDis7Examples/PduTrackLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..7407f218aa8fa6b9d6981b6196ffd74a817bf932 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/PduTrackLog.txt @@ -0,0 +1,183 @@ +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/PduTrack.java -Drun.class=OpenDis7Examples.PduTrack run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +*** PduTrack.main() self test started... +[PduTrack main() self test] selfTest() start... +[PduTrack main() self test] DisTime.hasEpochLvc()=true, DisTime.getEpochLvc()=2022-06-26T03:49:22.355281100Z, Instant.now()=2022-06-26T03:49:22.355281100Z +ESPDU 0, 1969-00-31 16:00:35 (00035791), EntityID=(1, 2, 3), location=( 0.0, 0.0, 0.0) +ESPDU 1, 1969-03-31 16:03:13 (00193273), EntityID=(1, 2, 3), location=( 1.0, 1.0, 1.0) +ESPDU 2, 1969-05-31 16:05:23 (00323315), EntityID=(1, 2, 3), location=( 2.0, 2.0, 2.0) +ESPDU 3, 1969-07-31 16:07:34 (00454551), EntityID=(1, 2, 3), location=( 3.0, 3.0, 3.0) +ESPDU 4, 1969-09-31 16:09:43 (00583399), EntityID=(1, 2, 3), location=( 4.0, 4.0, 4.0) +[PduTrack main() self test] getEspduCount()=5 +[PduTrack main() self test] getDefaultWaypointInterval()=1.0 +[PduTrack main() self test] getTotalDurationSeconds()=5.0 +================================= +PduTrack pduList marshalling checks += = = = = = = = = = = = = = = = = +espdu from pduTrack pduList +ESPDU 0, 1969-00-31 16:00:35 (00035791), EntityID=(1, 2, 3), location=( 0.0, 0.0, 0.0) +espdu.marshal() byteArray: 07, 01, 01, 01, 00, 00, 8B, CF, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 30, 00, 00, 00, 00 +espdu.marshal(byteBuffer): 07, 01, 01, 01, 00, 00, 8B, CF, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 30, 00, 00, 00, 00 +espdu.marshal(dataOutputStream): 07, 01, 01, 01, 00, 00, 8B, CF, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 30, 00, 00, 00, 00 + +espdu.copyByteBuffer() +, 1969-00-31 16:00:00 (00000000), EntityID=(0, 0, 0), location=( 0.0, 0.0, 0.0) +espdu.copyByteBuffer().marshal() byteArray: 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 +espdu.copyByteBuffer().marshal(byteBufferCopy): 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 +espdu.copyByteBuffer().marshal(dataOutputStream): 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 + +espdu.copyDataOutputStream() +ESPDU 0, 1969-00-31 16:00:35 (00035791), EntityID=(1, 2, 3), location=( 0.0, 0.0, 0.0) +espdu.copyDataOutputStream().marshal() byteArray: 07, 01, 01, 01, 00, 00, 8B, CF, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 30, 00, 00, 00, 00 +espdu.copyDataOutputStream().marshal(byteBufferCopy): 07, 01, 01, 01, 00, 00, 8B, CF, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 30, 00, 00, 00, 00 +espdu.copyDataOutputStream().marshal(dataOutputStream): 07, 01, 01, 01, 00, 00, 8B, CF, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 30, 00, 00, 00, 00 + += = = = = = = = = = = = = = = = = +espdu from pduTrack pduList +ESPDU 1, 1969-03-31 16:03:13 (00193273), EntityID=(1, 2, 3), location=( 1.0, 1.0, 1.0) +espdu.marshal() byteArray: 07, 01, 01, 01, 00, 02, F2, F9, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 31, 00, 00, 00, 00 +espdu.marshal(byteBuffer): 07, 01, 01, 01, 00, 02, F2, F9, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 31, 00, 00, 00, 00 +espdu.marshal(dataOutputStream): 07, 01, 01, 01, 00, 02, F2, F9, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 31, 00, 00, 00, 00 + +espdu.copyByteBuffer() +, 1969-00-31 16:00:00 (00000000), EntityID=(0, 0, 0), location=( 0.0, 0.0, 0.0) +espdu.copyByteBuffer().marshal() byteArray: 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 +espdu.copyByteBuffer().marshal(byteBufferCopy): 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 +espdu.copyByteBuffer().marshal(dataOutputStream): 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 + +espdu.copyDataOutputStream() +ESPDU 1, 1969-03-31 16:03:13 (00193273), EntityID=(1, 2, 3), location=( 1.0, 1.0, 1.0) +espdu.copyDataOutputStream().marshal() byteArray: 07, 01, 01, 01, 00, 02, F2, F9, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 31, 00, 00, 00, 00 +espdu.copyDataOutputStream().marshal(byteBufferCopy): 07, 01, 01, 01, 00, 02, F2, F9, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 31, 00, 00, 00, 00 +espdu.copyDataOutputStream().marshal(dataOutputStream): 07, 01, 01, 01, 00, 02, F2, F9, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 3F, F0, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 31, 00, 00, 00, 00 + += = = = = = = = = = = = = = = = = +espdu from pduTrack pduList +ESPDU 2, 1969-05-31 16:05:23 (00323315), EntityID=(1, 2, 3), location=( 2.0, 2.0, 2.0) +espdu.marshal() byteArray: 07, 01, 01, 01, 00, 04, EE, F3, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 32, 00, 00, 00, 00 +espdu.marshal(byteBuffer): 07, 01, 01, 01, 00, 04, EE, F3, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 32, 00, 00, 00, 00 +espdu.marshal(dataOutputStream): 07, 01, 01, 01, 00, 04, EE, F3, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 32, 00, 00, 00, 00 + +espdu.copyByteBuffer() +, 1969-00-31 16:00:00 (00000000), EntityID=(0, 0, 0), location=( 0.0, 0.0, 0.0) +espdu.copyByteBuffer().marshal() byteArray: 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 +espdu.copyByteBuffer().marshal(byteBufferCopy): 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 +espdu.copyByteBuffer().marshal(dataOutputStream): 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 + +espdu.copyDataOutputStream() +ESPDU 2, 1969-05-31 16:05:23 (00323315), EntityID=(1, 2, 3), location=( 2.0, 2.0, 2.0) +espdu.copyDataOutputStream().marshal() byteArray: 07, 01, 01, 01, 00, 04, EE, F3, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 32, 00, 00, 00, 00 +espdu.copyDataOutputStream().marshal(byteBufferCopy): 07, 01, 01, 01, 00, 04, EE, F3, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 32, 00, 00, 00, 00 +espdu.copyDataOutputStream().marshal(dataOutputStream): 07, 01, 01, 01, 00, 04, EE, F3, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 32, 00, 00, 00, 00 + += = = = = = = = = = = = = = = = = +espdu from pduTrack pduList +ESPDU 3, 1969-07-31 16:07:34 (00454551), EntityID=(1, 2, 3), location=( 3.0, 3.0, 3.0) +espdu.marshal() byteArray: 07, 01, 01, 01, 00, 06, EF, 97, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 33, 00, 00, 00, 00 +espdu.marshal(byteBuffer): 07, 01, 01, 01, 00, 06, EF, 97, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 33, 00, 00, 00, 00 +espdu.marshal(dataOutputStream): 07, 01, 01, 01, 00, 06, EF, 97, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 33, 00, 00, 00, 00 + +espdu.copyByteBuffer() +, 1969-00-31 16:00:00 (00000000), EntityID=(0, 0, 0), location=( 0.0, 0.0, 0.0) +espdu.copyByteBuffer().marshal() byteArray: 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 +espdu.copyByteBuffer().marshal(byteBufferCopy): 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 +espdu.copyByteBuffer().marshal(dataOutputStream): 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 + +espdu.copyDataOutputStream() +ESPDU 3, 1969-07-31 16:07:34 (00454551), EntityID=(1, 2, 3), location=( 3.0, 3.0, 3.0) +espdu.copyDataOutputStream().marshal() byteArray: 07, 01, 01, 01, 00, 06, EF, 97, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 33, 00, 00, 00, 00 +espdu.copyDataOutputStream().marshal(byteBufferCopy): 07, 01, 01, 01, 00, 06, EF, 97, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 33, 00, 00, 00, 00 +espdu.copyDataOutputStream().marshal(dataOutputStream): 07, 01, 01, 01, 00, 06, EF, 97, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 40, 08, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 33, 00, 00, 00, 00 + += = = = = = = = = = = = = = = = = +espdu from pduTrack pduList +ESPDU 4, 1969-09-31 16:09:43 (00583399), EntityID=(1, 2, 3), location=( 4.0, 4.0, 4.0) +espdu.marshal() byteArray: 07, 01, 01, 01, 00, 08, E6, E7, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 34, 00, 00, 00, 00 +espdu.marshal(byteBuffer): 07, 01, 01, 01, 00, 08, E6, E7, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 34, 00, 00, 00, 00 +espdu.marshal(dataOutputStream): 07, 01, 01, 01, 00, 08, E6, E7, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 34, 00, 00, 00, 00 + +espdu.copyByteBuffer() +, 1969-00-31 16:00:00 (00000000), EntityID=(0, 0, 0), location=( 0.0, 0.0, 0.0) +espdu.copyByteBuffer().marshal() byteArray: 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 +espdu.copyByteBuffer().marshal(byteBufferCopy): 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 +espdu.copyByteBuffer().marshal(dataOutputStream): 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 + +espdu.copyDataOutputStream() +ESPDU 4, 1969-09-31 16:09:43 (00583399), EntityID=(1, 2, 3), location=( 4.0, 4.0, 4.0) +espdu.copyDataOutputStream().marshal() byteArray: 07, 01, 01, 01, 00, 08, E6, E7, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 34, 00, 00, 00, 00 +espdu.copyDataOutputStream().marshal(byteBufferCopy): 07, 01, 01, 01, 00, 08, E6, E7, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 34, 00, 00, 00, 00 +espdu.copyDataOutputStream().marshal(dataOutputStream): 07, 01, 01, 01, 00, 08, E6, E7, 00, 90, 28, 00, 00, 01, 00, 02, 00, 03, 01, 00, 01, 03, 00, CD, 3E, 02, 01, 00, 00, 00, 00, E1, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 40, 10, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 3F, 49, 0F, DB, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20, 20, 20, 20, 45, 53, 50, 44, 55, 20, 34, 00, 00, 00, 00 + += = = = = = = = = = = = = = = = = +================================= +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd"> +<X3D profile='Interchange' version='4.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.0.xsd'> + <head> + <meta content='PduTrackInterpolation.x3d' name='title'/> + <meta content='Conversion of ESPDU track into X3D animation interpolators and LineSet.' name='description'/> + <meta content='1 January 2022' name='created'/> + <meta content='25 June 2022' name='modified'/> + <meta content='Don Brutzman' name='creator'/> + <meta content='https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/PduTrackInterpolation.x3d' name='identifier'/> + <meta content='PduTrack utility, opendis7-java Library https://github.com/open-dis/opendis7-java' name='generator'/> + <meta content='NPS MOVES MV3500 Networked Graphics https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500' name='reference'/> + <meta content='X3D Resources https://www.web3d.org/x3d/content/examples/X3dResources.html' name='reference'/> + <meta content='X3D Scene Authoring Hints https://www.web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html' name='reference'/> + <meta content='X3D Tooltips https://www.web3d.org/x3d/tooltips/X3dTooltips.html' name='reference'/> + <meta content='X3D Validator https://savage.nps.edu/X3dValidator' name='reference'/> + <meta content='Open source https://raw.githubusercontent.com/open-dis/opendis7-java/master/license.html' name='license'/> + </head> + <Scene> + <WorldInfo title='PduTrackInterpolation.x3d'/> + <TimeSensor DEF='PduTrackSelfTestClock' cycleInterval='5.0' loop='true'/> + <PositionInterpolator DEF='PduTrackSelfTestPositions' key='0.0 1.0 2.0 3.0 4.0' keyValue=' +0.0 0.0 0.0, +1.0 1.0 1.0, +2.0 2.0 2.0, +3.0 3.0 3.0, +4.0 4.0 4.0'/> + <OrientationInterpolator DEF='PduTrackSelfTestOrientations' key='0.0 1.0 2.0 3.0 4.0' keyValue=' +0.0 1.0 0.0 0.7853982, +0.0 1.0 0.0 0.7853982, +0.0 1.0 0.0 0.7853982, +0.0 1.0 0.0 0.7853982, +0.0 1.0 0.0 0.7853982'/> + <ROUTE fromField='fraction_changed' fromNode='PduTrackSelfTestClock' toField='set_fraction' toNode='PduTrackSelfTestPositions'/> + <ROUTE fromField='fraction_changed' fromNode='PduTrackSelfTestClock' toField='set_fraction' toNode='PduTrackSelfTestOrientations'/> + <Shape> + <Appearance DEF='TrackAppearance'> + <Material emissiveColor='0.2 0.8 0.8'/> + </Appearance> + <LineSet vertexCount='5'> + <Coordinate point=' +0.0 0.0 0.0, +1.0 1.0 1.0, +2.0 2.0 2.0, +3.0 3.0 3.0, +4.0 4.0 4.0'/> + </LineSet> + </Shape> + <Transform DEF='AnimationTransform'> + <Transform rotation='0 0 1 1.57'> + <Shape> + <Appearance USE='TrackAppearance'/> + <Cone bottomRadius='0.5'/> + </Shape> + </Transform> + </Transform> + <ROUTE fromField='value_changed' fromNode='PduTrackSelfTestPositions' toField='translation' toNode='AnimationTransform'/> + <ROUTE fromField='value_changed' fromNode='PduTrackSelfTestOrientations' toField='rotation' toNode='AnimationTransform'/> + </Scene> +</X3D> + +================================= +[PduTrack main() self test] selfTest() complete. +*** PduTrack.main() self test complete. +BUILD SUCCESSFUL (total time: 2 seconds) diff --git a/assignments/src/src/OpenDis7Examples/README.md b/assignments/src/src/OpenDis7Examples/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9718043fd1d864e5c4858b344f0b613b905bce41 --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/README.md @@ -0,0 +1,19 @@ +# DIS Protocol Examples using Open-DIS-Java Library v7 + +These examples illustrate use of latest OpenDis7 library for IEEE Distributed Interactive Simulation (DIS) Protocol + +<!-- View this page at https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/README.md --> + +All examples tested, running and documented satisfactorily. + +This package presents course examples using the [Open-DIS-Java](https://github.com/open-dis/opendis7-java) library, with online [Javadoc](https://savage.nps.edu/opendis7-java/javadoc) showing complete coverage of 72 DIS PDUs and 22,000+ enumerations. + +See the [specifications](../../../specifications) directory to for guidance on obtaining reference copies of DIS and RPRFOM standards. + +| AllPduSender packets in Wireshark |EspduSender packets in Wireshark | +|--------------------------------------|----------------------------------| +|  |  | + +| Example Simulation Program packets in Wireshark | PduReaderPlayer in Wireshark | +|-------------------------------------------------|------------------------------| +|  |  | \ No newline at end of file diff --git a/assignments/src/src/OpenDis7Examples/images/OpenDis7ExamplesAllPduScreenCapture.png b/assignments/src/src/OpenDis7Examples/images/OpenDis7ExamplesAllPduScreenCapture.png new file mode 100644 index 0000000000000000000000000000000000000000..f22ecf7fbfaf759fe3c2fdbae60934a7b080a817 Binary files /dev/null and b/assignments/src/src/OpenDis7Examples/images/OpenDis7ExamplesAllPduScreenCapture.png differ diff --git a/assignments/src/src/OpenDis7Examples/package-info.java b/assignments/src/src/OpenDis7Examples/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..b785145d7ea1647b6f909cdba772907b5a53e32a --- /dev/null +++ b/assignments/src/src/OpenDis7Examples/package-info.java @@ -0,0 +1,10 @@ +/** + * opendis7 Java examples supporting the NPS MOVES MV3500 Networked Graphics course. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples/src/OpenDis7Examples" target="blank">NetworkedGraphicsMV3500 examples: OpenDis7Examples</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 OpenDis7Examples; diff --git a/assignments/src/src/README.md b/assignments/src/src/README.md new file mode 100644 index 0000000000000000000000000000000000000000..34d2d0890b7973f2db2c20668a3fad1c9aaaf521 --- /dev/null +++ b/assignments/src/src/README.md @@ -0,0 +1,19 @@ +## MV3500 Examples Source Archive + +These example directories are presented in the same order provided in the course [../../presentations](presentations). + +<!-- View this page at https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/README.md --> + +1. [TcpExamples](TcpExamples) show how to create connection-oriented Transmission Control Protocol (TCP) sockets + +2. [UdpExamples](UdpExamples) show how to create User Datagram Protocol (UDP) sockets + +3. [OpenDis7Examples](OpenDis7Examples) illustrate use of latest OpenDis7 library for IEEE Distributed Interactive Simulation (DIS) Protocol + +4. [SimkitOpenDis7Examples](SimkitOpenDis7Examples) provides simple examples combining Simkit Discrete Event Simulation (DES) and IEEE DIS + +also with + +5. [OpenDis4Examples](OpenDis4Examples) illustrate use of (legacy) OpenDis4 library for IEEE Distributed Interactive Simulation (DIS) Protocol + +6. [HttpServletExamples](HttpServletExamples) shows how to use Java Servlets as server-side code running on an http server diff --git a/assignments/src/src/SimkitOpenDis7Examples/ArrivalProcess.java b/assignments/src/src/SimkitOpenDis7Examples/ArrivalProcess.java new file mode 100644 index 0000000000000000000000000000000000000000..8ff1b0c41204af0334617c636178c73e17ffb49d --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/ArrivalProcess.java @@ -0,0 +1,97 @@ +package SimkitOpenDis7Examples; + +import simkit.SimEntityBase; +import simkit.random.RandomVariate; + +/** + * One of the simplest non-trivial Event Graph models. A series of Arrival + * events is scheduled based on an inter arrival time random variate. The state + * variable, simply counts the number of these arrivals. + * + * @author abuss@nps.edu + */ +public class ArrivalProcess extends SimEntityBase { + + /** + * Generates interarrival times + */ + private RandomVariate interarrivalTimeGenerator; + + /** + * State variable that counts the number of Arrival events + */ + protected int numberArrivals; + + /** + * Instantiate an ArrivalProcess with the given interarrivalTimeGenerator + * + * @param interarrivalTimeGenerator Given RandomVariate for interarrival + * times + */ + public ArrivalProcess(RandomVariate interarrivalTimeGenerator) { + this.setInterarrivalTimeGenerator(interarrivalTimeGenerator); + } + + /** + * If the ArrivalProcess is instantiated using the zero-argument + * constructor, be sure the set the interarrivalTimeGenerator with an + * explicit call to its setter method. + */ + public ArrivalProcess() { + } + + /** + * Initialize numberArrivals to 0 + */ + public void reset() { + super.reset(); + numberArrivals = 0; + } + + /** + * Schedule the first Arrival event with delay generated by + * interarrivalTimeGenerator + */ + public void doRun() { + firePropertyChange("numberArrivals", getNumberArrivals()); + + waitDelay("Arrival", interarrivalTimeGenerator); + } + + /** + * Increment numberArrivals<br> + * Schedule next Arrival event with delay generated by + * interarrivalTimeGenerator + */ + public void doArrival() { + int oldNumberArrivals = getNumberArrivals(); + numberArrivals += 1; + firePropertyChange("numberArrivals", oldNumberArrivals, getNumberArrivals()); + + waitDelay("Arrival", interarrivalTimeGenerator); + } + + /** + * accessor method to get a state variable + * @return the interarrivalTimeGenerator + */ + public RandomVariate getInterarrivalTimeGenerator() { + return interarrivalTimeGenerator; + } + + /** + * accessor method to set a state variable + * @param interarrivalTimeGenerator the interarrivalTimeGenerator to set + */ + public void setInterarrivalTimeGenerator(RandomVariate interarrivalTimeGenerator) { + this.interarrivalTimeGenerator = interarrivalTimeGenerator; + } + + /** + * accessor method to get a state variable + * @return the numberArrivals + */ + public int getNumberArrivals() { + return numberArrivals; + } +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/ArrivalProcessOpenDis7.java b/assignments/src/src/SimkitOpenDis7Examples/ArrivalProcessOpenDis7.java new file mode 100644 index 0000000000000000000000000000000000000000..b4b496ec0c396fa655dc46c15400570433aa0e8f --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/ArrivalProcessOpenDis7.java @@ -0,0 +1,132 @@ +package SimkitOpenDis7Examples; + +import edu.nps.moves.dis7.enumerations.VariableRecordType; +import edu.nps.moves.dis7.utilities.DisChannel; +import simkit.SimEntityBase; +import simkit.random.RandomVariate; + +/** + * ArrivalProcess event graph with openDis7 output PDU messages added. + * One of the simplest non-trivial Event Graph models. A series of Arrival + * events is scheduled based on an inter arrival time random variate. The state + * variable, simply counts the number of these arrivals. + * + * @see SimkitOpenDis7Examples.SimpleServer + * @see SimkitOpenDis7Examples.run.RunSimpleServerOpenDis7 + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/raw/master/examples/src/SimkitOpenDis7Examples/ArrivalProcessOpenDis7EventGraph.png" target="_blank">ArrivalProcessDisPdu.png</a> + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/raw/master/examples/src/SimkitOpenDis7Examples/SimpleServerComponentEventGraph.png" target="_blank">SimpleServerComponentEventGraph.png</a> + * @author abuss@nps.edu + * @author brutzman@nps.edu + */ +public class ArrivalProcessOpenDis7 extends SimEntityBase { + + private final DisChannel disChannel = new DisChannel(); + + /** + * Generates interarrival times + */ + private RandomVariate interarrivalTimeGenerator; + + /** + * State variable that counts the number of Arrival events + */ + protected int numberArrivals; + + /** Initialize channel setup for OpenDis7 and report a test PDU */ + private void initializeDisChannel() + { + disChannel.setUpNetworkInterface(); + disChannel.printlnTRACE ("disChannel.getNetworkAddress()=" + disChannel.getNetworkAddress() + + ", getNetworkPort()=" + disChannel.getNetworkPort()); + + disChannel.sendCommentPdu(VariableRecordType.OTHER, "ArrivalProcessOpenDis7 initialized"); + } + + /** + * Instantiate an ArrivalProcess with the given interarrivalTimeGenerator + * + * @param interarrivalTimeGenerator Given RandomVariate for interarrival + * times + */ + public ArrivalProcessOpenDis7(RandomVariate interarrivalTimeGenerator) { + this.interarrivalTimeGenerator = interarrivalTimeGenerator; + initializeDisChannel(); + } + + /** + * If the ArrivalProcess is instantiated using the zero-argument + * constructor, be sure the set the interarrivalTimeGenerator with an + * explicit call to its setter method. + */ + public ArrivalProcessOpenDis7() { + initializeDisChannel(); + } + + /** + * Initialize numberArrivals to 0 + */ + @Override + public void reset() { + super.reset(); + numberArrivals = 0; + } + + /** + * Schedule the first Arrival event with delay generated by + * interarrivalTimeGenerator + */ + public void doRun() { + firePropertyChange("numberArrivals", getNumberArrivals()); + + // TODO send simulation management PDUs via DIS channel, announce commencement + + waitDelay("Arrival", interarrivalTimeGenerator); + } + + /** + * Increment numberArrivals<br> + * Schedule next Arrival event with delay generated by + * interarrivalTimeGenerator + */ + public void doArrival() { + int oldNumberArrivals = getNumberArrivals(); + numberArrivals += 1; + firePropertyChange("numberArrivals", oldNumberArrivals, getNumberArrivals()); + + // TODO announce selected arrivals via DIS channel + + waitDelay("Arrival", interarrivalTimeGenerator); + } + + /** + * accessor method to get a state variable + * @return the interarrivalTimeGenerator + */ + public RandomVariate getInterarrivalTimeGenerator() { + return interarrivalTimeGenerator; + } + + /** + * accessor method to set a state variable + * @param interarrivalTimeGenerator the interarrivalTimeGenerator to set + */ + public void setInterarrivalTimeGenerator(RandomVariate interarrivalTimeGenerator) { + this.interarrivalTimeGenerator = interarrivalTimeGenerator; + } + + /** + * accessor method to get a state variable + * @return the numberArrivals + */ + public int getNumberArrivals() { + return numberArrivals; + } + + /** + * accessor method to get current DIS channel object + * @return the disChannel + */ + public DisChannel getDisChannel() { + return disChannel; + } +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/ArrivalProcessOpenDis7EventGraph.png b/assignments/src/src/SimkitOpenDis7Examples/ArrivalProcessOpenDis7EventGraph.png new file mode 100644 index 0000000000000000000000000000000000000000..ad9db14a8fbe98b2f60e65d5f496a71a4618c62e Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/ArrivalProcessOpenDis7EventGraph.png differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/README.md b/assignments/src/src/SimkitOpenDis7Examples/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5bb6cc0e3b210f02238669008be1839d26146702 --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/README.md @@ -0,0 +1,52 @@ +# Simkit DIS Examples + +[This directory](https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples/src/SimkitOpenDis7Examples) includes simple Simkit programs which are getting modified to +utilize opendis7-java libraries for PDU output. + +## Design Goals + +* Integrate code to share state changes from Simkit entities as DIS PDU messages. +* Establish reference examples with corresponding output logs for test confirmation. +* Build interoperability examples for distributed simulation using Simkit, DIS and X3D. + +## Example Programs + +Design outline: [SimkitSimpleDiscreteEventSimulationModelForDIS.docx](documentation/SimkitSimpleDiscreteEventSimulationModelForDIS.docx) + +a. ArrivalProcess, SimpleServer: provide a simple starter example + * [ArrivalProcess.java](ArrivalProcess.java) + * [SimpleServer.java](SimpleServer.java) and [SimpleServerComponentEventGraph.png](SimpleServerComponentEventGraph.png) + * [run.RunSimpleServer.java](run/RunSimpleServer.java) and [run.RunSimpleServerLog.txt](run/RunSimpleServerLog.txt) + * [ComputerAssignment 01 - The Arrival Process.docx](documentation/MV3302/ComputerAssignment 01 - The Arrival Process.docx) + +b. ArrivalProcessOpenDis7, SimpleServer: compatibly adds DIS output PDUs + * [ArrivalProcessOpenDis7.java](ArrivalProcessOpenDis7.java) and + [ArrivalProcessOpenDis7EventGraph.png](ArrivalProcessOpenDis7EventGraph.png) + * [SimpleServer.java](SimpleServer.java) and [SimpleServerComponentEventGraph.png](SimpleServerComponentEventGraph.png) + * [run.SimpleServerOpenDis7.java](run/SimpleServerOpenDis7.java) and [run.RunSimpleServerLog.txt](run/SimpleServerOpenDis7.txt) + +c. Two Crane Berths + * [Ship.java](Ship.java) + * [ShipArrivalProcess.java](ShipArrivalProcess.java) and + [ShipArrivalProcessComponentEventGraph.png](ShipArrivalProcessComponentEventGraph.png) + * [TwoCraneBerths.java](TwoCraneBerths.java) and + [TwoCranesBerthComponentEventGraph.png](TwoCranesBerthComponentEventGraph.png) + * [run.RunTwoCranesBerth.java](run/RunTwoCranesBerth.java) and [run.RunTwoCranesBerthLog.txt](run/RunTwoCranesBerthLog.txt) + * [HarborWithTwoCranes.docx](documentation/HarborWithTwoCranes.docx) and [WrittenAssignment5Solution.docx](documentation/WrittenAssignment5Solution.docx) + * [ComputerAssignment 05 - Two Crane Berths.docx](documentation/MV3302/ComputerAssignment 05 - Two Crane Berths.docx) + +## References + +* Buss, Arnold, [Component Based Simulation Modeling with Simkit](documentation/BussComponentBasedSimulationModelingSimkitWintersim2002.pdf), Proceedings of the 2002 Winter Simulation Conference. +* [Discrete Event Simulation Modeling](documentation/Discrete Event Simulation Modeling.pdf) manual for Simkit +* https://github.com/ahbuss/Simkit +* https://gitlab.nps.edu/abuss/MV3302ClassCode +* [MV3302: Introduction to Discrete Event Simulation Modeling (SP22_1_AB)](https://cle.nps.edu/portal/site/7c6b3539-58e4-4640-9551-ab03f8629e3c) in NPS Sakai +* [MV3302 > Resources > Handouts](https://cle.nps.edu/portal/site/7c6b3539-58e4-4640-9551-ab03f8629e3c/tool/7f0dea2b-fa42-4bed-8c38-c67ce9f56582?panel=Main) + +## TODO + +a. Refactor [OpenDis7Examples.ExampleSimulationProgram.java](../OpenDis7Examples/ExampleSimulationProgram.java) to extract re-usable DIS + network parameters, setup and teardown as a convenient superclass. + +b. Add additional PDU outputs to these examples. diff --git a/assignments/src/src/SimkitOpenDis7Examples/Ship.java b/assignments/src/src/SimkitOpenDis7Examples/Ship.java new file mode 100644 index 0000000000000000000000000000000000000000..aa46b4ca887a0452d52e0757bdf579c65b48db9c --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/Ship.java @@ -0,0 +1,52 @@ +package SimkitOpenDis7Examples; + +import simkit.Entity; + +/** + * Model a ship that arrives at a pier for crane servicing + * @author abuss@nps.edu + */ +public class Ship extends Entity { + + /** + * Remaining time to unload ship at unit rate + */ + protected double remainingUnloadingTime; + + /** + * Model constructor + * @throws IllegalArgumentException if remainingUnloadingTime ≤ 0.0 + * @param remainingUnloadingTime Given initial unloading time + */ + public Ship(double remainingUnloadingTime) { + super("Ship"); + if (remainingUnloadingTime <= 0.0) { + throw new IllegalArgumentException( + "remainingUnloadingTime must be > 0.0: " + + remainingUnloadingTime); + } + this.remainingUnloadingTime = remainingUnloadingTime; + } + + /** + * Decrement remainingUnloadingTime by the elapsed time at the given rate + * + * @param rate Given rate of unloading + */ + public void work(double rate) { + remainingUnloadingTime -= getElapsedTime() * rate; + } + + /** + * accessor method to get a state variable + * @return The remainingUnloadingTime + */ + public double getRemainingUnloadingTime() { + return remainingUnloadingTime; + } + + @Override + public String toString() { + return super.toString() + String.format(" %.3f", getRemainingUnloadingTime()); + } +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/ShipArrivalProcess.java b/assignments/src/src/SimkitOpenDis7Examples/ShipArrivalProcess.java new file mode 100644 index 0000000000000000000000000000000000000000..209bab376d71be17596bba00fe71dbc11f3c3f58 --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/ShipArrivalProcess.java @@ -0,0 +1,62 @@ +package SimkitOpenDis7Examples; + +import simkit.random.RandomVariate; + +/** + * Model a ship arrival process + * @author abuss@nps.edu + */ +public class ShipArrivalProcess extends ArrivalProcess { + + /** + * Generates the initial unloading times for the Ships + */ + private RandomVariate unloadTimeGenerator; + + /** + * Zero-argument constructor + */ + public ShipArrivalProcess() { + } + + /** + * Instance constructor + * @param interarrivalTimeGenerator Given generator for interarrival times + * @param unloadTimeGenerator Given generator for total unloading times + */ + public ShipArrivalProcess( + RandomVariate interarrivalTimeGenerator, + RandomVariate unloadTimeGenerator) { + this(); + this.setInterarrivalTimeGenerator(interarrivalTimeGenerator); + this.setUnloadTimeGenerator(unloadTimeGenerator); + } + + /** + * Instantiate a new Ship and Schedule Arrival(Ship) + */ + @Override + public void doArrival() { + super.doArrival(); + Ship ship = new Ship(unloadTimeGenerator.generate()); + waitDelay("Arrival", 0.0, ship); + } + + /** + * accessor method to get a state variable + * @return the unloadTimeGenerator + */ + public RandomVariate getUnloadTimeGenerator() { + return unloadTimeGenerator; + } + + /** + * accessor method to set a state variable + * @param unloadTimeGenerator the unloadTimeGenerator to set + */ + public void setUnloadTimeGenerator(RandomVariate unloadTimeGenerator) { + this.unloadTimeGenerator = unloadTimeGenerator; + } + + +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/ShipArrivalProcessComponentEventGraph.png b/assignments/src/src/SimkitOpenDis7Examples/ShipArrivalProcessComponentEventGraph.png new file mode 100644 index 0000000000000000000000000000000000000000..626df45401cac09b588bab20c763aaeef5662e20 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/ShipArrivalProcessComponentEventGraph.png differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/SimpleServer.java b/assignments/src/src/SimkitOpenDis7Examples/SimpleServer.java new file mode 100644 index 0000000000000000000000000000000000000000..5afa8dc658f80996cb82b19cf875fddf4f1a17f5 --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/SimpleServer.java @@ -0,0 +1,193 @@ +package SimkitOpenDis7Examples; + +import simkit.Priority; +import simkit.SimEntityBase; +import simkit.random.RandomVariate; + +/** + * Simple Server component. Instances of this class cannot be used on their own, + * but require another SimEntity to schedule Arrival events. If it is desired to + * listen to an event of another name,use an Adapter instance. + * + * The StartService is schedule with a positive priority, which will ensure it + * will occur ahead of any simultaneously scheduled Arrival events, as long as + * they have the default priority of 0.0. + * + * @author abuss@nps.edu + */ +public class SimpleServer extends SimEntityBase { + + /** + * Total number of servers + */ + private int totalNumberServers; + + /** + * Generates service times + */ + private RandomVariate serviceTimeGenerator; + + /** + * number of available servers at any time + */ + protected int numberAvailableServers; + + /** + * number in queue at any time + */ + protected int numberInQueue; + + /** + * Number customers served + */ + protected int numberServed; + + /** + * Zero-argument constructor + */ + public SimpleServer() { + } + + /** + * Creates a new instance of SimpleServer with the given parameters + * + * @param totalNumberServers Total number of servers + * @param serviceTimeGenerator Service time generator. Must be RandomVariate + * instance that only generates non-negative values. + */ + public SimpleServer(int totalNumberServers, RandomVariate serviceTimeGenerator) { + setTotalNumberServers(totalNumberServers); + setServiceTimeGenerator(serviceTimeGenerator); + } + + /** + * Set numberAvailable servers to total number servers, numberInQueue to 0, + * numberServed to 0. + */ + @Override + public void reset() { + super.reset(); + numberInQueue = 0; + numberAvailableServers = totalNumberServers; + numberServed = 0; + } + + /** + * Just fires PropertyChange events + */ + public void doRun() { + firePropertyChange("numberInQueue", getNumberInQueue()); + firePropertyChange("numberAvailableServers", getNumberAvailableServers()); + firePropertyChange("numberServed", getNumberServed()); + } + + /** + * Increment number in queue. If a server is available, schedule + * StartService immediately with priority of 1.0 + */ + public void doArrival() { + int oldNumberInQueue = numberInQueue; + numberInQueue = numberInQueue + 1; + firePropertyChange("numberInQueue", oldNumberInQueue, getNumberInQueue()); + if (getNumberAvailableServers() > 0) { + waitDelay("StartService", 0.0, Priority.HIGH); + } + } + + /** + * Decrement numberInQueue and numberAvailableServers Schedule EndService + * after service time delay + */ + public void doStartService() { + int oldNumberInQueue = numberInQueue; + numberInQueue = numberInQueue - 1; + firePropertyChange("numberInQueue", oldNumberInQueue, numberInQueue); + int oldNumberAvailableServers = numberAvailableServers; + numberAvailableServers = numberAvailableServers - 1; + firePropertyChange("numberAvailableServers", oldNumberAvailableServers, numberAvailableServers); + +// double serviceTime = getServiceTimeGenerator().generate(); +// firePropertyChange("serviceTime", serviceTime); + + waitDelay("EndService", serviceTimeGenerator); + + } + + /** + * Increment numberAvailableServers If customers in queue, schedule + * StartService immediately with HIGH priority + */ + public void doEndService() { + int oldNumberAvailableServers = numberAvailableServers; + numberAvailableServers = numberAvailableServers + 1; + firePropertyChange("numberAvailableServers", oldNumberAvailableServers, numberAvailableServers); + + int oldNumberServed = numberServed; + numberServed = numberServed + 1; + firePropertyChange("numberServed", oldNumberServed, numberServed); + + if (getNumberInQueue() > 0) { + waitDelay("StartService", 0.0, Priority.HIGH); + } + } + + /** + * accessor method to get a state variable + * @return the numberAvailableServers + */ + public int getNumberAvailableServers() { + return numberAvailableServers; + } + + /** + * accessor method to get a state variable + * @return the numberInQueue + */ + public int getNumberInQueue() { + return numberInQueue; + } + + /** + * accessor method to set a state variable + * @param totalNumberServers total number of servers + * @throws IllegalArgumentException if totalNumberServers < 0 + */ + public void setTotalNumberServers(int totalNumberServers) { + if (totalNumberServers <= 0) { + throw new IllegalArgumentException("Need positive number of servers: " + totalNumberServers); + } + this.totalNumberServers = totalNumberServers; + } + + /** + * accessor method to get a state variable + * @return the serviceTimeGenerator + */ + public RandomVariate getServiceTimeGenerator() { + return this.serviceTimeGenerator; + } + + /** + * accessor method to set a state variable + * @param serviceTimeGenerator the serviceTimeGenerator to set + */ + public void setServiceTimeGenerator(RandomVariate serviceTimeGenerator) { + this.serviceTimeGenerator = serviceTimeGenerator; + } + + /** + * accessor method to get a state variable + * @return the totalNumberServers + */ + public int getTotalNumberServers() { + return this.totalNumberServers; + } + + /** + * accessor method to get a state variable + * @return the numberServed + */ + public int getNumberServed() { + return this.numberServed; + } +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/SimpleServerComponentEventGraph.png b/assignments/src/src/SimkitOpenDis7Examples/SimpleServerComponentEventGraph.png new file mode 100644 index 0000000000000000000000000000000000000000..dff11b08b2a259a4e8aadea52554a135ee216eb5 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/SimpleServerComponentEventGraph.png differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/SimpleServerOpenDis7.java b/assignments/src/src/SimkitOpenDis7Examples/SimpleServerOpenDis7.java new file mode 100644 index 0000000000000000000000000000000000000000..de9824ebc3f69956b8d6467020b886b1d1fe5e9e --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/SimpleServerOpenDis7.java @@ -0,0 +1,203 @@ +package SimkitOpenDis7Examples; + +import edu.nps.moves.dis7.enumerations.DisPduType; +import edu.nps.moves.dis7.pdus.EntityStatePdu; +import edu.nps.moves.dis7.utilities.DisChannel; +import edu.nps.moves.dis7.utilities.PduFactory; +import simkit.Priority; +import simkit.SimEntityBase; +import simkit.random.RandomVariate; + +/** + * Simple Server component. Instances of this class cannot be used on their own, + * but require another SimEntity to schedule Arrival events. If it is desired to + * listen to an event of another name,use an Adapter instance. + * + * The StartService is schedule with a positive priority, which will ensure it + * will occur ahead of any simultaneously scheduled Arrival events, as long as + * they have the default priority of 0.0. + * + * @author abuss@nps.edu + */ +public class SimpleServerOpenDis7 extends SimEntityBase +{ + // Utility constructor method: initial descriptor and verboseness of disNetworkInterface, pduRecorder + private final DisChannel disChannel = new DisChannel("TwoCraneBerthsOpenDis7", false, true); + + PduFactory pduFactory = new PduFactory(); + EntityStatePdu espduCrane = (EntityStatePdu) pduFactory.createPdu(DisPduType.ENTITY_STATE); + + /** + * Total number of servers + */ + private int totalNumberServers; + + /** + * Generates service times + */ + private RandomVariate serviceTimeGenerator; + + /** + * number of available servers at any time + */ + protected int numberAvailableServers; + + /** + * number in queue at any time + */ + protected int numberInQueue; + + /** + * Number customers served + */ + protected int numberServed; + + /** + * Zero-argument constructor + */ + public SimpleServerOpenDis7() { + } + + /** + * Creates a new instance of SimpleServer with the given parameters + * + * @param totalNumberServers Total number of servers + * @param serviceTimeGenerator Service time generator. Must be RandomVariate + * instance that only generates non-negative values. + */ + public SimpleServerOpenDis7(int totalNumberServers, RandomVariate serviceTimeGenerator) { + setTotalNumberServers(totalNumberServers); + setServiceTimeGenerator(serviceTimeGenerator); + } + + /** + * Set numberAvailable servers to total number servers, numberInQueue to 0, + * numberServed to 0. + */ + @Override + public void reset() { + super.reset(); + numberInQueue = 0; + numberAvailableServers = totalNumberServers; + numberServed = 0; + } + + /** + * Just fires PropertyChange events + */ + public void doRun() { + firePropertyChange("numberInQueue", getNumberInQueue()); + firePropertyChange("numberAvailableServers", getNumberAvailableServers()); + firePropertyChange("numberServed", getNumberServed()); + } + + /** + * Increment number in queue. If a server is available, schedule + * StartService immediately with priority of 1.0 + */ + public void doArrival() { + int oldNumberInQueue = numberInQueue; + numberInQueue = numberInQueue + 1; + firePropertyChange("numberInQueue", oldNumberInQueue, getNumberInQueue()); + if (getNumberAvailableServers() > 0) { + waitDelay("StartService", 0.0, Priority.HIGH); + } + } + + /** + * Decrement numberInQueue and numberAvailableServers Schedule EndService + * after service time delay + */ + public void doStartService() { + int oldNumberInQueue = numberInQueue; + numberInQueue = numberInQueue - 1; + firePropertyChange("numberInQueue", oldNumberInQueue, numberInQueue); + int oldNumberAvailableServers = numberAvailableServers; + numberAvailableServers = numberAvailableServers - 1; + firePropertyChange("numberAvailableServers", oldNumberAvailableServers, numberAvailableServers); + +// double serviceTime = getServiceTimeGenerator().generate(); +// firePropertyChange("serviceTime", serviceTime); + + waitDelay("EndService", serviceTimeGenerator); + + } + + /** + * Increment numberAvailableServers If customers in queue, schedule + * StartService immediately with HIGH priority + */ + public void doEndService() { + int oldNumberAvailableServers = numberAvailableServers; + numberAvailableServers = numberAvailableServers + 1; + firePropertyChange("numberAvailableServers", oldNumberAvailableServers, numberAvailableServers); + + int oldNumberServed = numberServed; + numberServed = numberServed + 1; + firePropertyChange("numberServed", oldNumberServed, numberServed); + + if (getNumberInQueue() > 0) { + waitDelay("StartService", 0.0, Priority.HIGH); + } + } + + /** + * accessor method to get a state variable + * @return the numberAvailableServers + */ + public int getNumberAvailableServers() { + return numberAvailableServers; + } + + /** + * accessor method to get a state variable + * @return the numberInQueue + */ + public int getNumberInQueue() { + return numberInQueue; + } + + /** + * accessor method to set a state variable + * @param totalNumberServers total number of servers + * @throws IllegalArgumentException if totalNumberServers < 0 + */ + public void setTotalNumberServers(int totalNumberServers) { + if (totalNumberServers <= 0) { + throw new IllegalArgumentException("Need positive number of servers: " + totalNumberServers); + } + this.totalNumberServers = totalNumberServers; + } + + /** + * accessor method to get a state variable + * @return the serviceTimeGenerator + */ + public RandomVariate getServiceTimeGenerator() { + return this.serviceTimeGenerator; + } + + /** + * accessor method to set a state variable + * @param serviceTimeGenerator the serviceTimeGenerator to set + */ + public void setServiceTimeGenerator(RandomVariate serviceTimeGenerator) { + this.serviceTimeGenerator = serviceTimeGenerator; + } + + /** + * accessor method to get a state variable + * @return the totalNumberServers + */ + public int getTotalNumberServers() { + return this.totalNumberServers; + } + + /** + * accessor method to get a state variable + * @return the numberServed + */ + public int getNumberServed() { + return this.numberServed; + } +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerths.java b/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerths.java new file mode 100644 index 0000000000000000000000000000000000000000..a10641544236b4071ee0455fd9e22c417326d7fa --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerths.java @@ -0,0 +1,245 @@ +package SimkitOpenDis7Examples; + +import java.util.SortedSet; +import java.util.TreeSet; +import simkit.Priority; +import simkit.SimEntityBase; + +/** + * Model two crane berths + * @author abuss@nps.edu + */ +public class TwoCraneBerths extends SimEntityBase +{ + + /** + * Queue of Ships waiting to go into the berth + */ + protected SortedSet<Ship> queue; + + /** + * Contains 0, 1, or two Ships being unloaded + */ + protected SortedSet<Ship> berth; + + /** + * Time in the system for each Ship + */ + protected double timeInSystem; + + /** + * Delay in the queue for each Ship + */ + protected double delayInQueue; + + /** + * Instantiate queue and berth containers + */ + public TwoCraneBerths() { + this.queue = new TreeSet<>(); + this.berth = new TreeSet<>(); + } + + /** + * Clear queue and berth containers + */ + @Override + public void reset() { + super.reset(); + queue.clear(); + berth.clear(); + timeInSystem = Double.NaN; // Not a Number + delayInQueue = Double.NaN; // Not a Number + } + + /** + * Only PropertyChangeEvents + */ + public void doRun() + { + firePropertyChange("queue", getQueue()); + firePropertyChange("berth", getBerth()); + firePropertyChange("timeInSystem", getTimeInSystem()); + firePropertyChange("delayInQueue", getDelayInQueue()); + } + + /** + * Add the given Ship to queue<br> + * If berths is empty, schedule StartUnloadingTwoCranes<br> + * If berths has 1 Ship, schedule SwitchToOneCrane + * + * @param ship Given Ship arriving to harbor + */ + public void doArrival(Ship ship) { + + ship.stampTime(); + + SortedSet<Ship> oldQueue = getQueue(); + queue.add(ship); + firePropertyChange("queue", oldQueue, getQueue()); + + if (berth.isEmpty()) { + waitDelay("StartUnloadingTwoCranes", 0.0, Priority.HIGH); + } + + if (berth.size() == 1) { + waitDelay("SwitchToOneCrane", 0.0); + } + } + + /** + * Remove the first Ship from queue<br> + * DelayInQueue is elapsedTime of that Ship<br> + * Add the ship to berth container<br> + * Schedule EndUnloadingTwoCranes at half the remaining time + */ + public void doStartUnloadingTwoCranes() { + SortedSet<Ship> oldQueue = getQueue(); + Ship ship = queue.first(); + queue.remove(ship); + firePropertyChange("queue", oldQueue, getQueue()); + + delayInQueue = ship.getElapsedTime(); + firePropertyChange("delayInQueue", getDelayInQueue()); + + ship.stampTime(); + + SortedSet<Ship> oldBerth = getBerth(); + berth.add(ship); + firePropertyChange("berth", oldBerth, getBerth()); + + waitDelay("EndUnloadingTwoCranes", 0.5 * ship.getRemainingUnloadingTime()); + } + + /** + * Remove the (one) Ship from berth<br> + * TimeInSystem is the age of the Ship + */ + public void doEndUnloadingTwoCranes() { + SortedSet<Ship> oldBerth = getBerth(); + Ship ship = berth.first(); + berth.remove(ship); + firePropertyChange("berth", oldBerth, getBerth()); + + timeInSystem = ship.getAge(); + firePropertyChange("timeInSystem", getTimeInSystem()); + } + + /** + * This event is when a Ship arrives to find only one other Ship being + * unloaded.<br> + * Credit the ship in the berth with work at a rate of 2 (since 2 cranes + * have been unloading it<br> + * Interrupt EndUnloadingTwoCranes<br> + * Schedule EndUnloadingOneCrane with the Ship already in the berth<br> + * Schedule StartUnloadingOneCrane + */ + public void doSwitchToOneCrane() { + Ship ship = berth.first(); + ship.work(2.0); + ship.stampTime(); + + interrupt("EndUnloadingTwoCranes"); + + waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship); + + waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH); + } + + /** + * Pop the first Ship from the queue<br> + * delayInQueue is elapsedTime (from Arrival event)<br> + * Add that Ship to berth container<br> + * Schedule EndUnloadingOneCrane with that Ship + */ + public void doStartUnloadingOneCrane() { + SortedSet<Ship> oldQueue = getQueue(); + Ship ship = queue.first(); + queue.remove(ship); + firePropertyChange("queue", oldQueue, getQueue()); + + delayInQueue = ship.getElapsedTime(); + firePropertyChange("delayInQueue", getDelayInQueue()); + + ship.stampTime(); + + SortedSet<Ship> oldBerth = getBerth(); + berth.add(ship); + firePropertyChange("berth", oldBerth, getBerth()); + + waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship); + } + + /** + * Remove given Ship from berth<br> + * If Ships in queue, schedule StartUnloadingOneCrane<br> + * If queue is empty, schedule SwitchToTwoCranes<br> + * timeInSystem is age of Ship + * + * @param ship Given Ship + */ + public void doEndUnloadingOneCrane(Ship ship) { + SortedSet<Ship> oldBerth = getBerth(); + berth.remove(ship); + firePropertyChange("berth", oldBerth, getBerth()); + + if (queue.size() > 0) { + waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH); + } + + if (queue.isEmpty() && berth.size() == 1) { + waitDelay("SwitchToTwoCranes", 0.0); + } + + timeInSystem = ship.getAge(); + firePropertyChange("timeInSystem", getTimeInSystem()); + } + + /** + * Credit the work of the remaining Ship in berth at unit rate<br> + * Interrupt EndUnloadingOneCrane<br> + * Schedule EndUnloadingTwoCranes at double the rate (i.e., half the remaining time) + */ + public void doSwitchToTwoCranes() { + Ship ship = berth.first(); + ship.work(1.0); + ship.stampTime(); + + interrupt("EndUnloadingOneCrane", ship); + + waitDelay("EndUnloadingTwoCranes", + 0.5 * ship.getRemainingUnloadingTime()); + } + + /** + * Get tree of sorted Ship set queue + * @return Shallow copy of queue + */ + public SortedSet<Ship> getQueue() { + return new TreeSet<>(queue); + } + + /** + * Get tree of sorted Ship set berths + * @return Shallow copy of berth + */ + public SortedSet<Ship> getBerth() { + return new TreeSet<>(berth); + } + + /** + * accessor method to get a state variable + * @return The timeInSystem + */ + public double getTimeInSystem() { + return timeInSystem; + } + + /** + * accessor method to get a state variable + * @return The delayInQueue + */ + public double getDelayInQueue() { + return delayInQueue; + } +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsAssignment05.docx b/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsAssignment05.docx new file mode 100644 index 0000000000000000000000000000000000000000..73271d2d04efcd4250e536d58b18e760f9c36b8d Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsAssignment05.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsAssignment05Solution.docx b/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsAssignment05Solution.docx new file mode 100644 index 0000000000000000000000000000000000000000..a91574dcc69242c82303703ba899025c83314656 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsAssignment05Solution.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsOpenDis7.java b/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsOpenDis7.java new file mode 100644 index 0000000000000000000000000000000000000000..a6deb8fa55631a010b7c98923c348605b70dccd9 --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsOpenDis7.java @@ -0,0 +1,406 @@ +package SimkitOpenDis7Examples; + +import edu.nps.moves.dis7.enumerations.DisPduType; +import edu.nps.moves.dis7.enumerations.VariableRecordType; +import edu.nps.moves.dis7.pdus.EntityStatePdu; +import edu.nps.moves.dis7.pdus.EulerAngles; +import edu.nps.moves.dis7.pdus.Vector3Double; +import edu.nps.moves.dis7.utilities.DisChannel; +import edu.nps.moves.dis7.utilities.PduFactory; +import java.util.SortedSet; +import java.util.TreeSet; +import simkit.Priority; +import simkit.SimEntityBase; + +/** + * Add DIS outputs to TwoCraneBerths simkit simulation + * @see SimkitOpenDis7Examples.TwoCraneBerths + * @see <a href="run/RunTwoCranesBerthOpenDis7Log.txt" target="_blank">RunTwoCranesBerthOpenDis7Log.txt</a> + * @see <a href="TwoCraneBerthsAssignment05.docx" target="_blank">TwoCraneBerthsAssignment05.docx</a> + * @see <a href="TwoCraneBerthsAssignment05Solution.docx" target="_blank">TwoCraneBerthsAssignment05Solution.docx</a> + * @author abuss@nps.edu@nps.edu + * @author brutzman@nps.edu + */ +public class TwoCraneBerthsOpenDis7 extends SimEntityBase +{ + // Utility constructor method: initial descriptor and verboseness of disNetworkInterface, pduRecorder + private final DisChannel disChannel = new DisChannel("TwoCraneBerthsOpenDis7", false, true); + + PduFactory pduFactory = new PduFactory(); + EntityStatePdu espduCrane = (EntityStatePdu) pduFactory.createPdu(DisPduType.ENTITY_STATE); + + /** + * Queue of Ships waiting to go into the berth + */ + protected SortedSet<Ship> queue; + + /** + * Contains 0, 1, or two Ships being unloaded + */ + protected SortedSet<Ship> berth; + + /** + * Time in the system for each Ship + */ + protected double timeInSystem; + + /** + * Delay in the queue for each Ship + */ + protected double delayInQueue; + + /** + * number of Ships offloaded + */ + protected int shipCount = 0; + + /** + * Instantiate queue and berth containers + */ + public TwoCraneBerthsOpenDis7() { + this.queue = new TreeSet<>(); + this.berth = new TreeSet<>(); + } + + /** + * Clear queue and berth containers + */ + @Override + public void reset() { + super.reset(); + queue.clear(); + berth.clear(); + timeInSystem = Double.NaN; // Not a Number + delayInQueue = Double.NaN; // Not a Number + } + + /** + * Only PropertyChangeEvents + */ + public void doRun() + { + disChannel.setVerboseComments(true); + disChannel.setVerboseDisNetworkInterface(true); + + firePropertyChange("queue", getQueue()); + firePropertyChange("berth", getBerth()); + firePropertyChange("timeInSystem", getTimeInSystem()); + firePropertyChange("delayInQueue", getDelayInQueue()); + } + + /** + * Add the given Ship to queue<br> + * If berths is empty, schedule StartUnloadingTwoCranes<br> + * If berths has 1 Ship, schedule SwitchToOneCrane + * + * @param ship Given Ship arriving to harbor + */ + public void doArrival(Ship ship) { + + ship.stampTime(); + + SortedSet<Ship> oldQueue = getQueue(); + queue.add(ship); + firePropertyChange("queue", oldQueue, getQueue()); + + if (berth.isEmpty()) { + waitDelay("StartUnloadingTwoCranes", 0.0, Priority.HIGH); + } + + if (berth.size() == 1) { + waitDelay("SwitchToOneCrane", 0.0); + } + } + + /** + * Remove the first Ship from queue<br> + * DelayInQueue is elapsedTime of that Ship<br> + * Add the ship to berth container<br> + * Schedule EndUnloadingTwoCranes at half the remaining time + */ + public void doStartUnloadingTwoCranes() { + SortedSet<Ship> oldQueue = getQueue(); + Ship ship = queue.first(); + queue.remove(ship); + firePropertyChange("queue", oldQueue, getQueue()); + + delayInQueue = ship.getElapsedTime(); + firePropertyChange("delayInQueue", getDelayInQueue()); + + ship.stampTime(); + + SortedSet<Ship> oldBerth = getBerth(); + berth.add(ship); + firePropertyChange("berth", oldBerth, getBerth()); + + // TODO reportCraneContainerUnloadOperationsDIS() + + waitDelay("EndUnloadingTwoCranes", 0.5 * ship.getRemainingUnloadingTime()); + } + + /** + * Remove the (one) Ship from berth<br> + * TimeInSystem is the age of the Ship + */ + public void doEndUnloadingTwoCranes() { + SortedSet<Ship> oldBerth = getBerth(); + Ship ship = berth.first(); + berth.remove(ship); + firePropertyChange("berth", oldBerth, getBerth()); + + timeInSystem = ship.getAge(); + firePropertyChange("timeInSystem", getTimeInSystem()); + } + + /** + * This event is when a Ship arrives to find only one other Ship being + * unloaded.<br> + * Credit the ship in the berth with work at a rate of 2 (since 2 cranes + * have been unloading it<br> + * Interrupt EndUnloadingTwoCranes<br> + * Schedule EndUnloadingOneCrane with the Ship already in the berth<br> + * Schedule StartUnloadingOneCrane + */ + public void doSwitchToOneCrane() { + Ship ship = berth.first(); + ship.work(2.0); + ship.stampTime(); + + interrupt("EndUnloadingTwoCranes"); + + waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship); + + waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH); + } + + /** + * Pop the first Ship from the queue<br> + * delayInQueue is elapsedTime (from Arrival event)<br> + * Add that Ship to berth container<br> + * Schedule EndUnloadingOneCrane with that Ship + */ + public void doStartUnloadingOneCrane() { + SortedSet<Ship> oldQueue = getQueue(); + Ship ship = queue.first(); + queue.remove(ship); + firePropertyChange("queue", oldQueue, getQueue()); + + delayInQueue = ship.getElapsedTime(); + firePropertyChange("delayInQueue", getDelayInQueue()); + + ship.stampTime(); + + SortedSet<Ship> oldBerth = getBerth(); + berth.add(ship); + firePropertyChange("berth", oldBerth, getBerth()); + + // log crane operations for each ship + shipCount++; + + if (shipCount == 1) + System.out.println("====================================="); + if (shipCount <= 2) + { + reportCraneContainerUnloadOperationsDIS( ship.getTimeStamp(), // simkit timeStamp + 10, // numberOfContainers + 90.0 // initial position of Ship + ); // TODO indicate berth + System.out.println("====================================="); + } + + waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship); + } + + /** + * Perform crane container unloading operations and send PDUs to report progress + * @param simkitTimeStamp simkit timeStamp when crane operations began + * @param numberContainers how many container boxes to offload + * @param pierDistanceForCraneOffload Y coordinate down pier across from ship's berth, aligned with cargo + * @see <a href="https://en.wikipedia.org/wiki/The_Box_(Levinson_book)" target="_blank">The Box: How the Shipping Container Made the World Smaller and the World Economy Bigger is</a> + */ + public void reportCraneContainerUnloadOperationsDIS( + double simkitTimeStamp, + // which crane + // which berth + int numberContainers, + double pierDistanceForCraneOffload + // lengthOfCrane + ) + { + int disTimeStamp = (int)simkitTimeStamp; // TODO document relationship + + // Pier coordinate system follows, Right-Hand Rule (RHR) throughout: + // +X axis to right with X=0 on centerline of pier (train tracks + // +Y axis down pier with Y=0 at head of pier, + // +Z axis vertical with Z=0 at level of pier + // phi is rotation about +X axis, radians + // theta is rotation about +Y axis, radians + // psi is rotation about +X axis, radians + + Vector3Double positionPierHead = new Vector3Double(); +// Vector3Double positionPierHead = new Vector3Double(0.0, 0.0, 0.0); // TODO needs utility constructor + Vector3Double positionPierOffload = new Vector3Double(); + positionPierOffload.setY(pierDistanceForCraneOffload); + + double craneLinearSpeed = 1.0; // m/sec + double craneRotationRate = 10.0; // degrees/second + double containerHookupDuration = 60.0; // seconds average + double containerDetachDuration = 30.0; // seconds average + + // not modeling crane elevation angle, only orientation of crane cab and gantry + EulerAngles orientationToShip = (new EulerAngles()).setPsi((float) (90.0 * Math.PI/180.0)); // TODO utility methods needed + EulerAngles orientationToPier = (new EulerAngles()).setPsi((float) ( 0.0 * Math.PI/180.0)); // TODO utility methods needed + + // initialize ESPDU +// espduCrane.reset(); // TODO intialization utility method +// espduCrane.setEntityAppearance(TODO); // highlight active crane? + espduCrane.setTimestamp(disTimeStamp); + + // 1. Crane at head of pier, operator present, boom elevated vertically in stow position + espduCrane.setEntityLocation(positionPierHead); + espduCrane.setEntityOrientation(orientationToPier); + disChannel.sendSinglePdu (disTimeStamp, espduCrane); + disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Ready to process Ship " + shipCount + " with crane at head of pier"); + + // 2, Ship arrives, tug departs + // ship PDU already, TODO can track tugboat here if desired for further fidelity + + // 3. Crane moves to position of ship: travel to positionOfCrane ay craneLinearSpeed + double craneTravelDuration = pierDistanceForCraneOffload / craneLinearSpeed; // units analysis: meters / (meters/second) = seconds + espduCrane.setEntityLocation(pierDistanceForCraneOffload, 0.0, 0.0); + disChannel.sendSinglePdu(disTimeStamp, espduCrane); + disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, + "Crane moved to position " + pierDistanceForCraneOffload + "m for offload after " + craneTravelDuration + " seconds"); + + // 4. repeat until done: Crane rotates, lift container, rotates, lower container + for (int containerIndex = 1; containerIndex <= numberContainers; containerIndex++) + { + // 4.a crane rotates to ship + double craneRotationDelay = 90.0 / craneRotationRate; // units analysis: degrees / (degrees/second) = seconds + espduCrane.setEntityOrientation(orientationToShip); + disChannel.sendSinglePdu(disTimeStamp, espduCrane); + disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Crane oriented to ship after " + craneRotationDelay + " seconds" + + " with craneRotationRate=" + craneRotationRate + " degrees/second"); + +// // 4.b announce next step without further delay, then perform container hookup + disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Hooking up Container " + containerIndex + " to crane has started..."); // TODO + whichCrane + + disTimeStamp += containerHookupDuration; +// disChannel.sendSinglePdu(disTimeStamp, espduCrane); // superfluous, crane hasn't moved + disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Hooked up: Container " + containerIndex + " to crane" // TODO + whichCrane + + " after " + craneRotationDelay + " seconds"); + + // 4.c crane rotates to pier + disTimeStamp += craneRotationDelay; + espduCrane.setEntityOrientation(orientationToPier); + disChannel.sendSinglePdu(disTimeStamp, espduCrane); + disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Crane oriented to pier after " + craneRotationDelay + " seconds" + + " with craneRotationRate=" + craneRotationRate + " degrees/second"); + + // 4.d crane unhooks container + disTimeStamp += containerDetachDuration; +// disChannel.sendSinglePdu(disTimeStamp, espduCrane); // superfluous, crane hasn't moved + disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Crane detached: Container " + containerIndex + " on pier" // TODO + whichCrane + + " after " + containerDetachDuration + " seconds"); + + // send PDUs accordingly + double totalDelay = (2.0 * craneRotationDelay + containerHookupDuration + containerDetachDuration); + disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.ELAPSED_TIME,"Time duration for crane moving container " + containerIndex + ": " + totalDelay + " seconds"); + + // Future work: if this container is special, meaning on watchlist, report it + } + + // 4. Crane stows boom in vertical position + // TODO future refinement if even-more fidelity is desired + + // 5. Crane returns to head of pier every time in order to avoid interference with ship mooring/unmooring + espduCrane.setEntityLocation(positionPierHead); // head of pier + disTimeStamp += craneTravelDuration; // travel time back to head of pier + espduCrane.setEntityLocation(positionPierHead); + disChannel.sendSinglePdu(disTimeStamp, espduCrane); + } + /** + * Shutdown DIS network interfaces, enabling program termination + */ + public void shutdownDisChannel() + { + if (disChannel != null) + { + disChannel.leave(); + disChannel.tearDownNetworkInterface(); + } + } + + /** + * Remove given Ship from berth<br> + * If Ships in queue, schedule StartUnloadingOneCrane<br> + * If queue is empty, schedule SwitchToTwoCranes<br> + * timeInSystem is age of Ship + * + * @param ship Given Ship + */ + public void doEndUnloadingOneCrane(Ship ship) { + SortedSet<Ship> oldBerth = getBerth(); + berth.remove(ship); + firePropertyChange("berth", oldBerth, getBerth()); + + if (queue.size() > 0) { + waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH); + } + + if (queue.isEmpty() && berth.size() == 1) { + waitDelay("SwitchToTwoCranes", 0.0); + } + + timeInSystem = ship.getAge(); + firePropertyChange("timeInSystem", getTimeInSystem()); + } + + /** + * Credit the work of the remaining Ship in berth at unit rate<br> + * Interrupt EndUnloadingOneCrane<br> + * Schedule EndUnloadingTwoCranes at double the rate (i.e., half the remaining time) + */ + public void doSwitchToTwoCranes() { + Ship ship = berth.first(); + ship.work(1.0); + ship.stampTime(); + + interrupt("EndUnloadingOneCrane", ship); + + waitDelay("EndUnloadingTwoCranes", + 0.5 * ship.getRemainingUnloadingTime()); + } + + /** + * Get tree of sorted Ship set queue + * @return Shallow copy of queue + */ + public SortedSet<Ship> getQueue() { + return new TreeSet<>(queue); + } + + /** + * Get tree of sorted Ship set berths + * @return Shallow copy of berth + */ + public SortedSet<Ship> getBerth() { + return new TreeSet<>(berth); + } + + /** + * accessor method to get a state variable + * @return The timeInSystem + */ + public double getTimeInSystem() { + return timeInSystem; + } + + /** + * accessor method to get a state variable + * @return The delayInQueue + */ + public double getDelayInQueue() { + return delayInQueue; + } +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsScenarioSketch.jpg b/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsScenarioSketch.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c23da5774f4f62b2e6bf182311aace53e889fb92 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/TwoCraneBerthsScenarioSketch.jpg differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/TwoCranesBerthComponentEventGraph.png b/assignments/src/src/SimkitOpenDis7Examples/TwoCranesBerthComponentEventGraph.png new file mode 100644 index 0000000000000000000000000000000000000000..dde26d29446baf5b62b49d3011faa55ad6e0f2ec Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/TwoCranesBerthComponentEventGraph.png differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/TwoCranesBerthComponentEventGraphOpenDis7.png b/assignments/src/src/SimkitOpenDis7Examples/TwoCranesBerthComponentEventGraphOpenDis7.png new file mode 100644 index 0000000000000000000000000000000000000000..e949b1af5bde4a36efdc2525ad5a1a4c300fac1f Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/TwoCranesBerthComponentEventGraphOpenDis7.png differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/TwoCranesTwoPiersSketch.jpg b/assignments/src/src/SimkitOpenDis7Examples/TwoCranesTwoPiersSketch.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5f0681603bf90b6934aefab6de88441ae88c521b Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/TwoCranesTwoPiersSketch.jpg differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/BussComponentBasedSimulationModelingSimkitWintersim2002.pdf b/assignments/src/src/SimkitOpenDis7Examples/documentation/BussComponentBasedSimulationModelingSimkitWintersim2002.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fd148b3fcd586f237c8df1d394ba35007c509594 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/BussComponentBasedSimulationModelingSimkitWintersim2002.pdf differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/Discrete Event Simulation Modeling.pdf b/assignments/src/src/SimkitOpenDis7Examples/documentation/Discrete Event Simulation Modeling.pdf new file mode 100644 index 0000000000000000000000000000000000000000..529b1ed191932d95269a4471d6fb0ed5c7ca3995 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/Discrete Event Simulation Modeling.pdf differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/HarborWithTwoCranes.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/HarborWithTwoCranes.docx new file mode 100644 index 0000000000000000000000000000000000000000..73271d2d04efcd4250e536d58b18e760f9c36b8d Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/HarborWithTwoCranes.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 01 - The Arrival Process.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 01 - The Arrival Process.docx new file mode 100644 index 0000000000000000000000000000000000000000..3d2e31d90e7194186741fdeba8c9d90e4b4c124f Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 01 - The Arrival Process.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 02 - The Multiple Server Queue.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 02 - The Multiple Server Queue.docx new file mode 100644 index 0000000000000000000000000000000000000000..5d9064884772fc4e5b51ddc8e3bae287f389842e Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 02 - The Multiple Server Queue.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 03 - Server with Reneges.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 03 - Server with Reneges.docx new file mode 100644 index 0000000000000000000000000000000000000000..7bdfa0720f6358104b2994011af683807046ca6b Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 03 - Server with Reneges.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 04 - Transfer Line.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 04 - Transfer Line.docx new file mode 100644 index 0000000000000000000000000000000000000000..10fec58e9c034aff50433e40923d44bb61587901 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 04 - Transfer Line.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 05 - Two Crane Berths.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 05 - Two Crane Berths.docx new file mode 100644 index 0000000000000000000000000000000000000000..a91574dcc69242c82303703ba899025c83314656 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 05 - Two Crane Berths.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 06 - Movers and MoverManagers.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 06 - Movers and MoverManagers.docx new file mode 100644 index 0000000000000000000000000000000000000000..c174d84d220e0308afa431f37ea3fe0707d20350 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/ComputerAssignment 06 - Movers and MoverManagers.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Midterm-2022 Solution.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Midterm-2022 Solution.docx new file mode 100644 index 0000000000000000000000000000000000000000..7dd33e982616ac2b3ddb161541a3bfd956fa3624 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Midterm-2022 Solution.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Sample Electronic Submission.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Sample Electronic Submission.docx new file mode 100644 index 0000000000000000000000000000000000000000..4a85437723f8f8d6b527feddb80509636fbe32eb Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Sample Electronic Submission.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Sample Written Submission.pdf b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Sample Written Submission.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8592c05ebc09a7307df99871ce271e77b91f75b4 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Sample Written Submission.pdf differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/SampleMidterm.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/SampleMidterm.docx new file mode 100644 index 0000000000000000000000000000000000000000..cd64836b412ee77ff365fb6e6ce795591a896810 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/SampleMidterm.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/SampleMidtermSolution.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/SampleMidtermSolution.docx new file mode 100644 index 0000000000000000000000000000000000000000..7cd2db9c4957831c261e1ba85249299ceac032ae Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/SampleMidtermSolution.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Simple Movers Output.txt b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Simple Movers Output.txt new file mode 100644 index 0000000000000000000000000000000000000000..85640332d61f945fe8b26935d1fa6d2e6feb1865 --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/Simple Movers Output.txt @@ -0,0 +1,411 @@ +SimpleMover.1 + maxSpeed = 30.0 + initialLocation = Point2D.Double[0.0, 250.0] +SimplePathMoverManager.2 + path[0] = Point2D.Double[200.0, 0.0] + path[1] = Point2D.Double[-200.0, 250.0] + path[2] = Point2D.Double[200.0, 250.0] + path[3] = Point2D.Double[0.0, 250.0] + startOnRun = true +SimpleMover.3 + maxSpeed = 40.0 + initialLocation = Point2D.Double[0.0, 150.0] +SimplePatrolMoverManager.4 + path[0] = Point2D.Double[0.0, 300.0] + path[1] = Point2D.Double[0.0, -100.0] + startOnRun = true +SimpleMover.5 + maxSpeed = 50.0 + initialLocation = Point2D.Double[0.0, 0.0] +SimpleRandomMoverManager.6 + startOnRun = true + coordinateGenerator[0] = Uniform (-250.000, 250.000) + coordinateGenerator[1] = Uniform (-100.000, 300.000) +** Event List 0 -- Starting Simulation ** +0.0000 Run <SimpleMover.1> +0.0000 Run <SimplePathMoverManager.2> +0.0000 Run <SimpleMover.3> +0.0000 Run <SimplePatrolMoverManager.4> +0.0000 Run <SimpleMover.5> +0.0000 Run <SimpleRandomMoverManager.6> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- Starting Simulation ** + +<SimpleMover.1> lastStopLocation: Point2D.Double[0.0, 250.0] +<SimpleMover.1> velocity: Point2D.Double[0.0, 0.0] +<SimpleMover.1> destination: Point2D.Double[NaN, NaN] +<SimpleMover.1> startMoveTime: 0.0 +Time: 0.0000 CurrentEvent: Run [1] +** Event List 0 -- ** +0.0000 Run <SimplePathMoverManager.2> +0.0000 Run <SimpleMover.3> +0.0000 Run <SimplePatrolMoverManager.4> +0.0000 Run <SimpleMover.5> +0.0000 Run <SimpleRandomMoverManager.6> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimplePathMoverManager.2> next: 0 +Time: 0.0000 CurrentEvent: Run [2] +** Event List 0 -- ** +0.0000 Run <SimpleMover.3> +0.0000 Run <SimplePatrolMoverManager.4> +0.0000 Run <SimpleMover.5> +0.0000 Run <SimpleRandomMoverManager.6> +0.0000 Start <SimplePathMoverManager.2> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.3> lastStopLocation: Point2D.Double[0.0, 150.0] +<SimpleMover.3> velocity: Point2D.Double[0.0, 0.0] +<SimpleMover.3> destination: Point2D.Double[NaN, NaN] +<SimpleMover.3> startMoveTime: 0.0 +Time: 0.0000 CurrentEvent: Run [3] +** Event List 0 -- ** +0.0000 Run <SimplePatrolMoverManager.4> +0.0000 Run <SimpleMover.5> +0.0000 Run <SimpleRandomMoverManager.6> +0.0000 Start <SimplePathMoverManager.2> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimplePatrolMoverManager.4> next: 0 +Time: 0.0000 CurrentEvent: Run [4] +** Event List 0 -- ** +0.0000 Run <SimpleMover.5> +0.0000 Run <SimpleRandomMoverManager.6> +0.0000 Start <SimplePathMoverManager.2> +0.0000 Start <SimplePatrolMoverManager.4> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 0.0000 CurrentEvent: Run [5] +** Event List 0 -- ** +0.0000 Run <SimpleRandomMoverManager.6> +0.0000 Start <SimplePathMoverManager.2> +0.0000 Start <SimplePatrolMoverManager.4> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 0.0000 CurrentEvent: Run [6] +** Event List 0 -- ** +0.0000 Start <SimplePathMoverManager.2> +0.0000 Start <SimplePatrolMoverManager.4> +0.0000 Start <SimpleRandomMoverManager.6> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 0.0000 CurrentEvent: Start [1] +** Event List 0 -- ** +0.0000 Start <SimplePatrolMoverManager.4> +0.0000 Start <SimpleRandomMoverManager.6> +0.0000 MoveTo {Point2D.Double[200.0, 0.0]} <SimplePathMoverManager.2> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 0.0000 CurrentEvent: Start [2] +** Event List 0 -- ** +0.0000 Start <SimpleRandomMoverManager.6> +0.0000 MoveTo {Point2D.Double[200.0, 0.0]} <SimplePathMoverManager.2> +0.0000 MoveTo {Point2D.Double[0.0, 300.0]} <SimplePatrolMoverManager.4> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 0.0000 CurrentEvent: Start [3] +** Event List 0 -- ** +0.0000 MoveTo {Point2D.Double[200.0, 0.0]} <SimplePathMoverManager.2> +0.0000 MoveTo {Point2D.Double[0.0, 300.0]} <SimplePatrolMoverManager.4> +0.0000 MoveTo {Point2D.Double[158.66502991411835, 299.62435979396105]} <SimpleRandomMoverManager.6> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.1> destination: Point2D.Double[NaN, NaN] => Point2D.Double[200.0, 0.0] +Time: 0.0000 CurrentEvent: MoveTo {Point2D.Double[200.0, 0.0]} [1] +** Event List 0 -- ** +0.0000 MoveTo {Point2D.Double[0.0, 300.0]} <SimplePatrolMoverManager.4> +0.0000 MoveTo {Point2D.Double[158.66502991411835, 299.62435979396105]} <SimpleRandomMoverManager.6> +0.0000 StartMove {SimpleMover.1 (0.000, 250.000) [0.000, 0.000]} <SimpleMover.1> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.3> destination: Point2D.Double[NaN, NaN] => Point2D.Double[0.0, 300.0] +Time: 0.0000 CurrentEvent: MoveTo {Point2D.Double[0.0, 300.0]} [2] +** Event List 0 -- ** +0.0000 MoveTo {Point2D.Double[158.66502991411835, 299.62435979396105]} <SimpleRandomMoverManager.6> +0.0000 StartMove {SimpleMover.1 (0.000, 250.000) [0.000, 0.000]} <SimpleMover.1> +0.0000 StartMove {SimpleMover.3 (0.000, 150.000) [0.000, 0.000]} <SimpleMover.3> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 0.0000 CurrentEvent: MoveTo {Point2D.Double[158.66502991411835, 299.62435979396105]} [3] +** Event List 0 -- ** +0.0000 StartMove {SimpleMover.1 (0.000, 250.000) [0.000, 0.000]} <SimpleMover.1> +0.0000 StartMove {SimpleMover.3 (0.000, 150.000) [0.000, 0.000]} <SimpleMover.3> +0.0000 StartMove {SimpleMover.5 (0.000, 0.000) [0.000, 0.000]} <SimpleMover.5> +10.0000 Stop <SimplePatrolMoverManager.4> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.1> startMoveTime: 0.0 => 0.0 +<SimpleMover.1> velocity: Point2D.Double[0.0, 0.0] => Point2D.Double[18.74085142663273, -23.426064283290913] +Time: 0.0000 CurrentEvent: StartMove {SimpleMover.1 (0.000, 250.000) [18.741, -23.426]} [1] +** Event List 0 -- ** +0.0000 StartMove {SimpleMover.3 (0.000, 150.000) [0.000, 0.000]} <SimpleMover.3> +0.0000 StartMove {SimpleMover.5 (0.000, 0.000) [0.000, 0.000]} <SimpleMover.5> +10.0000 Stop <SimplePatrolMoverManager.4> +10.6719 EndMove {SimpleMover.1 (0.000, 250.000) [18.741, -23.426]} <SimpleMover.1> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.3> startMoveTime: 0.0 => 0.0 +<SimpleMover.3> velocity: Point2D.Double[0.0, 0.0] => Point2D.Double[0.0, 40.0] +Time: 0.0000 CurrentEvent: StartMove {SimpleMover.3 (0.000, 150.000) [0.000, 40.000]} [2] +** Event List 0 -- ** +0.0000 StartMove {SimpleMover.5 (0.000, 0.000) [0.000, 0.000]} <SimpleMover.5> +3.7500 EndMove {SimpleMover.3 (0.000, 150.000) [0.000, 40.000]} <SimpleMover.3> +10.0000 Stop <SimplePatrolMoverManager.4> +10.6719 EndMove {SimpleMover.1 (0.000, 250.000) [18.741, -23.426]} <SimpleMover.1> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 0.0000 CurrentEvent: StartMove {SimpleMover.5 (0.000, 0.000) [23.399, 44.187]} [3] +** Event List 0 -- ** +3.7500 EndMove {SimpleMover.3 (0.000, 150.000) [0.000, 40.000]} <SimpleMover.3> +6.7808 EndMove {SimpleMover.5 (0.000, 0.000) [23.399, 44.187]} <SimpleMover.5> +10.0000 Stop <SimplePatrolMoverManager.4> +10.6719 EndMove {SimpleMover.1 (0.000, 250.000) [18.741, -23.426]} <SimpleMover.1> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.3> lastStopLocation: Point2D.Double[0.0, 150.0] => Point2D.Double[0.0, 300.0] +<SimpleMover.3> velocity: Point2D.Double[0.0, 40.0] => Point2D.Double[0.0, 0.0] +<SimplePatrolMoverManager.4> next: 0 => 1 +Time: 3.7500 CurrentEvent: EndMove {SimpleMover.3 (0.000, 300.000) [0.000, 0.000]} [1] +** Event List 0 -- ** +3.7500 MoveTo {Point2D.Double[0.0, -100.0]} <SimplePatrolMoverManager.4> +6.7808 EndMove {SimpleMover.5 (87.746, 165.701) [23.399, 44.187]} <SimpleMover.5> +10.0000 Stop <SimplePatrolMoverManager.4> +10.6719 EndMove {SimpleMover.1 (70.278, 162.152) [18.741, -23.426]} <SimpleMover.1> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.3> destination: Point2D.Double[0.0, 300.0] => Point2D.Double[0.0, -100.0] +Time: 3.7500 CurrentEvent: MoveTo {Point2D.Double[0.0, -100.0]} [4] +** Event List 0 -- ** +3.7500 StartMove {SimpleMover.3 (0.000, 300.000) [0.000, 0.000]} <SimpleMover.3> +6.7808 EndMove {SimpleMover.5 (87.746, 165.701) [23.399, 44.187]} <SimpleMover.5> +10.0000 Stop <SimplePatrolMoverManager.4> +10.6719 EndMove {SimpleMover.1 (70.278, 162.152) [18.741, -23.426]} <SimpleMover.1> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.3> startMoveTime: 0.0 => 3.75 +<SimpleMover.3> velocity: Point2D.Double[0.0, 0.0] => Point2D.Double[0.0, -40.0] +Time: 3.7500 CurrentEvent: StartMove {SimpleMover.3 (0.000, 300.000) [0.000, -40.000]} [4] +** Event List 0 -- ** +6.7808 EndMove {SimpleMover.5 (87.746, 165.701) [23.399, 44.187]} <SimpleMover.5> +10.0000 Stop <SimplePatrolMoverManager.4> +10.6719 EndMove {SimpleMover.1 (70.278, 162.152) [18.741, -23.426]} <SimpleMover.1> +13.7500 EndMove {SimpleMover.3 (0.000, 300.000) [0.000, -40.000]} <SimpleMover.3> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 6.7808 CurrentEvent: EndMove {SimpleMover.5 (158.665, 299.624) [0.000, 0.000]} [2] +** Event List 0 -- ** +6.7808 MoveTo {Point2D.Double[5.1771862199530005, -47.38683607429266]} <SimpleRandomMoverManager.6> +10.0000 Stop <SimplePatrolMoverManager.4> +10.6719 EndMove {SimpleMover.1 (127.079, 91.152) [18.741, -23.426]} <SimpleMover.1> +13.7500 EndMove {SimpleMover.3 (0.000, 178.767) [0.000, -40.000]} <SimpleMover.3> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 6.7808 CurrentEvent: MoveTo {Point2D.Double[5.1771862199530005, -47.38683607429266]} [5] +** Event List 0 -- ** +6.7808 StartMove {SimpleMover.5 (158.665, 299.624) [0.000, 0.000]} <SimpleMover.5> +10.0000 Stop <SimplePatrolMoverManager.4> +10.6719 EndMove {SimpleMover.1 (127.079, 91.152) [18.741, -23.426]} <SimpleMover.1> +13.7500 EndMove {SimpleMover.3 (0.000, 178.767) [0.000, -40.000]} <SimpleMover.3> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 6.7808 CurrentEvent: StartMove {SimpleMover.5 (158.665, 299.624) [-20.226, -45.727]} [5] +** Event List 0 -- ** +10.0000 Stop <SimplePatrolMoverManager.4> +10.6719 EndMove {SimpleMover.1 (127.079, 91.152) [18.741, -23.426]} <SimpleMover.1> +13.7500 EndMove {SimpleMover.3 (0.000, 178.767) [0.000, -40.000]} <SimpleMover.3> +14.3697 EndMove {SimpleMover.5 (158.665, 299.624) [-20.226, -45.727]} <SimpleMover.5> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 10.0000 CurrentEvent: Stop [1] +** Event List 0 -- ** +10.0000 OrderStop <SimplePatrolMoverManager.4> +10.6719 EndMove {SimpleMover.1 (187.409, 15.739) [18.741, -23.426]} <SimpleMover.1> +13.7500 EndMove {SimpleMover.3 (0.000, 50.000) [0.000, -40.000]} <SimpleMover.3> +14.3697 EndMove {SimpleMover.5 (93.556, 152.423) [-20.226, -45.727]} <SimpleMover.5> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +Time: 10.0000 CurrentEvent: OrderStop [1] +** Event List 0 -- ** +10.0000 Stop {SimpleMover.3 (0.000, 50.000) [0.000, -40.000]} <SimpleMover.3> +10.6719 EndMove {SimpleMover.1 (187.409, 15.739) [18.741, -23.426]} <SimpleMover.1> +13.7500 EndMove {SimpleMover.3 (0.000, 50.000) [0.000, -40.000]} <SimpleMover.3> +14.3697 EndMove {SimpleMover.5 (93.556, 152.423) [-20.226, -45.727]} <SimpleMover.5> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.3> lastStopLocation: Point2D.Double[0.0, 300.0] => Point2D.Double[0.0, 50.0] +<SimpleMover.3> velocity: Point2D.Double[0.0, -40.0] => Point2D.Double[0.0, 0.0] +Time: 10.0000 CurrentEvent: Stop {SimpleMover.3 (0.000, 50.000) [0.000, 0.000]} [1] +** Event List 0 -- ** +10.6719 EndMove {SimpleMover.1 (187.409, 15.739) [18.741, -23.426]} <SimpleMover.1> +14.3697 EndMove {SimpleMover.5 (93.556, 152.423) [-20.226, -45.727]} <SimpleMover.5> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.1> lastStopLocation: Point2D.Double[0.0, 250.0] => Point2D.Double[200.0, 0.0] +<SimpleMover.1> velocity: Point2D.Double[18.74085142663273, -23.426064283290913] => Point2D.Double[0.0, 0.0] +<SimplePathMoverManager.2> next: 0 => 1 +Time: 10.6719 CurrentEvent: EndMove {SimpleMover.1 (200.000, 0.000) [0.000, 0.000]} [3] +** Event List 0 -- ** +10.6719 MoveTo {Point2D.Double[-200.0, 250.0]} <SimplePathMoverManager.2> +14.3697 EndMove {SimpleMover.5 (79.967, 121.700) [-20.226, -45.727]} <SimpleMover.5> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.1> destination: Point2D.Double[200.0, 0.0] => Point2D.Double[-200.0, 250.0] +Time: 10.6719 CurrentEvent: MoveTo {Point2D.Double[-200.0, 250.0]} [6] +** Event List 0 -- ** +10.6719 StartMove {SimpleMover.1 (200.000, 0.000) [0.000, 0.000]} <SimpleMover.1> +14.3697 EndMove {SimpleMover.5 (79.967, 121.700) [-20.226, -45.727]} <SimpleMover.5> +20.0000 Stop <SimpleRandomMoverManager.6> + ** End of Event List -- ** + +<SimpleMover.1> startMoveTime: 0.0 => 10.671873729054747 +<SimpleMover.1> velocity: Point2D.Double[0.0, 0.0] => Point2D.Double[-25.43994912015264, 15.899968200095401] +Time: 10.6719 CurrentEvent: StartMove {SimpleMover.1 (200.000, 0.000) [-25.440, 15.900]} [6] +** Event List 0 -- ** +14.3697 EndMove {SimpleMover.5 (79.967, 121.700) [-20.226, -45.727]} <SimpleMover.5> +20.0000 Stop <SimpleRandomMoverManager.6> +26.3952 EndMove {SimpleMover.1 (200.000, 0.000) [-25.440, 15.900]} <SimpleMover.1> + ** End of Event List -- ** + +Time: 14.3697 CurrentEvent: EndMove {SimpleMover.5 (5.177, -47.387) [0.000, 0.000]} [4] +** Event List 0 -- ** +14.3697 MoveTo {Point2D.Double[-232.29182581417263, 296.9878137111664]} <SimpleRandomMoverManager.6> +20.0000 Stop <SimpleRandomMoverManager.6> +26.3952 EndMove {SimpleMover.1 (105.929, 58.795) [-25.440, 15.900]} <SimpleMover.1> + ** End of Event List -- ** + +Time: 14.3697 CurrentEvent: MoveTo {Point2D.Double[-232.29182581417263, 296.9878137111664]} [7] +** Event List 0 -- ** +14.3697 StartMove {SimpleMover.5 (5.177, -47.387) [0.000, 0.000]} <SimpleMover.5> +20.0000 Stop <SimpleRandomMoverManager.6> +26.3952 EndMove {SimpleMover.1 (105.929, 58.795) [-25.440, 15.900]} <SimpleMover.1> + ** End of Event List -- ** + +Time: 14.3697 CurrentEvent: StartMove {SimpleMover.5 (5.177, -47.387) [-28.384, 41.162]} [7] +** Event List 0 -- ** +20.0000 Stop <SimpleRandomMoverManager.6> +22.7359 EndMove {SimpleMover.5 (5.177, -47.387) [-28.384, 41.162]} <SimpleMover.5> +26.3952 EndMove {SimpleMover.1 (105.929, 58.795) [-25.440, 15.900]} <SimpleMover.1> + ** End of Event List -- ** + +Time: 20.0000 CurrentEvent: Stop [2] +** Event List 0 -- ** +20.0000 OrderStop <SimpleRandomMoverManager.6> +22.7359 EndMove {SimpleMover.5 (-154.636, 184.372) [-28.384, 41.162]} <SimpleMover.5> +26.3952 EndMove {SimpleMover.1 (-37.307, 148.317) [-25.440, 15.900]} <SimpleMover.1> + ** End of Event List -- ** + +Time: 20.0000 CurrentEvent: OrderStop [2] +** Event List 0 -- ** +20.0000 Stop {SimpleMover.5 (-154.636, 184.372) [-28.384, 41.162]} <SimpleMover.5> +22.7359 EndMove {SimpleMover.5 (-154.636, 184.372) [-28.384, 41.162]} <SimpleMover.5> +26.3952 EndMove {SimpleMover.1 (-37.307, 148.317) [-25.440, 15.900]} <SimpleMover.1> + ** End of Event List -- ** + +Time: 20.0000 CurrentEvent: Stop {SimpleMover.5 (-154.636, 184.372) [0.000, 0.000]} [2] +** Event List 0 -- ** +26.3952 EndMove {SimpleMover.1 (-37.307, 148.317) [-25.440, 15.900]} <SimpleMover.1> + ** End of Event List -- ** + +<SimpleMover.1> lastStopLocation: Point2D.Double[200.0, 0.0] => Point2D.Double[-200.0, 250.0] +<SimpleMover.1> velocity: Point2D.Double[-25.43994912015264, 15.899968200095401] => Point2D.Double[0.0, 0.0] +<SimplePathMoverManager.2> next: 1 => 2 +Time: 26.3952 CurrentEvent: EndMove {SimpleMover.1 (-200.000, 250.000) [0.000, 0.000]} [5] +** Event List 0 -- ** +26.3952 MoveTo {Point2D.Double[200.0, 250.0]} <SimplePathMoverManager.2> + ** End of Event List -- ** + +<SimpleMover.1> destination: Point2D.Double[-200.0, 250.0] => Point2D.Double[200.0, 250.0] +Time: 26.3952 CurrentEvent: MoveTo {Point2D.Double[200.0, 250.0]} [8] +** Event List 0 -- ** +26.3952 StartMove {SimpleMover.1 (-200.000, 250.000) [0.000, 0.000]} <SimpleMover.1> + ** End of Event List -- ** + +<SimpleMover.1> startMoveTime: 10.671873729054747 => 26.395175615815752 +<SimpleMover.1> velocity: Point2D.Double[0.0, 0.0] => Point2D.Double[30.0, 0.0] +Time: 26.3952 CurrentEvent: StartMove {SimpleMover.1 (-200.000, 250.000) [30.000, 0.000]} [8] +** Event List 0 -- ** +39.7285 EndMove {SimpleMover.1 (-200.000, 250.000) [30.000, 0.000]} <SimpleMover.1> + ** End of Event List -- ** + +<SimpleMover.1> lastStopLocation: Point2D.Double[-200.0, 250.0] => Point2D.Double[200.0, 250.0] +<SimpleMover.1> velocity: Point2D.Double[30.0, 0.0] => Point2D.Double[0.0, 0.0] +<SimplePathMoverManager.2> next: 2 => 3 +Time: 39.7285 CurrentEvent: EndMove {SimpleMover.1 (200.000, 250.000) [0.000, 0.000]} [6] +** Event List 0 -- ** +39.7285 MoveTo {Point2D.Double[0.0, 250.0]} <SimplePathMoverManager.2> + ** End of Event List -- ** + +<SimpleMover.1> destination: Point2D.Double[200.0, 250.0] => Point2D.Double[0.0, 250.0] +Time: 39.7285 CurrentEvent: MoveTo {Point2D.Double[0.0, 250.0]} [9] +** Event List 0 -- ** +39.7285 StartMove {SimpleMover.1 (200.000, 250.000) [0.000, 0.000]} <SimpleMover.1> + ** End of Event List -- ** + +<SimpleMover.1> startMoveTime: 26.395175615815752 => 39.72850894914909 +<SimpleMover.1> velocity: Point2D.Double[0.0, 0.0] => Point2D.Double[-30.0, 0.0] +Time: 39.7285 CurrentEvent: StartMove {SimpleMover.1 (200.000, 250.000) [-30.000, 0.000]} [9] +** Event List 0 -- ** +46.3952 EndMove {SimpleMover.1 (200.000, 250.000) [-30.000, 0.000]} <SimpleMover.1> + ** End of Event List -- ** + +<SimpleMover.1> lastStopLocation: Point2D.Double[200.0, 250.0] => Point2D.Double[0.0, 250.0] +<SimpleMover.1> velocity: Point2D.Double[-30.0, 0.0] => Point2D.Double[0.0, 0.0] +<SimplePathMoverManager.2> next: 3 => 4 +Time: 46.3952 CurrentEvent: EndMove {SimpleMover.1 (0.000, 250.000) [0.000, 0.000]} [7] +** Event List 0 -- ** +46.3952 Stop <SimplePathMoverManager.2> + ** End of Event List -- ** + +Time: 46.3952 CurrentEvent: Stop [3] +** Event List 0 -- ** +46.3952 OrderStop <SimplePathMoverManager.2> + ** End of Event List -- ** + +Time: 46.3952 CurrentEvent: OrderStop [3] +** Event List 0 -- ** +46.3952 Stop {SimpleMover.1 (0.000, 250.000) [0.000, 0.000]} <SimpleMover.1> + ** End of Event List -- ** + +<SimpleMover.1> lastStopLocation: Point2D.Double[0.0, 250.0] => Point2D.Double[0.0, 250.0] +<SimpleMover.1> velocity: Point2D.Double[0.0, 0.0] => Point2D.Double[0.0, 0.0] +Time: 46.3952 CurrentEvent: Stop {SimpleMover.1 (0.000, 250.000) [0.000, 0.000]} [3] +** Event List 0 -- ** + << empty >> + ** End of Event List -- ** \ No newline at end of file diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment1.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment1.docx new file mode 100644 index 0000000000000000000000000000000000000000..7b02d16b602a096514e014be5c3b23b8dbc5c7aa Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment1.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment1Solution.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment1Solution.docx new file mode 100644 index 0000000000000000000000000000000000000000..3f6bc3afe005e77a11bc71cb630b15b9c44b67b5 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment1Solution.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment2.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment2.docx new file mode 100644 index 0000000000000000000000000000000000000000..3438b6b508cabaef0f81a26525edcd776358b009 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment2.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment2Solution.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment2Solution.docx new file mode 100644 index 0000000000000000000000000000000000000000..a06ee419659e80c596784ad56ecb8801ccd4dd1e Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment2Solution.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment3.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment3.docx new file mode 100644 index 0000000000000000000000000000000000000000..84dcb3e749691a115e27448eb857935410f3f54a Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment3.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment3Solution.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment3Solution.docx new file mode 100644 index 0000000000000000000000000000000000000000..809dbf2d314b3ce1f5333ec25db1a04315ae4eff Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment3Solution.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment4.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment4.docx new file mode 100644 index 0000000000000000000000000000000000000000..87b2dda8f10d6796662153d05fe605dda2f7f780 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment4.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment4Solution.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment4Solution.docx new file mode 100644 index 0000000000000000000000000000000000000000..e3b337d56c7da772e972c03029f16219bc5dcb54 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment4Solution.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment5.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment5.docx new file mode 100644 index 0000000000000000000000000000000000000000..4ce1abec915850b5cded414e1e462c16e80eac87 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment5.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment5Solution.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment5Solution.docx new file mode 100644 index 0000000000000000000000000000000000000000..496e068a041c1b3abcbf0f8c24568282c8f72606 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment5Solution.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment6.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment6.docx new file mode 100644 index 0000000000000000000000000000000000000000..6564483b505cfae3fd505de5a543881cb21afe3a Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment6.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment7_2022.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment7_2022.docx new file mode 100644 index 0000000000000000000000000000000000000000..492f048c54c74345ff7b7dc742738a87eab24aa0 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/MV3302/WrittenAssignment7_2022.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitDisDiagramModelNetworkIntegration.png b/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitDisDiagramModelNetworkIntegration.png new file mode 100644 index 0000000000000000000000000000000000000000..ad9db14a8fbe98b2f60e65d5f496a71a4618c62e Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitDisDiagramModelNetworkIntegration.png differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitDisDiagrams.vsdx b/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitDisDiagrams.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..aabd65d6cc0ee0c5987365b76de7030abaf00042 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitDisDiagrams.vsdx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitDisDiagramsTwoCranesBerthResupply.png b/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitDisDiagramsTwoCranesBerthResupply.png new file mode 100644 index 0000000000000000000000000000000000000000..1798f09ccaa6e748894a1f86e990bc30066592c2 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitDisDiagramsTwoCranesBerthResupply.png differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitQuickReference.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitQuickReference.docx new file mode 100644 index 0000000000000000000000000000000000000000..c833724ac72f4da83ea01d999a0b0fffe4f8d7d9 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitQuickReference.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitSimpleDiscreteEventSimulationModelForDIS.docx b/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitSimpleDiscreteEventSimulationModelForDIS.docx new file mode 100644 index 0000000000000000000000000000000000000000..9b53790d0458594f1553db9b99c9cc03bf9b9096 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/documentation/SimkitSimpleDiscreteEventSimulationModelForDIS.docx differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/package-info.java b/assignments/src/src/SimkitOpenDis7Examples/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..0e224c9a88014fc274223f6a3e94ae20e21f3aac --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/package-info.java @@ -0,0 +1,10 @@ +/** + * Simkit event graphs with opendis7 Java outputs supporting the NPS MOVES MV3500 Networked Graphics course. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples/src/SimkitOpenDis7Examples" target="blank">NetworkedGraphicsMV3500 examples: SimkitOpenDis7Examples</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 SimkitOpenDis7Examples; diff --git a/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServer.java b/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServer.java new file mode 100644 index 0000000000000000000000000000000000000000..bcd76af54119b1e7c3c27b9a7b73751762cd2497 --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServer.java @@ -0,0 +1,87 @@ +package SimkitOpenDis7Examples.run; + +import SimkitOpenDis7Examples.ArrivalProcess; +import SimkitOpenDis7Examples.SimpleServer; +import simkit.Schedule; +import simkit.random.RandomVariate; +import simkit.random.RandomVariateFactory; +import simkit.stat.SimpleStatsTimeVarying; +import simkit.util.SimplePropertyDumper; + +/** + * Run a simple server problem and compute statistical measurement of results. + * <h2>Output:</h2><pre> + * ArrivalProcess.1 + * interarrivalTimeGenerator = Uniform (0.900, 2.200) + * SimpleServer.2 + * serviceTimeGenerator = Gamma (1.700, 1.800) + * totalNumberServers = 2 + * Simulation ended at time 100,000.000 + * + * There have been 64,475 arrivals + * There have been 64,472 customers served + * Average number in queue 15.9655 + * Average utilization 0.9819</pre> + * + * @author abuss@nps.edu + */ +public class RunSimpleServer +{ + /** Default constructor */ + public RunSimpleServer() + { + // default constructor + } + /** + * Run a simple program and compute statistical measurement of results. + * @param args the command line arguments + */ + public static void main(String args[]) + { + String rvName = "Uniform"; // TODO is enumeration available? + double lower = 0.9; + double upper = 2.2; + RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance(rvName, lower, upper); + ArrivalProcess arrival = new ArrivalProcess(interarrivalTimeGenerator); + + rvName = "Gamma"; // TODO is enumeration available? + double alpha = 1.7; + double beta = 1.8; + + RandomVariate serviceTimeGenerator = RandomVariateFactory.getInstance(rvName, alpha, beta); + int numServ = 1; + SimpleServer server = new SimpleServer(numServ, serviceTimeGenerator); + arrival.addSimEventListener(server); + + SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(); +// server.addPropertyChangeListener(simplePropertyDumper); +// arrival.addPropertyChangeListener(simplePropertyDumper); + + SimpleStatsTimeVarying numberInQueueStat = new SimpleStatsTimeVarying("numberInQueue"); + SimpleStatsTimeVarying numberAvailableServersStat = new SimpleStatsTimeVarying("numberAvailableServers"); + + server.addPropertyChangeListener(numberInQueueStat); + server.addPropertyChangeListener(numberAvailableServersStat); + + System.out.println(arrival); + System.out.println(server); + +// Schedule.setVerbose(true); +// Schedule.setSingleStep(false); +// double stopTime = 6.0; + double stopTime = 100000.0; + + Schedule.stopAtTime(stopTime); + + Schedule.reset(); + numberInQueueStat.reset(); + numberAvailableServersStat.reset(); + Schedule.startSimulation(); + + System.out.printf("Simulation ended at time %,.3f%n", Schedule.getSimTime()); + System.out.printf("%nThere have been %,d arrivals%n", arrival.getNumberArrivals()); + System.out.printf("There have been %,d customers served%n", server.getNumberServed()); + System.out.printf("Average number in queue\t%.4f%n", numberInQueueStat.getMean()); + System.out.printf("Average utilization\t%.4f%n", 1.0 - numberAvailableServersStat.getMean() / server.getTotalNumberServers()); + } +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServerLog.txt b/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServerLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..b7679ce2153bddca01ebe902722157d13aa2e45d --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServerLog.txt @@ -0,0 +1,22 @@ +ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=SimkitOpenDis7Examples/run/RunSimpleServer.java -Drun.class=SimkitOpenDis7Examples.run.RunSimpleServer 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 +warning: [options] system modules path not set in conjunction with -source 17 +1 warning +compile-single: +run-single: +ArrivalProcess.1 + interarrivalTimeGenerator = Uniform (0.900, 2.200) +SimpleServer.2 + totalNumberServers = 1 + serviceTimeGenerator = Gamma (1.700, 1.800) +Simulation ended at time 100,000.000 + +There have been 64,526 arrivals +There have been 32,790 customers served +Average number in queue 15912.7375 +Average utilization 1.0000 +BUILD SUCCESSFUL (total time: 5 seconds) diff --git a/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServerOpenDis7.java b/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServerOpenDis7.java new file mode 100644 index 0000000000000000000000000000000000000000..bbcdfe6378793736d7e8e6a67b1b133ed8d0eb99 --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServerOpenDis7.java @@ -0,0 +1,102 @@ +package SimkitOpenDis7Examples.run; + +import SimkitOpenDis7Examples.ArrivalProcessOpenDis7; +import SimkitOpenDis7Examples.SimpleServerOpenDis7; +import simkit.Schedule; +import simkit.random.RandomVariate; +import simkit.random.RandomVariateFactory; +import simkit.stat.SimpleStatsTimeVarying; +import simkit.util.SimplePropertyDumper; + +/** + * Runs SimpleServer event graph with openDis7 output PDUs added. + * TODO work in progress: adding functionality, refining naming and code patterns. + * + * <h2>Output:</h2><pre> + * ArrivalProcess.1 + * interarrivalTimeGenerator = Uniform (0.900, 2.200) + * SimpleServer.2 + * serviceTimeGenerator = Gamma (1.700, 1.800) + * totalNumberServers = 2 + * Simulation ended at time 100,000.000 + * + * There have been 64,475 arrivals + * There have been 64,472 customers served + * Average number in queue 15.9655 + * Average utilization 0.9819</pre> + * + * @see SimkitOpenDis7Examples.ArrivalProcessOpenDis7 + * @see SimkitOpenDis7Examples.SimpleServer + * @see <a href="RunSimpleServerOpenDis7Log.txt" target="_blank">RunSimpleServerOpenDis7Log.txt</a> + * @see <a href="../ArrivalProcessOpenDis7EventGraph.png" target="_blank">ArrivalProcessOpenDis7EventGraph.png</a> + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/raw/master/examples/src/SimkitOpenDis7Examples/documentation/ArrivalProcessDisPdu.png" target="_blank">ArrivalProcessDisPdu.png</a> + * @author abuss@nps.edu@nps.edu + * @author brutzman@nps.edu + */ +public class RunSimpleServerOpenDis7 +{ + /** Default constructor */ + public RunSimpleServerOpenDis7() + { + // default constructor + } + /** + * Run a simple program and compute statistical measurement of results. + * @see RunSimpleServer + * @param args the command line arguments + */ + public static void main(String args[]) + { + String rvName = "Uniform"; // TODO is enumeration available? + double lower = 0.9; + double upper = 2.2; + RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance(rvName, lower, upper); + ArrivalProcessOpenDis7 arrival = new ArrivalProcessOpenDis7(interarrivalTimeGenerator); + + rvName = "Gamma"; // TODO is enumeration available? + double alpha = 1.7; + double beta = 1.8; + + RandomVariate serviceTimeGenerator = RandomVariateFactory.getInstance(rvName, alpha, beta); + int numServ = 1; + SimpleServerOpenDis7 server = new SimpleServerOpenDis7(numServ, serviceTimeGenerator); + arrival.addSimEventListener(server); + + SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(); +// server.addPropertyChangeListener(simplePropertyDumper); +// arrival.addPropertyChangeListener(simplePropertyDumper); + + SimpleStatsTimeVarying numberInQueueStat = new SimpleStatsTimeVarying("numberInQueue"); + SimpleStatsTimeVarying numberAvailableServersStat = new SimpleStatsTimeVarying("numberAvailableServers"); + + server.addPropertyChangeListener(numberInQueueStat); + server.addPropertyChangeListener(numberAvailableServersStat); + + System.out.println(arrival); + System.out.println(server); + +// Schedule.setVerbose(true); +// Schedule.setSingleStep(false); +// double stopTime = 6.0; + double stopTime = 100000.0; + + Schedule.stopAtTime(stopTime); + + Schedule.reset(); + numberInQueueStat.reset(); + numberAvailableServersStat.reset(); + Schedule.startSimulation(); + + System.out.printf("Simulation ended at time %,.3f%n", Schedule.getSimTime()); + System.out.printf("%nThere have been %,d arrivals%n", arrival.getNumberArrivals()); + System.out.printf("There have been %,d customers served%n", server.getNumberServed()); + System.out.printf("Average number in queue\t%.4f%n", numberInQueueStat.getMean()); + System.out.printf("Average utilization\t%.4f%n", 1.0 - numberAvailableServersStat.getMean() / server.getTotalNumberServers()); + + System.out.println("Execution complete."); + + // TODO send simulation management PDUs via DIS channel, announce completion + arrival.getDisChannel().tearDownNetworkInterface(); + System.exit(0); // normal completion + } +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServerOpenDis7Log.txt b/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServerOpenDis7Log.txt new file mode 100644 index 0000000000000000000000000000000000000000..fbc63d4c924cd51a326c20e1c97b88cedd2ef3ff --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/run/RunSimpleServerOpenDis7Log.txt @@ -0,0 +1,56 @@ +ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=SimkitOpenDis7Examples/run/RunSimpleServerOpenDis7.java -Drun.class=SimkitOpenDis7Examples.run.RunSimpleServerOpenDis7 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 +warning: [options] system modules path not set in conjunction with -source 17 +1 warning +compile-single: +run-single: +[DisChannel] thisHostName=IT160907-INFLPP +[DisThreadedNetworkInterface] using network interface Intel(R) Wi-Fi 6E AX210 160MHz +[DisThreadedNetworkInterface] datagramSocket.joinGroup address=239.1.2.3 port=3000 isConnected()=false createDatagramSocket() complete. +[DisThreadedNetworkInterface] createThreads() receiveThread.isAlive()=true +[DisThreadedNetworkInterface] createThreads() sendingThread.isAlive()=true +[DisChannel] Network confirmation: address=239.1.2.3 port=3000 +[DisChannel] Beginning pdu save to directory ./pduLog +[PduRecorder] Recorder log file open: C:\x3d-nps-gitlab\NetworkedGraphicsMV3500\examples\pduLog\PduCaptureLog22.dislog +[DisThreadedNetworkInterface] using network interface Intel(R) Wi-Fi 6E AX210 160MHz +[DisThreadedNetworkInterface] datagramSocket.joinGroup address=239.1.2.3 port=3000 isConnected()=false createDatagramSocket() complete. +[DisThreadedNetworkInterface] createThreads() receiveThread.isAlive()=true +[DisThreadedNetworkInterface] createThreads() sendingThread.isAlive()=true +[PduRecorder PduRecorder] listening to IP address 239.1.2.3 on port 3000 +[DisChannel] disChannel.getNetworkAddress()=239.1.2.3, getNetworkPort()=3000 +[DisThreadedNetworkInterface DisChannel] [sending 1] DisPduType 22 COMMENT, size 80 bytes) +[DisThreadedNetworkInterface DisChannel] [receipt 1] DisPduType 22 COMMENT, size 80 bytes) +[DisThreadedNetworkInterface PduRecorder] [receipt 1] DisPduType 22 COMMENT, size 80 bytes) +[DisChannel] *** [CommentPdu OTHER] [ArrivalProcessOpenDis7 initialized] +[DisChannel] thisHostName=IT160907-INFLPP +ArrivalProcessOpenDis7.1 + interarrivalTimeGenerator = Uniform (0.900, 2.200) +SimpleServerOpenDis7.2 + totalNumberServers = 1 + serviceTimeGenerator = Gamma (1.700, 1.800) +Simulation ended at time 100,000.000 + +There have been 64,526 arrivals +There have been 32,790 customers served +Average number in queue 15912.7375 +Average utilization 1.0000 +Execution complete. +*** setKillSentinelAndInterrupts() killed=true sendingThread.isInterrupted()=true receiveThread.isInterrupted()=true +[DisThreadedNetworkInterface PduRecorder] close(): pdus2send.size()=0 baos.size()=0 dos.size()=0 +[DisThreadedNetworkInterface PduRecorder] 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\PduCaptureLog22.dislog +*** setKillSentinelAndInterrupts() killed=true sendingThread.isInterrupted()=true receiveThread.isInterrupted()=true +[DisThreadedNetworkInterface DisChannel] close(): pdus2send.size()=0 baos.size()=0 dos.size()=80 +[DisThreadedNetworkInterface DisChannel] 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 +BUILD SUCCESSFUL (total time: 10 seconds) diff --git a/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerths.java b/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerths.java new file mode 100644 index 0000000000000000000000000000000000000000..4334f2207b65b95e963f2c291dd446c7bee81b69 --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerths.java @@ -0,0 +1,92 @@ +package SimkitOpenDis7Examples.run; + +import SimkitOpenDis7Examples.ShipArrivalProcess; +import SimkitOpenDis7Examples.TwoCraneBerths; +import simkit.Schedule; +import simkit.random.RandomVariate; +import simkit.random.RandomVariateFactory; +import simkit.stat.CollectionSizeTimeVaryingStats; +import simkit.stat.SimpleStatsTally; + +/** + * Run simple two-berth model for 10 years (3650 days). + * <h2>Output:</h2><pre> +ShipArrivalProcess.1 + unloadTimeGenerator = Uniform (0.500, 1.500) + interarrivalTimeGenerator = Exponential (0.700) +TwoCraneBerths.2 + +Simulation ended at time 3,650.0 + +Number of ships arriving: 5,135 +Number of ships unloaded: 5,129 +Maximum # in queue: 11 +Average # in queue: 0.6834 +Average # busy berths: 1.1737 +Average time in system: 1.3207 +Average delay in queue: 0.4857 +</pre> +* + * @author abuss@nps.edu + */ +public class RunTwoCraneBerths +{ + /** Default constructor */ + public RunTwoCraneBerths() + { + // default constructor + } + /** + * Run a simple program and compute statistical measurement of results. + * @param args the command line arguments + */ + public static void main(String[] args) { + RandomVariate interarrivalTimeGenerator = + RandomVariateFactory.getInstance("Exponential", 0.7); + RandomVariate unloadingTimeGenerator = + RandomVariateFactory.getInstance("Uniform", 0.5, 1.5); + ShipArrivalProcess shipArrivalProcess = + new ShipArrivalProcess(interarrivalTimeGenerator, + unloadingTimeGenerator); + + TwoCraneBerths twoCraneBerths = new TwoCraneBerths(); + shipArrivalProcess.addSimEventListener(twoCraneBerths); + + SimpleStatsTally delayInQueueStat = new SimpleStatsTally("delayInQueue"); + SimpleStatsTally timeInSystemStat = new SimpleStatsTally("timeInSystem"); + CollectionSizeTimeVaryingStats numberInQueueStat = + new CollectionSizeTimeVaryingStats("queue"); + CollectionSizeTimeVaryingStats numberInBerthStat = + new CollectionSizeTimeVaryingStats("berth"); +// SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(); +// twoCraneBerths.addPropertyChangeListener(simplePropertyDumper); + + twoCraneBerths.addPropertyChangeListener(delayInQueueStat); + twoCraneBerths.addPropertyChangeListener(timeInSystemStat); + twoCraneBerths.addPropertyChangeListener(numberInQueueStat); + twoCraneBerths.addPropertyChangeListener(numberInBerthStat); + + System.out.println(shipArrivalProcess); + System.out.println(twoCraneBerths); + + double stopTime = 10 * 365; + Schedule.stopAtTime(stopTime); + Schedule.setVerbose(false); + + Schedule.reset(); + Schedule.startSimulation(); + + System.out.printf("%nSimulation ended at time %,.1f%n%n", + Schedule.getSimTime()); + + System.out.printf("Number of ships arriving:\t%,d%n", shipArrivalProcess.getNumberArrivals()); + System.out.printf("Number of ships unloaded:\t%,d%n", timeInSystemStat.getCount()); + System.out.printf("Maximum # in queue:\t\t%.0f%n", numberInQueueStat.getMaxObs()); + System.out.printf("Average # in queue:\t\t%.4f%n", numberInQueueStat.getMean()); + System.out.printf("Average # busy berths:\t\t%.4f%n", numberInBerthStat.getMean()); + System.out.printf("Average time in system:\t\t%.4f%n", + timeInSystemStat.getMean()); + System.out.printf("Average delay in queue:\t\t%.4f%n", + delayInQueueStat.getMean()); } + +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsLog.txt b/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..437f9dc4c5a5f926fc48a85f663a0e8f0313d76e --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsLog.txt @@ -0,0 +1,25 @@ +ant -f C:\\x3d-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=SimkitOpenDis7Examples/run/RunTwoCraneBerths.java -Drun.class=SimkitOpenDis7Examples.run.RunTwoCraneBerths 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 +warning: [options] system modules path not set in conjunction with -source 17 +1 warning +compile-single: +run-single: +ShipArrivalProcess.1 + unloadTimeGenerator = Uniform (0.500, 1.500) + interarrivalTimeGenerator = Exponential (0.700) +TwoCraneBerths.2 + +Simulation ended at time 3,650.0 + +Number of ships arriving: 5,135 +Number of ships unloaded: 5,129 +Maximum # in queue: 11 +Average # in queue: 0.6834 +Average # busy berths: 1.1737 +Average time in system: 1.3207 +Average delay in queue: 0.4857 +BUILD SUCCESSFUL (total time: 6 seconds) diff --git a/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsOpenDis7.java b/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsOpenDis7.java new file mode 100644 index 0000000000000000000000000000000000000000..c6d4ea43cea3e9b5daa031eb499f7e85ecbd05e1 --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsOpenDis7.java @@ -0,0 +1,99 @@ +package SimkitOpenDis7Examples.run; + +import SimkitOpenDis7Examples.ShipArrivalProcess; +import SimkitOpenDis7Examples.TwoCraneBerthsOpenDis7; +import simkit.Schedule; +import simkit.random.RandomVariate; +import simkit.random.RandomVariateFactory; +import simkit.stat.CollectionSizeTimeVaryingStats; +import simkit.stat.SimpleStatsTally; + +/** + * Run simple two-berth model for 10 years (3650 days). + * <h2>Output:</h2><pre> +ShipArrivalProcess.1 + unloadTimeGenerator = Uniform (0.500, 1.500) + interarrivalTimeGenerator = Exponential (0.700) +TwoCraneBerthsOpenDis7.2 + +Simulation ended at time 3,650.0 + +Number of ships arriving: 5,135 +Number of ships unloaded: 5,129 +Maximum # in queue: 11 +Average # in queue: 0.6834 +Average # busy berths: 1.1737 +Average time in system: 1.3207 +Average delay in queue: 0.4857 +</pre> +* + * @author abuss@nps.edu + */ +public class RunTwoCraneBerthsOpenDis7 +{ + /** Default constructor */ + public RunTwoCraneBerthsOpenDis7() + { + // default constructor + } + /** + * Run a simple program and compute statistical measurement of results. + * @param args the command line arguments + */ + public static void main(String[] args) + { + System.out.println ("RunTwoCraneBerthsOpenDis7 started"); // here we go + RandomVariate interarrivalTimeGenerator = + RandomVariateFactory.getInstance("Exponential", 0.7); + RandomVariate unloadingTimeGenerator = + RandomVariateFactory.getInstance("Uniform", 0.5, 1.5); + ShipArrivalProcess shipArrivalProcess = + new ShipArrivalProcess(interarrivalTimeGenerator, + unloadingTimeGenerator); + + // can start debugging here + TwoCraneBerthsOpenDis7 twoCraneBerthsOpenDis7 = new TwoCraneBerthsOpenDis7(); + shipArrivalProcess.addSimEventListener(twoCraneBerthsOpenDis7); + + SimpleStatsTally delayInQueueStat = new SimpleStatsTally("delayInQueue"); + SimpleStatsTally timeInSystemStat = new SimpleStatsTally("timeInSystem"); + CollectionSizeTimeVaryingStats numberInQueueStat = + new CollectionSizeTimeVaryingStats("queue"); + CollectionSizeTimeVaryingStats numberInBerthStat = + new CollectionSizeTimeVaryingStats("berth"); +// SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(); +// twoCraneBerths.addPropertyChangeListener(simplePropertyDumper); + + twoCraneBerthsOpenDis7.addPropertyChangeListener(delayInQueueStat); + twoCraneBerthsOpenDis7.addPropertyChangeListener(timeInSystemStat); + twoCraneBerthsOpenDis7.addPropertyChangeListener(numberInQueueStat); + twoCraneBerthsOpenDis7.addPropertyChangeListener(numberInBerthStat); + + System.out.println(shipArrivalProcess); + System.out.println(twoCraneBerthsOpenDis7); + + double stopTime = 10 * 365; + Schedule.stopAtTime(stopTime); + Schedule.setVerbose(false); + + Schedule.reset(); + Schedule.startSimulation(); + + System.out.printf("%nSimulation ended at time %,.1f%n%n", + Schedule.getSimTime()); + + System.out.printf("Number of ships arriving:\t%,d%n", shipArrivalProcess.getNumberArrivals()); + System.out.printf("Number of ships unloaded:\t%,d%n", timeInSystemStat.getCount()); + System.out.printf("Maximum # in queue:\t\t%.0f%n", numberInQueueStat.getMaxObs()); + System.out.printf("Average # in queue:\t\t%.4f%n", numberInQueueStat.getMean()); + System.out.printf("Average # busy berths:\t\t%.4f%n", numberInBerthStat.getMean()); + System.out.printf("Average time in system:\t\t%.4f%n", + timeInSystemStat.getMean()); + System.out.printf("Average delay in queue:\t\t%.4f%n", + delayInQueueStat.getMean()); + + twoCraneBerthsOpenDis7.shutdownDisChannel(); + System.out.println ("RunTwoCraneBerthsOpenDis7 finished"); // out here + System.exit(0); + } +} diff --git a/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsOpenDis7Log.txt b/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsOpenDis7Log.txt new file mode 100644 index 0000000000000000000000000000000000000000..84d6808b7f615e7a8ce352220840024de2503fd3 Binary files /dev/null and b/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsOpenDis7Log.txt differ diff --git a/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsOpenDis7PduCaptureLog.dislog b/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsOpenDis7PduCaptureLog.dislog new file mode 100644 index 0000000000000000000000000000000000000000..15ff64ab7c74f35ea59b1635c3fde73074351d2c --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/run/RunTwoCraneBerthsOpenDis7PduCaptureLog.dislog @@ -0,0 +1,172 @@ +# Start, ENCODING_PLAINTEXT, [PduRecorder] 20220619_172513, DIS capture file, .\pduLog\PduCaptureLog.dislog +2022-06-19,17:25:13.862,7,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:13.979,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,82,101,97,100,121,32,116,111,32,112,114,111,99,101,115,115,32,83,104,105,112,32,49,32,119,105,116,104,32,99,114,97,110,101,32,97,116,32,104,101,97,100,32,111,102,32,112,105,101,114,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:14.080,7,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:14.204,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-80,67,114,97,110,101,32,97,116,32,112,111,115,105,116,105,111,110,32,57,48,46,48,109,32,102,111,114,32,111,102,102,108,111,97,100,32,97,102,116,101,114,32,57,48,46,48,32,115,101,99,111,110,100,115,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:14.315,7,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:14.427,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:14.540,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,49,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:14.645,7,1,22,5,0,0,0,60,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,49,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:14.755,7,0,1,1,0,0,0,69,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:14.869,7,1,22,5,0,0,0,69,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:14.982,7,1,22,5,0,0,0,99,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,49,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:15.086,7,1,22,5,0,0,0,99,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,49,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:15.194,7,0,1,1,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:15.300,7,1,22,5,0,0,0,99,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:15.402,7,1,22,5,0,0,0,99,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,50,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:15.506,7,1,22,5,0,0,0,-97,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,50,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:15.616,7,0,1,1,0,0,0,-88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:15.722,7,1,22,5,0,0,0,-88,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:15.825,7,1,22,5,0,0,0,-58,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,50,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:15.928,7,1,22,5,0,0,0,-58,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,50,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:16.043,7,0,1,1,0,0,0,-58,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:16.145,7,1,22,5,0,0,0,-58,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:16.253,7,1,22,5,0,0,0,-58,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,51,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:16.359,7,1,22,5,0,0,1,2,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,51,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:16.462,7,0,1,1,0,0,1,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:16.568,7,1,22,5,0,0,1,11,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:16.669,7,1,22,5,0,0,1,41,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,51,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:16.784,7,1,22,5,0,0,1,41,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,51,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:16.900,7,0,1,1,0,0,1,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:17.011,7,1,22,5,0,0,1,41,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:17.113,7,1,22,5,0,0,1,41,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,52,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:17.215,7,1,22,5,0,0,1,101,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,52,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:17.316,7,0,1,1,0,0,1,110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:17.429,7,1,22,5,0,0,1,110,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:17.529,7,1,22,5,0,0,1,-116,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,52,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:17.639,7,1,22,5,0,0,1,-116,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,52,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:17.745,7,0,1,1,0,0,1,-116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:17.846,7,1,22,5,0,0,1,-116,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:17.953,7,1,22,5,0,0,1,-116,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,53,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:18.068,7,1,22,5,0,0,1,-56,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,53,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:18.175,7,0,1,1,0,0,1,-47,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:18.284,7,1,22,5,0,0,1,-47,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:18.393,7,1,22,5,0,0,1,-17,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,53,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:18.507,7,1,22,5,0,0,1,-17,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,53,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:18.629,7,0,1,1,0,0,1,-17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:18.743,7,1,22,5,0,0,1,-17,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:18.846,7,1,22,5,0,0,1,-17,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,54,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:18.952,7,1,22,5,0,0,2,43,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,54,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:19.054,7,0,1,1,0,0,2,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:19.169,7,1,22,5,0,0,2,52,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:19.279,7,1,22,5,0,0,2,82,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,54,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:19.381,7,1,22,5,0,0,2,82,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,54,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:19.484,7,0,1,1,0,0,2,82,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:19.592,7,1,22,5,0,0,2,82,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:19.700,7,1,22,5,0,0,2,82,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,55,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:19.805,7,1,22,5,0,0,2,-114,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,55,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:19.914,7,0,1,1,0,0,2,-105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:20.021,7,1,22,5,0,0,2,-105,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:20.123,7,1,22,5,0,0,2,-75,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,55,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:20.237,7,1,22,5,0,0,2,-75,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,55,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:20.349,7,0,1,1,0,0,2,-75,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:20.454,7,1,22,5,0,0,2,-75,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:20.559,7,1,22,5,0,0,2,-75,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,56,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:20.661,7,1,22,5,0,0,2,-15,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,56,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:20.767,7,0,1,1,0,0,2,-6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:20.874,7,1,22,5,0,0,2,-6,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:20.976,7,1,22,5,0,0,3,24,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,56,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:21.081,7,1,22,5,0,0,3,24,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,56,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:21.187,7,0,1,1,0,0,3,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:21.291,7,1,22,5,0,0,3,24,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:21.393,7,1,22,5,0,0,3,24,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,57,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:21.505,7,1,22,5,0,0,3,84,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,57,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:21.609,7,0,1,1,0,0,3,93,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:21.714,7,1,22,5,0,0,3,93,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:21.818,7,1,22,5,0,0,3,123,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,57,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:21.943,7,1,22,5,0,0,3,123,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,57,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:22.059,7,0,1,1,0,0,3,123,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:22.166,7,1,22,5,0,0,3,123,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:22.275,7,1,22,5,0,0,3,123,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,8,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,49,48,32,116,111,32,99,114,97,110,101,32,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:22.390,7,1,22,5,0,0,3,-73,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-104,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,49,48,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:22.496,7,0,1,1,0,0,3,-64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:22.599,7,1,22,5,0,0,3,-64,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:22.704,7,1,22,5,0,0,3,-34,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-120,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,49,48,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:22.805,7,1,22,5,0,0,3,-34,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-48,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,49,48,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:22.910,7,0,1,1,0,0,4,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:23.026,7,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:23.137,7,1,22,5,0,0,0,1,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,82,101,97,100,121,32,116,111,32,112,114,111,99,101,115,115,32,83,104,105,112,32,50,32,119,105,116,104,32,99,114,97,110,101,32,97,116,32,104,101,97,100,32,111,102,32,112,105,101,114,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:23.245,7,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:23.353,7,1,22,5,0,0,0,1,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-80,67,114,97,110,101,32,97,116,32,112,111,115,105,116,105,111,110,32,57,48,46,48,109,32,102,111,114,32,111,102,102,108,111,97,100,32,97,102,116,101,114,32,57,48,46,48,32,115,101,99,111,110,100,115,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:23.457,7,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:23.570,7,1,22,5,0,0,0,1,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:23.680,7,1,22,5,0,0,0,1,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,49,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:23.783,7,1,22,5,0,0,0,61,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,49,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:23.889,7,0,1,1,0,0,0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:23.992,7,1,22,5,0,0,0,70,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:24.099,7,1,22,5,0,0,0,100,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,49,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:24.201,7,1,22,5,0,0,0,100,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,49,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:24.317,7,0,1,1,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:24.418,7,1,22,5,0,0,0,100,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:24.524,7,1,22,5,0,0,0,100,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,50,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:24.639,7,1,22,5,0,0,0,-96,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,50,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:24.741,7,0,1,1,0,0,0,-87,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:24.856,7,1,22,5,0,0,0,-87,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:24.958,7,1,22,5,0,0,0,-57,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,50,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:25.073,7,1,22,5,0,0,0,-57,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,50,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:25.181,7,0,1,1,0,0,0,-57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:25.288,7,1,22,5,0,0,0,-57,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:25.394,7,1,22,5,0,0,0,-57,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,51,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:25.500,7,1,22,5,0,0,1,3,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,51,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:25.601,7,0,1,1,0,0,1,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:25.703,7,1,22,5,0,0,1,12,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:25.807,7,1,22,5,0,0,1,42,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,51,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:25.913,7,1,22,5,0,0,1,42,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,51,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:26.016,7,0,1,1,0,0,1,42,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:26.120,7,1,22,5,0,0,1,42,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:26.223,7,1,22,5,0,0,1,42,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,52,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:26.333,7,1,22,5,0,0,1,102,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,52,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:26.435,7,0,1,1,0,0,1,111,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:26.543,7,1,22,5,0,0,1,111,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:26.652,7,1,22,5,0,0,1,-115,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,52,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:26.765,7,1,22,5,0,0,1,-115,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,52,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:26.871,7,0,1,1,0,0,1,-115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:26.977,7,1,22,5,0,0,1,-115,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:27.097,7,1,22,5,0,0,1,-115,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,53,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:27.202,7,1,22,5,0,0,1,-55,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,53,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:27.303,7,0,1,1,0,0,1,-46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:27.408,7,1,22,5,0,0,1,-46,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:27.511,7,1,22,5,0,0,1,-16,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,53,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:27.617,7,1,22,5,0,0,1,-16,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,53,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:27.721,7,0,1,1,0,0,1,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:27.835,7,1,22,5,0,0,1,-16,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:27.936,7,1,22,5,0,0,1,-16,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,54,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:28.045,7,1,22,5,0,0,2,44,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,54,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:28.156,7,0,1,1,0,0,2,53,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:28.265,7,1,22,5,0,0,2,53,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:28.372,7,1,22,5,0,0,2,83,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,54,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:28.481,7,1,22,5,0,0,2,83,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,54,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:28.585,7,0,1,1,0,0,2,83,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:28.689,7,1,22,5,0,0,2,83,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:28.789,7,1,22,5,0,0,2,83,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,55,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:28.890,7,1,22,5,0,0,2,-113,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,55,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:28.996,7,0,1,1,0,0,2,-104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:29.102,7,1,22,5,0,0,2,-104,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:29.216,7,1,22,5,0,0,2,-74,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,55,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:29.332,7,1,22,5,0,0,2,-74,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,55,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:29.437,7,0,1,1,0,0,2,-74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:29.539,7,1,22,5,0,0,2,-74,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:29.643,7,1,22,5,0,0,2,-74,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,56,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:29.747,7,1,22,5,0,0,2,-14,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,56,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:29.852,7,0,1,1,0,0,2,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:29.958,7,1,22,5,0,0,2,-5,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:30.063,7,1,22,5,0,0,3,25,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,56,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:30.167,7,1,22,5,0,0,3,25,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,56,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:30.275,7,0,1,1,0,0,3,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:30.386,7,1,22,5,0,0,3,25,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:30.487,7,1,22,5,0,0,3,25,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,0,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,57,32,116,111,32,99,114,97,110,101,32 # DisPduType 22 COMMENT +2022-06-19,17:25:30.592,7,1,22,5,0,0,3,85,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-112,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,57,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:30.692,7,0,1,1,0,0,3,94,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:30.794,7,1,22,5,0,0,3,94,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:30.897,7,1,22,5,0,0,3,124,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-128,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,57,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:31.002,7,1,22,5,0,0,3,124,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-56,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,57,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:31.103,7,0,1,1,0,0,3,124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-55,15,-37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:31.205,7,1,22,5,0,0,3,124,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,115,104,105,112,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:31.307,7,1,22,5,0,0,3,124,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,8,72,111,111,107,105,110,103,32,117,112,32,67,111,110,116,97,105,110,101,114,32,49,48,32,116,111,32,99,114,97,110,101,32,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:31.415,7,1,22,5,0,0,3,-72,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-104,72,111,111,107,101,100,32,117,112,58,32,67,111,110,116,97,105,110,101,114,32,49,48,32,116,111,32,99,114,97,110,101,32,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:31.525,7,0,1,1,0,0,3,-63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,86,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +2022-06-19,17:25:31.632,7,1,22,5,0,0,3,-63,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,64,67,114,97,110,101,32,111,114,105,101,110,116,101,100,32,116,111,32,112,105,101,114,32,97,102,116,101,114,32,57,46,48,32,115,101,99,111,110,100,115 # DisPduType 22 COMMENT +2022-06-19,17:25:31.737,7,1,22,5,0,0,3,-33,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,97,-88,0,0,1,-120,68,101,116,97,99,104,101,100,58,32,67,111,110,116,97,105,110,101,114,32,49,48,32,111,110,32,112,105,101,114,32,97,102,116,101,114,32,51,48,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:31.853,7,1,22,5,0,0,3,-33,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-77,-70,0,0,1,-48,84,105,109,101,32,100,117,114,97,116,105,111,110,32,102,111,114,32,99,114,97,110,101,32,109,111,118,105,110,103,32,99,111,110,116,97,105,110,101,114,32,49,48,58,32,49,48,56,46,48,32,115,101,99,111,110,100,115,0,0,0,0,0,0 # DisPduType 22 COMMENT +2022-06-19,17:25:31.970,7,0,1,1,0,0,4,57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE +# Finish, ENCODING_PLAINTEXT, [PduRecorder] 20220619_172533, DIS capture file, .\pduLog\PduCaptureLog.dislog diff --git a/assignments/src/src/SimkitOpenDis7Examples/run/package-info.java b/assignments/src/src/SimkitOpenDis7Examples/run/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..01f79d5e8609d63795c6d252f31610cc7430d6b2 --- /dev/null +++ b/assignments/src/src/SimkitOpenDis7Examples/run/package-info.java @@ -0,0 +1,11 @@ +/** + * Invocation run classes for Simkit event graphs with opendis7 Java outputs supporting the NPS MOVES MV3500 Networked Graphics course. + * Note that the "run" subpackage is a common Simkit design pattern for separating simkit models from executable programs. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples" target="_blank">NetworkedGraphicsMV3500 examples</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 SimkitOpenDis7Examples.run; diff --git a/assignments/src/src/TcpExamples/README.md b/assignments/src/src/TcpExamples/README.md new file mode 100644 index 0000000000000000000000000000000000000000..53cad8dd2ca02c6c3a764295db0645367aaaeb09 --- /dev/null +++ b/assignments/src/src/TcpExamples/README.md @@ -0,0 +1,13 @@ +## TCP Examples Source Code + +Programs in this directory show how to create connection-oriented Transmission Control Protocol (TCP) sockets + +<!-- View this page at https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/TcpExamples/README.md --> + +| Telnet example | Telnet connection counting | +|----------------------|-------------------------------| +|  |  + +| Client-server socket communications | Client-Server Timing Sequence Diagram | +|-------------------------------------|---------------------------------------| +|  |  | diff --git a/assignments/src/src/TcpExamples/TcpExample1NetBeansConsoleTelnet.pdf b/assignments/src/src/TcpExamples/TcpExample1NetBeansConsoleTelnet.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6da2f6981a6c7ac8b3e745b40c4b22613dca99a4 Binary files /dev/null and b/assignments/src/src/TcpExamples/TcpExample1NetBeansConsoleTelnet.pdf differ diff --git a/assignments/src/src/TcpExamples/TcpExample1NetBeansConsoleTelnet.png b/assignments/src/src/TcpExamples/TcpExample1NetBeansConsoleTelnet.png new file mode 100644 index 0000000000000000000000000000000000000000..371d0175017153c5c87af5ace1b3719d2ce52f46 Binary files /dev/null and b/assignments/src/src/TcpExamples/TcpExample1NetBeansConsoleTelnet.png differ diff --git a/assignments/src/src/TcpExamples/TcpExample1NetBeansConsoleTelnet.vsdx b/assignments/src/src/TcpExamples/TcpExample1NetBeansConsoleTelnet.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..685e64ed571a6804ccdbde3394732ce0fab882b2 Binary files /dev/null and b/assignments/src/src/TcpExamples/TcpExample1NetBeansConsoleTelnet.vsdx differ diff --git a/assignments/src/src/TcpExamples/TcpExample1ScreenshotNetcat.png b/assignments/src/src/TcpExamples/TcpExample1ScreenshotNetcat.png new file mode 100644 index 0000000000000000000000000000000000000000..9d8dbc9aaf8cb5059a6dc937916e4df33e8f9f0d Binary files /dev/null and b/assignments/src/src/TcpExamples/TcpExample1ScreenshotNetcat.png differ diff --git a/assignments/src/src/TcpExamples/TcpExample1ScreenshotTelnet.png b/assignments/src/src/TcpExamples/TcpExample1ScreenshotTelnet.png new file mode 100644 index 0000000000000000000000000000000000000000..51c1479478333f17767d4bf6368c450527ccf6f8 Binary files /dev/null and b/assignments/src/src/TcpExamples/TcpExample1ScreenshotTelnet.png differ diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework1/Romero/ReneHW1.java b/assignments/src/src/TcpExamples/TcpExample1Telnet.java similarity index 82% rename from assignments/src/MV3500Cohort2024JulySeptember/homework1/Romero/ReneHW1.java rename to assignments/src/src/TcpExamples/TcpExample1Telnet.java index 7f828bf387cf86bb6be1d55245c6216547448fd7..c42da16d066cf129bae314ead0d6137c874702ec 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework1/Romero/ReneHW1.java +++ b/assignments/src/src/TcpExamples/TcpExample1Telnet.java @@ -1,117 +1,112 @@ -package MV3500Cohort2024JulySeptember.homework1.Romero; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.net.ServerSocket; -import java.net.Socket; - -/** - * <p> - * The simplest possible TCP network program, opening a socket and waiting for a reply. - * It listens for any socket connection response, either from telnet (telnet localhost 2317) - * or another program that you write (which we will do later). - * Once a socket connection is established, TcpExample1Telnet simply - * writes a string in response to that connection and finishes, exiting. - * - * <p> - * As an alternative to running the Windows (or other operating system) console, - * you can instead run the NetBeans terminal window. If you are on Windows, - * NetBeans is looking for Cygwin installation (for Unix-like compatibility) - * with details at <a href="https://savage.nps.edu/Savage/developers.html#Cygwin" target="blank">Savage Developers Guide: Cygwin</a>. - * Modifying this program is the basis for Assignment 1. - * </p> - * - * <p> - * Testing the running server program from telnet looks like this: - * </p> - * <pre> - * it154916:projects mcgredo$ <b>telnet localhost 2317</b> - * Trying ::1... - * Connected to localhost. - * Escape character is '^]'. - * This was written by the server - * Connection closed by foreign host. - * </pre> - * <p> - * Notice that "This was written by the server" matches - * what is written by the code below, over the output stream. - * </p> - * - * <p> - * After this first connection the program below drops to - * the bottom of the method, and does not repeat itself. - * In other words, the program exits. - * </p> - * - * @see <a href="../../../src/TcpExamples/TcpExample1TerminalLog.txt" target="_blank">TcpExample1TerminalLog.txt</a> - * @see <a href="../../../src/TcpExamples/TcpExample1NetBeansConsoleTelnet.png" target="_blank">TcpExample1NetBeansConsoleTelnet.png</a> - * @see <a href="../../../src/TcpExamples/TcpExample1NetBeansConsoleTelnet.pdf" target="_blank">TcpExample1NetBeansConsoleTelnet.pdf</a> - * @see <a href="../../../src/TcpExamples/TcpExample1ScreenshotNetcat.png" target="_blank">TcpExample1ScreenshotNetcat.png</a> - * @see <a href="../../../src/TcpExamples/TcpExample1ScreenshotTelnet.png" target="_blank">TcpExample1ScreenshotTelnet.png</a> - * @see <a href="https://savage.nps.edu/Savage/developers.html#Cygwin" target="blank">Savage Developers Guide: Cygwin</a> - * @see <a href="https://savage.nps.edu/Savage/developers.html#telnet" target="blank">Savage Developers Guide: telnet</a> - * - * @author mcgredo - * @author brutzman@nps.edu - */ - -public class ReneHW1 -{ - /** Default constructor */ - public ReneHW1() - { - // default constructor - } - /** - * Program invocation, execution starts here - * @param args command-line arguments - */ - public static void main(String[] args) - { - try - { - System.out.println(ReneHW1.class.getName() + " has started and is waiting for a connection."); - System.out.println(" help: https://savage.nps.edu/Savage/developers.html#telnet"); - System.out.println(" terminal: enter (telnet localhost 2317) or, for macOS (nc localhost 2317)..." ); - - // The ServerSocket waits for a connection from a client. - // It returns a Socket object when the connection occurs. - ServerSocket serverSocket = new ServerSocket(2317); - - // Use Java io classes to write text (as opposed to - // unknown bytes of some sort) to the client - - // The Socket object represents the connection between - // the server and client, including a full duplex connection - try (Socket clientConnection = serverSocket.accept()) // listen, wait here for a client to connect - { - // OK we got something, time to respond! - // Use Java io classes to write text (as opposed to - // unknown bytes of some sort) to the client - OutputStream os = clientConnection.getOutputStream(); - PrintStream ps = new PrintStream(os); - - ps.println("This client response was written by server " + ReneHW1.class.getName()); // to remote client - System.out.println("This server response was written by server " + ReneHW1.class.getName()); // to server console - - // "flush()" in important in that it forces a write - // across what is in fact a slow connection - ps.flush(); - } - - System.out.println(ReneHW1.class.getName() + " completed successfully."); - } - catch(IOException ioe) - { - System.err.println("Exception with " + ReneHW1.class.getName() + " networking:"); // describe what is happening - System.err.println(ioe); - // Provide more helpful information to user if exception occurs due to running twice at one time - - // brute force exception checking, can be brittle if exception message changes - // if (e.getMessage().equals("Address already in use: NET_Bind")) - if (ioe instanceof java.net.BindException) - System.err.println("*** Be sure to stop any other running instances of programs using this port!"); - } - } -} \ No newline at end of file +package TcpExamples; + +import java.io.*; +import java.net.*; + +/** + * <p> + * The simplest possible TCP network program, opening a socket and waiting for a reply. + * It listens for any socket connection response, either from telnet (telnet localhost 2317) + * or another program that you write (which we will do later). + * Once a socket connection is established, TcpExample1Telnet simply + * writes a string in response to that connection and finishes, exiting. + * + * <p> + * As an alternative to running the Windows (or other operating system) console, + * you can instead run the NetBeans terminal window. If you are on Windows, + * NetBeans is looking for Cgwin installation (for Unix-like compatibility) + * with details at <a href="https://savage.nps.edu/Savage/developers.html#Cygwin" target="blank">Savage Developers Guide: Cygwin</a>. + * Modifying this program is the basis for Assignment 1. + * </p> + * + * <p> + * Testing the running server program from telnet looks like this: + * </p> + * <pre> + * it154916:projects mcgredo$ <b>telnet localhost 2317</b> + * Trying ::1... + * Connected to localhost. + * Escape character is '^]'. + * This was written by the server + * Connection closed by foreign host. + * </pre> + * <p> + * Notice that "This was written by the server" matches + * what is written by the code below, over the output stream. + * </p> + * + * <p> + * After this first connection the program below drops to + * the bottom of the method, and does not repeat itself. + * In other words, the program exits. + * </p> + * + * @see <a href="../../../src/TcpExamples/TcpExample1TerminalLog.txt" target="_blank">TcpExample1TerminalLog.txt</a> + * @see <a href="../../../src/TcpExamples/TcpExample1NetBeansConsoleTelnet.png" target="_blank">TcpExample1NetBeansConsoleTelnet.png</a> + * @see <a href="../../../src/TcpExamples/TcpExample1NetBeansConsoleTelnet.pdf" target="_blank">TcpExample1NetBeansConsoleTelnet.pdf</a> + * @see <a href="../../../src/TcpExamples/TcpExample1ScreenshotNetcat.png" target="_blank">TcpExample1ScreenshotNetcat.png</a> + * @see <a href="../../../src/TcpExamples/TcpExample1ScreenshotTelnet.png" target="_blank">TcpExample1ScreenshotTelnet.png</a> + * @see <a href="https://savage.nps.edu/Savage/developers.html#Cygwin" target="blank">Savage Developers Guide: Cygwin</a> + * @see <a href="https://savage.nps.edu/Savage/developers.html#telnet" target="blank">Savage Developers Guide: telnet</a> + * + * @author mcgredo + * @author brutzman@nps.edu + */ +public class TcpExample1Telnet +{ + /** Default constructor */ + public TcpExample1Telnet() + { + // default constructor + } + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String[] args) + { + try + { + System.out.println(TcpExample1Telnet.class.getName() + " has started and is waiting for a connection."); + System.out.println(" help: https://savage.nps.edu/Savage/developers.html#telnet"); + System.out.println(" terminal: enter (telnet localhost 2317) or, for macOS (nc localhost 2317)..." ); + + // The ServerSocket waits for a connection from a client. + // It returns a Socket object when the connection occurs. + ServerSocket serverSocket = new ServerSocket(2317); + + // Use Java io classes to write text (as opposed to + // unknown bytes of some sort) to the client + + // The Socket object represents the connection between + // the server and client, including a full duplex connection + try (Socket clientConnection = serverSocket.accept()) // listen, wait here for a client to connect + { + // OK we got something, time to respond! + // Use Java io classes to write text (as opposed to + // unknown bytes of some sort) to the client + OutputStream os = clientConnection.getOutputStream(); + PrintStream ps = new PrintStream(os); + + ps.println("This client response was written by server " + TcpExample1Telnet.class.getName()); // to remote client + System.out.println("This server response was written by server " + TcpExample1Telnet.class.getName()); // to server console + + // "flush()" in important in that it forces a write + // across what is in fact a slow connection + ps.flush(); + } + System.out.println(TcpExample1Telnet.class.getName() + " completed successfully."); + } + catch(IOException ioe) + { + System.err.println("Exception with " + TcpExample1Telnet.class.getName() + " networking:"); // describe what is happening + System.err.println(ioe); + // Provide more helpful information to user if exception occurs due to running twice at one time + + // brute force exception checking, can be brittle if exception message changes + // if (e.getMessage().equals("Address already in use: NET_Bind")) + if (ioe instanceof java.net.BindException) + System.err.println("*** Be sure to stop any other running instances of programs using this port!"); + } + } +} diff --git a/assignments/src/src/TcpExamples/TcpExample1TerminalLog.txt b/assignments/src/src/TcpExamples/TcpExample1TerminalLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..2bc38877fff342314788b81f53d97b73cda259e9 --- /dev/null +++ b/assignments/src/src/TcpExamples/TcpExample1TerminalLog.txt @@ -0,0 +1,33 @@ +Invocation instructions: +1. run/debug TcpExample1Telnet.java +2. console: nc localhost 2317 + alternate: telnet localhost 2217 + +Program responses: + +=================================================== +run: +TcpExample1Telnet has started and is waiting for a connection. + enter (telnet localhost 2317) or (nc localhost 2317)... +This server response was written by server TcpExample1. +TcpExample1 completed successfully. +BUILD SUCCESSFUL (total time: 16 seconds) + +=================================================== +netcat window: + +brutzman@DESKTOP-2S09UKA /cygdrive/c/Program Files/NetBeans_11.0/bin +$ nc localhost 2317 +This client response was written by server TcpExample1. + +=================================================== +Telnet window: + +don@it154928 /cygdrive/c/Program Files/NetBeans 8.2 +$ telnet localhost 2317 +Trying ::1... +Connected to localhost. +Escape character is '^]'. +This client response was written by server TcpExample1. +Connection closed by foreign host. +=================================================== diff --git a/assignments/src/src/TcpExamples/TcpExample2ConnectionCounting.java b/assignments/src/src/TcpExamples/TcpExample2ConnectionCounting.java new file mode 100644 index 0000000000000000000000000000000000000000..de9a434599c0f5bff320eab63a516922a837af3d --- /dev/null +++ b/assignments/src/src/TcpExamples/TcpExample2ConnectionCounting.java @@ -0,0 +1,149 @@ +package TcpExamples; + +import java.io.*; +import java.net.*; + +/** + * <p> + * This program is only slightly more complex than {@link TcpExample1Telnet}, + * counting each connection instead of immediately exiting after the first connection. + * The only thing this program does differently is introduce a loop into the response, + * so you don't have to restart the program after one response. + * Also, it prints out the socket pair the server sees. + * </p> + * <p> + * Suggestion: connect to this program via telnet several times, + * comparing the socket-pair responses each time. + * </p> + * <p> + * <b><code>telnet localhost 2317</code></b> + * </p> + * <p> + * If you're paying attention (and sophisticated!) you can contact the + * another person's computer in class while running this program. This is + * a good way to check local-area network (LAN) connectivity. + * To learn that local computer's IPv4 Address, type + * </p> + * <p> + * <b><code>ipconfig</code></b> + * </p> + * <p> + * (On the NPS campus you might get a ipOfServerLaptop number like 172.20.148.215). + * The someone else (or even that person) can run + * </p> + * <p> + * <b><code>telnet ipOfServerLaptop 2317</code></b> + * </p> + * <p> + * If this program is running, then that machine displays the current counter value of + * socket pairs received. + * </p> + * @see <a href="../../../src/TcpExamples/TcpExample2ConnectionCountingTerminalLog.txt" target="blank">TcpExample2ConnectionCountingTerminalLog.txt</a> + * @see <a href="../../../src/TcpExamples/TcpExample2ConnectionCountingScreenshot.png" target="blank">TcpExample2ConnectionCountingScreenshot.png</a> + * @see <a href="https://savage.nps.edu/Savage/developers.html#Cygwin" target="blank">Savage Developers Guide: Cygwin</a> + * @see <a href="https://savage.nps.edu/Savage/developers.html#telnet" target="blank">Savage Developers Guide: telnet</a> + * @see <a href="https://en.wikipedia.org/wiki/Ipconfig" target="blank">Wikipedia: ipconfig</a> + * + * @author mcgredo + * @author brutzman@nps.edu + */ +public class TcpExample2ConnectionCounting +{ + /** Default constructor */ + public TcpExample2ConnectionCounting() + { + // default constructor + } + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String[] args) + { + try + { + // welcome aboard messages + System.out.println("TcpExample2ConnectionCounting has started and is waiting for a connection."); + System.out.println(" help: https://savage.nps.edu/Savage/developers.html#telnet"); + System.out.println(" Windows ipconfig (or Mac ifconfig) indicates current IPv4_Address (for example local wireless IP address)"); + System.out.println(" Windows enter (telnet localhost 2317) or Mac enter (nc localhost 2317) for loopback operation, or" ); + System.out.println(" Windows enter (telnet IPv4_Address 2317) or Mac enter (nc IPv4_Address 2317) for LAN operation" ); + System.out.println("TcpExample2ConnectionCounting server standing by..." ); + + // ServerSocket waits for a connection from a client. + // Notice that it is outside the loop; ServerSocket needs to be made only once. + + int connectionCount = 0; // state variable + + ServerSocket serverSocket = new ServerSocket(2317); // server decides here what port to listen on. + // of interest: often client doesn't care what port it uses locally when connecting to that server port. + + // Loop, infinitely, waiting for client connections. + // Stop the program somewhere else. + while(true) + { + // serverSocket.accept() blocks! then proceeds once a connection is "accept"ed + try (Socket clientConnection = serverSocket.accept()) { // the accept() method blocks here until a client connects + connectionCount++; // got another one! a client has connected + + OutputStream os = clientConnection.getOutputStream(); + PrintStream ps = new PrintStream(os); + +// if (connectionCount == 1) // first time through, report connection +// { +// // Where are we? In other words, what is our host number? Advertise it. +// // Note that we use the serverSocket to get address, since host may have multiple network connections. +// // https://stackoverflow.com/questions/9481865/getting-the-ip-address-of-the-current-machine-using-java +// String localHostAddress = clientConnection.getInetAddress().getHostAddress(); +// System.out.println("Local host address is " + localHostAddress); +// if (localHostAddress.contains("/")) +// localHostAddress = localHostAddress.substring(localHostAddress.indexOf("/")+1); +// // show localhost IP number to facilitate connections over local area network (LAN, WAN) +// System.out.println(" enter (nc localhost 2317) or (telnet localhost 2317) for local operation" ); +// System.out.println(" enter (nc " + localHostAddress + " 2317) or " + +// "(telnet " + localHostAddress + " 2317)..." ); +// } + + ps.println("This client response was written by server " + TcpExample2ConnectionCounting.class.getName()); // to remote client + System.out.println("This server response was written by server " + TcpExample2ConnectionCounting.class.getName()); // to server console + + ps.println("You were connection #" + connectionCount + ", by my count"); + + // Print some information locally about the Socket connection. + // This includes the port and IP numbers on both sides (the socket pair.) + + InetAddress localAddress = clientConnection.getLocalAddress(); + InetAddress remoteAddress = clientConnection.getInetAddress(); + + int localPort = clientConnection.getLocalPort(); + int remotePort = clientConnection.getPort(); // remember the prior question, why are 2 ports different? + + // My socket pair connection looks like this, to localhost: + // Socket pair: (( /0:0:0:0:0:0:0:1, 2317 ), ( /0:0:0:0:0:0:0:1, 54876 )) note IPv6 + // Socket pair: (( /0:0:0:0:0:0:0:1, 2317 ), ( /0:0:0:0:0:0:0:1, 54881 )) + // + // Why is first IP/port the same, while the second set has different ports? + + System.out.println("Socket pair (server, client): (( " + localAddress.toString() + ", " + localPort + " ), ( " + + remoteAddress.toString() + ", " + remotePort + " ))"); + + System.out.println("got another connection, #" + connectionCount); // report progress + + // Notice the use of flush() and close(). Without + // the close() to Socket object may stay open for + // a while after the client has stopped needing this + // connection. Close() explicitly ends the connection. + ps.flush(); + } + } + } + catch(IOException e) + { + System.err.println("Problem with " + TcpExample2ConnectionCounting.class.getName() + " networking:"); // describe what is happening + System.err.println("Error: " + e); + // Provide more helpful information to user if exception occurs due to running twice at one time + if (e instanceof java.net.BindException) + System.err.println("*** Be sure to stop any other running instances of programs using this port!"); + } + } +} diff --git a/assignments/src/src/TcpExamples/TcpExample2ConnectionCountingScreenshot.png b/assignments/src/src/TcpExamples/TcpExample2ConnectionCountingScreenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..242286d10aa7cb2dc816499d794d93e7b18efaf6 Binary files /dev/null and b/assignments/src/src/TcpExamples/TcpExample2ConnectionCountingScreenshot.png differ diff --git a/assignments/src/src/TcpExamples/TcpExample2ConnectionCountingTerminalLog.txt b/assignments/src/src/TcpExamples/TcpExample2ConnectionCountingTerminalLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..e7324dfea05687f0e3e4130afb6a058a3a994d2d --- /dev/null +++ b/assignments/src/src/TcpExamples/TcpExample2ConnectionCountingTerminalLog.txt @@ -0,0 +1,46 @@ +Invocation instructions: +1. run/debug TcpExample2ConnectionCounting.java + +2. Windows: ipconfig + MacOS: ifconfig + +3. Windows: telnet localhost 2317 + MacOS: nc localhost 2317 + +Program responses: + +=================================================== +run-single: +TcpExample2ConnectionCounting has started and is waiting for a connection. + help: https://savage.nps.edu/Savage/developers.html#telnet + Windows ipconfig (or Mac ifconfig) indicates current IPv4_Address (for example local wireless IP address) + Windows enter (telnet localhost 2317) or Mac enter (nc localhost 2317) for loopback operation, or + Windows enter (telnet IPv4_Address 2317) or Mac enter (nc IPv4_Address 2317) for LAN operation +TcpExample2ConnectionCounting server standing by... +This server response was written by server TcpExamples.TcpExample2ConnectionCounting +Socket pair (server, client): (( /172.20.154.38, 2317 ), ( /172.20.153.125, 55424 )) +got another connection, #1 +This server response was written by server TcpExamples.TcpExample2ConnectionCounting +Socket pair (server, client): (( /172.20.154.38, 2317 ), ( /172.20.153.125, 55425 )) +got another connection, #2 +This server response was written by server TcpExamples.TcpExample2ConnectionCounting +Socket pair (server, client): (( /172.20.154.38, 2317 ), ( /172.20.153.125, 55426 )) +got another connection, #3 +This server response was written by server TcpExamples.TcpExample2ConnectionCounting +Socket pair (server, client): (( /172.20.154.38, 2317 ), ( /172.20.153.125, 55427 )) +got another connection, #4 +This server response was written by server TcpExamples.TcpExample2ConnectionCounting +Socket pair (server, client): (( /172.20.154.38, 2317 ), ( /172.20.153.125, 55428 )) +got another connection, #5 +This server response was written by server TcpExamples.TcpExample2ConnectionCounting +Socket pair (server, client): (( /172.20.154.38, 2317 ), ( /172.20.154.38, 49308 )) +got another connection, #6 + +=================================================== +$ telnet localhost 2317 + +This client response was written by server TcpExamples.TcpExample2ConnectionCounting +You were connection #6, by my count + +Connection to host lost. +=================================================== \ No newline at end of file diff --git a/assignments/src/src/TcpExamples/TcpExample3Client.java b/assignments/src/src/TcpExamples/TcpExample3Client.java new file mode 100644 index 0000000000000000000000000000000000000000..7312d3aac7f8aacf27abd5ca77d4c299b0867044 --- /dev/null +++ b/assignments/src/src/TcpExamples/TcpExample3Client.java @@ -0,0 +1,113 @@ +package TcpExamples; + +import java.io.*; +import java.net.*; + +/** + * <p> + * This program duplicates what happened when telnet (or nc) was invoked in prior examples, + * directly connecting to an already-running {@link TcpExample3Server}. + * In prior examples, we used telnet (or netcat) to connect to the server application. + * In this example, we are now writing our own program to make the socket connection. + * </p> + * <p> + * As you will see, when we run this program after we start the server program, + * we will see a string similar to what telnet printed, sent by the server. + * The output at the server shows different socket-pair values, each time the loop iterates. + * </p> + * + * @see TcpExample3Server + * @see <a href="../../../src/TcpExamples/TcpExample3TerminalLog.txt" target="blank">TcpExample3TerminalLog.txt</a> + * @see <a href="../../../src/TcpExamples/TcpExample3ServerClientScreenshot.png" target="blank">TcpExample3ServerClientScreenshot.png</a> + * @see <a href="https://savage.nps.edu/Savage/developers.html#Cygwin" target="blank">Savage Developers Guide: Cygwin</a> + * @see <a href="https://savage.nps.edu/Savage/developers.html#telnet" target="blank">Savage Developers Guide: telnet</a> + * @see <a href="https://en.wikipedia.org/wiki/Ipconfig" target="blank">Wikipedia: ipconfig</a> + * + * @author mcgredo + * @author brutzman@nps.edu + */ +public class TcpExample3Client +{ + /** Default constructor */ + public TcpExample3Client() + { + // default constructor + } + + /** IPv6 String constant for localhost address, similarly IPv4 127.0.0.1 + * @see <a href="https://en.wikipedia.org/wiki/localhost" target="_blank">https://en.wikipedia.org/wiki/localhost</a> + * @see <a href="https://en.wikipedia.org/wiki/IPv6_address" target="_blank">https://en.wikipedia.org/wiki/IPv6_address</a> + */ + public final static String LOCALHOST = "0:0:0:0:0:0:0:1"; //Local host + + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + @SuppressWarnings("SleepWhileInLoop") // you have been warned! + public static void main(String[] args) + { + // Local variables/fields + Socket socket = null; + InputStream is; + Reader isr; + BufferedReader br; + String serverMessage; + int clientLoopCount = 0; + + try { + while (true) + { + clientLoopCount++; // increment at beginning of loop for reliability + System.out.println(TcpExample3Client.class.getName() + " creating socket..."); + + // We request an IP to connect to ("localhost") and + // port number at that IP (2317). This establishes + // a connection to that IP in the form of a Socket + // object; the server uses a ServerSocket to wait for + // connections. + socket = new Socket(LOCALHOST, 2317); // can change hostname (or IP number) to connect to another system + + // Now hook everything up (i.e. set up the streams), Java style: + is = socket.getInputStream(); + isr = new InputStreamReader(is); + br = new BufferedReader(isr); + + // Read a single line written by the server. We'd + // do things a bit differently if there were many lines to be read + // from the server instead of one only. + serverMessage = br.readLine(); + System.out.println("=================================================="); + + System.out.print ("Client loop " + clientLoopCount + ": "); + System.out.println("now we're talking!"); + System.out.println("The message the server sent was: '" + serverMessage + "'"); + // socket gets closed, either automatically/silently by this code (or possibly by the server) + + Thread.sleep(500l); // slow things down, for example 500l (long) = 500 msec (1/2 second) + + } // end while(true) // infinite loops are dangerous, be sure to kill this process! + } + catch (IOException | InterruptedException e ) + { + System.err.println("Problem with " + TcpExample3Client.class.getName() + " networking:"); // describe what is happening + System.err.println("Error: " + e); + + // Provide more helpful information to user if exception occurs due to running twice at one time + if (e instanceof java.net.BindException) { + System.err.println("*** Be sure to stop any other running instances of programs using this port!"); + } + } + finally // occurs after any other activity when shutting down + { + try { + if (socket != null) + socket.close(); + } catch (IOException e) {} + + // program exit: tell somebody about that happening. Likely cause: server drops connection. + System.out.println(); + System.out.println(TcpExample3Client.class.getName() + " exit"); + } + } +} diff --git a/assignments/src/src/TcpExamples/TcpExample3Server.java b/assignments/src/src/TcpExamples/TcpExample3Server.java new file mode 100644 index 0000000000000000000000000000000000000000..016480d7c0c1d33a6614c8817a1269c512a2e77f --- /dev/null +++ b/assignments/src/src/TcpExamples/TcpExample3Server.java @@ -0,0 +1,130 @@ +package TcpExamples; + +import java.io.*; +import java.net.*; + +/** + * <p> + * This program is only slightly more complex than {@link TcpExample1Telnet} + * and {@link TcpExample2ConnectionCounting}, awaiting a socket response. + * The only thing it does differently is introduce a loop into the response, so + * you don't have to restart the program after one response. Also, it prints out + * the socket pair the server sees. Run the program via telnet (or nc) + * several times and compare the socket pairs. + * </p> + * <p> + * <b><code>telnet localhost 2317</code></b> + * </p> + * <p> + * If you're paying attention (and sophisticated!) you can contact the + * another person's computer in class while running this program. This is + * a good way to check local-area network (LAN) connectivity. + * To learn that local computer's IPv4 Address, type + * </p> + * <p> + * <b><code>ipconfig</code></b> + * </p> + * <p> + * Then contact the other computer by using telnet (or nc) + * </p> + * <p> + * <code><b>telnet</b> [ipNumberOfServerLaptop] <b>2317</b></code> + * </p> + * <p> + * and have the other system display the socket pairs received. + * </p> + * + * @see TcpExample3Client + * @see <a href="../../../src/TcpExamples/TcpExample3TerminalLog.txt" target="blank">TcpExample3TerminalLog.txt</a> + * @see <a href="../../../src/TcpExamples/TcpExample3ServerClientScreenshot.png" target="blank">TcpExample3ServerClientScreenshot.png</a> + * @see <a href="https://savage.nps.edu/Savage/developers.html#Cygwin" target="blank">Savage Developers Guide: Cygwin</a> + * @see <a href="https://savage.nps.edu/Savage/developers.html#telnet" target="blank">Savage Developers Guide: telnet</a> + * @see <a href="https://en.wikipedia.org/wiki/Ipconfig" target="blank">Wikipedia: ipconfig</a> + * + * @author mcgredo + * @author brutzman@nps.edu + */ +public class TcpExample3Server +{ + /** Default constructor */ + public TcpExample3Server() + { + // default constructor + } + + /** + * Program invocation, execution starts here + * If already compiled, can run using console in directory ../../build/classes/ by invoking \ + * java -classpath . TcpExamples.TcpExample3Server + * @param args command-line arguments + */ + public static void main(String[] args) { + try { + + // ServerSocket waits for a connection from a client. + // Notice that it is outside the loop; ServerSocket + // needs to be made only once. + System.out.println(TcpExample3Server.class.getName() + " has started..."); // it helps debugging to put this on console first + + ServerSocket serverSocket = new ServerSocket(2317); + OutputStream os; + PrintStream ps; + InetAddress localAddress, remoteAddress; + int localPort, remotePort; + int serverLoopCount = 0; + + // Server is up and waiting (i.e. "blocked" or paused) + // Loop, infinitely, waiting for client connections. + // Stop the program somewhere else. + while (true) { + + // block until connected to a client + try (Socket clientConnectionSocket = serverSocket.accept()) + { + serverLoopCount++; // increment at beginning of loop for reliability + + // Now hook everything up (i.e. set up the streams), Java style: + os = clientConnectionSocket.getOutputStream(); + ps = new PrintStream(os); + ps.println("This is response " + serverLoopCount + " produced by the server."); // this gets sent back to client! + + // Print some information locally about the Socket connection. + // This includes the port and IP numbers on both sides (the socket pair). + localAddress = clientConnectionSocket.getLocalAddress(); + remoteAddress = clientConnectionSocket.getInetAddress(); + localPort = clientConnectionSocket.getLocalPort(); + remotePort = clientConnectionSocket.getPort(); + + System.out.print ("Server loop " + serverLoopCount + ": "); + + // My socket pair connection looks like this, to localhost: + // Socket pair: (( /0:0:0:0:0:0:0:1, 2317 ), ( /0:0:0:0:0:0:0:1, 54876 )) + // Socket pair: (( /0:0:0:0:0:0:0:1, 2317 ), ( /0:0:0:0:0:0:0:1, 54881 )) + + // Why is the first IP/port the same, while the second set has different ports? + System.out.println(TcpExample3Server.class.getName() + " socket pair showing host name, address, port:"); + System.out.println(" (( " + + localAddress.getHostName() + "=" + localAddress.getHostAddress() + ", " + localPort + " ), ( " + + remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " ))"); + + if ( localAddress.getHostName().equals( localAddress.getHostAddress()) || + remoteAddress.getHostName().equals(remoteAddress.getHostAddress())) + System.out.println(" note HostName matches address if host has no DNS name"); + // Notice the use of flush() and try w/ resources. Without + // the try w/ resources the Socket object may stay open for + // a while after the client has stopped needing this + // connection. try w/ resources explicitly ends the connection. + ps.flush(); + // like it or not, you're outta here! + } + } + } catch (IOException e) { + System.err.println("Problem with " + TcpExample3Server.class.getName() + " networking: " + e); + + // Provide more helpful information to user if exception occurs due to running twice at one time + if (e instanceof java.net.BindException) { + System.err.println("*** Be sure to stop any other running instances of programs using this port!"); + } + } + } +} diff --git a/assignments/src/src/TcpExamples/TcpExample3ServerClientScreenshot.png b/assignments/src/src/TcpExamples/TcpExample3ServerClientScreenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..64210e343ab2c91bad19fa88fb8a8c989e8b9c16 Binary files /dev/null and b/assignments/src/src/TcpExamples/TcpExample3ServerClientScreenshot.png differ diff --git a/assignments/src/src/TcpExamples/TcpExample3TerminalLog.txt b/assignments/src/src/TcpExamples/TcpExample3TerminalLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..e6b55d9562b8fa4f8dfb79ffcb15420e4119a20d --- /dev/null +++ b/assignments/src/src/TcpExamples/TcpExample3TerminalLog.txt @@ -0,0 +1,46 @@ +Invocation instructions: +* run/debug TcpExample3Server.java +* run/debug TcpExample3Client.java + +Program responses: + +=================================================== +run-single: +TcpExample3Server has started... +Server loop 1: TcpExample3Server socket pair showing host name, address, port: + (( 0:0:0:0:0:0:0:1=0:0:0:0:0:0:0:1, 2317 ), ( 0:0:0:0:0:0:0:1=0:0:0:0:0:0:0:1, 54180 )) + note HostName matches address if host has no DNS name +Server loop 2: TcpExample3Server socket pair showing host name, address, port: + (( 0:0:0:0:0:0:0:1=0:0:0:0:0:0:0:1, 2317 ), ( 0:0:0:0:0:0:0:1=0:0:0:0:0:0:0:1, 54181 )) + note HostName matches address if host has no DNS name +Server loop 3: TcpExample3Server socket pair showing host name, address, port: + (( 0:0:0:0:0:0:0:1=0:0:0:0:0:0:0:1, 2317 ), ( 0:0:0:0:0:0:0:1=0:0:0:0:0:0:0:1, 54182 )) + note HostName matches address if host has no DNS name +[etc.] +[kill process to exit] + +=================================================== +run-single: +TcpExample3Client creating socket... +================================================== +Client loop 1: now we're talking! +The message the server sent was: 'This is response 1 produced by the server.' +TcpExample3Client creating socket... +================================================== +Client loop 2: now we're talking! +The message the server sent was: 'This is response 2 produced by the server.' +TcpExample3Client creating socket... +================================================== +Client loop 3: now we're talking! +The message the server sent was: 'This is response 3 produced by the server.' +TcpExample3Client creating socket... +================================================== +[etc.] +TcpExample3Client exit + +You must kill this client process to stop it, each is in an infinite loop. + +If first you kill the server process, that will kill the client process +automatically when the connection drops, simply because the client program +is written that way. Killing the client process first does not stop the +server, which will keep the localhost port locked. Go ahead and test this. diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Lennon/LennonHW2Client.java b/assignments/src/src/TcpExamples/TcpExample4Client.java similarity index 50% rename from assignments/src/MV3500Cohort2024JulySeptember/homework2/Lennon/LennonHW2Client.java rename to assignments/src/src/TcpExamples/TcpExample4Client.java index de94d5fb361ce77f084802c845fed37e3c512050..9c6999a580ebe4a9bcb4fdbadeed854077df491c 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Lennon/LennonHW2Client.java +++ b/assignments/src/src/TcpExamples/TcpExample4Client.java @@ -1,11 +1,7 @@ -package MV3500Cohort2024JulySeptember.homework2.Lennon; +package TcpExamples; -//import TcpExamples.TcpExample3Client; -//import TcpExamples.TcpExample4DispatchServer; -//import TcpExamples.TcpExample4HandlerThread; import java.io.*; import java.net.*; -import java.util.Scanner; //import java.time.LocalTime; // conversion? /** @@ -24,15 +20,15 @@ import java.util.Scanner; * @author Don Brutzman * @author MV3500 class */ -public class LennonHW2Client +public class TcpExample4Client { /** Default constructor */ - public LennonHW2Client() + public TcpExample4Client() { - // default constructor } static String DESTINATION_HOST = "localhost"; + static int MAX_LOOP_COUNT = 4; /** * Program invocation, execution starts here @@ -40,23 +36,23 @@ public class LennonHW2Client */ public static void main(String[] args) { try { - boolean play; - Scanner scanner = new Scanner(System.in); - - do{ - System.out.println("======================================================="); - System.out.println(LennonHW2Client.class.getName() + " creating new socket ...\n"); + System.out.println(TcpExample4Client.class.getName() + " start, loop " + MAX_LOOP_COUNT + " times"); + System.out.println("=================================================="); + for (int loopCount = 1; loopCount <= MAX_LOOP_COUNT; loopCount++) // loop then exit + { + System.out.println(TcpExample4Client.class.getName() + " creating socket #" + loopCount + "..."); // We request an IP to connect to ("localhost") and // port number at that IP (2317). This establishes // a connection to that IP in the form of the Socket // object; the server uses a ServerSocket to wait for - // connections. - + // connections.This particualar example is interacting + // with what it expects is a server that writes a single text + // line after 10 sec. + long startTime = System.currentTimeMillis(); // open a socket for each loop Socket socket = new Socket(DESTINATION_HOST, 2317); - long startTime = System.currentTimeMillis(); // Setup. Read the single line written by the server. // We'd do things a bit differently if many lines to be read @@ -66,51 +62,18 @@ public class LennonHW2Client BufferedReader br = new BufferedReader(isr); String serverMessage = br.readLine(); // blocks - System.out.println("Message from server:" + serverMessage); - String guess = null; - boolean validGuess = false; - while(!validGuess){ - guess = scanner.nextLine(); - try{ - int numGuess = Integer.parseInt(guess); - if (numGuess < 1 || numGuess > 10){ - System.out.println("I said between 1 and 10. Guess Again"); - continue; - } - validGuess = true; - } - catch(NumberFormatException e){ - System.out.println("That's not a number. Guess Again"); - } - } - OutputStream os = socket.getOutputStream(); - PrintStream ps = new PrintStream(os); - - ps.println(guess); - ps.flush(); - - is = socket.getInputStream(); - isr = new InputStreamReader(is); - br = new BufferedReader(isr); + long readTime = System.currentTimeMillis(); + long timeLength = readTime - startTime; - serverMessage = br.readLine(); // blocks - long endTime = System.currentTimeMillis(); - long timeLength = endTime - startTime; - - System.out.println("\nMessage from server:" + serverMessage); - System.out.println("Time to play = " + timeLength); - - System.out.println("\nWant to go again? Y/N"); - - String response = scanner.nextLine(); - play = "Y".equals(response.toUpperCase()); - }while(play); - System.out.println("\nGOODBYE"); - System.out.println("======================================================="); - System.out.println(LennonHW2Client.class.getName() + " complete"); + System.out.println(TcpExample4Client.class.getName() + ": message received from server='" + serverMessage + "'"); + System.out.println(TcpExample4Client.class.getName() + ": time msec required for read=" + timeLength); + System.out.println("=================================================="); + // To push this further, launch multiple copies of TcpExample4Client simultaneously + } + System.out.println(TcpExample4Client.class.getName() + " complete"); // main method now exits } catch (IOException e) { - System.out.println("Problem with " + LennonHW2Client.class.getName() + " networking:networking:"); // describe what is happening + System.out.println("Problem with " + TcpExample4Client.class.getName() + " networking:networking:"); // describe what is happening System.out.println("Error: " + e); // Provide more helpful information to user if exception occurs due to running twice at one time if (e instanceof java.net.BindException) { diff --git a/assignments/src/src/TcpExamples/TcpExample4DispatchServer.java b/assignments/src/src/TcpExamples/TcpExample4DispatchServer.java new file mode 100644 index 0000000000000000000000000000000000000000..d889c89002b2663d85764ec45a88b4e9495c0388 --- /dev/null +++ b/assignments/src/src/TcpExamples/TcpExample4DispatchServer.java @@ -0,0 +1,64 @@ +package TcpExamples; + +import java.io.IOException; +import java.net.*; + +/** + * 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 TcpExample4Client + * @see TcpExample4HandlerThread + * + * @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 + */ +public class TcpExample4DispatchServer +{ + /** Default constructor */ + public TcpExample4DispatchServer() + { + // default constructor + } + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String[] args) + { + try { + ServerSocket serverSocket = new ServerSocket(2317); + TcpExample4HandlerThread handlerThread; + Socket clientConnection; + + int connectionCount = 0; // state variable + + System.out.println(TcpExample4DispatchServer.class.getName() + " ready to accept socket connections..."); + while (true) // infinite loop + { + clientConnection = serverSocket.accept(); // block until connected + + connectionCount++; // unblocked, got another connection + System.out.println("============================================================="); + System.out.println(TcpExample4DispatchServer.class.getName() + ".handlerThread invocation for connection #" + connectionCount + "..."); + handlerThread = new TcpExample4HandlerThread(clientConnection); + handlerThread.start(); // invokes the run() method in that object + System.out.println(TcpExample4DispatchServer.class.getName() + ".handlerThread is launched, awaiting another connection..."); + } + } catch (IOException e) { + System.out.println("Problem with " + TcpExample4DispatchServer.class.getName() + " networking:"); // describe what is happening + System.out.println("Error: " + e); + // Provide more helpful information to user if exception occurs due to running twice at one time + if (e instanceof java.net.BindException) { + System.out.println("*** Be sure to stop any other running instances of programs using this port!"); + } + } + System.out.println("============================================================="); + } +} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/TcpExample4HandlerThread.java b/assignments/src/src/TcpExamples/TcpExample4HandlerThread.java similarity index 83% rename from assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/TcpExample4HandlerThread.java rename to assignments/src/src/TcpExamples/TcpExample4HandlerThread.java index 70bc2c165e307cbe5338aba7fb26e73bccea2600..2c3a128371e31e9a12b2bcdedb74bbedf5c7a54b 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Romero/TcpExample4HandlerThread.java +++ b/assignments/src/src/TcpExamples/TcpExample4HandlerThread.java @@ -1,4 +1,4 @@ -package MV3500Cohort2024JulySeptember.homework2.Romero; +package TcpExamples; import java.io.*; import java.net.*; @@ -31,9 +31,9 @@ public class TcpExample4HandlerThread extends Thread /** The socket connection to a client */ Socket socket; - /** - * The thread constructor creates the socket from a ServerSocket, waiting for the client to connect, - * and passes that socket when constructing the thread responsible for handling the connection. + /** The thread constructor creates the socket from + * a ServerSocket, and passes one to the thread + * responsible for handling the connection. * * @param socket The socket connection handled by this thread */ @@ -41,15 +41,6 @@ public class TcpExample4HandlerThread extends Thread { this.socket = socket; } - /** - * Program invocation and execution starts here - but is illegal and unwanted, so warn the unsuspecting user! - * @param args command-line arguments - */ - public static void main(String[] args) - { - System.out.println ("*** TcpExample4HandlerThread is not a standalone executable progam."); - System.out.println ("*** Please run TcpExample4DispatchServer instead... now exiting."); - } /** Handles one connection. We add an artificial slowness * to handling the connection with a sleep(). This means diff --git a/assignments/src/src/TcpExamples/TcpExample4SequenceDiagram.png b/assignments/src/src/TcpExamples/TcpExample4SequenceDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..3eb3a8e753d2e7aea1baf4a1366b06397446f829 Binary files /dev/null and b/assignments/src/src/TcpExamples/TcpExample4SequenceDiagram.png differ diff --git a/assignments/src/src/TcpExamples/TcpExample4SequenceDiagram.vsdx b/assignments/src/src/TcpExamples/TcpExample4SequenceDiagram.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..0248702b8eb0d8819b9bc052a73aac1abfdbdda7 Binary files /dev/null and b/assignments/src/src/TcpExamples/TcpExample4SequenceDiagram.vsdx differ diff --git a/assignments/src/src/TcpExamples/TcpExample4SequenceSketch.png b/assignments/src/src/TcpExamples/TcpExample4SequenceSketch.png new file mode 100644 index 0000000000000000000000000000000000000000..e34c8bcadd16bf3a9fd372580b93b33dafc995dd Binary files /dev/null and b/assignments/src/src/TcpExamples/TcpExample4SequenceSketch.png differ diff --git a/assignments/src/src/TcpExamples/TcpExample4TerminalLog.txt b/assignments/src/src/TcpExamples/TcpExample4TerminalLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..62945afa1c89dca8c65efab4cf390c6bd520bf7b --- /dev/null +++ b/assignments/src/src/TcpExamples/TcpExample4TerminalLog.txt @@ -0,0 +1,69 @@ +Invocation instructions: +1. run/debug TcpExample4ThreadTcpExample4DispatchServerServer.java +2. don't run TcpExample4HandlerThread (since it is automatically launched as needed) +3. run/debug TcpExample4Client.java + +Two program response logs, server and client: + +=================================================== +=================================================== +run: +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=TcpExamples/TcpExample4DispatchServer.java -Drun.class=TcpExamples.TcpExample4DispatchServer run-single + +run-single: +TcpExamples.TcpExample4DispatchServer ready to accept socket connections... +============================================================= +TcpExamples.TcpExample4DispatchServer.handlerThread invocation for connection #1... +TcpExamples.TcpExample4DispatchServer.handlerThread is launched, awaiting another connection... +TcpExamples.TcpExample4HandlerThread starting to handle a thread... +TcpExamples.TcpExample4HandlerThread pausing for TIMEOUT=2000ms to emulate computation and avoid server-side overload +TcpExamples.TcpExample4HandlerThread finished handling a thread, now exit. +============================================================= +TcpExamples.TcpExample4DispatchServer.handlerThread invocation for connection #2... +TcpExamples.TcpExample4DispatchServer.handlerThread is launched, awaiting another connection... +TcpExamples.TcpExample4HandlerThread starting to handle a thread... +TcpExamples.TcpExample4HandlerThread pausing for TIMEOUT=2000ms to emulate computation and avoid server-side overload +TcpExamples.TcpExample4HandlerThread finished handling a thread, now exit. +============================================================= +TcpExamples.TcpExample4DispatchServer.handlerThread invocation for connection #3... +TcpExamples.TcpExample4DispatchServer.handlerThread is launched, awaiting another connection... +TcpExamples.TcpExample4HandlerThread starting to handle a thread... +TcpExamples.TcpExample4HandlerThread pausing for TIMEOUT=2000ms to emulate computation and avoid server-side overload +TcpExamples.TcpExample4HandlerThread finished handling a thread, now exit. +============================================================= +TcpExamples.TcpExample4DispatchServer.handlerThread invocation for connection #4... +TcpExamples.TcpExample4DispatchServer.handlerThread is launched, awaiting another connection... +TcpExamples.TcpExample4HandlerThread starting to handle a thread... +TcpExamples.TcpExample4HandlerThread pausing for TIMEOUT=2000ms to emulate computation and avoid server-side overload +TcpExamples.TcpExample4HandlerThread finished handling a thread, now exit. +BUILD STOPPED (total time: 25 seconds) + +=================================================== +=================================================== +run: +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=TcpExamples/TcpExample4Client.java -Drun.class=TcpExamples.TcpExample4Client run-single + +run: +TcpExamples.TcpExample4Client start, loop 4 times +================================================== +TcpExamples.TcpExample4Client creating socket #1... +TcpExamples.TcpExample4Client: message received from server='This message was written by the server TcpExamples.TcpExample4HandlerThread' +TcpExamples.TcpExample4Client: time msec required for read=2024 +================================================== +TcpExamples.TcpExample4Client creating socket #2... +TcpExamples.TcpExample4Client: message received from server='This message was written by the server TcpExamples.TcpExample4HandlerThread' +TcpExamples.TcpExample4Client: time msec required for read=2008 +================================================== +TcpExamples.TcpExample4Client creating socket #3... +TcpExamples.TcpExample4Client: message received from server='This message was written by the server TcpExamples.TcpExample4HandlerThread' +TcpExamples.TcpExample4Client: time msec required for read=2007 +================================================== +TcpExamples.TcpExample4Client creating socket #4... +TcpExamples.TcpExample4Client: message received from server='This message was written by the server TcpExamples.TcpExample4HandlerThread' +TcpExamples.TcpExample4Client: time msec required for read=2011 +================================================== +TcpExamples.TcpExample4Client complete +BUILD SUCCESSFUL (total time: 8 seconds) + +=================================================== +=================================================== \ No newline at end of file diff --git a/assignments/src/src/TcpExamples/package-info.java b/assignments/src/src/TcpExamples/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..84c534757e0c48c8321bf36bd2d769dac7a141ab --- /dev/null +++ b/assignments/src/src/TcpExamples/package-info.java @@ -0,0 +1,10 @@ +/** + * TCP Unicast Examples supporting the NPS MOVES MV3500 Networked Graphics course. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples" target="blank">NetworkedGraphicsMV3500 examples</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 TcpExamples; diff --git a/assignments/src/src/UdpExamples/MulticastUdpReceiver.java b/assignments/src/src/UdpExamples/MulticastUdpReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..e7d5220158b9ae03570998d5729f7ecaa6853348 --- /dev/null +++ b/assignments/src/src/UdpExamples/MulticastUdpReceiver.java @@ -0,0 +1,123 @@ +package UdpExamples; + +import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface; +import java.io.*; +import java.net.*; +import java.nio.ByteBuffer; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Looks a lot like UdpReceiver. Start this before launching MulticastSender. + * + * @author mcgredo + * @author brutzman@nps.edu + */ +public class MulticastUdpReceiver +{ + /** Default constructor */ + public MulticastUdpReceiver() + { + // default constructor + } + // reserved range for all IPv4 multicast: 224.0.0.0 through 239.255.255.255 + // https://en.wikipedia.org/wiki/Multicast_address + // https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml + private static final String MULTICAST_ADDRESS = "239.1.2.15"; + private static final int DESTINATION_PORT = 1718; + + /** + * Time to live: how many router-decrement levels can be crossed + */ + private static final int TTL = 10; + + private static final boolean INFINITE_READ_LOOP = true; + private static NetworkInterface ni; + + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String[] args) + { + MulticastSocket multicastSocket = null; + InetSocketAddress group = null; + ByteBuffer buffer = ByteBuffer.allocate(1500); + DatagramPacket packet = new DatagramPacket(buffer.array(), buffer.capacity()); + + try { + System.out.println("UdpExamples.MulticastUdpReceiver started..."); + + // This is a java/IPv6 problem. You should also add it to the + // arguments used to start the app, eg -Djava.net.preferIPv4Stack=true + // set in the "run" section of preferences. Also, typically + // netbeans must be restarted after these settings. + // https://stackoverflow.com/questions/18747134/getting-cant-assign-requested-address-java-net-socketexception-using-ehcache + System.setProperty("java.net.preferIPv4Stack", "true"); + + multicastSocket = new MulticastSocket(DESTINATION_PORT); + multicastSocket.setTimeToLive(TTL); + InetAddress multicastAddress = InetAddress.getByName(MULTICAST_ADDRESS); + + group = new InetSocketAddress(multicastAddress, DESTINATION_PORT); + + // Join group useful on receiving side + multicastSocket.joinGroup(group, ni = DisThreadedNetworkInterface.findIpv4Interface()); + // You can join multiple groups here + + System.out.println("Multicast address/port: " + multicastAddress.getHostAddress() + "/" + DESTINATION_PORT); + System.out.println("Multicast packets received log:"); + + int index, count = 0; // initialize + float firstFloat, secondFloat; + StringBuilder firstCharacters = new StringBuilder(); + char nextChar; + + while (true) { // true is always true, so this is an infinite loop that continues until interrupted + multicastSocket.receive(packet); + count++; + + nextChar = ' '; + while (nextChar != ';') // read and build string until terminator ; found + { + nextChar = buffer.getChar(); + firstCharacters.append(nextChar); + } + if (firstCharacters.toString().contains(MulticastUdpSender.QUIT_SENTINEL)) { + System.out.println("Received sentinel \"" + MulticastUdpSender.QUIT_SENTINEL + "\""); + if (!INFINITE_READ_LOOP) { + break; // exit out of reading loop + } + } + index = buffer.getInt(); + firstFloat = buffer.getFloat(); + secondFloat = buffer.getFloat(); + buffer.clear(); + + if (count < 10) { + System.out.print(" "); // prettier output formatting + } + System.out.print(count + ". \"" + firstCharacters + "\" "); // wrap string in quote marks + System.out.println("index=" + index + ", firstFloat=" + firstFloat + " secondFloat=" + secondFloat); + + System.out.println("MulticastReceiver loop complete."); + firstCharacters.setLength(0); + } + } catch (IOException e) { + System.err.println("Problem with MulticastReceiver, see exception trace:"); + System.err.println(e); + } finally // clean up after exit condition + { + if (multicastSocket != null && !multicastSocket.isClosed()) { + try { + multicastSocket.leaveGroup(group, ni); + } catch (IOException ex) { + Logger.getLogger(MulticastUdpReceiver.class.getName()).log(Level.SEVERE, null, ex); + } + multicastSocket.close(); + } + // socket/database/completion cleanup code can go here, if needed. + System.out.println("MulticastReceiver finally block, complete."); + } + } +} diff --git a/assignments/src/src/UdpExamples/MulticastUdpSender.java b/assignments/src/src/UdpExamples/MulticastUdpSender.java new file mode 100644 index 0000000000000000000000000000000000000000..68788b7f83da4a6edbf7c8d358669ebd7de0963f --- /dev/null +++ b/assignments/src/src/UdpExamples/MulticastUdpSender.java @@ -0,0 +1,134 @@ +package UdpExamples; + +import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface; +import java.io.*; +import java.net.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Looks a lot like UdpSender. Start this after launching MulticastReceiver. + * + * Privacy note: this sender advertises your user name as part of the multicast packet message + * + * @author mcgredo + * @author brutzman@nps.edu + */ +public class MulticastUdpSender +{ + /** Default constructor */ + public MulticastUdpSender() + { + // default constructor + } + // reserved range for all IPv4 multicast: 224.0.0.0 through 239.255.255.255 + // https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml + + /** Default multicast group address for send and receive connections. + * @see <a href="https://en.wikipedia.org/wiki/Multicast_address" target="_blank">https://en.wikipedia.org/wiki/Multicast_address</a> */ + public static final String MULTICAST_ADDRESS = "239.1.2.15"; // within reserved multicast address range + /** Default socket port used, matches Wireshark DIS capture default + * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)" target="_blank">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> */ + public static final int DESTINATION_PORT = 1718; + + /** Time to live: how many router-decrement levels can be crossed */ + public static final int TTL = 10; + + /** How many packets to send prior to termination */ + public static final int LOOPSIZE = 20; // or maybe 20000 + + /** Receiving this message causes termination + * @see <a href="https://en.wikipedia.org/wiki/Sentinel_value" target="_blank">https://en.wikipedia.org/wiki/Sentinel_value</a> */ + public static final String QUIT_SENTINEL = "QUIT QUIT QUIT!"; + private static NetworkInterface ni; + + /** + * Program invocation, execution starts here + * @param args command-line arguments + * @throws java.io.IOException execution error + */ + @SuppressWarnings("SleepWhileInLoop") + public static void main(String[] args) throws IOException + { + MulticastSocket multicastSocket = null; + InetSocketAddress group = null; + + // Put together a message with binary content. "ByteArrayOutputStream" + // is a java.io utility that lets us put together an array of binary + // data, which we put into the UDP packet. + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + + try + { + System.out.println("UdpExamples.MulticastUdpSender started..."); + // This is a java/IPv6 problem. You should also add it to the + // arguments used to start the app, eg -Djava.net.preferIPv4Stack=true + // set in the "run" section of preferences. Also, typically + // netbeans must be restarted after these settings. + // https://stackoverflow.com/questions/18747134/getting-cant-assign-requested-address-java-net-socketexception-using-ehcache + System.setProperty("java.net.preferIPv4Stack", "true"); + + // multicast group we are sending to--not a single host + multicastSocket = new MulticastSocket(/*DESTINATION_PORT*/); + multicastSocket.setTimeToLive(TTL); // time to live reduces scope of transmission + InetAddress multicastAddress = InetAddress.getByName(MULTICAST_ADDRESS); + System.out.println("Multicast address/port: " + multicastAddress.getHostAddress() + "/" + DESTINATION_PORT); + + group = new InetSocketAddress(multicastAddress, DESTINATION_PORT); + // Join group useful on receiving side + multicastSocket.joinGroup(group, ni = DisThreadedNetworkInterface.findIpv4Interface()); + // You can join multiple groups here + + byte[] buffer = baos.toByteArray(); + DatagramPacket packet = new DatagramPacket(buffer, buffer.length, group/*, DESTINATION_PORT*/); + + for (int index = 0; index < LOOPSIZE; index++) + { + // Put together an updated packet to send + if (index < LOOPSIZE - 1) + { + // Put together an updated packet to send + dos.writeChars("From " + System.getProperty("user.name") + ": "); + dos.writeChars("MulticastSender packet " + Integer.toString(index) + ";"); // string chars for readability + dos.writeInt (index); // arbitrary data, needs Java or byte-alignment to read + dos.writeFloat(17.0f); // arbitrary data, needs Java or byte-alignment to read + dos.writeFloat(23.0f); // arbitrary data, needs Java or byte-alignment to read + } + else dos.writeChars(QUIT_SENTINEL + ";"); // note string must include ; semicolon as termination sentinel + + buffer = baos.toByteArray(); + packet.setData(buffer); + multicastSocket.send(packet); + System.out.println("Sent multicast packet " + (index + 1) + " of " + LOOPSIZE); + baos.reset(); + + // How fast does this go? Does UDP try to slow it down, or does + // this cause network problems? (hint: yes for an unlimited send + // rate, unlike TCP). How do you know on the receiving side + // that you haven't received a duplicate UDP packet, out of + // order packet, or dropped packet? Necessary considerations. + Thread.sleep(1000); // Send 100, one per second + } + System.out.println("MulticastSender complete."); + } + catch(IOException | InterruptedException e) + { + System.err.println("Problem with MulticastSender, see exception trace:"); + System.err.println(e); + } finally { + + if (multicastSocket != null && !multicastSocket.isClosed()) { + try { + multicastSocket.leaveGroup(group, ni); + } catch (IOException ex) { + Logger.getLogger(MulticastUdpSender.class.getName()).log(Level.SEVERE, null, ex); + } + multicastSocket.close(); + } + + dos.close(); + } + } + +} diff --git a/assignments/src/src/UdpExamples/MulticastUdpSenderWireshark.png b/assignments/src/src/UdpExamples/MulticastUdpSenderWireshark.png new file mode 100644 index 0000000000000000000000000000000000000000..554252e59b9815a5e8704ee219a71b6d7cf39e3b Binary files /dev/null and b/assignments/src/src/UdpExamples/MulticastUdpSenderWireshark.png differ diff --git a/assignments/src/src/UdpExamples/MulticastUdpTerminalLog.txt b/assignments/src/src/UdpExamples/MulticastUdpTerminalLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..812f534444435079cdb571599980a61693ef0d72 --- /dev/null +++ b/assignments/src/src/UdpExamples/MulticastUdpTerminalLog.txt @@ -0,0 +1,82 @@ +Invocation instructions: +1. run/debug MulticastReceiver.java +2. run/debug MulticastSender.java + +Program responses follow for sender and receiver: + +=================================================== +UdpMulticastExamples.MulticastUdpSender started... +Multicast address/port: 239.1.2.15/1718 +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] Using network interface Intel(R) Centrino(R) Ultimate-N 6300 AGN +Sent multicast packet 1 of 20 +Sent multicast packet 2 of 20 +Sent multicast packet 3 of 20 +Sent multicast packet 4 of 20 +Sent multicast packet 5 of 20 +Sent multicast packet 6 of 20 +Sent multicast packet 7 of 20 +Sent multicast packet 8 of 20 +Sent multicast packet 9 of 20 +Sent multicast packet 10 of 20 +Sent multicast packet 11 of 20 +Sent multicast packet 12 of 20 +Sent multicast packet 13 of 20 +Sent multicast packet 14 of 20 +Sent multicast packet 15 of 20 +Sent multicast packet 16 of 20 +Sent multicast packet 17 of 20 +Sent multicast packet 18 of 20 +Sent multicast packet 19 of 20 +Sent multicast packet 20 of 20 +MulticastSender complete. +BUILD SUCCESSFUL (total time: 22 seconds) + +=================================================== +run: +UdpMulticastExamples.MulticastUdpReceiver started... +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] Using network interface Intel(R) Centrino(R) Ultimate-N 6300 AGN +Multicast address/port: 239.1.2.15/1718 +Multicast packets received log: + 1. "From don: MulticastSender packet 0;" index=0, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. + 2. "From don: MulticastSender packet 1;" index=1, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. + 3. "From don: MulticastSender packet 2;" index=2, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. + 4. "From don: MulticastSender packet 3;" index=3, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. + 5. "From don: MulticastSender packet 4;" index=4, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. + 6. "From don: MulticastSender packet 5;" index=5, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. + 7. "From don: MulticastSender packet 6;" index=6, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. + 8. "From don: MulticastSender packet 7;" index=7, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. + 9. "From don: MulticastSender packet 8;" index=8, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. +10. "From don: MulticastSender packet 9;" index=9, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. +11. "From don: MulticastSender packet 10;" index=10, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. +12. "From don: MulticastSender packet 11;" index=11, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. +13. "From don: MulticastSender packet 12;" index=12, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. +14. "From don: MulticastSender packet 13;" index=13, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. +15. "From don: MulticastSender packet 14;" index=14, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. +16. "From don: MulticastSender packet 15;" index=15, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. +17. "From don: MulticastSender packet 16;" index=16, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. +18. "From don: MulticastSender packet 17;" index=17, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. +19. "From don: MulticastSender packet 18;" index=18, firstFloat=17.0 secondFloat=23.0 +MulticastReceiver loop complete. +Received sentinel "QUIT QUIT QUIT!" +20. "QUIT QUIT QUIT!;" index=6357107, firstFloat=1.0653034E-38 secondFloat=9.275539E-39 +MulticastReceiver loop complete. + +=================================================== diff --git a/assignments/src/src/UdpExamples/README.md b/assignments/src/src/UdpExamples/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1a22a7925642d72e706f18bdcb96f66e80a49098 --- /dev/null +++ b/assignments/src/src/UdpExamples/README.md @@ -0,0 +1,9 @@ +## UDP Examples Source Code + +Programs in this directory show how to create User Datagram Protocol (UDP) sockets + +<!-- View this page at https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/UdpExamples/README.md --> + +| Unicast UDP Sender packets in Wireshark | Multicast UDP Sender packets inWireshark | +|----------------------------------------------|:------------------------------------------| +|  | | diff --git a/assignments/src/src/UdpExamples/UnicastUdpReceiver.java b/assignments/src/src/UdpExamples/UnicastUdpReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..7bc05fb2b31412a200efdedf9aaacbad60771465 --- /dev/null +++ b/assignments/src/src/UdpExamples/UnicastUdpReceiver.java @@ -0,0 +1,109 @@ +package UdpExamples; + +import java.io.*; +import java.net.*; + +/** + * An example of receiving UDP packets. Since very often both the + * sender and receiver are on the same host we use different ports + * for each. This prevents collision complaints from the localhost. + * + * Start this before launching UdpSender. + * + * @see <a href="https://docs.oracle.com/javase/tutorial/networking/datagrams/index.html" target="_blank">https://docs.oracle.com/javase/tutorial/networking/datagrams/index.html</a> + * @see <a href="https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html" target="_blank">https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html</a> + * @see <a href="https://en.wikipedia.org/wiki/User_Datagram_Protocol" target="_blank">https://en.wikipedia.org/wiki/User_Datagram_Protocol</a> + * @author mcgredo + * @author brutzman@nps.edu + */ +public class UnicastUdpReceiver +{ + /** Default constructor */ + public UnicastUdpReceiver() + { + // default constructor + } +// public static final int SENDING_PORT = 1414; // port used by UdpSender, unneeded here + /** socket value of shared interest */ + public static final int UDP_PORT = 1415; // sharable + /** socket value of shared interest */ + public static final String DESTINATION_HOST = "localhost"; + + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String[] args) + { + DatagramSocket udpSocket = null; + + try + { + System.out.println(UnicastUdpReceiver.class.getName() + " started..."); + + // Create a UDP socket + udpSocket = new DatagramSocket(UDP_PORT); + udpSocket.setReceiveBufferSize(1500); // how many bytes are in buffer? MTU=1500 is good + udpSocket.setBroadcast(false); // we're just receiving here +// udpSocket.setReuseAddress(true); + + byte[] byteArray = new byte[1500]; + DatagramPacket receivePacket = new DatagramPacket(byteArray, byteArray.length); + + ByteArrayInputStream bais = new ByteArrayInputStream(byteArray); + DataInputStream dis = new DataInputStream(bais); + + boolean isEvenParity; + int packetCount = 0; + int firstInt; + float secondFloat; + String thirdString; + String padding; + + // You need a new receiving packet to read from every packet received + while (true) + { + packetCount++; // good practice to increment counter at start of loop, when possible + udpSocket.receive(receivePacket); // blocks until packet is received + + if (packetCount == 1) + { + if (udpSocket.getInetAddress() == null) + System.out.println("UdpReceiver address/port: UDP socket address null (loopback)" + "/" + UDP_PORT); + else System.out.println("UdpReceiver address/port: " + udpSocket.getInetAddress().getHostAddress() + "/" + UDP_PORT); + } + + // values of interest follow. order and types of what was sent must match what you are reading! + firstInt = dis.readInt(); // packetID + secondFloat = dis.readFloat(); + thirdString = dis.readUTF(); // string value with guaranteed encoding, matches UTF-8 is 8 bit + isEvenParity = dis.readBoolean(); // ok, we've gotten everything we're looking for. + + dis.reset(); // now clear the input stream after reading, in preparation for next loop + + if (isEvenParity) + padding = " "; + else padding = ""; + + System.out.println("[" + UnicastUdpReceiver.class.getName() + "]" + + " port=" + UDP_PORT + + " packetID=" + firstInt + // have output message use same name as sender + ", second float value=" + secondFloat + + ", third String value=\"" + thirdString + "\"" + // note that /" is literal quote character + " isPacketIdEvenParity=" + isEvenParity + "," + padding + + " packet counter=" + packetCount); + } + } + catch(IOException e) + { + System.err.println("Problem with UdpReceiver, see exception trace:"); + System.err.println(e); + } + finally // clean up prior to exit, don't want to leave behind zombie socket + { + if (udpSocket != null) + udpSocket.close(); + System.out.println(UnicastUdpReceiver.class.getName() + " complete."); // all done + } + } +} diff --git a/assignments/src/src/UdpExamples/UnicastUdpSender.java b/assignments/src/src/UdpExamples/UnicastUdpSender.java new file mode 100644 index 0000000000000000000000000000000000000000..e7d4daf32708dfa6815fae497003410e3bb1a468 --- /dev/null +++ b/assignments/src/src/UdpExamples/UnicastUdpSender.java @@ -0,0 +1,137 @@ +package UdpExamples; + +import java.io.*; +import java.net.*; + +/** + * An example of sending UDP packets. The sending and receiving programs + * use different UDP ports; there can be problems getting this to work + * if both the sending and receiving sockets try to use the same port + * on the same host. + * + * Start this before launching UdpReceiver. + * + * @see <a href="https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html" target="_blank">https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html</a> + * @see <a href="https://en.wikipedia.org/wiki/User_Datagram_Protocol" target="_blank">https://en.wikipedia.org/wiki/User_Datagram_Protocol</a> + * @see <a href="https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html" target="_blank">System properties</a> + * @author mcgredo + * @author brutzman@nps.edu + */ +public class UnicastUdpSender +{ + /** Default constructor */ + public UnicastUdpSender() + { + // default constructor + } + private static final String MY_NAME = System.getProperty("user.name"); // guru incantation 8) +// public static final int SENDING_PORT = 1414; // not needed, can let system choose an open local port + /** socket value of shared interest */ + public static final int UDP_PORT = UnicastUdpReceiver.UDP_PORT; // 1415; ensure consistent + private static final int TOTAL_PACKETS_TO_SEND = 100; + + /** socket value of shared interest */ + public static final String DESTINATION_HOST = "localhost"; + // here is what we need for lab comms +// public static final String DESTINATION_HOST = "10.1.105.16"; // localhost 127.0.0.1 or argon 10.1.105.1 or 10.1.105.1 or whatever + + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + @SuppressWarnings("SleepWhileInLoop") + public static void main(String[] args) + { + DatagramSocket udpSocket = null; + DataOutputStream dos = null; + int packetID = 0; // counter variable to send in packet + float countdown = -1.0f; // unreachable value is good sentinel to ensure expected changes occur + String message = MY_NAME + " says Hello MV3500"; // no really + String padding = new String(); + + try + { + System.out.println(UnicastUdpSender.class.getName() + " shows how to send simple-type values via DataOutputStream"); + System.out.println(UnicastUdpSender.class.getName() + " started..."); + + // Create a UDP socket + udpSocket = new DatagramSocket(); // let system assign output port, then SENDING_PORT not needed + + // Put together a message with binary content. "ByteArrayOutputStream" + // is a java.io utility that lets us put together an array of binary + // data, which we put into the UDP packet. + + ByteArrayOutputStream baos = new ByteArrayOutputStream(1500); // how many bytes are in buffer? MTU=1500 is good + dos = new DataOutputStream(baos); // wrapper for writing values, connects both streams + + // Put together a packet to send + // these types and order of variables must match on sender and receiver + byte[] byteArray = baos.toByteArray(); + + // ID of the host we are sending to + InetAddress destinationAddress = InetAddress.getByName(DESTINATION_HOST); + // ID of the host we are sending from + InetAddress sourceAddress = InetAddress.getByName("localhost"); // possibly identical if source not modified + + DatagramPacket datagramPacket = new DatagramPacket(byteArray, byteArray.length, destinationAddress, UDP_PORT); + + System.out.println("UdpSender address/port: " + destinationAddress.getHostAddress() + "/" + UDP_PORT); + + // Hmmm, how fast does UDP stream go? Does UDP effectively slow packets down, or does + // this cause network problems? (hint: yes for an unlimited send rate, unlike TCP). + // How do you know on the receiving side that you haven't received a + // duplicate UDP packet, out-of-order packet, or dropped packet? your responsibility. + + for (int index = 1; index <= TOTAL_PACKETS_TO_SEND; index++) // avoid infinite send loops in code, they can be hard to kill! + { + packetID++; // increment counter, prefer using explicit value to index + countdown = TOTAL_PACKETS_TO_SEND - packetID; // countdown from goal total + boolean isPacketIdEvenParity = ((packetID % 2) == 0); // % is modulo operator; result 0 is even parity, 1 is odd parity + + // values of interest follow. order and types of what was sent must match what you are reading! + dos.writeInt (packetID); + dos.writeFloat (countdown); + dos.writeUTF (message); // string value with guaranteed encoding, matches UTF-8 is 8 bit + dos.writeBoolean(isPacketIdEvenParity); + + dos.flush(); // sends DataOutputStream to ByteArrayOutputStream, clearing the buffer + byteArray = baos.toByteArray(); // OK so go get the flushed result... + datagramPacket.setData(byteArray); // and put it in the packet... + udpSocket.send(datagramPacket); // and send it away. boom gone, nonblocking. +// System.out.println("udpSocket output port=" + udpSocket.getLocalPort()); // diagnostic tells what port was chosen by system + + if (isPacketIdEvenParity) + padding = " "; // single blank character as a string of length 1 + else padding = ""; // empty string + + Thread.sleep(100); // Send packets at rate of one per second + System.out.println("[" + UnicastUdpSender.class.getName() + "] " + MY_NAME + " " + sourceAddress + + " port=" + UDP_PORT + + " has sent values (" + packetID + "," + countdown + ",\"" + message + "\"," + isPacketIdEvenParity + + ")" + padding + " as packet #" + index + " of " + TOTAL_PACKETS_TO_SEND); + baos.reset(); // clear the output stream after sending + } // end for loop + } + catch (IOException | InterruptedException e) + { + System.err.println("Problem with UdpSender, see exception trace:"); + System.err.println(e); + } + finally // clean up prior to exit, don't want to leave behind zombies + { + if (udpSocket != null) + udpSocket.close(); + try + { + if (dos != null) + dos.close(); + } + catch (IOException e) + { + System.err.println("Problem with UdpSender, see exception trace:"); + System.err.println(e); + } + System.out.println(UnicastUdpSender.class.getName() + " complete."); // all done + } + } +} diff --git a/assignments/src/src/UdpExamples/UnicastUdpSenderWireshark.png b/assignments/src/src/UdpExamples/UnicastUdpSenderWireshark.png new file mode 100644 index 0000000000000000000000000000000000000000..1f942e7bb96079af5b73e17424c727700e8b6d92 Binary files /dev/null and b/assignments/src/src/UdpExamples/UnicastUdpSenderWireshark.png differ diff --git a/assignments/src/src/UdpExamples/UnicastUdpSenderWiresharkCapture.pcapng b/assignments/src/src/UdpExamples/UnicastUdpSenderWiresharkCapture.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..19954b32a75dc72d76cf4a4f2962870914b89dc5 Binary files /dev/null and b/assignments/src/src/UdpExamples/UnicastUdpSenderWiresharkCapture.pcapng differ diff --git a/assignments/src/src/UdpExamples/UnicastUdpTerminalLog.txt b/assignments/src/src/UdpExamples/UnicastUdpTerminalLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..4299dbbd2e5c33f5714efa39c7f66ee421c0b9e6 --- /dev/null +++ b/assignments/src/src/UdpExamples/UnicastUdpTerminalLog.txt @@ -0,0 +1,336 @@ +These Java program examples read/write strictly typed values (integer, float, string, boolean). + +Invocation instructions: +1. first run/debug UdpReceiver.java so it is listening. +2. then run/debug UdpSender.java + +Program responses follow for sender and receiver: + +=================================================== +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=UdpMulticastExamples/UdpSender.java -Drun.class=UdpMulticastExamples.UdpSender run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +UdpMulticastExamples.UdpSender shows how to send simple-type values via DataOutputStream +UdpMulticastExamples.UdpSender started... +UdpSender address/port: 127.0.0.1/1415 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (1,99.0,"don says Hello MV3500",false) as packet #1 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (2,98.0,"don says Hello MV3500",true) as packet #2 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (3,97.0,"don says Hello MV3500",false) as packet #3 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (4,96.0,"don says Hello MV3500",true) as packet #4 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (5,95.0,"don says Hello MV3500",false) as packet #5 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (6,94.0,"don says Hello MV3500",true) as packet #6 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (7,93.0,"don says Hello MV3500",false) as packet #7 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (8,92.0,"don says Hello MV3500",true) as packet #8 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (9,91.0,"don says Hello MV3500",false) as packet #9 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (10,90.0,"don says Hello MV3500",true) as packet #10 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (11,89.0,"don says Hello MV3500",false) as packet #11 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (12,88.0,"don says Hello MV3500",true) as packet #12 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (13,87.0,"don says Hello MV3500",false) as packet #13 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (14,86.0,"don says Hello MV3500",true) as packet #14 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (15,85.0,"don says Hello MV3500",false) as packet #15 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (16,84.0,"don says Hello MV3500",true) as packet #16 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (17,83.0,"don says Hello MV3500",false) as packet #17 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (18,82.0,"don says Hello MV3500",true) as packet #18 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (19,81.0,"don says Hello MV3500",false) as packet #19 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (20,80.0,"don says Hello MV3500",true) as packet #20 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (21,79.0,"don says Hello MV3500",false) as packet #21 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (22,78.0,"don says Hello MV3500",true) as packet #22 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (23,77.0,"don says Hello MV3500",false) as packet #23 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (24,76.0,"don says Hello MV3500",true) as packet #24 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (25,75.0,"don says Hello MV3500",false) as packet #25 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (26,74.0,"don says Hello MV3500",true) as packet #26 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (27,73.0,"don says Hello MV3500",false) as packet #27 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (28,72.0,"don says Hello MV3500",true) as packet #28 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (29,71.0,"don says Hello MV3500",false) as packet #29 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (30,70.0,"don says Hello MV3500",true) as packet #30 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (31,69.0,"don says Hello MV3500",false) as packet #31 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (32,68.0,"don says Hello MV3500",true) as packet #32 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (33,67.0,"don says Hello MV3500",false) as packet #33 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (34,66.0,"don says Hello MV3500",true) as packet #34 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (35,65.0,"don says Hello MV3500",false) as packet #35 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (36,64.0,"don says Hello MV3500",true) as packet #36 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (37,63.0,"don says Hello MV3500",false) as packet #37 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (38,62.0,"don says Hello MV3500",true) as packet #38 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (39,61.0,"don says Hello MV3500",false) as packet #39 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (40,60.0,"don says Hello MV3500",true) as packet #40 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (41,59.0,"don says Hello MV3500",false) as packet #41 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (42,58.0,"don says Hello MV3500",true) as packet #42 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (43,57.0,"don says Hello MV3500",false) as packet #43 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (44,56.0,"don says Hello MV3500",true) as packet #44 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (45,55.0,"don says Hello MV3500",false) as packet #45 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (46,54.0,"don says Hello MV3500",true) as packet #46 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (47,53.0,"don says Hello MV3500",false) as packet #47 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (48,52.0,"don says Hello MV3500",true) as packet #48 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (49,51.0,"don says Hello MV3500",false) as packet #49 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (50,50.0,"don says Hello MV3500",true) as packet #50 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (51,49.0,"don says Hello MV3500",false) as packet #51 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (52,48.0,"don says Hello MV3500",true) as packet #52 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (53,47.0,"don says Hello MV3500",false) as packet #53 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (54,46.0,"don says Hello MV3500",true) as packet #54 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (55,45.0,"don says Hello MV3500",false) as packet #55 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (56,44.0,"don says Hello MV3500",true) as packet #56 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (57,43.0,"don says Hello MV3500",false) as packet #57 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (58,42.0,"don says Hello MV3500",true) as packet #58 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (59,41.0,"don says Hello MV3500",false) as packet #59 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (60,40.0,"don says Hello MV3500",true) as packet #60 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (61,39.0,"don says Hello MV3500",false) as packet #61 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (62,38.0,"don says Hello MV3500",true) as packet #62 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (63,37.0,"don says Hello MV3500",false) as packet #63 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (64,36.0,"don says Hello MV3500",true) as packet #64 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (65,35.0,"don says Hello MV3500",false) as packet #65 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (66,34.0,"don says Hello MV3500",true) as packet #66 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (67,33.0,"don says Hello MV3500",false) as packet #67 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (68,32.0,"don says Hello MV3500",true) as packet #68 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (69,31.0,"don says Hello MV3500",false) as packet #69 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (70,30.0,"don says Hello MV3500",true) as packet #70 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (71,29.0,"don says Hello MV3500",false) as packet #71 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (72,28.0,"don says Hello MV3500",true) as packet #72 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (73,27.0,"don says Hello MV3500",false) as packet #73 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (74,26.0,"don says Hello MV3500",true) as packet #74 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (75,25.0,"don says Hello MV3500",false) as packet #75 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (76,24.0,"don says Hello MV3500",true) as packet #76 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (77,23.0,"don says Hello MV3500",false) as packet #77 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (78,22.0,"don says Hello MV3500",true) as packet #78 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (79,21.0,"don says Hello MV3500",false) as packet #79 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (80,20.0,"don says Hello MV3500",true) as packet #80 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (81,19.0,"don says Hello MV3500",false) as packet #81 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (82,18.0,"don says Hello MV3500",true) as packet #82 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (83,17.0,"don says Hello MV3500",false) as packet #83 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (84,16.0,"don says Hello MV3500",true) as packet #84 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (85,15.0,"don says Hello MV3500",false) as packet #85 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (86,14.0,"don says Hello MV3500",true) as packet #86 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (87,13.0,"don says Hello MV3500",false) as packet #87 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (88,12.0,"don says Hello MV3500",true) as packet #88 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (89,11.0,"don says Hello MV3500",false) as packet #89 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (90,10.0,"don says Hello MV3500",true) as packet #90 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (91,9.0,"don says Hello MV3500",false) as packet #91 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (92,8.0,"don says Hello MV3500",true) as packet #92 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (93,7.0,"don says Hello MV3500",false) as packet #93 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (94,6.0,"don says Hello MV3500",true) as packet #94 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (95,5.0,"don says Hello MV3500",false) as packet #95 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (96,4.0,"don says Hello MV3500",true) as packet #96 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (97,3.0,"don says Hello MV3500",false) as packet #97 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (98,2.0,"don says Hello MV3500",true) as packet #98 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (99,1.0,"don says Hello MV3500",false) as packet #99 of 100 +[UdpMulticastExamples.UdpSender] don localhost/127.0.0.1 port=1415 has sent values (100,0.0,"don says Hello MV3500",true) as packet #100 of 100 +UdpMulticastExamples.UdpSender complete. +BUILD SUCCESSFUL (total time: 13 seconds) + +=================================================== +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=UdpMulticastExamples/UdpReceiver.java -Drun.class=UdpMulticastExamples.UdpReceiver run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +compile-single: +run-single: +UdpMulticastExamples.UdpReceiver started... +UdpReceiver address/port: UDP socket address null (loopback)/1415 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=1, second float value=99.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=1 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=2, second float value=98.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=2 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=3, second float value=97.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=3 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=4, second float value=96.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=4 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=5, second float value=95.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=5 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=6, second float value=94.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=6 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=7, second float value=93.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=7 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=8, second float value=92.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=8 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=9, second float value=91.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=9 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=10, second float value=90.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=10 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=11, second float value=89.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=11 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=12, second float value=88.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=12 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=13, second float value=87.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=13 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=14, second float value=86.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=14 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=15, second float value=85.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=15 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=16, second float value=84.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=16 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=17, second float value=83.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=17 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=18, second float value=82.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=18 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=19, second float value=81.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=19 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=20, second float value=80.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=20 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=21, second float value=79.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=21 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=22, second float value=78.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=22 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=23, second float value=77.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=23 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=24, second float value=76.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=24 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=25, second float value=75.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=25 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=26, second float value=74.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=26 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=27, second float value=73.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=27 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=28, second float value=72.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=28 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=29, second float value=71.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=29 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=30, second float value=70.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=30 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=31, second float value=69.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=31 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=32, second float value=68.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=32 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=33, second float value=67.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=33 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=34, second float value=66.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=34 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=35, second float value=65.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=35 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=36, second float value=64.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=36 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=37, second float value=63.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=37 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=38, second float value=62.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=38 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=39, second float value=61.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=39 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=40, second float value=60.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=40 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=41, second float value=59.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=41 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=42, second float value=58.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=42 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=43, second float value=57.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=43 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=44, second float value=56.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=44 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=45, second float value=55.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=45 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=46, second float value=54.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=46 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=47, second float value=53.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=47 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=48, second float value=52.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=48 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=49, second float value=51.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=49 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=50, second float value=50.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=50 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=51, second float value=49.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=51 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=52, second float value=48.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=52 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=53, second float value=47.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=53 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=54, second float value=46.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=54 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=55, second float value=45.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=55 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=56, second float value=44.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=56 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=57, second float value=43.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=57 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=58, second float value=42.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=58 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=59, second float value=41.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=59 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=60, second float value=40.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=60 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=61, second float value=39.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=61 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=62, second float value=38.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=62 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=63, second float value=37.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=63 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=64, second float value=36.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=64 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=65, second float value=35.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=65 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=66, second float value=34.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=66 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=67, second float value=33.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=67 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=68, second float value=32.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=68 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=69, second float value=31.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=69 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=70, second float value=30.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=70 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=71, second float value=29.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=71 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=72, second float value=28.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=72 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=73, second float value=27.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=73 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=74, second float value=26.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=74 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=75, second float value=25.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=75 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=76, second float value=24.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=76 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=77, second float value=23.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=77 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=78, second float value=22.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=78 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=79, second float value=21.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=79 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=80, second float value=20.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=80 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=81, second float value=19.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=81 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=82, second float value=18.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=82 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=83, second float value=17.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=83 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=84, second float value=16.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=84 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=85, second float value=15.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=85 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=86, second float value=14.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=86 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=87, second float value=13.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=87 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=88, second float value=12.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=88 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=89, second float value=11.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=89 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=90, second float value=10.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=90 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=91, second float value=9.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=91 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=92, second float value=8.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=92 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=93, second float value=7.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=93 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=94, second float value=6.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=94 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=95, second float value=5.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=95 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=96, second float value=4.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=96 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=97, second float value=3.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=97 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=98, second float value=2.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=98 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=99, second float value=1.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=99 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=100, second float value=0.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=100 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=1, second float value=99.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=101 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=2, second float value=98.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=102 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=3, second float value=97.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=103 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=4, second float value=96.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=104 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=5, second float value=95.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=105 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=6, second float value=94.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=106 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=7, second float value=93.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=107 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=8, second float value=92.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=108 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=9, second float value=91.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=109 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=10, second float value=90.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=110 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=11, second float value=89.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=111 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=12, second float value=88.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=112 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=13, second float value=87.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=113 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=14, second float value=86.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=114 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=15, second float value=85.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=115 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=16, second float value=84.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=116 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=17, second float value=83.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=117 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=18, second float value=82.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=118 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=19, second float value=81.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=119 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=20, second float value=80.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=120 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=21, second float value=79.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=121 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=22, second float value=78.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=122 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=23, second float value=77.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=123 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=24, second float value=76.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=124 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=25, second float value=75.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=125 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=26, second float value=74.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=126 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=27, second float value=73.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=127 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=28, second float value=72.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=128 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=29, second float value=71.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=129 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=30, second float value=70.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=130 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=31, second float value=69.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=131 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=32, second float value=68.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=132 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=33, second float value=67.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=133 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=34, second float value=66.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=134 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=35, second float value=65.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=135 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=36, second float value=64.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=136 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=37, second float value=63.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=137 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=38, second float value=62.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=138 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=39, second float value=61.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=139 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=40, second float value=60.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=140 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=41, second float value=59.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=141 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=42, second float value=58.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=142 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=43, second float value=57.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=143 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=44, second float value=56.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=144 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=45, second float value=55.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=145 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=46, second float value=54.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=146 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=47, second float value=53.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=147 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=48, second float value=52.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=148 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=49, second float value=51.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=149 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=50, second float value=50.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=150 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=51, second float value=49.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=151 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=52, second float value=48.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=152 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=53, second float value=47.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=153 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=54, second float value=46.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=154 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=55, second float value=45.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=155 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=56, second float value=44.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=156 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=57, second float value=43.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=157 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=58, second float value=42.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=158 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=59, second float value=41.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=159 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=60, second float value=40.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=160 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=61, second float value=39.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=161 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=62, second float value=38.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=162 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=63, second float value=37.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=163 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=64, second float value=36.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=164 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=65, second float value=35.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=165 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=66, second float value=34.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=166 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=67, second float value=33.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=167 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=68, second float value=32.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=168 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=69, second float value=31.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=169 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=70, second float value=30.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=170 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=71, second float value=29.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=171 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=72, second float value=28.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=172 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=73, second float value=27.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=173 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=74, second float value=26.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=174 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=75, second float value=25.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=175 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=76, second float value=24.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=176 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=77, second float value=23.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=177 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=78, second float value=22.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=178 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=79, second float value=21.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=179 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=80, second float value=20.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=180 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=81, second float value=19.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=181 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=82, second float value=18.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=182 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=83, second float value=17.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=183 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=84, second float value=16.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=184 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=85, second float value=15.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=185 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=86, second float value=14.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=186 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=87, second float value=13.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=187 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=88, second float value=12.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=188 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=89, second float value=11.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=189 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=90, second float value=10.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=190 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=91, second float value=9.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=191 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=92, second float value=8.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=192 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=93, second float value=7.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=193 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=94, second float value=6.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=194 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=95, second float value=5.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=195 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=96, second float value=4.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=196 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=97, second float value=3.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=197 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=98, second float value=2.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=198 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=99, second float value=1.0, third String value="don says Hello MV3500" isPacketIdEvenParity=false, packet counter=199 +[UdpMulticastExamples.UdpReceiver]port=1415 packetID=100, second float value=0.0, third String value="don says Hello MV3500" isPacketIdEvenParity=true, packet counter=200 + +=================================================== \ No newline at end of file diff --git a/assignments/src/src/UdpExamples/package-info.java b/assignments/src/src/UdpExamples/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..ba08cb901d79834a505154495a7e2d0536d03678 --- /dev/null +++ b/assignments/src/src/UdpExamples/package-info.java @@ -0,0 +1,10 @@ +/** + * UDP Multicast Examples supporting the NPS MOVES MV3500 Networked Graphics course. + * + * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples" target="blank">NetworkedGraphicsMV3500 examples</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 UdpExamples; diff --git a/assignments/src/src/overview.html b/assignments/src/src/overview.html new file mode 100644 index 0000000000000000000000000000000000000000..6934f6486fdc55ff3e6da9d143d70624290f00d9 --- /dev/null +++ b/assignments/src/src/overview.html @@ -0,0 +1,50 @@ +<html> + <!-- this page is used as part of javadoc autogeneration --> + <body> + + <h1> Course Resources </h1> + <p> + <!-- Note that javadoc throws an incorrect error regarding title attribute, but resulting HTML works as expected --> + <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/README.md" target="_blank" title="Open-Dis Surfer Dude, Thanks Don McGregor!"><img src="OpenDisSurferDude.png" alt="Open-Dis Surfer Dude, Thanks Don McGregor!" style="float:right"/></a> + <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/assignments" target="_blank">Assignments</a>, + <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples" target="_blank">examples</a>, and + <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/presentations" target="_blank">presentations</a> + are provided in + <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500" target="_blank">MV3500 Distributed Simulation Fundamentals</a> + course archive by the + <a href="https://www.nps.edu/web/moves" target="_blank">Modeling, Virtual Environments, Simulation (MOVES) Institute</a> + of the + <a href="https://www.nps.edu" target="_blank">Naval Postgraduate School (NPS)</a>. + </p> + <p> + <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/MV3500DistributedSimulationSyllabus2024JulySeptember.pdf" target="_blank">MV3500 Course Syllabus</a> + provides a hands-on programming introduction to distributed communications in simulation applications. + </p> + + <h1> References </h1> + + <ul> + <li> + The + <a href="https://github.com/open-dis/opendis7-java" target="_blank">opendis7-java</a> + library provides a complete type-safe Java implementation of both + the DIS Protocol version 7 (IEEE 1278.1-2012) and SISO-REF-010 Enumerations specifications, + interfaces and objects, all as open source. + </li> + <li> + <a href="https://savage.nps.edu/Savage/developers.html" target="_blank">Savage Developers Guide</a> + describes system configuration supporting various software projects by the NPS MOVES Savage Research Group. + </li> + <li> + <a href="https://wireshark.org" target="_blank">Wireshark</a> network protocol analyzer, + and + <a href="https://www.youtube.com/watch?v=TkCSr30UojM" target="_blank">Wireshark Tutorial for Beginners video</a> by Anson Alexander + </li> + </ul> + <p> + This project Javadoc documentation is maintained online as part of + <a href="https://savage.nps.edu/opendis7-java" target="_blank">opendis7-java Distribution Products</a>. + </p> + + </body> +</html> \ No newline at end of file