10 KiB
See also: device, notifications
Initialization
In order to stream, a client must know the stream names, available formats, etc.
The only way for a client to get these is by subscribing to the notification topic. When the server detects a subscriber on this topic, it will broadcast a set of initialization messages in the following order:
device-headerdevice-options- optional- For each stream:
stream-headerstream-options
These initialization messages should only have effect on devices that are not already initialized. They are expected in the above order.
Once all streams have been received, the device is initialized and ready to use. See Streaming.
"Atomic" Initialization
Initialization may happen interspersed with regular notifications: for example, a server that's already serving data and notifications to an existing client may see another client and broadcast initialization messages.
Only one set of initialization messages can be sent at a time. I.e., if a new client is detected while initialization messages for a previous client are still outgoing, a new set of messages must go out but only once the previous set is finished.
While a set of initialization messages are outgoing, all other notifications must take a back seat and wait until the set is written out.
Messages
device-header
This is the very first message, for example:
{
"id": "device-header",
"n-streams": 5,
"extrinsics": [
["Depth","Gyro",[1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,-0.005520000122487545,0.005100000184029341,0.011739999987185001]]
["Depth","Infrared 2",[1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,-0.04986396059393883,0.0,0.0]]
],
"presets": ["Default", "Max Range", "Max Quality"]
}
n-streamsis the number of streams to expect The device will wait for this many stream headers to arrive to finish initializationextrinsicsdescribe world coordinate transformations between any two streams in the device, required for proper translation of pixel coordinates between sensors, such as when a point-cloud is neededpresetsis an optional array of preset names The presets may then be applied usingchange-preset
Extrinsics
In order to translate from one stream viewpoint to another, a graph needs to be available with nodes for each stream and a directional edge between them (one from A to B; another from B to A).
So extrinsics is an array of such edges: [<edge1>,<edge2>,...],
Each edge is also an array: [<from>,<to>,[<r00>,<r01>,...,<r22>,<tx>,<ty>,<tz>]].
Where <from> and <to> are stream names, and the array inside contains the 9 rotation values (column-major) followed by 3 translation vector values.
The complete graph can be transmitted like this but this is overkill: given at least one edge from each stream to another, the rest can be computed. This is what librealsense does:
- Depth to IR = identity
- Depth to IR2 = {...}
- RGB to Depth = {...}
With those 3, one can compute IR2 to RGB, for example.
device-options
This is optional: not all devices have options. See device.
{
"id": "device-options",
"options": [
["Domain",0,0,232,1,0,"The DDS domain (0-232) in which this device will be discovered"],
["IP Address","1.2.3.4",null,"Which IP address to assign to the device; if empty, DHCP will be used", ["optional","IPv4"]]
]
}
"options"is an array of options- Each option is an array of
[name, value, range..., default-value, description, [properties...]]:- The
nameis what will be displayed to the user - The current
value - An optional
rangeof valid values- Numeric options (
float,int), defined by aminimum,maximum, andstepping- I.e., is-valid = one-of(
minimum,minimum+1*stepping,minimum+2*stepping, ...,maximum)
- I.e., is-valid = one-of(
- Booleans can remove the range, e.g.
["Enabled", true, true, "Description"]- Booleans can be expressed as a range with
minimum=0,maximum=1,stepping=1
- Booleans can be expressed as a range with
- Free string options would likewise have no range, e.g.
["Name", "Bob", "", "The customer's name"]"IPv4"is a string option that conforms toW.X.Y.Z(IP address) format
- Enum options are strings with an array of choices, e.g.
["Preset", "Maximum Quality", ["Maximum Range", "Maximum Quality", "Maximum Speed"], "Maximum Speed", "Standard preset combination of options"]
- Numeric options (
- A
default-valuewhich also adheres to the range- If this and the range are missing, the option is read-only
- A user-friendly description that describes the option, to be shown in any tooltip
- Additional
propertiesdescribing behavior or nature, as an array of (case-sensitive) strings"optional"to note that it's possible for it to not have a value; lack of a value is denoted asnullin the JSON- If optional, a type must be deducible or present in the properties
- E.g.,
["name", null, "description", ["optional", "string"]]is an optional read-only string value that's currently unset - Enums cannot be optional
"string","int","boolean","float","IPv4","enum"can (and sometime must) indicate the value type- If missing, the type will be deduced, if possible, from the values
"read-only"options are not settableset-optionwill fail for these, though their value may change on the server side
- The
- The device server has final say whether an option value is valid or not, and return an error if
set-optionspecifies an unsupported or invalid value based on context
- Each option is an array of
Device options will not be shown in the Viewer.
stream-header
Information about a specific stream:
nameis the stream name, e.g.Color- This will be shown in the Viewer
- This is also the name of the topic containing the stream data
- E.g.,
rt/<topic-root>_Color - If it contains a space, the space will be replaced by
_- e.g.,rt/<topic-root>_Infrared_1
- E.g.,
profilesarray- Each profile is itself an array of
[frequency, format, width, height] - Format is a string representation, similar to the image encoding in ROS
- Each profile is itself an array of
default-profile-indexis the index into theprofilesfor the default profilesensor-nameis the name of the sensor- Sometimes, a single sensor may produce multiple streams, e.g.
Stereo Moduleproduces aDepthstream and alsoInfrared - Streaming one stream requires starting the sensor, and so may have effect on the other streams, depending on the server implementation
- This allows streams to be grouped by the client and may affect its logic
- Sometimes, a single sensor may produce multiple streams, e.g.
typeis one ofir,depth,color,confidence,motion- similar to the librealsensers2_streamenummetadata-enabledistrueif ametadatatopic for the device will be written to
{
"default-profile-index": 29,
"id": "stream-header",
"metadata-enabled": true,
"name": "Color",
"profiles": [
[30,"rgb8",1280,800],
[30,"BYR2",1280,800],
[30,"Y16",1280,800],
...
],
"sensor-name": "RGB Camera",
"type": "color"
}
stream-options
stream-nameis the name of the stream, same as instream-headerintrinsicsis:- For video streams, see below
- For motion streams, a mapping from either
accelorgyroto an array of float values conforming to:struct rs2_motion_device_intrinsic { // Scale X cross axis cross axis Bias X // cross axis Scale Y cross axis Bias Y // cross axis cross axis Scale Z Bias Z float data[3][4]; // Variance of noise for X, Y, and Z axis float noise_variances[3]; // Variance of bias for X, Y, and Z axis float bias_variances[3]; }
JSON "intrinsics": { "accel": [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], "gyro": [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] }optionsis an array of option objects, same asdevice-optionsabove
Stream options are shown in the Viewer.
Video Stream Intrinsics
{
"id": "stream-options",
"intrinsics": {
"width": 1280,
"height": 720,
"principal-point": [640.2379150390625,357.3431396484375],
"focal-length": [631.3428955078125,631.3428955078125]
},
"options": [
["Backlight Compensation",0.0,0.0,1.0,1.0,0.0,"Enable / disable backlight compensation"],
["Brightness",0.0,-64.0,64.0,1.0,0.0,"UVC image brightness"],
],
"stream-name": "Infrared 1"
}
Like extrinsics are used to communicate translation between different stream viewpoints, the intrinsics serve to transform 2D pixel values to 3D world coordinates. I.e., an RGB pixel has to be converted to a 3D point in space, then mapped to a 3D point from the viewpoint of the Depth stream, then transformed back into a 2D Depth pixel.
The intrinsics are communicated in an object, as shown above:
- A
widthandheightare for the native stream resolution, as 16-bit integer values - A
principal-pointdefined as[<x>,<y>]floating point values - A
focal-length, also as[<x>,<y>]floats
A distortion model may be applied:
- The
modelwould specify which model is to be used, with the default ofbrown - The
coefficientsis an array of floating point values, the number and meaning which depend on themodel- For
brown, 5 points [k1, k2, p1, p2, k3] are needed
- For
The coefficients are assumed 0 if not there, applying no un/distortion.
An additional force-symmetry boolean can be applied, and defaults to false.
The intrinsics are communicated for the native resolution the device chooses. Librealsense, or any client, will need to scale these to a target resolution.