Many VR-Link users need to use PDUs that are not part of the DIS standard, and thus not implemented in VR-Link.
However, VR-Link can work with user-defined PDUs just like it treats PDUs that are implemented in VR-Link.
There are two ways to work with user-defined PDUs:
Using DtUnknownPdu is sometimes easier for simple PDUs that can be represented by C-style structures. In essence, the DtUnknownPdu just serves as a wrapper around such a structure. Deriving your own DtPdu class requires some extra work up front, but it is easier to use in your application, especially if it is a variable-length PDU, or one that has several variants.
You can use a DtUnknownPdu (defined in unknownPdu.h) to represent a PDU for which there is no PDU class. This includes new or experimental PDUs that you develop.
To send a PDU using the DtUnknownPdu class:
Fill a buffer with the exact bytes you want to send on the network (probably by filling in a C-structure). Make sure this structure includes the DIS PDU header whose structure is defined in pduHeader.h (in ./include/packets).
By using our "Net" types, such as DtNetInt32 (defined in vlNetTypes.h), you insure platform independence. When you are on little endian machines, byte swapping is performed when assigning to a Net type, and when a Net type is implicitly cast to a native type.
For example, suppose you create a Test PDU with two fields called a and b, and choose PDU kind number 220 to represent this PDU:
On the receiving side, DtUnknownPdu does not have addCallback() or removeCallback() functions, since a DtUnknownPdu does not know what PDU kind you are interested in. But you can still register callbacks with the DtExerciseConn on a particular PDU kind, in our case 220. Note the cast of the integer 220 to a DtPduKind enum here.
Since 220 is not a PDU kind that VR-Link knows about, when it receives a packet of that kind, it creates a DtUnknownPdu and passes that to your callback function. You can cast the DtPdu* to a DtUnknownPdu* within your callback if you want to, but it is not necessary, since the only useful thing you can do with a DtUnknownPdu is get its network representation, which is done through a DtPdu member function.
VR-Link's DtExerciseConn::send() and DtExerciseConn::sendStamped() functions can send any type of PDU, as long as the object passed to it is of a type derived from DtPdu. So, to send user-defined PDUs, you can write a derived class, after which you can immediately use your derived class with these functions.
When DtExerciseConn receives a packet from the network, it creates an object of the appropriate class derived from DtPdu, based on the PDU type in the packet. For instance, a DtEntityStatePdu is created if a packet representing an Entity State PDU is received. For this reason, VR-Link needs to know that your derived class exists. Registration of your class with VR-Link is usually done in your PDU class's addCallback() function.
The testPdu example creates a variable length PDU. The TestPdu class represents a hypothetical variable-length "Test PDU" – one that has three fields: an integer named "a", a variable-length array of integers named "b" whose cardinality is the value of "a", and a float called c. The code for this example is in ./examples/extend/testPdu. The class documentation contains a complete description of the example.
[<< Working with PDUs] [Home] [Top of Page] [Configuring Your Connection to the DIS Network >>]