Handling teleop command streams

Registering a teleop callback

The Agent SDK Client class has a method called register_teleop_callback.

It has the following description:
Control datapoints received from teleop whose “stream” value matches an element of the given stream filter will be streamed into the provided callback. If no stream filter is provided, control datapoints from all streams will be received.

And takes these parameters:
f (Callable[[ControlDatapoint], None]) – A callback that will be executed on teleop control datapoints as they are received by the Formant agent.
stream_filter (Optional[List[str]]) – A list of stream names. The provided callback is only executed on control datapoints whose names are in this list.

and returns None.

Example script

from formant.sdk.agent.v1 import Client as FormantClient


"""
/* ControlDatapoint contains data sent from Formant teleop. */
 message ControlDatapoint {
  string stream = 1;
  int64 timestamp = 2;  // unix epoch time in milliseconds
  oneof data {  // payload, use one of the fields below.
    Bitset bitset = 3;
    Twist twist = 4;
    Transform pose = 5;
    Numeric numeric = 6;
    PoseWithCovariance pose_with_covariance = 7;
  }
}
"""

def handle_teleop(control_datapoint):
  print(control_datapoint.stream)
  print(control_datapoint.timestamp)
  print(control_datapoint)
  
if __name__ == "__main__":
    fclient = FormantClient(
        ignore_throttled=True,
        ignore_unavailable=True,
    )

    # Handling data ...
    fclient.register_teleop_callback(
        handle_teleop, ["Joystick", "Localization", "Buttons"]
    )

This script prints the stream name, timestamp, and full control datapoint for each control datapoint received from teleop.

Registering multiple callbacks

📘

Broadcasting behavior

Every registered callback receives all control datapoints from teleop. If there are many callbacks registered, make sure that it's okay if each control datapoint is broadcast to each callback.

This is opposed to how handling commands works.

Control datapoints

What is a ControlDatapoint? A ControlDatapoint is a protobuf object representing the command sent through one of the teleop elements. They can be high-frequency in the case of joystick, sliders, and knobs. You can take a look at ControlDatapoint's spec here:
https://github.com/FormantIO/formant/blob/826322aca53a6cc112346d171729f07e17e62e58/protos/model/v1/datapoint.proto#L39

Teleop element

Control datapoint type

Control datapoint selector

Joystick

Twist

twist

Buttons

Bitset

bitset

Slider

Numeric

numeric

Knob

Numeric

numeric

Goal (Localization)

Transform

pose

Relocalization

PoseWithCovariance

pose_with_covariance