VRPN 06.04

VRPN main page

Obtaining VRPN

VRPN Support

Installing and Testing

Compiling and Modifying

Client code

Server code

Troubleshooting

Connections

Logging and Playback

Shared Objects

Sound

Clock Synchronization

Text Messages

Doxygen documentation

VRPN on PDAs

Coming attractions & suggestions

UNC-specific information

Creating a new server within an existing device class

The root device class for each device type (vrpn_Tracker, etc.) handles the registration of message types and sender names used by all objects of that type. It also contains routines for packing and unpacking the messages that are sent between the client-side class (vrpn_Tracker_Remote) and the servers (vrpn_Tracker_Fastrak, etc.). This keeps all of the encoding and decoding in one class, and ensures that all derived classes use the same methods to do this. The device class and _Remote device are defined in the header file that is part of the library (vrpn_Tracker.h, for example), and their methods described in source files (vrpn_Tracker.C, for example). Specific server classes derived from the base class can be in separate header and source files, since they do not need to be compiled except on the architecture and machine where they run (the UNC Ceiling Tracker server, for example). Some servers (such as the example servers) are present in the library directly.

The easiest way to implement a new server is to copy the server that is most like the one you want, and modify it to suit. Towards this end, simple example server classes have been provided for several of the common devices within VRPN (see below).

Adding new capabilities to existing devices

When a server for a new device has capabilities that are not supported by the base class, there are two possible courses of action. (1) If the new capability is likely to be shared by several devices of the same type (such as the ability to set how often a tracker sends reports), then the root device class is extended to include encode and decode methods for a new message type and the _Remote class is extended to send or receive messages of the that type. Particular tracker drivers that are able to handle the new commands register handlers for the new messages (using the inherited method register_autodeleted_handler()), or emit the new types of information messages. It is important that the _Remote class continues to work with both devices that handle/emit the new messages and those that do not. (2) If the device is a highly-specific or experimental one, then the new messages and handlers can be built directly into the device driver itself, and the application can send and receive messages using the raw functions in vrpn_Connection, or a separate object (with the same name as the device) can be created just to send/receive the new messages.

It is advisable to think of the most general form of a new message, and attempt to build it into the root device, whenever possible. This allows the maximum code re-use and flexibility with using different devices from the same application.

Creating completely new devices

If you find that the capabilities of the new device are different enough from the existing device classes (or have different semantics), it is better to create a new device class than to try and shoe-horn the server into one of the existing classes. This was done when vrpn_Dial was created (it was deemed to be different enough in semantics from vrpn_Analog to warrant this); even though you may implement either an analog device or a dial from the same physical potentiometer (the difference is that a dial is used to set orientation and an analog is used to give a range of values). If you decide to do this, see the creating a new device class page.

Example Servers

There are device drivers for various types of devices. Many devices classes have an example that can be used as a basis for both testing the library and writing new drivers. These are listed here by class:

vrpn_Tracker

There is an example for a vrpn_Tracker class, called vrpn_Tracker_NULL that is defined in vrpn_Tracker.[hC]. This tracker sends the identity transform at a specified interval on the specified number of sensors.

vrpn_Button

There is an example for a vrpn_Button class, called vrpn_Button_Example_Server, that is defined in vrpn_Button.[hC]. It implements a class that toggles buttons on and off at a specified interval.

vrpn_Analog

There is a class called vrpn_Analog_Server that is defined in vrpn_Analog.[hC] that allows you to send analog values.

vrpn_Text

You pretty much just use a vrpn_Text_Sender or vrpn_Text_Receiver as-is.

vrpn_ForceDevice

None yet available.

vrpn_Sound

None yet available.