Connection Modes
UDP, Hybrid and LiveKit: what each carries, what it needs, and how the SDK picks one.
The SDK reaches the robot through Asimov Edge, the service on 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").
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.
Asimov Edge sends UDP state to one host. On the robot, set the Asimov Edge parameters
udp-control to on and udp-state-host to your computer's address, in the Asimov Manager
settings.
config = ConnectionConfig(udp=UdpConfig(host=args.host))
with Robot(config).connect("udp") as robot:
state = robot.state
print(robot.info)
print(f"robot mode {state.mode.name}, armed {robot.armed}")
if state.battery is not None:
print(f"battery {state.battery.soc_percent:.0f} %")
print(f"latest state is {state.age_s * 1000:.0f} ms old")The full script is 01_connect_udp.py.
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 (Developer Credentials). 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.
config = ConnectionConfig(
udp=UdpConfig(host=args.host),
livekit=ManagerConfig(url=args.manager, credential=credential),
)
with Robot(config).connect("hybrid") as robot:
print(robot.info.endpoint)
print(f"camera {robot.has('camera')}, microphone {robot.has('microphone')}")
print(f"robot mode {robot.state.mode.name}")The full script is 02_connect_hybrid.py.
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. The SDK asks Asimov Manager for a room
token, joins, and reports robot.info.endpoint as room@url.
config = ConnectionConfig(livekit=ManagerConfig(url=args.manager, credential=credential))
with Robot(config).connect("livekit") as robot:
print(robot.info.endpoint) # room@url as the identity Asimov Manager issued
print(f"robot mode {robot.state.mode.name}")
print(f"camera {robot.has('camera')}, microphone {robot.has('microphone')}")The full script is 03_connect_livekit.py.
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 Asimov Edge uses on the robot; 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.
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.
To build the connection in code instead, pass a ConnectionConfig to Robot(...), as the
examples above do.
What Connect Waits For
connect() returns once the robot has reported state, so robot.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, for a robot whose firmware is one version ahead or
behind.
A lost link stops the robot
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, Asimov Edge also zeroes a
velocity 2 s after the last command it received. See Safety.
Related
- Quickstart: save a robot and run the first script
- Command Line:
menlo setupandmenlo robots - Asimov Manager: credentials and Asimov Edge parameters
- Reference:
ConnectionConfig,UdpConfig,ManagerConfig,LiveKitConfig
How is this guide?