Connection Modes
UDP, Hybrid and LiveKit: what each carries, what it needs, and how the SDK picks one.
The SDK reaches the robot in one of three connection modes. The Robot object and every
verb are the same in all three; the mode decides what the connection carries and where it
works from.
| Mode | Control and state | Camera and audio | Works from |
|---|---|---|---|
udp | UDP on the robot's network | none | the robot's network |
hybrid | UDP on the robot's network | a LiveKit room | the robot's network |
livekit | a LiveKit room | a LiveKit room | wherever Asimov Manager is reachable |
A saved robot carries a mode, so Robot().connect() needs no argument. Pass one to override
it for a session: connect("udp").
In Code
connect.py builds the connection in code. Set MODE at the top of the file to "udp",
"hybrid" or "livekit"; the three ConnectionConfig shapes sit side by side:
# udp: control and state over UDP on the robot's network. No camera or audio.
udp = ConnectionConfig(udp=UdpConfig(host=ROBOT_ADDRESS))
# hybrid: control and state over UDP, camera and audio over LiveKit.
hybrid = ConnectionConfig(
udp=UdpConfig(host=ROBOT_ADDRESS),
livekit=ManagerConfig(url=MANAGER_URL, credential=CREDENTIAL),
)
# livekit: everything through the robot's LiveKit room, wherever Asimov Manager is reachable.
livekit = ConnectionConfig(livekit=ManagerConfig(url=MANAGER_URL, credential=CREDENTIAL))
config = {"udp": udp, "hybrid": hybrid, "livekit": livekit}[MODE]
with Robot(config).connect(MODE) as robot:
state = robot.get_state()
print(f"connected over {MODE} to {robot.info.endpoint}")
print(f"robot mode {state.mode.name}, armed {robot.armed}")
if state.battery is not None:
print(f"battery {state.battery.soc_percent:.0f} %")
else:
print("battery not reported")
capabilities = ("drive", "state", "battery", "camera", "microphone", "speaker")
print("capabilities:", ", ".join(c for c in capabilities if robot.has(c)))The other example scripts call Robot() with no config and read the environment or a saved
robot instead; see How the SDK Picks a Connection.
UDP
Commands go to the robot on UDP port 8850 and state comes back on port 8851. There is no media and no sign-in: anyone on the robot's network who can reach port 8850 can command it, so trust the network before you turn it on.
The robot sends UDP state to one host. In Asimov Manager, set the Asimov Edge parameters
udp-control to on and udp-state-host to your computer's address
(Asimov Manager).
One client per state port: a second script on the same computer binds
UdpConfig(state_bind=("0.0.0.0", <port>)) and the robot's udp-state-port matches it.
Hybrid
Control and state travel as in udp, so a velocity command does not cross the internet. The camera, microphone and speaker travel over the robot's LiveKit room, which the SDK joins with an SDK credential from Asimov Manager. Use hybrid on the robot's network when a script needs the camera or sound.
It needs the robot's address, its Asimov Manager URL and an SDK credential. Issue the credential on the Developer page of Asimov Manager (Get an SDK Credential). The credential's role applies to the LiveKit room: a Control credential can talk through the speaker, an Observe credential watches and listens only. Commands in hybrid travel over UDP, which has no sign-in, so the role does not limit driving.
LiveKit
Everything, commands included, goes through the robot's LiveKit room. Commands travel on the
data topic commands and state on the data track state, at about 10 Hz. Use livekit away
from the robot's network, or when an agent framework joins the same room and the SDK is one
more participant in it.
It needs the Asimov Manager URL and an SDK credential
(Get an SDK Credential). The SDK asks Asimov
Manager for a room token, joins, and reports robot.info.endpoint as room@url as <identity>. The
credential's role applies:
a Control credential drives, an Observe credential watches and listens, and the robot
drops its commands.
The Asimov Manager URL is the one you open in the browser: http://192.168.22.32,
http://asimov.local:8080 or a bare host name. The LiveKit URL Asimov Manager hands out is
the one the robot itself uses; when it says localhost, the SDK substitutes the manager's
host. A manager that redirects is reported as a ConnectError, not followed.
Every SDK session joins the room as its own participant, sdk-<credential id>-<host>-<6 hex>.
ManagerConfig(label="...") fixes the suffix so a restarted script replaces its previous session
instead of joining beside it. To join with a token you minted yourself, pass
LiveKitConfig(url, room, token) instead of ManagerConfig; one token is one participant.
To use the room without the SDK at all, see Without the SDK.
How the SDK Picks a Connection
Robot() with no argument builds its connection from the environment or a saved robot, in
this order:
- Environment variables:
MENLO_UDP_HOST, orMENLO_MANAGER_URLandMENLO_CREDENTIAL, or both pairs. They are not merged with a saved robot. - A saved robot from
~/.menlo/robots.toml: the one named byMENLO_ROBOT, else the file's default, else the only one. - Otherwise
ConnectError, namingmenlo setupand the variables.
MENLO_MODE sets the mode connect() uses with no argument and MENLO_LIMITS the velocity
limits, whichever source supplied the connection. MENLO_HOME moves the store directory.
A saved robot holds everything one mode needs, and can hold more than one mode's fields:
default = "lab"
[robots.lab]
mode = "hybrid"
udp_host = "192.168.22.32"
manager_url = "http://192.168.22.32"
credential = "..."
room = "robot-menlo-0001"
[robots.lab.limits]
vx = 0.3udp needs udp_host; hybrid needs udp_host, manager_url and credential; livekit
needs manager_url and credential. A mode whose field is missing raises ConnectError
naming the field and the menlo robots add command that fills it. Save and change robots
with the command line; the file is created with mode 0600
because it holds SDK credentials.
What Connect Waits For
connect() returns once the robot has reported state, so robot.get_state() is valid on the
next line. It raises ConnectError after timeout (5 s by default) without state. On hybrid and
livekit the media tracks are awaited for media_timeout (3 s); the capabilities the SDK claims
are the tracks that arrived.
connect(require_state=False) opens the room without waiting for the firmware: camera,
microphone and speaker work at once, and state and the motion verbs unlock when the first
state frame arrives.
A protocol version other than the one the SDK speaks raises ProtocolMismatchError.
allow_version_skew=True connects anyway, and the robot may misread the commands the SDK
sends. Update the SDK or the robot instead.
A lost link ends a held velocity
After 2 s without state the SDK raises LinkLostError, sends zero velocity if it holds one,
and every verb raises until you close() and connect() again. On udp and hybrid, the
robot also zeroes a velocity 2 s after the last command it received. On livekit, Asimov
Edge stops a held velocity when the SDK sends zero or leaves the room; see
Watchdogs.
Related
- Quickstart: point the SDK at the robot and run the first scripts
- Command Line:
menlo setupandmenlo robots - Drive from Python: the SDK credential and the UDP settings, step by step
- Asimov Manager: the robot's settings
- Reference:
ConnectionConfig,UdpConfig,ManagerConfig,LiveKitConfig
How is this guide?