Skip to content
Snippets Groups Projects
Commit 54b08bfc authored by bkii's avatar bkii
Browse files

Merge origin/master

parents 06d7ac54 ee626611
No related branches found
No related tags found
No related merge requests found
......@@ -9,81 +9,76 @@ import java.io.IOException;
import java.util.Scanner;
/**
* PduSaver.java created on Aug 21, 2019
* MOVES Institute Naval Postgraduate School, Monterey, CA, USA www.nps.edu
* PduSaver.java created on Aug 21, 2019 MOVES Institute Naval Postgraduate
* School, Monterey, CA, USA www.nps.edu
*
* @author Mike Bailey, jmbailey@nps.edu
* @version $Id$
*/
public class PduListenerSaver
{
private final static String DEFAULT_OUTPUTDIR = "pduLog";
private final static String MCAST_ADDR = "239.1.2.3";
private final static int DIS_PORT = 3000;
public class FetterolfPduListenerSaver {
private enum mystate
{
RUNNING,
PAUSED;
}
private final static String DEFAULT_OUTPUTDIR = "pduLog";
private final static String MCAST_ADDR = "239.1.2.3";
private final static int DIS_PORT = 3000;
public static void main(String[] args)
{
String outDir = DEFAULT_OUTPUTDIR;
String mcast = MCAST_ADDR;
int port = DIS_PORT;
System.out.println("DisExamplesOpenDis7.PduListenerSaver started...");
switch (args.length) {
case 0:
break;
case 1:
outDir = args[0];
break;
case 3:
outDir = args[0];
mcast = args[1];
port = Integer.parseInt(args[2]);
break;
default:
System.err.println("Usage: PduListener() or PduListener(\"outputdir\") or PduListener(\"outputdir\",\"multicast address\", ipPort");
System.exit(1);
private enum mystate {
RUNNING,
PAUSED;
}
System.out.println("Beginning pdu save to directory " + outDir);
try {
Recorder recorder = new Recorder(outDir, mcast, port);
public static void main(String[] args) {
String outDir = DEFAULT_OUTPUTDIR;
String mcast = MCAST_ADDR;
int port = DIS_PORT;
recorder.startResume();
mystate state = mystate.RUNNING;
System.out.println("* recorder.startResume(), state=RUNNING, recording in progress...");
Scanner scan = new Scanner(System.in);
System.out.println("DisExamplesOpenDis7.PduListenerSaver started...");
while (true) {
System.out.println("Warning: you must quit when complete, otherwise recorded PDUs are lost!");
System.out.println("Type p/enter to pause, r/enter to resume, q/enter to stop recording, save and quit");
String line = scan.nextLine();
if (line.equalsIgnoreCase("p") && state == mystate.RUNNING) {
recorder.stopPause();
state = mystate.PAUSED;
System.out.println("* recorder.stopPause(), state=PAUSED, recording paused...");
}
else if (line.equalsIgnoreCase("r") && state == mystate.PAUSED) {
recorder.startResume();
state = mystate.RUNNING;
System.out.println("* recorder.startResume(), state=RUNNING, recording in progress...");
switch (args.length) {
case 0:
break;
case 1:
outDir = args[0];
break;
case 3:
outDir = args[0];
mcast = args[1];
port = Integer.parseInt(args[2]);
break;
default:
System.err.println("Usage: PduListener() or PduListener(\"outputdir\") or PduListener(\"outputdir\",\"multicast address\", ipPort");
System.exit(1);
}
else if (line.equalsIgnoreCase("q")) {
recorder.end();
System.out.println("* recorder.end(), recording complete.");
break;
System.out.println("Beginning pdu save to directory " + outDir);
try {
Recorder recorder = new Recorder(outDir, mcast, port);
recorder.startResume();
mystate state = mystate.RUNNING;
System.out.println("* recorder.startResume(), state=RUNNING, recording in progress...");
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("Warning: you must quit when complete, otherwise recorded PDUs are lost!");
System.out.println("Type p/enter to pause, r/enter to resume, q/enter to stop recording, save and quit");
String line = scan.nextLine();
if (line.equalsIgnoreCase("p") && state == mystate.RUNNING) {
recorder.stopPause();
state = mystate.PAUSED;
System.out.println("* recorder.stopPause(), state=PAUSED, recording paused...");
} else if (line.equalsIgnoreCase("r") && state == mystate.PAUSED) {
recorder.startResume();
state = mystate.RUNNING;
System.out.println("* recorder.startResume(), state=RUNNING, recording in progress...");
} else if (line.equalsIgnoreCase("q")) {
recorder.end();
System.out.println("* recorder.end(), recording complete.");
break;
}
}
System.out.println("Ending pdu save to " + recorder.getLogFile());
} catch (IOException ex) {
System.err.println("*** Exception: " + ex.getClass().getSimpleName() + ": " + ex.getLocalizedMessage());
}
}
System.out.println("Ending pdu save to "+recorder.getLogFile());
}
catch (IOException ex) {
System.err.println("*** Exception: " + ex.getClass().getSimpleName() + ": " + ex.getLocalizedMessage());
}
}
}
......@@ -8,87 +8,82 @@ import edu.nps.moves.dis7.enumerations.*;
import edu.nps.moves.dis7.util.*;
import java.util.ArrayList;
public class AllPduReceiver
{
public static final int DEFAULT_MULTICAST_PORT = AllPduSender.DEFAULT_MULTICAST_PORT;
public static final String DEFAULT_MULTICAST_ADDRESS = AllPduSender.DEFAULT_MULTICAST_ADDRESS;
public static final boolean USE_FAST_ESPDU = false;
public class FetterolfPduReceiver {
public static void main(String args[])
{
PduFactory factory;
MulticastSocket socket;
InetAddress address;
DatagramPacket packet;
public static final int DEFAULT_MULTICAST_PORT = FetterolfPduReceiver.DEFAULT_MULTICAST_PORT;
public static final String DEFAULT_MULTICAST_ADDRESS = FetterolfPduReceiver.DEFAULT_MULTICAST_ADDRESS;
public static final boolean USE_FAST_ESPDU = false;
try {
System.out.println("DisExamplesOpenDis7.AllPduReceiver started...");
if (args.length == 2) {
socket = new MulticastSocket(Integer.parseInt(args[0]));
address = InetAddress.getByName(args[1]);
}
else {
System.out.println("Usage: AllPduReceiver <port> <multicast group>");
System.out.println("Default: AllPduReceiver " + DEFAULT_MULTICAST_PORT + " " + DEFAULT_MULTICAST_ADDRESS);
socket = new MulticastSocket(DEFAULT_MULTICAST_PORT);
address = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS);
}
socket.joinGroup(address);
public static void main(String args[]) {
PduFactory factory;
MulticastSocket socket;
InetAddress address;
DatagramPacket packet;
factory = new PduFactory();
try {
System.out.println("DisExamplesOpenDis7.AllPduReceiver started...");
if (args.length == 2) {
socket = new MulticastSocket(Integer.parseInt(args[0]));
address = InetAddress.getByName(args[1]);
} else {
System.out.println("Usage: AllPduReceiver <port> <multicast group>");
System.out.println("Default: AllPduReceiver " + DEFAULT_MULTICAST_PORT + " " + DEFAULT_MULTICAST_ADDRESS);
socket = new MulticastSocket(DEFAULT_MULTICAST_PORT);
address = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS);
}
socket.joinGroup(address);
while (true) // Loop infinitely, receiving datagrams
{
byte buffer[] = new byte[1500]; // typical MTU size
factory = new PduFactory();
packet = new DatagramPacket(buffer, buffer.length); // reset
while (true) // Loop infinitely, receiving datagrams
{
byte buffer[] = new byte[1500]; // typical MTU size
socket.receive(packet);
packet = new DatagramPacket(buffer, buffer.length); // reset
Pdu pdu = factory.createPdu(packet.getData());
if (pdu != null)
{
DISPDUType currentPduType = pdu.getPduType(); //short currentPduType = pdu.getPduType();
String currentPduTypeName = pdu.getClass().getName();
DISProtocolFamily currentProtocolFamilyID = pdu.getProtocolFamily(); //short currentProtocolFamilyID = pdu.getProtocolFamily();
String currentPduFamilyName = pdu.getClass().getSuperclass().getSimpleName();
socket.receive(packet);
StringBuilder message = new StringBuilder();
message.append("received DIS PDU ");
if (currentPduType.getValue() < 10)
message.append(" "); // column spacing
message.append(currentPduType.getValue());
String currentPduTypePadded = String.format("%-34s", currentPduType); // - indicates right padding of whitespace
message.append(" " ).append(currentPduTypePadded);
String currentPduTypeNamePadded = String.format("%-49s", currentPduTypeName); // - indicates right padding of whitespace
message.append(" of type ").append(currentPduTypeNamePadded); // package.class name
message.append(" (protocolFamily ").append(currentProtocolFamilyID);
// message.append(" ").append(currentPduFamilyName); // class name is also available
message.append(")");
System.out.println(message.toString());
Pdu pdu = factory.createPdu(packet.getData());
if (pdu != null) {
DISPDUType currentPduType = pdu.getPduType(); //short currentPduType = pdu.getPduType();
String currentPduTypeName = pdu.getClass().getName();
DISProtocolFamily currentProtocolFamilyID = pdu.getProtocolFamily(); //short currentProtocolFamilyID = pdu.getProtocolFamily();
String currentPduFamilyName = pdu.getClass().getSuperclass().getSimpleName();
switch (currentPduType) // using enumeration values from edu.​nps.​moves.​dis7.​enumerations.​DISPDUType
{
case COMMENT:
CommentPdu commentPdu = (CommentPdu)pdu; // cast to precise type
ArrayList<VariableDatum> payloadList = (ArrayList)commentPdu.getVariableDatums();
for (VariableDatum variableDatum : payloadList)
StringBuilder message = new StringBuilder();
message.append("received DIS PDU ");
if (currentPduType.getValue() < 10) {
message.append(" "); // column spacing
}
message.append(currentPduType.getValue());
String currentPduTypePadded = String.format("%-34s", currentPduType); // - indicates right padding of whitespace
message.append(" ").append(currentPduTypePadded);
String currentPduTypeNamePadded = String.format("%-49s", currentPduTypeName); // - indicates right padding of whitespace
message.append(" of type ").append(currentPduTypeNamePadded); // package.class name
message.append(" (protocolFamily ").append(currentProtocolFamilyID);
// message.append(" ").append(currentPduFamilyName); // class name is also available
message.append(")");
System.out.println(message.toString());
switch (currentPduType) // using enumeration values from edu.​nps.​moves.​dis7.​enumerations.​DISPDUType
{
String nextComment = new String(variableDatum.getVariableDatumValue()); // convert byte[] to String
System.out.println("\"" + nextComment + "\"");
case COMMENT:
CommentPdu commentPdu = (CommentPdu) pdu; // cast to precise type
ArrayList<VariableDatum> payloadList = (ArrayList) commentPdu.getVariableDatums();
for (VariableDatum variableDatum : payloadList) {
String nextComment = new String(variableDatum.getVariableDatumValue()); // convert byte[] to String
System.out.println("\"" + nextComment + "\"");
}
}
} else {
System.out.println("received packet but pdu is null, packet.getData().length=" + packet.getData().length + ", error...");
}
}
} catch (IOException e) {
System.out.println("Problem with DisExamplesOpenDis7.AllPduReceiver, see exception trace:");
System.out.println(e);
} finally {
System.out.println("DisExamplesOpenDis7.AllPduReceiver complete.");
}
else
System.out.println("received packet but pdu is null, packet.getData().length=" + packet.getData().length + ", error...");
}
}
catch (IOException e) {
System.out.println("Problem with DisExamplesOpenDis7.AllPduReceiver, see exception trace:");
System.out.println(e);
}
finally {
System.out.println("DisExamplesOpenDis7.AllPduReceiver complete.");
}
}
}
......@@ -8,68 +8,67 @@ import edu.nps.moves.dis7.*;
import edu.nps.moves.dis7.enumerations.*;
/**
* This is an example that sends many/most types of PDUs. Useful for testing standards
* compliance or getting a full set of PDUs. It also writes the generated PDUs to an XML file.
* Adapted from OpenDIS library example package edu.nps.moves.examples
* This is an example that sends many/most types of PDUs. Useful for testing
* standards compliance or getting a full set of PDUs. It also writes the
* generated PDUs to an XML file. Adapted from OpenDIS library example package
* edu.nps.moves.examples
*
* @author DMcG
* @version $Id:$
*/
public class AllPduSender
{
/** Default multicast group address we send on. */
public class FetterolfPduSender {
/**
* Default multicast group address we send on.
*/
public static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3";
/** Default multicast port used, matches Wireshark DIS capture default */
public static final int DEFAULT_MULTICAST_PORT = 3000;
/**
* Default multicast port used, matches Wireshark DIS capture default
*/
public static final int DEFAULT_MULTICAST_PORT = 3000;
private int port;
InetAddress multicastAddress;
public AllPduSender(int port, String multicast) {
try
{
public FetterolfPduSender(int port, String multicast) {
try {
this.port = port;
multicastAddress = InetAddress.getByName(multicast);
if (!multicastAddress.isMulticastAddress())
{
if (!multicastAddress.isMulticastAddress()) {
System.out.println("Not a multicast address: " + multicast);
}
}
catch (UnknownHostException e) {
} catch (UnknownHostException e) {
System.out.println("Unable to open socket: " + e);
}
}
public void run()
{
System.out.println("DisExamplesOpenDis7.AllPduSender started...");
try
{
public void run() {
System.out.println("DisExamplesOpenDis7.AllPduSender started...");
try {
System.out.println("Generate PDUs and note issues, if any...");
List<Pdu> generatedPdusList = new ArrayList<>();
// Loop through all the enumerated PDU types, create a PDU for each type,
// add that PDU to generatedPdusList, and send each one
for (DISPDUType pdu : DISPDUType.values())
{
for (DISPDUType pdu : DISPDUType.values()) {
// System.out.println("PDU " + pdu.getValue() + " " + pdu.name() + " " + pdu.getDescription()); // diagnostic
Pdu aPdu = null; // edu.​nps.​moves7.​dis.PDU superclass for all PDUs, in preparation for custom assignment
try {
switch (pdu) // using enumeration values from edu.​nps.​moves.​dis7.​enumerations.​DISPDUType
{
case OTHER: // 0
System.out.println ("*** Note: DISPDUType." + pdu.name() + " not supported"); // TODO why was this received?
System.out.println("*** Note: DISPDUType." + pdu.name() + " not supported"); // TODO why was this received?
// nothing to send
break;
case ENTITY_STATE: // 1
aPdu = new EntityStatePdu();
EntityStatePdu espdu = (EntityStatePdu) aPdu;
EntityMarking entityMarking = new EntityMarking ();
EntityMarking entityMarking = new EntityMarking();
entityMarking.setCharacters("AllPduSender".getBytes()); //entityMarking.setCharacters(Byte.valueOf("0")); // 11 characters max?
espdu.setMarking(entityMarking);
......@@ -82,73 +81,67 @@ public class AllPduSender
// TODO how to set azimuth, i.e. course direction over ground?
break;
//added in different PDUs from the jar file.
case COLLISION:
aPdu = new CollisionPdu();
break;
case TRANSMITTER:
aPdu = new TransmitterPdu();
break;
case ACKNOWLEDGE:
aPdu = new AcknowledgePdu();
break;
case RECEIVER:
aPdu = new ReceiverPdu();
break;
case COMMENT:
// aPdu = new CommentPdu(); // default for this switch logic
// see Garrett Loffelman and Pete Severson's code for OpenDis version 4 example
// https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/tree/master/assignments/src/MV3500Cohort2018JulySeptember/projects/LoeffelmanSeverson
CommentPdu newCommentPdu = new CommentPdu();
CommentPdu newCommentPdu = new CommentPdu();
ArrayList<VariableDatum> payloadList = new ArrayList<VariableDatum>();
ArrayList<String> commentsList = new ArrayList<>();
commentsList.add("Hello CommentPDU");
commentsList.add("Here is a new message");
if (!commentsList.isEmpty())
if (!commentsList.isEmpty()) {
System.out.println("Preparing CommentPDU:");
}
for (String comment : commentsList)
{
for (String comment : commentsList) {
VariableDatum newVariableDatum = new VariableDatum();
newVariableDatum.setVariableDatumValue (comment.getBytes()); // conversion
newVariableDatum.setVariableDatumLength(comment.getBytes().length * 8); // bits, not bytes, see spec and javadoc
newVariableDatum.setVariableDatumValue(comment.getBytes()); // conversion
newVariableDatum.setVariableDatumLength(comment.getBytes().length * 8); // bits, not bytes, see spec and javadoc
// alternatively, you do not need to set this and the marshaller will figure it out from the byte array
// (see javadoc for VariableDatum.setVariableDatumLength())
payloadList.add(newVariableDatum);
System.out.println(" \"" + comment + "\"");
}
newCommentPdu.setVariableDatums(payloadList);
aPdu = newCommentPdu; // hand off for sending
break;
//commented out this warning message
// default:
// System.out.println("*** Warning: PDU " + pdu.getValue() + " " + pdu + " not supported, created or sent ");
// code generation block for this class follows:
// code generation block for this class follows:
// System.out.println(" case " + pdu + ": // " + pdu.getValue());
// System.out.println(" aPdu = new " + pdu.getDescription().replace(" ","").replace("-","").replace("/","") +
// "Pdu();");
// System.out.println(" break;");
// System.out.println();
}
if (aPdu != null)
{
if (aPdu != null) {
generatedPdusList.add(aPdu);
}
}
catch (Exception e)
{
}
} catch (Exception e) {
System.out.print("Exception thrown for PDU " + pdu.getValue() + " " + pdu);
System.out.print(Arrays.toString(e.getStackTrace()));
// continue looping
......@@ -161,15 +154,13 @@ public class AllPduSender
MulticastSocket socket = new MulticastSocket(DEFAULT_MULTICAST_PORT);
socket.joinGroup(localMulticastAddress);
for (int idx = 0; idx < generatedPdusList.size(); idx++)
{
for (int idx = 0; idx < generatedPdusList.size(); idx++) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
byte[] buffer;
Pdu aPdu = generatedPdusList.get(idx);
try
{
try {
aPdu.marshal(dos);
buffer = baos.toByteArray();
......@@ -181,10 +172,9 @@ public class AllPduSender
}
String currentPduTypeValuePadded = String.format("%2s", aPdu.getPduType().getValue());
String currentPduTypePadded = String.format("%-34s", aPdu.getPduType()); // - indicates right padding of whitespace
System.out.print ("Sent DIS PDU " + currentPduTypeValuePadded + " " + currentPduTypePadded );
System.out.print("Sent DIS PDU " + currentPduTypeValuePadded + " " + currentPduTypePadded);
System.out.println(" of type " + aPdu.getClass().getName());
}
catch (Exception ex) {
} catch (Exception ex) {
System.out.println("Marshaling error" + ex);
}
}
......@@ -192,25 +182,19 @@ public class AllPduSender
//PduContainer container = new PduContainer();
//container.setPdus(generatedPdus);
//container.marshallToXml("examplePdus.xml");
}
catch (IOException e)
{
} catch (IOException e) {
System.out.println(e);
}
}
public static void main(String args[])
{
if (args.length == 2)
{
AllPduSender sender = new AllPduSender(Integer.parseInt(args[0]), args[1]);
public static void main(String args[]) {
if (args.length == 2) {
FetterolfPduSender sender = new FetterolfPduSender(Integer.parseInt(args[0]), args[1]);
sender.run();
}
else
{
} else {
System.out.println("Usage: AllPduSender <port> <multicast group>");
System.out.println("Default: AllPduSender " + DEFAULT_MULTICAST_PORT + " " + DEFAULT_MULTICAST_ADDRESS);
AllPduSender sender = new AllPduSender(DEFAULT_MULTICAST_PORT, DEFAULT_MULTICAST_ADDRESS);
FetterolfPduSender sender = new FetterolfPduSender(DEFAULT_MULTICAST_PORT, DEFAULT_MULTICAST_ADDRESS);
sender.run();
}
System.out.println("DisExamplesOpenDis7.AllPduSender complete.");
......
1. Purpose - The purpose of this project was to incorporate Distributive
Interactive Simulation (DIS) protocol data units (PDU) into MAJ John Furr's
thesis work. His project models a specific aspect of ground combat communications,
producing data that may influence and change how ground units conduct tactical
communications while in close contact with the enemy. As such, there is great
benefit to adding a networking capability to his simulation that will allow it to
interact with other combat models.
2. Background - MAJ Furr programmed a discrete event simulation (DES) of the
call-for-fire process from the forward observation positions through battalion
level fires using java and SimKit. His simulation covers multiple forms of radio
frequencies and means of communication. Consequently, his results show how an
enemy capable of monitoring the electromagnetic spectrum can intercept conventional
omni-directional frequency modulation waveforms and exploit this information to
disrupt our kill chain. What was lacking from his program was the ability to
integrate his simulation with other combat models.
3. Process - Capt Jonathan Boron and Maj Daniel Yurkovich utilized an incremental
model process to incorporate the DIS PDUs into MAJ Furr's simulation. The approach
began with understanding MAJ Furr's code and how java classes interacted with each
other and populated events onto the event list. With this understanding, a PDU
Constructor class was developed to provide a blueprint that supports the creation
of all required PDUs. At this point, the following PDUs deemed necessary for proof
of concept were: CreateEntity, EntityState, Fire, Detonation, Transmitter, Receiver,
and Signal PDUs. A major breakthrough that enabled quick, seamless implementation of
PDU construction into the simulation was found in MAJ Furr's creation of the
SimpleMover3D class. All moving elements, both enemy and friendly, were subclassed
from this SimpleMover3D class. Within the SimpleMover3D class we placed the primary
PDUConstructor object, as well as methods that allowed Transmitter, Signal, and
Receiver PDUs to be sent. Moreover, with further refinement of the program, the
CreateEntity and EntityState PDUs were completely integrated into the SimpleMover3D
class. Since a large focus of MAJ Furr's work was how different radio procedures
influenced the battlefield, a struggle for Capt Boron and Maj Yurkovich was to
identify where radio messages were executed and broadcasted in the DES portion of
the program.
4. How to use - DIS was implemented in the simulation such that no other additional
files need to be explicitly run for PDUs to be constructed and sent. A PduReceiver
class was programmed, as well, in order to assist in monitoring the state of the
program and debugging. Thus, to observe and track the PDUs being sent, simply run
this file prior to executing MAJ Furr's main program.
5. Future work - The intricacies subordinate to the main 72 PDUs identified in
the MOVES Institute's open-dis7-source.jar need improvement if a more effective
and thorough implementation is desired. A better understanding of how the
Institute of Electrical and Electronics Engineers Standard for DIS - Application
Protocols (IEEE Std 1278.1-2012) and Simulation Interoperability Standards
Organization Reference for Enumerations for Simulation Interoperability (SISO-
REF-010-2019) work together would make future work easier to complete. Moreover,
the simulation itself, while an effective model of the call-for-fire process,
lacked certain, minute details to fully populate all parameters of the PDUs. This
included specific information, such as the type and number of transmission
tower arrays and the frequency and model of radios employed. Subsequently, some
data requires refinement in each PDU. Lastly, this project showed that DIS can
seamlessly interoperate with SimKit programs. Although outside of the scope of
this project, it would be beneficial for a more thorough integration of the
PDUConstructor and PDUSender classes into the SimKit package.
6. Conclusion - The modular structure of SimKit and DES allowed for the seamless
implementation of DIS PDUs into MAJ Furr's call-for-fire combat simulation. The
classes taught in the first year of the MOVES curriculum, specifically Java and
DES, establish a strong foundation for any second year MOVES student to continue
to improve MAJ Furr's simulation and broaden its impact with DIS implementation in
MV3500.
1. Purpose - The purpose of this project was to incorporate Distributive
Interactive Simulation (DIS) protocol data units (PDU) into MAJ John Furr's
thesis work. His project models a specific aspect of ground combat communications,
producing data that may influence and change how ground units conduct tactical
communications while in close contact with the enemy. As such, there is great
benefit to the warfighter by adding a networking capability to his simulation
that will allow it to interact with other combat models.
2. Background - MAJ Furr programmed a discrete event simulation (DES) of the
call-for-fire process from the forward observation positions through battalion
level fires using java and SimKit. His simulation covers multiple forms of radio
frequencies and means of communication. Consequently, his results show how an
enemy capable of monitoring the electromagnetic spectrum can intercept conventional
omni-directional frequency modulation waveforms and exploit this information to
disrupt our kill chain. What was lacking from his program was the ability to
integrate his simulation with other combat models.
3. Process - Capt Jonathan Boron and Maj Daniel Yurkovich utilized an incremental
model process to incorporate the DIS PDUs into MAJ Furr's simulation. The approach
began with understanding MAJ Furr's code and how java classes interacted with each
other and populated events onto the event list. With this understanding, a PDU
Constructor class was developed to provide a blueprint that supports the creation
of all required PDUs. At this point, the following PDUs deemed necessary for proof
of concept were: CreateEntity, EntityState, Fire, Detonation, Transmitter, Receiver,
and Signal PDUs. A major breakthrough that enabled quick, seamless implementation of
PDU construction into the simulation was found in MAJ Furr's creation of the
SimpleMover3D class. All moving elements, both enemy and friendly, were subclassed
from this SimpleMover3D class. Within the SimpleMover3D class we placed the primary
PDUConstructor object, as well as methods that allowed Transmitter, Signal, and
Receiver PDUs to be sent. Moreover, with further refinement of the program, the
CreateEntity and EntityState PDUs were completely integrated into the SimpleMover3D
class. Since a large focus of MAJ Furr's work was how different radio procedures
influenced the battlefield, a struggle for Capt Boron and Maj Yurkovich was to
identify where radio messages were executed and broadcasted in the DES portion of
the program.
4. How to use - DIS was implemented in the simulation such that no other additional
files need to be explicitly run for PDUs to be constructed and sent. A PduReceiver
class was programmed, as well, in order to assist in monitoring the state of the
program and debugging. Thus, to observe and track the PDUs being sent, simply run
this file prior to executing MAJ Furr's main program.
5. Future work - The intricacies subordinate to the main 72 PDUs identified in
the MOVES Institute's open-dis7-source.jar need improvement if a more effective
and thorough implementation is desired. A better understanding of how the
Institute of Electrical and Electronics Engineers Standard for DIS - Application
Protocols (IEEE Std 1278.1-2012) and Simulation Interoperability Standards
Organization Reference for Enumerations for Simulation Interoperability (SISO-
REF-010-2019) work together would make future work easier to complete. Moreover,
the simulation itself, while an effective model of the call-for-fire process,
lacked certain, minute details to fully populate all parameters of the PDUs. This
included specific information, such as the type and number of transmission
tower arrays and the frequency and model of radios employed. Subsequently, some
data requires refinement in each PDU. Lastly, this project showed that DIS can
seamlessly interoperate with SimKit programs. Although outside of the scope of
this project, it would be beneficial for a more thorough integration of the
PDUConstructor and PDUSender classes into the SimKit package.
6. Conclusion - The modular structure of SimKit and DES allowed for the seamless
implementation of DIS PDUs into MAJ Furr's call-for-fire combat simulation. The
classes taught in the first year of the MOVES curriculum, specifically Java and
DES, establish a strong foundation for any second year MOVES student to continue
to improve MAJ Furr's simulation and broaden its impact with DIS implementation in
MV3500.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment