Skip to content
Get SDK Access

RCSP Specification

This document specifies everything needed to implement the Rokoko Command Server Protocol (RCSP).

The RCSP protocol abstracts away the low-level binary Rokoko device protocol so users can use a simpler, JSON-based interface. It also unifies internal Rokoko SDK / driver control in the same interface, so users can control both the driver and the devices with the same protocol.

Further, it also offers delivery of events from both devices and the Rokoko driver based on a publisher-subscribe model.

  • The protocol is based on TCP
  • The server listens on port 45451
  • The server MUST be able to handle multiple clients simultaneously
  • The server MUST be able to queue commands
  • All commands MUST elicit a response
    • This MUST be either a valid response or an error response
  • The order of responses MUST follow the order of the commands
  • Events are allowed to come between command ⟺ response pair
  • The protocol is Case-Sensitive
  • Optional JSON values MAY be null

All messages consists of a binary header followed by a JSON payload.

struct header {
enum payload_type : uint8_t {
command = 1,
response_ok = 2,
response_error = 3,
event = 4,
};
static constexpr uint8_t marker_val{};
uint8_t marker{0xDC}; // 0xDC = DeviceCommands
uint8_t header_version{1};
uint8_t header_size{sizeof(*this)};
payload_type type;
uint32_t payload_size;
};

This header describes the payload type. The following rules applies to these types:

payload_typeDirection AllowedPayload Format
commandClient ⟹ ServerJSON
responseServer ⟹ ClientJSON
eventServer ⟹ ClientJSON

Payloads are JSON based. The payload_types each have an associated JSON object that they wrap their data in.

In the following, this syntax is used:

  • object_ref: A reference to another named JSON object
  • Optional values are prefixed with opt_
    • All values without opt_ prefixed are required
  • All objects in the JSON object trees all end in the basic JSON types:
    • "<string>", "<number>", "<boolean>", "<null>"
  • "<array>"s and "<object>"s containing a type are denoted:
    • "array<object_ref>" and "object<object_ref>"
"Command": "<string>"
"TrackId": "<string>"
"Version": "<number>"
"Arguments": "<opt_object>"

Where “Arguments” is an object with key-value pairs, where the key SHALL be the argument’s Name.

The TrackId SHALL be echoed in the same key in rcsp_response_payload.

Response Payload (Success) (rcsp_response_payload)

Section titled “Response Payload (Success) (rcsp_response_payload)”

A generic ok without payload:

"TrackId": "<string>"
"Status": "<string>"
"Version": "<number>"
"Response": "<opt_object>"

Some commands just have a simple “Ok” response, in which case the "Response": "<opt_object>" may be omitted. This response is named rcsp_response_ok.

Response Payload (Error) (rcsp_response_error)

Section titled “Response Payload (Error) (rcsp_response_error)”
"TrackId": "<string>"
"Status": "<string>"
"Version": "<number>"
"Error": "<rcsp_error>"

Where rcsp_error is:

"Code": "<string>"
"Message": "<opt_string>"

The available error codes are:

Code
Unknown error
Unknown command
Invalid marker
Wrong header type
Parse error
Missing required argument
Missing required key
Invalid argument
Invalid value type
Invalid value
Runtime error
Device not found
Device not available
Device command error
Sub-device not found
Unsupported command
Busy
Response too small
Device not updatable

They can also be listed with the “ListErrorCodes” command.

"Publisher": "<string>",
"Topic": "<string>",
"EventData": "<publisher dependent (see below)>"

The possible available Publishers and their EventData can be seen in the table below:

NOTE

This list may not be exhaustive. Use the “ListPublishers” command for a list of actual supported Publishers and their Topics

Non-device publishers (subscribed via “Subscribe”):

PublisherTopicEventData
”DeviceEvents""Seen"
"Connected"
"Initialized"
"Mapped"
"Disconnected"
"Destroyed"
"Calibrated"
"FlipDecided"
"EmfSaturated"
"GyrSaturated"
"AccSaturated"
"CoilDetected"
"BootloaderConnected"
"BootloaderDisconnected”
rcsp_device_event_data
”Logs""Error"
"Warning"
"Info”
rcsp_log_event_data
”UpdateFwEvents""Progress"
"Failure"
"Done”
rcsp_update_fw_event_data

Device-specific publishers (subscribed via “DeviceSubscribe”, requires DeviceId):

PublisherTopicEventData
”DeviceLogs""Error"
"Warning"
"Info"
"Debug”
rcsp_device_log_event_data
”DeviceEvents""ButtonPushed”rcsp_device_event_data
"EventSuccess": "<opt_string>",
"DeviceId": "<opt_number>",
"IsBootloader": "<opt_boolean>",
"ButtonPushType": "<opt_string>",
"Connection": "<opt_string>",
"WasLastConnection": "<opt_boolean>"

“EventSuccess” can be either “Success” or “Failure”.

“DeviceId” corresponds to the “DeviceId” in the “ListDevices” response.

“Connection” is the connection the event is about, one of the entries of “Connections” in the “ListDevices” response. A “Disconnected” event is one connection going away, and “WasLastConnection” says whether the device went with it: true and the device is gone, false and it is still reached over another connection.

“BootloaderConnected” and “BootloaderDisconnected” carry the “DeviceId” the bootloader is listed under, “IsBootloader” true, and its “Connection”.

“ButtonPushType” is only present for the “ButtonPushed” topic and can be one of:

  • “SinglePress”
  • “DoublePress”
  • “LongPress”
"LogMsg": "<string>"
"LogMsg": "<string>",
"DeviceId": "<number>",
"TimestampNs": "<number>",
"SrcLocation": "<string>"

“TimestampNs” is the device-local timestamp in nanoseconds.

“SrcLocation” is the source location string (e.g., module or function name) of the log message origin on the device.

"PercentComplete": "<opt_number>",
"DeviceId": "<opt_number>",
"ErrorMsg": "<opt_string>"

“DeviceId” is the device being updated, as “ListDevices” lists it, and stays the same for the whole update, including the reboot into bootloader mode.

For all the command tables below, the following holds:

  • Each command is the value of “Command” in rcsp_cmd.
  • All the arguments given in Arguments are key-value pairs in the “Response” object in rcsp_cmd.
    • If Arguments in the table is null, it is not needed.
  • Each response object is the “Response” in rcsp_response_payload.

IMPORTANT

The Response shows the expected response on success. On failure, all commands will get the same rcsp_response_error.

Some commands use the same objects or object arguments. To highlight when this is the case, these will be presented separately here and referred to below by name (given in the header):

"DeviceId": "<number>",
"Connection": "<opt_string>"

Every command that takes “DeviceId” also takes an optional “Connection”: which of the device’s connections, as “Connections” in rcsp_device_list names them, the command goes over. This is how you tell a device reached both over a cable and over the network which link a command is meant for, for example a subscription, which the device keeps per connection.

  • Omitted: the first of the device’s “Connections”, which is a cable before a network.
  • A connection the device is not on: Device not found, with a message naming the connections it is on. Run “ListDevices” again to get the current list.
  • Not the name of a connection: Invalid value, with the accepted names.

The argument objects below do not repeat it.

A general description of an argument.

"Name": "<string>",
"Info": "<string>",
"Type": "<string>",
"Optional": "<boolean>"

The Name refers to the key used in the key-value pairs in the argument dictionary. The “Type” can be one of:

  • “String”
  • “Number”
  • “Array”
  • “Object”
  • “Boolean”

“Optional” determines if the argument is optional or required.

A general description of a command.

"Command": "<string>"
"Version": "<number>"
"Info": "<string>"
"Args": "array<rcsp_arg_description>"

An array of bytes that might be printable. The “Raw” field holds the numbers (decimal format) while the string shows the printable version (this is context specific) and could be fx “0xabcd” or, if the context calls for characters, “some_string”.

NOTE

The printable ("Str") will only show the characters until the first non-printable character.

IMPORTANT

When this object is used as input, only "Raw" is read; "Str" is ignored. A client that sends just "Str" will not get the value it expects.

"Raw": "array<number>",
"Str": "<string>"

RCSP’s general representation of a version.

"Major": "<number>",
"Minor": "<number>",
"Patch": "<opt_number>",
"Build": "<opt_number>"
CommandArgumentsResponseDescription
”Info”nullrcsp_infoGet basic info
”GracefulExit”nullrcsp_response_okStop the entire application
”ListCommands”nullrcsp_cmd_listList available Top-level commands
”ListDevices”nullrcsp_device_listList connected devices
”ListErrorCodes”nullrcsp_error_code_listList all error codes
”ListDeviceCommands”device_id_argrcsp_device_cmd_listList available commands for a given device. Details here.
"UpTimeSecs": "<number>",
"SupportedHeaderVersions": "array<number>",
"AppVersion": "<rcsp_version_obj>",
"GitSha": "<string>",
"SystemName": "<string>"

NOTE

The “SupportedHeaderVersions” refers to the binary header supported versions.

The “SystemName” value contains the OS name.

"Commands": "array<rcsp_cmd_description>"
"Devices": "array<rcsp_device>"

One row per device. A device the driver reaches more than one way, such as a suit on Wi-Fi with a USB cable plugged in, is one row, with its connections listed together. The response’s “Version” is 2.

Where rcsp_device is:

"DeviceId": "<number>",
"DeviceType": "<string>",
"Connections": "array<string>",
"Updatable": "<boolean>",
"IsBootloader": "<boolean>",

“Connections” lists every connection the device is reached over, in the order the driver prefers them: a cable before a network. The first entry is the connection a command to the device goes over, unless the command names another in its “Connection” argument (see device_id_arg). “Updatable” means the device can be updated over some connection.

Where “DeviceType” can be:

  • “SmartSuitPro”
  • “Smartgloves”
  • “CoilPro”
  • “Unknown”

and each entry of “Connections” can be:

  • “Serial”
  • “TCP”
  • “UDP”
  • “Emulated”
  • “Playback”
  • “Unknown”

A glove behind a suit is listed on the suit’s connections, since that is how it is reached.

A device in its bootloader is a row of its own, with “IsBootloader” true, under the same “DeviceId” the device has in app mode. For a moment after a device reboots, its app row and its bootloader row can both be present.

"ErrorCodes": "array<string>"
"DeviceCommands": "array<rcsp_cmd_description>"
CommandArgumentsResponseDescription
”ListPublishers”opt_device_id_argrcsp_publisher_listList available publishers. With DeviceId, lists device publishers
”Subscribe”rcsp_subscription_argrcsp_response_okSubscribe to non-device publishers along with their topics
”Unsubscribe”rcsp_subscription_argrcsp_response_okUnsubscribe from non-device publishers
”DeviceSubscribe”rcsp_device_subscribe_argrcsp_response_okSubscribe to device-specific publishers (requires DeviceId)
“DeviceUnsubscribe”rcsp_device_subscribe_argrcsp_response_okUnsubscribe from device-specific publishers (requires DeviceId)
"DeviceId": "<opt_number>",
"Connection": "<opt_string>"

“Connection” is as in device_id_arg, and applies when “DeviceId” is given.

"Publishers": "array<rcsp_publisher>",

where rcsp_publisher is:

"Publisher": "<string>",
"Topics": "array<string>"
"Publishers": "array<rcsp_publisher>"
"DeviceId": "<number>",
"Publishers": "array<rcsp_publisher>"

See Events or run the ListPublishers cmd for possible values.

Not all commands are supported by all devices. The supported commands can be polled. Every one of them takes the optional “Connection” of device_id_arg alongside “DeviceId”. The potential supported device commands are:

CommandArgumentsResponseDescription
”SetEmfChannel”rcsp_set_emf_ch_argrcsp_response_okSet EMF channel
”GetEmfChannel”device_id_argrcsp_response_emf_chGet EMF channel
”ReadSensorFwInfo”device_id_argrcsp_response_fw_infoGet Sensor FW information
”SetDeviceName”rcsp_device_name_argrcsp_response_okSet the name of the device
”GetDeviceName”device_id_argrcsp_response_device_nameGet the name of the device
”SetFrameRate”rcsp_frame_rate_argrcsp_response_okSet the device’s (desired) frame rate
”GetFrameRate”device_id_argrcsp_response_frame_rateGet the device’s (expected) frame rate
”GetDeviceInfo”device_id_argrcsp_response_glove_info
rcsp_response_ssp_info
Get various information from the device
”CalibrateStaticPose”device_id_argrcsp_response_okCalibrate device with a static (non-moving) pose
”ReinitAlgo”device_id_argrcsp_response_okReinitialize the device’s algorithm
”ResetDevice”device_id_argrcsp_response_okReset (reboot) the device (Smartgloves, fw >= 3.0.25)
“GetWifiVersion”device_id_argrcsp_response_wifi_verGet the version of the wifi module
”SetNetworkConfiguration”rcsp_net_settings_argrcsp_response_okSet the devices network configuration
”GetNetworkConfiguration”device_id_argrcsp_response_net_settingsGet the devices network configuration
”ScanNetwork”rcsp_net_scan_argrcsp_response_scan_resultScan the network in the given band / channel
”StartWifi”rcsp_start_wifi_argrcsp_response_okStart the wifi module with the latest settings. Optionally set a connection timeout.
”PostProcess”rcsp_postprocess_argrcsp_response_okControl postprocessing
”UpdateFirmware”rcsp_fw_update_arg rcsp_response_okUpdate FW. Will update progress through events.
”UpdateSensorFirmware”rcsp_sensor_fw_update_arg rcsp_response_okUpdate sensor FW. Will update progress through events.
”UpdateWifiModule”rcsp_update_wifi_module_arg rcsp_response_okUpdate WiFi Module FW. Will update progress through events.
”SetColorLed”rcsp_set_color_led_arg rcsp_response_okSet the given clor LED.
”SetLedBehavior”rcsp_set_led_behavior_arg rcsp_response_okSet the LED behavior.
”SubscribeToData”device_id_argrcsp_response_okSubscribe to sensor data from the device
”UnsubscribeFromData”device_id_argrcsp_response_okUnsubscribe from sensor data from the device

NOTE

Whether “SubscribeToData” is required depends on the transport:

  • USB-connected devices: data streaming is off by default. Call “SubscribeToData” to start receiving sensor data, and “UnsubscribeFromData” to stop.
  • TCP-connected devices: data streaming is on by default. No explicit subscription is required to start receiving data.

These are sensible defaults for the most common use cases of each transport, but either behavior can be toggled at runtime with “SubscribeToData” / “UnsubscribeFromData”.

"DeviceId": "<number>",
"Channel": "<number>"
"Channel": "<number>",
"FreqX": "<opt_number>",
"FreqY": "<opt_number>",
"FreqZ": "<opt_number>"

The frequency values are in Hz. They are only available in version 2 of the command.

"DeviceId": "<number>",
"DeviceName": "<string>"
"DeviceId": "<number>",
"FrameRate": "<number>"

“FrameRate” is in Hz. If the arg does not match with an available option, it will be rounded to nearest available.

"DeviceId": "<number>",
"Settings": "<rcsp_net_settings>"

where rcsp_net_settings:

"HubAddr": "<number>",
"DhcpMode": "<number>",
"ChannelNo": "<number>",
"SecurityType": "<string>",
"ServerIp": "<string>",
"ServerPort": "<number>",
"DeviceIp": "<string>",
"Gateway": "<string>",
"Band": "<string>",
"Ssid": "<rcsp_printable_byte_array>",
"Psk": "<rcsp_printable_byte_array>",

“Band” can be:

  • “2.4GHz”
  • “5GHz”
  • “Dual”

For backward compatibility, the legacy numeric values (0, 1, 2) are still accepted on input.

“SecurityType” is emitted as a string and, like “Band”, also accepts the legacy numeric value on input. The commonly used values are:

  • “Open”
  • “WPA2”
  • “WPA3_Personal”
"DeviceId": "<number>",
"Band": "<number>",
"ChannelNo": "<opt_number>"
  • “Band”: 0 (2.4 GHz), 1 (5 GHz) or 2 (dual band).
  • “ChannelNo”: The channel to scan. If omitted or 0, every channel in the band is scanned.

“ScanNetwork” is not available over a TCP connection: on a Smartgloves II the scan restarts the Wi-Fi module, which would drop the connection the command came in on. Send it over USB.

"DeviceId": "<number>",
"TimeoutMs": "<opt_number>"
  • “TimeoutMs”: Connection timeout in milliseconds. If omitted, no timeout is used.
"DeviceId": "<number>",
"ProcessType": "<string>"

where "ProcessType" should be one of:

  • “StartSmoothing”
  • “StopSmoothing”

Note that “StopSmoothing” can only be called after start “StartSmoothing”.

When “StopSmoothing” is called, the processing of all the data will commence and will be delivered via the output of the driver.

This will happen through a new device that will present itself in the output (via a new definition frame). All the processed output will be linked to the device_id of this special device. The definition frame for this special device will be tagged with a special key to denote it is postproccesed data, so the user can handle it in a special way, like filter it out from display or save it to a recording.

"DeviceId": "<number>",
"FwPath": "<string>",
"ForceUpdate": "<opt_bool>",
  • “ForceUpdate”: Updates will try to force update a device, even if some discrepancies have been found. For example if the header of the FW file does not match the device type or the magic number is wrong. (Default: false)
  • “Connection”: as in device_id_arg. The firmware is transferred over the connection chosen, so a device reached both ways can be told which.
"DeviceId": "<number>",
"FwPath": "<string>",
"ForceUpdate": "<opt_bool>",
"SensorsInBoot": "<opt_bool>",

Same as rcsp_fw_update_arg, but for sensor FW updates.

  • “SensorsInBoot”: If sensors are already in bootloader, sometimes the RCSP Server must know to take appropriate action when updating. (Default: false)
"DeviceId": "<number>",
"FwPath": "<string>",
"DeviceId": "<number>",
"LedId": "<string>",
"Red": "<number>",
"Green": "<number>",
"Blue": "<number>",

All color components are between 0-255.

And the “LedId” for Smartgloves II can be:

  • RingLed
"DeviceId": "<number>",
"LedId": "<string>",
"Behavior": "<number>",

The “Behavior” can be one of:

ValueBehavior
0Off
1On
2Blink (slow)
3Blink (fast)

The “LedId” for Smartgloves II can be:

  • StatusLed
"Sensors": "array<sensor_info>"

Where "sensor_info" is:

"Addr": "<number>",
"RawHeading": "<number>",
"Signature": "<number>",
"FwVersion": "<rcsp_version_obj>",
"BootVersion": "<rcsp_version_obj>",
"BootStatus": "<number>",
"BootStatusStr": "<string>",
"IsCalibrated": "<number>",
"ValidCalib": "<boolean>",
"Epoch": "<number>",
"CalibrationID": "<number>",
"IdUnique": "<rcsp_printable_byte_array>",
"SensorSetupStatus": "<number>",
"BuildNumber": "<number>",
"ProdAssyRaw": "<number>",
"HwVersion": "<rcsp_version_obj>",
"Vendor" "<string>",
"InBootloader" "<boolean>",

Note that “Addr”, “Data”, “Module” and “Command” are decomposed from the “RawHeading”.

rcsp_response_glove_info / rcsp_response_ssp_info (common)

Section titled “rcsp_response_glove_info / rcsp_response_ssp_info (common)”

The response differs, depending on whether the command is sent to a SSP, a Smartglove, or a Coil Pro. The common part is:

"Header": "<string>",
"IdUnique": "<rcsp_printable_byte_array>",
"FwVersion": "<rcsp_version_obj>",
"BootVersion": "<rcsp_version_obj>",
"UsbApiVersion": "<rcsp_version_obj>",
"WifiApiVersion": "<rcsp_version_obj>",
"BtApiVersion": "<rcsp_version_obj>",
"HubSerialNumber": "<rcsp_printable_byte_array>",
"ProdAssyRaw": "<number>",
"DeviceType": "<string>",
"HwVersion": "<rcsp_version_obj>",
"ProdBoardId": "<number>",
"ProdDate": "<number>",
"ProdEpoch": "<number>",
"BuildEpoch": "<number>",
"<DEVICE_SPECIFIC>": "see below"

Where "<DEVICE_SPECIFIC>" is device specifc.

For rcsp_response_glove_info, "<DEVICE_SPECIFIC>" = "Smartgloves" and the value is:

"IsLeft": "<boolean>",

For rcsp_response_ssp_info, "<DEVICE_SPECIFIC>" = "SmartSuitPro" and the value is:

"Features": {
"Bitmask": "<number>",
"IsGloveReady": "<boolean>",
"HasLeftGlove": "<boolean>",
"HasRightGlove": "<boolean>",
"HasSTSensor": "<boolean>"
},

For rcsp_response_ssp_info, "<DEVICE_SPECIFIC>" = "CoilPro", no extra values.

"WifiFwVersion": "<string>"

Same as rcsp_net_settings.

"ScanResults": "array<rcsp_scan_result>"

Where rcsp_scan_result is:

"ChannelNo": "<number>",
"SecurityMode": "<string>",
"Rssi": "<number>",
"Ssid": "<rcsp_printable_byte_array>",
"Bssid": "<rcsp_printable_byte_array>"
"FrameRate": "<number>"
"DeviceName": "<string>"

Commands for interfacing with recording / playback.

CommandArgumentsResponseDescription
”SaveJsonData”rcsp_user_json_data_argrcsp_response_okSave the specified JSON data to the current recording with the given tag (Requires a started recording).
”LoadJsonData”rcsp_load_user_json_data_argrcsp_load_user_json_data_arg_responseLoad JSON data with the given tag (Requires a loaded recording, i.e., playback).
”ListJsonDataTags”nullrcsp_list_user_data_tags_responseList all tags for saved JSON data
"Tag": "<number>",
"UserData": "<object>"

Note that the UserData is JSON formatted, so it can be any struct the user wants. The Tag can be used to save various different structs. The Tag must be > 0.

"Tag": "<number>"

Tag corresponds to the tag that was saved.

Same as rcsp_user_json_data_arg

"Tags": "array<number>"

We want to subscribe to device events, specifically we want to know when devices Connected and Disconnected. We are also interested in getting “Warning” logs. To do this, we use the “Subcribe” command. It needs the argument rcsp_subscription_arg. We fill out the rcsp_cmd object:

"Command": "Subscribe",
"TrackId": "MyTrackId42",
"Version": 1,
"Arguments": {
"Publishers": [
{
"Publisher": "DeviceEvents",
"Topics": [
"Connected",
"Disconnected"
]
},
{
"Publisher": "Logs",
"Topics": [
"Warning"
]
}
]
}

As noted above in the table, if this command was successful it will respond with a rcsp_response_ok:

"Status": "Ok",
"TrackId": "MyTrackId42"