diff --git a/projects/Assignments/FinalProjects/2018March/LandasTackettDeMoura/README.md b/projects/Assignments/FinalProjects/2018March/LandasTackettDeMoura/README.md index a704e52cd0e75e5a801b3642b756d0b74085a1da..7f0070db61af6e51933857077e87c52f353bdd79 100644 --- a/projects/Assignments/FinalProjects/2018March/LandasTackettDeMoura/README.md +++ b/projects/Assignments/FinalProjects/2018March/LandasTackettDeMoura/README.md @@ -1,7 +1,46 @@ -## Final Course Projects 2018March +MV3500 - Internetwork Communications and Simulation +Prof. Dr. Don Brutzman -Create a dedicated subdirectory for each individual or team project. +Landas, Enrico +Tacket, Cody +Yamashita de Moura, Douglas -Example: `SmithJones` +Final Project +Adapt a Unity or Other Program to Emit PDUs Using Open-DIS C# Binding -See the course syllabus for details on how to document your project. +Two C# scripts, Sender.cs and Receiver.cs, were created to send and receive +PDUs, respectively. The following data is included: + +Sender.cs +- IP Address: 239.1.2.3 +- Port: 3000 +- EntityID.Entity: 1 + +Receiver.cs +- IP Address: 239.1.2.3 +- Port: 3000 +- EntityID.Entity: 2 + +For the project purpose, the scripts were implemented in such a way that all +multicast information is enclosed on the scripts and only selected information +is processed and printed on the screen. Each computer will print the data +from the entity that is different from the one it is sending. + +Unity Project +- The Unity package can be downloaded from: +- https://owncloud.nps.edu/owncloud/index.php/s/mewLa2BUEWhucPa + +Video +- A video showing two applications working can be found at the Video folder +of the Unity package + +TO-DO List +- Create an Unity interface to receive input data: IP address, port, etc +- Transform the object location to real world location (using latitude, +longitude and altitude) +- Replace the 'InvokeRepeating' method using a thread (when creating a sender +and a client on the same computer, this method may not work properly, i.e., +the interval between the calls could be different from the expected) +- Implement creation of the received object on the Receiver.cs (or other +interface to be created) +- Implement control of the object (NavySeal guy) using keyboard/mouse \ No newline at end of file diff --git a/projects/Assignments/FinalProjects/2018March/LandasTackettDeMoura/Receiver.cs b/projects/Assignments/FinalProjects/2018March/LandasTackettDeMoura/Receiver.cs new file mode 100644 index 0000000000000000000000000000000000000000..8504e9fd0d29c75f99b2a87d8ad096203150c25d --- /dev/null +++ b/projects/Assignments/FinalProjects/2018March/LandasTackettDeMoura/Receiver.cs @@ -0,0 +1,100 @@ +using System; +using UnityEngine; +using System.Net; +using System.Net.Sockets; +using OpenDis.Core; +using OpenDis.Dis1998; +using OpenDis.Enumerations; +using UnityEngine.UI; + +public class Receiver : MonoBehaviour { + + UdpClient client; + IPEndPoint localEp; + EntityStatePdu newEntityStatePDU; + IPAddress multicastaddress; + PduProcessor pduProcessor; + int PDU_TYPE_POSITION = 2; + public GameObject locationText; + Vector3Double location; + EntityID entityID; + EntityType entityType; + + // Use this for initialization + public void onClick () { + + Debug.Log("Start receiving..."); + + // Create UDP Client to receive data + client = new UdpClient(); + client.ExclusiveAddressUse = false; + localEp = new IPEndPoint(IPAddress.Any, 3000); + client.Client.SetSocketOption(SocketOptionLevel.Socket, + SocketOptionName.ReuseAddress, true); + client.ExclusiveAddressUse = false; + client.Client.Bind(localEp); + multicastaddress = IPAddress.Parse("239.1.2.3"); + client.JoinMulticastGroup(multicastaddress); + locationText = GameObject.FindGameObjectWithTag("ReceiverLocationText"); + + // Broadcast IP - Client + InvokeRepeating("BroadcastClientIP", 0, 1f); + } + + // Receive data + void BroadcastClientIP() + { + try + { + if(client.Available > 0) + { + // Blocks until a message returns on this socket from a remote host. + Byte[] receivedBytes = client.Receive(ref localEp); + + if(receivedBytes != null && receivedBytes.Length > 0) + { + try + { + PduType pduType = (PduType)receivedBytes[PDU_TYPE_POSITION]; + Pdu pdu = PduProcessor.UnmarshalRawPdu(pduType, receivedBytes, Endian.Big); + switch ((PduType)pdu.PduType) + { + case PduType.EntityState: + ProcessEntityStatePdu((EntityStatePdu)pdu); + SetLocationText(); + break; + default: + break; + } + } catch (Exception e) + { + Debug.LogError(e.ToString()); + } + } + } + } + catch (Exception e) + { + Debug.LogError(e.ToString()); + } + } + + // Process Entity State PDU + void ProcessEntityStatePdu(EntityStatePdu espdu) + { + entityID = espdu.EntityID; + entityType = espdu.EntityType; + location = espdu.EntityLocation; + } + + // Print NavySeal info on screen + void SetLocationText() + { + if (entityID.Entity != 1) + { + locationText.GetComponent<Text>().text = String.Format("NAVY SEAL RECEIVER\nID: {0}\nCountry: {1}\nCategory: {2}\nLocation: ({3}, {4}, {5})", entityID.Entity.ToString(), entityType.Country.ToString(), entityType.Category.ToString(), location.X.ToString("F2"), location.Y.ToString("F2"), location.Z.ToString("F2")); + Debug.Log(String.Format("NAVY SEAL RECEIVER\nID: {0}\nCountry: {1}\nCategory: {2}\nLocation: ({3}, {4}, {5})", entityID.Entity.ToString(), entityType.Country.ToString(), entityType.Category.ToString(), location.X.ToString("F2"), location.Y.ToString("F2"), location.Z.ToString("F2"))); + } + } + +} diff --git a/projects/Assignments/FinalProjects/2018March/LandasTackettDeMoura/Sender.cs b/projects/Assignments/FinalProjects/2018March/LandasTackettDeMoura/Sender.cs new file mode 100644 index 0000000000000000000000000000000000000000..fb98d126cf787192e6fb9640112bd24686d5e8a3 --- /dev/null +++ b/projects/Assignments/FinalProjects/2018March/LandasTackettDeMoura/Sender.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using System.Net; +using System.Net.Sockets; +using System.Text; +using OpenDis.Dis1998; +using OpenDis.Core; +using System.IO; +using System.Threading; +using UnityEngine.UI; + +public class Sender : MonoBehaviour { + + UdpClient sender; + string serverIP; + int broadcastPort = 3000; + IPEndPoint remoteEP; + string data = ""; + public GameObject locationText; + EntityStatePdu espdu; + EntityID entityID; + EntityType entityType; + + //NavySeal object and position + public GameObject NavySeal; + private double x; + private double y; + private double z; + + void Start() { + + // Get Navy Seal object + NavySeal = GameObject.FindGameObjectWithTag("NavySealPrefab"); + + // Create new entity state and set exercise + espdu = new EntityStatePdu(); + espdu.ExerciseID = 1; + + // Create and set entity marking + Marking myMarking = new Marking(); + myMarking.CharacterSet = 1; + String markingTest = "Test"; + myMarking.Characters = Encoding.UTF8.GetBytes(markingTest); + espdu.Marking = myMarking; + + // Get time stamp + espdu.Timestamp = (uint)DateTimeOffset.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds; + + // Set entity ID parameters + entityID = espdu.EntityID; + entityID.Site = 1; + entityID.Application = 1; + entityID.Entity = 1; + + // Set entity type parameters + entityType = espdu.EntityType; + entityType.EntityKind = 1; + entityType.Country = 225; + entityType.Domain = 1; + entityType.Category = 1; + entityType.Subcategory = 20; + entityType.Specific = 3; + + locationText = GameObject.FindGameObjectWithTag("SenderLocationText"); + } + + // Use this for initialization + public void onClick () { + Debug.Log("Starting multicasting..."); + + //Create UDP Client for broadcasting the server + sender = new UdpClient(); + IPAddress groupIP = IPAddress.Parse("239.1.2.3"); + sender.JoinMulticastGroup(groupIP); + remoteEP = new IPEndPoint(groupIP, broadcastPort); + + //Broadcast IP - Server + InvokeRepeating("BroadcastServerIP", 0, 1f); + } + + // Prepare and send data + void BroadcastServerIP() + { + // Get and print entity position + x = NavySeal.transform.position.x; + y = NavySeal.transform.position.y; + z = NavySeal.transform.position.z; + //Debug.Log(NavySeal.transform.position); + + // Set entity location + Vector3Double location = espdu.EntityLocation; + location.X = x; + location.Y = y; + location.Z = z; + + // Get time stamp + espdu.Timestamp = (uint)DateTimeOffset.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds; + + //Prepare output + DataOutputStream dos = new DataOutputStream(Endian.Big); + espdu.MarshalAutoLengthSet(dos); + + // Transmit messages + byte[] buffer = dos.ConvertToBytes(); + sender.Send(buffer, buffer.Length, remoteEP); + //Debug.Log(Time.realtimeSinceStartup + ": Sent broadcast data: " + espdu); + + SetLocationText(); + } + + // Print NavySeal info on screen + void SetLocationText() + { + locationText.GetComponent<Text>().text = String.Format("NAVY SEAL SENDER\nID: {0}\nCountry: {1}\nCategory: {2}\nLocation: ({3}, {4}, {5})", entityID.Entity.ToString(), entityType.Country.ToString(), entityType.Category.ToString(), x.ToString("F2"), y.ToString("F2"), z.ToString("F2")); + Debug.Log(String.Format("NAVY SEAL SENDER\nID: {0}\nCountry: {1}\nCategory: {2}\nLocation: ({3}, {4}, {5})", entityID.Entity.ToString(), entityType.Country.ToString(), entityType.Category.ToString(), x.ToString("F2"), y.ToString("F2"), z.ToString("F2"))); + } + +}