Skip to content

sdk: a python client, and a loop to write behaviours in - #271

Open
Nixxx19 wants to merge 3 commits into
pollen-robotics:mainfrom
Nixxx19:a-script-can-drive-the-duck-in-thirty-lines-v2
Open

sdk: a python client, and a loop to write behaviours in#271
Nixxx19 wants to merge 3 commits into
pollen-robotics:mainfrom
Nixxx19:a-script-can-drive-the-duck-in-thirty-lines-v2

Conversation

@Nixxx19

@Nixxx19 Nixxx19 commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

stacked on #266, which is the socket this talks to. M5's finish line is "a server-side script can fetch a frame and send an intent in a few dozen lines", and this is the other half of it.

the investigation M5 says to do first — whether one client covers both webrtc and websocket — i think answers itself once you look at spaces/shared/control.py. that Rpc has already carried the same json-rpc over three transports: a datachannel through the rendezvous, a datachannel on the lan, and http with no webrtc at all. so the transport was never the hard part. the sdk binds a websocket to that same object rather than being a fourth implementation of the wire.

from duck import Duck

with Duck("robot.local") as duck:
    print(duck.health()["healthy"])
    duck.move(vx=0.1)

the part i think is actually worth having is watch(). one call each is fine for a script that asks a question, but a behaviour is a loop, and what it looks at arrives on three streams at three different rates — state at the control rate, depth at 15 hz, frames at whatever you asked for. merging those is what every caller would otherwise write for itself:

for view in duck.watch(fps=4, camera=False):
    if view.nearest and view.nearest < 0.4:
        duck.move(vyaw=0.8)
    else:
        duck.move(vx=0.12)

view.nearest follows tof::Frame::zone rather than re-deriving the thresholds, including the bit that bites: the sensor returns negative distances on a failed convergence and still flags them valid, so taken at face value they are the nearest thing in the room. there's a test for exactly that.

no perception in here. view.frame is the jpeg as it arrived and what's in it is the caller's model to run.

frames are worth a look too — the robot doesn't serve them, it dials out to a socket the sdk opens, so there's no relay candidate or ice anywhere.

drove it against the real agent route with a fake robotd behind it: health, move and stop round-trip, system.pairingPin comes back "not available over this transport", and the loop merges state and depth and picks the right nearest. ten tests on the wire and the depth rules, no robot needed.

couldn't run it against a full mediad locally — webrtcsink isn't packaged in any debian suite so the container has no pipeline — so the live check covers the route and the dispatcher, not the camera.

@Nixxx19 Nixxx19 changed the title sdk: a python client, so a script can fetch a frame and send an intent sdk: a python client, and a loop to write behaviours in Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant