Conversation
Greptile SummaryThis PR adds a full Booster K1 integration — connection module (
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Agent
participant K1Connection
participant BoosterRPC as BoosterConnection (RPC)
participant VideoWS as Robot WebSocket (Video)
participant Robot as Booster K1 Hardware
Note over K1Connection: start() called
K1Connection->>BoosterRPC: BoosterConnection(ip)
K1Connection->>VideoWS: Thread: _run_video_stream()
K1Connection->>K1Connection: Thread: _publish_camera_info()
K1Connection->>K1Connection: cmd_vel.subscribe(self.move)
loop Every 1s
K1Connection-->>K1Connection: camera_info.publish(camera_info_static)
end
loop Video frames (WebSocket)
VideoWS->>Robot: websockets.connect(ws://ip:port)
Robot-->>VideoWS: JPEG bytes
VideoWS->>K1Connection: _on_frame(jpeg_bytes)
K1Connection-->>K1Connection: color_image.publish(image)
end
Agent->>K1Connection: walk(x, y, yaw, duration) [@skill]
K1Connection->>K1Connection: move(twist, duration) [@rpc]
K1Connection->>BoosterRPC: _conn.call(ROBOT_MOVE, req)
BoosterRPC->>Robot: RPC → velocity command
Note over K1Connection: time.sleep(duration)
K1Connection->>BoosterRPC: _conn.call(ROBOT_MOVE, stop)
BoosterRPC->>Robot: RPC → stop command
Agent->>K1Connection: stand() [@skill]
K1Connection->>K1Connection: standup() [@rpc]
K1Connection->>BoosterRPC: call(GET_ROBOT_STATUS)
Robot-->>BoosterRPC: status.mode
K1Connection->>BoosterRPC: call(ROBOT_CHANGE_MODE, PREPARE)
Note over K1Connection: time.sleep(3s)
K1Connection->>BoosterRPC: call(ROBOT_CHANGE_MODE, WALKING)
Note over K1Connection: time.sleep(3s)
K1Connection->>BoosterRPC: call(GET_ROBOT_STATUS) [verify]
|
|
@greptile |
|
@greptile |
|
@greptile |
61082b0 to
6886921
Compare
|
@greptile |
dimos/robot/booster/k1/blueprints/agentic/booster_k1_agentic.py
Outdated
Show resolved
Hide resolved
| def start(self) -> None: | ||
| super().start() | ||
|
|
||
| self._conn = BoosterConnection(ip=self.config.ip) |
There was a problem hiding this comment.
I think K1Connection should not contain BoosterConnection directly.
For unitree, we put the connection inside UnitreeWebRTCConnection so that it can be easily swapped with MujocoConnection if the --simulation flag is passed.
I think you should add a class called BoosterHardwareConnection which contains BoosterConnection.
It would be nice in later PRs to add a simulation for it. I can't easily find one for K1, but mujoco_menagerie has mujoco files for T1 and there's a T1 policy here: https://github.com/google-deepmind/mujoco_playground/blob/main/mujoco_playground/experimental/sim2sim/onnx/t1_policy.onnx
There was a problem hiding this comment.
I like the idea of a BoosterHardwareConnection, I'll add it.
As for the Mujoco side of Booster, I looked into it earlier and I was able to successfully train a policy for the Booster K1 in Mjlab (Mujoco with an Isaac Sim like API), I'll try deploying it tomorrow.
To go about integrating custom policies on the Booster, I think we should rename BoosterConnection to BoosterRPCConnection and BoosterSDKConnection for a low level adapter for the Booster Python SDK.
| return False | ||
| self._conn.call(RpcApiId.ROBOT_MOVE, bytes(stop)) | ||
| return True | ||
| except Exception as e: |
There was a problem hiding this comment.
This try-except just hides errors. It's better to let them be visible.
There was a problem hiding this comment.
As in change the logging type? If so, I changed it from logging.debug to logging.warning
There was a problem hiding this comment.
Warning is better, but personally, I'd remove it entirely so the caller can receive the exception.
… agentic, basic, and smart functionalities
…out navigation skill
Co-authored-by: Paul Nechifor <paul@nechifor.net>
| "navigation-skill-container": "dimos.agents.skills.navigation", | ||
| "object-db-module": "dimos.perception.detection.moduleDB", | ||
| "mid360-module": "dimos.hardware.sensors.lidar.livox.module", | ||
| "navigation-skill": "dimos.agents.skills.navigation", |
There was a problem hiding this comment.
You have conflicts in this file. The best way to solve them is to delete everything in this dict and the one above and let the test regenerate the right values.
Problem
This merge request adds support for the Booster K1 robot, along with accompanying blueprints (
booster-k1-basic,booster-k1,booster-k1-spatial,booster-k1-agentic).Note
This relies on booster-rpc (GitHub source), a library I wrote that provides high-level control of the Booster K1 by interfacing with the same RPC and WebSocket protocols used by the Booster App. Through booster-rpc, Dimensional will be the first and only way to control the Booster wirelessly with no installation or SSH required. Additionally, the App and Dimensional can control the robot concurrently. In the future this will be generalized across all Booster robots
Closes DIM-583
Solution
Breaking Changes
None
How to Test
ROBOT_IPcan be found on the Booster AppContributor License Agreement