Skip to content

Commit a95b456

Browse files
fix(unitree-go2): minor issues (#1307)
* fix(unitree-go2): minor issues * fix(unitree-go2): minor issues * fix stand down/up * fix mypy
1 parent 15a57ae commit a95b456

File tree

9 files changed

+29
-62
lines changed

9 files changed

+29
-62
lines changed

dimos/agents/skills/navigation.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def __init__(self) -> None:
6363

6464
@rpc
6565
def start(self) -> None:
66+
super().start()
6667
self._disposables.add(Disposable(self.color_image.subscribe(self._on_color_image)))
6768
self._disposables.add(Disposable(self.odom.subscribe(self._on_odom)))
6869
self._skill_started = True
@@ -92,12 +93,12 @@ def tag_location(self, location_name: str) -> str:
9293

9394
if not self._skill_started:
9495
raise ValueError(f"{self} has not been started.")
95-
tf = self.tf.get("map", "base_link", time_tolerance=2.0)
96-
if not tf:
97-
return "Could not get the robot's current transform."
9896

99-
position = tf.translation
100-
rotation = tf.rotation.to_euler()
97+
if not self._latest_odom:
98+
return "No odometry data received yet, cannot tag location."
99+
100+
position = self._latest_odom.position
101+
rotation = self._latest_odom.orientation
101102

102103
location = RobotLocation(
103104
name=location_name,

dimos/core/__init__.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from __future__ import annotations
22

33
import multiprocessing as mp
4-
import signal
54
import time
65
from typing import TYPE_CHECKING, cast
76

@@ -266,31 +265,6 @@ def start(n: int | None = None, memory_limit: str = "auto") -> DimosCluster:
266265
)
267266

268267
patched_client = patchdask(client, cluster)
269-
patched_client._shutting_down = False # type: ignore[attr-defined]
270-
271-
# Signal handler with proper exit handling
272-
def signal_handler(sig, frame) -> None: # type: ignore[no-untyped-def]
273-
# If already shutting down, force exit
274-
if patched_client._shutting_down: # type: ignore[attr-defined]
275-
import os
276-
277-
console.print("[red]Force exit!")
278-
os._exit(1)
279-
280-
patched_client._shutting_down = True # type: ignore[attr-defined]
281-
console.print(f"[yellow]Shutting down (signal {sig})...")
282-
283-
try:
284-
patched_client.close_all() # type: ignore[attr-defined]
285-
except Exception:
286-
pass
287-
288-
import sys
289-
290-
sys.exit(0)
291-
292-
signal.signal(signal.SIGINT, signal_handler)
293-
signal.signal(signal.SIGTERM, signal_handler)
294268

295269
return patched_client
296270

dimos/e2e_tests/test_person_follow.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,8 @@ def test_person_follow(
6464
) -> None:
6565
start_blueprint("--mujoco-start-pos", "-6.18 0.96", "run", "unitree-go2-agentic")
6666

67-
lcm_spy.save_topic("/rpc/HumanInput/start/res")
68-
lcm_spy.wait_for_saved_topic("/rpc/HumanInput/start/res", timeout=120.0)
69-
lcm_spy.save_topic("/agent")
70-
lcm_spy.wait_for_saved_topic_content("/agent", b"AIMessage", timeout=120.0)
67+
lcm_spy.save_topic("/rpc/Agent/on_system_modules/res")
68+
lcm_spy.wait_for_saved_topic("/rpc/Agent/on_system_modules/res", timeout=120.0)
7169

7270
time.sleep(5)
7371

dimos/e2e_tests/test_spatial_memory.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,8 @@ def test_spatial_memory_navigation(
3434
) -> None:
3535
start_blueprint("run", "unitree-go2-agentic")
3636

37-
lcm_spy.save_topic("/rpc/HumanInput/start/res")
38-
lcm_spy.wait_for_saved_topic("/rpc/HumanInput/start/res", timeout=120.0)
39-
lcm_spy.save_topic("/agent")
40-
lcm_spy.wait_for_saved_topic_content("/agent", b"AIMessage", timeout=120.0)
37+
lcm_spy.save_topic("/rpc/Agent/on_system_modules/res")
38+
lcm_spy.wait_for_saved_topic("/rpc/Agent/on_system_modules/res", timeout=120.0)
4139

4240
time.sleep(5)
4341

dimos/navigation/frontier_exploration/wavefront_frontier_goal_selector.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,16 @@ def stop_exploration(self) -> bool:
735735
):
736736
self.exploration_thread.join(timeout=2.0)
737737

738+
# Publish current location as goal to stop the robot.
739+
if self.latest_odometry is not None:
740+
goal = PoseStamped(
741+
position=self.latest_odometry.position,
742+
orientation=self.latest_odometry.orientation,
743+
frame_id="world",
744+
ts=self.latest_odometry.ts,
745+
)
746+
self.goal_request.publish(goal)
747+
738748
logger.info("Stopped autonomous frontier exploration")
739749
return True
740750

dimos/robot/unitree/connection.py

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import functools
1818
import threading
1919
import time
20-
from typing import TypeAlias
20+
from typing import Any, TypeAlias
2121

2222
import numpy as np
2323
from numpy.typing import NDArray
@@ -34,7 +34,6 @@
3434
WebRTCConnectionMethod,
3535
)
3636

37-
from dimos.core import rpc
3837
from dimos.core.resource import Resource
3938
from dimos.msgs.geometry_msgs import Pose, Transform, Twist
4039
from dimos.msgs.sensor_msgs import Image, PointCloud2
@@ -228,7 +227,7 @@ def run_unsubscription() -> None:
228227
)
229228

230229
# Generic sync API call (we jump into the client thread)
231-
def publish_request(self, topic: str, data: dict): # type: ignore[no-untyped-def, type-arg]
230+
def publish_request(self, topic: str, data: dict[Any, Any]) -> Any:
232231
future = asyncio.run_coroutine_threadsafe(
233232
self.conn.datachannel.pub_sub.publish_request_new(topic, data), self.loop
234233
)
@@ -275,33 +274,20 @@ def video_stream(self) -> Observable[Image]:
275274
def lowstate_stream(self) -> Observable[LowStateMsg]:
276275
return backpressure(self.unitree_sub_stream(RTC_TOPIC["LOW_STATE"]))
277276

278-
def standup_ai(self) -> bool:
279-
return self.publish_request(RTC_TOPIC["SPORT_MOD"], {"api_id": SPORT_CMD["BalanceStand"]}) # type: ignore[no-any-return]
280-
281-
def standup_normal(self) -> bool:
282-
self.publish_request(RTC_TOPIC["SPORT_MOD"], {"api_id": SPORT_CMD["StandUp"]})
283-
time.sleep(0.5)
284-
self.publish_request(RTC_TOPIC["SPORT_MOD"], {"api_id": SPORT_CMD["RecoveryStand"]})
285-
return True
286-
287-
@rpc
288277
def standup(self) -> bool:
289-
if self.mode == "ai":
290-
return self.standup_ai()
291-
else:
292-
return self.standup_normal()
278+
return bool(self.publish_request(RTC_TOPIC["SPORT_MOD"], {"api_id": SPORT_CMD["StandUp"]}))
293279

294-
@rpc
295280
def liedown(self) -> bool:
296-
return self.publish_request(RTC_TOPIC["SPORT_MOD"], {"api_id": SPORT_CMD["StandDown"]}) # type: ignore[no-any-return]
281+
return bool(
282+
self.publish_request(RTC_TOPIC["SPORT_MOD"], {"api_id": SPORT_CMD["StandDown"]})
283+
)
297284

298285
async def handstand(self): # type: ignore[no-untyped-def]
299286
return self.publish_request(
300287
RTC_TOPIC["SPORT_MOD"],
301288
{"api_id": SPORT_CMD["Standup"], "parameter": {"data": True}},
302289
)
303290

304-
@rpc
305291
def color(self, color: VUI_COLOR = VUI_COLOR.RED, colortime: int = 60) -> bool:
306292
return self.publish_request( # type: ignore[no-any-return]
307293
RTC_TOPIC["VUI"],

dimos/robot/unitree/go2/blueprints/basic/unitree_go2_basic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
image_topic="/world/color_image",
5353
optical_frame="camera_optical",
5454
),
55-
"world/global_map": lambda grid: grid.to_rerun(voxel_size=0.1),
55+
"world/global_map": lambda grid: grid.to_rerun(voxel_size=0.1, mode="boxes"),
5656
"world/navigation_costmap": lambda grid: grid.to_rerun(
5757
colormap="Accent",
5858
z_offset=0.015,

dimos/simulation/engines/mujoco_engine.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from typing import TYPE_CHECKING
2222

2323
import mujoco
24-
import mujoco.viewer as viewer # type: ignore[import-untyped]
24+
import mujoco.viewer as viewer # type: ignore[import-untyped,import-not-found]
2525

2626
from dimos.simulation.engines.base import SimulationEngine
2727
from dimos.simulation.utils.xml_parser import JointMapping, build_joint_mappings

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ module = [
360360
"mujoco_playground.*",
361361
"nav_msgs.*",
362362
"open_clip",
363+
"pinocchio",
363364
"piper_sdk.*",
364365
"plotext",
365366
"plum.*",
@@ -375,7 +376,6 @@ module = [
375376
"torchreid",
376377
"ultralytics.*",
377378
"unitree_webrtc_connect.*",
378-
"watchdog.*",
379379
"xarm.*",
380380
]
381381
ignore_missing_imports = true

0 commit comments

Comments
 (0)