diff --git a/README.md b/README.md
index 9c83be98c36ce1c4319ff61cfa7f27536988f3ec..d99536a4c350ccedad44744983116c7ef771b29b 100644
--- a/README.md
+++ b/README.md
@@ -12,5 +12,6 @@ References and Resources:
 and [Video of Cloning a Git Repository Using NetBeans IDE](https://netbeans.org/kb/docs/ide/git_nb_ssh_screencast.html)
 * [Open-DIS Repository](https://github.com/open-dis) and [Distributed Interactive Simulation: The Missing Handbook](https://github.com/open-dis/DISTutorial/blob/master/README.md)
 * [Savage Developers Guide](https://savage.nps.edu/Savage/developers.html) resources for [DIS](https://savage.nps.edu/Savage/developers.html#DIS)
+* UML [Sequence diagram](https://en.wikipedia.org/wiki/Sequence_diagram) on Wikipedia
 * [WireShark](https://wireshark.org) and [WireShark Tutorial for Beginners](https://www.youtube.com/watch?v=TkCSr30UojM) video by Anson Alexander
 * [X3D-Edit](https://savage.nps.edu/X3D-Edit/#Downloads) as Netbeans Plugin
diff --git a/presentations/09_HLA_HighLevelArchitecture.pptx b/presentations/09_HLA_HighLevelArchitecture.pptx
index 3c7efffca499febbd720e46c6b766c64aefbc861..6a19d4ea663354f688775d541479c1f1cef11f3a 100644
Binary files a/presentations/09_HLA_HighLevelArchitecture.pptx and b/presentations/09_HLA_HighLevelArchitecture.pptx differ
diff --git a/presentations/IITSEC2018_DIS_Tutorial.pptx b/presentations/IITSEC2018_DIS_Tutorial.pptx
index 3d25c67bb2d5a410c1c16a5af53b84b25566f815..be15c3c31a68a11db10a599b62e3dec773641976 100644
Binary files a/presentations/IITSEC2018_DIS_Tutorial.pptx and b/presentations/IITSEC2018_DIS_Tutorial.pptx differ
diff --git a/projects/Assignments/AngelBlankFP/EspduReceiverB.java b/projects/Assignments/AngelBlankFP/EspduReceiverB.java
deleted file mode 100644
index d63205138f4f44350d34f10611df6edea73d58fd..0000000000000000000000000000000000000000
--- a/projects/Assignments/AngelBlankFP/EspduReceiverB.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package java.edu.nps.moves.examples;
-
-import java.net.*;
-import java.util.*;
-
-import edu.nps.moves.disutil.*;
-
-import edu.nps.moves.dis.*;
-
-/**
- * Receives PDUs from the network in IEEE format.
- *
- * @author DMcG
- * @version $Id:$
- */
-public class EspduReceiverB {
-
-    /** 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
-     */
-    public static final int MAX_PDU_SIZE = 8192;
-
-    public static void main(String args[]) {
-        MulticastSocket socket;
-        DatagramPacket packet;
-        InetAddress address;
-        PduFactory pduFactory = new PduFactory();
-
-        try {
-            // Specify the socket to receive data
-            socket = new MulticastSocket(3001);
-            socket.setBroadcast(true);
-       
-            //address = InetAddress.getByName(EspduSender.DEFAULT_MULTICAST_GROUP);
-            //socket.joinGroup(address);
-
-            // Loop infinitely, receiving datagrams
-            while (true) {
-                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 it = pduBundle.iterator();
-
-                while(it.hasNext())
-                {
-                    Pdu aPdu = (Pdu)it.next();
-                
-                    System.out.print("got PDU of type: " + aPdu.getClass().getName());
-                    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 (Exception e) {
-
-            System.out.println(e);
-        }
-
-
-    } // end main
-} // end class
diff --git a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduReceiverA.java b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduReceiverA.java
deleted file mode 100644
index 1f815104f01f0d88ed010bd8b6b79bef5fca751c..0000000000000000000000000000000000000000
--- a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduReceiverA.java
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-import java.net.*;
-import java.util.*;
-
-import edu.nps.moves.disutil.*;
-import edu.nps.moves.dis.*;
-
-/**
- * Receives PDUs from the network in IEEE format.
- *
- * @author DMcG
- * @version $Id:$
- */
-public class ABEspduReceiverA {
-
-    /** 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
-     */
-    public static final int MAX_PDU_SIZE = 8192;
-    public static final String GROUP = "239.1.2.3";
-    public static void main(String args[]) {
-        MulticastSocket socket;
-        DatagramPacket packet;
-        InetAddress address;
-        PduFactory pduFactory = new PduFactory();
-        
-        
-
-        try {
-            // Create TCP Bridge
-             ServerSocket serverSocket = new ServerSocket(2999);
-            
-            
-            
-            // Specify the socket to receive data
-            socket = new MulticastSocket(3000);
-            socket.setBroadcast(true);
-       
-            address = InetAddress.getByName(GROUP);
-            socket.joinGroup(address);
-
-            // Loop infinitely, receiving datagrams
-            while (true) {
-                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 it = pduBundle.iterator();
-
-                while(it.hasNext())
-                {
-                    Pdu aPdu = (Pdu)it.next();
-                
-                    System.out.print("got PDU of type: " + aPdu.getClass().getName());
-                    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 (Exception e) {
-
-            System.out.println(e);
-        }
-
-
-    } // end main
-} // end class
diff --git a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduReceiverB.java b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduReceiverB.java
deleted file mode 100644
index 06765cff1fb730a62a921e66532c29df7acf3549..0000000000000000000000000000000000000000
--- a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduReceiverB.java
+++ /dev/null
@@ -1,122 +0,0 @@
-
-
-
-import java.net.*;
-import java.util.*;
-
-import edu.nps.moves.disutil.*;
-import edu.nps.moves.dis.*;
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
-
-/**
- * Receives PDUs from the network in IEEE format.
- *
- * @author DMcG
- * @version $Id:$
- */
-public class ABEspduReceiverB {
-
-    /** 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
-     */
-    public static final int MAX_PDU_SIZE = 8192;
-    
-    public static final String GROUP = "239.1.2.4";
-
-    public static void main(String args[]) {
-        MulticastSocket socket;
-        DatagramPacket packet;
-        InetAddress address;
-        PduFactory pduFactory = new PduFactory();
-
-        try {
-            // Specify the socket to receive data
-            socket = new MulticastSocket(3101);
-            socket.setBroadcast(true);
-            int connectionCount = 0;
-            ServerSocket serverSocket = new ServerSocket(2999);
-            Socket clientConnection = serverSocket.accept();
-            
-            InputStream is = clientConnection.getInputStream();
-            InputStreamReader isr = new InputStreamReader(is);
-            BufferedReader br = new BufferedReader(isr);
-
-            address = InetAddress.getByName(GROUP);
-            socket.joinGroup(address);
-
-            // Loop infinitely, receiving datagrams
-            while (true) {
-                byte buffer[] = new byte[MAX_PDU_SIZE];
-                packet = new DatagramPacket(buffer, buffer.length);
-
-                socket.receive(packet);
-                
-                //OutputStream os = clientConnection.getOutputStream();
-               // PrintStream ps = new PrintStream(os);
-               // connectionCount++;
-               // ps.println("This was written by the server");
-                
-               
-           
-                String serverMessage = br.readLine();
-                System.out.println("The message the client sent was " + serverMessage);
-                
-                // 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();
-                
-                // 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("Socket pair: (( " + localAddress.toString() + ", " + localPort + " ), ( " + 
-                        remoteAddress.toString() + ", " + remotePort + " ))");
-                
-                System.out.println("Connection count is: " + connectionCount);
-
-                List<Pdu> pduBundle = pduFactory.getPdusFromBundle(packet.getData());
-                System.out.println("Bundle size is " + pduBundle.size());
-                
-                Iterator it = pduBundle.iterator();
-                
-                
-
-                while(it.hasNext())
-                {
-                    Pdu aPdu = (Pdu)it.next();
-                
-                    System.out.print("got PDU of type: " + aPdu.getClass().getName());
-                    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 (Exception e) {
-
-            System.out.println(e);
-        }
-
-
-    } // end main
-} // end class
diff --git a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduSenderB.java b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduSenderB.java
deleted file mode 100644
index e488ead683af89f2bed4f937ba3d162110e698a2..0000000000000000000000000000000000000000
--- a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduSenderB.java
+++ /dev/null
@@ -1,331 +0,0 @@
-
-
-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. 
- *
- * @author DMcG
- */
-public class ABEspduSenderB 
-{
-    public static final int NUMBER_TO_SEND = 5000;
-
-    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
-
-    /** default multicast group we send on */
-    public static final String DEFAULT_MULTICAST_GROUP = "239.1.2.4";
-   
-    /** Port we send on */
-    public static final int    DIS_DESTINATION_PORT = 3101;
-    
-/** 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 mcast.
-     *                To determine bcast destination IP, use an online bcast address
-     *                caclulator, for example http://www.remotemonitoringsystems.ca/broadcast.php
-     *                If in mcast mode, a join() will be done on the mcast address.
-     * port: port used for both source and destination.
-     * @param args 
-     */
-public static void main(String args[])
-{
-    /** an entity state pdu */
-    EntityStatePdu espdu = new EntityStatePdu();
-    MulticastSocket socket = null;
-    DisTime disTime = DisTime.getInstance();
-    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 = DIS_DESTINATION_PORT;
-    NetworkMode mode = NetworkMode.MULTICAST;
-    InetAddress destinationIp = null;
-    
-    try
-    {
-        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
-    }
-    catch(Exception 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)
-            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
-        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);
-                
-            }
-        } // end networkModeString
-    }
-    catch(Exception 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 eid = espdu.getEntityID();
-    eid.setSite(1);  // 0 is apparently not a valid site number, per the spec
-    eid.setApplication(1); 
-    eid.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> bcastAddresses = getBroadcastAddresses();
-    // Loop through sending N ESPDUs
-    try
-    {
-        System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
-        for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
-        {
-            // DIS time is a pain in the ass. 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 ts = disTime.getDisAbsoluteTimestamp();
-            espdu.setTimestamp(ts);
-            
-            // 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)(idx));
-            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();
-
-            bcastAddresses = getBroadcastAddresses();
-            Iterator it = bcastAddresses.iterator();
-            while(it.hasNext())
-            {
-               InetAddress bcast = (InetAddress)it.next();
-               System.out.println("Sending bcast to " + bcast);
-               DatagramPacket packet = new DatagramPacket(data, data.length, bcast, 3000);
-               socket.send(packet);
-               packet = new DatagramPacket(fireArray, fireArray.length, bcast, 3000);
-               //socket.send(packet);
-            }
-            
-            // Send every 1 sec. Otherwise this will be all over in a fraction of a second.
-            Thread.sleep(3000);
-
-            location = espdu.getEntityLocation();
-            
-            System.out.println("Espdu #" + idx + " EID=[" + eid.getSite() + "," + eid.getApplication() + "," + eid.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);
-//            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
-
-        }
-    }
-    catch(Exception e)
-    {
-        System.out.println(e);
-    }
-    
-    
-    
-   
-        
-    }
-    
-    
-    
-
-
- /**
-    * A number of sites get all snippy about using 255.255.255.255 for a bcast
-    * address; it trips their security software and they kick you off their 
-    * network. (Comcast, NPS.) This determines the bcast address for all
-    * connected interfaces, based on the IP and subnet mask. If you have
-    * a dual-homed host it will return a bcast address for both. If you have
-    * some VMs running on your host this will pick up the addresses for those
-    * as well--eg 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 bcast addresses
-    */
-   public static Set<InetAddress> getBroadcastAddresses()
-   {
-       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
-       Enumeration interfaces;
-       
-       try
-       {
-           interfaces = NetworkInterface.getNetworkInterfaces();
-           
-           while(interfaces.hasMoreElements())
-           {
-               NetworkInterface anInterface = (NetworkInterface)interfaces.nextElement();
-               
-               if(anInterface.isUp())
-               {
-                   Iterator it = anInterface.getInterfaceAddresses().iterator();
-                   while(it.hasNext())
-                   {
-                       InterfaceAddress anAddress = (InterfaceAddress)it.next();
-                       if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
-                           continue;
-                       
-                       //System.out.println("Getting bcast address for " + anAddress);
-                       InetAddress abcast = anAddress.getBroadcast();
-                       if(abcast != null)
-                        bcastAddresses.add(abcast);
-                   }
-               }
-           }
-           
-       }
-       catch(Exception e)
-       {
-           e.printStackTrace();
-           System.out.println(e);
-       }
-       
-       return bcastAddresses;   
-   }
-
-}
diff --git a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduReceiverAtoTCP.java b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduReceiverAtoTCP.java
new file mode 100644
index 0000000000000000000000000000000000000000..113dbe0c7ccc86e3f7a8ecb97713966a477fdefd
--- /dev/null
+++ b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduReceiverAtoTCP.java
@@ -0,0 +1,97 @@
+
+import java.net.*;
+import java.util.*;
+
+import edu.nps.moves.disutil.*;
+import edu.nps.moves.dis.*;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+
+/**
+ * Receives PDUs from the network creates a TCP connection, then 
+ * sends information to through the connection.
+ *
+ * @author Angelopoulos/Blankenbeker
+ * @version 8 MAR 2018
+ */
+public class AngelBlankEspduReceiverAtoTCP {
+
+    public static final String TCP_DESTINATION_IP = "172.20.146.111";
+    public static final int DIS_DESTINATION_PORT = 3000;
+    public static final int TCP_DESTINATION_PORT = 2999;
+    public static final int MAX_PDU_SIZE = 8192;
+    public static final String GROUP = "239.1.2.4";
+    
+    public static void main(String args[]) {
+        MulticastSocket socket;
+        DatagramSocket dataGram;
+        DatagramPacket packet;
+        InetAddress address;
+        PduFactory pduFactory = new PduFactory();
+        try {
+            // Specify the socket to receive data
+            socket = new MulticastSocket(DIS_DESTINATION_PORT);
+            socket.setBroadcast(true);
+       
+            address = InetAddress.getByName(GROUP);
+            socket.joinGroup(address);
+            
+            //System.out.println("Joined Group.");
+            // Loop infinitely, receiving datagrams
+            while (true) {
+                try
+                {
+
+                    byte buffer[] = new byte[MAX_PDU_SIZE];
+                    packet = new DatagramPacket(buffer, buffer.length);
+
+                    socket.receive(packet);
+                    //System.out.println("Packet Received");
+
+                    List<Pdu> pduBundle = pduFactory.getPdusFromBundle(packet.getData());
+                    //System.out.println("Bundle size is " + pduBundle.size());
+
+                    Iterator it = pduBundle.iterator();
+
+                    while(it.hasNext())
+                    {
+                        Pdu aPdu = (Pdu)it.next();
+
+                       // System.out.print("got PDU of type: " + aPdu.getClass().getName());
+                        if(aPdu instanceof EntityStatePdu)
+                        {
+
+                            EntityID eid = ((EntityStatePdu)aPdu).getEntityID();
+                            if (eid.getSite() == 100)
+                            {
+                                dataGram = new DatagramSocket();
+                                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                                DataOutputStream dos = new DataOutputStream(baos);  
+                                aPdu.marshal(dos);
+                                byte[] data = baos.toByteArray();
+                                
+                                DatagramPacket DpSend =  new DatagramPacket(data, data.length,  InetAddress.getByName(TCP_DESTINATION_IP), TCP_DESTINATION_PORT);
+                                dataGram.send(DpSend);
+                                System.out.println("Alpha Bridging Complete to: " + TCP_DESTINATION_IP);
+                                //EntityType entityType = ((EntityStatePdu)aPdu).getEntityType();
+                            }
+                            Vector3Double location = ((EntityStatePdu)aPdu).getEntityLocation();
+                            System.out.print(" EID:[" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "] ");
+                            //System.out.print(" Location in DIS coordinates: [" + location.getX() + ", " + location.getY() + ", " + location.getZ() + "]");
+                            double c[] = {location.getX(), location.getY(), location.getZ()};
+                            double lla[] = CoordinateConversions.xyzToLatLonDegrees(c);
+                            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
+                        }
+                        System.out.println();
+                    } // end trop through PDU bundle
+                }
+                catch (Exception e) {
+                    System.out.println(e);
+                }
+            } // end while
+        } // End try
+        catch (Exception e) {
+            System.out.println(e);
+        }
+    } // end main
+} // end class
diff --git a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduReceiverBtoTCP.java b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduReceiverBtoTCP.java
new file mode 100644
index 0000000000000000000000000000000000000000..eddb89e2ff145359a7a397777881227351dee63b
--- /dev/null
+++ b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduReceiverBtoTCP.java
@@ -0,0 +1,88 @@
+
+import java.net.*;
+import java.util.*;
+
+import edu.nps.moves.disutil.*;
+import edu.nps.moves.dis.*;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+
+
+/**
+ * Receives PDUs from the network in IEEE format and creates a TCP connection, 
+ * then sends information through the connection.
+ *
+ * @author Angelopoulos/Blankenbeker
+ * @version 8 MAR 2018
+ */
+public class AngelBlankEspduReceiverBtoTCP {
+
+    public static final String TCP_DESTINATION_IP = "172.20.144.187";
+    public static final int DIS_DESTINATION_PORT = 2800;
+    public static final int TCP_DESTINATION_PORT = 2998;
+    public static final int MAX_PDU_SIZE = 8192;
+    public static final String GROUP = "239.1.2.3";
+    public static void main(String args[]) {
+        MulticastSocket socket;
+        DatagramPacket packet;
+        DatagramSocket dataGram;
+        InetAddress address;
+        PduFactory pduFactory = new PduFactory();
+        
+        try {
+
+            // Specify the socket to receive data
+            socket = new MulticastSocket(DIS_DESTINATION_PORT);
+            socket.setBroadcast(true);
+            address = InetAddress.getByName(GROUP);
+            socket.joinGroup(address);
+            //System.out.println("Joined Group.");
+            // Loop infinitely, receiving datagrams
+            while (true) {
+                try{
+                byte buffer[] = new byte[MAX_PDU_SIZE];
+                packet = new DatagramPacket(buffer, buffer.length);
+                socket.receive(packet);
+                //System.out.println("Packet Received");
+                List<Pdu> pduBundle = pduFactory.getPdusFromBundle(packet.getData());
+                //System.out.println("Bundle size is " + pduBundle.size());
+                Iterator it = pduBundle.iterator();
+
+                while(it.hasNext()){
+                    Pdu aPdu = (Pdu)it.next();
+                    //System.out.print("got PDU of type: " + aPdu.getClass().getName());
+                    if(aPdu instanceof EntityStatePdu){
+                        EntityID eid = ((EntityStatePdu)aPdu).getEntityID();
+                        if (eid.getSite() == 200){
+                            dataGram = new DatagramSocket();
+                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                            DataOutputStream dos = new DataOutputStream(baos);  
+                            aPdu.marshal(dos);
+                            byte[] data = baos.toByteArray();
+                                
+                            DatagramPacket DpSend =  new DatagramPacket(data, data.length,  InetAddress.getByName(TCP_DESTINATION_IP), TCP_DESTINATION_PORT);
+                            dataGram.send(DpSend);                                    // Create TCP Bridge
+                            System.out.println("Bravo briding complete to: "+ TCP_DESTINATION_IP);
+                            //EntityType entityType = ((EntityStatePdu)aPdu).getEntityType();
+                            }
+                            Vector3Double location = ((EntityStatePdu)aPdu).getEntityLocation();
+                            System.out.print(" EID:[" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "] ");
+                            //System.out.print(" Location in DIS coordinates: [" + location.getX() + ", " + location.getY() + ", " + position.getZ() + "]");
+                            double c[] = {location.getX(), location.getY(), location.getZ()};
+                            double lla[] = CoordinateConversions.xyzToLatLonDegrees(c);
+                            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
+                        }
+                        System.out.println();
+                    } // end trop through PDU bundle
+                }
+                catch (Exception e) {
+                    System.out.println(e);
+                }
+            } // end while
+        } // End try
+        catch (Exception e) {
+            System.out.println(e);
+        }
+
+    } // end main
+} // end class
diff --git a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduSenderA.java b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduSenderA.java
new file mode 100644
index 0000000000000000000000000000000000000000..7140be6af48fffd9a198f54223ad4a4ee2ed55f0
--- /dev/null
+++ b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduSenderA.java
@@ -0,0 +1,210 @@
+
+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;
+
+/**
+ * Emits PDUs from the network in IEEE format.
+ *
+ * @author Angelopoulos/Blankenbeker
+ * @version 8 MAR 2018
+ */
+public class AngelBlankEspduSenderA 
+{
+    public static final int NUMBER_TO_SEND = 5000;
+
+    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
+
+    /** default multicast group we send on */
+    public static final String DEFAULT_MULTICAST_GROUP="239.1.2.4";
+   
+    /** Port we send on */
+    public static final int DIS_DESTINATION_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 mcast.
+     *                To determine bcast destination IP, use an online bcast address
+     *                caclulator, for example http://www.remotemonitoringsystems.ca/broadcast.php
+     *                If in mcast mode, a join() will be done on the mcast address.
+     * port: port used for both source and destination.
+     * @param args 
+     */
+public static void main(String args[])
+{
+    /** an entity state pdu */
+    EntityStatePdu espdu = new EntityStatePdu();
+    MulticastSocket socket = null;
+    DisTime disTime = DisTime.getInstance();
+    int alternator = -1;
+    // ICBM coordinates for my office
+    double lat = 36.595517; 
+    double lon = -121.877000;
+    int port = DIS_DESTINATION_PORT;
+    NetworkMode mode = NetworkMode.MULTICAST;
+    InetAddress destinationIp = null;
+    
+    try
+    {
+        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
+    }
+    catch(Exception 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)
+            port = Integer.parseInt(portString);
+        
+        socket = new MulticastSocket(DIS_DESTINATION_PORT);
+        
+        // Where we send packets to, the destination IP address
+        if(destinationIpString != null)
+        {
+            destinationIp = InetAddress.getByName(destinationIpString);
+        }
+
+        // Type of transport: unicast, broadcast, or multicast
+        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);   
+            }
+        } // end networkModeString
+    }
+    catch(Exception e)
+    {
+        System.out.println("Unable to initialize networking. Exiting.");
+        System.out.println(e);
+        System.exit(-1);
+    }
+        espdu.setExerciseID((short)1);
+        EntityID eid = espdu.getEntityID();
+        eid.setSite(100);  // 0 is apparently not a valid site number, per the spec
+        eid.setApplication(1); 
+        eid.setEntity(2); 
+        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
+    try
+    {
+        System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
+        for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
+        {
+            eid.setEntity(idx+1);
+            int ts = disTime.getDisAbsoluteTimestamp();
+            espdu.setTimestamp(ts);
+            double direction = Math.pow((double)(-1.0), (double)(idx));
+            lon = lon + (direction * 0.00006);
+            double disCoordinates[] = CoordinateConversions.getXYZfromLatLonDegrees(lat, lon, 1.0);
+            Vector3Double location = espdu.getEntityLocation();
+            location.setX(disCoordinates[0]);
+            location.setY(disCoordinates[1]);
+            location.setZ(disCoordinates[2]);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            DataOutputStream dos = new DataOutputStream(baos);
+            espdu.marshal(dos);
+            byte[] data = baos.toByteArray();
+            DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(DEFAULT_MULTICAST_GROUP), DIS_DESTINATION_PORT);
+            socket.send(packet);
+            Thread.sleep(3000);
+            location = espdu.getEntityLocation();
+            System.out.println("Espdu #" + idx + " EID=[" + eid.getSite() + "," + eid.getApplication() + "," + eid.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);
+            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
+        }
+    }
+    catch(Exception e)
+    {
+        System.out.println(e);
+    }
+        
+}
+
+ /**
+    * A number of sites get all snippy about using 255.255.255.255 for a bcast
+    * address; it trips their security software and they kick you off their 
+    * network. (Comcast, NPS.) This determines the bcast address for all
+    * connected interfaces, based on the IP and subnet mask. If you have
+    * a dual-homed host it will return a bcast address for both. If you have
+    * some VMs running on your host this will pick up the addresses for those
+    * as well--eg 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 bcast addresses
+   
+   public static Set<InetAddress> getBroadcastAddresses()
+   {
+       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
+       Enumeration interfaces;
+       
+       try
+       {
+           interfaces = NetworkInterface.getNetworkInterfaces();
+           
+           while(interfaces.hasMoreElements())
+           {
+               NetworkInterface anInterface = (NetworkInterface)interfaces.nextElement();
+               
+               if(anInterface.isUp())
+               {
+                   Iterator it = anInterface.getInterfaceAddresses().iterator();
+                   while(it.hasNext())
+                   {
+                       InterfaceAddress anAddress = (InterfaceAddress)it.next();
+                       if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
+                           continue;
+                       
+                       //System.out.println("Getting bcast address for " + anAddress);
+                       InetAddress abcast = anAddress.getBroadcast();
+                       if(abcast != null)
+                        bcastAddresses.add(abcast);
+                   }
+               }
+           }
+           
+       }
+       catch(Exception e)
+       {
+           e.printStackTrace();
+           System.out.println(e);
+       }
+       
+       return bcastAddresses;   
+   }
+**/
+}
diff --git a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduSenderB.java b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduSenderB.java
index 197d9c29565c6241152efe34d80a02c9d2683e05..b48aeb88df858fcde75ad55313a3cb80ad74ff63 100644
--- a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduSenderB.java
+++ b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduSenderB.java
@@ -1,347 +1,210 @@
-
-import edu.nps.moves.dis.EntityID;
-import edu.nps.moves.dis.EntityStatePdu;
-import edu.nps.moves.dis.EntityType;
-import edu.nps.moves.dis.FirePdu;
-import edu.nps.moves.dis.Vector3Double;
-import edu.nps.moves.disutil.CoordinateConversions;
-import edu.nps.moves.disutil.DisTime;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.net.DatagramPacket;
-import java.net.InetAddress;
-import java.net.InterfaceAddress;
-import java.net.MulticastSocket;
-import java.net.NetworkInterface;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Properties;
-import java.util.Set;
-
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-
-/**
- *
- * @author Michael
- */
-public class AngelBlankEspduSenderB {
-
-    public static final int NUMBER_TO_SEND = 5000;
-
-    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
-
-    /** default multicast group we send on */
-    public static final String DEFAULT_MULTICAST_GROUP = "239.1.2.4";
-   
-    /** Port we send on */
-    public static final int    DIS_DESTINATION_PORT = 3101;
-    
-/** 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 mcast.
-     *                To determine bcast destination IP, use an online bcast address
-     *                caclulator, for example http://www.remotemonitoringsystems.ca/broadcast.php
-     *                If in mcast mode, a join() will be done on the mcast address.
-     * port: port used for both source and destination.
-     * @param args 
-     */
-public static void main(String args[])
-{
-    /** an entity state pdu */
-    EntityStatePdu espdu = new EntityStatePdu();
-    MulticastSocket socket = null;
-    DisTime disTime = DisTime.getInstance();
-    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 = DIS_DESTINATION_PORT;
-    NetworkMode mode = NetworkMode.MULTICAST;
-    InetAddress destinationIp = null;
-    
-    try
-    {
-        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
-    }
-    catch(Exception 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)
-            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
-        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);
-                
-            }
-        } // end networkModeString
-    }
-    catch(Exception 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 eid = espdu.getEntityID();
-    eid.setSite(1);  // 0 is apparently not a valid site number, per the spec
-    eid.setApplication(1); 
-    eid.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> bcastAddresses = getBroadcastAddresses();
-    // Loop through sending N ESPDUs
-    try
-    {
-        System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
-        for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
-        {
-            // DIS time is a pain in the ass. 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 ts = disTime.getDisAbsoluteTimestamp();
-            espdu.setTimestamp(ts);
-            
-            // 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)(idx));
-            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();
-
-            bcastAddresses = getBroadcastAddresses();
-            Iterator it = bcastAddresses.iterator();
-            while(it.hasNext())
-            {
-               InetAddress bcast = (InetAddress)it.next();
-               System.out.println("Sending bcast to " + bcast);
-               DatagramPacket packet = new DatagramPacket(data, data.length, bcast, 3000);
-               socket.send(packet);
-               packet = new DatagramPacket(fireArray, fireArray.length, bcast, 3000);
-               //socket.send(packet);
-            }
-            
-            // Send every 1 sec. Otherwise this will be all over in a fraction of a second.
-            Thread.sleep(3000);
-
-            location = espdu.getEntityLocation();
-            
-            System.out.println("Espdu #" + idx + " EID=[" + eid.getSite() + "," + eid.getApplication() + "," + eid.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);
-//            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
-
-        }
-    }
-    catch(Exception e)
-    {
-        System.out.println(e);
-    }
-    
-    
-    
-   
-        
-    }
-    
-    
-    
-
-
- /**
-    * A number of sites get all snippy about using 255.255.255.255 for a bcast
-    * address; it trips their security software and they kick you off their 
-    * network. (Comcast, NPS.) This determines the bcast address for all
-    * connected interfaces, based on the IP and subnet mask. If you have
-    * a dual-homed host it will return a bcast address for both. If you have
-    * some VMs running on your host this will pick up the addresses for those
-    * as well--eg 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 bcast addresses
-    */
-   public static Set<InetAddress> getBroadcastAddresses()
-   {
-       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
-       Enumeration interfaces;
-       
-       try
-       {
-           interfaces = NetworkInterface.getNetworkInterfaces();
-           
-           while(interfaces.hasMoreElements())
-           {
-               NetworkInterface anInterface = (NetworkInterface)interfaces.nextElement();
-               
-               if(anInterface.isUp())
-               {
-                   Iterator it = anInterface.getInterfaceAddresses().iterator();
-                   while(it.hasNext())
-                   {
-                       InterfaceAddress anAddress = (InterfaceAddress)it.next();
-                       if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
-                           continue;
-                       
-                       //System.out.println("Getting bcast address for " + anAddress);
-                       InetAddress abcast = anAddress.getBroadcast();
-                       if(abcast != null)
-                        bcastAddresses.add(abcast);
-                   }
-               }
-           }
-           
-       }
-       catch(Exception e)
-       {
-           e.printStackTrace();
-           System.out.println(e);
-       }
-       
-       return bcastAddresses;   
-   }
-
-}
+
+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. 
+ *
+ * @author Angelopoulos/Blankenbeker
+ * 8 MAR 2018
+ */
+public class AngelBlankEspduSenderB 
+{
+    public static final int NUMBER_TO_SEND = 5000;
+    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
+    /** default multicast group we send on */
+    public static final String DEFAULT_MULTICAST_GROUP="239.1.2.3";
+    /** Port we send on */
+    public static final int DIS_DESTINATION_PORT = 2800;
+
+public static void main(String args[])
+{
+    /** an entity state pdu */
+    EntityStatePdu espdu = new EntityStatePdu();
+    MulticastSocket socket = null;
+    DisTime disTime = DisTime.getInstance();
+    int alternator = -1;
+    
+    // ICBM coordinates for my office
+    double lat = 36.595517; 
+    double lon = -121.877000;
+   
+    int port = DIS_DESTINATION_PORT;
+    NetworkMode mode = NetworkMode.MULTICAST;
+    InetAddress destinationIp = null;
+    try
+    {
+        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
+    }
+    catch(Exception 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)
+            port = Integer.parseInt(portString);
+        
+        socket = new MulticastSocket(DIS_DESTINATION_PORT);
+        
+        // Where we send packets to, the destination IP address
+        if(destinationIpString != null)
+        {
+            destinationIp = InetAddress.getByName(destinationIpString);
+        }
+
+        // Type of transport: unicast, broadcast, or multicast
+        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);
+                
+            }
+        } // end networkModeString
+    }
+    catch(Exception e)
+    {
+        System.out.println("Unable to initialize networking. Exiting.");
+        System.out.println(e);
+        System.exit(-1);
+    }
+    
+   
+    espdu.setExerciseID((short)1);
+    EntityID eid = espdu.getEntityID();
+    eid.setSite(200);  // 0 is apparently not a valid site number, per the spec
+    eid.setApplication(1); 
+    eid.setEntity(2); 
+    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
+    
+    try
+    {
+       
+        System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
+        for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
+        {
+            eid.setEntity(idx+1);
+           
+            int ts = disTime.getDisAbsoluteTimestamp();
+            espdu.setTimestamp(ts);
+            double direction = Math.pow((double)(-1.0), (double)(idx));
+            lon = lon + (direction * 0.00006);
+            double disCoordinates[] = CoordinateConversions.getXYZfromLatLonDegrees(lat, lon, 1.0);
+            Vector3Double location = espdu.getEntityLocation();
+            location.setX(disCoordinates[0]);
+            location.setY(disCoordinates[1]);
+            location.setZ(disCoordinates[2]);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            DataOutputStream dos = new DataOutputStream(baos);
+            espdu.marshal(dos);
+            byte[] data = baos.toByteArray();
+            DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(DEFAULT_MULTICAST_GROUP), DIS_DESTINATION_PORT);
+            socket.send(packet);
+            Thread.sleep(3000);
+            location = espdu.getEntityLocation();           
+            System.out.println("Espdu #" + idx + " EID=[" + eid.getSite() + "," + eid.getApplication() + "," + eid.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);
+            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
+        }
+    }
+    catch(Exception e)
+    {
+        System.out.println(e);
+    }
+        
+}
+
+ /**
+    * A number of sites get all snippy about using 255.255.255.255 for a bcast
+    * address; it trips their security software and they kick you off their 
+    * network. (Comcast, NPS.) This determines the bcast address for all
+    * connected interfaces, based on the IP and subnet mask. If you have
+    * a dual-homed host it will return a bcast address for both. If you have
+    * some VMs running on your host this will pick up the addresses for those
+    * as well--eg 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 bcast addresses
+    */
+   public static Set<InetAddress> getBroadcastAddresses()
+   {
+       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
+       Enumeration interfaces;
+       
+       try
+       {
+           interfaces = NetworkInterface.getNetworkInterfaces();
+           
+           while(interfaces.hasMoreElements())
+           {
+               NetworkInterface anInterface = (NetworkInterface)interfaces.nextElement();
+               
+               if(anInterface.isUp())
+               {
+                   Iterator it = anInterface.getInterfaceAddresses().iterator();
+                   while(it.hasNext())
+                   {
+                       InterfaceAddress anAddress = (InterfaceAddress)it.next();
+                       if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
+                           continue;
+                       
+                       //System.out.println("Getting bcast address for " + anAddress);
+                       InetAddress abcast = anAddress.getBroadcast();
+                       if(abcast != null)
+                        bcastAddresses.add(abcast);
+                   }
+               }
+           }
+           
+       }
+       catch(Exception e)
+       {
+           e.printStackTrace();
+           System.out.println(e);
+       }
+       
+       return bcastAddresses;   
+   }
+
+}
diff --git a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduTCPReceiverASenderB.java b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduTCPReceiverASenderB.java
new file mode 100644
index 0000000000000000000000000000000000000000..69fe8350023ff6eb72fc36306102235c1d52cc87
--- /dev/null
+++ b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduTCPReceiverASenderB.java
@@ -0,0 +1,190 @@
+
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import edu.nps.moves.dis.*;
+import edu.nps.moves.disutil.*;
+import edu.nps.moves.disutil.CoordinateConversions;
+import edu.nps.moves.disutil.DisTime;
+
+/**
+ * Listens for TCP connection from AngelBlankReciverBToTCP and sends ESPDU. 
+ *
+ * @author Angelopoulos/Blankenbeker
+ * 8 MAR 2018
+ */
+public class AngelBlankEspduTCPReceiverASenderB
+{
+    public static final int NUMBER_TO_SEND = 5000;
+    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
+    /** default multicast group we send on */
+    public static final String DEFAULT_MULTICAST_GROUP="239.1.2.3";
+    public static final int MAX_PDU_SIZE = 8192;
+    public static final int TCP_DESTINATION_PORT = 2999;
+    /** Port we send on */
+    public static final int DIS_DESTINATION_PORT = 2800;
+/** 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 mcast.
+     *                To determine bcast destination IP, use an online bcast address
+     *                caclulator, for example http://www.remotemonitoringsystems.ca/broadcast.php
+     *                If in mcast mode, a join() will be done on the mcast address.
+     * port: port used for both source and destination.
+     * @param args 
+     */
+public static void main(String args[])
+{
+    /** an entity state pdu */
+    EntityStatePdu espdu = new EntityStatePdu();
+    MulticastSocket socket = null;
+    DisTime disTime = DisTime.getInstance();
+    int alternator = -1;
+    int port = DIS_DESTINATION_PORT;
+    NetworkMode mode = NetworkMode.MULTICAST;
+    InetAddress destinationIp = null;
+    PduFactory pduFactory = new PduFactory();
+    try
+    {
+        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
+    }
+    catch(Exception e)
+    {
+        System.out.println(e + " Cannot create multicast address");
+        System.exit(0);
+    }
+    Properties systemProperties = System.getProperties();
+    String destinationIpString = systemProperties.getProperty("destinationIp");
+    String portString = systemProperties.getProperty("port");
+    String networkModeString = systemProperties.getProperty("networkMode"); // unicast or multicast or broadcast
+    try
+    {
+ 
+        // Port we send to
+        if(portString != null)
+            port = Integer.parseInt(portString);
+        
+        socket = new MulticastSocket(DIS_DESTINATION_PORT);
+        
+        // Where we send packets to, the destination IP address
+        if(destinationIpString != null)
+        {
+            destinationIp = InetAddress.getByName(destinationIpString);
+        }
+
+        // Type of transport: unicast, broadcast, or multicast
+        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);
+                
+            }
+        } // end networkModeString
+    }
+    catch(Exception e)
+    {
+        System.out.println("Unable to initialize networking. Exiting.");
+        System.out.println(e);
+        System.exit(-1);
+    }
+
+    try
+    {
+        int connectionCount = 0;
+        DatagramSocket ds = new DatagramSocket(TCP_DESTINATION_PORT);
+
+        while(true){
+            try
+            {
+                byte buffer[] = new byte[MAX_PDU_SIZE];
+                DatagramPacket tcpPacket = new DatagramPacket(buffer, buffer.length);
+                ds.receive(tcpPacket);
+                connectionCount++;
+                System.out.println("Current PDUs transferred over TCP: "+ connectionCount);
+                List<Pdu> pduBundle = pduFactory.getPdusFromBundle(tcpPacket.getData());
+                //System.out.println("Bundle size is " + pduBundle.size());
+                Iterator it = pduBundle.iterator();
+
+                while(it.hasNext()){
+                    //System.out.println("Entity ID transferred: ");
+                    Pdu aPdu = (Pdu)it.next();
+                    //System.out.print("got PDU of type: " + aPdu.getClass().getName());
+                    if(aPdu instanceof EntityStatePdu){
+                        EntityID eid = ((EntityStatePdu)aPdu).getEntityID();
+                        System.out.println("Entity ID transferred: "+eid.getEntity());
+                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                        DataOutputStream dos = new DataOutputStream(baos);
+                        aPdu.marshal(dos);
+                        byte[] data = baos.toByteArray();
+                        DatagramPacket udpPacket = new DatagramPacket(data, data.length, InetAddress.getByName(DEFAULT_MULTICAST_GROUP), DIS_DESTINATION_PORT);
+                        socket.send(udpPacket); 
+                    }
+                }
+            }
+            catch(Exception e)
+            {
+                System.out.println(e);
+            }
+        }
+    }
+    catch(Exception e)
+    {
+        System.out.println(e);
+    }
+        
+}
+
+/**
+   public static Set<InetAddress> getBroadcastAddresses()
+   {
+       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
+       Enumeration interfaces;
+       
+       try
+       {
+           interfaces = NetworkInterface.getNetworkInterfaces();
+           
+           while(interfaces.hasMoreElements())
+           {
+               NetworkInterface anInterface = (NetworkInterface)interfaces.nextElement();
+               
+               if(anInterface.isUp())
+               {
+                   Iterator it = anInterface.getInterfaceAddresses().iterator();
+                   while(it.hasNext())
+                   {
+                       InterfaceAddress anAddress = (InterfaceAddress)it.next();
+                       if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
+                           continue;
+                       
+                       //System.out.println("Getting bcast address for " + anAddress);
+                       InetAddress abcast = anAddress.getBroadcast();
+                       if(abcast != null)
+                        bcastAddresses.add(abcast);
+                   }
+               }
+           }
+           
+       }
+       catch(Exception e)
+       {
+           e.printStackTrace();
+           System.out.println(e);
+       }
+       
+       return bcastAddresses;   
+   }
+**/
+}
diff --git a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduTCPReceiverBSenderA.java b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduTCPReceiverBSenderA.java
new file mode 100644
index 0000000000000000000000000000000000000000..582ea180c6ddac25791fe6c0eab0ac63e6aa5069
--- /dev/null
+++ b/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/AngelBlankEspduTCPReceiverBSenderA.java
@@ -0,0 +1,204 @@
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import edu.nps.moves.dis.*;
+import edu.nps.moves.disutil.DisTime;
+import edu.nps.moves.disutil.PduFactory;
+
+/**
+ * listens for TCP connection from AngelBlankReceiverAtoTCP and sends ESPDU in IEEE binary format. 
+ *
+ * @author Angelopoulos/Blankenbeker
+ * @version 8 MAR 2018
+ */
+public class AngelBlankEspduTCPReceiverBSenderA
+{
+    public static final int NUMBER_TO_SEND = 5000;
+
+    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
+    public static final int MAX_PDU_SIZE = 8192;
+    /** default multicast group we send on */
+    public static final String DEFAULT_MULTICAST_GROUP="239.1.2.4";
+    public static final int TCP_DESTINATION_PORT = 2998;
+    /** Port we send on */
+    public static final int DIS_DESTINATION_PORT = 3000;
+
+public static void main(String args[])
+{
+    /** an entity state pdu */
+    EntityStatePdu espdu = new EntityStatePdu();
+    MulticastSocket socket = null;
+    DisTime disTime = DisTime.getInstance();
+    int alternator = -1;
+    
+    int port = DIS_DESTINATION_PORT;
+    NetworkMode mode = NetworkMode.MULTICAST;
+    InetAddress destinationIp = null;
+    PduFactory pduFactory = new PduFactory();
+    
+    try
+    {
+        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
+    }
+    catch(Exception 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)
+            port = Integer.parseInt(portString);
+        
+        socket = new MulticastSocket(DIS_DESTINATION_PORT);
+        
+        // Where we send packets to, the destination IP address
+        if(destinationIpString != null)
+        {
+            destinationIp = InetAddress.getByName(destinationIpString);
+        }
+
+        // Type of transport: unicast, broadcast, or multicast
+        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);
+                
+            }
+        } // end networkModeString
+    }
+    catch(Exception e)
+    {
+        System.out.println("Unable to initialize networking. Exiting.");
+        System.out.println(e);
+        System.exit(-1);
+    }
+
+    try
+    {
+        int connectionCount = 0;
+        DatagramSocket ds = new DatagramSocket(TCP_DESTINATION_PORT);
+
+        while(true){
+            try
+            {
+                byte buffer[] = new byte[MAX_PDU_SIZE];
+                DatagramPacket tcpPacket = new DatagramPacket(buffer, buffer.length);
+                ds.receive(tcpPacket);
+                //Socket clientConnection = serverSocket.accept();
+                connectionCount++;
+                System.out.println("Current PDUs transferred over TCP: "+ connectionCount);
+                List<Pdu> pduBundle = pduFactory.getPdusFromBundle(tcpPacket.getData());
+                //System.out.println("Bundle size is " + pduBundle.size());
+                Iterator it = pduBundle.iterator();
+
+                while(it.hasNext()){
+                    //System.out.println("Entity ID transferred: ");
+                    Pdu aPdu = (Pdu)it.next();
+                    //System.out.print("got PDU of type: " + aPdu.getClass().getName());
+                    if(aPdu instanceof EntityStatePdu){
+                        EntityID eid = ((EntityStatePdu)aPdu).getEntityID();
+                        System.out.println("Entity ID transferred: "+eid.getEntity());
+                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                        DataOutputStream dos = new DataOutputStream(baos);
+                        aPdu.marshal(dos);
+                        byte[] data = baos.toByteArray();
+                        DatagramPacket udpPacket = new DatagramPacket(data, data.length, InetAddress.getByName(DEFAULT_MULTICAST_GROUP), DIS_DESTINATION_PORT);
+                        socket.send(udpPacket); 
+                    }       
+                }
+            }
+            catch(Exception e)
+            {
+                System.out.println(e);
+            }
+        }
+    }
+    catch(Exception e)
+    {
+        System.out.println(e);
+    }
+        
+}
+
+ /**
+    * A number of sites get all snippy about using 255.255.255.255 for a bcast
+    * address; it trips their security software and they kick you off their 
+    * network. (Comcast, NPS.) This determines the bcast address for all
+    * connected interfaces, based on the IP and subnet mask. If you have
+    * a dual-homed host it will return a bcast address for both. If you have
+    * some VMs running on your host this will pick up the addresses for those
+    * as well--eg 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 bcast addresses
+    
+   public static Set<InetAddress> getBroadcastAddresses()
+   {
+       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
+       Enumeration interfaces;
+       
+       try
+       {
+           interfaces = NetworkInterface.getNetworkInterfaces();
+           
+           while(interfaces.hasMoreElements())
+           {
+               NetworkInterface anInterface = (NetworkInterface)interfaces.nextElement();
+               
+               if(anInterface.isUp())
+               {
+                   Iterator it = anInterface.getInterfaceAddresses().iterator();
+                   while(it.hasNext())
+                   {
+                       InterfaceAddress anAddress = (InterfaceAddress)it.next();
+                       if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
+                           continue;
+                       
+                       //System.out.println("Getting bcast address for " + anAddress);
+                       InetAddress abcast = anAddress.getBroadcast();
+                       if(abcast != null)
+                        bcastAddresses.add(abcast);
+                   }
+               }
+           }
+           
+       }
+       catch(Exception e)
+       {
+           e.printStackTrace();
+           System.out.println(e);
+       }
+       
+       return bcastAddresses;   
+   }
+**/
+}
diff --git a/projects/Assignments/README.md b/projects/Assignments/README.md
index 7b1d689b7dc2db3fc1a3cfa9f83b432cdc7c111e..f0cb9175d15e3e4d9dd8e56819a1b393acac9931 100644
--- a/projects/Assignments/README.md
+++ b/projects/Assignments/README.md
@@ -25,3 +25,4 @@ You can now verify that your files are been shared by checking the website:
 
 * [Netbeans 8](http://www.netbeans.org) and [Using Git Support](https://netbeans.org/kb/docs/ide/git.html) with [tutorial video](https://netbeans.org/kb/docs/ide/github_nb_screencast.html)
 * [GitLab Flavored Markdown (GFM)](https://docs.gitlab.com/ee/user/markdown.html) and [Markdown Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)
+* UML [Sequence diagram](https://en.wikipedia.org/wiki/Sequence_diagram) on Wikipedia
diff --git a/projects/Assignments/homework1/BlankenbekerMyTcpServer.java b/projects/Assignments/homework1/BlankenbekerMyTcpServer.java
index 4dc227890b63db663d542795fc12b6a4bf95a6b1..a595ef3089f22afebc38391242075080204c31a6 100644
--- a/projects/Assignments/homework1/BlankenbekerMyTcpServer.java
+++ b/projects/Assignments/homework1/BlankenbekerMyTcpServer.java
@@ -33,12 +33,12 @@ public class BlankenbekerMyTcpServer
             // needs to be made only once.
             int connectionCount = 0;
             ServerSocket serverSocket = new ServerSocket(2317);
-
+            Socket clientConnection = serverSocket.accept();
             // Loop, infinitely, waiting for client connections.
             // Stop the program somewhere else.
             while(true)
             {
-                Socket clientConnection = serverSocket.accept();
+               
                 
                 OutputStream os = clientConnection.getOutputStream();
                 PrintStream ps = new PrintStream(os);
diff --git a/projects/Assignments/homework2/AngelAssignment 2.pptx b/projects/Assignments/homework2/AngelAssignment 2.pptx
index 9b88f3aaa11439addbe0d16fd4102f3356c90fab..65d72be5ab54cca0e078c8da621852bdabbac06b 100644
Binary files a/projects/Assignments/homework2/AngelAssignment 2.pptx and b/projects/Assignments/homework2/AngelAssignment 2.pptx differ
diff --git a/projects/Assignments/homework2/BlankenbekerMulticastSender.java b/projects/Assignments/homework2/BlankenbekerMulticastSender.java
index 4207b1799abaad4ea1daa672e737ea9a5f1ddf95..25b01dff4b4cfa3a379d6ebd9baa406581ad6d37 100644
--- a/projects/Assignments/homework2/BlankenbekerMulticastSender.java
+++ b/projects/Assignments/homework2/BlankenbekerMulticastSender.java
@@ -24,7 +24,7 @@ public class BlankenbekerMulticastSender {
    
     public static void main(String[] args) 
     {
-         Truck truck = new Truck();
+         BlankenbekerTruck truck = new BlankenbekerTruck();
         while (true) {
             truck.move();
         try
diff --git a/projects/Assignments/homework2/Truck.java b/projects/Assignments/homework2/BlankenbekerTruck.java
similarity index 82%
rename from projects/Assignments/homework2/Truck.java
rename to projects/Assignments/homework2/BlankenbekerTruck.java
index a1e40bf6243a2295286bcf3139f0f9e217fa4732..e63b7a4817564ca4d0066cea0ed3c581198456ea 100644
--- a/projects/Assignments/homework2/Truck.java
+++ b/projects/Assignments/homework2/BlankenbekerTruck.java
@@ -3,18 +3,18 @@
  * To change this template file, choose Tools | Templates
  * and open the template in the editor.
  */
-package mv3500code;
+//package mv3500code;
 
 /**
  *
  * @author Michael
  */
-public class Truck {
+public class BlankenbekerTruck {
     private float x;
     private float y;
     private float z;
     
-    public Truck(){
+    public BlankenbekerTruck(){
         x = 0;
         y=0;
         z=0;
diff --git a/projects/Assignments/homework2/HanleyUMLDrawingHW2.vsdx b/projects/Assignments/homework2/HanleyUMLDrawingHW2.vsdx
new file mode 100644
index 0000000000000000000000000000000000000000..ab061d5c900f679a0fa02e97feb5a04121dff994
Binary files /dev/null and b/projects/Assignments/homework2/HanleyUMLDrawingHW2.vsdx differ
diff --git a/projects/Assignments/homework2/LandasUMLAssignment02_2_2.pdf b/projects/Assignments/homework2/LandasUMLAssignment02_2_2.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..300376e40266aaefa33d17b619d4bdfb10dd513c
Binary files /dev/null and b/projects/Assignments/homework2/LandasUMLAssignment02_2_2.pdf differ
diff --git a/projects/Assignments/homework2/README.txt b/projects/Assignments/homework2/README.txt
index a906a9aed154e1fd6c59d227565b13f30bf4e4c1..49171e5b8742247fdff794ea25a3a222f29ae887 100644
--- a/projects/Assignments/homework2/README.txt
+++ b/projects/Assignments/homework2/README.txt
@@ -1 +1,6 @@
-What's going on here?
+README files for your project (such as SmithREADME.txt or SmithREADME.md) help 
+document what works, references of interest, what problems were encountered,
+and what TODO items remain.
+
+This documentation not only helps others, but also helps you keep track of
+progress for ongoing or future improvements.
diff --git a/projects/Assignments/homework2/SnellMulticastClient.java b/projects/Assignments/homework2/SnellMulticastClient.java
index b6a9437f772687af331e1426f149698828c31894..559f8c400feaa59b79eea70907e0381a30a09c48 100644
--- a/projects/Assignments/homework2/SnellMulticastClient.java
+++ b/projects/Assignments/homework2/SnellMulticastClient.java
@@ -3,7 +3,7 @@
  * To change this template file, choose Tools | Templates
  * and open the template in the editor.
  */
-package HW2;
+//package HW2;
 
 import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
diff --git a/projects/Assignments/homework2/SnellMulticastServer.java b/projects/Assignments/homework2/SnellMulticastServer.java
index 1d07ef5a73e152c03ed06defbcc7a40f991ae2c3..58346b4333d82c925ff06c9123f394ee6dddd84d 100644
--- a/projects/Assignments/homework2/SnellMulticastServer.java
+++ b/projects/Assignments/homework2/SnellMulticastServer.java
@@ -1,4 +1,4 @@
-package HW2;
+//package HW2;
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
diff --git a/projects/Assignments/homework2/YamashitaDeMouraAssignment2.docx b/projects/Assignments/homework2/YamashitaDeMouraAssignment2.docx
new file mode 100644
index 0000000000000000000000000000000000000000..957bf719eb838584792896d4d449431f122dd497
Binary files /dev/null and b/projects/Assignments/homework2/YamashitaDeMouraAssignment2.docx differ
diff --git a/projects/Assignments/homework3/ABEspduReceiverA.java b/projects/Assignments/homework3/ABEspduReceiverA.java
deleted file mode 100644
index 7b28b2b368975e266954717d0c0ea5955769bf8b..0000000000000000000000000000000000000000
--- a/projects/Assignments/homework3/ABEspduReceiverA.java
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-import java.net.*;
-import java.util.*;
-
-import edu.nps.moves.disutil.*;
-
-import edu.nps.moves.dis.*;
-
-/**
- * Receives PDUs from the network in IEEE format.
- *
- * @author DMcG
- * @version $Id:$
- */
-public class ABEspduReceiverA {
-
-    /** 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
-     */
-    public static final int MAX_PDU_SIZE = 8192;
-    public static final String GROUP = "239.1.2.3";
-    public static void main(String args[]) {
-        MulticastSocket socket;
-        DatagramPacket packet;
-        InetAddress address;
-        PduFactory pduFactory = new PduFactory();
-
-        try {
-            // Specify the socket to receive data
-            socket = new MulticastSocket(3000);
-            socket.setBroadcast(true);
-       
-            address = InetAddress.getByName(GROUP);
-            socket.joinGroup(address);
-
-            // Loop infinitely, receiving datagrams
-            while (true) {
-                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 it = pduBundle.iterator();
-
-                while(it.hasNext())
-                {
-                    Pdu aPdu = (Pdu)it.next();
-                
-                    System.out.print("got PDU of type: " + aPdu.getClass().getName());
-                    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 (Exception e) {
-
-            System.out.println(e);
-        }
-
-
-    } // end main
-} // end class
diff --git a/projects/Assignments/homework3/ABEspduReceiverB.java b/projects/Assignments/homework3/ABEspduReceiverB.java
deleted file mode 100644
index c19654ecc603a97eda1e0846fa0ec48c3665dc46..0000000000000000000000000000000000000000
--- a/projects/Assignments/homework3/ABEspduReceiverB.java
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-import java.net.*;
-import java.util.*;
-
-import edu.nps.moves.disutil.*;
-import edu.nps.moves.dis.*;
-
-/**
- * Receives PDUs from the network in IEEE format.
- *
- * @author DMcG
- * @version $Id:$
- */
-public class ABEspduReceiverB {
-
-    /** 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
-     */
-    public static final int MAX_PDU_SIZE = 8192;
-    
-    public static final String GROUP = "239.1.2.3";
-
-    public static void main(String args[]) {
-        MulticastSocket socket;
-        DatagramPacket packet;
-        InetAddress address;
-        PduFactory pduFactory = new PduFactory();
-
-        try {
-            // Specify the socket to receive data
-            socket = new MulticastSocket(3000);
-            socket.setBroadcast(true);
-       
-
-            address = InetAddress.getByName(GROUP);
-            socket.joinGroup(address);
-
-            // Loop infinitely, receiving datagrams
-            while (true) {
-                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 it = pduBundle.iterator();
-
-                while(it.hasNext())
-                {
-                    Pdu aPdu = (Pdu)it.next();
-                
-                    System.out.print("got PDU of type: " + aPdu.getClass().getName());
-                    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 (Exception e) {
-
-            System.out.println(e);
-        }
-
-
-    } // end main
-} // end class
diff --git a/projects/Assignments/homework3/ABEspduSenderB.java b/projects/Assignments/homework3/ABEspduSenderB.java
deleted file mode 100644
index 4e373aa924a7f4c957fd198a2f9b7717b664ba95..0000000000000000000000000000000000000000
--- a/projects/Assignments/homework3/ABEspduSenderB.java
+++ /dev/null
@@ -1,323 +0,0 @@
-
-
-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. 
- *
- * @author DMcG
- */
-public class ABEspduSenderB 
-{
-    public static final int NUMBER_TO_SEND = 5000;
-
-    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
-
-    /** default multicast group we send on */
-    public static final String DEFAULT_MULTICAST_GROUP = "239.1.2.3";
-   
-    /** Port we send on */
-    public static final int    DIS_DESTINATION_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 mcast.
-     *                To determine bcast destination IP, use an online bcast address
-     *                caclulator, for example http://www.remotemonitoringsystems.ca/broadcast.php
-     *                If in mcast mode, a join() will be done on the mcast address.
-     * port: port used for both source and destination.
-     * @param args 
-     */
-public static void main(String args[])
-{
-    /** an entity state pdu */
-    EntityStatePdu espdu = new EntityStatePdu();
-    MulticastSocket socket = null;
-    DisTime disTime = DisTime.getInstance();
-    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 = DIS_DESTINATION_PORT;
-    NetworkMode mode = NetworkMode.MULTICAST;
-    InetAddress destinationIp = null;
-    
-    try
-    {
-        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
-    }
-    catch(Exception 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)
-            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
-        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);
-                
-            }
-        } // end networkModeString
-    }
-    catch(Exception 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 eid = espdu.getEntityID();
-    eid.setSite(1);  // 0 is apparently not a valid site number, per the spec
-    eid.setApplication(1); 
-    eid.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> bcastAddresses = getBroadcastAddresses();
-    // Loop through sending N ESPDUs
-    try
-    {
-        System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
-        for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
-        {
-            // DIS time is a pain in the ass. 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 ts = disTime.getDisAbsoluteTimestamp();
-            espdu.setTimestamp(ts);
-            
-            // 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)(idx));
-            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();
-
-            bcastAddresses = getBroadcastAddresses();
-            Iterator it = bcastAddresses.iterator();
-            while(it.hasNext())
-            {
-               InetAddress bcast = (InetAddress)it.next();
-               System.out.println("Sending bcast to " + bcast);
-               DatagramPacket packet = new DatagramPacket(data, data.length, bcast, 3000);
-               socket.send(packet);
-               packet = new DatagramPacket(fireArray, fireArray.length, bcast, 3000);
-               //socket.send(packet);
-            }
-            
-            // Send every 1 sec. Otherwise this will be all over in a fraction of a second.
-            Thread.sleep(3000);
-
-            location = espdu.getEntityLocation();
-            
-            System.out.println("Espdu #" + idx + " EID=[" + eid.getSite() + "," + eid.getApplication() + "," + eid.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);
-//            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
-
-        }
-    }
-    catch(Exception e)
-    {
-        System.out.println(e);
-    }
-        
-}
-
- /**
-    * A number of sites get all snippy about using 255.255.255.255 for a bcast
-    * address; it trips their security software and they kick you off their 
-    * network. (Comcast, NPS.) This determines the bcast address for all
-    * connected interfaces, based on the IP and subnet mask. If you have
-    * a dual-homed host it will return a bcast address for both. If you have
-    * some VMs running on your host this will pick up the addresses for those
-    * as well--eg 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 bcast addresses
-    */
-   public static Set<InetAddress> getBroadcastAddresses()
-   {
-       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
-       Enumeration interfaces;
-       
-       try
-       {
-           interfaces = NetworkInterface.getNetworkInterfaces();
-           
-           while(interfaces.hasMoreElements())
-           {
-               NetworkInterface anInterface = (NetworkInterface)interfaces.nextElement();
-               
-               if(anInterface.isUp())
-               {
-                   Iterator it = anInterface.getInterfaceAddresses().iterator();
-                   while(it.hasNext())
-                   {
-                       InterfaceAddress anAddress = (InterfaceAddress)it.next();
-                       if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
-                           continue;
-                       
-                       //System.out.println("Getting bcast address for " + anAddress);
-                       InetAddress abcast = anAddress.getBroadcast();
-                       if(abcast != null)
-                        bcastAddresses.add(abcast);
-                   }
-               }
-           }
-           
-       }
-       catch(Exception e)
-       {
-           e.printStackTrace();
-           System.out.println(e);
-       }
-       
-       return bcastAddresses;   
-   }
-
-}
diff --git a/projects/Assignments/homework3/AngelBlank/ABEspduReceiverA.java b/projects/Assignments/homework3/AngelBlank/ABEspduReceiverA.java
deleted file mode 100644
index 14fa3eb227c44a20f81d48d61739c3c18c155a8f..0000000000000000000000000000000000000000
--- a/projects/Assignments/homework3/AngelBlank/ABEspduReceiverA.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package AngelBlank;
-
-import java.net.*;
-import java.util.*;
-
-import edu.nps.moves.disutil.*;
-import edu.nps.moves.dis.*;
-
-/**
- * Receives PDUs from the network in IEEE format.
- *
- * @author DMcG
- * @version $Id:$
- */
-public class ABEspduReceiverA {
-
-    /** 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
-     */
-    public static final int MAX_PDU_SIZE = 8192;
-    public static final String GROUP = "239.1.2.3";
-    public static void main(String args[]) {
-        MulticastSocket socket;
-        DatagramPacket packet;
-        InetAddress address;
-        PduFactory pduFactory = new PduFactory();
-        
-        
-
-        try {
-            // Create TCP Bridge
-             ServerSocket serverSocket = new ServerSocket(2999);
-            
-            
-            
-            // Specify the socket to receive data
-            socket = new MulticastSocket(3000);
-            socket.setBroadcast(true);
-       
-            address = InetAddress.getByName(GROUP);
-            socket.joinGroup(address);
-
-            // Loop infinitely, receiving datagrams
-            while (true) {
-                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 it = pduBundle.iterator();
-
-                while(it.hasNext())
-                {
-                    Pdu aPdu = (Pdu)it.next();
-                
-                    System.out.print("got PDU of type: " + aPdu.getClass().getName());
-                    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 (Exception e) {
-
-            System.out.println(e);
-        }
-
-
-    } // end main
-} // end class
diff --git a/projects/Assignments/homework3/AngelBlank/ABEspduReceiverB.java b/projects/Assignments/homework3/AngelBlank/ABEspduReceiverB.java
deleted file mode 100644
index 07c9b290455af164b3475b829ae44598eb20179b..0000000000000000000000000000000000000000
--- a/projects/Assignments/homework3/AngelBlank/ABEspduReceiverB.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package AngelBlank;
-
-
-import java.net.*;
-import java.util.*;
-
-import edu.nps.moves.disutil.*;
-import edu.nps.moves.dis.*;
-
-/**
- * Receives PDUs from the network in IEEE format.
- *
- * @author DMcG
- * @version $Id:$
- */
-public class ABEspduReceiverB {
-
-    /** 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
-     */
-    public static final int MAX_PDU_SIZE = 8192;
-    
-    public static final String GROUP = "239.1.2.3";
-
-    public static void main(String args[]) {
-        MulticastSocket socket;
-        DatagramPacket packet;
-        InetAddress address;
-        PduFactory pduFactory = new PduFactory();
-
-        try {
-            // Specify the socket to receive data
-            socket = new MulticastSocket(3000);
-            socket.setBroadcast(true);
-       
-
-            address = InetAddress.getByName(GROUP);
-            socket.joinGroup(address);
-
-            // Loop infinitely, receiving datagrams
-            while (true) {
-                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 it = pduBundle.iterator();
-
-                while(it.hasNext())
-                {
-                    Pdu aPdu = (Pdu)it.next();
-                
-                    System.out.print("got PDU of type: " + aPdu.getClass().getName());
-                    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 (Exception e) {
-
-            System.out.println(e);
-        }
-
-
-    } // end main
-} // end class
diff --git a/projects/Assignments/homework3/AngelBlank/ABEspduSenderB.java b/projects/Assignments/homework3/AngelBlank/ABEspduSenderB.java
deleted file mode 100644
index c562c08720f8393185c735366975a341e6231bb8..0000000000000000000000000000000000000000
--- a/projects/Assignments/homework3/AngelBlank/ABEspduSenderB.java
+++ /dev/null
@@ -1,323 +0,0 @@
-package AngelBlank;
-
-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. 
- *
- * @author DMcG
- */
-public class ABEspduSenderB 
-{
-    public static final int NUMBER_TO_SEND = 5000;
-
-    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
-
-    /** default multicast group we send on */
-    public static final String DEFAULT_MULTICAST_GROUP = "239.1.2.3";
-   
-    /** Port we send on */
-    public static final int    DIS_DESTINATION_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 mcast.
-     *                To determine bcast destination IP, use an online bcast address
-     *                caclulator, for example http://www.remotemonitoringsystems.ca/broadcast.php
-     *                If in mcast mode, a join() will be done on the mcast address.
-     * port: port used for both source and destination.
-     * @param args 
-     */
-public static void main(String args[])
-{
-    /** an entity state pdu */
-    EntityStatePdu espdu = new EntityStatePdu();
-    MulticastSocket socket = null;
-    DisTime disTime = DisTime.getInstance();
-    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 = DIS_DESTINATION_PORT;
-    NetworkMode mode = NetworkMode.MULTICAST;
-    InetAddress destinationIp = null;
-    
-    try
-    {
-        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
-    }
-    catch(Exception 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)
-            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
-        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);
-                
-            }
-        } // end networkModeString
-    }
-    catch(Exception 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 eid = espdu.getEntityID();
-    eid.setSite(1);  // 0 is apparently not a valid site number, per the spec
-    eid.setApplication(1); 
-    eid.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> bcastAddresses = getBroadcastAddresses();
-    // Loop through sending N ESPDUs
-    try
-    {
-        System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
-        for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
-        {
-            // DIS time is a pain in the ass. 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 ts = disTime.getDisAbsoluteTimestamp();
-            espdu.setTimestamp(ts);
-            
-            // 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)(idx));
-            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();
-
-            bcastAddresses = getBroadcastAddresses();
-            Iterator it = bcastAddresses.iterator();
-            while(it.hasNext())
-            {
-               InetAddress bcast = (InetAddress)it.next();
-               System.out.println("Sending bcast to " + bcast);
-               DatagramPacket packet = new DatagramPacket(data, data.length, bcast, 3000);
-               socket.send(packet);
-               packet = new DatagramPacket(fireArray, fireArray.length, bcast, 3000);
-               //socket.send(packet);
-            }
-            
-            // Send every 1 sec. Otherwise this will be all over in a fraction of a second.
-            Thread.sleep(3000);
-
-            location = espdu.getEntityLocation();
-            
-            System.out.println("Espdu #" + idx + " EID=[" + eid.getSite() + "," + eid.getApplication() + "," + eid.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);
-//            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
-
-        }
-    }
-    catch(Exception e)
-    {
-        System.out.println(e);
-    }
-        
-}
-
- /**
-    * A number of sites get all snippy about using 255.255.255.255 for a bcast
-    * address; it trips their security software and they kick you off their 
-    * network. (Comcast, NPS.) This determines the bcast address for all
-    * connected interfaces, based on the IP and subnet mask. If you have
-    * a dual-homed host it will return a bcast address for both. If you have
-    * some VMs running on your host this will pick up the addresses for those
-    * as well--eg 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 bcast addresses
-    */
-   public static Set<InetAddress> getBroadcastAddresses()
-   {
-       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
-       Enumeration interfaces;
-       
-       try
-       {
-           interfaces = NetworkInterface.getNetworkInterfaces();
-           
-           while(interfaces.hasMoreElements())
-           {
-               NetworkInterface anInterface = (NetworkInterface)interfaces.nextElement();
-               
-               if(anInterface.isUp())
-               {
-                   Iterator it = anInterface.getInterfaceAddresses().iterator();
-                   while(it.hasNext())
-                   {
-                       InterfaceAddress anAddress = (InterfaceAddress)it.next();
-                       if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
-                           continue;
-                       
-                       //System.out.println("Getting bcast address for " + anAddress);
-                       InetAddress abcast = anAddress.getBroadcast();
-                       if(abcast != null)
-                        bcastAddresses.add(abcast);
-                   }
-               }
-           }
-           
-       }
-       catch(Exception e)
-       {
-           e.printStackTrace();
-           System.out.println(e);
-       }
-       
-       return bcastAddresses;   
-   }
-
-}
diff --git a/projects/Assignments/homework3/AngelBlank/ABEspduSenderA.java b/projects/Assignments/homework3/Angel_OpenDisEspduSender.java
similarity index 68%
rename from projects/Assignments/homework3/AngelBlank/ABEspduSenderA.java
rename to projects/Assignments/homework3/Angel_OpenDisEspduSender.java
index 4a6391b7681db3fb44248bfaa2bb652298b00ca8..100647dc1226e851771844b16475cb3e15ae8076 100644
--- a/projects/Assignments/homework3/AngelBlank/ABEspduSenderA.java
+++ b/projects/Assignments/homework3/Angel_OpenDisEspduSender.java
@@ -1,324 +1,341 @@
-package AngelBlank;
-
-
-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. 
- *
- * @author DMcG
- */
-public class ABEspduSenderA 
-{
-    public static final int NUMBER_TO_SEND = 5000;
-
-    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
-
-    /** default multicast group we send on */
-    public static final String DEFAULT_MULTICAST_GROUP="239.1.2.3";
-   
-    /** Port we send on */
-    public static final int    DIS_DESTINATION_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 mcast.
-     *                To determine bcast destination IP, use an online bcast address
-     *                caclulator, for example http://www.remotemonitoringsystems.ca/broadcast.php
-     *                If in mcast mode, a join() will be done on the mcast address.
-     * port: port used for both source and destination.
-     * @param args 
-     */
-public static void main(String args[])
-{
-    /** an entity state pdu */
-    EntityStatePdu espdu = new EntityStatePdu();
-    MulticastSocket socket = null;
-    DisTime disTime = DisTime.getInstance();
-    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 = DIS_DESTINATION_PORT;
-    NetworkMode mode = NetworkMode.MULTICAST;
-    InetAddress destinationIp = null;
-    
-    try
-    {
-        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
-    }
-    catch(Exception 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)
-            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
-        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);
-                
-            }
-        } // end networkModeString
-    }
-    catch(Exception 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 eid = espdu.getEntityID();
-    eid.setSite(1);  // 0 is apparently not a valid site number, per the spec
-    eid.setApplication(1); 
-    eid.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> bcastAddresses = getBroadcastAddresses();
-    // Loop through sending N ESPDUs
-    try
-    {
-        System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
-        for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
-        {
-            // DIS time is a pain in the ass. 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 ts = disTime.getDisAbsoluteTimestamp();
-            espdu.setTimestamp(ts);
-            
-            // 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)(idx));
-            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();
-
-            bcastAddresses = getBroadcastAddresses();
-            Iterator it = bcastAddresses.iterator();
-            while(it.hasNext())
-            {
-               InetAddress bcast = (InetAddress)it.next();
-               System.out.println("Sending bcast to " + bcast);
-               DatagramPacket packet = new DatagramPacket(data, data.length, bcast, 3000);
-               socket.send(packet);
-               packet = new DatagramPacket(fireArray, fireArray.length, bcast, 3000);
-               //socket.send(packet);
-            }
-            
-            // Send every 1 sec. Otherwise this will be all over in a fraction of a second.
-            Thread.sleep(3000);
-
-            location = espdu.getEntityLocation();
-            
-            System.out.println("Espdu #" + idx + " EID=[" + eid.getSite() + "," + eid.getApplication() + "," + eid.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);
-//            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
-
-        }
-    }
-    catch(Exception e)
-    {
-        System.out.println(e);
-    }
-        
-}
-
- /**
-    * A number of sites get all snippy about using 255.255.255.255 for a bcast
-    * address; it trips their security software and they kick you off their 
-    * network. (Comcast, NPS.) This determines the bcast address for all
-    * connected interfaces, based on the IP and subnet mask. If you have
-    * a dual-homed host it will return a bcast address for both. If you have
-    * some VMs running on your host this will pick up the addresses for those
-    * as well--eg 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 bcast addresses
-    */
-   public static Set<InetAddress> getBroadcastAddresses()
-   {
-       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
-       Enumeration interfaces;
-       
-       try
-       {
-           interfaces = NetworkInterface.getNetworkInterfaces();
-           
-           while(interfaces.hasMoreElements())
-           {
-               NetworkInterface anInterface = (NetworkInterface)interfaces.nextElement();
-               
-               if(anInterface.isUp())
-               {
-                   Iterator it = anInterface.getInterfaceAddresses().iterator();
-                   while(it.hasNext())
-                   {
-                       InterfaceAddress anAddress = (InterfaceAddress)it.next();
-                       if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
-                           continue;
-                       
-                       //System.out.println("Getting bcast address for " + anAddress);
-                       InetAddress abcast = anAddress.getBroadcast();
-                       if(abcast != null)
-                        bcastAddresses.add(abcast);
-                   }
-               }
-           }
-           
-       }
-       catch(Exception e)
-       {
-           e.printStackTrace();
-           System.out.println(e);
-       }
-       
-       return bcastAddresses;   
-   }
-
-}
+//package edu.nps.moves.examples; // copy example from OpenDIS distribution, modify to serve as template
+
+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. 
+ *
+ * @author DMcG
+ */
+public class Angel_OpenDisEspduSender 
+{
+    public static final int NUMBER_TO_SEND = 5000;
+
+    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
+
+    /** Default multicast group address we send on */
+    public static final String DEFAULT_MULTICAST_GROUP="239.1.2.3";
+   
+    /** Default port we send on */
+    public static final int    DIS_DESTINATION_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 
+     */
+public static void main(String args[])
+{
+    /** 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 = DIS_DESTINATION_PORT;
+    NetworkMode mode = NetworkMode.BROADCAST;
+    InetAddress destinationIp = null; // must be initialized, even if null
+    
+    try
+    {
+        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
+    }
+    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)
+            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);
+            }
+        } // 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)2);          // AIR (vs air, surface, subsurface, space)
+    entityType.setCategory((short)2);        // Fighter/Attack
+    entityType.setSubcategory((short)2);     // 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());
+            double disCoordinates1[] = CoordinateConversions.getXYZfromLatLonDegrees(36.593731, -121.882534, 1.0);
+            double disCoordinates2[] = CoordinateConversions.getXYZfromLatLonDegrees(36.594548, -121.882651, 1.0);
+            double disCoordinates3[] = CoordinateConversions.getXYZfromLatLonDegrees(36.596826, -121.882694, 1.0);
+            double disCoordinates4[] = CoordinateConversions.getXYZfromLatLonDegrees(36.598394, -121.883188, 1.0);
+            double disCoordinates5[] = CoordinateConversions.getXYZfromLatLonDegrees(36.599927, -121.883510, 1.0);
+            double disCoordinates6[] = CoordinateConversions.getXYZfromLatLonDegrees(36.599979, -121.887286, 1.0);
+            double disCoordinates7[] = CoordinateConversions.getXYZfromLatLonDegrees(36.598170, -121.887715, 1.0);
+            double disCoordinates8[] = CoordinateConversions.getXYZfromLatLonDegrees(36.596826, -121.888895, 1.0);
+            double disCoordinates9[] = CoordinateConversions.getXYZfromLatLonDegrees(36.595121, -121.889239, 1.0);
+            double disCoordinates10[] = CoordinateConversions.getXYZfromLatLonDegrees(36.594415,-121.885934, 1.0);
+            
+        double[][] disCoords = {disCoordinates1, disCoordinates2, disCoordinates3, disCoordinates4,
+            disCoordinates5, disCoordinates6, disCoordinates7, disCoordinates8, disCoordinates8, 
+            disCoordinates10};
+  
+        for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
+        {
+            // DIS time is a pain in the ass. 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)(idx));
+            //lon = lon + (direction * 0.00006);
+            //System.out.println(lon);
+            
+
+
+            Vector3Double location = espdu.getEntityLocation();
+            int res = idx/2 % 10;
+            location.setX(disCoords[res][0]);
+            location.setY(disCoords[res][1]);
+            location.setZ(disCoords[res][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 it = broadcastAddresses.iterator();
+            while(it.hasNext())
+            {
+               InetAddress broadcast = (InetAddress)it.next();
+               System.out.println("Sending broadcast datagram packet to " + broadcast);
+               DatagramPacket packet = new DatagramPacket(data, data.length, broadcast, 3000);
+               socket.send(packet);
+			   // TODO experiment with these!  8)
+               //packet = new DatagramPacket(fireArray, fireArray.length, broadcast, 3000); // alternate
+               socket.send(packet);
+            }
+            
+            // Send every 1 sec. Otherwise this will be all over in a fraction of a second.
+            Thread.sleep(3000);
+
+            location = espdu.getEntityLocation();
+            
+            System.out.println("Espdu #" + idx + " 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);
+//            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
+
+        }
+    }
+    catch(IOException | InterruptedException e)
+    {
+        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--eg 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 it = anInterface.getInterfaceAddresses().iterator();
+                   while(it.hasNext())
+                   {
+                       InterfaceAddress anAddress = (InterfaceAddress)it.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)
+       {
+           e.printStackTrace();
+           System.out.println(e);
+       }
+       
+       return broadcastAddresses;   
+   }
+
+}
diff --git a/projects/Assignments/homework3/AngelopoulosREADME.md b/projects/Assignments/homework3/AngelopoulosREADME.md
new file mode 100644
index 0000000000000000000000000000000000000000..bf6e056dcfd35700eaedff6ff73b6c0b6e43d41a
--- /dev/null
+++ b/projects/Assignments/homework3/AngelopoulosREADME.md
@@ -0,0 +1,34 @@
+## Homework Assignment 3 Checklist
+
+1. [x] Add X3D-Edit as Netbeans Plugin from https://savage.nps.edu/X3D-Edit/#Downloads
+
+1. [x] Optional: checkout Open-DIS-Java library source from https://github.com/open-dis/open-dis-java
+
+1. [x] Otherwise just inspect files of interest from
+   [edu.nps.moves.examples](https://github.com/open-dis/open-dis-java/tree/master/src/main/java/edu/nps/moves/examples)
+
+1. [x] Copy README.md and create YournameREADME.md documentation file...
+
+1. [x] Plan a track of interest, described in YournameREADME.md documentation file...
+
+The armor (Enhanced Ground Combat Vehicle) travels from intersection of Freemont and 68, down Camino Aguajito,
+left on Del Monte Ave, Left on Camino El Estero, and finally a left on Fremont to the beginning.  The travel movement is 
+roughly 1/3 of a mile every 24 seconds.  It might be a bit fast....but its ARMY/MARINE Strong!
+
+1. [x] Copy, then Refactor/Rename example file OpenDisEspduSender.java or OpenDisPduSender.java as YourNameSomething.java
+
+1. [x] Modify your example file to produce track PDUs (and be cool)
+
+1. [x] Generate PDUs...
+
+1. [x] Test PDU reading using Wireshark...
+
+Some examples of PDUs within WireShark
+
+111	32.870689	172.20.144.243	172.20.159.255	DIS	186	PDUType: 1 	 Entity State, Platform, Air, (1:1:2)
+110	32.870603	172.20.144.243	172.20.159.255	DIS	186	PDUType: 1 	 Entity State, Platform, Air, (1:1:2)
+97	29.761150	172.20.144.243	172.20.159.255	DIS	186	PDUType: 1 	 Entity State, Platform, Air, (1:1:2)
+
+1. [x] Record PDU file using X3D-Edit...
+
+1. [x] Playback PDU file using X3D-Edit...
diff --git a/projects/Assignments/homework3/Angelopoulos_dispackets.disbin b/projects/Assignments/homework3/Angelopoulos_dispackets.disbin
new file mode 100644
index 0000000000000000000000000000000000000000..75f5caf1ddc7fed9a2c5ac6d83bc52d1e4fa1337
Binary files /dev/null and b/projects/Assignments/homework3/Angelopoulos_dispackets.disbin differ
diff --git a/projects/Assignments/homework3/Angelopoulos_dispackets.disbin.disbinidx b/projects/Assignments/homework3/Angelopoulos_dispackets.disbin.disbinidx
new file mode 100644
index 0000000000000000000000000000000000000000..159aa2e788491aa6a444ff345031cbd29ecc337c
Binary files /dev/null and b/projects/Assignments/homework3/Angelopoulos_dispackets.disbin.disbinidx differ
diff --git a/projects/Assignments/homework3/BlankenbekerDISpacketsHW3.disbin b/projects/Assignments/homework3/BlankenbekerDISpacketsHW3.disbin
new file mode 100644
index 0000000000000000000000000000000000000000..8dc1bd8f7790381bfa99bfd65342bf48ee6e65dd
Binary files /dev/null and b/projects/Assignments/homework3/BlankenbekerDISpacketsHW3.disbin differ
diff --git a/projects/Assignments/homework3/BlankenbekerDISpacketsHW3.disbin.disbinidx b/projects/Assignments/homework3/BlankenbekerDISpacketsHW3.disbin.disbinidx
new file mode 100644
index 0000000000000000000000000000000000000000..5ed6ff1e1123af2dd04e7e9c8247aa60ad6c0f66
Binary files /dev/null and b/projects/Assignments/homework3/BlankenbekerDISpacketsHW3.disbin.disbinidx differ
diff --git a/projects/Assignments/homework3/BlankenbekerHW3README.md b/projects/Assignments/homework3/BlankenbekerHW3README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c77377b79cd3818957b32fab44892fd2da0f1ec0
--- /dev/null
+++ b/projects/Assignments/homework3/BlankenbekerHW3README.md
@@ -0,0 +1,30 @@
+## Homework Assignment 3 Checklist
+
+1. [x] Add X3D-Edit as Netbeans Plugin from https://savage.nps.edu/X3D-Edit/#Downloads
+
+1. [x] Optional: checkout Open-DIS-Java library source from https://github.com/open-dis/open-dis-java
+
+1. [x] Otherwise just inspect files of interest from
+   [edu.nps.moves.examples](https://github.com/open-dis/open-dis-java/tree/master/src/main/java/edu/nps/moves/examples)
+
+1. [X] Copy README.md and create YournameREADME.md documentation file...
+
+1. [x] Plan a track of interest, described in YournameREADME.md documentation file...
+
+    The track consists of a highway driving route from Monterey, CA to Palmdale, CA.
+
+1. [x] Copy, then Refactor/Rename example file OpenDisEspduSender.java or OpenDisPduSender.java as YourNameSomething.java
+
+1. [x] Modify your example file to produce track PDUs (and be cool)
+
+1. [x] Generate PDUs...
+
+1. [x] Test PDU reading using Wireshark...
+    
+    Wireshark output depicted activity when PDUs were being created.
+
+1. [x] Record PDU file using X3D-Edit...
+
+1. [x] Playback PDU file using X3D-Edit...
+
+PDU file succesfully recorded and played back using the X3D-Edit tools.
diff --git a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduSenderA.java b/projects/Assignments/homework3/BlankenbekerOpenDisEspduSender.java
similarity index 72%
rename from projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduSenderA.java
rename to projects/Assignments/homework3/BlankenbekerOpenDisEspduSender.java
index 700c93ecee0f23b30126276235134edcaa1e02bc..5fdfd87a4b6834e2fb81442ffa761383d58c50d7 100644
--- a/projects/Assignments/FinalProjects/2018March/AngelopoulosBlankenbeker/ABEspduSenderA.java
+++ b/projects/Assignments/homework3/BlankenbekerOpenDisEspduSender.java
@@ -1,324 +1,364 @@
-
-
-
-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. 
- *
- * @author DMcG
- */
-public class ABEspduSenderA 
-{
-    public static final int NUMBER_TO_SEND = 5000;
-
-    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
-
-    /** default multicast group we send on */
-    public static final String DEFAULT_MULTICAST_GROUP="239.1.2.3";
-   
-    /** Port we send on */
-    public static final int    DIS_DESTINATION_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 mcast.
-     *                To determine bcast destination IP, use an online bcast address
-     *                caclulator, for example http://www.remotemonitoringsystems.ca/broadcast.php
-     *                If in mcast mode, a join() will be done on the mcast address.
-     * port: port used for both source and destination.
-     * @param args 
-     */
-public static void main(String args[])
-{
-    /** an entity state pdu */
-    EntityStatePdu espdu = new EntityStatePdu();
-    MulticastSocket socket = null;
-    DisTime disTime = DisTime.getInstance();
-    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 = DIS_DESTINATION_PORT;
-    NetworkMode mode = NetworkMode.MULTICAST;
-    InetAddress destinationIp = null;
-    
-    try
-    {
-        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
-    }
-    catch(Exception 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)
-            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
-        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);
-                
-            }
-        } // end networkModeString
-    }
-    catch(Exception 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 eid = espdu.getEntityID();
-    eid.setSite(1);  // 0 is apparently not a valid site number, per the spec
-    eid.setApplication(1); 
-    eid.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> bcastAddresses = getBroadcastAddresses();
-    // Loop through sending N ESPDUs
-    try
-    {
-        System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
-        for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
-        {
-            // DIS time is a pain in the ass. 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 ts = disTime.getDisAbsoluteTimestamp();
-            espdu.setTimestamp(ts);
-            
-            // 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)(idx));
-            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();
-
-            bcastAddresses = getBroadcastAddresses();
-            Iterator it = bcastAddresses.iterator();
-            while(it.hasNext())
-            {
-               InetAddress bcast = (InetAddress)it.next();
-               System.out.println("Sending bcast to " + bcast);
-               DatagramPacket packet = new DatagramPacket(data, data.length, bcast, 3000);
-               socket.send(packet);
-               packet = new DatagramPacket(fireArray, fireArray.length, bcast, 3000);
-               //socket.send(packet);
-            }
-            
-            // Send every 1 sec. Otherwise this will be all over in a fraction of a second.
-            Thread.sleep(3000);
-
-            location = espdu.getEntityLocation();
-            
-            System.out.println("Espdu #" + idx + " EID=[" + eid.getSite() + "," + eid.getApplication() + "," + eid.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);
-//            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
-
-        }
-    }
-    catch(Exception e)
-    {
-        System.out.println(e);
-    }
-        
-}
-
- /**
-    * A number of sites get all snippy about using 255.255.255.255 for a bcast
-    * address; it trips their security software and they kick you off their 
-    * network. (Comcast, NPS.) This determines the bcast address for all
-    * connected interfaces, based on the IP and subnet mask. If you have
-    * a dual-homed host it will return a bcast address for both. If you have
-    * some VMs running on your host this will pick up the addresses for those
-    * as well--eg 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 bcast addresses
-    */
-   public static Set<InetAddress> getBroadcastAddresses()
-   {
-       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
-       Enumeration interfaces;
-       
-       try
-       {
-           interfaces = NetworkInterface.getNetworkInterfaces();
-           
-           while(interfaces.hasMoreElements())
-           {
-               NetworkInterface anInterface = (NetworkInterface)interfaces.nextElement();
-               
-               if(anInterface.isUp())
-               {
-                   Iterator it = anInterface.getInterfaceAddresses().iterator();
-                   while(it.hasNext())
-                   {
-                       InterfaceAddress anAddress = (InterfaceAddress)it.next();
-                       if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
-                           continue;
-                       
-                       //System.out.println("Getting bcast address for " + anAddress);
-                       InetAddress abcast = anAddress.getBroadcast();
-                       if(abcast != null)
-                        bcastAddresses.add(abcast);
-                   }
-               }
-           }
-           
-       }
-       catch(Exception e)
-       {
-           e.printStackTrace();
-           System.out.println(e);
-       }
-       
-       return bcastAddresses;   
-   }
-
-}
+// package edu.nps.moves.examples; // copy example from OpenDIS distribution, modify to serve as template
+
+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. 
+ *
+ * @author DMcG
+ */
+public class BlankenbekerOpenDisEspduSender 
+{
+    
+    public static final int NUMBER_TO_SEND = 5000;
+
+    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
+
+    /** Default multicast group address we send on */
+    public static final String DEFAULT_MULTICAST_GROUP="239.1.2.3";
+    
+    private static final ArrayList <Float[]> track = new ArrayList<>();
+   
+    /** Default port we send on */
+    public static final int    DIS_DESTINATION_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 
+     */
+public static void main(String args[])
+{
+    /** 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 = DIS_DESTINATION_PORT;
+    NetworkMode mode = NetworkMode.MULTICAST;
+    InetAddress destinationIp = null; // must be initialized, even if null
+    
+    try
+    {
+        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
+    }
+    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)
+            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);
+            }
+        } // 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
+    {
+        
+        Float[] TrackCoor1 = new Float [2];
+        TrackCoor1[0] = 36.59135f;
+        TrackCoor1[1] = -121.88051f;
+        track.add(TrackCoor1);
+        Float[] TrackCoor2 = new Float [2];
+        TrackCoor2[0] = 36.59487f;
+        TrackCoor2[1] = -121.86739f;
+        track.add(TrackCoor2);
+        Float[] TrackCoor3 = new Float [2];
+        TrackCoor3[0] = 36.63259f;
+        TrackCoor3[1] = -121.66926f;
+        track.add(TrackCoor3);
+        Float[] TrackCoor4 = new Float [2];
+        TrackCoor4[0] = 36.64481f;
+        TrackCoor4[1] = -121.61162f;
+        track.add(TrackCoor4);
+        Float[] TrackCoor5 = new Float [2];
+        TrackCoor5[0] = 35.64239f;
+        TrackCoor5[1] = -120.68503f;
+        track.add(TrackCoor5);
+        Float[] TrackCoor6 = new Float [2];
+        TrackCoor6[0] = 35.61577f;
+        TrackCoor6[1] = -119.65283f;
+        track.add(TrackCoor6);
+        Float[] TrackCoor7 = new Float [2];
+        TrackCoor7[0] = 34.76589f;
+        TrackCoor7[1] = -118.79854f;
+        track.add(TrackCoor7);
+        Float[] TrackCoor8 = new Float [2];
+        TrackCoor8[0] = 34.77651f;
+        TrackCoor8[1] = -118.17049f;
+        track.add(TrackCoor8);
+        Float[] TrackCoor9 = new Float [2];
+        TrackCoor9[0] = 34.5806f;
+        TrackCoor9[1] = -118.1334f;
+        track.add(TrackCoor9);
+        
+//        System.out.println("********" + String.valueOf(track_coordinates[0]) );
+//        System.out.println("********" + track_coordinates.get(5)[1]);
+        System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
+        for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
+        {
+            // DIS time is a pain in the ass. 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");
+
+            Float lat = track.get(idx)[0];
+            Float lon = track.get(idx)[1];
+            
+            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 it = broadcastAddresses.iterator();
+            while(it.hasNext())
+            {
+               InetAddress broadcast = (InetAddress)it.next();
+               System.out.println("Sending broadcast datagram packet to " + broadcast);
+               DatagramPacket packet = new DatagramPacket(data, data.length, broadcast, 3000);
+               socket.send(packet);
+			   // TODO experiment with these!  8)
+               packet = new DatagramPacket(fireArray, fireArray.length, broadcast, 3000); // alternate
+               socket.send(packet);
+            }
+            
+            // Send every 1 sec. Otherwise this will be all over in a fraction of a second.
+            Thread.sleep(3000);
+
+            location = espdu.getEntityLocation();
+            
+            System.out.println("Espdu #" + idx + " 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);
+//            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
+
+        }
+    }
+    catch(IOException | InterruptedException e)
+    {
+        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--eg 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 it = anInterface.getInterfaceAddresses().iterator();
+                   while(it.hasNext())
+                   {
+                       InterfaceAddress anAddress = (InterfaceAddress)it.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)
+       {
+           e.printStackTrace();
+           System.out.println(e);
+       }
+       
+       return broadcastAddresses;   
+   }
+
+}
diff --git a/projects/Assignments/AngelBlankFP/EspduReceiver.java b/projects/Assignments/homework3/EspduReceiver.java
similarity index 100%
rename from projects/Assignments/AngelBlankFP/EspduReceiver.java
rename to projects/Assignments/homework3/EspduReceiver.java
diff --git a/projects/Assignments/AngelBlankFP/EspduSender.java b/projects/Assignments/homework3/EspduSender_1.java
similarity index 100%
rename from projects/Assignments/AngelBlankFP/EspduSender.java
rename to projects/Assignments/homework3/EspduSender_1.java
diff --git a/projects/Assignments/homework3/OpenDisEspduSender.java b/projects/Assignments/homework3/OpenDisEspduSender.java
index 3acdfaa35258635e7e4624aecfbd42a13b354fac..fb6e9964a28054b36e55f230bbf2bf3b122a2fb7 100644
--- a/projects/Assignments/homework3/OpenDisEspduSender.java
+++ b/projects/Assignments/homework3/OpenDisEspduSender.java
@@ -21,6 +21,8 @@ public class OpenDisEspduSender
 
     /** Default multicast group address we send on */
     public static final String DEFAULT_MULTICAST_GROUP="239.1.2.3";
+    
+    private static final ArrayList <Float[]> track = new ArrayList<>();
    
     /** Default port we send on */
     public static final int    DIS_DESTINATION_PORT = 3000;
@@ -43,8 +45,8 @@ public static void main(String args[])
     int alternator = -1;
     
     // ICBM coordinates for my office
-    double lat = 36.595517; 
-    double lon = -121.877000;
+    //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.
@@ -149,6 +151,46 @@ public static void main(String args[])
     // Loop through sending N ESPDUs
     try
     {
+        
+        Float[] TrackCoor1 = new Float [2];
+        TrackCoor1[0] = 36.59135f;
+        TrackCoor1[1] = -121.88051f;
+        track.add(TrackCoor1);
+        Float[] TrackCoor2 = new Float [2];
+        TrackCoor2[0] = 36.59487f;
+        TrackCoor2[1] = -121.86739f;
+        track.add(TrackCoor2);
+        Float[] TrackCoor3 = new Float [2];
+        TrackCoor3[0] = 36.63259f;
+        TrackCoor3[1] = -121.66926f;
+        track.add(TrackCoor3);
+        Float[] TrackCoor4 = new Float [2];
+        TrackCoor4[0] = 36.64481f;
+        TrackCoor4[1] = -121.61162f;
+        track.add(TrackCoor4);
+        Float[] TrackCoor5 = new Float [2];
+        TrackCoor5[0] = 35.64239f;
+        TrackCoor5[1] = -120.68503f;
+        track.add(TrackCoor5);
+        Float[] TrackCoor6 = new Float [2];
+        TrackCoor6[0] = 35.61577f;
+        TrackCoor6[1] = -119.65283f;
+        track.add(TrackCoor6);
+        Float[] TrackCoor7 = new Float [2];
+        TrackCoor7[0] = 34.76589f;
+        TrackCoor7[1] = -118.79854f;
+        track.add(TrackCoor7);
+        Float[] TrackCoor8 = new Float [2];
+        TrackCoor8[0] = 34.77651f;
+        TrackCoor8[1] = -118.17049f;
+        track.add(TrackCoor8);
+        Float[] TrackCoor9 = new Float [2];
+        TrackCoor9[0] = 34.5806f;
+        TrackCoor9[1] = -118.1334f;
+        track.add(TrackCoor9);
+        
+//        System.out.println("********" + String.valueOf(track_coordinates[0]) );
+//        System.out.println("********" + track_coordinates.get(5)[1]);
         System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
         for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
         {
@@ -197,9 +239,8 @@ public static void main(String args[])
             //lon = lon + (double)((double)idx / 100000.0);
             //System.out.println("lla=" + lat + "," + lon + ", 0.0");
 
-            double direction = Math.pow((double)(-1.0), (double)(idx));
-            lon = lon + (direction * 0.00006);
-            System.out.println(lon);
+            Float lat = track.get(idx)[0];
+            Float lon = track.get(idx)[1];
             
             double disCoordinates[] = CoordinateConversions.getXYZfromLatLonDegrees(lat, lon, 1.0);
             Vector3Double location = espdu.getEntityLocation();
@@ -227,23 +268,23 @@ public static void main(String args[])
             DataOutputStream dos = new DataOutputStream(baos);
             espdu.marshal(dos);
 
-            FirePdu fire = new FirePdu();
-            byte[] fireArray = fire.marshal();
+            FirePdu firePdu = new FirePdu();
+            byte[] fireArray = firePdu.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 it = broadcastAddresses.iterator();
-            while(it.hasNext())
+            Iterator iteratorBroadcastAddresses = broadcastAddresses.iterator();
+            while(iteratorBroadcastAddresses.hasNext())
             {
-               InetAddress broadcast = (InetAddress)it.next();
-               System.out.println("Sending broadcast datagram packet to " + broadcast);
-               DatagramPacket packet = new DatagramPacket(data, data.length, broadcast, 3000);
+               InetAddress broadcastAddress = (InetAddress)iteratorBroadcastAddresses.next();
+               System.out.println("Sending broadcast datagram packet to " + broadcastAddress);
+               DatagramPacket packet = new DatagramPacket(data, data.length, broadcastAddress, 3000);
                socket.send(packet);
 			   // TODO experiment with these!  8)
-               packet = new DatagramPacket(fireArray, fireArray.length, broadcast, 3000); // alternate
+               packet = new DatagramPacket(fireArray, fireArray.length, broadcastAddress, 3000); // alternate
                socket.send(packet);
             }
             
@@ -299,7 +340,7 @@ public static void main(String args[])
                    {
                        InterfaceAddress anAddress = (InterfaceAddress)it.next();
                        if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
-                           continue;
+                           continue; // skip to next iterator value
                        
                        //System.out.println("Getting broadcast address for " + anAddress);
                        InetAddress broadcastAddress = anAddress.getBroadcast();
diff --git a/projects/Assignments/homework3/Sasala_HW3_Screenshots.pdf b/projects/Assignments/homework3/Sasala_HW3_Screenshots.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..49d03e35f7783db967736bbb1ed2072a60c1aba6
Binary files /dev/null and b/projects/Assignments/homework3/Sasala_HW3_Screenshots.pdf differ
diff --git a/projects/Assignments/homework3/ABEspduSenderA.java b/projects/Assignments/homework3/Sasala_OpenDisEspduSender1.java
similarity index 72%
rename from projects/Assignments/homework3/ABEspduSenderA.java
rename to projects/Assignments/homework3/Sasala_OpenDisEspduSender1.java
index d3cd7510899593dda0626ba0803f2903ba027146..fbe926fb1529c0b09dc730487e983d7d8e736a59 100644
--- a/projects/Assignments/homework3/ABEspduSenderA.java
+++ b/projects/Assignments/homework3/Sasala_OpenDisEspduSender1.java
@@ -1,323 +1,297 @@
-
-
-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. 
- *
- * @author DMcG
- */
-public class ABEspduSenderA 
-{
-    public static final int NUMBER_TO_SEND = 5000;
-
-    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
-
-    /** default multicast group we send on */
-    public static final String DEFAULT_MULTICAST_GROUP="239.1.2.3";
-   
-    /** Port we send on */
-    public static final int    DIS_DESTINATION_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 mcast.
-     *                To determine bcast destination IP, use an online bcast address
-     *                caclulator, for example http://www.remotemonitoringsystems.ca/broadcast.php
-     *                If in mcast mode, a join() will be done on the mcast address.
-     * port: port used for both source and destination.
-     * @param args 
-     */
-public static void main(String args[])
-{
-    /** an entity state pdu */
-    EntityStatePdu espdu = new EntityStatePdu();
-    MulticastSocket socket = null;
-    DisTime disTime = DisTime.getInstance();
-    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 = DIS_DESTINATION_PORT;
-    NetworkMode mode = NetworkMode.MULTICAST;
-    InetAddress destinationIp = null;
-    
-    try
-    {
-        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
-    }
-    catch(Exception 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)
-            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
-        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);
-                
-            }
-        } // end networkModeString
-    }
-    catch(Exception 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 eid = espdu.getEntityID();
-    eid.setSite(1);  // 0 is apparently not a valid site number, per the spec
-    eid.setApplication(1); 
-    eid.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> bcastAddresses = getBroadcastAddresses();
-    // Loop through sending N ESPDUs
-    try
-    {
-        System.out.println("Sending " + NUMBER_TO_SEND + " ESPDU packets to " + destinationIp.toString());
-        for(int idx = 0; idx < NUMBER_TO_SEND; idx++)
-        {
-            // DIS time is a pain in the ass. 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 ts = disTime.getDisAbsoluteTimestamp();
-            espdu.setTimestamp(ts);
-            
-            // 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)(idx));
-            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();
-
-            bcastAddresses = getBroadcastAddresses();
-            Iterator it = bcastAddresses.iterator();
-            while(it.hasNext())
-            {
-               InetAddress bcast = (InetAddress)it.next();
-               System.out.println("Sending bcast to " + bcast);
-               DatagramPacket packet = new DatagramPacket(data, data.length, bcast, 3000);
-               socket.send(packet);
-               packet = new DatagramPacket(fireArray, fireArray.length, bcast, 3000);
-               //socket.send(packet);
-            }
-            
-            // Send every 1 sec. Otherwise this will be all over in a fraction of a second.
-            Thread.sleep(3000);
-
-            location = espdu.getEntityLocation();
-            
-            System.out.println("Espdu #" + idx + " EID=[" + eid.getSite() + "," + eid.getApplication() + "," + eid.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);
-//            System.out.println(" Location (lat/lon/alt): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]");
-
-        }
-    }
-    catch(Exception e)
-    {
-        System.out.println(e);
-    }
-        
-}
-
- /**
-    * A number of sites get all snippy about using 255.255.255.255 for a bcast
-    * address; it trips their security software and they kick you off their 
-    * network. (Comcast, NPS.) This determines the bcast address for all
-    * connected interfaces, based on the IP and subnet mask. If you have
-    * a dual-homed host it will return a bcast address for both. If you have
-    * some VMs running on your host this will pick up the addresses for those
-    * as well--eg 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 bcast addresses
-    */
-   public static Set<InetAddress> getBroadcastAddresses()
-   {
-       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
-       Enumeration interfaces;
-       
-       try
-       {
-           interfaces = NetworkInterface.getNetworkInterfaces();
-           
-           while(interfaces.hasMoreElements())
-           {
-               NetworkInterface anInterface = (NetworkInterface)interfaces.nextElement();
-               
-               if(anInterface.isUp())
-               {
-                   Iterator it = anInterface.getInterfaceAddresses().iterator();
-                   while(it.hasNext())
-                   {
-                       InterfaceAddress anAddress = (InterfaceAddress)it.next();
-                       if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
-                           continue;
-                       
-                       //System.out.println("Getting bcast address for " + anAddress);
-                       InetAddress abcast = anAddress.getBroadcast();
-                       if(abcast != null)
-                        bcastAddresses.add(abcast);
-                   }
-               }
-           }
-           
-       }
-       catch(Exception e)
-       {
-           e.printStackTrace();
-           System.out.println(e);
-       }
-       
-       return bcastAddresses;   
-   }
-
-}
+// package edu.nps.moves.examples; // copy example from OpenDIS distribution, modify to serve as template
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import edu.nps.moves.dis.*;
+import edu.nps.moves.disutil.DisTime;
+
+/**
+ * Creates and sends ESPDUs in IEEE binary format. 
+ *
+ * @author DMcG
+ */
+public class Sasala_OpenDisEspduSender1 
+{
+    public static final int NUMBER_TO_SEND = 5000;
+
+    public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
+
+    /** Default multicast group address we send on */
+    public static final String DEFAULT_MULTICAST_GROUP="239.1.2.3";
+   
+    /** Default port we send on */
+    public static final int    DIS_DESTINATION_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 
+     */
+public static void main(String args[])
+{
+    /** 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 radians = 0;
+    
+    // Default settings. These are used if no system properties are set. 
+    // If system properties are passed in, these are over ridden.
+    int port = DIS_DESTINATION_PORT;
+    NetworkMode mode = NetworkMode.BROADCAST;
+    InetAddress destinationIp = null; // must be initialized, even if null
+    
+    try
+    {
+        destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
+    }
+    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)
+            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);
+            }
+        } // 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 idx = 0; idx < NUMBER_TO_SEND; idx++)
+        {
+            // DIS time is a pain in the ass. 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.
+        
+            radians = (radians + (Math.PI/6)) % (2*Math.PI);
+       
+            Vector3Double location = espdu.getEntityLocation();
+            location.setX(Math.cos(radians)*1000);
+            location.setY(Math.sin(radians)*1000);
+            location.setZ(250);
+            
+            // Optionally, we can do some rotation of the entity
+            
+            Orientation orientation = espdu.getEntityOrientation();
+            orientation.setTheta((float)(radians + (Math.PI/2))%(float)(Math.PI *2));
+            
+            // 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 it = broadcastAddresses.iterator();
+            while(it.hasNext())
+            {
+               InetAddress broadcast = (InetAddress)it.next();
+               System.out.println("Sending broadcast datagram packet to " + broadcast);
+               DatagramPacket packet = new DatagramPacket(data, data.length, broadcast, 3000);
+               socket.send(packet);
+			   // TODO experiment with these!  8)
+               packet = new DatagramPacket(fireArray, fireArray.length, broadcast, 3000); // alternate
+               socket.send(packet);
+            }
+            
+            // Send every 1 sec. Otherwise this will be all over in a fraction of a second.
+            Thread.sleep(3000);
+            location = espdu.getEntityLocation();  
+            System.out.println("Espdu #" + idx + " EID=[" + entityID.getSite() + "," + entityID.getApplication() + "," + entityID.getEntity() + "]");
+            System.out.println(" DIS coordinates location=[" + location.getX() + "," + location.getY() + "," + location.getZ() + "]");
+            System.out.println(" Orientation: " + orientation.getTheta());
+            //System.out.println(" Location (lat/lon/alt): [" + lat + ", " + lla[1] + ", " + lla[2] + "]");
+
+        }
+    }
+    catch(IOException | InterruptedException e)
+    {
+        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--eg 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 it = anInterface.getInterfaceAddresses().iterator();
+                   while(it.hasNext())
+                   {
+                       InterfaceAddress anAddress = (InterfaceAddress)it.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)
+       {
+           e.printStackTrace();
+           System.out.println(e);
+       }
+       
+       return broadcastAddresses;   
+   }
+
+}
diff --git a/projects/Assignments/homework3/Sasala_README.md b/projects/Assignments/homework3/Sasala_README.md
new file mode 100644
index 0000000000000000000000000000000000000000..9e62214da8776261af2c6cbc52a43e50e31b8041
--- /dev/null
+++ b/projects/Assignments/homework3/Sasala_README.md
@@ -0,0 +1,29 @@
+## Homework Assignment 3 Checklist
+
+1. [x] Add X3D-Edit as Netbeans Plugin from https://savage.nps.edu/X3D-Edit/#Downloads
+
+2. [x] Optional: checkout Open-DIS-Java library source from https://github.com/open-dis/open-dis-java
+
+3. [x] Otherwise just inspect files of interest from
+   [edu.nps.moves.examples](https://github.com/open-dis/open-dis-java/tree/master/src/main/java/edu/nps/moves/examples)
+
+4. [x] Copy README.md and create YournameREADME.md documentation file...
+
+5. [x] Plan a track of interest - entity travels in a circle and changes heading(orientation) correspondingly 
+
+6. [x] Copy, then Refactor/Rename example file OpenDisEspduSender.java or OpenDisPduSender.java as YourNameSomething.java
+
+7. [x] Modify your example file to produce track PDUs (and be cool)
+
+8. [x] Generate PDUs...
+
+9. [x] Test PDU reading using Wireshark...example below (see also screenshot file)
+
+835	46.316530	172.20.155.227	172.20.159.255	DIS	186	PDUType: 1 	 Entity State, Platform, Land, (1:1:2)
+799	43.208823	172.20.155.227	172.20.159.255	DIS	186	PDUType: 1 	 Entity State, Platform, Land, (1:1:2)
+722	40.094776	172.20.155.227	172.20.159.255	DIS	186	PDUType: 1 	 Entity State, Platform, Land, (1:1:2)
+631	37.026221	172.20.155.227	172.20.159.255	DIS	186	PDUType: 1 	 Entity State, Platform, Land, (1:1:2)
+
+10. [x] Record PDU file using X3D-Edit...
+
+11. [x] Playback PDU file using X3D-Edit...
diff --git a/projects/Assignments/homework3/Tackett_Assignement3_OpenDisPduSender.java b/projects/Assignments/homework3/Tackett_Assignement3_OpenDisPduSender.java
deleted file mode 100644
index ffed87e5b259445042c0a48ea7347feebc8d909c..0000000000000000000000000000000000000000
--- a/projects/Assignments/homework3/Tackett_Assignement3_OpenDisPduSender.java
+++ /dev/null
@@ -1,182 +0,0 @@
-// package edu.nps.moves.examples; // copy example from OpenDIS distribution, modify to serve as template
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-import edu.nps.moves.dis.*;
-import edu.nps.moves.disenum.*;
-
-/**
- * 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.
- *
- * @author DMcG
- * @version $Id:$
- */
-public class Tackett_Assignement3_OpenDisPduSender {
-
-    public static final int    PORT = 3000;
-    public static final String MULTICAST_ADDRESS = "239.1.2.3";
-    private int port;
-    InetAddress multicastAddress;
-
-    public Tackett_Assignement3_OpenDisPduSender(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);
-        }
-    }
-
-    public void run() {
-        try {
-            List<Pdu> generatedPdus = new ArrayList<>();
-
-            // Loop through all the enumerated PDU types, create a PDU for each type,
-            // and add that PDU to a list.
-            for (PduType pdu : PduType.values()) {
-                Pdu aPdu = null;
-
-                switch (pdu) {
-                    case ENTITY_STATE:
-                        // TODO continue to add unit tests
-						EntityStatePdu entityStatePdu = new EntityStatePdu();
-						Marking espduMarking = new Marking();
-						espduMarking.setCharactersString("Testing 123");
-						// TODO libary should warn if > 11 characters
-						entityStatePdu.setMarking(espduMarking);
-						EntityID espduEntityID = new EntityID();
-						espduEntityID.setSite(1);
-						espduEntityID.setApplication(2);
-						espduEntityID.setEntity(3);
-						entityStatePdu.setEntityID(espduEntityID);
-                        // TODO consider adding utility methods to Open-DIS
-						aPdu = entityStatePdu;
-                        break;
-                        
-                    case COMMENT:
-                        aPdu = new CommentPdu();
-                        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) {
-                    generatedPdus.add(aPdu);
-                }
-            }
-
-            // Sort the created PDUs by class name
-            Collections.sort(generatedPdus, new edu.nps.moves.examples.ClassNameComparator());
-
-            // Send the PDUs we created
-            InetAddress localMulticastAddress = InetAddress.getByName(MULTICAST_ADDRESS);
-            MulticastSocket socket = new MulticastSocket(PORT);
-            socket.joinGroup(localMulticastAddress);
-
-            for (int idx = 0; idx < generatedPdus.size(); idx++) {
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                DataOutputStream dos = new DataOutputStream(baos);
-                byte[] buffer;
-
-                Pdu aPdu = generatedPdus.get(idx);
-                aPdu.marshal(dos);
-
-                buffer = baos.toByteArray();
-                DatagramPacket packet = new DatagramPacket(buffer, buffer.length, localMulticastAddress, PORT);
-                socket.send(packet);
-                System.out.println("Sent PDU of type " + aPdu.getClass().getName());
-            }
-
-            // 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);
-        }
-    }
-
-    public static void main(String args[]) {
-        if (args.length == 2) {
-            OpenDisPduSender sender = new  OpenDisPduSender(Integer.parseInt(args[0]), args[1]);
-            sender.run();
-        } else {
-            System.out.println("Usage:   OpenDisPduSender <port> <multicast group>");
-            System.out.println("Default: OpenDisPduSender  " + PORT + "   " + MULTICAST_ADDRESS);
-            OpenDisPduSender sender = new  OpenDisPduSender(PORT, MULTICAST_ADDRESS);
-            sender.run();
-        }
-    }
-}
diff --git a/projects/Assignments/homework3/Tackett_Wireshark.pcapng b/projects/Assignments/homework3/Tackett_Wireshark.pcapng
new file mode 100644
index 0000000000000000000000000000000000000000..6e0277a4267aa4f983d0b68438c1198e7674d99e
Binary files /dev/null and b/projects/Assignments/homework3/Tackett_Wireshark.pcapng differ
diff --git a/projects/Assignments/AngelBlankFP/EspduSenderB.java b/projects/Assignments/homework3/YamashitaDeMouraOpenDisEspduSender.java
similarity index 78%
rename from projects/Assignments/AngelBlankFP/EspduSenderB.java
rename to projects/Assignments/homework3/YamashitaDeMouraOpenDisEspduSender.java
index 80c46213cf5a45176f3ef35307259118c5bd5f9b..bab7c812ecbb2ca0dc6fd49fe0eaf5e94f5a15af 100644
--- a/projects/Assignments/AngelBlankFP/EspduSenderB.java
+++ b/projects/Assignments/homework3/YamashitaDeMouraOpenDisEspduSender.java
@@ -1,4 +1,4 @@
-package java.edu.nps.moves.examples;
+package homework3;
 
 import java.io.*;
 import java.net.*;
@@ -9,28 +9,33 @@ import edu.nps.moves.disutil.CoordinateConversions;
 import edu.nps.moves.disutil.DisTime;
 
 /**
- * Creates and sends ESPDUs in IEEE binary format. 
- *
- * @author DMcG
+ * MV3500
+ * 
+ * Creates and sends ESPDUs in IEEE binary format.
+ * 
+ * @author Douglas Yamashita de Moura
+ * @version 20180306
+ * 
  */
-public class EspduSenderB 
+
+public class YamashitaDeMouraOpenDisEspduSender 
 {
     public static final int NUMBER_TO_SEND = 5000;
 
     public enum NetworkMode{UNICAST, MULTICAST, BROADCAST};
 
-    /** default multicast group we send on */
+    /** Default multicast group address we send on */
     public static final String DEFAULT_MULTICAST_GROUP="239.1.2.3";
    
-    /** Port we send on */
+    /** Default port we send on */
     public static final int    DIS_DESTINATION_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 mcast.
-     *                To determine bcast destination IP, use an online bcast address
-     *                caclulator, for example http://www.remotemonitoringsystems.ca/broadcast.php
-     *                If in mcast mode, a join() will be done on the mcast address.
+     * 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 
      */
@@ -38,26 +43,26 @@ public static void main(String args[])
 {
     /** an entity state pdu */
     EntityStatePdu espdu = new EntityStatePdu();
-    MulticastSocket socket = null;
-    DisTime disTime = DisTime.getInstance();
+    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;
-
+    double hei = 0.0;
     
     // Default settings. These are used if no system properties are set. 
     // If system properties are passed in, these are over ridden.
     int port = DIS_DESTINATION_PORT;
     NetworkMode mode = NetworkMode.BROADCAST;
-    InetAddress destinationIp = null;
+    InetAddress destinationIp = null; // must be initialized, even if null
     
     try
     {
         destinationIp = InetAddress.getByName(DEFAULT_MULTICAST_GROUP);
     }
-    catch(Exception e)
+    catch(UnknownHostException e)
     {
         System.out.println(e + " Cannot create multicast address");
         System.exit(0);
@@ -75,7 +80,6 @@ public static void main(String args[])
     // Network mode: unicast, multicast, broadcast
     String networkModeString = systemProperties.getProperty("networkMode"); // unicast or multicast or broadcast
         
-
     // Set up a socket to send information
     try
     {
@@ -84,7 +88,7 @@ public static void main(String args[])
             port = Integer.parseInt(portString);
         
         socket = new MulticastSocket(port);
-        
+       
         // Where we send packets to, the destination IP address
         if(destinationIpString != null)
         {
@@ -92,6 +96,7 @@ public static void main(String args[])
         }
 
         // Type of transport: unicast, broadcast, or multicast
+		// TODO convert to String constants
         if(networkModeString != null)
         {
             if(networkModeString.equalsIgnoreCase("unicast"))
@@ -107,11 +112,10 @@ public static void main(String args[])
                 }
                 
                 socket.joinGroup(destinationIp);
-                
             }
         } // end networkModeString
     }
-    catch(Exception e)
+    catch(IOException | RuntimeException e)
     {
         System.out.println("Unable to initialize networking. Exiting.");
         System.out.println(e);
@@ -127,10 +131,10 @@ public static void main(String args[])
     // 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 eid = espdu.getEntityID();
-    eid.setSite(1);  // 0 is apparently not a valid site number, per the spec
-    eid.setApplication(1); 
-    eid.setEntity(2); 
+    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,
@@ -140,14 +144,14 @@ public static void main(String args[])
     // 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
+    entityType.setCountry(29);               // Brazil
+    entityType.setDomain((short)2);          // Air (vs land, surface, subsurface, space)
+    entityType.setCategory((short)2);        // Attack/Strike
+    entityType.setSubcategory((short)1);     // Embraer Super Tucano
+    //entityType.setSpec((short)3);            // M1A2 Abrams
     
 
-    Set<InetAddress> bcastAddresses = getBroadcastAddresses();
+    Set<InetAddress> broadcastAddresses;
     // Loop through sending N ESPDUs
     try
     {
@@ -176,8 +180,8 @@ public static void main(String args[])
 
             // An alterative approach: actually follow the standard. It's a crazy concept,
             // but it might just work.
-            int ts = disTime.getDisAbsoluteTimestamp();
-            espdu.setTimestamp(ts);
+            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
@@ -201,14 +205,18 @@ public static void main(String args[])
 
             double direction = Math.pow((double)(-1.0), (double)(idx));
             lon = lon + (direction * 0.00006);
-            System.out.println(lon);
+            //System.out.println(lon);
             
-            double disCoordinates[] = CoordinateConversions.getXYZfromLatLonDegrees(lat, lon, 1.0);
+            // Rate of climb (RoC) (up to 10 m/s)
+            double roc = Math.floor(Math.random()*Math.floor(10));
+            hei = hei + roc;
+            
+            double disCoordinates[] = CoordinateConversions.getXYZfromLatLonDegrees(lat, lon, hei);
             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("lat, lon, hei:" + lat + ", " + lon + ", " + hei);
             System.out.println("DIS coord:" + disCoordinates[0] + ", " + disCoordinates[1] + ", " + disCoordinates[2]);
 
             // Optionally, we can do some rotation of the entity
@@ -236,16 +244,17 @@ public static void main(String args[])
             // datagram and send it.
             byte[] data = baos.toByteArray();
 
-            bcastAddresses = getBroadcastAddresses();
-            Iterator it = bcastAddresses.iterator();
+            broadcastAddresses = getBroadcastAddresses();
+            Iterator it = broadcastAddresses.iterator();
             while(it.hasNext())
             {
-               InetAddress bcast = (InetAddress)it.next();
-               System.out.println("Sending bcast to " + bcast);
-               DatagramPacket packet = new DatagramPacket(data, data.length, bcast, 3000);
+               InetAddress broadcast = (InetAddress)it.next();
+               System.out.println("Sending broadcast datagram packet to " + broadcast + "\n");
+               DatagramPacket packet = new DatagramPacket(data, data.length, broadcast, 3000);
+               socket.send(packet);
+			   // TODO experiment with these!  8)
+               packet = new DatagramPacket(fireArray, fireArray.length, broadcast, 3000); // alternate
                socket.send(packet);
-               packet = new DatagramPacket(fireArray, fireArray.length, bcast, 3000);
-               //socket.send(packet);
             }
             
             // Send every 1 sec. Otherwise this will be all over in a fraction of a second.
@@ -253,7 +262,7 @@ public static void main(String args[])
 
             location = espdu.getEntityLocation();
             
-            System.out.println("Espdu #" + idx + " EID=[" + eid.getSite() + "," + eid.getApplication() + "," + eid.getEntity() + "]");
+            System.out.println("Espdu #" + idx + " 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);
@@ -261,7 +270,7 @@ public static void main(String args[])
 
         }
     }
-    catch(Exception e)
+    catch(IOException | InterruptedException e)
     {
         System.out.println(e);
     }
@@ -269,20 +278,20 @@ public static void main(String args[])
 }
 
  /**
-    * A number of sites get all snippy about using 255.255.255.255 for a bcast
+    * 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 bcast address for all
+    * 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 bcast address for both. 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--eg 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 bcast addresses
+    * @return set of all broadcast addresses
     */
    public static Set<InetAddress> getBroadcastAddresses()
    {
-       Set<InetAddress> bcastAddresses = new HashSet<InetAddress>();
+       Set<InetAddress> broadcastAddresses = new HashSet<>();
        Enumeration interfaces;
        
        try
@@ -302,22 +311,22 @@ public static void main(String args[])
                        if((anAddress == null || anAddress.getAddress().isLinkLocalAddress()))
                            continue;
                        
-                       //System.out.println("Getting bcast address for " + anAddress);
-                       InetAddress abcast = anAddress.getBroadcast();
-                       if(abcast != null)
-                        bcastAddresses.add(abcast);
+                       //System.out.println("Getting broadcast address for " + anAddress);
+                       InetAddress broadcastAddress = anAddress.getBroadcast();
+                       if(broadcastAddress != null)
+                          broadcastAddresses.add(broadcastAddress);
                    }
                }
            }
            
        }
-       catch(Exception e)
+       catch(SocketException e)
        {
            e.printStackTrace();
            System.out.println(e);
        }
        
-       return bcastAddresses;   
+       return broadcastAddresses;   
    }
 
 }
diff --git a/projects/Assignments/homework3/YamashitaDeMouraOutputNetBeansWireshark.PNG b/projects/Assignments/homework3/YamashitaDeMouraOutputNetBeansWireshark.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..b1b81965d57beb5341ad244d5e506ad0ec8a309f
Binary files /dev/null and b/projects/Assignments/homework3/YamashitaDeMouraOutputNetBeansWireshark.PNG differ
diff --git a/projects/Assignments/homework3/YamashitaDeMouraREADME.md b/projects/Assignments/homework3/YamashitaDeMouraREADME.md
new file mode 100644
index 0000000000000000000000000000000000000000..595278a45520b04e2a4eea4bddaf943e980874fd
--- /dev/null
+++ b/projects/Assignments/homework3/YamashitaDeMouraREADME.md
@@ -0,0 +1,30 @@
+## Homework Assignment 3 Checklist
+
+1. [x] Add X3D-Edit as Netbeans Plugin from https://savage.nps.edu/X3D-Edit/#Downloads
+
+1. [x] Optional: checkout Open-DIS-Java library source from https://github.com/open-dis/open-dis-java
+
+1. [x] Otherwise just inspect files of interest from
+   [edu.nps.moves.examples](https://github.com/open-dis/open-dis-java/tree/master/src/main/java/edu/nps/moves/examples)
+
+1. [x] Copy README.md and create YournameREADME.md documentation file...
+
+1. [x] Plan a track of interest, described in YournameREADME.md documentation file...
+
+1. [x] Copy, then Refactor/Rename example file OpenDisEspduSender.java or OpenDisPduSender.java as YourNameSomething.java
+
+1. [x] Modify your example file to produce track PDUs (and be cool)
+
+1. [x] Generate PDUs...
+
+1. [x] Test PDU reading using Wireshark...
+
+1. [ ] Record PDU file using X3D-Edit...
+
+1. [ ] Playback PDU file using X3D-Edit...
+
+Track of interest: 
+- Brazilian Attack/Strike Embraer Super Tucano
+
+Note: 
+- The height of the aircraft is increasing on RoC (Rate of Climb) up to 10 m/s
\ No newline at end of file