third-party/realdds/doc/initialization.md
See also: device, notifications
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 - optionalstream-headerstream-optionsThese 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.
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.
device-headerThis 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-streams is the number of streams to expect
The device will wait for this many stream headers to arrive to finish initializationextrinsics describe 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 neededpresets is an optional array of preset names
The presets may then be applied using change-presetIn 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:
With those 3, one can compute IR2 to RGB, for example.
device-optionsThis is optional: not all devices have options. Device options will not be shown in the Viewer. 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:Options are defined with a JSON array: [name, value, range..., default-value, description, [properties...]]:
name is what will be displayed to the uservaluerange of valid values
float, int), defined by a minimum, maximum, and stepping
minimum, minimum+1*stepping, minimum+2*stepping, ..., maximum )["Enabled", true, true, "Description"]
minimum=0, maximum=1, stepping=1["Name", "Bob", "", "The customer's name"]
"IPv4" is a string option that conforms to W.X.Y.Z (IP address) format["Preset", "Maximum Quality", ["Maximum Range", "Maximum Quality", "Maximum Speed"], "Maximum Speed", "Standard preset combination of options"][x1, y1, x2, y2]
["name", [1,2,3,4], null, "description", ["optional"]]default-value which also adheres to the range
properties describing 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 as null in the JSON
["name", null, "description", ["optional", "string"]] is an optional read-only string value that's currently unset"string", "int", "boolean", "float", "IPv4", "enum", "rect" can (and sometime must) indicate the value type
"read-only" options are not settable
set-option will fail for these, though their value may change on the server sidestream-headerInformation about a specific stream:
name is the stream name, e.g. Color
rt/<topic-root>_Color_ - e.g., rt/<topic-root>_Infrared_1profiles array
[frequency, format, width, height]default-profile-index is the index into the profiles for the default profilesensor-name is the name of the sensor
Stereo Module produces a Depth stream and also Infraredtype is one of ir, depth, color, confidence, motion - similar to the librealsense rs2_stream enummetadata-enabled is true if a metadata topic 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-optionsstream-name is the name of the stream, same as in stream-headerintrinsics is:
accel or gyro to 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];
}
options is an array of option objects, same as device-options above; stream options are shown in the Viewerembedded-filters is an array of embedded filters, with name and options for each filter; all these are shown in the Viewer
E.g.:{
"id": "stream-options",
"stream-name": "Motion",
"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]
},
"options": [],
"embedded-filters": []
}
{
"id": "stream-options",
"stream-name": "Depth",
"intrinsics": {
"width": 1280,
"height": 720,
"principal-point": [640.2379150390625,357.3431396484375],
"focal-length": [631.3428955078125,631.3428955078125]
},
"options": [],
"embedded-filters": [
{
"name": "Decimation Filter",
"options": [
["Toggle",0,0,1,1,0,"Activate filter: 0:disable filter, 1:enable filter"],
["Magnitude",2,1,8,1,2,"How many pixels will be grouped into 1",["read-only"]]
]
},
{
"name": "Temporal Filter",
"options": [
["Toggle",0,0,1,1,0,"Activate filter: 0:disable filter, 1:enable filter"],
["Alpha",0.4,0,1,0.01,0.4,"The Alpha factor in an exponential moving average with Alpha=1 - no filter. Alpha = 0 - infinite filter",["float"]],
["Delta",20,1,100,1,20,"Step-size boundary. Establishes the threshold used to preserve surfaces (edges)",["float"]],
["Persistency",3,0,8,1,3,"Hole Filling policy"]
]
}
]
}
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:
width and height are for the native stream resolution, as 16-bit integer valuesprincipal-point defined as [<x>,<y>] floating point valuesfocal-length, also as [<x>,<y>] floatsA distortion model may be applied:
model would specify which model is to be used, with the default of browncoefficients is an array of floating point values, the number and meaning which depend on the model
brown, 5 points [k1, k2, p1, p2, k3] are neededThe 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.