Skip to content

The JSON File (Lighthouse Devices)

Nathan Nuber edited this page Jul 29, 2022 · 4 revisions

Note: This page is a transplant of the render model documentation that was originally available to lighthouse hardware vendors. It covers the process to create the JSON file that describes hardware configuration and calibration to the lighthouse driver.

The JSON File

SteamVR™ Tracking

Introduction

Each tracked object in the SteamVR™ Tracking system contains a file that describes its sensor geometry and other important data about the device. This file is written using the JSON file format. Although many files use the JSON format, the file stored in the tracked object is so integral to the development and performance of the object that it receives the title “The JSON File.” The JSON file begins its life with a minimum of sensor positions and orientations, but is augmented throughout the design and integration process to include IMU data, lens distortion data, and other metadata used by SteamVR™. Finally, calibration routines refine the original sensor geometry values to the exact sensor locations on a specific object and rewrite the JSON file, resulting in a unique JSON file for every tracked object.

This document describes all of the variables that may be stored in the JSON file, what they mean, and how to specify them. This document is referenced from other documents that describe various steps in the design process. To understand when, why, and how each variable is added to the JSON file, follow the process outlined in the Object Design and Integration Overview​.

JSON Format

JSON stands for JavaScript Object Notation, and refers to a lightweight data-interchange format. Data-interchange formats are means of formatting data to share between different computing platforms and, sometimes, human readers. A complete description of the JSON format is available at www.json.org. Because the JSON file represents a JSON object, it opens with a brace { and closes with a brace }. The different members stored in the JSON file are stored as pairs, which are delimited using commas. Each pair is identified by a string that is separated from its value by a colon, “name” : value. Valid members of the tracked object JSON file are described below, and a complete JSON file is presented at the end of the document as an example.

Tip: Free source code editors like Notepad++ understand the JSON format and provide convenience features like syntax highlighting and code folding.

JSON Members

“manufacturer”

A string value representing the manufacturer’s company name.

Example:

"manufacturer" : "Valve

“model_number” A string value representing the model number of the object, assigned by the manufacturer.

Example:

"model_number" : "REF-HMD"

“device_class”

A string value that may be set to “hmd” or “controller” Setting the device_class to “controller” tells SteamVR™ to render the object in VR. Setting the value to “hmd” tells SteamVR™ to associate the tracked object with the binocular display and use the pose of the object as the point of view into virtual reality.

Example:

"device_class" : "hmd

“device_vid”

The USB vendor identification number. Each manufacturer should request a VID from USB.org. For prototyping purposes, use the Valve VID shown below.

Example:

"device_vid" : 10462

“device_pid”

The USB product identification number. Each manufacturer should create a PID per model. For prototyping purposes, use the PID shown below.

Example:

"device_pid" : 8960

“device_serial_number”

A string representing the unique serial number of the device. This value is only used as a reference to match JSON files to actual objects. Each object creates its own serial number from the serial number in the object’s processor. Writing that serial number into the JSON file allows developers to associate JSON files with actual objects. Maintaining that association is particularly important after optical and IMU calibration. The serial number generated by the object is displayed using lighthouse_console.

Example:

"device_serial_number" : "LHR-F8DE9EBE"

“lighthouse_config”

An object containing three member arrays. Each array index corresponds to a sensor on the tracked object. Specifying the values in modelPoints, modelNormals, and channelMap define the physical placement of the sensor, its orientation, and its electrical connection (port number). When SteamVR™ receives tracking data from a sensor on a particular port, it can use the data in lighthouse_config to associate that signal with a specific physical sensor located on the tracked object. SteamVR™ also reads the sensor placement described in lighthouse_config to establish the exact sensor geometry for the device. SteamVR™ solves incoming tracking data against the known sensor geometry to resolve the current pose of the object. image

Example: (Replace ellipsis with arrays described in each member below.)

"lighthouse_config" : {
 "channelMap" : [...],
 "modelNormals" : [...],
 "modelPoints" : [...]
 }

“modelNormals”

An array of [x, y, z] unit vectors that specify the direction the optical sensor faces in the object’s coordinate system.

Each photodiode is placed on the surface of the object facing outward. Imagine the sensor pictured below faces outward at a 45° angle between the -X and +Y axis. image

The unit vector normal to the face of the photodiode points in the direction 135° from the +X axis and 45° from the +Y axis. As a result the unit vector describing that orientation would be [ -0.7071, 0.7071, 0.0 ]. If we have placed the other sensors on 45° facets, we would expect the following normals.

Example:

"modelNormals" : [ [ -0.7071, 0.7071, 0.0 ], [ -0.7071, 0.0, -0.7071 ], [ -0.7071, 0.0, 0.7071 ], [ -0.7071, 0.0, -0.7071 ], [ -0.7071, -0.7071, 0.0 ] ]

“modelPoints”

An array of [x, y, z] coordinates that specify the location of the center of the optical sensor’s photosensitive area in the object’s coordinate system. Coordinate values are expressed in meters.

If we assigned the following dimensions to the sensor locations on the side of the HMD, we would need to represent those dimensions in the modelPoints array as shown below.

image

Example:

"modelPoints" : [
 [ -0.055, 0.030, 0.015 ],
 [ -0.050, 0.015, 0.005 ],
 [ -0.050, 0.0, 0.025 ],
 [ -0.050, -0.015, 0.005 ],
 [ -0.055, -0.030, 0.015 ]
 ]

“channelMap”

An array of port numbers. There is an element in the array for each sensor on the object. The value in the array element corresponds to the electrical channel connected to the sensor. When SteamVR™ receives tracking data from a channel, it can use this array to map that data to a sensor location specified in modelPoints.

If the five sensors shown on the side of the HMD in this example were connected to the electrical channels as indicated below, we would need the channelMap array [3, 5, 7, 11, 13]. The sensor channel number is determined by the sensor’s electrical connection to the object’s FPGA.

image

Note: The channel numbers are zero based, and cover the range 0 - 31. Altium’s multichannel schematic feature forces numbering to start at 1. Be careful when copying channel numbers from the net names in Altium. Net SENSOR_X1 is most likely connected to FPGA channel number 0. Subtract 1 from the reference designator to get the correct channel number.

“head”

An object with members that orient the tracked object’s coordinate system to the real world. The head member has two different meanings, depending on the value of device_class.

HMD Use Case

When the object is acting as an HMD, the head variable orients SteamVR™’s coordinate system to the tracked object. The origin of SteamVR™ is a point between an average user’s pupils, oriented with +Y pointing up, +X pointing to the user’s right, and -Z pointing out along the line of sight. If the model has a coordinate system that does not match this, then changing the head member is required.

image

For example, consider the HMD object below, with its coordinate system.

image

The “plus_x” value answers the question, “The head’s +X axis is pointing in which direction within the HMD’s CAD coordinate system?” The head’s +X axis points in the direction of the HMD’s -X axis. Therefore, the value for “plus_x” is [-1, 0, 0].

Likewise, the +Z axis of the head’s coordinate system points in the direction of the -Z axis of the HMD’s coordinate system. This requires a “plus_z” value of [0, 0, -1] to match the orientations.

The head’s origin is centered between the pupils, but the HMD’s origin is between the HMD’s lenses. When worn, the origin of the head is behind the origin of the HMD by 20 mm along the -Z axis. Matching the origins requires a value of [0.0, 0.0, -0.020] for the “position” coordinates.

Example:

"head" : {
 "plus_x" : [ -1, 0, 0 ],
 "plus_z" : [ 0, 0, -1 ],
 "position" : [ 0.0, 0.0, -0.020 ]
}

Controller

When the object is acting as a controller, the head variable orients the render model shown in SteamVR™ to the tracked object. The render model is created in the SteamVR™ coordinate system as described in The Render Model. One method for determining the head variable is to export the render model as an STL file, import that STL file into the 3D CAD space of the object. Then, measure the plus_x and plus_z normals and origin of the render model from the origin of the object.

Example:

"head" : {
 "plus_x": [1, 0, 0],
 "plus_z": [0, 0.05233595624, 0.99862953475],
 "position": [0, 0.015, -0.040]
}

“plus_x”

HMD: A unit vector [x, y, z] representing the direction of the head’s +X axis in the object’s coordinate system.

Controller: A unit vector [x, y, z] that aligns the render model in SteamVR™ to the object’s coordinate system.

“plus_z”

HMD: A unit vector [x, y, z] representing the direction of the head’s +Z axis in the object’s coordinate system.

Controller: A unit vector [x, y, z] that aligns the render model in SteamVR™ to the object’s coordinate system.

“position”

HMD: A coordinate [x, y, z] located at the midpoint between the average user’s physical pupil locations. This is typically determined by extending a vector out from the lens surface along the primary optical axis, until it crosses the plane of the average user’s pupil depth.

Controller: A coordinate [x, y, z] that positions the render model in SteamVR™ in the object’s coordinate system.

Note: A “plus_y” member is not required, because a right-handed coordinate system is assumed.

Clone this wiki locally