The VR Juggler Configuration Guide

$Revision: 89 $

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with the Invariant Sections being Appendix H, GNU Free Documentation License, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in Appendix H, GNU Free Documentation License.

Some of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and Infiscape Corporation was aware of the trademark claim, the designations have been printed in caps or initial caps.

$Date: 2007-04-09 09:48:38 -0500 (Mon, 09 Apr 2007) $


Table of Contents

Preface
1. Introduction
Parameterization of Components
Configuration Elements
Run-Time Reconfiguration
Configuration Files
Configuration Editing
VRJConfig
Static Configuration Editing and Remote Run-Time Reconfiguration
Using the VRJConfig Control Panel
Updating Configurations
Configuration of VR Juggler
2. Configuring Input
The Input Manager
Driver Search Path
Driver DLL Name
Driver Scan Path
Input Devices
Physical Devices
Simulator Devices
Device Proxies
Proxy Aliases
Position Filters
Matrix Notation
Tracker Transformations
Configuring Position Filters
Putting it All Together
3. Configuring Displays
The Display Manager
Users
Display Windows
The OpenGL Frame Buffer
Graphics Window Input
Viewports
Simulator Viewports
Surface Viewports
Multiple Viewports in a Single Window
4. Configuring a Cluster
Cluster Nodes
Cluster Manager
Cluster Plug-Ins
Remote Input Manager
Start Barrier
Application Data Manager
TCP Swap Lock
Parallel Port (Wired) Swap Lock
Input Device Sharing
Cluster Configuration Tips
Naming Cluster Node Config Elements
Choosing Master Nodes
5. Remote Run-Time Reconfiguration Using VRJConfig
Preparing VR Juggler for Remote Run-Time Reconfiguration
Connecting to VR Juggler Using VRJConfig
6. Config Definition Editing
Introduction to Config Definitions
Config Definition Features
Config Definitions and XML Schema
Config Definition Files
File Format Version
Root Document Attributes
Definition Version
Abstract Config Definitions
Config Definition Help Text
Config Definition Parents
Categories
Property Definitions
Upgrade Transforms
A. Tracker Configuration
Ascension Flock of Birds®
Ascension MotionStar Wireless® 2
InterSense API and InterSense IS-900
InterSense API Configuration Aspects
IS-900™ Configuration Aspects
Configuring InterSense Stations
Polhemus Fastrak®
VRCO Trackd® and trackdAPI Sensor
B. Glove Configuration
5DT Data Glove
Fakespace Pinch™ Gloves
Immersion CyberGlove®
C. Multi-Type Input Device Configuration
VRCO Trackd® and trackdAPI Controller
VRPN
Ascension Wanda®
Immersion Interface Box
Linux Joystick Device
The Linux joydev Kernel Module
USB Device Mapping
Analog and Digital Input Sources
Direct Input Game Controller
D. Other Device Drivers
U.S. Digital Serial Encoder
Microsoft Speech API
E. Configuration of Miscellaneous Components
VR Juggler Kernel Shutdown
Sonix Sound Manager
F. VRJConfig Custom Editors by Infiscape
Display Window Editor
Flock of Birds® Editor
MotionStar Wireless® Editor
Device Proxy Editor
Simulator Editor
G. File Format Specifications
Config Definition Files
Config Files
H. GNU Free Documentation License
PREAMBLE
APPLICABILITY AND DEFINITIONS
VERBATIM COPYING
COPYING IN QUANTITY
MODIFICATIONS
COMBINING DOCUMENTS
COLLECTIONS OF DOCUMENTS
AGGREGATION WITH INDEPENDENT WORKS
TRANSLATION
TERMINATION
FUTURE REVISIONS OF THIS LICENSE
ADDENDUM: How to use this License for your documents
Glossary of Terms
Index

List of Figures

1.1. Simple Configuration Element
1.2. VRJConfig
1.3. VRJConfig Configuration Editor Main Toolbar
1.4. VRJConfig Configuration Editor New and Open Buttons
1.5. VRJConfig Configuration Context Toolbar
1.6. VRJConfig Context Modification Menu
1.7. VRJConfig Config Element Navigator Panel
1.8. Config Element Chooser
1.9. Config Element Search Dialog
1.10. Editing a Property with a Variable Number of Values
1.11. Changing the Order of Property Values
1.12. VRJConfig Control Panel Start Screen
2.1. Frames of reference for configuring a tracking system
5.1. Subject Manager Lookup Dialog
5.2. VRJConfig Remote Run-Time Reconfiguration Button
F.1. Display Window Editor: Simulator Viewport
F.2. Display Window Editor: Viewport Resizing
F.3. Display Window Editor: Window/Viewport Menu
F.4. Display Window Editor: Display Window Properties Dialog
F.5. Display Window Editor: Simulator Viewport Add/Edit Dialog
F.6. Display Window Editor: Surface Viewport Add/Edit Dialog
F.7. Display Window Editor: Surface Orientation
F.8. Display Window Editor: Surface Viewport Configured
F.9. Display Window Editor: Multiple Viewports
F.10. Flock of Birds® Editor: Transmitter Settings
F.11. Flock of Birds® Editor: Sensor Settings
F.12. Flock of Birds® Editor: Serial Port Settings
F.13. MotionStar Wireless® Editor: Transmitter Settings
F.14. MotionStar Wireless® Editor: Sensor Settings
F.15. Device Proxy Editor: Single Positional Device
F.16. Proxy Editor: Creating a New Proxy/Device Connection (Step 1)
F.17. Proxy Editor: Creating a New Proxy/Device Connection (Step 2)
F.18. Proxy Editor: Creating a New Proxy/Device Connection (Step 3)
F.19. Proxy Editor: Adding Positional Units
F.20. Proxy Editor: Adding a Proxy Alias
F.21. Proxy Editor: Reassociating a Proxy Alias
F.22. Proxy Editor: Multi-Type Input Devices
F.23. Proxy Editor: Adding a Digital Input Source
F.24. Proxy Editor: Adding Another Digital Input Source
F.25. Simulator Editor: Single Window Simulator
F.26. Simulator Editor: Multi-Window Simulator
F.27. Simulator Editor: Simulated Analog Devices
F.28. Simulator Editor: Simulated Digital Devices
F.29. Simulator Editor: Simulated Positional Devices
F.30. Simulator Editor: On-the-Fly Error Detection
F.31. Simulator Editor: Advanced Simulated Device View

List of Tables

1.1. Valid Property Types
2.1. Proxies for an InterSense IS-900

List of Examples

6.1. Basic Config Definition File Structure
6.2. Multi-Version Config Definition Example (simulated_digital_device.jdef)
6.3. Simple Config Definition (position_proxy.jdef)
6.4. Example Abstract Config Definition (input_device.jdef)
6.5. HTML Encoded Within a <help> Tag
6.6. Resulting HTML Help String
6.7. Value Enumeration (surface_viewport.jdef)
6.8. Editable Value Enumeration (cluster_manager.jdef)
6.9. Allowed Type for an Embedded Config Element Value (position_proxy.jdef)
6.10. Single Allowed Type for a Config Element Pointer (position_proxy.jdef)
6.11. Multiple Allowed Types for a Config Element Pointer (user.jdef)

Preface

This book explains the process of configuring VR Juggler and its component modules. It is written for VR Juggler 2.0. Throughout, we will make reference to the modules JCCL and Gadgeteer, both of which are at Version 1.0 with the release of VR Juggler 2.0. Readers who are not familiar with the modular structure of VR Juggler are referred to the VR Juggler Project website, specifically the high-level description of the Juggler Suite. Understanding this will be vital to understanding how to configure the various software components utilized by VR Juggler.

Chapter 1. Introduction

Since its inception, VR Juggler has been designed to be highly flexible and dynamic. At the heart of this is the high degree of configurability present in VR Juggler. In spite of being a fundamental aspect of using VR Juggler, configuration of VR Juggler has always been difficult. Through this book, we will present VR Juggler configuration in a way that will make the process more approachable and that will enhance understanding of VR Juggler as a whole. We begin by examining the basic aspects of the VR Juggler configuration system, encapsulated within the JCCL module, and we then provide high-level explanations of how to configure general pieces of VR Juggler. At the end of this book, the reader will find appendices that explain the configuration of specific devices. The appendices include tips and troubleshooting points to help with commonly encountered complexities.

Parameterization of Components

A key feature of VR Juggler is its portability, both in terms of operating systems and in terms of immersive system. As a virtual platform for the development of virtual reality (VR) applications, VR Juggler facilitates the transition of VR applications from the desktop to the immersive system. It also aids in the migration of the application across a variety of immersive systems. VR Juggler achieves this degree of portability by separating the details of the immersive system from the application. Hence, those details can change without requiring any changes to the application.

To handle variations in immersive visualization systems, VR Juggler has been designed to be highly configurable. VR Juggler is not written to work with any specific type or classification of immersive system. Instead, it handles the general aspects common to all immersive systems in code while offloading the device-specific pieces to run-time configuration. The components of VR Juggler have been parameterized to ensure portability and scalability across a staggering variety of display and input hardware combinations.

Component parameterization is captured within configuration elements, or simply “config elements.” Understanding config elements is vital to understanding the process of configuring VR Juggler. Throughout this text, we will discuss config elements and their utility as the means for configuring VR Juggler.

Configuration Elements

A configuration element is the fundamental unit of configuration within VR Juggler. Each config element is composed of one or more properties and is identified by a user-specified name. Each property has a type such as string, integer, pointer, etc., and properties can have either a fixed number of values or a variable number (zero or more) of values. The conceptual structure of a simple config element is shown in Figure 1.1, “Simple Configuration Element”.

Figure 1.1. Simple Configuration Element

Simple Configuration Element

In the figure, we see that the property named Size has two values: width and height. The valid type for both values of this property is integer. In general, all the values of a given property will have the same type. While there are exceptions to this, we will not go into such details at this time. In nearly all current cases, remember that the values of a property all share the same type.

The list of valid types for properties is shown in Table 1.1, “Valid Property Types”. A basic understanding of the valid types and their run-time interpretation in C++ can be useful when entering values. For example, note that the property type “integer” can be interpreted as a wide variety of C++ integer types. In some cases, the component being configured may limit the range of valid integer values that can be accepted from a config element. Hence, it can be important to know what the range of valid values is for a given property.

Table 1.1. Valid Property Types

TypeValid C++ Interpretation
integerint, unsigned int, long, unsigned long, long long, unsigned long long, short, unsigned short, char, unsigned char
floatfloat, double
booleanbool, integer
stringstd::string, char*
config element pointerstd::string, char*
config elementjccl::ConfigElementPtr

Note

The concept of a config element “pointer” reduces to simply the name of another config element. At run-time, the loaded config elements are stored in a table that is indexed by element name. This means that within a given configuration, all the elements must have unique names.

Note that the last entry in Table 1.1, “Valid Property Types” is “config element.” This means that config elements can be nested within other config elements. A nested config element is often called an embedded config element. There is no limit to the depth of config element nesting, but in general, config elements are rarely nested more than one level deep. Doing so can complicate user understanding of the configuration process. It is hoped, however, that continued improvements to the VR Juggler configuration editor will alleviate confusion related to nested config elements. For now, it is sufficient to understand that a nested config element is just another property type.

The specification of property types, the number of allowed values, and other structural aspects of config elements are defined by configuration definition , or simply “config definitions.” The relationship between config elements and config definitions is quite similar to that of objects and classes in object-oriented languages. A class defines structural and behavioral information, and an object is an instance of a class. At any time, there can be many instances of a single class, each referenced by a different variable. Similarly, a config definition defines structural information, and a config element is an “instance” of the definition. There can be many config elements for a given definition, and each config element is identified by its unique name. Config definitions even support a limited form of multiple inheritance.

Config definitions are found in files that are named based on the config element type defined therein and have the extension .jdef. To allow versioning of config elements, a given config definition may have many versions, each of which is identified by an integer value that is incremented each time a structural change is made to the definition. Config definitions are loaded by scanning directories listed in an environment variable. VR Juggler performs this scan before any attempt to load a config file is made to ensure that the run-time environment knows about all existing config definitions.

Run-Time Reconfiguration

As one would expect, configuration elements are what provide the run-time configuration information for VR Juggler. A casual observer would say that VR Juggler is configured by the configuration files that are loaded at run time. In reality, VR Juggler is reconfigured by the individual config elements that are processed. As a whole, VR Juggler starts out with no configuration. With the help of the Configuration Manager, the VR Juggler kernel main loop performs what is known as run-time reconfiguration wherein the config elements read from the configuration file(s) given at run time are processed. This means that VR Juggler dynamically reconfigures itself over and over again until the kernel determines that no more reconfiguration can occur.

The Configuration Manager maintains three lists of config elements:

  1. Incoming list: Config elements that were added to the Configuration Manager since the last reconfiguration attempt was made.

  2. Pending list: All the unprocessed config elements.

  3. Active list: All the successfully processed config elements that are in use by the run-time environment.

The Configuration Manager delivers individual config elements from the pending list to those entities within VR Juggler that accept them. These entities are known as config element handlers, and they normally register themselves with the Configuration Manager when they are created.

For each config element in the pending list, the Configuration Manager tests to see if the dependencies of the element are satisfied. With the presence of config element pointers, one config element may depend on one or more other config elements being processed first. In other words, if config element A depends on config element B, then B must be in the active list before A can be given to a handler. If it is determined that the dependencies for the config element are met, then the Configuration Manager delivers the config element to its handler. If the dependencies are not met, then the config element goes back into the pending list, and another attempt to process it will be made later.

When a handler receives a config element, it attempts to read the values from the individual properties and configure (or de-configure) itself. If the handler concludes that its configuration procedure was successful, the Configuration Manager moves the config element from the pending list to the active list. If the handler cannot process the config element correctly, the config element goes back into the pending list so that another attempt to process it can be made later.

In typical usage, the startup process of a VR Juggler application shows the reconfiguration process. Attempts are made to process config elements until the pending list reaches a state where it is considered “stale. This means that a sufficient number of reconfiguration attempts were made with no config elements being processed. When all config elements are processed, a message similar to the following will be printed to the console where the application was executed:

[0002315/000] DBG:ConfigManager::pendingNeedsChecked: Pending list is now
                  STALE: 0 items still in the pending list
[0002315/000] DBG:---- Pending list: 0 items ----
                  ----------------------------------

If there should be one or more config elements that are left unprocessed for some reason, then output similar to the following will be printed:

[0002333/000] DBG:ConfigManager::pendingNeedsChecked: Pending list is now
                  STALE: 1 items still in the pending list
                  NOTE: These items have been specified in the configuration
                        but have not been loaded.
                        This may be a problem in the configuration OR
                        it may be waiting for more configuration information.
[0002333/000] DBG:---- Pending list: 1 items ----
                     ADD -->My IS-900 type: intersense
                  ----------------------------------

Note

Most people getting started with VR Juggler interpret one of the above messages to mean that something about the application has “stopped.” In reality, nothing has stopped permanently. The kernel main loop is still running, but there is nothing new in the pending config element list to process. The above message may be printed again later if new configuration elements are added to or removed from the Configuration Manager.

Neither of the above output messages is an error message. Rather, both forms of the output state that the reconfiguration process has reached a point where there is nothing new to process. The longer form indicates one of two things: either the configuration had extra, unused config elements or the configuration is incomplete. In the latter case, that usually means that a config element did not have one or more dependencies met. As we will see later in this chapter, it is possible to satisfy missing dependencies without restarting the application.

Tip

The output from the VR Juggler configuration process can sometimes be misleading. Due to its dynamic nature, attempts and reattempts are made to configure components within VR Juggler. Thus, if something in the configuration fails early in the process, it may cause problems much later on. It is therefore a very common mistake to assume that the last message printed to the console, no matter what it says, is where a problem occurred. If some part of the configuration fails, there may be other error messages or warning messages printed early in the output that explain what caused the later failure. As a rule of thumb, if a problem occurs with the execution of a VR Juggler application, scroll up to see if there are errors or warnings printed to the console before concluding that the last message is related to the fatal error.

Configuration Files

VR Juggler configuration files, or simply “config files,” are those files that end with the extension .jconf. They contain zero or more configuration elements, and they can reference other configuration files. The files themselves are stored in a format called XML, a text-based, and therefore cross-platform, file format.

In VR Juggler terminology, a configuration is a collection of config elements that provide a complete set of parameters needed to execute a VR Juggler application successfully. A configuration can be defined by one or more .jconf files, and .jconf files can be mixed and matched to give different configurations. The concept of a configuration is especially important within the context of the VR Juggler configuration editor, VRJConfig. We discuss VRJConfig more in the following section.

Ultimately, the concepts surrounding VR Juggler configurations are hierarchical in nature. Each piece of the configuration puzzle is composed of smaller pieces. The following summarizes the hierarchy starting from the smallest piece and going up from there:

  • Value: A storage unit capable of holding a single datum of any type.

  • Property: A property has zero or more values of the same type.

  • Configuration element: A config element is composed of one or more properties.

  • Configuration file: A config file contains zero or more config elements.

  • Configuration: A configuration is made up of one or more config files that together provide a comprehensive collection of settings for parameterized components in VR Juggler.

Configuration Editing

Since .jconf files are stored as plain XML, they can be edited manually using a standard text editor. While sometimes quick and convenient, this method is not recommended because it is very easy to make mistakes that break the configuration or that violate the XML syntax. Furthermore, editing configuration files by hand with a text editor retains the old mindset of testing configurations by running an application, shutting it down, changing the configuration, and running the application again. VR Juggler offers much more power and efficiency in terms of configuration editing than this. In this section, we introduce VRJConfig, the VR Juggler configuration editor, and we explain how it can be used for static and dynamic configuration editing. Since the theme of this book is configuring VR Juggler, it is important for us to explain VRJConfig. However, an in-depth usage guide is beyond the current scope of this document. We will explain the concepts present in VRJConfig and provide enough explanation of its usage to get readers comfortable working with it.

VRJConfig

VRJConfig is the Java®-based graphical user interface (GUI) for creating and editing VR Juggler configurations. A screen shot of the VRJConfig Configuration Editor is shown in Figure 1.2, “VRJConfig”. It is based on Tweek, an implementation of a distributed model/view/controller system. Without going into great detail about the Tweek Java® API, it is sufficient to state VRJConfig exists as a collection of JavaBeans™ loaded by and executed within the Tweek JavaBean™ Loader.

Figure 1.2. VRJConfig

VRJConfig

The VRJConfig Configuration Editor represents the low-level, all-purpose editor. It is capable of editing any config element. The representation of a config element provided by this editor shows both the property values and the structure of the element.

It is important to understand, however, that VRJConfig strives to provide an interface for configuration editing as opposed to the lower level concept of property editing. As was noted earlier, .jconf files can be edited manually using an ordinary text editor. This approach would be considered property editing because the user concentrates on the values of individual properties without necessarily considering the whole config element let alone the whole configuration. With the VRJConfig Configuration Editor, the intention is to provide more of a big-picture view of a collection of config elements as a complete configuration rather than as an assortment of disparate property values.

The Purpose of VRJConfig

Before we dive into the use of VRJConfig, we will explain more about the purpose of VRJConfig and how it relates to VR Juggler applications written in C++ or Python. We have just stated that VRJConfig strives to provide an interface for editing configurations. The name VRJConfig is a catch-all name for various components. The VRJConfig Configuration Editor was already shown above. The other two components are the VRJConfig Control Panel and the VRJConfig Config Definition Editor. These two components will be examined later.

In the most abstract terms, the purpose of VRJConfig is to provide a valid configuration for use by VR Juggler. There is an informal contract between VRJConfig and VR Juggler[1]. The contract is simple: VRJConfig guarantees that it will output valid XML describing a correct configuration of VR Juggler. Note that completeness of the configuration is not included in the contract because the notion of a “complete configuration” is not defined within the scope of VR Juggler. VR Juggler can run with no configuration at all, it can run with a fully immersive, multi-screen, cluster configuration, or somewhere in between. Hence, completeness depends on the needs of each user and his or her execution environment.

Unfortunately, the implementation of the contract is quite complex. As of VR Juggler 2.0 Beta 1, only the valid XML aspect is fully implemented. VRJConfig validates the config files and config definition files using the XML Schemata that describe those file formats. This ensures that the input to VRJConfig and the output it creates are valid XML and are valid in terms of the respective file formats. Therefore, VR Juggler is free from re-validating the input.

Caution

Users who edit configuration files and config definition files by hand using a text editor do not get the benefit of validation through the XML Schemata. Therefore, it is possible for VR Juggler to fail to load a given file or to crash altogether if the input is not valid. Manual editing, therefore, is highly discouraged. At the very least, users should load manually modified files into VRJConfig to ensure that they are valid XML.

Configuration Contexts

The VRJConfig Configuration Editor utilizes a multi-document interface (MDI) paradigm. Each internal window is called a configuration context, or simply a “context.” Each context should be treated as a complete configuration to achieve proper use of VRJConfig. Throughout the discussion of configuration contexts, the main toolbar at the top of the VRJConfig Configuration Editor panel will be important. It is shown again in Figure 1.3, “VRJConfig Configuration Editor Main Toolbar” to distinguish it from the full editor GUI.

Figure 1.3. VRJConfig Configuration Editor Main Toolbar

VRJConfig Configuration Editor Main Toolbar

Creating a Configuration Context

A new config context can be created either by opening an existing .jconf file or by creating a new .jconf file. In either case, a new internal window will open within the VRJConfig Configuration Editor. The main toolbar has buttons for creating a new .jconf file and for opening an existing .jconf file. They are highlighted in Figure 1.4, “VRJConfig Configuration Editor New and Open Buttons”.

Figure 1.4. VRJConfig Configuration Editor New and Open Buttons

VRJConfig Configuration Editor New and Open Buttons

Once the context is created, the view of VRJConfig will be similar to what was shown earlier in Figure 1.2, “VRJConfig”.

Managing Multiple Files in a Configuration Context

The purpose of a configuration context within VRJConfig is to facilitate the notion of editing a configuration as a whole. As such, adding more .jconf files to an open context is a common operation. Each context has its own toolbar that is independent of the main VRJConfig Configuration Editor toolbar, and this toolbar is what must be used to extend or modify the state of a given configuration context. The context-specific toolbar is shown in Figure 1.5, “VRJConfig Configuration Context Toolbar”.

Figure 1.5. VRJConfig Configuration Context Toolbar

VRJConfig Configuration Context Toolbar

On the left side of the toolbar, we see the usual icons for file creation, opening, and saving. To add a new .jconf file to the existing config context, either the New or the Open button must be used. Using the New or the Open button from the main VRJConfig toolbar will result in the creation of a new configuration context.

On the right side of the context-specific toolbar, we see a button with an icon that is a downward pointing arrow. This button is only active when there are at least two .jconf files open in the VRJConfig Configuration Editor as a whole. Clicking the button reveals a special menu shown in Figure 1.6, “VRJConfig Context Modification Menu”. In the menu, the selected .jconf files are those that are open in the current context. Selecting a file from the menu will add it to the current context. De-selecting a file removes it from the context. In this way, it is possible to build up config contexts using different config files.

Figure 1.6. VRJConfig Context Modification Menu

VRJConfig Context Modification Menu

Managing Multiple Configuration Contexts

With multiple configuration contexts open, it is often desirable to move or copy config elements around. The MDI paradigm helps make this possible by allowing multiple windows to be visible at once, and cut/copy/paste support within the VRJConfig Configuration Editor completes the picture. Note, however, that the granularity of cut/copy/paste operations—including drag and drop—is at the level of config elements. Individual properties cannot be copied between contexts or between config elements.

Navigating the Config Element Hierarchy

On the left side of each config context window is a tree view of the config element hierarchy (as seen in Figure 1.7, “VRJConfig Config Element Navigator Panel”). This hierarchy is a dynamically updating organizational model of all the config elements in the current configuration context. Within the tree, names shown in bold text are categories. Names shown in non-bold text are config element names. As config elements are added to and removed from the current context, the tree structure will change. Empty categories are not shown.

Figure 1.7. VRJConfig Config Element Navigator Panel

VRJConfig Config Element Navigator Panel

The config element hierarchy also depicts the hierarchy inherent in config elements. That is, the nesting of config elements within config elements is shown, too. This allows quick, direct access to nested config elements for property editing purposes.

Adding and Removing Config Elements

Adding new config elements to a configuration context is easy. Simply click the Add button shown above the config element hierarchy; it is always active. When clicked, a dialog box is opened that is used for choosing the type of config element to add to the context. The list, shown in Figure 1.8, “Config Element Chooser”, displays the human-friendly names of all known config element types. Entering text into the field labeled Config Element Type causes the selection to jump to the first element matching the entered text. This search is a rudimentary, exact-match type of search.

Figure 1.8. Config Element Chooser

Config Element Chooser

For a more advanced search capability, click the tab labeled Search. The dialog box will change to what is shown in Figure 1.9, “Config Element Search Dialog”. Initially, the config element list is empty, but as soon as text is entered into the search field, all elements whose human-friendly identifier match the entered text will be displayed. This search supports sub-string matches of search terms. The Search tab is useful to users who know exactly what they want or who have an idea of what to look for. In Figure 1.9, “Config Element Search Dialog”, the user started entering the word window as a search term, and all three possibilities for window-related config elements were immediately displayed.

Figure 1.9. Config Element Search Dialog

Config Element Search Dialog

Once the element type is chosen, click the OK button. A new element will be created in the current context with all of its property values initialized to their default setting. If multiple files are open within the context, another dialog box will be opened asking the user for a destination file for the new element. The first thing to do after creating a new config element is to set its name. In the config element hierarchy, new elements are created with a simple, unique name based on the human-readable description of the element type. To rename the element, either double-click on its name or right-click on the name and choose the Rename item from the pop-up menu.

Caution

In some cases, it is necessary to triple-click on the name of a config element in the hierarchy tree. This is because Java® sometimes interprets a double-click within a tree as an expand/collapse command for that branch of the tree. To get the correct behavior every time, right-click on the name of the config element to get the pop-up menu and choose Rename.

To remove a config element, click on its name within the hierarchy and click the Remove button. Otherwise, right-click on the element and choose the Remove item from the pop-up menu.

Editing Configuration Elements

The largest panel in the configuration context window is devoted to editing configuration elements. The full config element selected in the element tree is shown in this panel. From this panel, the individual property values can be edited. The view shown in this panel is designed to illustrate the hierarchical structure of a config element. Panels are nested within panels to show the nesting of config elements within config elements. Multi-value properties are rendered using a layout that shows data grouping as opposed to nesting.

Properties with a Fixed Number of Values

Editing properties with a fixed number of values is straightforward. Those that have a multiple values may need to be expanded to show the full list, but no extra steps are required to insert entries that can be edited. VRJConfig will always show the full number of values for this variety of property. For new config elements, it will fill in the default setting for each of the property's values.

Properties with a Variable Number of Values

Properties with a variable number of values are a little more tricky. This variety of property can have zero or more values set, and the default case is to have zero values set. As such, new values must be added before editing can take place. In Figure 1.10, “Editing a Property with a Variable Number of Values”, we see two highlighted buttons: one for adding a new value and one for removing an existing value. The New Value button is always at the top center of the inset panel while the Remove Value button appears on the right side of the inset panel. There will be one Remove Value button per value present in the config element.

Figure 1.10. Editing a Property with a Variable Number of Values

Editing a Property with a Variable Number of Values

The values of a property with a variable number of values may be reordered using VRJConfig. Depending on the interpretation config element, this may be useful for changing the processing order of the values. An example of this is shown in Figure 1.11, “Changing the Order of Property Values”. The highlighted up and down buttons move the associated value up or down one position in the ordering of the property's values.

Figure 1.11. Changing the Order of Property Values

Changing the Order of Property Values

Static Configuration Editing and Remote Run-Time Reconfiguration

Editing a static configuration represents the usual configuration editing process. This means that configuration files are loaded from permanent into VRJConfig. When the editing is complete, the files are saved back to permanent storage to be loaded at a later time by VR Juggler. Following this procedure stays with the traditional configuration process, depicted as follows:

  1. Create or edit a configuration.

  2. Run an application to test the configuration.

  3. Exit the application and go back to step 1 if more changes are required.

This process does not harness the full potential of VR Juggler. Through its run-time reconfiguration capabilities, VR Juggler can be reconfigured on the fly using VRJConfig as a remote configuration editing tool. That is, VRJConfig can connect to a running application and edit its configuration without requiring the application to be shut down and restarted. A full discussion of this topic is postponed until Chapter 5, Remote Run-Time Reconfiguration Using VRJConfig.

Using the VRJConfig Control Panel

Besides the low-level Configuration Editor, VRJConfig includes a component known as the “Control Panel.” It is named this way because it is styled after the Microsoft Windows® Control Panel. Through the Control Panel, users are presented with high-level, or “custom,” editors that are designed for specific configuration tasks. Furthermore, the Control Panel provides configuration creation tools in the form of wizards that combine multiple high-level editors into a step-by-step configuration process. Whereas the Configuration Editor is capable of editing any type of config element, customized code must be written for use by the Control Panel to edit specific element types. As of this writing, editors exist for the Ascension Flock of Birds®, the Ascension MotionStar Wireless®, the Fakespace Pinch™ Gloves, and the InterSense IS-900™ devices. There is also an editor that presents a directed graph representation of the all the proxies in the config context.

The VRJConfig Control Panel is loaded by clicking on the Control Panel JavaBean™, which is nested under the VRJConfig category. When it is first loaded, the Control Panel appears as shown in Figure 1.12, “VRJConfig Control Panel Start Screen”. The individual panels within the Control Panel are a mixture of category icons and editor or wizard icons. Clicking an icon either navigates to a sub-category or opens a high-level editor or a wizard, depending on what the icon represents. The Back and Forward buttons (in the upper right-hand corner) allow navigation through the panels.

The Control Panel is organized in a hierarchical manner. This is similar to the way that the low-level Configuration Editor organizes config elements in its navigator panel (refer back to Figure 1.7, “VRJConfig Config Element Navigator Panel”). The two hierarchies are similar, but the Control Panel hierarchy is not as dynamic as the Configuration Editor's navigator panel. Indeed, the Control Panel hierarchy is defined statically by the Control Panel configuration file (interested readers can see it in $VJ_BASE_DIR/share/vrjuggler/data/ControlPanel.xml) in order to avoid requiring many mouse button clicks just to get to the desired editor or wizard.

Figure 1.12. VRJConfig Control Panel Start Screen

VRJConfig Control Panel Start Screen

Editing an Existing Configuration Using the Control Panel

Similar to the low-level Configuration Editor, the Control Panel must be told what files will be edited. This is done by opening an existing configuration file. Note that the tool bar used by the Control Panel has the same buttons as the low-level Configuration Editor, shown earlier in Figure 1.3, “VRJConfig Configuration Editor Main Toolbar”. This indicates that the Control Panel has the same basic functionality for opening configuration contexts, but with the Control Panel, there is only a single context.

After opening a configuration file, navigate through the categories to find the editors that correspond to the contents of the file. The config elements within the file that have high-level editors will be displayed as icons within the Control Panel. Clicking on the icon will open the high-level editor for that config element. The changes made in the high-level editor can be undone by clicking the Cancel button or by closing the high-level editor and clicking the Undo button in the Control Panel toolbar. Some examples of high-level editors can be found in Appendix F, VRJConfig Custom Editors by Infiscape.

Creating a New Configuration Using a Wizard

The configuration wizards are still being developed, and there is nothing to be documented (or used) at this time.

Updating Configurations

As noted above, VR Juggler configuration files and config definition files use XML. Among other benefits, using XML allows for (relatively) simple updating and migration using XSL Transforms (XSLT). Prior to using XML for VR Juggler configuration files, there was either no way to automate configuration migration or a script had to be written in a language such as Python or Perl. XSLT offers the VR Juggler developers a comparatively convenient mechanism to implement configuration migration and update code. All that is needed to run the XSLT program on a configuration file or config definition file is an XSLT processor, which most modern operating systems include by default. Examples of XSLT processors are xsltproc (part of the GNOME library libxslt), Xalan-J, Xalan-C++, Saxon, and MSXSL.

VRJConfig makes use of XSLT internally to update config element versions automatically. The XSLT used for this purpose is found in the config definition files that come with VR Juggler. Each definition version, except the first, includes an “upgrade transform” to handle migrating from the previous definition version. When a config file is loaded, its version is tested to determine if it is up to date with the corresponding config definition. If it is not, VRJConfig will prompt the user to determine if it can proceed with the automatic upgrade. After doing so, users must be sure to save the config file.

Configuration of VR Juggler

With this introductory information complete, we can now move on to configuring VR Juggler. The remainder of this book is devoted to specific configuration topics. In general, configuring VR Juggler means configuring two large pieces: inputs and displays. In Chapter 2, Configuring Input, we explain the process of configuring input devices, both physical and simulated. In Chapter 3, Configuring Displays, we move on to the topic of configuring displays. The appendices of this book are devoted to configuration of specific input devices. Those readers who are already familiar with the general configuration of inputs to VR Juggler can refer to the appendices to find device-specific configuration instructions and tips.



[1] More specifically, the contract exists between the JCCL Java® API and the JCCL C++ API.

Chapter 2. Configuring Input

Input is critical to all immersive applications. Without it, achieving a sense of immersion is nearly impossible. VR Juggler provides a very advanced, robust, and flexible input management system through the Gadgeteer Input Manager. The flexibility of the Input Manager is due in no small part to the parameterization of components such as device drivers and input device proxies, but there is no denying the fact that configuring input for VR Juggler is difficult. Evolving features of VRJConfig are simplifying the process, but a thorough understanding of the input configuration process is invaluable regardless of features and capabilities offered by VRJConfig.

In this chapter, we will provide all the information needed to understand the configuration of input within VR Juggler. Fortunately, the design of the Input Manager reduces the process of input configuration to the same three conceptual steps regardless of what input device is being used:

  1. Configure the input device, physical or simulator

  2. Configure one or more proxies that point at the physical device

  3. Configure zero or more proxy aliases

In the real world, there may be as many as five actual steps, but the above three sum up the overall process to follow every time input is configured.

The Input Manager

The release of VR Juggler 2.0 Alpha 1 in March 2003 brought with it a new feature: device driver plug-ins. Instead of statically compiling all device drivers into the Input Manager, device drivers could now be loaded on demand. In order for this to occur correctly, however, the Input Manager now had to be told what driver(s) to load. This is achieved by configuring the Input Manager using a config element.

The Input Manager config element has three properties: a driver search path, a driver DLL name, and a directory to scan for drivers to load. All three properties may have zero or more values, but at least one must have a value in order for the config element to be useful. Each of the three is explained in the following subsections.

Driver Search Path

The driver search path provides the Input Manager with a list of directories where driver DLLs may be found. This property has a default setting determined at the time when the Input Manager was compiled. Based on the current list of supported operating systems, the default search path will be one of three values:

  • $VJ_BASE_DIR/lib/gadgeteer/drivers: The default for Linux, Microsoft Windows®, Mac OS X, FreeBSD, and other platforms where only one binary type is supported.

    Note

    On Microsoft Windows®, the default is actually %VJ_BASE_DIR%\lib\gadgeteer\drivers. Platform-specific path details such as this may be omitted in this document for brevity. Bear in mind that internal handling of paths by VR Juggler and its components is always done correctly for a given operating system.

  • $VJ_BASE_DIR/lib32/gadgeteer/drivers: The default for an N32 build on the IRIX® operating system.

  • $VJ_BASE_DIR/lib64/gadgeteer/drivers: The default for an N64 build on the IRIX® operating system.

Since the base collection of device drivers that come with Gadgeteer are guaranteed to appear in the default search path, there is usually no need to set a value for the Input Manager driver search path property. The search path is configurable to allow users to tell the Input Manager where to find drivers they have written themselves that appear outside the VR Juggler installation hierarchy. When one or more values are provided through the driver search path property, the default search path is always appended to the end of the list. This ensures that user-specified directories will always be searched first when loading drivers.

When setting the driver search path, environment variables are allowed. As with all uses of environment variables in VR Juggler configuration files, they must be specified using either the form ${ENV_VAR} or $(ENV_VAR). Using $ENV_VAR or %ENV_VAR% will not work in this case or any other case. Any environment variable may be used.

Driver DLL Name

The driver DLL name property is used to name specific device drivers to load. The name of the DLL to load must be specified in a special platform-agnostic manner. Essentially, this form boils down to removing the file extension from the DLL name. For example, the Ascension MotionStar Wireless® DLL may be named MotionStar_drv.so, MotionStar_drv.dylib, or MotionStar_drv.dll depending on the host operating system. Note that all three have a common base name: MotionStar_drv. In the configuration of the Input Manager, this common base name is the string to set for the property value. This aids with portability of configuration files and (we hope) reduces the mental overhead required to configure the Input Manager on different operating systems where conventions will almost certainly vary.

Driver Scan Path

The driver scan path provides a mechanism for loading all the device drivers found in the named directory or directories. This behavior is very similar to the old Input Manager that knew about all the device drivers, but in this case, the drivers are not statically compiled into the Input Manager. Use of this property is helpful when there is no need or no desire to load drivers individually. Doing so increases the memory overhead of the Input Manager, but it dramatically reduces the possibility for configuration errors related to driver loading.

Tip

Try to avoid using the driver scan path with the loading of individually named DLLs. Doing so could lead to unpredictable, undesirable behavior if the scanning process finds a DLL already identified by the naming of a specific driver DLL.

As with the driver search path, environment variables can be used in the string value(s) provided for this property. Furthermore, there is no need to specify a platform-specific file extension for use when scanning a directory for device drivers. The file extension is determined at compile time based on the target operating system. The search criterion used by the Input Manager is that the files match the pattern *_drv.<ext> where <ext> is the platform-specific file extension set at compile time.

Input Devices

The configuration process for input devices depends on the specific device being configured. In general, there is very little overlap among the configurations of the various device drivers that come with Gadgeteer. There are some exceptions such as the need to name a serial port and baud setting for some drivers, but this is hardly enough to provide the basis for a general explanation of how to configure input devices for use with VR Juggler. Instead, we will concentrate on the two categories of devices supported by Gadgeteer: physical devices and simulator devices. The term physical device is somewhat ambiguous because simulator devices get their input from a keyboard and mouse, and a keyboard and mouse are certainly physical input devices. The critical distinction is that simulator devices mimic the behavior of physical devices such as six-degree-of-freedom (6DOF) trackers using input from a keyboard and/or a mouse. As such, the configuration of simulator devices is very different from that of physical devices, and that difference is worth deeper examination.

A key aspect that is common to all input devices handled by the Input Manager is that they define input sources of one or more input categories. The input categories currently supported by Gadgeteer are the following:

  • Analog: Data in a continuous range with well-defined minimum and maximum values. Applications receive the data as normalized values in the range 0.0 to 1.0 inclusive.

  • Command: Discrete command input, often in the form of recognized spoken commands or pre-defined gestures.

  • Digital: Discrete on/off input, usually corresponding to simple button presses and releases.

  • Digital glove: Distinct combinations of fingers.

  • Gesture glove: Recognizable hand gestures based on knuckle angles.

  • Keyboard/mouse input handler: Source of keyboard and mouse events from the native windowing system.

  • Positional: Multi‒degree-of-freedom tracker data. Up to six degrees of freedom are supported.

  • String: Arbitrary sequences of characters, usually corresponding to spoken words or phrases.

Thus, a given device, physical or simulator, will fall into one or more of those categories. That same device may provide multiple input sources for a given input category. For example, a game pad may have eight buttons and two joysticks that operate in two axes. That game pad defines eight digital input sources (from the eight buttons) and four analog input sources (from the two axes of the two joysticks). We will speak of input sources more abstractly in the following sections, so it is important to understand what we mean by this term before proceeding.

Physical Devices

Physical devices are those that provide what is traditionally considered immersive input. Typically, such devices have multiple degrees of freedom and/or provide specific information about what the user is doing. For example, a glove device could provide data identifying a specific hand gesture that the user is making. By attaching a 6DOF tracker sensor to the glove, both the position of the hand and the gesture it is making would be available to an immersive application. Placing tracker sensors all over the user's body provides full-body position and orientation information.

In terms of the Gadgeteer Input Manager, physically devices have thus far been characterized as requiring a device driver plug-in. The driver implements in software the communication protocol with the hardware so that data can be read from the device and interpreted before being passed on to the VR Juggler application. As of this writing, it is certainly true that each supported physical device has its own device driver plug-in. Though this could change in the future, it will be useful to remember this fact for the purposes of the topics presented here.

The process of configuring a physical device means configuring its device driver. As noted above, there is very little commonality in the process of configuring specific hardware devices, but it is vital to understand the importance of properly configuring a device driver as part of the overall input configuration. If the driver itself is not configured correctly, there is no way that the rest of the input chain can function properly. In other words, if the driver cannot read data from the input device, there will be nothing to pass on to the VR Juggler application. For instructions and tips on specific device configurations, refer to the appendices at the end of this book.

Since all physical devices do have a device driver plug-in, proper configuration of the Input Manager is absolutely critical. Configuration elements for device drivers are handled by the drivers themselves, and if the Input Manager does not load a required device driver, the config element cannot be processed[2]. As such, it is very important to remember to configure the Input Manager as part of configuring a physical device.

Tip

If individual devices are configured in separate .jconf files, include an Input Manager config element for loading the device driver in the same file as the driver config element. The Input Manager can be configured repeatedly, so there is no problem with having multiple Input Manager config elements as part of a complete configuration. Each Input Manager config element must have a separate name, however, or else one config element may overwrite another in the Configuration Manager's pending list. The config element names can be made unique by including the name of the driver being loaded. For example, a .jconf file loading the IBox driver could include an Input Manager config element named “Input Manager IBox.

Simulator Devices

The configuration of simulator devices is much more involved than that required for physical devices. All simulator devices read data from a traditional desktop keyboard and mouse and translate the data into information that mimics the behavior of the various device types supported by the Input Manager[3]. To configure a simulator device, there are three pieces that must be configured: a keyboard/mouse input handler, an input window, and the actual simulator device. We explain this in more detail below.

Keyboard/Mouse Input Handlers

Keyboard and mouse input data are received using what are known as keyboard/mouse input handlers in Gadgeteer terminology. Keyboard/mouse input handlers are tied to a window in a given windowing system. That is, a desktop window of some form must be open and have focus in order for Gadgeteer to be able to receive keyboard and mouse input data. There are two options for achieving this when configuring VR Juggler: plain input windows that display nothing and graphics windows that display the three-dimensional scene. Both of these can be configured to feed keyboard and mouse activity into Gadgeteer keyboard/mouse input handlers. As such, we can think of both types of windows as event sources for keyboard/mouse input handlers. For the remainder of this book, we will normally refer to “keyboard/mouse input handlers” (the Gadgeteer device type) and to “event sources” (desktop windows that feed keyboard and mouse events into Gadgeteer keyboard/mouse input handlers). When necessary, we will refer specifically to plain input windows or to graphics windows. The use of graphics windows as event sources is discussed in more detail in the section called “Graphics Window Input”. For now, we will concentrate on the concept of event sources in general.

mouse sensitivity

This property defines the relationship between mouse movement within the event source and the number of key presses registered by the event source. The notion of a key press in the context of a mouse is counter-intuitive, and an in-depth explanation of what this means is beyond the scope of this document. We must explain, however, that keyboard/mouse input handlers record input using the abstract concept of a key press. This corresponds to an event raised by the windowing system and handled by event sources for keyboard/mouse input handlers. A keyboard/mouse input handler records how many times an event was raised since the last time its data sample buffers were retrieved by the Input Manager. In the context of mouse movement, the interpretation of how much the mouse moved is based on the number of mouse motion events raised rather than the number of pixels the mouse pointer would have moved physically. Such behavior is necessary for recording input when the mouse is locked to the center of a window. Setting the mouse sensitivity tells the keyboard/mouse input handler how to interpret the mouse motion events. A value of 1.0 for this property indicates that one pixel of movement will correspond to one key press. A value of 0.1 says that ten pixels of movement translate to one key press. The default value is 1.0.

device host

This property is used for configuring a cluster of graphics nodes. The topic of cluster configuration is addressed in Chapter 4, Configuring a Cluster.

Before we explain the use of keyboard/mouse input handler as data sources for simulator devices, we should note that keyboard/mouse input handlers can be used as input devices for VR Juggler applications. As we will see in the section called “Device Proxies”, there is a proxy type and corresponding device interface through which applications can receive keyboard and mouse input. In this case, there is no special device driver to load.

Input Windows

As stated above, input windows are normal desktop windows, but they display nothing. Their sole purpose is to handle keyboard and mouse events from the native windowing system and feed those events into a Gadgeteer keyboard/mouse input handler.

origin

This two-valued property sets the origin for the window when it is opened.

Important

In VR Juggler, the lower left-hand corner of the display is the origin for positioning windows. This is in contrast to the way some windowing systems work wherein the display origin is the upper left-hand corner.

size

This two-valued property defines the dimensions of the window in pixels.

display number

The “display number” property is used with windowing systems that define multiple displays on which windows can be opened. As of this writing, there is one such windowing system supported: the X Window System. The value set for this property is used as an index into an array of available displays defined in another config element called the Display System. The default value is 0, and this property will be ignored when using windowing systems that do not support multiple displays.

keyboard/mouse input handler name

This property points to another config element of type keyboard_mouse_device. The value is the configured name of the keyboard/mouse input handler to which events will be fed. This property must be set to point to a valid config element of a keyboard/mouse input handler in order for the input window to be useful.

lock key

The “lock key” property defines a key that, when pressed, causes the mouse pointer to be locked to the center of the window. Such a capability is useful when it is necessary for the mouse to remain within the borders of the window at all times. The lock key also unlocks the mouse pointer when it is in the locked state. The default value is KEY_NONE which indicates that there is no key that toggles mouse pointer locking.

start locked

Related to the lock key, the “start locked” property indicates where the mouse pointer should be locked to the center of the window as soon as it opens. This setting defaults to false.

sleep time

Each input window object handles events from the windowing system in its own thread. Depending on the nature of the windowing system, the event handling loop may never block on its own. To prevent the input window thread from starving all the other threads, this property sets a sleep time (in milliseconds) for the input window thread. Adjustment of this property may be necessary to get optimal behavior on a given computer. The default setting causes the input window sample loop to sleep 75 milliseconds between each event handling pass.

Specific Simulator Device Types

With an event source configured, we can now configure a simulator device. The simulator device type to configure will be based on what is needed by the application. There are five simulator device types from which we can choose:

  1. Simulated analog device: Provides a variable number of analog input sources in a configurable range based on two key presses (increment the value, decrement the value).

  2. Simulated digital device: Provides a variable number of digital (on/off) inputs based on a single key press.

  3. Simulated digital glove device: Provides a pair of digital inputs representing finger combinations from the left and right hand in a manner similar to a pair of Fakespace Pinch™ Gloves.

  4. Simulated glove gesture device: Provides a variable number of gesture inputs in a manner similar to a Virtual Technologies CyberGlove.

  5. Simulated positional device: Provides a single of 6DOF positional input source based on a combination of twelve key presses.

Below, we review each of these in detail and explain how to configure them in a manner that makes them easier for VR Juggler application users to understand. Before doing so, however, we must note that the config element for each simulated device type has a property for a keyboard/mouse input handler proxy. Device proxies will be explained in detail in the section called “Device Proxies”, but for now, it will be helpful to keep in mind that the simulated device types do not refer directly to a keyboard/mouse input handler. Instead, an extra level of indirection is introduced; namely, a proxy to the actual keyboard/mouse input handler.

Furthermore, all simulated device types have key presses configured as key/modifier pairs. On a standard keyboard, there are alphanumeric keys (A‒Z, 0‒9) and modifier keys (CTRL, ALT, and SHIFT). A key/modifier pair is thus a combination of an alphanumeric key and a modifier key. Since mouse input is also considered a key press in the eyes of the Input Manager, a key/modifier pair may also be the combination of mouse movement and a modifier key or the combination of a mouse button press and a modifier key.

Simulated Analog Devices

Simulated analog devices provide input values from a continuous, configurable range. At the application level, the input will be received as values normalized to occur in the range 0.0 and 1.0 inclusive. Each configured simulated analog device can provide zero or more analog input sources, each configured as a pair of key presses: one key press to increment the value and one to decrement it.

keyboard/mouse proxy

This property specifies a pointer to another config element of type keyboard_mouse_proxy that in turn points to the keyboard/mouse input handler from which keyboard and mouse input will be read.

increment key

This property defines a list of key/modifier pairs that are used to identify the key presses for incrementing the value of the analog input sources. There may be zero or more of these, and the amount must match the number of decrement key presses defined. The number of key presses defined indicates the number of analog data sources that this device has.

decrement key

This property is the complement to the “increment key” property. It too specifies a list of key/modifier pairs that are used to identify the key presses for decrementing the value of the analog input sources. There may be zero or more of these, and the amount must match the number of increment key presses defined. The number of key presses defined indicates the number of analog data sources that this device has.

delta

The “delta” property defines the change in the analog value per key press.

range minimum

This property sets the minimum possible value for the device as a floating-point value. The default is 0.0.

range maximum

This property sets the maximum possible value for the device as a floating-point value. The default is 255.0.

initial value

This property sets the starting value for the device as a floating-point value. This must be in the range [min, max]. The default is 0.0.

Note that a single simulated analog device shares the settings for the delta, range minimum, range maximum, and initial value across all its input sources. If there is a need to vary these settings, multiple simulated analog devices must be configured.

Simulated Digital Devices

Simulated digital devices translate keyboard events and mouse events (both motion events and button presses) into digital input. A single simulated digital device may provide many digital input sources.

keyboard/mouse proxy

This property specifies a pointer to another config element of type keyboard_mouse_proxy that in turn points to the keyboard/mouse input handler from which keyboard and mouse input will be read.

digital button key

The “digital button key” property defines a list of key/modifier pairs that provide digital input sources. There may be zero or more key/modifier pairs, and the number defined specifies the number of input sources that this device has.

Simulated Digital Glove Devices

Simulated digital glove devices mimic the behavior of gloves that have distinct gestures or finger combinations. Such gloves are usually in the same vein as the Fakespace Pinch™ Glove where the glove sends a signal indicating which fingers are pressed together or are pressing a pad on the base of the palm. Gestures are identified as being either on or off. This is use is different enough from gesture recognition devices that a separate device type was created for it, but it is worth noting that a “digital” glove could act as a gesture recognition glove with the correct information provided to the Input Manager.

keyboard/mouse proxy

This property specifies a pointer to another config element of type keyboard_mouse_proxy that in turn points to the keyboard/mouse input handler from which keyboard and mouse input will be read.

key press

This property defines a list of zero or more key/modifier pairs that provide digital values for each of the desired finger combinations. The number of input sources for this device will be determined by the length of this list. Digital device proxies (discussed later in the section called “Device Proxies”) will provide a more meaningful way of mapping the digital input source to a finger combination identifier.

left glove position

This property sets a pointer to a position proxy that provides 6DOF tracker information for the left hand.

right glove position

This property sets a pointer to a position proxy that provides 6DOF tracker information for the right hand.

Simulated Glove Gesture Devices

As of this writing, gesture support in VR Juggler 2.0 is non-functional, so these devices cannot be utilized by VR Juggler applications. Until such time as gesture support in VR Juggler is completed, this section will not be filled in.

Simulated Positional Devices

Simulated positional devices stand in for 6DOF trackers. Each has a unique 4×4 transformation matrix that can be used in traditional computer graphics computations. Unlike the previous simulated devices, one simulated positional device defines exactly one data source. To have n positional data sources for a VR Juggler applications, n simulated positional devices are required.

keyboard/device proxy

This property specifies a pointer to another config element of type keyboard_mouse_proxy that in turn points to the keyboard/mouse input handler from which keyboard and mouse input will be read.

key pairs

This property has twelve values that define the key/modifier pairs that are translated into changes in the 4×4 transformation matrix held by the simulated positional device. For each degree of freedom, there are two key/modifier pairs defined: one to increment the value along or around an axis and one to decrement it.

initial position

This property has three values that specify the initial position in three-dimensional space of this positional device.

initial rotation

Similar to the “initial position” property, this property has three values that define the rotation about the X, Y, and Z axes for this device.

translation delta

This property sets the change in translation per key press received from the keyboard/mouse input handler. This value is in meters, and the default is a translation of 0.1 meters (10 centimeters) per key press. Translation occurs in the axis associated with the key being pressed.

rotation delta

This property sets the change in rotation per key press. The value is given in degrees, and the default is 1.0 degrees of rotation per key press. Rotation occurs about the axis associated with the key being pressed.

translation coordinate system

This property has two possible values: Local or Global. The value chosen indicates whether translations occur in the local coordinate frame or in the global coordinate frame. The default is the local coordinate frame.

rotation coordinate system

This property has two possible values: Local or Global. The value chosen indicates whether rotations occur in the local coordinate frame or in the global coordinate frame. The default is the local coordinate frame.

position filters

This property defines zero or more position filters to apply to data received from this device. Position filters are covered in more detail in the section called “Position Filters”.

Device Proxies

Device proxies introduce the layer of abstraction and indirection needed to ensure that VR Juggler applications do not become tightly coupled with specific devices. That is, a VR Juggler application cannot be written to work only with an Ascension MotionStar Wireless®, for example, because device proxies prevent direct access to the underlying hardware device. Instead, the proxy acts as a pointer to a single data source from the actual device. Knowing this information will help with understanding how proxies are configured.

Earlier in the section called “Input Devices”, we listed the eight device categories defined by the Gadgeteer Input Manager. Each of those device types has a corresponding device proxy type, as shown below:

  • Analog proxy

  • Command proxy

  • Digital proxy

  • Digital glove proxy

  • Gesture proxy

  • Keyboard/mouse proxy

  • Positional proxy

  • String proxy

The config element for each proxy type has a property that points at an input device config element of the corresponding device type. For example, a position proxy config element can point at the config element for a simulated position device, an Ascension MotionStar Wireless®, a Polhemus Fastrak®, and so on.

The second property in every proxy type is a unit identifier. As we said in the section called “Input Devices”, each input device provides one or more input sources of a given input category. For example, an Ascension Flock of Birds® with three sensors (birds) would provide three input sources in the positional data category. An InterSense IS-900™ tracker with the usual head and wand sensors would provide two positional input sources, five digital input sources (five buttons on the wand), and two analog input sources (two axes on the wand joystick). The device proxy unit identifier acts as a zero-based index into the various input sources.

Putting all of this together, we find that we must have a unique proxy for each input source. Several proxies may point at a single input device, but each proxy config element will have its own name. The input device will have separate queues for its input source types, so the unit identifier property for each proxy must be set accordingly. For the IS-900™ mentioned in the previous paragraph, we would have the configuration arrangement shown in Table 2.1, “Proxies for an InterSense IS-900™”.

Table 2.1. Proxies for an InterSense IS-900

Input SourceProxy TypeProxy NameUnit Identifier
Head trackerPositionHead Proxy0
Wand trackerPositionWand Proxy1
Wand trigger buttonDigitalButton 0 Proxy0
Wand red buttonDigitalButton 1 Proxy1
Wand yellow buttonDigitalButton 2 Proxy2
Wand green buttonDigitalButton 3 Proxy3
Wand blue buttonDigitalButton 4 Proxy4
Wand joystick x-axisAnalogJoystick X-Axis Proxy0
Wand joystick y-axisAnalogJoystick Y-Axis Proxy1

Proxy Aliases

Proxy aliases provide more abstract identifiers for use at the level of VR Juggler applications. In a VR Juggler application, there will invariably be at least one device interface object, and that object must be initialized with a symbolic identifier used by the Input Manager to connect the device interface with a proxy[4]. While the specific proxy name can be used, aliases offer some additional flexibility because a single proxy may have many aliases. For example, a device with three digital buttons would have three digital proxies pointing at it. Those proxies could be named “Left Button,” “Middle Button,” and “Right Button.” A VR Juggler application could be written to refer to Left Button directly, but that leads to the potential for tight coupling with a specific immersive system configuration. To help prevent this, some aliases could be created for the digital proxies. Those aliases could have names such as “Accelerate Button,” “Rotate Button,” “Stop Button.” Providing more symbolic names such as these facilitates the migration and adaptation of VR Juggler applications to different immersive systems.

Position Filters

When dealing with data from the sensors of a tracker, the positional information returned from a tracking system can be used directly, but many times the frame of reference for the tracker and/or its sensors is not the same as the real world. Because of this, the tracking data needs to be transformed into a common coordinate frame. This may sound complex, but what it means is that the coordinate system used by the tracker system is not the same as what VR Juggler applications expect. This is not because VR Juggler requires some certain coordinate system. Rather, the reason is that applications are generally written to expect the immersive system to use a standard coordinate system. If an application had to run in two different immersive configurations and one system had the x-axis going to the right while the other had the x-axis going up, the application would not behave consistently between the two. Before we explain how to manage all these coordinate systems, we must first define the notation that we will use. Once that is done, we will move onto the actual configuration aspects.

Matrix Notation

The description herein will make use of a specific matrix notation for transformations between various frames of reference. We have found this notation to be very useful for tackling transformation problems related to immersive applications. The original inspiration came from a VR systems book, and we have adapted it slightly for our purposes. The simple form of the notation is the following:

frame1Mframe2

Here, we use subscripts to represent the two frames of reference for the transformation. In this case, we say that the matrix transforms from frame1 to frame2. More specifically it moves the frame of reference from frame1 to frame2. If we are talking about transforming points (or other geometry), then the transformation would be as follows:

Pframe1 = frame1Mframe2 * Pframe2

Notice that we use the notation for points as well as matrices. The subscript of the point represents the frame of reference to which the point's coordinates are relative.

Some readers may be thinking that we have this backwards and that the matrix above moves from frame2 to frame1. From the perspective of the transformed points, this is true. From the perspective of transforming frames of reference, however, the matrix moves from frame1 to frame2. It is all a matter of perspective. The math will work out the same either way, and readers are encouraged to think about it whichever way seems more comfortable.

Where this notation gets interesting is what if we want to move from frame1 to frame3 and we have the following matrices:

frame1Mframe2, frame3Mframe2

We know that the matrix we want is frame1Mframe3, so the correct matrix is the following:

frame1Mframe3 = frame1Mframe2 * frame2Mframe3

This means that we must invert the frame3Mframe2 matrix in order to use it. This notation makes such details easy to identify since the frames of reference are part of the matrix name. We make use of this in the next section to keep track of which matrices to use at which times.

Tracker Transformations

Figure 2.1, “Frames of reference for configuring a tracking system” shows a generic view of the coordinate frames at work in a standard tracking system. The details of this diagram are described below.

Figure 2.1. Frames of reference for configuring a tracking system

Frames of reference for configuring a tracking system

  • World coordinate frame: The world coordinate frame is the base coordinates of the real world system. In other words, this is the physical space of the immersive system. The coordinate frame used depends upon local preferences, but the VR Juggler coordinate frame usually has X to the right, Y up, and Z coming out of the screen. Note that this is a right-handed coordinate frame.

  • Tracker: This is the base frame of reference for the tracking system. This is normally defined by the "base unit" of the tracking system. For example, with an Ascension Flock of Birds® tracking system, this coordinate frame is defined by the location of the transmitter (the large black cube). The documentation provided with the tracking system usually identifies the coordinate frame used or explains how to configure it to suit local needs.

  • Receiver: This is the coordinate frame of the physical sensor (such as a bird in a Flock of Birds®). Normally, people do not think of the receiver as having a coordinate frame but instead think of it as having a position relative to the base tracking system. While this is true, that transformation actually defines another local coordinate frame for the receiver.

  • Tracked Object: The tracked object frame is a general name for the actual location that we are interested in tracking. In some cases, this is exactly the same as the Receiver, but this is not always the case. A common example of this is tracking the position of the user's eyes. Normally, people do not put a sensor exactly at the position of the user's eyes. Instead, the sensor is normally mounted on the side of a pair of glasses or a hat or some other object that the user wears on his or her head. In this case, the tracked object coordinate frame is at the location of the eyes.

When we configure a tracking system (and the associated position device proxies), we want to configure the system to return the correct tracked locations for the tracked objects in the environment. Computing this position involves the combination of multiple transformations. Just in the common case above, there are several transformations, shown below:

  • worldMtracker: This is the transformation that captures the location of the tracker base system in the real world.

  • trackerMreceiver: This is the reported transformation of the receiver. This is the only transformation that normally varies as an application is running and is the value that is returned by the tracking system.

  • receiverMtracked_object: This is the transformation from the position reported by the tracking system to the actual location that we want to track.

The value that the we want to configure the system to return is worldMtracked_object. This transformation is the location of the tracked object within the real world. To return this value we must compute the following:

worldMtracked_object = worldMtracker × trackerMreceiver × receiverMtracked_object

VR Juggler takes care of computing this value at run time, but as we stated earlier, the position of the tracker within the tracking coordinate system (i.e., trackerMreceiver) is the only value that normally varies at run time. The other two values must be configured in the tracking system configuration element. Fortunately, we have made this very easy to do in VR Juggler, and the description makes it sound much more complicated than the process really is.

Each object that can return position information (positional devices and position device proxies) can be configured with a set of position filters. The position filters are stored as a list of nested config elements within the positional object's configuration element. Every physical positional device has this property in its config element. While the possibility exists for multiple types of filters, there exists only one at the time of this writing: the position transformation filter. This filter is used to add transformations to the positional object in a VR Juggler configuration. This filter type allows the configuration of pre-multiplying and/or post-multiplying the returned positional value by a user-defined transformation matrix. This is exactly what we need to configure a tracking system.

Configuring Position Filters

We will start by configuring the tracking device. As we can see from the equation above, we need to pre-transform the value returned from the tracking system (trackerMreceiver) by the position of the tracking system within the virtual world (worldMtracker). We configure this by adding a position transform filter to the “position filter” property for the tracking device config element and setting the values of the pre-translation and pre-rotation to this value.

Important

All physical units for pre- and post-translation properties must be set in meters. There are no exceptions to this rule.

With the pre-translation and -rotation set up, we must also define the device units. The position transform filter config element has a property that identifies the scaling to apply to convert the units from the tracker into meters. The setting to choose depends on the tracker hardware, but if in doubt about the positional data being received by a VR Juggler application, try using the conversion from feet to meters.

To configure the tracked object positions, we need to configure the transformation applied to the position proxy for the tracked object (for example, the user head proxy). In this case, however, the transformation we need to apply is a post-transform of the value. In the config element for the positional device proxy, we must add a position transform filter to the “position filter” property and set the post-translation and post-rotation to the offset of the tracked object relative to the sensor being used to track the object.

Important

When setting up the position transform filter for a positional device proxy, always leave the unit conversion factor set to meters (a value of 1.0). By the time tracker data gets to the proxies, it is already in meters, and converting it to anything else would lead to problems at the VR Juggler application level.

Tip

In the ideal case, the above process would work flawlessly every time, but this does not always happen. We have a couple of suggestions for how to deal with configuration problems of this sort. First, we find that drawing a picture of the all transformations helps clarify all the information involved. Simply create a diagram that shows all the coordinate frames and the transformations between them. This can help in finding the one transformation that is not quite set correctly. Second, configure the immersive system one step at a time. Do not try to get both the tracking system transformation and the proxy transformation set all at once. Instead, work on getting the transformation correct for the tracking system first. Once this value is set, then start working on the proxy transformation. It is much easier to work on the configuration for a tracking system if only one value is changing at a time.

Putting it All Together

The previous section was purposely abstract in order to provide the conceptual background needed to understand the “what” and the “why” of configuring position filters. Ultimately, we care about the “how” of configuring position filters. As the name of this subsection implies, we will now put together all the concepts introduced above to explain concretely how to configure position filters. The following sub-subsections are essentially a step-by-step process for configuring the position filters used for the tracking system and its sensor(s).

Defining the Origin of the Virtual World

Choosing the origin of the virtual world is the first step in defining how the immersive visualization system will work. Everything prior to this point relates more to how the Input Manager of VR Juggler works, but for the remainder of this book, our attention will be focused on configuring how we want the immersive system to work. Since the origin is the basis for configuring everything else, we must start with it.

The origin of the virtual world is a point in the physical space (the space of the VR system). The coordinate system rooted at this origin point is the World coordinate system shown above in Figure 2.1, “Frames of reference for configuring a tracking system”. Users of VR Juggler can configure the origin to be anywhere they want, but it is best to pick a point that makes sense. Most VR applications are going to orient their virtual space around the virtual world origin (it makes the math easier most of the time). In order to see all the important aspects of the virtual world, then, the origin must be positioned well[5]. The following are some tips for placing the origin:

  • For a projection system with a floor, a good place for the virtual world origin is at the center of the floor. This gives the user some room to move around physically, and it helps provide the user with a sense that s/he is at the center of the virtual space.

  • For a projection system with no floor, placing the origin is more difficult. Since the user will not be able to see what is below him or her in the virtual world, having the origin too far from the screen will cause objects in the virtual world to go out of view too easily. If the origin is behind the screen, the user may feel as though s/he is a spectator in the virtual space rather than an immersed participant. If the origin is above the floor (to compensate for a screen that is raised off the floor), the user will feel as though s/he always has to look up at the world from a low perspective―essentially from a bug's-eye view).

  • For a head-mounted display, the origin should be placed relative to the tracking system transmitter (or the emitter, depending on the terminology used by the manufacturer). For example, if the transmitter is suspended from the ceiling so that it is above the user, put the origin directly underneath the transmitter. If the transmitter is mounted from the floor, then put the origin somewhere directly in front of the transmitter.

  • Keep the origin within the tracked area. Application authors are likely to assume that the user starts using the application at the virtual world origin. If the origin cannot be reached physically by the user because it is outside the tracked area, this could reduce the functionality of the application in such a configuration.

Defining the Transmitter Position and Orientation

Once the origin is chosen, then the pre-translation information can be entered into the tracker device position filter. This will tell the Input Manager how to transform data from the tracker into the coordinate frame of the virtual world, as described in the section called “Configuring Position Filters” and the section called “Putting it All Together”. Providing the pre-translation information is very simple. Measure from the physical location corresponding to the virtual world origin to the origin of the tracking system. Refer to the documentation of the tracking system to determine where its origin is (or how it may be set if it is configurable on the hardware side). Enter the measurements in meters for the pre-translation values (X, Y, and Z) of the position filter of the device configuration element. To put this another way, the pre-translation values entered for the tracking system transmitter correspond exactly with the position of the tracker in the virtual space relative to the origin of the virtual world.

Entering the orientation of the transmitter (the pre-rotation information in the position filter) can be a little more difficult. First, determine the coordinate frame of the transmitter. This is usually provided in the hardware documentation. Then, figure out how to rotate that coordinate frame so that it matches the VR Juggler coordinate frame. Remember that VR Juggler internally uses a right-handed coordinate frame with Y up. If it is possible to configure the coordinate frame of the tracker on the hardware side, it is typically easier to do this than to come up with the rotations needed to convert from the tracker coordinate frame to the VR Juggler coordinate frame.

Caution

Different graphics APIs have different coordinate frames. Do not consider such details when configuring VR Juggler. The VR Juggler Draw Managers worry about how to transform data from the internal VR Juggler coordinate frame into the coordinate frame of the graphics API. Users need never worry about such issues.

Defining the Tracked Points

The tracked points are those that correspond to the sensors of the tracking system. There will always be a head sensor[6], and there is usually a sensor for one of the user's hands or for a wand-type device. Depending on how the sensor is mounted, it may be necessary to pick a point to track. For example, if a tracker is affixed to a pair of stereoscopic viewing glasses, it will probably be out of the user's line of sight. To get a good perspective (and hence, a good stereo effect), however, the tracked point should be right between the user's eyes. This will require a post-transformation on the proxy corresponding to the sensor.

Defining the post-translation and -rotation for a position proxy is mathematically different than the way that the pre-translation and -rotation are set up for the transmitter. In this case, we are operating in the coordinate frame of the sensor rather than that of VR Juggler. Therefore, we must first determine the coordinate frame of the sensor. Then, we measure from the sensor to the tracked point. The measurements (in meters) for the X, Y, and Z positions of the tracked point relative to the sensor are entered for the post-translation of the position filter for the proxy. To get the post-rotations, determine how to rotate from the VR Juggler coordinate frame (right-handed, Y up) to the coordinate frame of the sensor. Enter those rotations (in degrees) for the post-rotation of the proxy position filter.

Note

Take careful notice of the way that this is reversed from the means for configuring the position and rotation of the tracking system transmitter. For the transmitter, we measured from the user-defined origin to the origin of the tracking system. Then, we rotated from the coordinate frame of the transmitter to the VR Juggler coordinate frame.



[2] An entry in the VR Juggler FAQ provides more information about this topic and addresses specific issues that users have encountered.

[3] For those unfamiliar with the functionality of the Input Manager, the supported device types are 6DOF positional, digital, analog, glove, command, string, and gesture. Refer to the VR Juggler Programmer's Guide for more information on this topic.

[4] For more information on the use of device proxies and device interfaces by VR Juggler applications, refer to the VR Juggler Programmer's Guide.

[5] Of course, many (most) applications will be written after the immersive system is configured, so application authors are likely to make assumptions about the position of the origin based on an existing configuration. For new installations that will be running existing applications, the choice of the origin placement may be more or less difficult depending on the needs of the applications.

[6] Even when the user's head is not tracked, some positional device must be configured to position the user's head. VR Juggler requires that each user has a head position. This may come in the form of a sensor, or it may be a simulated position device.

Chapter 3. Configuring Displays

Displays are the single most configurable component of VR Juggler. Considering the crucial nature of displays in immersive visualization, this makes sense. In this chapter, we explain all the ins and outs of configuring displays.

The Display Manager

When configuring displays, the Display Manager is the first piece that must be configured. The Display Manager is configured by the “Display System” element (type display_system). Except in the case of a cluster configuration, there must always be one and only one “Display System” configuration element in a configuration. As we will see, however, the information contained in the config element is only used by certain windowing systems. The Display System config element has only two properties: “number of pipes” and “X11 displays.” These are explained below.

number of pipes

This property tells the Display Manager how many physical graphics pipes the host machine has. This information is needed by packages such as OpenGL Performer, and it must accurately match the number of physical graphics pipes to prevent undesirable run-time behavior.

Caution

The second property in this configuration element provides a list of X11 pipes. Do not be confused about the meaning of this property. It does not have to correspond to the number of displays configured in the other property. While there may be a direct correspondence in many cases, there does not have to be. In other words, the number of displays configured in the “X11 displays” property will be greater than or equal to the value of this property.

X11 displays

This property defines a list of available X Window System (X11) display identifiers available for opening windows of any type. For machines running X11, there must be at least one value defined, and there is no upper limit to the number of values that may be set, but the number of displays configured here must be greater than or equal to the number of graphics pipes on the host machine. The display identifiers use either the X Window System display name or a special value, -1, indicating that the value of the DISPLAY environment variable should be used.

To review, X Window System displays are identified by the syntax :<display>.<screen>. For example, :0.0 is the most commonly found identifier. Virtually all workstations running the X Window System will have a :0.0 display. Multi-pipe machines will vary in the manner in which their displays are identified. For example, a multi-pipe Onyx running in a multi-keyboard configuration will have displays :0.0 through :n.0 for n displays. If that same Onyx were operating in a single-keyboard configuration, its displays would be :0.0 through :0.n. The interesting thing about the X Window System is that remote displays can be opened. Hence, it is often useful to define a value of a remote display where we can open windows. The syntax for this is the same as the standard X11 syntax for a remote display name.

To summarize, this property can have one or more values, and they can be any mixture of X11 display names and the special -1 value indicating that the value of the DISPLAY environment variable will be used. While there is no strict ordering required, it is usually helpful to have the values 0 through n match the ordering for the first n pipes on the machine. As we will see in the next section, the values set in this property will be referenced by display window configuration elements as items in an array.

It should be fairly obvious at this point that the “X11 displays” property of the “Display System” config element will only be utilized on machines running the X Window System. Nevertheless, there must always be one “Display System” config element in a non-cluster configuration with an accurate value set for the number of available graphics pipes.

Note

The handling of multi-head Microsoft Windows® computers by VR Juggler is not yet complete as of this writing. The Display Manager configuration process may evolve in the future to be less specific to the X Window System.

The Display Manager configuration impacts the number of rendering threads created. For a multi-pipe configuration, there will be one rendering thread created per pipe. If more than one display window is opened on a single pipe, all the windows in that pipe will render in the same thread.

Tip

Multi-threaded rendering can be configured with a single graphics pipe. This can be useful in debugging some multi-pipe rendering problems when only one pipe is available. To set this up, configure the Display Manager as though it were to be used on multi-pipe hardware, but set all the X11 display strings to the same value (usually “-1”). Then, configure two or more display windows with each referring to a different pipe (see the section called “Display Windows” for more about this aspect). When VR Juggler is run, it will create a separate thread for each pipe just as it would with a true multi-pipe configuration.

Users

In VR Juggler, characteristics about users are configurable. Most notably, this includes the separation between the user's eyes, which is also called the interocular distance. A configuration element for a user names the position device proxy for the user's head as well. At least one user must be defined per configuration because, as we will see later, the viewport(s) contained within a display window must refer to the user. Multiple users can be defined to handle multiple simultaneous tracked users, but we will not describe that aspect of configuration here because the configuration of display windows and input devices generalizes well to such a case. The complexity lies in writing a VR Juggler application capable of handling multiple simultaneous users.

Display Windows

As their name implies, display windows are used for rendering graphics. In VR Juggler, all display windows are capable of displaying OpenGL graphics, and internally, they make use of the platform-specific API for opening and managing OpenGL-aware windows. The platform-specific details are hidden behind the abstract concept of a display window, thus making the configuration process the same for all platforms. In this section, we will review the basic configurable properties of display windows. The config element for display windows contains several nested config elements, and each of those will be discussed in subsequent sections.

origin

This property defines the (X,Y) coordinate for the origin of the window. The (0,0) coordinate for the whole display is the lower left-hand corner of the screen, and display windows are positioned relative to that point. Furthermore, the lower left-hand corner of the window is the point that will be placed at the value specified by this property. The default settings for the two values are 0 and 0.

size

The “size” property defines the width and the height of the window. The default value for the width is 200; the default height is 200.

pipe

This property is an index into the zero-based list of X11 displays defined in the Display System config element. The display index chosen will be the display on which the window is opened. For a full description of configuring X11 displays, see the section called “The Display Manager”. The default pipe setting is 0.

in stereo

This property indicates where the display window should be opened with active stereo rendering capabilities enabled. If the contained viewport(s) will be using a stereo view, this boolean property must have its value set to true in order for active stereo to work correctly. If it is not set correctly, no sync signal will be generated by the hardware for communicating with shutter glasses.

active

This boolean property defines whether this display window should be used or not. Having such a property allows easy enabling and disabling of windows in configurations without physically adding and removing the config elements. This can be helpful for debugging or for quickly switching between different display configurations.

The OpenGL Frame Buffer

Each display window has a unique OpenGL frame buffer configuration. The nested config element has a direct correspondence to the way that the platform-specific OpenGL window API works, so familiarity with WGL or GLX is helpful when understanding what values to use for the frame buffer settings. Users must at least understand what is meant by “color depth” in order to configure the frame buffer correctly. Those who do not should leave all values at the default setting.

Note

The frame buffer configuration is defined as a nested config element to allow for future extensions where non-OpenGL windows could be supported. In that event, a different nested config element type would be used to configure the frame buffer. VRJConfig will facilitate such specializations if and when VR Juggler reaches that point.

Configuration of the frame buffer requires very little physical effort, but it can require some extra mental effort to get it right. The property semantics are rather unique due to the close correlation to the way that WGL and GLX work. The color depth settings and the depth buffer setting use a convention that is based on a minimum requirement scheme as opposed to a preferred setting scheme. For example, if the red channel size is set to 1 bit, then the windowing system is told to request an OpenGL visual with the highest possible number of bits for red that is greater than or equal to 1. Thus, the windowing system will be able choose a visual with a red channel size between 1 and 8, and it will choose the visual with the highest value. If the red channel size were set to 8 bits, the windowing system could only choose a visual with 8 bits for red. If no such visual were available, no window could be opened. If the red channel size is set to 0, then a visual with the smallest available bit size would be chosen. This convention is used for all the bit size settings.

visual id

Using this property, a specific GLX or WGL visual ID can be chosen for the display. All remaining property value settings will be ignored. The value entered for this property can be determined using the command glxinfo when using the X Window System or wglinfo when using Microsoft Windows®. If -1 is entered, this property value will be ignored. The default value is -1.

Important

The value given for this property must be entered in base 10, but glxinfo and wglinfo name visual IDs using base 16 (hexadecimal notation). Hence, the desired ID as printed by these commands must be converted to base 10 when editing the property using the VRJConfig Configuration Editor. If instead the display window custom editor (found in the VRJConfig Control Panel) is used, the value can be entered as printed by glxinfo or wglinfo. The conversion to base 10 is performed automatically by the custom editor.

red channel size

This property specifies the minimum number of bits per pixel to use for the red channel. The interpretation of this value by WGL or GLX is described above. The default value is 1.

green channel size

This property specifies the minimum number of bits per pixel to use for the green channel. The interpretation of this value by WGL or GLX is described above. The default value is 1.

blue channel size

This property specifies the minimum number of bits per pixel to use for the blue channel. The interpretation of this value by WGL or GLX is described above. The default value is 1.

alpha channel size

This property specifies the minimum number of bits per pixel to use for the alpha channel. The interpretation of this value by WGL or GLX is described above. The default value is 1.

depth buffer size

This property specifies the minimum number of bits to use for the depth buffer. The interpretation of this value by WGL or GLX is described above. The default value is 1.

Caution

Depending on the available graphics hardware, the maximum number of bits available for the depth buffer varies. Make sure to choose a value that will work for the hardware associated with this display window.

multisampling/full-screen anti-aliasing

Important

This property does not exist in versions of VR Juggler after April 9, 2007 (2.0.3-2 and beyond).

This boolean property indicates whether multisampling, previously referred to as full-screen anti-aliasing (FSAA), should be enabled for this display window. Not all hardware supports multisampling, and if the request to enable it is denied by the windowing API, it will be disabled for the window. That is, if multisampling is configured but not available, it will not prevent the display window from opening.

number of sample buffers

Important

This property does not exist in versions of VR Juggler before April 9, 2007 (those older than 2.0.3-2).

Versions of VR juggler prior to 2.0.3-2 (marked April 9, 2007) could only enable or disable multisampling. The number of sample buffers used for multisampling was hard coded to one. In 2.0.3-2 and beyond, the number of multisample buffers can be configured through this property. The default value is 0, which indicates that multisampling should not be used. By setting this property to a value of 1 or higher, multisampling will be requested for the OpenGL visual. Not all hardware supports multisampling, however. If the request to enable it is denied by the windowing API, the number of sample buffers and samples per buffer will be reduced until a valid OpenGL visual is obtained. If multisampling is not available at all, it will be disabled for the window. That is, if multisampling is configured but not available, it will not prevent the display window from opening.

number of samples per buffer

Important

This property does not exist in versions of VR Juggler before April 9, 2007 (those older than 2.0.3-2).

Versions of VR juggler prior to 2.0.3-2 (marked April 9, 2007) could only enable or disable multisampling. The number of samples per buffer used for multisampling was hard coded to one. In 2.0.3-2 and beyond, the number of samples per buffer can be configured through this property. The default value is 0, and this property is only used if the number of sample buffers is greater than 0 (see above). Not all hardware supports multisampling, however. If the request to enable it is denied by the windowing API, the number of sample buffers and samples per buffer will be reduced until a valid OpenGL visual is obtained. If multisampling is not available at all, it will be disabled for the window. That is, if multisampling is configured but not available, it will not prevent the display window from opening.

Graphics Window Input

In VR Juggler 1.0, display windows could not receive input from the keyboard and mouse. Separate windows (called “keyboard windows” in VR Juggler 1.0 terminology) had to be used for this purpose. There were very good reasons for making such a decision in the early stages of VR Juggler development, but in the long run, it proved to be a rather serious usability issue. With VR Juggler 1.1 and 2.0, it is possible to provide keyboard and mouse input directly into graphics windows by configuring them to feed keyboard and mouse events to keyboard/mouse input handlers. This concept was introduced earlier in the section called “Keyboard/Mouse Input Handlers”. By default, display windows do not feed events to keyboard/mouse input handlers. There are four properties of the display window configuration element that set up graphics window input. They are described below.

keyboard/mouse input handler name

This property points to another config element of type keyboard_mouse_device. The value is the configured name of the keyboard/mouse input handler to which events will be fed. Setting this property to a non-empty value is the crux of setting up a graphics window as an event source.

It is possible for multiple display windows and input windows to feed events into a single keyboard/mouse input handler. Through this capability, multiple display windows can be opened, all of which feed the same keyboard/mouse input handler. This can be useful for configurations where it would otherwise be necessary for users to know which specific window will accept keyboard and mouse input.

One useful configuration could be allowing users to exit an application by pressing the ESC key on any keyboard of a multi-keyboard, multi-pipe shared memory computer. Such a configuration would avoid the need for users to log in to a specific console to be able to launch and (cleanly) exit a VR Juggler application.

Caution

With such a configuration, any user at any console of the multi-keyboard, multi-pipe machine would be able to exit the application. This could certainly be undesirable under a variety of circumstances. An alternative approach would be to open a single input window on the pipe where the user logged in. This can be achieved by pointing the input window to a display number in the Display Manager X11 pipe list whose pipe number is -1. (Refer back to the section called “The Display Manager” for more information on such a configuration.) With this configuration, it may be necessary to send the input window to the back of the window ordering so that it does not obscure the display window, so it is not perfect either.

lock key

The “lock key” property defines a key that, when pressed, causes the mouse pointer to be locked to the center of the window. Such a capability is useful when it is necessary for the mouse to remain within the borders of the window at all times. The lock key also unlocks the mouse pointer when it is in the locked state. The default value is KEY_NONE which indicates that there is no key that toggles mouse pointer locking.

start locked

Related to the lock key, the “start locked” property indicates where the mouse pointer should be locked to the center of the window as soon as it opens. This setting defaults to false.

sleep time

Each display window object handles events from the windowing system in its own thread. Depending on the nature of the windowing system, the event handling loop may never block on its own. To prevent the display window thread from starving all the other threads, this property sets a sleep time (in milliseconds) for the input window thread. Adjustment of this property may be necessary to get optimal behavior on a given computer. The default setting causes the display window sample loop to sleep 75 milliseconds between each event handling pass.

Viewports

Users of VR Juggler 1.0 will remember that there were two types of displays that could be configured: surface displays and simulator displays. With the introduction of support for multiple viewports, the display handling was refactored so that all display information became captured in a single display type, the display window. The differences between simulator displays and surface displays are now contained in simulator viewports and surface viewports. In this section, we explain how to configure both types of viewport, and we describe how to combine multiple viewports within a single display window.

Before examining the specifics of the two viewport types, we begin by reviewing configuration properties common to both types. We will postpone the discussion of properties related to viewport size and position until the section called “Multiple Viewports in a Single Window”. This leaves us with two properties to consider, and they are described below:

view

The “view” property defines which eye will be rendered by the Draw Manager's rendering thread for the containing display window. There are three possible values allowed: Left Eye, Right Eye, and Stereo. If the third is chosen, the views for the left and right eyes together will be rendered. The default setting is to render the left eye alone.

user

This property points to a config element defining a single VR Juggler user, as described earlier in the section called “Users”. As mentioned, there must be at least one user defined per configuration.

Simulator Viewports

Simulator viewports are used for rendering the VR Juggler immersive system simulator interface. The default simulator interface has three components: a head, a wand, and a detached, movable camera. An axis representing the origin of the physical world is also rendered. Input into the simulator is configured as described earlier in the section called “Simulator Devices”. The viewport itself is configured easily with just a few settings. The first such property is the vertical field of view for the viewport. This property accepts real-numbered (float-point) values representing the degrees of the field of view. The default setting is 80.0 degrees.

The second property that is unique to simulator viewport configuration elements is the simulator plug-in. The type of this property is a nested configuration element. Since VR Juggler 2.0 Alpha 2, the simulator interface has been defined using a plug-in architecture. VR Juggler comes with two default simulator plug-ins: one for the OpenGL Draw Manager, and one for the OpenGL Performer Draw Manager. A full description of this architecture is beyond the scope of this document, but the default simulator plug-ins must be configured in order to be used. The following lists the properties for the default simulator plug-in configuration element:

camera position

This property points at a position device proxy config element that can move the detached camera around in the scene. Any position device proxy can be used.

wand position

This property points at a position device proxy config element that can move the wand around in the scene. Any position device proxy can be used.

draw projections

This boolean property indicates whether projections for surface viewports should be rendered within the simulator interface. When there are surface viewports included with the overall configuration, the default simulator plug-in can display where those surfaces exist relative to the origin of the physical world. The projections are rendered as translucent planes. Rendering these surfaces is a useful debugging technique, both for application development and for display configuration in general. The default setting for this property value is true.

surface color

This property has three real-numbered values that provide the red, green, and blue settings for the color of the rendered projection surfaces.

head model

This names the model to be loaded by the simulator plug-in used by the OpenGL Performer Draw Manager for rendering the head. It has no effect on the simulator plug-in used by the OpenGL Draw Manager where the head is rendered in code rather than by loading a model. The default value for this property is ${VJ_BASE_DIR}/share/vrjuggler/data/models/head.flt, a model that comes with VR Juggler.

wand model

This names the model to be loaded by the simulator plug-in used by the OpenGL Performer Draw Manager for rendering the wand. It has no effect on the simulator plug-in used by the OpenGL Draw Manager where the wand is rendered in code rather than by loading a model. The default value for this property is ${VJ_BASE_DIR}/share/vrjuggler/data/models/wand.flt, a model that comes with VR Juggler.

Since any simulator plug-in can be configured for any simulator viewport, there are many different possibilities for how those plug-ins would be configured. Specific configuration documentation for a given simulator plug-in should be found accompanying the plug-in. The above only describes the default simulator plug-in that comes with VR Juggler.

Surface Viewports

The second type of viewport is a surface viewport. These are used for projection surfaces such as the walls of a CAVE, the surface of an immersive desk, or the eyes of an HMD. In these viewports, the user's eyes and the camera are permanently attached, and as such, the rendered view is for the perspective of the tracked user. The manner by which the view is calculated depends on one key factor: whether the surface is at a fixed point or if it can move. Those surfaces that are in fixed positions are typically CAVE walls (CAVE floors, certainly), and those that can move have a tracker associated with them in some way. For example, the eyes of an HMD will move wherever the user's head moves, or the viewing surface of an immersive desk may be capable of rotating about a pivot point. Any of these scenarios is fully supported by VR Juggler surface viewports. The process of configuring any of these immersive displays is essentially the same. The only way in which they vary is whether a tracker is involved in computing the user's viewpoint, and this will only be the case for movable display surfaces. The configuration properties of surface viewports are thus the following:

corners

The four corners of the projection surface. The surface must be rectangular in shape, but it may be at any orientation. The settings for the corners represent the actual position of the physical surface's corners, and the units for the corners are always entered in meters. The origin point for the corners takes on a different meaning depending on whether the surface is fixed or movable, however. For a fixed-position projection surface, the origin will be the origin set by the tracker configuration. If there is no tracker, then choose an origin and set the corners relative to it. For a movable projection surface, the origin will be the position of the tracker sensor that is used to provide the viewpoint information.

is tracked

The setting for this boolean property indicates whether the surface is fixed in place (false) or movable (true). The default value is false.

Caution

Do not be confused by the notions of a tracked user and a tracked projection surface. The two are not necessarily related. For example, a PowerWall™ could have a tracked user, but the projection surface itself is not tracked. It is affixed to the wall and cannot move. Hence, it is not a tracked surface. The eyes of an HMD, on the other hand, are tracked because they move relative to the user's head.

tracker proxy

If the surface viewport is configured to be tracked, then a position device proxy must be referenced for the tracker sensor that will provide the viewing information. The proxy to choose (and hence the sensor from which data will be read) depend on the display itself. For an HMD, the proxy for the user's head would be the referenced proxy.

Multiple Viewports in a Single Window

The nature of viewports is such that multiple viewports can be contained within a single window. VR Juggler offers this functionality by providing common settings for both viewport types. These settings specify the positioning and the dimensions of the viewport within the boundaries of the display window. As such, fractional values are used rather than whole number values. More detail on these two properties is provided below:

origin

This property sets the (X,Y) position of the viewport within the display window. Just as with the origin of the window itself, the (0,0) position is the lower left-hand corner of the display window. The values for the X and Y coordinates must be specified as floating-point values within the range [0.0,1.0). Consider the values set as being a percentage of the overall window dimensions. For example, a viewport positioned at (0.5,0.5) would place it at the midpoint of both axes. The default position is (0.0,0.0).

size

This property sets the dimensions of the viewport relative to the display window size. The width and height values are fractional settings and must be in the range [0.0,1.0]. For example, a viewport with a width value of 1.0 and a height value of 0.5 would occupy the full width of the display window but only half of the height. The default width is 1.0, and the default height is 1.0.

With the capability in place to define viewports that occupy only portions of the overall display window, it is possible to mix viewport types within a single display window. While the value of this feature may be debatable, the flexibility exists nonetheless.

Chapter 4. Configuring a Cluster

Configuring VR Juggler in general means putting together all the knowledge from the previous chapters. Configuring VR Juggler to run on a cluster is no exception, though there is additional information needed for a cluster configuration that is not used for a single-machine configuration. All cluster configurations have two required pieces: one or more cluster nodes and a single Cluster Manager. There are optional plug-ins that can be loaded by the Cluster Manager, and some of these require additional configuration. In this chapter, we will explain each of these configuration aspects, taking full advantage of the knowledge garnered from previous chapters.

It is important for readers to understand that we will not explain the concepts or principles that provide the foundation for clustering support in VR Juggler. We are assuming that readers already understand what is meant by a graphics cluster.

Cluster Nodes

A powerful feature of the clustering support in VR Juggler is that a single configuration is used for every node in the cluster. This reduces the maintenance overhead by allowing the configuration to be centralized. Furthermore, it reduces the knowledge burden on the user because s/he does not have to worry about which configuration to load on any given machine. All machines load all the same configuration files.

To provide this feature, the cluster configuration makes use of what are called “cluster node config elements” (type cluster_node). They capture aspects of the hardware and software that are unique to each node in the cluster, and only the node identified in the config element will handle the information intended for it. Together, all the cluster node config elements make up the (conceptual) cluster network.

The cluster_node config element type makes use of nested (embedded) config elements to allow reuse of existing element types related to display configuration. With what we have seen in Chapter 3, Configuring Displays, we can see that there will be a lot of nesting of configuration information in a node configuration. Indeed, the deepest nesting of config elements in VR Juggler at the time of this writing is with per-node display windows in a cluster. Therefore, it is very important to understand what was presented in Chapter 3, Configuring Displays and to understand the hierarchical nature of VR Juggler configurations in general. This level of understanding will be vital in conceptualizing and rationalizing how VR Juggler will be configured to run on a cluster.

With that, we now dive into the properties that must be set for each node of a cluster where VR Juggler applications will be run:

display system

This property sets up the graphics pipe information, just as was presented in Chapter 3, Configuring Displays. There must be exactly one display system configuration per node, even if display windows will not be opened.

display windows

This property lists zero or more display windows to be opened on the local node. This is where each rendering node in the cluster defines its window(s). The windows themselves are configured exactly as described in Chapter 3, Configuring Displays.

Note

In VR Juggler 2.0 pre-releases up to and including Alpha 4, it is not possible to configure a display window as an event source in a cluster configuration. Such a configuration results in a circular dependency within the VR Juggler cluster configuration handling. This problem is resolved for releases after 2.0 Alpha 4.

listen port

This property identifies the port on which the cluster node will listen for incoming connections from the other nodes in the cluster. No other application can be actively using the port chosen for use by VR Juggler, and it is therefore important to choose wisely. On most operating systems, port numbers below 1024 are not allowed for user-level applications. In general, it is best to pick a port in the range 10000–65536. Consult the operating system documentation for more details on valid port numbers for user-level applications.

host name

This property identifies the node of the cluster. The value must be either a valid host name of the node. When a VR Juggler application is run, the configuration system will determine which cluster node is supposed to load the cluster node config element based on this property. It will match the host name based on the network configuration of the node. If there is a match, then that node will handle the configuration element. Otherwise, it will be ignored.

Caution

The most common source of errors with VR Juggler cluster configurations relates to node host names. Matching the host name of a given node with the information in the VR Juggler configuration is the linchpin to the whole process, and match failures will result in broken configurations.

Cluster Manager

Once the configuration information is defined for each of the cluster nodes, we can configure the Cluster Manager. The config element for the Cluster Manager (type cluster_manager) will reference each of the node configurations, so they have to be done first.

Configuring the Cluster Manager is very straightforward. First, any cluster plug-ins that will be needed for the cluster configuration should be identified. The cluster plug-ins are described in the next section. Then, the list of cluster nodes must be built up using pointers to the cluster node config elements. The properties of the Cluster Manager configuration are explained in more detail below:

plug-in path

This is the exact same concept as the driver search path used by the Input Manager (presented in the section called “Driver Search Path”). This path information will be used when loading cluster plug-ins at run time.

plug-in

This property can have zero or more values with each value providing the abstract name of a cluster plug-in to load. The exact names of the plug-ins are provided in the next section. At this point, however, it is important to understand that the plug-ins (DLLs) are identified using a platform-agnostic naming convention, just as is done with the device driver plug-ins for the Input Manager (described in the section called “Driver DLL Name”). The platform-agnostic name basically boils down to removing the file extension from the DLL name. This aids with portability of configuration files and (we hope) reduces the mental overhead required to configure the Cluster Manager on different operating systems where conventions will almost certainly vary.

cluster node

This property lists all the nodes of the cluster, regardless of whether they are rendering nodes, input nodes, or both. The values are pointers to the cluster node config elements. The ordering of the node identifiers is not important here, but every node must be listed for a proper configuration.

Cluster Plug-Ins

Cluster plug-ins extend the functionality of the base-level cluster code with specific, optional functionality. For example, there are plug-ins that implement distributed swap locking at the software level, but some graphics clusters will have support for hardware-level swap lock. In that case, there is no need to load a swap lock cluster plug-in.

Remote Input Manager

In this section, we describe the Remote Input Manager plug-in. This plug-in has the following characteristics:

  • Plug-in name: RIMPlugin

  • Required for sharing data from input devices among all the cluster nodes.

  • Has no specific configuration element.

One way of enabling clustering for visualization systems is to share the information from the various input devices. This is based on an assumption that visualization applications are largely (or entirely) interactive and base most (or all) graphical presentation on input from the user. For example, in the case of an immersive visualization system where the user's head position is tracked, the perspective into the scene will be calculated entirely from information from the head tracker. By sharing that information among all the nodes in the cluster, a the individual pieces of the overall view can be computed on the appropriate rendering nodes.

In a VR Juggler cluster configuration, this capability is realized through the Remote Input Manager plug-in. Without this plug-in, input device data is only available on the node where the device is physically connected. If the applications are expecting to get input from devices, then this plug-in must be loaded. This plug-in does not have a configuration element, so simply including it with the list of plug-ins for the Cluster Manager to load is sufficient to enable its use.

Start Barrier

In this section, we describe the Start Barrier plug-in. This plug-in has the following characteristics:

  • Plug-in name: StartBarrierPlugin

  • Required when the Remote Input Manager plug-in is used to ensure that all nodes start with the same input data.

  • Must identify the start barrier “master” and the network port on which it listens for incoming connections from the other cluster nodes.

When the Remote Input Manager plug-in is loaded, it is necessary to load the start barrier plug-in, too. The start barrier plug-in ensures that all nodes in the cluster begin their execution on the same frame. Essentially, this means that one node (the “master” node) keeps the cluster nodes from executing their respective frame loops until all the nodes identified in the Cluster Manager configuration are connected and waiting. This is critical for configurations where input device sharing is being used.

Configuring the start barrier is simple. First, a cluster node must be chosen to act as the start barrier master. This is the node to which all the other nodes will connect, and it will cause all nodes (including itself) to block until execution can begin. A port number must be given where the master node can listen for incoming connections. The port number choice will follow the same criteria as presented in the section called “Cluster Nodes”, but a different port number must be chosen than the one used for general communication by the cluster node.

Application Data Manager

In this section, we describe the Application Data Manager plug-in. This plug-in has the following characteristics:

  • Plug-in name: ApplicationDataManager

  • Required when applications have custom data structures that will be shared among the cluster nodes.

Another way of synchronizing data among the nodes of a graphics cluster is to allow applications to define their own data structures for sharing. In this scenario, there is one node (the master or data-local node) that can write to the shared objects, and all the other nodes (the slaves) can read from the shared objects. Each frame, the Application Data Manager on the data-local node will serialize all registered shared objects and distributed them to the other nodes of the cluster. With VR Juggler, this technique can be used in conjunction with, or instead of, the Remote Input Manager.

The Application Data Manager itself requires no configuration, but applications making use of the Application Data Manager features may require additional configuration information. Depending upon how applications are written, they may identify the master node for any given shared data structure through the use of the so-called “application data” config element (type application_data). Ultimately, it will be the responsibility of the application programmer to deal with this aspect of the configuration, but we provide an explanation here to ensure that all readers will understand this case. There are two properties for this element type, and they are explained in detail below:

globally unique identifier (GUID)

Every data type that will be shared by the VR Juggler clustering subsystem must be registered at run time. Globally unique identifiers (GUIDs, also known as “universally unique identifiers” or UUIDs) are 128-bit values that are guaranteed to be statistically unique. They provide a means for giving every user-defined data structure a unique identifier. VR Juggler application programmers will set the GUID for their data structures in the application object code using a string value. This same string value must be copied into the GUID property of the config element corresponding to that shared data structure.

responsible host (host name)

The data-local cluster node is identified using this property. The value type is a string that will be used to match against the host name of each cluster node. When the value of this property matches the host name of a cluster node, that cluster node will be the data-local node for the shared data structures. This process is the same as matching the cluster node config elements with the individual cluster nodes, presented earlier in the section called “Cluster Nodes”.

Using the application data config element allows VR Juggler application programmers to make their applications more portable. Without this feature, the data-local host name would have to be hard-coded into the application, thus tying the application to a specific cluster. Further explanation of this topic is beyond the scope of this document.

TCP Swap Lock

In this section, we describe the TCP Swap Lock plug-in. This plug-in has the following characteristics:

  • Plug-in name: SwapLockTCPPlugin

  • Required when buffer swap locking is required but no hardware-level swap locking is available.

  • Must identify the swap lock “master” and the network port on which it listens for incoming connections from the other cluster nodes.

Synchronizing multiple displays is one of the biggest challenges in graphics clusters. Because we are using different machines that may have different graphics cards, generating the graphics could take a different amount of time on each node. Modern graphics hardware uses a technique called double-buffering that displays the current frame from one buffer (the “front buffer”) while rendering the next frame another (the “back buffer”). Once the hardware has finished rendering to the back buffer, it swaps contents of the two buffers. We encounter a synchronization issue when the cluster nodes swap the buffers at different times. The result is a tearing effect that causes the display to appear unsynchronized very briefly. We can combat this issue by sending a signal among all machines telling them when they should swap their buffers. This signal locks the buffer swapping so that it is synchronized, and we refer to this as “swap locking.” This communication needs to have a very low latency to reduce the tearing effect—usually on the order of 10–80 microseconds.

Ideally, swap locking would be implemented at the graphics hardware level to ensure the lowest possible latency and least amount of overhead. When it is not available, however, we must find an alternative. The cluster support in VR Juggler includes software-level swap locking capabilities. One such implementation is the TCP swap lock plug-in.

The TCP swap lock plug-in performs the locking operation by using the network already in place for communication among the cluster nodes. The latency for this implementation is usually on the order of 100 microseconds, so it is slightly out of the ideal range. However, it is easy to use and requires no custom hardware.

Configuring the TCP swap lock plug-in is similar to configuring the start barrier plug-in (see the section called “Start Barrier”). A synchronization server (or master node) must be chosen, and a port must be set on which the server will listen for incoming connections from the other cluster nodes. Again, the port number choice will follow the same criteria as presented in the section called “Cluster Nodes”, and a different port number must be chosen than the one used for any other cluster communication.

Parallel Port (Wired) Swap Lock

In this section, we describe the Parallel Port Swap Lock plug-in. This plug-in has the following characteristics:

  • Plug-in name: SwapLockWiredPlugin

  • Required when buffer swap locking is required but no hardware-level swap locking is available.

  • Must identify the swap lock “master” and the slave nodes that will be synchronized.

  • Requires special hardware (see the SoftGenLock 1.0 documentation for links and detailed explanations).

  • Only available on Linux—it requires a custom kernel module.

Another software implementation of swap locking is the parallel port (or “wired”) swap lock plug-in. This plug-in is used in conjunction with special hardware that performs its communication via the parallel ports of the cluster nodes. This implies that the cluster nodes must all have a parallel port, which is typically found only on IBM-compatible computers. The actual communication is controlled by a custom piece of hardware that simply combines the signals from all the nodes and waits until the signals are all high or all low. At that point, another signal is sent that indicates that the graphics hardware can swap the buffers. This communication can be done on the order of 10 microseconds, which is well within the optimal range identified above.

Note

As of this writing, the use of this plug-in and the associated custom hardware is limited to the Linux operating system. A special Linux kernel module is required that allows the cluster plug-in to communicate directly with the parallel port without going through the overhead of making a system call into the OS kernel.

Configuring the wired swap lock plug-in is different than the other parts of the cluster configuration, though it makes use of the previously configured cluster nodes. First, a synchronization master must be chosen. Then, up to six slaves can be included or excluded from the synchronization process. Each of the slave node properties has a Boolean value that must be set to either true (will be synchronized) or false (will not be synchronized).

Input Device Sharing

Through the Remote Input Manager, all input devices supported by Gadgeteer are capable of being shared across a graphics cluster. This allows all the nodes of a cluster to read the data from an input device (for example, a positional tracker) that is attached physically to one machine. All config elements for input devices have a property called “Host Node” (or “device host”) that refers to a cluster node or to nothing. When it refers to nothing, that is the non-cluster case where everything is being executed on the same machine. When the property value refers to a cluster node, it indicates that the device is physically connected to the named cluster node. When configuring a cluster, all input devices must be configured so that it is clear which device is associated with which node in the cluster.

Caution

The “Host Node” property uses a config element pointer to refer to the cluster node acting as the data-local host. Its value must be the name of a valid configuration element of type cluster_node. Avoid trying to enter this value by hand; instead, use VRJConfig to get the list of available node names.

Cluster Configuration Tips

In this final section, we present some tips for configuring VR Juggler to run on a cluster based on our experience. These are not required steps; they are simply recommendations that can make cluster configurations simpler and more robust.

Naming Cluster Node Config Elements

When naming the node configuration (introduced in the section called “Cluster Nodes”), use a meaningful convention. For example, we recommend something of the form “Node(mach0)” for a machine named mach0. This is just a recommendation. Readers are free to devise their own conventions. We simply encourage consistency and meaningful config element names.

Choosing Master Nodes

Depending on the cluster plug-ins loaded, it may be necessary to choose master or server nodes (see the section called “Start Barrier”, the section called “Application Data Manager”, the section called “TCP Swap Lock”, and the section called “Parallel Port (Wired) Swap Lock”). In general, it is best to choose a single node in the cluster to act as the master for everything. This reduces some mental overhead, and it avoids complications that can arise from circular dependencies of nodes depending on each other and being unable to start their execution as a result.

Chapter 5. Remote Run-Time Reconfiguration Using VRJConfig

Among VR software development frameworks, VR Juggler has the unique capability of being reconfigured on the fly without requiring running applications to be restarted. This feature is implemented through the combination of the flexible configuration infrastructure and VRJConfig. Using CORBA, VRJConfig can communicate with a running instance of VR Juggler and send it configuration additions, modifications, and removals.

Preparing VR Juggler for Remote Run-Time Reconfiguration

Before we can communicate with a running VR Juggler instance, we have to be sure that the Configuration Manager has been set up to allow remote communication. The first step is to start up a CORBA Naming Service. The full details of CORBA are beyond the scope of this document, but we will explain the relevant parts here. Most CORBA implementations come with a Naming Service server application, and since omniORB is the primary C++ CORBA implementation used by the Juggler Suite, we will talk about it. The Naming Service application that comes with omniORB is called omniNames. The host computer where it is running and the port number on which it is listening for incoming connections (the default is 2809) are important pieces of information that we will need later.

With a Naming Service running, the next step is to create a configuration element for the CORBA remote run-time reconfiguration plug-in. This, of course, can be done using VRJConfig. This configuration element has three properties, each of which is described below.

Naming Service host

The host name or IP address of the machine where the Naming Service is running. The default value is localhost.

Naming Service port number

The port on which the Naming Service is listening for incoming connections from clients. The default value is 2809, the standard port for the CORBA Naming Service protocol.

IIOP version

The version number of the Internet Inter-ORB Protocol (IIOP) supported by the Naming Service. In the case of omniORB 3.0, only version 1.0 is supported. omniORB 4.0 and newer support versions 1.0 and 1.2. The default is 1.0.

With a configuration element set up for configuring the CORBA remote run-time reconfiguration plug-in, a VR Juggler application can be run. If all goes well, the plug-in will be loaded automatically and configured successfully. If there are problems loading the plug-in, configuring it, or setting up its communication channel with the Naming Service, an error message will be printed to the console. If the plug-in is not set up correctly, remote run-time reconfiguration cannot occur.

Connecting to VR Juggler Using VRJConfig

Once VR Juggler is ready to be reconfigured remotely, taking advantage of remote run-time reconfiguration is easy. There are two steps to get started: connect to a running VR Juggler instance and request its active configuration. To connect to a VR Juggler instance from VRJConfig, select the item named Connect to ORB under the Network menu. A dialog box will open requesting information about a CORBA Naming Service. The values entered into the input fields of the dialog box will be the same as what was entered for the configuration element used to set up the CORBA remote run-time reconfiguration plug-in above. Namely, they are the host name or IP address of the machine where the CORBA Naming Service is running; the port number on which the Naming Service is listening for incoming connections; and the IIOP version number. An extra field exists for naming context information, but it must be left empty.

Once the fields are filled in, click the Connect button. The Tweek Java® GUI, the environment within which VRJConfig executes, will make a connection to the Naming Service and request references to objects known as Tweek Subject Managers[7]. This state is depicted in Figure 5.1, “Subject Manager Lookup Dialog”. Choosing the correct Subject Manager from the list of available options is critical to performing remote run-time reconfiguration on the correct VR Juggler instance. The Subject Manager to choose can be identified using the informational items shown on the right side of the lower half of the dialog box. The Subject Manager being used by the Configuration Manager will always have its “Usage” property set to the value “Config Manager.” The “Hostname” property also gives a hint about which Subject Manager to choose.

Figure 5.1. Subject Manager Lookup Dialog

Subject Manager Lookup Dialog

Once the Subject Manager is chosen, VRJConfig uses that information to set up the communication channel with the remote C++ application. At this time, the remote run-time reconfiguration button in the main VRJConfig toolbar will become active. This button is highlighted in Figure 5.2, “VRJConfig Remote Run-Time Reconfiguration Button”. Clicking it requests the active configuration from the VR Juggler instance to which we are connected. The active configuration will be loaded into a new configuration context just as if a new configuration file had been opened.

Figure 5.2. VRJConfig Remote Run-Time Reconfiguration Button

VRJConfig Remote Run-Time Reconfiguration Button

Editing an active configuration is very similar to editing a normal configuration loaded from disk. Config elements can be added, modified, and removed. To commit changes (i.e., to perform remote run-time reconfiguration of the running VR Juggler instance), click the Save button in the context toolbar. Recall that this toolbar was shown earlier in Figure 1.5, “VRJConfig Configuration Context Toolbar”. For a more complete description of how to use VRJConfig in general, please refer back to the section called “Configuration Editing”.



[7] For more details about Tweek, Subject Managers, and other CORBA features, refer to the Tweek publications and the Tweek documentation.

Chapter 6. Config Definition Editing

In VR Juggler 2.0, the graphical Config Definition Editor is still very rough. Numerous improvements have been made in the VR Juggler 2.0 Beta 3 release, but the Config Definition Editor GUI will require extensive revamping to become truly useful. For that reason, we will provide enough information in this chapter for users to be able to edit config definitions (.jdef files) using a simple text editor.

Regardless of the state of the Config Definition Editor GUI, this chapter is intended for VR Juggler users who are extending VR Juggler with custom configuration information. This comes most frequently in the form of new device drivers since all device drivers must be configured. VR Juggler application objects can be configured using the Juggler configuration system, and this requires the creation of one or more application-specific config definitions. Readers who fall into neither of these categories can safely skip this chapter.

Important

For custom config definitions, remember to set the environment variable $JCCL_DEFINITION_PATH appropriately. This environment variable extends the .jdef search path used by VRJConfig and the JCCL module. Refer to the VR Juggler Getting Started Guide for more information about this environment variable and all others used by VR Juggler.

Introduction to Config Definitions

Until now, we have not given much attention to config definitions. The focus of this document is the configuration of VR Juggler, and that means using the existing config definitions that come with VR Juggler to create config elements. In the section called “Configuration Elements”, we gave a quick introduction to config definitions, primarily to introduce the terminology and to explain the relationship to config elements. As a reminder, here is that quick introduction again:

The specification of property types, the number of allowed values, and other structural aspects of config elements are defined by configuration definitions, or simply “config definitions.” The relationship between config elements and config definitions is quite similar to that of objects and classes in object-oriented languages. A class defines structural and behavioral information, and an object is an instance of a class. At any time, there can be many instances of a single class, each referenced by a different variable. Similarly, a config definition defines structural information, and a config element is an “instance” of the definition. There can be many config elements for a given definition, and each config element is identified by its unique name. Config definitions even support a limited form of multiple inheritance.

That explanation applies most accurately to the concept of a config definition. In more practical terms, config definitions primarily serve to provide the information needed for a graphical editor of config elements to be able to do its job. That job will typically involve validating all given config elements and editing the properties of those config elements. For VR Juggler 2.0, the graphical editor is, of course, VRJConfig. VRJConfig is composed of several pieces: the VRJConfig Configuration Editor, the VRJConfig Control Panel with its custom editors & wizards, the JCCL Editor Beans, and the Config Definition Editor. (Refer back to the section called “Configuration Editing” for more information about VRJConfig and its components that edit config elements.) The components of VRJConfig that edit config elements make heavy use of the config definition for each config element, and it is not possible for VRJConfig or VR Juggler to load a config element without a definition. Hence, config definitions are the lynch pin for the whole Juggler configuration system. In spite of their importance, the majority of VR Juggler users should never have to worry about editing config definitions.

Note

In some places, we will make comparisons with the VR Juggler 1.0 configuration system. When appropriate, we will use VR Juggler 1.0 terminology since that is what applies. For those readers not familiar with VR Juggler 1.0, config elements were called “config chunks” in VR Juggler 1.0, and config definitions were called “chunk descriptions.

Config Definition Features

Config definitions provide a variety of features for describing and editing config elements. It is interesting to note that none of these features existed in VR Juggler 1.0 and have all been added to address limitations of the VR Juggler 1.0 configuration system.

Versioning and Automatic Upgrading

Config definitions are versioned so that instances of them (i.e., config elements) include version information. Furthermore, the config definitions contain code for upgrading config elements when the version changes. Because config elements are described using XML, the natural choice for transforming a config element from one version to another is XSLT. Aside from the fact that XSLT is designed for transforming XML documents, it can be nested within other XML documents. Config definitions take advantage of this capability to embed the config element upgrade code in line with the definition itself.

Inheritance

Many config elements share the same properties, and object-oriented inheritance offers a means to define a property once and reuse it in multiple config definitions. Inheritance also allows for a form of polymorphism with config elements. For example, all config definitions for input devices are derived from the base config definition input_device. The graphical editor can then identify all config elements for input devices. This allows for new points of extension in the configuration code, and it reduces (even eliminates) hard coding within the config definitions and the editor itself.

To illustrate the power of this feature, consider the case of a custom config definition for a positional tracking device. Because of the way that input devices are configured, a positional proxy must be pointed at the config element for the device in order for the device to be accessed by a VR Juggler application object. In VR Juggler 1.0, it was necessary to modify the positional proxy chunk description to add the custom config definition. In VR Juggler 2.0, the config definition for positional proxies defines its device pointer to point to config elements that derive from the config definition type positional_device. The custom config definition for the new tracking device need only derive from positional_device in order for VRJConfig to be able to allow the positional proxy at the device config element.

Categorization

Since the early days of VR Juggler, the need for organizing the config elements within the graphical configuration editor was recognized. In VR Juggler 1.0, categorization was performed using a static file that had to know about all known config chunks. Config chunks that were not listed in that file could not be categorized without modifying the organizing file. In VR Juggler 2.0, config definitions provide their own organizational information, and VRJConfig creates the organizing hierarchy dynamically based on the config definitions it finds at run time. The result is a much more dynamic and extensible means for organizing config elements.

Default Property Values

When creating a new config element, it is often quite tedious to have to fill in every property value, especially when there is little variation among some (or many) of those values. Since version 2.0 of the config definition format, default property values have been supported. VRJConfig uses default values to fill in the property values when a new config element is created. Users then only have to set values for those properties where the default is not the desired setting.

Config Definitions and XML Schema

During the development of VR Juggler 2.0, a switch was made from the custom file formats used by VR Juggler 1.0 to XML. Early on in this process, the Juggler developers re-evaluated the utility of config definitions when technologies such as Document Type Definitions (DTDs) and XML Schema were readily available. Special attention was paid to XML Schema since it has become the most prevalent mechanism for validating the correctness of XML in general. Ultimately, it was agreed that XML Schema is not quite expressive enough for to provide fully featured editing of config elements. The config definition format allows a degree of flexibility not present in XML Schema when it comes to providing extra information to the graphical editors.

XML Schema is used to validate .jconf and .jdef files when they are loaded into VRJConfig. The schemata are named configuration.xsd for .jconf files and definition.xsd for .jdef files. Interested readers can find the schemata for these two file formats in several places:

  • In the Juggler source tree under juggler/modules/jackal/data/configuration.xsd and juggler/modules/jackal/data/definition.xsd.

  • In a Juggler distribution tree under $VJ_BASE_DIR/share/jccl/data/schema/www.vrjuggler.org/jccl/xsd.

  • On the Internet through the URI given at the top of .jconf and .jdef files in the xsi:schemaLocation attribute of the document root.

Config Definition Files

The basic structure of a config definition file is quite simple. A single .jdef file contains exactly one config definition and all its versions. A single definition version has the following children:

  • A flag stating whether this definition type is “abstract” or not. This is used by the graphical editor to determine whether a config element may be instantiated for this definition. Abstract config definitions may not be instantiated as config elements.

  • Help text as character-encoded HTML. This means that HTML tags appear as &lt;tag&gt; rather than as <tag>. (It is possible to nest XHTML within another XML document, but version 3.x of the config definition format does not utilize that capability of XML.)

  • A list of zero or more parent definition names for inheritance.

  • A list of zero or more categories used to place config elements into a hierarchical arrangements.

  • A list of zero or more property definitions. More attention will be given to property definitions later in the section called “Property Definitions”.

  • A block of XSLT code used to transform the previous version (N) to the current version (N+1). This will be empty for the first version of a config definition.

This is illustrated in Example 6.1, “Basic Config Definition File Structure” using simplified pseudo-code. The indentation indicates the hierarchy of the parent/child relationships. In this example, we see that there are two versions of the definition. The XSLT code for updating from version N to version N+1 is associated with version N+1.

Example 6.1. Basic Config Definition File Structure

definition
   definition_version N
      abstract [true/false]
      definition help
      parent(s) [zero or more]
      category(ies) [zero or more]
      property [zero or more]
         property help
         property value(s)
      upgrade_transform [empty]
   definition_version N+1
      abstract [true/false]
      definition help
      parent(s) [zero or more]
      category(ies) [zero or more]
      property [zero or more]
         property help
         property value(s)
      upgrade_transform [XSLT]

An example of an actual config definition file containing multiple versions—including the XSLT for updating from version 1 to version 2—is shown in Example 6.2, “Multi-Version Config Definition Example (simulated_digital_device.jdef)”. While this example looks rather daunting upon first inspection, it is quite simple to understand by approaching it hierarchically. We can see that version 1 of this definition has the simple structure shown in the pseudo-code example. This definition inherits from the config definition type digitial_device and defines two properties of its own: event_window_proxy and key_pair. In version 2, the inheritance is still the same, but one of the property definitions has been renamed[8]. The property event_window_proxy has been renamed to keyboard_mouse_proxy. The XSLT upgrade transform takes care of this property renaming.

Example 6.2. Multi-Version Config Definition Example (simulated_digital_device.jdef)

<?xml version="1.0" encoding="UTF-8"?>
<?org-vrjuggler-jccl-settings definition.version="3.1"?>
<definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.vrjuggler.org/jccl/xsd/3.1/definition"
    name="simulated_digital_device" icon_path=""
    xsi:schemaLocation="http://www.vrjuggler.org/jccl/xsd/3.1/definition http://www.vrjuggler.org/jccl/xsd/3.1/definition.xsd">
   <definition_version version="1" label="Simulated Digital Device">
      <abstract>false</abstract>
      <help>
         A simulated digital device that gets its input from an event
         window.
      </help>
      <parent>digital_device</parent>
      <category>/Devices/Digital</category>
      <property valuetype="configelementpointer" variable="false"
                name="event_window_proxy">
         <help>
            The proxy to the event window to use for user input.
         </help>
         <value label="Event Window Proxy"/>
         <allowed_type>event_window_proxy</allowed_type>
      </property>
      <property valuetype="configelement" variable="true"
                name="key_pair">
         <help>
            The keys used to trigger multiple digital inputs.
         </help>
         <value label="Digital Button Key"/>
         <allowed_type>key_modifier_pair</allowed_type>
      </property>
      <upgrade_transform/>
   </definition_version>
   <definition_version version="2" label="Simulated Digital Device">
      <abstract>false</abstract>
      <help>
         A simulated digital device that gets its input from a
         keyboard/mouse input handler (through a proxy).
      </help>
      <parent>digital_device</parent>
      <category>/Devices/Digital</category>
      <property valuetype="configelementpointer" variable="false"
                name="keyboard_mouse_proxy">
         <help>
            The proxy to the keyboard/mouse input handler to use for
            user input.
         </help>
         <value label="Keyboard/Mouse Proxy"/>
         <allowed_type>keyboard_mouse_proxy</allowed_type>
      </property>
      <property valuetype="configelement" variable="true"
                name="key_pair">
         <help>
            The keys used to trigger multiple digital inputs.
         </help>
         <value label="Digital Button Key"/>
         <allowed_type>key_modifier_pair</allowed_type>
      </property>
      <upgrade_transform>
         <xsl:stylesheet
             xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:jconf="http://www.vrjuggler.org/jccl/xsd/3.0/configuration"
             version="1.0">
            <xsl:output method="xml" version="1.0" encoding="UTF-8"
                        indent="yes"/>
            <xsl:variable name="jconf">http://www.vrjuggler.org/jccl/xsd/3.0/configuration</xsl:variable>

            <xsl:template match="/">
                <xsl:apply-templates/>
            </xsl:template>

            <xsl:template match="jconf:simulated_digital_device">
               <xsl:element namespace="{$jconf}"
                            name="simulated_digital_device">
                  <xsl:attribute name="name">
                     <xsl:value-of select="@name"/>
                  </xsl:attribute>
                  <xsl:attribute name="version">
                     <xsl:text>2</xsl:text>
                  </xsl:attribute>
                  <xsl:element namespace="{$jconf}"
                               name="keyboard_mouse_proxy">
                     <xsl:value-of select="./jconf:event_window_proxy"/>
                  </xsl:element>
                  <xsl:for-each select="./jconf:key_pair">
                     <xsl:copy-of select="."/>
                  </xsl:for-each>
                  <xsl:copy-of select="./jconf:device_host"/>
               </xsl:element>
            </xsl:template>
         </xsl:stylesheet>
      </upgrade_transform>
   </definition_version>
</definition>

Now that we have seen how config definition files handle multiple versions of a given config definition, we will focus on a simpler config definition that has only one version. In Example 6.3, “Simple Config Definition (position_proxy.jdef)”, we see the config definition for config elements that configure position proxies. This config definition demonstrates a wide variety of the capabilities of config definitions. The following subsections will walk us through this config definition piece by piece.

Example 6.3. Simple Config Definition (position_proxy.jdef)

<?xml version="1.0" encoding="UTF-8"?>
<?org-vrjuggler-jccl-settings definition.version="3.1"?>
<definition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.vrjuggler.org/jccl/xsd/3.1/definition"
    name="position_proxy"
    icon_path="jar:file:${VJ_BASE_DIR}/share/vrjuggler/beans/VRJConfig.jar!/org/vrjuggler/vrjconfig/images/position64.png"
    xsi:schemaLocation="http://www.vrjuggler.org/jccl/xsd/3.1/definition http://www.vrjuggler.org/jccl/xsd/3.1/definition.xsd">
   <definition_version version="1" label="Position Proxy">
      <abstract>false</abstract>
      <help>
         Used to access a single positional input source.
      </help>
      <parent>proxy</parent>
      <category>/Proxies</category>
      <property valuetype="configelementpointer"
                variable="false" name="device">
         <help>The device the proxy points to</help>
         <value label="Device"/>
         <allowed_type>positional_device</allowed_type>
      </property>
      <property valuetype="integer" variable="false" name="unit">
         <help>
            The unit in the device this proxy attaches to.
         </help>
         <value label="Unit" defaultvalue="0"/>
      </property>
      <property valuetype="configelement" variable="true"
                name="position_filters">
         <help>
            This is a list of all the filters that are to be
            applied to the positional device data.
         </help>
         <value label="Position Filter"/>
         <allowed_type>position_transform_filter</allowed_type>
      </property>
      <upgrade_transform/>
   </definition_version>
</definition>

File Format Version

The first thing we encounter in every .jdef file (after the XML document description) is the file format version information. This is specified using an XML processing instruction and is not part of the XML Schema for config definition documents, as shown below:

<?org-vrjuggler-jccl-settings definition.version="3.1"?>

The file format version information is used by various parts of the config infrastructure to determine how to handle the input. For example, XSLT documents used to transform between versions of the config definition file format read this instruction to verify that the input is the expected format version. The transformed document then includes a new processing instruction indicating that the document is using the current file format version.

Root Document Attributes

The root node of the config definition document is <definition>, and it has several required attributes. They are as follows:

  • name: The name of the config definition type being described by the contents of the file. This must match the name of the .jdef file, and it must be a valid XML element name.

  • icon_path: A URL providing a path to an image that can be used as an icon instances of this definition or an empty string to indicate that no specific icon is to be associated with the config definition. This is intended to be used by a configuration editor (i.e., VRJConfig), but it is currently unused. Jar (Java® archive) URLs can be used for the icon path.

  • xmlns: The XML namespace for this document. The value is based on the file format version. For version 3.1 of the config definition file format, the value must be “http://www.vrjuggler.org/jccl/xsd/3.1/definition”.

  • xmlns:xsi: The XML namespace declaration for the XML Schema document format.

  • xsi:schemaLocation: The location of the XML Schema used to validate config definition documents as a URI. The value is based on the file format version. For version 3.1 of the config definition file format, the value must be “http://www.vrjuggler.org/jccl/xsd/3.1/definition http://www.vrjuggler.org/jccl/xsd/3.1/definition.xsd”. Note that the XML namespace must be included as part of the XML Schema URI to correlate the config definition document with its schema specification.

Definition Version

To support automatic upgrading of config elements, a single config definition can have multiple versions. The versions are tracked in the .jdef file with one version existing per <definition_version> tag. The actual config definition exists as a child of the <definition_version> tag.

The <definition_version> XML tag has two required attributes:

  1. version: An integer version number that uniquely identifies this version of the config definition.

  2. label: The human-readable name of the config definition. This should be a short name that is very closely related to the name of the config definition type. Generally, a graphical editor will display this identifier rather than the lower level definition type name when identifying the type of a config element.

Config definitions should be sorted in increasing order, though this is not strictly required by the format. This convention is used more for making the .jdef file contents more understandable by people looking through the XML. For information about config element version updating, see the section called “Upgrade Transforms”.

Abstract Config Definitions

With the introduction of support for config definition inheritance in version 3.0 of the config definition file format, there arose the possibility of defining base config definitions to provide common properties. For example, all config definitions for device drivers have input_device as their most base definition type. The config definition for input_device defines the device_host property which is needed for sharing input device data in a cluster configuration. Hence, all input devices inherit the device_host property from input_device.

Creating a config element of type input_device, however, does not make sense. The config element will not be handled by anything in Juggler at run time. Therefore, users should not be able to create input_device config elements using a graphical editor. To ensure that this does not happen, the input_device config element is marked as being abstract through the <abstract> XML tag, as shown in Example 6.4, “Example Abstract Config Definition (input_device.jdef)”. Referring back to our tutorial config definition type (shown in Example 6.3, “Simple Config Definition (position_proxy.jdef)”), we see that that definition is not abstract.

Example 6.4. Example Abstract Config Definition (input_device.jdef)

<definition name="input_device" ...>
   <definition_version version="1"
                       label="Input Device Base Definition">
      <abstract>true</abstract>
      ...
   </definition_version>
</definition>

The <abstract> XML tag is optional. If it is not included in the config definition version, the config definition defaults to not abstract. In general, though, it should be included for the sake of clarity.

Config Definition Help Text

Config definition help text is specified using the <help> XML tag. The text contents of this XML tag are interpreted as HTML by the graphical editor. While XHTML could be nested as a child of the <help> XML tag, this is not currently done by the config definition format. Hence, the HTML tags must be specified using the coded character entities for the < and > characters (&lt; and &gt; respectively). Refer to Example 6.5, “HTML Encoded Within a <help> Tag” for an example of how this is done. See Example 6.6, “Resulting HTML Help String” for the string that would actually be passed on to an HTML renderer after loading the config definition.

Example 6.5. HTML Encoded Within a <help> Tag

<help>
   Interocular distance; the distance between your eyes.
   This value must be in meters.
   (&lt;a href="http://.../config/ch03s02.html"&gt;more ...&lt;/a&gt;)
</help>

Example 6.6. Resulting HTML Help String

Interocular distance; the distance between your eyes.
This value must be in meters.
(<a href="http://.../config/ch03s02.html">more ...</a>)

The preceding examples show the use of hyperlinks within the help text. It is worth noting that VRJConfig makes hyperlinks clickable when displaying the rendered HTML help text. Loading of remote images, however, is not supported. Generally, the HTML help text should be just that: text.

Config Definition Parents

Version 3.0 of the config definition file format introduced support for config definition inheritance. This feature has already been introduced in this chapter. The parent types for a config definition are named using the config definition type. Looking back at our exemplar config definition, we see that a single parent is declared: proxy. A config definition may have zero or more parents.

Caution

Use care when declaring the parents of a config definition. Multiple inheritance introduces the possibility for conflicting property definitions, and the configuration infrastructure does not currently provide any means for detecting or handling this such a situation. Ultimately, the Config Definition Editor should provide a means to manage config definition inheritance robustly.

Categories

The categories of a config definition are used by graphical Juggler configuration editors. The categories provide a means for an editor to organize config definitions and config elements hierarchically. A category is declared using the <category> XML tag. A config definition may declare zero or more categories, and the categories themselves are free-from strings. The category hierarchy is defined by separating the path hierarchy using the slash (/) character. All categories must begin with a slash character indicating the root of the hierarchy. Examples of categories used by existing Juggler config definitions are /Proxies, /Devices/Simulator, and /Cluster.

Property Definitions

Property definitions specify the properties that make up a config element. A config definition will have zero or more property definitions[9]. A property definition specifies the name of the property, the type of the value(s) of the property, the number of values, and default values. We will address all of these aspects in this section.

Property Definition Attributes

Property definitions are demarcated by the <property> XML tag. This tag has three required attributes:

  1. name: The name of the property itself which is used to mark up values within the config element. As such, the name must be a valid XML element name, and it must be unique within the config definition.

  2. variable: A Boolean flag identifying whether this property allows a variable number of values as opposed to a fix number. In version 3.0 and 3.1 of the config definition file format, a variable number of values means that zero or more values for the property are allowed. The value of the attribute must be either true or false.

  3. valuetype: The type interpretation of this property. The semantic interpretation of the property type is up to the programmer making use of the config element defined by the definition containing this property. However, VRJConfig will use this information to restrict what values may be entered for this property to ensure that the semantic interpretation will be correct as long as the programmer makes use of the property correctly. There are six allowed values for this attribute (specified as XML strings). They are boolean, configelement, configelementpointer, float, integer, and string.

Property Definition Help Text

Help text for property definitions follows exactly the same rules, conventions, and restrictions as that of help text for config definitions. Refer back to the section called “Config Definition Help Text” for more information.

Property Value Definitions

Property value definitions provide information to the graphical editor about how to edit the value(s) of a property. They give a string label to be used for associating the property value with a meaningful concept, and they may offer a default value to reduce the amount of input required by the user. Property value definitions are described using the <value> XML tag, and each property definition must have one or more property value definitions.

The rules for property value definitions are somewhat tricky, however. First, there are two attributes for the <value> XML tag:

  1. label: This required attribute is the high-level description of how the property value will be interpreted. VRJConfig will display the value label next to the value editor to help the user understand what to enter. In general, each property value definition should have a distinct label to indicate to the user of the graphical editor how the value will be interpreted.

  2. defaultvalue: This optional attribute gives the default setting for this property value definition. The value type should match the type declared for the property. An empty value is allowed as the default. Note, however, that if the property type is an embedded config element (the valuetype attribute for the <property> tag is set to configelement), then there can be no default value specified through this attribute. This is because the attribute value would have to be encoded XML. Instead, the default value is an embedded config element with its own property default values.

There are two cases for how property value definitions are used: fixed-count property values and variable-numbered property values. For a property with a fixed number of values, the number of <value> tags indicates the number of values that are required for the property. For a property with a variable number of values, there must be exactly one <value> tag that acts as a prototype for each newly added value.

Property Value Enumerations

In cases of simple property value types (string, integer, and float), there may be a fixed number of allowed values. In that case, the property definition can contain an enumeration that lists those possible values. The graphical editor then uses this list to restrict what the user can choose for a value. The list is specified using the <enumeration> XML tag and its child tag <enum>.

An example use of a value enumeration is shown in Example 6.7, “Value Enumeration (surface_viewport.jdef)”. This example demonstrates how the enumeration can be used to provide symbolic identifiers for the allowed values. The property “view” in the surface_viewport config element can be set with either the integer values or the symbolic identifiers.

Example 6.7. Value Enumeration (surface_viewport.jdef)

<definition name="surface_viewport" ...>
   ...
   <definition_version ...>
      ...
      <property valuetype="integer" variable="false" name="view">
         <help/>
         <value label="View" defaultvalue="1"/>
         <enumeration editable="false">
            <enum label="Left Eye" value="1"/>
            <enum label="Right Eye" value="2"/>
            <enum label="Stereo" value="3"/>
         </enumeration>
      </property>
      ...
   </definition_version>
</definition>

In version 3.1 of the config definition file format, editable enumerations were introduced. An enumeration is identified as being editable by setting the editable attribute of the <enumeration> to true. (Note that this attribute is set to false in Example 6.7, “Value Enumeration (surface_viewport.jdef)”.) These provide another means to extend configurations with custom information without having to edit the distributed VR Juggler data files. In VRJConfig, an editable enumeration is presented as a value chooser that allows editing of the values. This comes in handy when there are values that are highly likely to be used, but there are other possible values that cannot be known when the config definition is written. An example of an editable enumeration is shown in Example 6.8, “Editable Value Enumeration (cluster_manager.jdef)”. In this case, the value enumeration provides the default set of cluster plug-ins that ship with VR Juggler. Because users can write their own cluster plug-ins, it is necessary to allow those custom plug-ins to be identified in the “plugin” property.

Example 6.8. Editable Value Enumeration (cluster_manager.jdef)

<definition name="cluster_manager" ...>
   ...
   <definition_version ...>
      <property valuetype="string" variable="true" name="plugin">
         <help>The names of the cluster plugins to load.</help>
         <value label="Plugin" defaultvalue=""/>
         <enumeration editable="true">
            <enum label="ApplicationDataManager"
                  value="ApplicationDataManager"/>
            <enum label="RIMPlugin" value="RIMPlugin"/>
            <enum label="StartBarrierPlugin"
                  value="StartBarrierPlugin"/>
            <enum label="SwapLockTCPPlugin"
                  value="SwapLockTCPPlugin"/>
            <enum label="SwapLockWiredPlugin"
                  value="SwapLockWiredPlugin"/>
         </enumeration>
      </property>
   </definition_version>
</definition>

Allowed Types for Embedded Config Elements and Config Element Pointers

When a property type is defined to be an embedded config element or a config element pointer, it is necessary to list the allowed config element types for the property. In the case of an embedded config element, this identifies to the graphical editor what config element types are allowed to be nested as values of the this property. For config element pointers, the allowed type list restricts the config element types at which the property value may point. This is similar to declaring a pointer in C or C++ to be of a type other than void*.

For both of these cases, the <allowed_type> XML tag must be used. Zero or more <allowed_type> XML tags may exist as a child of the <property_definition> element. The content of the <allowed_type> tag is technically free-form text, but for it to be useful, that text must be another config definition type. The definition type may be a base type, and VRJConfig will properly handle this case when presenting the user with a list of possible config elements to use as values for the property. Refer to Example 6.9, “Allowed Type for an Embedded Config Element Value (position_proxy.jdef)”, Example 6.10, “Single Allowed Type for a Config Element Pointer (position_proxy.jdef)”, and Example 6.11, “Multiple Allowed Types for a Config Element Pointer (user.jdef)” for examples of using <allowed_type>.

Tip

Try to use base types for allowed types. The config definitions that ship with VR Juggler use base types for allowed types to ensure the extensibility of VR Juggler, both in terms of the C++ code and in terms of custom configuration definitions.

Example 6.9. Allowed Type for an Embedded Config Element Value (position_proxy.jdef)

<definition name="position_proxy" ...>
   <definition_version ...>
      ...
      <property valuetype="configelement" variable="true"
                name="position_filters">
         ...
         <value label="Position Filter"/>
         <allowed_type>position_transform_filter</allowed_type>
      </property>
      ...
   </definition_version>
</definition_version>

Example 6.10. Single Allowed Type for a Config Element Pointer (position_proxy.jdef)

<definition name="position_proxy" ...>
   <definition_version ...>
      ...
      <property valuetype="configelementpointer" variable="false"
                name="device">
         ...
         <value label="Device"/>
         <allowed_type>positional_device</allowed_type>
      </property>
      ...
   </definition_version>
</definition_version>

Example 6.11. Multiple Allowed Types for a Config Element Pointer (user.jdef)

<definition name="user" ...>
   <definition_version ...>
      ...
      <property valuetype="configelementpointer"
                variable="false" name="head_position">
         ...
         <value label="Head Position"/>
         <allowed_type>alias</allowed_type>
         <allowed_type>position_proxy</allowed_type>
      </property>
      ...
   </definition_version>
</definition_version>

Upgrade Transforms

Upgrade transforms are what make automatic configuration updating possible. When a new config definition version is created, an upgrade transform should be written using XSLT. When VRJConfig loads a configuration file, it checks the versions of all the contained config elements to ensure that they are using the latest version of the definition. VRJConfig will iteratively apply upgrades to a config element until it is at the most current version.

A given upgrade transform is written as an incremental upgrade from the previous version. That is, for version N+1 of a config definition, the upgrade transform associated with the definition for version N+1 upgrades elements at version N. The XSLT code only has to operate on a single part of the XML tree—namely, the config element that is an instance of the old config definition.

Note

VRJConfig in VR Juggler 2.0 does not support executing extension functions. Therefore, XSLT extension functions cannot currently be used in the XSLT code for an upgrade transform.

Caution

A common pitfall for authors of upgrade transforms is the misuse of XML namespaces. Juggler configuration documents use the XML namespace http://www.vrjuggler.org/jccl/3.0/configuration, and this must be used correctly within the XSLT code. Examples of upgrade transforms given in this chapter demonstrate how to use the namespace correctly. The key points to note are the declaration of the namespace as an attribute of the xsl:stylesheet document and the declaration and use of a variable {$jconf} that is set to the value of the namespace.



[8] The distinction between renaming a property definition and replacing a definition is not well defined. In this case, it is basically a simple renaming because the most obvious change between versions is the name of the property for the proxy. Note, however, that the allowed type for the config element pointer value has changed, too. The interpretation of such details is up to the author of the config definition and the upgrade transform.

[9] Having zero property definitions is uncommon but is allowed for base definition types that are used to provide points of extension in the configuration. See $VJ_BASE_DIR/share/vrjuggler/data/definitions/digital_device.jdef for a config definition that defines no properties of its own.

Appendix A. Tracker Configuration

In this appendix, we explain the details of configuring individual trackers supported by Gadgeteer. In general, the configuration process for all trackers involves two steps:

  1. Filling in the details of the tracker is connected to the computer where the driver will be run, and

  2. Defining the transformation for converting raw tracker samples into the Juggler coordinate frame.

We will concentrate on step #1 in this appendix. The details of step #2 have already been presented in the section called “Position Filters”. Where applicable, we will offer tips for setting up the transform for individual trackers, but we will not repeat the full description of position filters. Furthermore, we will not repeat the explanation of device data sources and device proxies. It is expected that readers of this appendix have already read and understood everything presented in Chapter 2, Configuring Input.

Ascension Flock of Birds®

Important

The Flock of Birds® driver in VR Juggler 2.0 does not work correctly. The VRPN or Trackd drivers must be used instead to access the Flock of Birds® tracking system.

Configuration of the Ascension Flock of Birds® device driver is relatively straightforward. For the most complete understanding of how a Flock of Birds® tracker works and the terminology used here, it is highly recommended that users read the freely available document titled Flock of Birds® Installation and Operation Guide, which can be downloaded from the Ascension Technology Corporation website. The driver was written relative to 910141-A Rev B of that document, published January 31, 2002. We will not attempt to repeat the information presented in that document. Instead, we will focus on the process of configuring the Gadgeteer device driver that communicates with the Flock of Birds® hardware.

serial port

The name of the serial port to which the Flock of Birds® device is attached. The port name will vary based on the conventions of the host operating system. For Microsoft Windows®, this will be along the lines of COM1, COM2, etc. For UNIX-based platforms, the value will be similar to /dev/ttyS0, /dev/ttyd2, etc.

baud

The baud setting to use for input and output on the serial port. The correct setting depends on the Flock of Birds® device and on the capabilities of the serial port.

hemisphere

The transmitter hemisphere in which the sensors will be tracked. The setting for this depends on the position and orientation of the transmitter. The rear (aft) hemisphere is where the wire leads into the transmitter.

master address

The Fast Bird Bus address of the master bird. The address of the master bird depends on how the hardware is set up. If the Flock of Birds® firmware revision is 3.67 or newer, the value of this property is ignored because the master bird address can be auto-detected by the hardware.

addressing mode

The addressing mode in use by the Flock of Birds® hardware. The addressing mode depends on what type of Flock of Birds® hardware is being used and how it is configured. If the firmware revision is 3.67 or newer, the value of this property is ignored because the addressing mode can be auto-detected by the hardware.

filter

The software filter to use. Currently, the value of this property is not used in setting up the communication with the Flock of Birds®. The Flock of Birds® manual suggests that average use of the hardware should not require changing the filter settings.

position filters

The position filters that will be used to transform 6DOF positional data received from the tracking device. This property allows a variable number of nested config elements of type position_transform_filter (the only position filter type currently implemented). The filters are applied in the order in which they appear as the values of this property. There should always be at least one position filter configured. Refer to the section called “Position Filters” for more details on position filters and how to use them.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.

Ascension MotionStar Wireless® 2

We now examine the configuration of the Gadgeteer driver for the Ascension MotionStar Wireless® 2 tracking system. Configuration of the device driver is relatively straightforward. For the most complete understanding of how a MotionStar Wireless® tracker works and the terminology used here, it is highly recommended that users read the freely available document titled MotionStar Wireless™ Installation and Operation Guide, which can be downloaded from the Ascension Technology Corporation website. The driver was written relative to 910006-A Rev C of that document, published May 23, 2001. We will not attempt to repeat the information presented in that document. Instead, we will focus on the process of configuring the Gadgeteer device driver that communicates with the MotionStar Wireless® 2 hardware.

Important

The Gadgeteer driver for the MotionStar Wireless® 2 tracking system is implemented using the Ethernet protocol. Gadgeteer does not have a driver for a MotionStar Wireless® system connected using RS-232. Furthermore, it is not known whether this driver works with a non-wireless MotionStar® system connected using Ethernet.

When configuring the Gadgeteer driver for the MotionStar Wireless® tracking system, it is important to understand that there must be one instance of the driver configured for each pack that will be used in the immersive visualization system. In this case, there will be a master chassis for one of the packs. The remaining packs will each communicate with a distinct slave chassis. The driver configuration must accurately reflect this configuration of the hardware.

address

The host name or IP address of the MotionStar® chassis with which the driver will communicate.

server port

The network port on which the MotionStar® chassis is listening for an incoming connection. The choice of the port dictates whether the User Datagram Protocol (UDP) or the Transmission Control Protocol (TCP) will be used. To use UDP, the value of this property must be 5000. For TCP, the value must be 6000. Most testing of the Gadgeteer driver for the MotionStar Wireless® system has been done using TCP, and this is the recommended setting.

Caution

Port 6000 is also used for the X11 protocol. In general, this is not a problem because the MotionStar® server chassis is not running an X Window System server.

is master

Identifies whether the driver will be connecting to a master server chassis or a slave server chassis. A slave chassis is used in a multi-pack setting.

hemisphere

The transmitter hemisphere in which the sensors will be tracked. The setting for this depends on the position and orientation of the transmitter. The rear (aft) hemisphere is where the wire leads into the transmitter.

data format

The data format that will be used to return sensor data from the chassis to the driver. The default value is Position/Angles, which returns full 6DOF tracking data. Refer to the MotionStar Wireless® manual for more details on the available data formats.

Important

As of this writing, only the Position/Angles setting for the driver is known to work reliably. The other possible data formats have not been tested as well as Position/Angles. In general, Position/Quaternion would be the preferred setting if it were known to work reliably.

mode

The sample mode for the driver and the server chassis. Choosing “Run Continuous” indicates that the server chassis will be put into a mode where it will constantly send data samples to the driver without requiring a new query/response operation from the driver. Choosing “Sample Individually” requires that the driver explicitly request each sample from the server. The latter results in much more network traffic and should generally not be used.

report rate

The report rate for the sensors, which must be a whole number in the range [0, 255]. A value of 0 effectively disables the sensors by causing them to return no data for each measurement cycle. A value of 1 causes the sensors to return data for every measurement cycle. A value of 2 results in the sensors returning data every second measurement cycle, and so on. In general, this should be set to 1.

measurement rate

The value of this property is used to set the measurement rate on the server chassis. This overrides the measurement rate setting in the BASE.INI file, and for that reason, the value should be chosen carefully. As described in the MotionStar Wireless® manual, the value must be a floating-point value in the range [30.0, 100.0]. Several “ideal” values are suggested in the manual.

position filters

The position filters that will be used to transform 6DOF positional data received from the tracking device. This property allows a variable number of nested config elements of type position_transform_filter (the only position filter type currently implemented). The filters are applied in the order in which they appear as the values of this property. There should always be at least one position filter configured. Refer to the section called “Position Filters” for more details on position filters and how to use them.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.

InterSense API and InterSense IS-900

InterSense API

  • Driver name: IntersenseAPI_drv

  • Config element type: intersense_api

  • Driver availability: Linux, IRIX®, Mac OS X, Microsoft Windows®

  • Product availability: Linux, IRIX®, Mac OS X, Microsoft Windows®

  • Product website: http://www.intersense.com/support/

InterSense IS-900

When configuring InterSense trackers, there are two driver options: the IS-900™ and the so-called InterSense API. As the name suggests, the IS-900™ driver only works with the InterSense IS-900™ product. The InterSense API driver, on the other hand, makes use of a software library (a DLL) called the InterSense Interface Libraries SDK distributed by InterSense to communicate with all InterSense products supported by the DLL. (In this text, we will refer to the InterSense Interface Libraries SDK as simply the “InterSense driver DLL”.)

In this section, we will explain how to configure both the InterSense API driver and the IS-900™ driver. As we will see, there is a fair amount of commonality in the configuration process. Readers can safely read either the subsection for the InterSense API driver or the subsection for the IS-900™ driver. Both include complete information for the respective driver. The explanation of InterSense station configuration is included in a separate subsection.

InterSense API Configuration Aspects

We now review the specific details of configuring the InterSense API driver. Before configuring the Gadgeteer InterSense API driver, please be sure to read the documentation that comes with the InterSense driver DLL. With versions up to and including 3.58 of the driver DLL, the documentation is in the file README.TXT. That document explains how to install the driver DLL, how to set up port mapping information if necessary, and what platform-specific limitations exist. More specifically, readers are strongly encouraged to note what serial ports are allowed to be used when hooking up an InterSense tracking system.

driver

There are two ways to set the value for this property. The first way is to fill in just the name of the driver DLL distributed by InterSense without the platform-specific file extension (such as .so, .dylib, or .dll). In this case, the value for this property would be isense on Microsoft Windows® and libisense on all other platforms. Choosing this approach to setting the value requires that the InterSense driver DLL be installed in a directory where the run-time loader can find it. If the InterSense driver DLL is installed as described in the driver DLL documentation, then it will be found using the default search path. Otherwise, the run-time loader search path can be extended using an environment variable. The following are platform-specific environment variables used for this purpose:

  • Microsoft Windows®: PATH

  • Mac OS X: DYLD_LIBRARY_PATH

  • IRIX®: LD_LIBRARY_PATH or LD_LIBRARY32_PATH

  • Linux and other UNIX variants: LD_LIBRARY_PATH

If it is impossible or undesirable to install the driver DLL as described in its documentation, the absolute path of the driver DLL without the platform-specific file extension can be given as the value for this property. For example, if we have downloaded and unpacked the InterSense driver DLL package to /home/user1/isense, the value on Linux would be /home/user1/isense/Linux/libisense. For Mac OS X, the value would be /home/user1/isense/MacOSX/libisense. On Microsoft Windows®, if we have unpacked the InterSense driver DLL package to C:\isense, the value would be C:\isense\Windows\isense.

Note

The IRIX® version of the InterSense driver DLL is only available as an N32 binary. It cannot be loaded into a 64-bit build of the Gadgeteer InterSense API driver.

serial port

When configuring the InterSense API driver, there are two options available to users. The first option is to use the traditional approach of entering the serial device name. The port name will vary based on the conventions of the host operating system. For Microsoft Windows®, this will be along the lines of COM1, COM2, etc. For UNIX-based platforms, the value will be similar to /dev/ttyS1, /dev/ttyd2, etc. Alternatively, a value of 0 can be entered for this property. This directs the InterSense driver DLL to scan all available ports until it finds an InterSense device. While this is easier to configure, it does not work in the case when multiple InterSense devices are plugged in to the serial ports of a computer.

stations

The settings for each station connected to the InterSense base unit. This property allows a variable number of nested config elements of type intersense_station. There should always be at least one station configured. Without a station connected to the base unit, it is not possible to get any data from the InterSense device. We will explain more about InterSense stations in the section called “Configuring InterSense Stations”.

verbose

Enables output from the low-level driver. In general, this should be set to false, but it can be useful to set it to true when debugging device problems.

min

The minimum bound for received analog data as a floating-point value. This is shared across all analog input sources defined as part of configuring the InterSense stations. As with all analog devices, the analog data that ultimately reaches the VR Juggler application object will be scaled to be within the range [0.0, 1.0]. The value of this property will be used by the internal scaling algorithm.

max

The maximum bound for received analog data as a floating-point value. This is shared across all analog input sources defined as part of configuring the InterSense stations. As with all analog devices, the analog data that ultimately reaches the VR Juggler application object will be scaled to be within the range [0.0, 1.0]. The value of this property will be used by the internal scaling algorithm.

position filters

The position filters that will be used to transform 6DOF positional data received from the tracking device. This property allows a variable number of nested config elements of type position_transform_filter (the only position filter type currently implemented). The filters are applied in the order in which they appear as the values of this property. There should always be at least one position filter configured. Refer to the section called “Position Filters” for more details on position filters and how to use them.

Tip

Using the InterSense software ISDEMO.EXE, it is possible to configure the origin and the coordinate frame of the tracking system to be whatever is convenient. Hence, the easiest way to configure the position filters for an InterSense device is to use ISDEMO.EXE to make the origin and coordinate frame be what VR Juggler expects. Then, no transformations are required in the position transform filter. If nothing else, use ISDEMO.EXE to verify that the InterSense tracker coordinate frame is right-handed.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.

IS-900™ Configuration Aspects

We now review the specific details of configuring the IS-900™ driver. Remember that this driver only works with the InterSense IS-900™ tracking system and that use of the InterSense API driver is recommended wherever possible.

serial port

The name of the serial port to which the InterSense tracking device is attached. The port name will vary based on the conventions of the host operating system. For Microsoft Windows®, this will be along the lines of COM1, COM2, etc. For UNIX-based platforms, the value will be similar to /dev/ttyS0, /dev/ttyd2, etc.

baud

The baud setting to use for input and output on the serial port. The correct setting depends on the InterSense tracking device and on the capabilities of the serial port.

stations

The settings for each station connected to the InterSense base unit. This property allows a variable number of nested config elements of type intersense_station. There should always be at least one station configured. Without a station connected to the base unit, it is not possible to get any data from the InterSense device. We will explain more about InterSense stations in the section called “Configuring InterSense Stations”.

verbose

Enables output from the low-level driver. In general, this should be set to false, but it can be useful to set it to true when debugging device problems.

script

The absolute path to a script that will be given to the InterSense tracking device to execute at start-up time. Refer to the InterSense device documentation for more details on how to utilize this capability of the hardware.

min

The minimum bound for received analog data as a floating-point value. This is shared across all analog input sources defined as part of configuring the InterSense stations. As with all analog devices, the analog data that ultimately reaches the VR Juggler application object will be scaled to be within the range [0.0, 1.0]. The value of this property will be used by the internal scaling algorithm.

max

The maximum bound for received analog data as a floating-point value. This is shared across all analog input sources defined as part of configuring the InterSense stations. As with all analog devices, the analog data that ultimately reaches the VR Juggler application object will be scaled to be within the range [0.0, 1.0]. The value of this property will be used by the internal scaling algorithm.

position filters

The position filters that will be used to transform 6DOF positional data received from the tracking device. This property allows a variable number of nested config elements of type position_transform_filter (the only position filter type currently implemented). The filters are applied in the order in which they appear as the values of this property. There should always be at least one position filter configured. Refer to the section called “Position Filters” for more details on position filters and how to use them.

Tip

Using the InterSense software ISDEMO.EXE, it is possible to configure the origin and the coordinate frame of the tracking system to be whatever is convenient. Hence, the easiest way to configure the position filters for an InterSense device is to use ISDEMO.EXE to make the origin and coordinate frame be what VR Juggler expects. Then, no transformations are required in the position transform filter. If nothing else, use ISDEMO.EXE to verify that the InterSense tracker coordinate frame is right-handed.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.

Configuring InterSense Stations

InterSense stations are receivers for input data read from InterSense tracked devices. Each tracked device (such as the head tracker and the InterSense wand) will have its own station. When configuring one of the InterSense device drivers, there must be an InterSense station config element (of type intersense_station) nested within the driver config element for each station.

Understanding the way in which InterSense stations are configured is, unfortunately, complicated. This arises from the presence of two drivers with a great deal of high-level commonality. At the low level, however, the drivers are very different. In particular, the InterSense IS-900™ driver has been around since VR Juggler 1.0.0, and the version in Gadgeteer has a lot of legacy behavior dating back to the original introduction of the driver to the VR Juggler 1.0 code base. On the other hand, the InterSense API driver is new with VR Juggler 2.0 and Gadgeteer 1.0. While it is closely related to the InterSense IS-900™ driver, it makes better use of the new features of Gadgeteer introduced after VR Juggler 1.0. For this reason (and many others), the InterSense API driver is the preferred choice.

We defer the explanation of the differences in handling of InterSense station configurations until after we introduce the configurable properties of InterSense stations. The properties are as follows:

enabled

Indicates whether the physical InterSense station should be used for sampling data. This can be used to disable a station if necessary.

station index

The index of the station as determined by the InterSense hardware configuration. This is used to associate the InterSense station config element with the physical station.

use digital

This property is used to determine whether any digital inputs (such as buttons) associated with the station should be used. This should only be set to true when the station actually has digital inputs.

use analog

This property is used to determine whether any analog inputs (such as joysticks) associated with the station should be used. This should only be set to true when the station actually has analog inputs.

digital first

The starting index for digital device proxies referring to input sources from this station. With the InterSense API driver, this property is ignored. Correct, effective use of this property is explained in more detail below.

digital count

The number of digital inputs that are available through this tracker station. Correct, effective use of this property is explained in more detail below.

analog first

The starting index for analog device proxies referring to input sources from this station. With the InterSense API driver, this property is ignored. Correct, effective use of this property is explained in more detail below.

analog count

The number of analog inputs that are available through this tracker station. Correct, effective use of this property is explained in more detail below.

The most important difference between the InterSense IS-900™ and InterSense API drivers concerns how they determine the indexing of the input sources that will be accessed by digital and analog proxies. The InterSense API driver uses a simple incremental scheme for defining the indices for the proxies. The InterSense IS-900™ driver, however, uses a more complex approach that offers some flexibility, though the added flexibility is not really useful. Again, this complexity is probably the result of legacy behavior from the VR Juggler 1.0 version of the driver and could (potentially) be eliminated.

Ultimately, both drivers return the same data regardless of their handling of input source indexing. What must be understood is how the indexing schemes work. We will begin with the InterSense API driver because it is easier to understand. As was introduced in the section called “Input Devices” and the section called “Device Proxies”, device proxies reference a zero-based index into a sequence of input sources. Each station corresponds to one tracked device, and the indices of those tracked devices is based on the order of the nested InterSense station config elements. The first station config element provides position input source 0 for a position proxy, the second provides position input source 1, and so on.

Within each station, analog and/or digital inputs can be enabled. The index values for analog and digital inputs can be thought of as a counter that starts at 0 and is incremented for each station based on the number of analog and digital inputs that are available. For example, consider a scenario where we have three stations (0, 1, and 2) with the following hardware configuration:

  • Station 0 has no analog or digital inputs

  • Station 1 has two analog inputs but no digital inputs

  • Station 2 has one analog input and five digital inputs

The counters for the analog inputs and digital inputs remain at zero for Station 0. For Station 1, the counter for the analog inputs grows to two, and the counter for the digital inputs remains at zero. We can have two analog device proxies that refer to our InterSense API device, one pointing at analog input source 0 and the other at analog input source 1. The data received through the proxies will come from the analog inputs of Station 1. Finally, for Station 2, the counter for the analog inputs is incremented to three, and the counter for the digital inputs increases to five. We can now add one more analog device proxy that points to analog input source 2 and five new digital device proxies pointing to digital input sources 0 through 4. All of this can be done by ignoring the “digital first” and “analog first” properties, though they can be used to store the values for the counters if that is helpful.

In the case of the InterSense IS-900™ driver, the same concept of the counters for digital and analog input sources still applies. However, the “digital first” and “analog first” properties must be used, and they must be used carefully. The values of these properties are internally by the InterSense IS-900™ driver for storage of device data samples. Errors in the configuration will almost certainly result in incorrect or otherwise undesirable results. The added flexibility, hinted at above, is that users can set up their own ordering for the input source indices rather than basing it on the ordering of the nested InterSense station config elements. However, this flexibility is largely useless because device proxies already provide this capability in a more robust manner.

Polhemus Fastrak®

  • Driver name: Fastrak_drv

  • Config element type: fastrak

  • Interface type: serial

  • Driver availability: Linux, IRIX®, Solaris, FreeBSD, Mac OS X, Microsoft Windows®

  • Product website: http://www.polhemus.com/fastrak.htm

VRCO Trackd® and trackdAPI Sensor

VRCO Trackd® Sensor

  • Driver name: Trackd_drv

  • Config element type: trackd_sensor

  • Driver availability: Linux, IRIX®, Solaris, FreeBSD, Mac OS X

  • Product availability: Linux, IRIX®, Solaris, HP-UX, Microsoft Windows®

  • Product website: http://www.vrco.com/products/trackd/trackd.html

VRCO trackdAPI Sensor

  • Driver name: TrackdAPI_drv

  • Config element type: trackd_api_sensor

  • Driver availability: Linux, IRIX®, Solaris, Microsoft Windows®

  • Product availability: Linux, IRIX®, Solaris, HP-UX, Microsoft Windows®

  • Product website: http://www.vrco.com/products/trackd/trackd_api.html

  • Other information: requires a license from VRCO

Appendix B. Glove Configuration

In this appendix, we explain the details of configuring glove devices supported by Gadgeteer.

Note

VR Juggler 2.0 lacks support for gesture-based glove devices. The glove devices that are supported are treated as either digital or analog devices. Full gesture support is planned for VR Juggler 2.2 (which will include Gadgeteer 1.2), and glove configuration processes may change with that release. What is presented in this appendix is the process to configured the supported glove types as either analog or digital devices.

5DT Data Glove

  • Driver name: DataGlove_drv

  • Config element type: data_glove

  • Interface type: serial

  • Driver availability: Linux, IRIX®, Solaris, FreeBSD, Mac OS X, Microsoft Windows®

  • Product website: http://www.5dt.com/hardware.html

The 5DT Data Glove driver is one of the simplest Gadgeteer device drivers to configure. The most important aspect, ultimately, is getting the analog proxies set up correctly to be able to read data from the seven data sources provided by a single 5DT Data Glove. We first present the configurable properties of the 5DT Data Glove config element (type data_glove) and then explain how to set the indices for the analog proxies.

serial port

The serial port to which the 5DT Data Glove is connected. The port name will vary based on the conventions of the host operating system. For Microsoft Windows®, this will be along the lines of COM1, COM2, etc. For UNIX-based platforms, the value will be similar to /dev/ttyS0, /dev/ttyd2, etc.

baud

The baud setting to use for input and output on the serial port. The correct setting depends on the 5DT Data Glove and on the capabilities of the serial port.

glove position

The name of a position proxy that is associated with the Data Glove. Often times, a tracker sensor will be attached to a glove device to combine hand tracking with glove data.

Note

At this time, the position proxy is not used by the Data Glove driver. Therefore, it is acceptable to have no value set for this property.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.

The version of the 5DT Data Glove in Gadgeteer 1.0 has seven analog input sources, and thus, up to seven analog proxies can be configured to read from the device. The indices for the analog proxies are the following:

  • 0: thumb

  • 1: index finger

  • 2: middle finger

  • 3: ring finger

  • 4: pinky finger

  • 5: hand pitch

  • 6: hand roll

Fakespace Pinch™ Gloves

  • Driver name: PinchGlove_drv

  • Config element type: pinch_glove

  • Interface type: serial

  • Driver availability: Linux, IRIX®, Solaris, FreeBSD, Mac OS X, Microsoft Windows®

The Fakespace Pinch Glove driver is another of the simplest Gadgeteer device drivers to configure. The most important aspect, ultimately, is getting the digital proxies set up correctly to be able to read data from the data sources provided by a Fakespace Pinch Glove device. The driver supports reading from one or two Pinch Gloves connected to a single Pinch Glove box. Whether one or two Pinch Gloves are connected, the driver always provides ten digital data sources. We first present the configurable properties of the Fakespace Pinch Glove config element (type pinch_glove) and then explain how to set the indices for the digital proxies.

serial port

The serial port to which the Fakespace Pinch Glove box is connected. The port name will vary based on the conventions of the host operating system. For Microsoft Windows®, this will be along the lines of COM1, COM2, etc. For UNIX-based platforms, the value will be similar to /dev/ttyS0, /dev/ttyd2, etc.

baud

The baud setting to use for input and output on the serial port. The correct setting depends on the Fakespace Pinch Glove box and on the capabilities of the serial port.

glove position

The name of a position proxy that is associated with a Pinch Glove. Often times, a tracker sensor will be attached to a glove device to combine hand tracking with glove data.

Note

At this time, the position proxy is not used by the Pinch Glove driver. Therefore, it is acceptable to have no value set for this property.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.

As stated above, the version of the Fakespace Pinch Glove in Gadgeteer 1.0 provides ten digital input sources, and thus, up to ten digital proxies can be configured to read from the device. The indices for the digital proxies are the following:

  • 0: left thumb

  • 1: left index finger

  • 2: left middle finger

  • 3: left ring finger

  • 4: left pinky finger

  • 5: right thumb

  • 6: right index finger

  • 7: right middle finger

  • 8: right ring finger

  • 9: right pinky finger

These indices will be the same regardless of which gloves are connected to the Pinch Glove box, and the proxies make it possible to hide such details from the application programmers.

Immersion CyberGlove®

This device is not supported by Gadgeteer 1.0. Support is planned to be restored with the release of Gadgeteer 1.2.

Appendix C. Multi-Type Input Device Configuration

In this appendix, we address the configuration of device drivers for input devices that return more than one type of input data. For example, virtually every game controller made in the last fifteen years has provided both digital and analog input through one or more buttons and one or more joysticks respectively. Furthermore, we have already seen two examples of device drivers in Gadgeteer that provide multiple types of data: the IS-900 and the InterSense API drivers (see the section called “InterSense API and InterSense IS-900™”).

VRCO Trackd® and trackdAPI Controller

VRCO Trackd® Controller

  • Driver name: Trackd_drv

  • Config element type: trackd_controller

  • Driver availability: Linux, IRIX®, Solaris, FreeBSD, Mac OS X

  • Product availability: Linux, IRIX®, Solaris, HP-UX, Microsoft Windows®

  • Product website: http://www.vrco.com/products/trackd/trackd.html

VRCO trackdAPI Controller

  • Driver name: TrackdAPI_drv

  • Config element type: trackd_api_controller

  • Driver availability: Linux, IRIX®, Solaris, Microsoft Windows®

  • Product availability: Linux, IRIX®, Solaris, HP-UX, Microsoft Windows®

  • Product website: http://www.vrco.com/products/trackd/trackd_api.html

  • Other information: requires a license from VRCO

VRPN

  • Driver name: VRPN_drv

  • Config element type: vrpn

  • Driver availability: Linux, IRIX®, Solaris, FreeBSD, Mac OS X, Microsoft Windows®

  • Product availability: Linux, IRIX®, Solaris, FreeBSD, Mac OS X, Microsoft Windows®

  • Product website: http://www.cs.unc.edu/Research/vrpn/

  • Other information: requires version 06.07 beta 1 or newer for Mac OS X use; VR Juggler 2.0.2 and newer support reading analog data from the VRPN server

The VRPN driver in Gadgeteer provides access to positional, digital, and analog input coming from any positional, digital, and/or analog device supported by VRPN. The VRPN driver in Gadgeteer acts as a client to a VRPN server, so configuring VR Juggler to use VRPN for input requires two steps: setting up a VRPN server and configuring the VRPN driver in Gadgeteer. We will not cover how to configure a VRPN server. Readers needing that information are referred to the VRPN website.

There are only a few properties in the VRPN config element (type vrpn). The properties are presented below. Afterwards, we explain how to set the indices used by positional, digital, and analog proxies.

tracker server

The identifier for the VRPN tracker server from which positional data will be read.

button server

The identifier for the VRPN button server from which digital data will be read.

analog server

The identifier for the VRPN analog server from which analog data will be read.

number of trackers

The number of trackers (i.e., sensors) connected to the tracker server that are providing positional data to clients. If set to 0, then no connection will be made to the tracker server (if named).

number of buttons

The number of buttons connected to the button server that are providing digital data to clients. If set to 0, then no connection will be made to the button server (if named).

number of analogs

The number of analog data channels provided by the analog server. If set to 0, then no connection will be made to the analog server (if named).

min

The minimum bound for received analog data as a floating-point value. This is shared across all analog input channels being read from the VRPN server. As with all analog devices, the analog data that ultimately reaches the VR Juggler application object will be scaled to be within the range [0.0, 1.0]. The value of this property will be used by the internal scaling algorithm. Generally, the value for this property should be -1.0.

max

The maximum bound for received analog data as a floating-point value. This is shared across all analog input channels being read from the VRPN server. As with all analog devices, the analog data that ultimately reaches the VR Juggler application object will be scaled to be within the range [0.0, 1.0]. The value of this property will be used by the internal scaling algorithm. Generally, the value for this property should be 1.0.

position filters

The position filters that will be used to transform 6DOF positional data received from the tracking device. This property allows a variable number of nested config elements of type position_transform_filter (the only position filter type currently implemented). The filters are applied in the order in which they appear as the values of this property. There should always be at least one position filter configured. Refer to the section called “Position Filters” for more details on position filters and how to use them.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.

Once the driver is configured, positional, digital, and/or analog device proxies must be pointed at the VRPN driver config element. The number of proxies of each type used depends on how many trackers and buttons were configured. For example, if zero trackers, six buttons, and six analogs were configured in the VRPN driver config element, there would be zero positional device proxies, at least six digital device proxies, and at least six analog device procies. The unit indexing is based at zero (0) for both the positional and digital data sources, and the indexing for the two data source types is independent. For example, if the VRPN driver were configured to have three trackers, six buttons, and two analogs, there would be three positional device proxies with units 0 through 2, six digital device proxies with units 0 through 5, and two analog device proxies with units 0 through 1.

Ascension Wanda®

The Ascension Wanda® is a hand-held device providing three digital input sources and two analog input sources (the axes of the joystick). The device contains an embedded 6DOF sensor, but the Gadgeteer driver for the Wanda® does not make use of that input source. Accessing that sensor data would occur through a different Ascension tracker device.

There is very little about the Gadgeteer driver for the Ascension Wanda to configure. We describe the properties of the driver config element (type wanda) below:

port name

The name of the serial port through which the Gadgeteer driver can communicate with the device. The port name will vary based on the conventions of the host operating system. For Microsoft Windows®, this will be along the lines of COM1, COM2, etc. For UNIX-based platforms, the value will be similar to /dev/ttyS0, /dev/ttyd2, etc.

min

The minimum value returned by the hardware to the driver for the analog axes of the Wanda® joystick The value of this property is ignored by the device driver. The device always returns axis data in the range -34 to 34 inclusive (in mathematical terms, [-34, 34]). Using the default value (-34.0) for this property is always safe.

max

The maximum value returned by the hardware to the driver for the analog axes of the Wanda® joystick The value of this property is ignored by the device driver. The device always returns axis data in the range -34 to 34 inclusive (in mathematical terms, [-34, 34]). Using the default value (34.0) for this property is always safe.

read timeout

The Wanda® device only returns data when the user presses a button, releases a button, or moves the joystick. Otherwise, there are no data on the serial line. This means that the Gadgeteer driver could end up blocking forever waiting on data that is never coming. To prevent this from happening, the driver uses a timeout for read operations when there may not be data to read. To get good performance from the driver and to prevent the driver thread from starving the other threads, this property can be used to adjust the read timeout period. The timeout period is measured in milliseconds, and the default timeout is 20 milliseconds. Timeouts up to 100 milliseconds have been tested without noticeable driver performance degradation. The value to use will depend largely on the computer to which the Wanda® is attached.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.

Unlike other serial device drivers in Gadgeteer, there is no baud setting for the Wanda® driver. This is because the hardware always communicates at 1200 baud. Trying to use other values would prevent proper communication with the device, so users are not allowed to configure the baud setting.

Note

The Ascension Wanda® will be detected as a serial mouse when using Microsoft Windows®. When this happens, the operating system locks the COM port and prevents other software from communicating with the Wanda® device. This is usually indicated by the Wanda® driver reporting that access to the COM port is denied (error code 5) when the Input Manager tries to start the driver. To prevent this, follow these steps:

  1. Boot into Windows® with the Wanda® plugged in to a COM port.

  2. Open the Registry Editor by running regedit.exe.

  3. Navigate to the registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sermouse and select the value “Start” in the right-hand panel.

  4. Change the value of “Start” to 4. (Normally, it will be 3.)

  5. Reboot.

After doing the above, the Wanda® will be available for use by VR Juggler applications.

Immersion Interface Box

The Immersion Interface Box (or “IBox” as it is sometimes called) provides a flexible mechanism for reading digital and analog data from any piece of hardware that can be wired into the Interface Box. Hooking hardware up to the Interface Box is far beyond the scope of this document, but as we will see, configuring the IBox driver is very simple. The IBox itself allows up to four digital and four analog hardware devices to be connected to it, and thus the driver provides up to four digital and four analog input sources. Below, we describe the properties for the config element used to configure the Interface Box driver (type ibox), and then we describe how to configure digital and analog device proxies that point at the IBox config element.

port name

The name of the serial port through which the Gadgeteer driver can communicate with the device. The port name will vary based on the conventions of the host operating system. For Microsoft Windows®, this will be along the lines of COM1, COM2, etc. For UNIX-based platforms, the value will be similar to /dev/ttyS0, /dev/ttyd2, etc.

baud

The baud setting to use for input and output on the serial port. The correct setting depends on the Interface Box and on the capabilities of the serial port.

min

The minimum bound for received analog data as a floating-point value. This is shared across all analog input sources defined as part of configuring the InterSense stations. As with all analog devices, the analog data that ultimately reaches the VR Juggler application object will be scaled to be within the range [0.0, 1.0]. The value of this property will be used by the internal scaling algorithm. The default value is 0.0.

max

The maximum bound for received analog data as a floating-point value. This is shared across all analog input sources defined as part of configuring the InterSense stations. As with all analog devices, the analog data that ultimately reaches the VR Juggler application object will be scaled to be within the range [0.0, 1.0]. The value of this property will be used by the internal scaling algorithm. The default value is 255.0.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.

Once the driver is configured, analog and/or digital device proxies must be pointed at the IBox driver config element. The number of proxies of each type used depends on how many hardware devices are plugged into the Interface Box. For example, if zero analog devices and three devices are wired physically into the Interface Box, there would be zero analog device proxies and at least three digital device proxies. The unit indexing is based at zero (0) for both the analog and digital data sources, and the indexing for the two data source types is independent. For example, if the IBox had three analog devices and two digital devices plugged into it, there would be two analog device proxies with units 0 through 2 and two digital device proxies with units 0 through 2.

Caution

Be careful when trying different baud settings. If the device driver is not shut down cleanly (such as through the use of CTRL-c to kill the application) immediately prior to changing the baud setting, the IBox hardware will not respond correctly the next time it is accessed. Turning the IBox off and then back on is necessary to get the hardware back into the correct state. If instead the driver is shut down cleanly, then changing the baud setting will not cause any problems. In summary, it is always best to try to shut down the device driver cleanly. If this does not happen, it may be necessary to power cycle the IBox to get it to initialize correctly for future uses.

Linux Joystick Device

  • Driver name: LinuxJoydev_drv

  • Config element type: linux_joydev

  • Interface type: game port or USB

  • Driver availability: Linux

  • Other information: requires Linux joydev kernel module

The Linux joystick device driver makes use of the Linux joydev kernel module to communicate with joysticks and game pads connected via a PC game port or USB. Because the specifics of joysticks and game pads vary from vendor to vendor and model to model, the Linux joydev device is highly dynamic and generic. The Linux joystick device driver in Gadgeteer takes advantage of this to avoid restricting what types of joysticks or game pads may be used. This is reflected in the configurable properties of the Linux joystick device driver config element (type linux_joydev), shown below:

port name

The name of the joystick port through which the Gadgeteer driver can communicate with the device. The port name will be one of /dev/js0, /dev/js1, /dev/input/js0, etc. The default value for this property is /dev/js0.

Caution

With the Linux 2.4 kernel, it is unclear whether multiple USB joysticks or game pads plugged in to a single computer will always have the same port numbers assigned to them each time the computer is rebooted. By default, there appears to be no guarantee that a given joystick or game pad will always be associated with the same /dev/jsN device node. There may be a way to tell the Linux kernel how to assign port numbers to USB joysticks or game pads, but the process is not known to us as of this writing. Further, it is not known if the Linux 2.6 kernel exhibits the same behavior.

axis buttons

A variable-valued property that identifies which axes (using zero-based integer identifiers) should be treated as digital buttons. The additional buttons will be appended to the basic set of digital inputs available from the device. This feature is useful with a directional pad (also known as a “hat”) to get additional button inputs.

Note

The analog input from the axis (or axes) will still be available. An “axis button” provides a second interpretation of the received input data.

min

The minimum value returned by the hardware to the driver for the analog axes of the joystick(s) on the game controller. The value of this property is ignored by the device driver. The joydev kernel module always returns joystick axis data in the range -32,767 to 32,767 inclusive (in mathematical terms, [-32,767, 32,767]). Using the default value for this property is always safe.

max

The maximum value returned by the hardware to the driver for the analog axes of the joystick(s) on the game controller. The value of this property is ignored by the device driver. The joydev kernel module always returns joystick axis data in the range -32,767 to 32,767 inclusive (in mathematical terms, [-32,767, 32,767]). Using the default value for this property is always safe.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.

In spite of the simplicity of the Linux joystick device config element, there are several caveats and points of caution associated with using joysticks and/or game pads on Linux. The following subsections address various issues that must be kept in mind when setting up a VR Juggler configuration that will make use of the Linux joystick device driver.

The Linux joydev Kernel Module

Before the Linux joystick device driver in Gadgeteer can be used at all, the Linux joydev kernel module must be loaded. Some Linux distributions may not include a pre-compiled version of the kernel module[10], which means that the module must be built from the Linux kernel source. This is not a trivial process, and it can have disastrous results if something goes wrong.

For the benefit of users who find themselves lacking a copy of the Linux joydev kernel module for their kernel, we include instructions here for building the module on an unpatched, uni-processor Red Hat Enterprise Linux 3 installation. The steps may vary with differing Linux distributions and with differing Linux kernel versions.

Caution

Read the following very carefully! These steps will configure and build a new kernel, but only a single module (joydev.o) ultimately gets installed. Nothing else in the kernel installation will be changed. The only difference to the kernel installation after performing these steps is that the file joydev.o will be added to the existing installation.

First, edit line 4 of the file /usr/src/linux-2.4.21-4.EL/Makefile so that it appears as follows:

EXTRAVERSION = -4.EL

Then, the joydev module can be compiled, installed, and loaded using the following steps. Note that the percent character (%) represents the command prompt and should not actually be typed.

% cd /usr/src/linux-2.4.21-4.EL
% make mrproper
% cp configs/kernel-2.4.21-i686.config .config
% make dep
% make
% make modules
% cp drivers/input/joydev.o /lib/modules/2.4.21-4.EL/kernel/drivers/input/joydev.o
% insmod joydev

USB Device Mapping

In order for USB joysticks and game pads to be handled by the joydev kernel module, it is necessary for the USB configuration to identify the devices correctly. Doing so requires that the USB device mapping include the identifiers for the joystick or game pad being used. Modern Linux distributions come with device mappings for a wide variety of devices, but there will always be new products and new models of existing products being released.

First, to determine if a USB joystick or game pad is being handled by the joydev kernel module, look at the contents of /var/log/messages when the device is plugged in. There should be output similar to the following (from a Linux 2.4 kernel):

kernel: input0: USB HID v1.00 Gamepad [...] on usb2:6.0
/etc/hotplug/usb.agent: Setup hid for USB product 6a4/1580/100

If the device is being handled by the joydev kernel module, there will be a second line of output from /etc/hotplug/usb.agent:

/etc/hotplug/usb.agent: Setup joydev for USB product 6a4/1580/100

If that output is not printed, then the USB joystick or game pad is not correctly configured to use the joydev kernel module. In that case, the file /etc/hotplug/usb.handmap must be extended to include the missing information.

Fortunately, the first line of output from /etc/hotplug/usb.agent provides the details we need to do this. In the output, the sequence “6a4/1580/100” provides us with the hexadecimal vendor ID (0x06a4) and the product ID (0x1580). This can also be determined using the graphical application usbview, included with the usbview” package. If usbview is not available, however, the above will work with all Linux distributions.

With the vendor ID and product ID in hand, we can extend /etc/hotplug/usb.handmap with the following line:

joydev 0x0003 0x06a4 0x1580 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000

Here, the vendor ID appears as the second number and the product ID as the third. After making this change, it is not necessary to reboot, but the USB device should be unplugged and plugged back in to ensure that the device is correctly handled by the joydev kernel module.

Analog and Digital Input Sources

The Linux joystick device returns analog and digital data. The number of analog and/or digital proxies to use and the input source indices to use depends on the physical device. The most convenient way we have found to determine the ordering of the buttons and axes on a given joystick is to use the software utilities jstest (included with the joystick” package). Pressing buttons and moving joysticks will result in output being printed to the console or terminal window.

Direct Input Game Controller

  • Driver name: DirectXJoystick_drv

  • Config element type: directx_joystick

  • Interface type: game port or USB

  • Driver availability: Microsoft Windows®

  • Other information: requires DirectX 8.0 or newer

The Direct Input game controller driver for Microsoft Windows® makes use of DirectX to communicate with a wide variety of game controllers. The controllers may be attached to either a USB port or a game port. Essentially, if the device is supported by Direct Input, then the Gadgeteer driver can communicate with it.

This device is not quite as flexible as its Linux counterpart due to fundamental differences between Direct Input and the Linux joydev kernel module (see the section called “Linux Joystick Device”). While the number of digital and analog input sources is determined at run time by querying the game controller device, the driver has the following limitations on the input sources:

  • Zero (0) to thirty-two (32) buttons providing digital input

  • Zero (0) to three (3) joysticks, each providing two analog inputs

  • Zero (0) to two (2) sliders, each providing one analog input

  • Zero (0) to four (4) directional pads (also known as “point-of-view hats”), each providing two analog inputs

The analog inputs provided by a game controller should generally be thought of as axes. As noted above, a single joystick on a game controller provides two analog input sources, meaning that it has two axes (X and Y). More buttons can be defined using a feature of the driver called “axis buttons,” explained in more detail below. Furthermore, the driver could be modified to use an extended feature of Direct Input allowing up to 128 buttons, but the number of possible analog inputs would not increase.

The analog axis numbering depends on the order in which Direct Input reports the existence of a given axis to the Gadgeteer driver. The driver guarantees that the axes will be accessible as a contiguous block with input indices in the range 0 to n (inclusive) for n axes. Determining the axis ordering can become a trial-and-error process, but once the ordering is identified for a given game controller device, it should not have to be changed. Proxy aliases can be used to mask the details of the axis ordering from the VR Juggler application programmer. The full list of configurable properties is shown below:

axis buttons

A variable-valued property that identifies which axes (using zero-based integer identifiers) should be treated as digital buttons. The additional buttons will be appended to the basic set of digital inputs available from the device. This feature is useful with a directional pad to get additional button inputs. The digital buttons are defined in clockwise order starting from north (away from the user).

Note

The analog input from the axis (or axes) will still be available. An “axis button” provides a second interpretation of the received input data.

min

The minimum value returned by the hardware to the driver for the analog axes of the joystick(s) on the game controller. The value of this property is ignored by the device driver. Direct Input allows user code to choose the minimum value for an axis, so the driver sets its own value. Using the default value for this property is always safe.

max

The maximum value returned by the hardware to the driver for the analog axes of the joystick(s) on the game controller. The value of this property is ignored by the device driver. Direct Input allows user code to choose the maximum value for an axis, so the driver sets its own value. Using the default value for this property is always safe.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.



[10] Red Hat Enterprise Linux 3 Workstation is one such distribution that is known to ship without a pre-compiled copy of the joydev module.

Appendix D. Other Device Drivers

In this appendix, we explain how to configure various device drivers that do not exactly fall into the categories of the preceding appendices.

U.S. Digital Serial Encoder

Microsoft Speech API

Microsoft Speech API Command Driver

  • Driver name: MSFTSpeechRecog_drv

  • Config element type: msft_speech_recog_digital

  • Driver availability: Microsoft Windows®

  • Other information: requires Microsoft Speech SDK 5.1

Microsoft Speech API String Driver

  • Driver name: MSFTSpeechRecog_drv

  • Config element type: msft_speech_recog_string

  • Driver availability: Microsoft Windows®

  • Other information: requires Microsoft Speech SDK 5.1

Note

More information about the use of the Microsoft Speech API driver and its use with VR Juggler can be found on the Purdue University Envision Center website and their Wiki.

The Microsoft Speech API driver provides access to the Win32 Speech API (often referred to as “SAPI”) for use as an input device to VR Juggler application objects. Before configuring VR Juggler to use the Win32 SAPI, the Speech API itself must be installed and configured. Please refer to the Microsoft Speech website for more information on that topic.

Once the Win32 SAPI is installed and ready to use, we can configure the Gadgeteer device driver that provides access to it. The Microsoft Speech API driver has two “incarnations”: a command-oriented version and a string-oriented version. It is the first device driver in Gadgeteer to make use of the string and command device types, introduced earlier in the section called “Input Devices”. The choice of which driver to use is up to the person configuring the input devices. As with any driver configuration, it should meet the needs of the VR Juggler applications that are accessing the specific type of input. For example, if an application object is using command-oriented input but not string-oriented input, there would not be a need to configure the string-oriented version of the Microsoft Speech API driver. As we will see, configuring both versions of the driver is very similar, so understanding how to configure one version will form the basis of understanding how to configure the other version.

The list of configurable properties for the string- and command-oriented Microsoft Speech API drivers is shown below. Note that both drivers have the same set of properties. Hence, the distinguishing feature of a configuration of this driver will be the proxy type configured to refer to the input device.

grammar file

A valid path to an XML file containing the Win32 SAPI grammar to be used for interpreting speech input from the user. The creation of this file is up to the author of the VR Juggler application object utilizing string and/or command input. More details on this topic are beyond the scope of this document. Readers are referred to the Microsoft Speech website and to the additional information provided on the Purdue University Envision Center Wiki.

host node

In a cluster configuration, a pointer to the cluster node config element where the device is physically attached. In a non-cluster configuration, this property should have an empty value. Refer to Chapter 4, Configuring a Cluster for more details on cluster configuration and shared input device data.

Once the driver is configured, proxies must be pointed at the appropriate config element. The proxy type to use depends on which version of the driver has been configured. If the command-oriented driver is in use, then the proxy type to use is command proxy (config element type command_proxy). Similarly, if the string-oriented driver is in use, then use string proxies (config element type string_proxy). Both versions of the Microsoft Speech API driver provide exactly one input source, so any proxy(ies) configured to point at the device will always refer to input source zero (0).

Appendix E. Configuration of Miscellaneous Components

In this appendix, we cover specific configuration topics that do not fit in with any of the previous appendices. Readers will notice that the previous appendices dealt with the configuration of specific input devices—a topic that is important to all users of VR Juggler. The parameterization of VR Juggler extends to many other parts of the software, and this is where we cover the configuration of those parts.

VR Juggler Kernel Shutdown

The VR Juggler kernel can be directed to shut itself down through a digital device interface named “VJSystemStopKernel.” When this digital device is toggled on, the kernel tells itself to stop its control loop and return control to the thread that started it. This is the built-in mechanism for shutting down VR Juggler applications cleanly. Of course, application objects can perform their own handling of shutting themselves down, and the route of going through the kernel and “VJSystemStopKernel” need not be followed.

Configuring the digital device interface “VJSystemStopKernel” is just like configuring any other digital device (readers not familiar with configuring input devices should see Chapter 2, Configuring Input for details). Generally, a simulated digital device would be configured to get its input from some keyboard/mouse input handler. Whether this is a graphics window or a plain input window is up to the person creating the configuration. Of course, the flexibility and generality of input handling in VR Juggler allows the digital input to come through a physical device such as a glove gesture or a wand button press. Regardless of the digital device, a digital device proxy must then be created to read from the appropriate device unit. This digital device proxy may be named “VJSystemStopKernel,” or a proxy alias may be created with that name that refers to the digital device proxy. That is all there is to it.

Note

The example VR Juggler configuration files such as sim.base.jconf make this aspect of VR Juggler configuration look much more complicated than it really is. Because they are example files, they show different ways of shutting down VR Juggler, both through the kernel and through a response by the application object. Creators of VR Juggler configurations do not have to follow those complex examples and can safely follow the simple instructions presented here.

Sonix Sound Manager

The Sonix Sound Manager provides a means to access the Sonix module of the Juggler Suite with relatively little effort. While Sonix can be accessed and managed directly from a VR Juggler application object, the Sonix Sound Manager encapsulates most of the code that would have to be written every time Sonix would be utilized. For example, the choice of the audio API, the audio “frame” update, and the registration of sound objects with Sonix are handled the Sonix Sound Manager. In the case of the audio API and the sound objects, the Sonix Sound Manager sets up these features through the standard Juggler run-time configuration. As a result, Sonix can be reconfigured at run time by reconfiguring the Sonix Sound Manager. Handling this sort of feature from a VR Juggler application object is certainly possible, but it would increase the complexity of the application object code. Ultimately, the most important benefit of using the Sonix Sound Manager is that authors of VR Juggler application objects can concentrate on the (relatively simple) use of Sonix sound handle objects and not worry about the other details of accessing Sonix.

Configuring the Sonix Sound Manager requires very little effort. It has only four basic configurable settings:

  1. The sound API to use.

  2. The three-dimensional location of the listener.

  3. A search path for finding audio files.

  4. The list of sound objects to register with Sonix for access by VR Juggler application objects.

These three items correspond to the properties of the Sonix Sound Manager config element (type sound_manager_sonix). Those properties are listed below:

sound API

The string value of this property names the audio backend to be used by Sonix for rendering audio data. Currently, Sonix has five possible audio backends: stub, OpenAL, Audiere, AudioWorks, and Subsynth. Audio backends are implemented as components loaded by Sonix at run time. They are, in other words, plug-ins to Sonix. The choice of which plug-in to use depends on the availability of the plug-in and possible conflicts that may exist with the plug-in and the run-time environment. Below, we provide some more information about each of the Sonix plug-ins to assist in making a decision about which to use.

  • OpenAL is a specification designed to provide a cross-platform sound programming interface akin to OpenGL. Implementations of the OpenAL 1.0 specification are available for Microsoft Windows®, Linux, *BSD, Mac OS X, and IRIX®. However, the implementation of OpenAL for IRIX® makes use of POSIX threads, thereby making it incompatible with the SPROC subsystem in the VR Juggler Portable Runtime. Therefore, OpenAL cannot be used on IRIX® with VR Juggler application objects unless the SPROC build of VR Juggler is being used.

  • Audiere is a simple, cross-platform programming interface for C and C++ programmers that can play a wide variety of audio file formats. Audiere is available on Microsoft Windows®, Linux, and IRIX®. The last release of Audiere (1.9.3) was made in September 2003, and it is unclear if the project is still being maintained. While it is not (yet) as portable as OpenAL, Audiere tends to be more reliable than OpenAL in terms of consistent audio playback across platforms. Similar to OpenAL, Audiere uses POSIX threads and is therefore not compatible with SPROC builds of VR Juggler.

  • Multigen-Paradigm AudioWorks2 is a programming interface for the playback of three-dimensional audio. To date, the Sonix AudioWorks backend has only been tested on IRIX, thus making it the least portable option. Unlike Audiere and OpenAL, AudioWorks only works with SPROC builds of VR Juggler. However, it is unclear if Multigen-Paradigm still provides AudioWorks2 as a product, so the utility of this audio backend for Sonix may be greatly diminished.

  • Subsynth was the master's project of Kevin Meinert, the author of Sonix. As a low-level audio tool, the goals of Subsynth are fairly different than those of OpenAL or Audiere. As of this writing, it has been a long time since the Subsynth plug-in for Sonix was tested last. For that reason, using the Subsynth backend to Sonix is probably not a viable alternative to OpenAL or Audiere.

  • The so-called “stub” plug-in to Sonix is not really a plug-in at all. It is a built-in component that is used as a fall back when no other audio implementation is found at run time. The stub plug-in is useful because it allows applications to access Sonix even when sounds cannot be played, thereby ensuring that the code is portable between different VR system installations. Of course, to get the full intended functionality of the application, sound would be needed, but when that is not possible, the stub plug-in makes it so that users do not have to change their code to deal with this case. In general, this plug-in would not be configured explicitly as the sound API. Instead, it should normally be left up to Sonix to determine when to use this plug-in instead of one of the others.

listener position

The three-dimensional location (X, Y, Z) of the user in the virtual world coordinate space. This location is relative to the user-chosen VR Juggler origin. In many cases, this location will be at the VR Juggler origin.

file search path

A list of zero or more directories to be searched when looking for audio files named by sound object properties. Currently, this property is not used by the Sonix Sound Manager, but this will change in a future release of VR Juggler.

sound object

A list of zero or more sound objects that will be registered with Sonix at run time. The type of this property is an embedded config element, and the allowed config element type is sound. We explain sound objects in more detail next.

Users of Sonix generally utilize “sound handles” to manipulate and play sounds. The configuration of the Sonix Sound Manager includes the definition of zero or more sound objects, and VR Juggler application object authors can get access to these sound objects through Sonix sound handles. The Sonix Sound Manager handles the details of loading the sound data into memory and configuring the sound objects so that users need only declare a Sonix sound handle and initialize it with a unique name. The list of sound objects in the Sonix Sound Manager is made of up config elements of type sound. The name of the embedded config element provides the unique name that will be requested from Sonix by the VR Juggler application object, so each sound object config element given to the Sonix Sound Manager must have a unique name. The configurable properties of the sound object config element type are as follows:

filename

A valid path to the sound file to load.

ambient

A boolean flag indicating whether the sound is ambient.

re-trigglerable

A boolean flag indicating whether the sound can be re-triggered (restarted) while being played.

streaming

A boolean flag indicating whether the sound is streaming. For Audiere, looping sounds must be streaming. Non-streaming sounds in Audiere are treated as one-shot sound effects.

loop

An integer value indicating how many times to loop the sound when it is triggered (played). A value of -1 indicates that the sound should loop infinitely. For Audiere, a sound must be configured as streaming in order to be looped. The default value is 1, indicating the sound should be played once each time it is triggered.

pitch bend

A floating-point value that changes the pitch of the sound. Valid values are in the range [0,n) where 1.0 is the normal pitch of the sound, 2.0 doubles the pitch of the sound, and 0.5 halves the pitch of the sound. The default value is 1.0.

cutoff

A floating-point value that changes the low-pass filter cutoff for the sound. Values must be in the range [0.0,1.0]. The default value is 1.0.

volume

A floating-point value that changes the volume for the sound. Values must be in the range [0.0,1.0]. The default value is 1.0 (full volume).

position

A set of floating-point values (X, Y, and Z) specifying the location of the sound in the virtual world coordinate space.

Appendix F. VRJConfig Custom Editors by Infiscape

In this appendix, we present an overview of the custom editors for VRJConfig, the VR Juggler configuration editor, that have been written by Infiscape Corporation and donated to the VR Juggler project. Custom editors are accessed through the VRJConfig Control Panel. They are usually designed to act as standalone editors (capable of editing one config element or a collection of config elements depending on the usage) or as part of a wizard that assists with the creation of a new configuration.

Display Window Editor

The Display Window Editor was first demonstrated at the annual VR Juggler Birds of a Feather meeting at SIGGRAPH 2004. As its name suggests, the Display Window Editor is designed to edit display window configuration elements and the viewports contained with display windows. The interface is very high level and is designed to mimic the traditional desktop computer interface. Windows may be repositioned and resized within the managed area using the mouse, and they can be made full screen or removed from the configuration with a single click. Within the windows, surface and simulator viewports may be placed and resized by dragging them.

An example of the Display Window Editor is shown in Figure F.1, “Display Window Editor: Simulator Viewport”. When accessed as an editor for a display window config element, this editor only allows editing of that single config element. In this figure, we have a display window containing a single simulator viewport that occupies the full area of the display window. The window frame may be moved around the (virtual) desktop area, and it may be resized by dragging the edges or corners of the window frame[11].

Figure F.1. Display Window Editor: Simulator Viewport

Display Window Editor: Simulator Viewport

A powerful feature of the Display Window Editor is the ability to manipulate the viewports contained within the display window. In Figure F.2, “Display Window Editor: Viewport Resizing”, we see that the viewport has been shrunk down to be roughly 25% of the overall display window area. This is accomplished by selecting the viewport within the window frame and dragging it to resize it. The editor makes sure that the viewport configuration is always valid, meaning that it can never be larger than 100% of the display window area, and its boundaries are always within the border of the display window area. Once the viewport is made smaller than the total display window area, the viewport can be dragged around within the display window to change its location.

Figure F.2. Display Window Editor: Viewport Resizing

Display Window Editor: Viewport Resizing

Right-clicking on the display window displays the context menu shown in Figure F.3, “Display Window Editor: Window/Viewport Menu”. This menu allows for quick editing of simple properties of the display window and the selected viewport (if one is currently selected). Choosing one of the Properties items at the bottom of the menu opens a dialog that provides an interface for editing other properties of the viewport or the display window. The display window properties dialog is shown in Figure F.4, “Display Window Editor: Display Window Properties Dialog”.

Figure F.3. Display Window Editor: Window/Viewport Menu

Display Window Editor: Window/Viewport Menu

Figure F.4. Display Window Editor: Display Window Properties Dialog

Display Window Editor: Display Window Properties Dialog

In addition to making it easy to resize and move viewports within a display window, the Display Window Editor simplifies the process of adding (and removing) simulator and surface viewports. Adding a simulator viewport is quite simple, and the dialog box for creating and adding a new simulator viewport is shown in Figure F.5, “Display Window Editor: Simulator Viewport Add/Edit Dialog”. The origin and size spinners are constrained so that it is impossible to create a viewport that extends beyond the boundaries of the display window frame. The origin and size settings for the viewport are specified as percentages which reflects that the viewport occupies a fractional portion of the display window area. Setting values for the user, the camera position proxy, and the wand position proxy requires that the correct config element already exist. They cannot be added through this dialog.

Note

The dialog boxes used for adding new simulator and surface viewports are the same dialog boxes used to edit the properties of a selected viewport. When right-clicking on a viewport and selecting Viewport Properties..., the appropriate viewport properties dialog shown below will be opened.

Figure F.5. Display Window Editor: Simulator Viewport Add/Edit Dialog

Display Window Editor: Simulator Viewport Add/Edit Dialog

Surface viewports are more complicated than simulator viewports because the corners of the projection surface must be defined. The dialog box for adding (and editing) surface viewports within a display window is shown in Figure F.5, “Display Window Editor: Simulator Viewport Add/Edit Dialog”. Similar to the simulator viewport dialog shown above, the origin and size of the viewport are constrained so that the viewport will always be within the bounds of the display window.

Figure F.6. Display Window Editor: Surface Viewport Add/Edit Dialog

Display Window Editor: Surface Viewport Add/Edit Dialog

In the VRJConfig Configuration Editor, setting these corners requires entering twelve values (X-, Y-, and Z-coordinates for each of four corners). In many cases, users must calculate one or more of the corner locations based on the dimensions of the projection surface and the known location of a specific corner. Through the Display Window Editor, users must only enter the location of one corner for a given surface viewport, even in the case of projection surfaces that are not oriented at 90° angles.

In Figure F.7, “Display Window Editor: Surface Orientation”, we see the user choosing the orientation of the projection surface to which the new viewport will correspond. There are six pre-defined orientations corresponding to the sides of a cube. The seventh orientation allows the user to fill in a custom rotation about the X-, Y-, and Z-axes. The angles of rotation are entered in degrees. After choosing an orientation, the location of a single corner of the projection surface is entered. This corner must be one that is known based on its location relative to the Juggler origin. Finally, the surface width and height are entered. With this information, the editor can compute the remaining three corners to be entered for the full configuration of the surface viewport. The fully configured surface viewport is shown in Figure F.8, “Display Window Editor: Surface Viewport Configured”.

Important

Remember that projection surface location and orientation parameters are entered relative to the user-defined origin of the virtual world. Furthermore, the coordinate frame for the surface projection uses the Juggler coordinate frame, a right-handed system with Y up. The iconic representations of the pre-defined orientations show the location of the surface relative to the user who is facing down the negative Z-axis when looking forward.

Figure F.7. Display Window Editor: Surface Orientation

Display Window Editor: Surface Orientation

Figure F.8. Display Window Editor: Surface Viewport Configured

Display Window Editor: Surface Viewport Configured

The Display Window Editor supports management of an arbitrary number of simulator and surface viewports within a single display window. In Figure F.9, “Display Window Editor: Multiple Viewports”, we see the result of modifying the original display window configuration by resizing and repositioning the original single simulator viewport and adding a surface viewport and a second simulator viewport.

Figure F.9. Display Window Editor: Multiple Viewports

Display Window Editor: Multiple Viewports

Flock of Birds® Editor

The Flock of Birds® Editor makes use of shared editor components designed to simplify the process of setting up a positional tracker for use with VR Juggler. Generally, entering the basic hardware settings (serial port name, tracked hemisphere, etc.) for any positional tracker is easy. The complexity arises in configuring the position transform filter that describes the position and orientation of the tracker coordinate frame relative to the Juggler coordinate frame. Looking at Figure F.10, “Flock of Birds® Editor: Transmitter Settings” and Figure F.11, “Flock of Birds® Editor: Sensor Settings”, we see that the “meat” of this custom editor is in the lower half of the window where the transmitter and sensor settings are configured.

For the transmitter settings, the first setting is to fill in the units being returned by the hardware. For a Flock of Birds®, this value should always be “Feet”. Next, we see that the Juggler coordinate frame is presented next to the coordinate frame of the Flock of Birds® transmitter. A list of possible rotations (24 in total) for both coordinate frames are presented. The computation for filling in the pre-translation settings for the position transform filter is done behind the scenes to relieve the user of a mentally complex and error-prone task. When none of the provided coordinate frame rotations matches the rotation of the sensor, users can select the Manual Entry button and enter the values directly. Finally, we must set the location of the transmitter relative to the user-chosen Juggler origin. To relieve users of having to perform manual conversions, the physical units to be entered can be chosen using the pull-down menu labeled Measurement Units.

Note

In the current version of this custom editor, changing the Juggler coordinate frame has no effect. This will be rectified in a future release.

Figure F.10. Flock of Birds® Editor: Transmitter Settings

Flock of Birds Editor: Transmitter Settings

After setting up the transmitter, we must configure each of the sensors. These settings are found under the Sensors tab. This panel provides a high-level interface to configuring device proxies and proxy aliases. As with the transmitter configuration panel, the focus is on hiding the complexity of the position transform filter associated with each positional proxy. As can be seen in Figure F.11, “Flock of Birds® Editor: Sensor Settings”, the interface is very similar to that used for editing the position transform filter of the transmitter, so we will not repeat the full explanation here.

Note

In the current version of this custom editor, changing the Juggler coordinate frame has no effect. This will be rectified in a future release.

Figure F.11. Flock of Birds® Editor: Sensor Settings

Flock of Birds Editor: Sensor Settings

One common problem encountered by inexperienced users is what name to use for the serial port. In general, it is expected that users configuring hardware know how the hardware is wired into the computer, but to assist with this common problem this custom editor provides serial port name “templates” for several different operating systems. In Figure F.12, “Flock of Birds® Editor: Serial Port Settings”, we see that the current value is /dev/ttyd3, which is most likely an IRIX® serial port name. The list of templates has the roots of serial port names seen on IRIX®, Microsoft Windows®, Linux, and Solaris™. Because the pull-down menu is editable, users may enter whatever they need for the serial port name.

Figure F.12. Flock of Birds® Editor: Serial Port Settings

Flock of Birds Editor: Serial Port Settings

MotionStar Wireless® Editor

The MotionStar Wireless® Editor makes use of shared editor components designed to simplify the process of setting up a positional tracker for use with VR Juggler. The user interface is very similar to that of the Flock of Birds® Editor because the two share editing components. Generally, entering the basic hardware settings (chassis host name, tracked hemisphere, etc.) for a MotionStar Wireless® tracker is easy. The complexity arises in configuring the position transform filter that describes the position and orientation of the tracker coordinate frame relative to the Juggler coordinate frame. Looking at Figure F.13, “MotionStar Wireless® Editor: Transmitter Settings” and Figure F.14, “MotionStar Wireless® Editor: Sensor Settings”, we see that the bulk of this custom editor is in the lower half of the window where the transmitter and sensor settings are configured, just as was the case with the Flock of Birds® Editor. Refer back to the section called “Flock of Birds® Editor” for information about how to use the components in the tabs labeled Transmitter and Sensors.

Figure F.13. MotionStar Wireless® Editor: Transmitter Settings

MotionStar Wireless Editor: Transmitter Settings

Figure F.14. MotionStar Wireless® Editor: Sensor Settings

MotionStar Wireless Editor: Sensor Settings

Device Proxy Editor

The Device Proxy Editor provides an interface for visualizing and modifying the relationships between input devices and the device proxies that are accessed by VR Juggler application programmers. Conceptually, proxies point to input devices, and thus, a natural interface is that of a graph with vertices and edges. The vertices represent input devices and device proxies, and the edges represent the (one-way) connection between the two. Configuring this can be quite challenging because the low-level VRJConfig Configuration Editor concentrates on a single config element at a time, and keeping track of the relationships between multiple config elements requires a lot of mental overhead.

The Device Proxy Editor is designed to reduce the mental overhead of configuring the relationships between input devices and device proxies. Depending on how it is accessed, all the devices and proxies present in a configuration will be displayed, or a single proxy will be the focus of the editor. The editor itself is based on JGraph 5.4, and it takes advantage of the graph rendering and editing capabilities provided by that software. For example, in , we see an example of a Flock of Birds® device with two sensors represented by two positional proxies named “HeadProxy” and “WandProxy”.

Figure F.15. Device Proxy Editor: Single Positional Device

Device Proxy Editor: Single Positional Device

Each proxy points at a specific input source (unit) of the device. These pointers can be changed by selecting the pointer and moving it. If necessary, the connection between the proxy and the device can be severed entirely. Conversely, new connections can be created by changing to connection mode, selecting the proxy, and dragging a connection to the desired input source. This process is shown in Figure F.16, “Proxy Editor: Creating a New Proxy/Device Connection (Step 1)”, Figure F.17, “Proxy Editor: Creating a New Proxy/Device Connection (Step 2)”, and Figure F.18, “Proxy Editor: Creating a New Proxy/Device Connection (Step 3)”.

Figure F.16. Proxy Editor: Creating a New Proxy/Device Connection (Step 1)

Proxy Editor: Creating a New Proxy/Device Connection (Step 1)

Figure F.17. Proxy Editor: Creating a New Proxy/Device Connection (Step 2)

Proxy Editor: Creating a New Proxy/Device Connection (Step 2)

Figure F.18. Proxy Editor: Creating a New Proxy/Device Connection (Step 3)

Proxy Editor: Creating a New Proxy/Device Connection (Step 3)

Many input devices support a variable number of input sources (and a variable number of input types). The Proxy Editor makes it easy to add and remove input sources for a given device. For example, in Figure F.19, “Proxy Editor: Adding Positional Units”, we see how three more positional input sources have been added to the “Flock” device by clicking the button Create Position Input Source. Further, we see that “HeadProxy” has been changed to point at the fourth positional input source. Removing input sources is achieved by clicking the trash can icon to the right of the label for the input source that will be removed.

Note

The Proxy Editor keeps track of the input source indexing during additions and removals. Device proxies are updated automatically when such changes occur and require no further action on the part of the user.

Figure F.19. Proxy Editor: Adding Positional Units

Proxy Editor: Adding Positional Units

Proxy aliases are a useful feature for VR Juggler application programmers. It allows them to write their applications to reference abstract device names such as “Accelerate Button”, “Stop Button”, “Head Position”, etc. Proxy aliases are simply alternate names for device proxies, and it is important that this relationship be displayed when editing device proxies. To avoid cluttering up the graph, the aliases for a given proxy are displayed as part of the node for that proxy. Aliases can be added and removed from each proxy, and aliases can be reassociated with different proxies. For example, in Figure F.20, “Proxy Editor: Adding a Proxy Alias”, we see that a new alias “Pointer” has been added to “WandProxy” by clicking the button Create Alias. If this alias needs to be reassociated with a different proxy, the scissors button is clicked to move the alias to the clipboard. Upon doing so, the Paste Alias button will be enabled for all proxy nodes. Clicking that button in a proxy node will associate the alias with that proxy, and all the Paste Alias buttons will become disabled again. (This is done to prevent configuration errors.) We can see the result of this operation in Figure F.21, “Proxy Editor: Reassociating a Proxy Alias”.

Figure F.20. Proxy Editor: Adding a Proxy Alias

Proxy Editor: Adding a Proxy Alias

Figure F.21. Proxy Editor: Reassociating a Proxy Alias

Proxy Editor: Reassociating a Proxy Alias

As noted above, there are devices that support multiple input sources and multiple types of input. An example of this is the Intersense API driver, and the configuration of this device and its proxies is shown in Figure F.22, “Proxy Editor: Multi-Type Input Devices”. This device type supports positional, digital, and analog data. As with the case of a device that has only a single type of input data, the indexing of the different types of input sources is handled automatically by the Proxy Editor. In Figure F.23, “Proxy Editor: Adding a Digital Input Source”, we see that a new digital input source has been added to Station 1, and in Figure F.24, “Proxy Editor: Adding Another Digital Input Source”, we see that another digital input source has been added to Station 0. Note that the digital input source numbering has been updated accordingly.

Figure F.22. Proxy Editor: Multi-Type Input Devices

Proxy Editor: Multi-Type Input Devices

Figure F.23. Proxy Editor: Adding a Digital Input Source

Proxy Editor: Adding a Digital Input Source

Figure F.24. Proxy Editor: Adding Another Digital Input Source

Proxy Editor: Adding Another Digital Input Source

Simulator Editor

The Simulator Editor combines the Display Window Editor (see the section called “Display Window Editor”) and the Device Proxy Editor (see the section called “Device Proxy Editor”). As we can see in Figure F.25, “Simulator Editor: Single Window Simulator”, the Simulator Editor can look very much like the Display Window Editor. This example shows the simulator configuration found in $VJ_BASE_DIR/share/vrjuggler/data/configFiles/standalone.jconf. However, note that there is a previously unseen button labeled Edit Simulator Input Settings in the display window frame. Further, we see that the Display and Input Window buttons are now enabled. (In the Display Window Editor, these are always disabled because the Display Window always edits a single display_window config element.)

Figure F.25. Simulator Editor: Single Window Simulator

Simulator Editor: Single Window Simulator

A more illustrative example of the Simulator Editor in action is shown in Figure F.26, “Simulator Editor: Multi-Window Simulator” where the files $VJ_BASE_DIR/share/vrjuggler/data/configFiles/sim.base.jconf and $VJ_BASE_DIR/share/vrjuggler/data/configFiles/sim.wand.mixin.jconf have been loaded. Note that only certain frames in this figure have the button labeled Edit Simulator Input Settings. This button only appears with windows that are configured to feed keyboard and mouse events to a keyboard/mouse input handler.

Important

The ability to edit the keyboard/mouse input handler pointer for display and input windows is limited with this editor. When a simulator configuration is opened in this editor, it is assumed that the relationship between windows and keyboard/mouse input handlers has already been set up, either using a wizard, a different custom editor, or the VRJConfig Configuration Editor. The focus of this editor is the windows and the simulated devices, not the low-level details about how keyboard and mouse events are managed. It is possible to change which keyboard/mouse input handler a given window feeds, but it is not possible to add or remove keyboard/mouse input handlers with this editor.

Figure F.26. Simulator Editor: Multi-Window Simulator

Simulator Editor: Multi-Window Simulator

By clicking on one of the Edit Simulator Input Settings buttons, we can edit the simulated devices that receive input from the selected display or input window. Doing so will open a dialog similar to that seen in Figure F.27, “Simulator Editor: Simulated Analog Devices”. This dialog shows all the simulated devices associated with the keyboard/mouse input handler that the display or input window feeds. Through this dialog, we can edit the keyboard and mouse bindings that are interpreted by the simulated devices as well as the proxies associated with each of those devices. Currently, simulated analog devices (see Figure F.27, “Simulator Editor: Simulated Analog Devices”), simulated digital devices (see Figure F.28, “Simulator Editor: Simulated Digital Devices”), and simulated positional devices (see Figure F.29, “Simulator Editor: Simulated Positional Devices”) are supported by this dialog.

Figure F.27. Simulator Editor: Simulated Analog Devices

Simulator Editor: Simulated Analog Devices

Figure F.28. Simulator Editor: Simulated Digital Devices

Simulator Editor: Simulated Digital Devices

Figure F.29. Simulator Editor: Simulated Positional Devices

Simulator Editor: Simulated Positional Devices

The dialog box for editing keyboard and mouse bindings for simulated devices provides on-the-fly detection of errors when changing the settings. For example, when editing a simulated digital device, the user may accidentally select the same bindings for two input sources of the device. In that case, the error will be highlighted to draw the user's attention to it. An example of this is shown in Figure F.30, “Simulator Editor: On-the-Fly Error Detection”.

Figure F.30. Simulator Editor: On-the-Fly Error Detection

Simulator Editor: On-the-Fly Error Detection

Clicking the Advanced tab will present a view similar to that shown in Figure F.31, “Simulator Editor: Advanced Simulated Device View”. This view makes use of the exact same interface as the Device Proxy Editor to show the full relationship between simulated devices, device proxies, and keyboard/mouse input handlers. In this figure, we see that there are three keyboard/mouse input handlers (“Wand Keyboard”, “Sim View Camera Controls”, and “Head Keyboard”), and we can see how everything ultimately points at those nodes.

Figure F.31. Simulator Editor: Advanced Simulated Device View

Simulator Editor: Advanced Simulated Device View



[11] Be aware that this editor makes use of internal frames, so when we refer to the “window frame,” we mean that of the internal window on the virtual desktop, not the frame of the custom editor dialog box.

Appendix G. File Format Specifications

In this appendix, we will explain the details of the two configuration file types: config definition files (those ending with the extension .jdef) and config files (those ending with the extension .jconf).

Config Definition Files

Refer to Chapter 6, Config Definition Editing for a high-level description of the format of config definition files.

Config Files

Appendix H. GNU Free Documentation License

Version 1.2, November 2002

FSF Copyright note

Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

PREAMBLE

The purpose of this License is to make a manual, textbook, or other functional and useful document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

APPLICABILITY AND DEFINITIONS

This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.

A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.

A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not "Transparent" is called "Opaque".

Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.

The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.

A section "Entitled XYZ" means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as "Acknowledgements", "Dedications", "Endorsements", or "History".) To "Preserve the Title" of such a section when you modify the Document means that it remains a section "Entitled XYZ" according to this definition.

The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.

VERBATIM COPYING

You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and you may publicly display copies.

COPYING IN QUANTITY

If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

MODIFICATIONS

You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

GNU FDL Modification Conditions

  1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
  2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
  3. State on the Title page the name of the publisher of the Modified Version, as the publisher.
  4. Preserve all the copyright notices of the Document.
  5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
  6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
  7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
  8. Include an unaltered copy of this License.
  9. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
  10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
  11. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
  12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
  13. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version.
  14. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section.
  15. Preserve any Warranty Disclaimers.

If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.

You may add a section Entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

COMBINING DOCUMENTS

You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.

The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

In the combination, you must combine any sections Entitled "History" in the various original documents, forming one section Entitled "History"; likewise combine any sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled "Endorsements".

COLLECTIONS OF DOCUMENTS

You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

AGGREGATION WITH INDEPENDENT WORKS

A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an "aggregate" if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

TRANSLATION

Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.

If a section in the Document is Entitled "Acknowledgements", "Dedications", or "History", the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

TERMINATION

You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

FUTURE REVISIONS OF THIS LICENSE

The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.

Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.

ADDENDUM: How to use this License for your documents

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

Sample Invariant Sections list

Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the "with...Texts." line with this:

Sample Invariant Sections list

with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.

Glossary of Terms

C

Common Object Request Broker Architecture (CORBA)

A cross-platform, cross-language standard for distributed programming.

configuration

In the scope of VR Juggler and VRJConfig, a configuration is a collection of config elements that provide a complete para

configuration context

Within the VRJConfig Configuration Editor, a single internal window providing a view of many config elements that make up a complete configuration.

configuration definition (config definition)

The description of the structure of a configuration element.

configuration element (config element)

The fundamental unit of configuration within VR Juggler. Config elements are composed of properties and are processed at run-time by configurable entities within VR Juggler.

config element handler

An object that can process one or more configuration element types. In C++ terms, this is an instance of a C++ class that implements the interface defined by the abstract class jccl::ConfigElementHandler.

D

device driver

A piece of software that communicates with some hardware through a well-defined protocol. A device driver typically translates the information received from the hardware into data that is more easily handled by the software that accesses the driver.

display window

See graphics window.

double buffering

dynamically loadable library (DLL)

Compiled (i.e., binary) code that can be added to other compiled code on the fly. This may be done either by the run-time loader when handling shared libraries, or it may be done by the code itself to handle the loading of extensions.

dynamic shared object (DSO)

Another name for DLL.

E

event source

In Gadgeteer, an abstract term referring to a desktop window (either a plain, empty input window or a graphics window) that feeds keyboard and mouse input data into a Gadgeteer keyboard/mouse input handler. Event sources only have relevance within the scope of configuring VR Juggler and are not accessed directly by VR Juggler applications.

G

graphics cluster

A collection of computers with high-performance graphics cards connected for the purpose of rendering real-time three-dimensional images. Generally, a graphics cluster is composed of low-cost, commodity computers with off-the-shelf hardware as an alternative to a single shared memory supercomputer with multiple high-performance graphics pipes.

graphics window

A desktop window configured to allow hardware-accelerated monoscopic or stereoscopic rendering of a three-dimensional scene. The actual window type is tied to the native windowing system (e.g., Win32 or the X Window System).

I

input window

A plain desktop window that displays nothing. The actual window type is tied to the native windowing system (e.g., Win32 or the X Window System).

K

kernel module

An optional component that can be loaded into the operating system kernel on the fly after the operating system has been booted. In terms of the Linux kernel (and some other open source operating systems), kernel modules can be compiled directly into the kernel, or they may be loaded as modules at run time. In either case, modules usually server to extend the basic feature set of the kernel. In this document, we usually use “kernel module” as a short form of “Linux kernel module.

keyboard/mouse input handler

In Gadgeteer, a device type that receives keyboard and mouse activity (key presses, key releases, mouse motion, button clicks, etc.) from the native windowing system (Win32, the X Window System, Aqua, etc.) and translates it into cross-platform events. These events will be reinterpreted internally by Gadgeteer and/or delivered to VR Juggler applications for application-specific handling.

P

property

In the context of the VR Juggler configuration system, a property represents a subcomponent of a configuration element. In other words, configuration elements are composed of properties. Each property has a type and either a fixed or a variable number of values of that type. These values provide the settings utilized by parameterized (configurable) components within VR Juggler.

S

serial port

U

universal serial bus (USB)

USB port

V

virtual platform

An abstraction layer for immersive systems that hides the details of the immersive visualization hardware. It serves as a means to separate an immersive application from the hardware on which the application is run.

W

windowing system

Software that manages the creation, use, and removal of windows in a graphical desktop such as is used by Microsoft Windows®, UNIX, and the Mac OS. Specific examples of windowing systems are Win32, the X Window System (also known as X11), and Aqua.

X

XML

The eXtensible Markup Language (XML) is a highly flexible way to mark up text and data. See the XML website and the XML 1.0 Specification for more details.

XML Schema

XSL

The eXtensible Stylesheet Language (XSL) is ... See the XSL website for more details.

XSL Transformations (XSLT)

Programs written in XML with the sole purpose of translating XML input into some other format (including XML). See the XSL website and the XSLT 1.0 Specification for more details.

Index

A

application-specific shared data
configurable properties, Application Data Manager, Application Data Manager
audio
Sonix Sound Manager, Sonix Sound Manager, Sonix Sound Manager
configurable properties, Sonix Sound Manager, Sonix Sound Manager

C

cluster manager
configurable properties, Cluster Manager, Cluster Manager
cluster node
configurable properties, Cluster Nodes, Cluster Nodes
display system, Cluster Nodes, Cluster Nodes
display window list, Cluster Nodes, Cluster Nodes
host name setting, Cluster Nodes, Cluster Nodes
listen port choice, Cluster Nodes, Cluster Nodes
config definition search path
extending, Config Definition Editing
config definitions (see configuration definitions)
config element handler, Run-Time Reconfiguration
config elements (see configuration elements)
configuration contract, The Purpose of VRJConfig
configuration definitions, Configuration Elements
abstract, Abstract Config Definitions, Abstract Config Definitions
basic structure, Config Definition Files
categories, Categories, Categories
definition version, Definition Version, Definition Version
label attribute, Definition Version
ordering, Definition Version
version attribute, Definition Version
file format version, File Format Version, File Format Version
help text, Config Definition Help Text, Config Definition Help Text
introduction, Introduction to Config Definitions, Config Definitions and XML Schema
parents, Config Definition Parents, Config Definition Parents
property definition, Property Definitions, Allowed Types for Embedded Config Elements and Config Element Pointers
(see also property definitions)
relationship to XML Schema, Config Definitions and XML Schema, Config Definitions and XML Schema
root document attributes, Root Document Attributes, Root Document Attributes
icon_path, Root Document Attributes
name, Root Document Attributes
xmlns, Root Document Attributes
xmlns:xsi, Root Document Attributes
xsi:schemaLocation, Root Document Attributes
upgrade transforms, Upgrade Transforms, Upgrade Transforms
upgrading, Versioning and Automatic Upgrading, Versioning and Automatic Upgrading
versioning, Versioning and Automatic Upgrading, Versioning and Automatic Upgrading
XHTML, Config Definition Files, Config Definition Help Text
XML namespaces, Config Definition Editing
XML Schema, Config Definition Editing
XSLT, Config Definition Editing, Config Definition Files
configuration elements, Parameterization of Components
using environment variables in property value strings, Driver Search Path, Driver Search Path
Configuration Manager, Run-Time Reconfiguration
active list, Run-Time Reconfiguration
config element processing algorithm, Run-Time Reconfiguration, Run-Time Reconfiguration
incoming list, Run-Time Reconfiguration
pending list, Run-Time Reconfiguration
stale, Run-Time Reconfiguration
CORBA remote run-time reconfiguration
configurable properties, Preparing VR Juggler for Remote Run-Time Reconfiguration, Preparing VR Juggler for Remote Run-Time Reconfiguration

D

device configuration
5DT Data Glove, 5DT Data Glove, 5DT Data Glove
configurable properties, 5DT Data Glove, 5DT Data Glove
Ascension Flock of Birds, Ascension Flock of Birds®, Ascension Flock of Birds®
configurable properties, Ascension Flock of Birds®, Ascension Flock of Birds®
Ascension MotionStar Wireless, Ascension MotionStar Wireless® 2, Ascension MotionStar Wireless® 2
configurable properties, Ascension MotionStar Wireless® 2, Ascension MotionStar Wireless® 2
multi-pack configuration, Ascension MotionStar Wireless® 2
Ascension Wanda, Ascension Wanda®, Ascension Wanda®
configurable properties, Ascension Wanda®, Ascension Wanda®
Direct Input game controller, Direct Input Game Controller, Direct Input Game Controller
configurable properties, Direct Input Game Controller, Direct Input Game Controller
Fakespace Pinch Glove, Fakespace Pinch™ Gloves, Fakespace Pinch™ Gloves
configurable properties, Fakespace Pinch™ Gloves, Fakespace Pinch™ Gloves
Immersion CyberGlove, Immersion CyberGlove®, Immersion CyberGlove®
Immersion Interface Box, Immersion Interface Box, Immersion Interface Box
configurable properties, Immersion Interface Box, Immersion Interface Box
InterSense API, InterSense API and InterSense IS-900™, Configuring InterSense Stations
configurable properties, InterSense API Configuration Aspects, InterSense API Configuration Aspects
station configurable properties, Configuring InterSense Stations, Configuring InterSense Stations
InterSense IS-900, InterSense API and InterSense IS-900™, Configuring InterSense Stations
configurable properties, IS-900™ Configuration Aspects, IS-900™ Configuration Aspects
station configurable properties, Configuring InterSense Stations, Configuring InterSense Stations
Linux joystick, Linux Joystick Device, Analog and Digital Input Sources
configurable properties, Linux Joystick Device, Linux Joystick Device
Microsoft Speech API, Microsoft Speech API, Microsoft Speech API
configurable properties, Microsoft Speech API, Microsoft Speech API
Polhemus Fastrak, Polhemus Fastrak®, Polhemus Fastrak®
VRCO Trackd controller, VRCO Trackd® and trackdAPI Controller, VRCO Trackd® and trackdAPI Controller
VRCO Trackd Sensor, VRCO Trackd® and trackdAPI Sensor, VRCO Trackd® and trackdAPI Sensor
VRCO trackdAPI controller, VRCO Trackd® and trackdAPI Controller, VRCO Trackd® and trackdAPI Controller
VRCO trackdAPI Sensor, VRCO Trackd® and trackdAPI Sensor
VRPN, VRPN, VRPN
configurable properties, VRPN, VRPN
Display Manager (see display system)
display system, The Display Manager, The Display Manager
configurable properties, The Display Manager, The Display Manager
display window, Display Windows, Display Windows
as event source, Graphics Window Input, Graphics Window Input
configurable properties, Display Windows, Display Windows, Graphics Window Input, Graphics Window Input
OpenGL frame buffer (see OpenGL frame buffer)
simulator viewport
configurable properties, Viewports, Simulator Viewports, Simulator Viewports, Multiple Viewports in a Single Window, Multiple Viewports in a Single Window
surface viewport
configurable properties, Viewports, Viewports, Surface Viewports, Multiple Viewports in a Single Window, Multiple Viewports in a Single Window
viewports, Viewports, Multiple Viewports in a Single Window
common configurable properties, Viewports, Multiple Viewports in a Single Window, Multiple Viewports in a Single Window
comparison with VR Juggler 1.0 display types, Viewports, Viewports
simulator, Simulator Viewports, Simulator Viewports
surface, Surface Viewports, Surface Viewports

E

environment variables
JCCL_DEFINITION_PATH, Config Definition Editing
event source
configurable properties, Input Windows, Input Windows

J

JCCL, Introduction, The Purpose of VRJConfig
jdef files (see configuration definitions)

K

kernel
shutdown configuration, VR Juggler Kernel Shutdown, VR Juggler Kernel Shutdown
keyboard/mouse input handler
as data source for simulator devices, Keyboard/Mouse Input Handlers, Keyboard/Mouse Input Handlers
as data source for VR Juggler application objects, Keyboard/Mouse Input Handlers, Keyboard/Mouse Input Handlers

M

machine-specific (see cluster node)

O

OpenGL frame buffer
configurable properties, The OpenGL Frame Buffer, The OpenGL Frame Buffer
origin (see virtual world origin)

R

remote run-time reconfiguration (see CORBA remote run-time reconfiguration)
run-time reconfiguration, Remote Run-Time Reconfiguration Using VRJConfig
(see also CORBA remote run-time reconfiguration)

S

simulator device
analog, Simulated Analog Devices, Simulated Analog Devices
configurable properties, Simulated Analog Devices, Simulated Analog Devices
digital, Simulated Digital Devices, Simulated Digital Devices
configurable properties, Simulated Digital Devices, Simulated Digital Devices
digital glove, Simulated Digital Glove Devices, Simulated Digital Glove Devices
configurable properties, Simulated Digital Glove Devices, Simulated Digital Glove Devices
gesture, Simulated Glove Gesture Devices, Simulated Glove Gesture Devices
positional, Simulated Positional Devices, Simulated Positional Devices
configurable properties, Simulated Positional Devices, Simulated Positional Devices
simulator display (see display window)
simulator plug-in
architecture, Simulator Viewports, Simulator Viewports
default, Simulator Viewports, Simulator Viewports
configurable properties, Simulator Viewports, Simulator Viewports
simulator viewport (see display window)
Sonix, Sonix Sound Manager
(see also audio)
stale pending list, Run-Time Reconfiguration
surface display (see display window)
surface viewport (see display window)

T

tracker
configuration (see device configuration)
tracking system
transmitter placement configuration, Defining the Transmitter Position and Orientation, Defining the Transmitter Position and Orientation
Tweek, VRJConfig