Skip to content
Snippets Groups Projects
Commit 1ad5a2ff authored by jojot's avatar jojot
Browse files

Homework2 Tam

parent 1b9ea499
No related branches found
No related tags found
No related merge requests found
/**
* 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 MV3500Cohort2022MayJune.homework2.Tam;
import static MV3500Cohort2022MayJune.homework2.Tam.ExampleSimulationProgramTam.TRACE_PREFIX;
import static MV3500Cohort2022MayJune.homework2.Tam.ExampleSimulationProgramTam.thisProgram;
import edu.nps.moves.dis7.entities.swe.platform.surface._001Poseidon;
import edu.nps.moves.dis7.enumerations.ForceID;
import edu.nps.moves.dis7.pdus.EntityStatePdu;
import edu.nps.moves.dis7.pdus.Pdu;
import edu.nps.moves.dis7.pdus.Vector3Double;
import edu.nps.moves.dis7.utilities.DisTime;
import edu.nps.moves.dis7.utilities.stream.X3dCreateInterpolators;
import edu.nps.moves.dis7.utilities.stream.X3dCreateLineSet;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* 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">ExampleTrackInterpolationLog.txt</a>
* @see <a href="https://calhoun.nps.edu/handle/10945/65436">REPEATABLE UNIT TESTING OF DISTRIBUTED INTERACTIVE SIMULATION (DIS) PROTOCOL BEHAVIOR STREAMS USING WEB STANDARDS</a> by Tobias Brennenstuhl, Masters Thesis, Naval Postgraduate School (NPS), June 2020
* @see <a href="https://gitlab.nps.edu/Savage/SavageTheses/-/tree/master/BrennenstuhlTobias">https://gitlab.nps.edu/Savage/SavageTheses/-/tree/master/BrennenstuhlTobias</a>
*/
public class ExampleTrackInterpolationTam extends ExampleSimulationProgramTam
{
// -------------------- 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();
simulationTime = initialTime - currentTimeStep; // pre-initialization for first loop
initializeSimulationEntities();
// use declared PDU objects and set their values.
entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID;
// TODO someday, use enumerations; is there a unique site triplet for MOVES Institute?
pduRecorder.setVerbose(false);
pduRecorder.hasVerboseOutput(); // debug check
EntityStatePdu espdu_1 = pduFactory.makeEntityStatePdu();
espdu_1.setEntityID(entityID_1);
espdu_1.setForceId(ForceID.FRIENDLY);
espdu_1.setEntityType(new _001Poseidon()); // note import statement above
espdu_1.setMarking("track path");
// espdu_1.clearMarking(); // test
// espdu_1.getMarkingString(); // trace
// espdu_1.setEntityLocation(new Vector3Double().setX(0).setY(0).setZ(0)); // long form
espdu_1.setEntityLocation(0, 0, 0); // utility method
float speedEntity_1 = 1.0f; // meters/second
EntityStatePdu.Direction directionEntity_1 = EntityStatePdu.Direction.NORTH;
PduTrack pduTrack_1 = new PduTrack();
pduTrack_1.setDescriptor("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 (pduRecorder.hasVerboseOutput())
System.out.println("sending PDUs for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent");
sendSinglePdu(espdu_1);
// sendCommentPdu(currentTimeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
pduSentList.add(espdu_1);
reportPdu(simulationLoopCount, espdu_1.getEntityLocation(), directionEntity_1);
// TODO simulation management PDUs for startup, planning to design special class support
// ===================================================================================================
// loop the simulation while allowed, programmer can set additional conditions to break out and finish
while (simulationLoopCount < SIMULATION_MAX_LOOP_COUNT) // are we done yet?
{
simulationLoopCount++; // good practice: increment loop counter as first action in that loop
simulationTime += currentTimeStep; // good practice: update clock along with loop index
// =============================================================================================
// * your own simulation code starts here! *
// =============================================================================================
// are there any other variables to modify at the beginning of your loop?
// compute a track, update an ESPDU, whatever it is that your model is doing...
// Pick direction, change each 10 seconds, traverse a box. No physics. Walk a box!
if (simulationLoopCount <= 10)
directionEntity_1 = EntityStatePdu.Direction.NORTH;
else if (simulationLoopCount <= 20)
directionEntity_1 = EntityStatePdu.Direction.EAST;
else if (simulationLoopCount <= 30)
directionEntity_1 = EntityStatePdu.Direction.SOUTH;
else // if (simulationLoopCount <= 40)
directionEntity_1 = EntityStatePdu.Direction.WEST;
// use utility method to simply update velocity vector using speed value and direction
espdu_1.setEntityLinearVelocity(speedEntity_1, directionEntity_1);
// Where is my entity? Insert changes in position; this sample only changes X position.
espdu_1.advanceEntityLocation(currentTimeStep);
// make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending)
narrativeMessage1 = "MV3500 TrackSimulationProgram";
narrativeMessage2 = "runSimulation() loop " + simulationLoopCount + " at time " + simulationTime;
narrativeMessage3 = ""; // intentionally blank for testing
// your loop termination condition goes here
if (simulationLoopCount > 40) // for example
{
simulationComplete = true;
}
// =============================================================================================
// * your own simulation code is finished here! *
// =============================================================================================
// staying synchronized with timestep: wait duration for elapsed time in this loop
// Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes
if (false) // real-time operation or simulation speedup
{
Thread.sleep((long) (currentTimeStep * 1000)); // seconds * (1000 msec/sec) = milliseconds
System.out.println(TRACE_PREFIX + "Pausing for " + currentTimeStep + " seconds");
}
// OK now send the status PDUs for this loop, and then continue
if (pduRecorder.hasVerboseOutput())
System.out.println("sending PDUs for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent");
sendSinglePdu(espdu_1);
sendCommentPdu(currentTimeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
if (pduRecorder.hasVerboseOutput())
System.out.println(TRACE_PREFIX + "PDUs successfully sent for this loop");
pduSentList.add(espdu_1);
pduTrack_1.addPdu(espdu_1);
Vector3Double location = espdu_1.getEntityLocation();
reportPdu(simulationLoopCount, location, directionEntity_1);
// ===============================
// current loop now finished, check whether to terminate if simulation complete, otherwise continue
if (simulationComplete || (simulationLoopCount > 10000)) // for example; including fail-safe condition is good
{
System.out.println(TRACE_PREFIX + "loop termination condition met, simulationComplete=" + simulationComplete); // ", final loopCount=" + loopCount +
break;
}
} // end of simulation loop
// ===================================================================================================
System.out.println(TRACE_PREFIX + "all PDUs successfully sent for this loop (pduSentList.size()=" + pduSentList.size() + " total)");
// track analysis
System.out.println(TRACE_PREFIX + "pduTrack_1 initialLocation=" + pduTrack_1.getInitialLocation() + ", latestLocation=" + pduTrack_1.getLatestLocation());
pduTrack_1.sortPdus()
.createRawWaypoints();
System.out.println("pduTrack_1 getEspduCount()=" + pduTrack_1.getEspduCount());
System.out.println("pduTrack_1 duration = " + pduTrack_1.getTotalDurationSeconds() + " seconds = " +
pduTrack_1.getTotalDurationTicks() + " ticks");
System.out.println("=================================");
System.out.println(pduTrack_1.createX3dModel());
System.out.println("=================================");
narrativeMessage2 = "runSimulation() completed successfully"; // all done
sendCommentPdu(narrativeComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
if (pduRecorder.hasVerboseOutput())
System.out.println(TRACE_PREFIX + "final CommentPdu successfully sent for simulation");
// TODO simulation management PDUs
}
catch (InterruptedException iex) // handle any exception that your code might choose to provoke!
{
Logger.getLogger(ExampleTrackInterpolationTam.class.getName()).log(Level.SEVERE, null, iex);
}
}
/**
* Report current PDU information to console
* @param simulationLoopCount current loop index
* @param location current location
* @param directionEntity current direction
* @return same object to permit progressive setters
*/
public ExampleTrackInterpolationTam reportPdu(int simulationLoopCount, Vector3Double location, EntityStatePdu.Direction directionEntity)
{
System.out.println (String.format("%2d ", simulationLoopCount) + "Entity location=(" +
String.format("%4.1f", location.getX()) + ", " +
String.format("%4.1f", location.getY()) + ", " +
String.format("%4.1f", location.getZ()) + ") " +
String.format("%-5s", directionEntity.name())
// + " " + espdu_1.getEntityLinearVelocity().toString()
);
return this;
}
/* Default constructors used unless otherwise defined/overridden. */
/**
* Main method is first executed when a program instance is loaded.
*
* @see
* <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java
* Tutorials: A Closer Look at the "Hello World!" Application</a>
* @param args command-line arguments are an array of optional String
* parameters that are passed from execution environment during invocation
*/
public static void main(String[] args)
{
TRACE_PREFIX = "[" + ExampleTrackInterpolationTam.class.getName() + "] ";
System.out.println(TRACE_PREFIX + "main() started...");
thisProgram = new ExampleTrackInterpolationTam(); // creates instance of self within static main() method
thisProgram.handleArgs (args); // process command-line invocation arguments
thisProgram.setUpNetworkInterface();
thisProgram.pduRecorder.setDescriptor (TRACE_PREFIX.replace("[","").replace("]","") + " pduRecorder");
thisProgram.pduRecorder.setVerbose(false);
thisProgram.setVerboseComments(false);
thisProgram.disNetworkInterface.setVerbose(false);
thisProgram.runSimulationLoops(); // ... your simulation execution code goes in there ...
thisProgram.tearDownNetworkInterface(); // make sure no processes are left lingering
System.out.println(TRACE_PREFIX + "complete."); // report successful completion
System.exit(0); // ensure all threads and sockets released
}
}
This diff is collapsed.
package MV3500Cohort2022MayJune.homework2.Tam;
import MV3500Cohort2022MayJune.homework2.Duran.*;
import MV3500Cohort2021JulySeptember.homework2.Domonique.*;
import java.io.*;
import java.net.*;
/**
*
* @author Johanna Tam
*/
public class TamTcpExampleClient {
/** IPv6 String constant for localhost address, similarly IPv4 127.0.0.1
* @see <a href="https://en.wikipedia.org/wiki/localhost">https://en.wikipedia.org/wiki/localhost</a>
* @see <a href="https://en.wikipedia.org/wiki/IPv6_address">https://en.wikipedia.org/wiki/IPv6_address</a>
*/
public final static String LOCALHOST = "0:0:0:0:0:0:0:1";
/**
* Program invocation, execution starts here
* @param args command-line arguments
* @throws java.lang.InterruptedException user can cancel execution
*/
public static void main(String[] args) throws InterruptedException {
// 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(TamTcpExampleClient.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); // locohost?
// 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("I am hungry");
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 e)
{
System.err.println("Problem with " + TamTcpExampleClient.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(TamTcpExampleClient.class.getName() + " exit");
}
}
}
\ No newline at end of file
package MV3500Cohort2022MayJune.homework2.Tam;
import MV3500Cohort2022MayJune.homework2.Duran.*;
import MV3500Cohort2021JulySeptember.homework2.Domonique.*;
import java.io.*;
import java.net.*;
/**
* homework assignment
* @author Johanna Tam
*/
public class TamTcpExampleServer {
/**
* 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(TamTcpExampleServer.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("okay " + serverLoopCount + " let's go to Starbucks"); // 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(TamTcpExampleServer.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 " + TamTcpExampleServer.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!");
}
}
}
}
/**
* ExampleSimpleSimulation program-modification homework assignment supporting the NPS MOVES MV3500 Networked Graphics course.
*
* @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/assignments">networkedGraphicsMV3500 assignments</a>
* @see java.lang.Package
* @see <a href="https://stackoverflow.com/questions/22095487/why-is-package-info-java-useful">StackOverflow: why-is-package-info-java-useful</a>
* @see <a href="https://stackoverflow.com/questions/624422/how-do-i-document-packages-in-java">StackOverflow: how-do-i-document-packages-in-java</a>
*/
package MV3500Cohort2022MayJune.homework2.Tam;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment