From d53e7d112c7697d82cfc3194b4ecfc4d2880cceb Mon Sep 17 00:00:00 2001 From: lesh Date: Sat, 12 Jul 2025 17:15:39 -0700 Subject: [PATCH 1/7] foxglove bridge stub --- dimos/robot/foxglove_bridge.py | 50 +++++++++++++++++++ .../multiprocess/unitree_go2.py | 6 +++ 2 files changed, 56 insertions(+) create mode 100644 dimos/robot/foxglove_bridge.py diff --git a/dimos/robot/foxglove_bridge.py b/dimos/robot/foxglove_bridge.py new file mode 100644 index 0000000000..fb0b974732 --- /dev/null +++ b/dimos/robot/foxglove_bridge.py @@ -0,0 +1,50 @@ +# Copyright 2025 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import asyncio +import threading + +# this is missing, I'm just trying to import lcm_foxglove_bridge.py from dimos_utils +import dimos_utils.lcm_foxglove_bridge as bridge +from foxglove_websocket import run_cancellable + +from dimos.core import Module, rpc + + +class FoxgloveBridge(Module): + _thread: threading.Thread + _loop: asyncio.AbstractEventLoop + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.start() + + @rpc + def start(self): + def run_bridge(): + self._loop = asyncio.new_event_loop() + asyncio.set_event_loop(self._loop) + try: + self._loop.run_until_complete(bridge.main()) + except Exception as e: + print(f"Foxglove bridge error: {e}") + + self._thread = threading.Thread(target=run_bridge, daemon=True) + self._thread.start() + + @rpc + def stop(self): + if self._loop and self._loop.is_running(): + self._loop.call_soon_threadsafe(self._loop.stop) + self._thread.join(timeout=2) diff --git a/dimos/robot/unitree_webrtc/multiprocess/unitree_go2.py b/dimos/robot/unitree_webrtc/multiprocess/unitree_go2.py index 659eafde0c..1740b7edbc 100644 --- a/dimos/robot/unitree_webrtc/multiprocess/unitree_go2.py +++ b/dimos/robot/unitree_webrtc/multiprocess/unitree_go2.py @@ -30,6 +30,7 @@ from dimos.msgs.geometry_msgs import Vector3 from dimos.msgs.sensor_msgs import Image from dimos.protocol import pubsub +from dimos.robot.foxglove_bridge import FoxgloveBridge from dimos.robot.global_planner import AstarPlanner from dimos.robot.local_planner.simple import SimplePlanner from dimos.robot.unitree_webrtc.connection import VideoMessage, WebRTCRobot @@ -182,6 +183,8 @@ async def run(ip): ctrl.plancmd.transport = core.LCMTransport("/global_target", Vector3) global_planner.target.connect(ctrl.plancmd) + foxglove_bridge = FoxgloveBridge() + # we review the structure print("\n") for module in [connection, mapper, local_planner, global_planner, ctrl]: @@ -199,6 +202,9 @@ async def run(ip): print(colors.green("starting global planner")) global_planner.start() + print(colors.green("starting foxglove bridge")) + foxglove_bridge.start() + # uncomment to move the bot # print(colors.green("starting ctrl")) # ctrl.start() From c1bbeb18c8d67ba023f5e925734b844cffb39186 Mon Sep 17 00:00:00 2001 From: lesh Date: Sat, 12 Jul 2025 17:18:45 -0700 Subject: [PATCH 2/7] removed foxglove_websocket import --- dimos/robot/foxglove_bridge.py | 1 - 1 file changed, 1 deletion(-) diff --git a/dimos/robot/foxglove_bridge.py b/dimos/robot/foxglove_bridge.py index fb0b974732..5d78fc5396 100644 --- a/dimos/robot/foxglove_bridge.py +++ b/dimos/robot/foxglove_bridge.py @@ -17,7 +17,6 @@ # this is missing, I'm just trying to import lcm_foxglove_bridge.py from dimos_utils import dimos_utils.lcm_foxglove_bridge as bridge -from foxglove_websocket import run_cancellable from dimos.core import Module, rpc From 6414a9634c3a34d470af7665f76a7cc3f5ef6c86 Mon Sep 17 00:00:00 2001 From: stash Date: Sat, 12 Jul 2025 18:25:15 -0700 Subject: [PATCH 3/7] Fully working Foxglove bridge as module via dimos_utils package --- dimos/robot/run_foxglove_bridge.py | 46 ++++++++++++++++++++++++++++++ pyproject.toml | 6 +++- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 dimos/robot/run_foxglove_bridge.py diff --git a/dimos/robot/run_foxglove_bridge.py b/dimos/robot/run_foxglove_bridge.py new file mode 100644 index 0000000000..6656b61dca --- /dev/null +++ b/dimos/robot/run_foxglove_bridge.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +""" +use lcm_foxglove_bridge as a module from dimos_utils +""" + +import asyncio +import threading +import dimos_utils.lcm_foxglove_bridge as bridge + +def run_bridge_example(): + """Example of running the bridge in a separate thread""" + + def bridge_thread(): + """Thread function to run the bridge""" + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + bridge_runner = bridge.LcmFoxgloveBridgeRunner( + host="0.0.0.0", + port=8765, + debug=True, + num_threads=4 + ) + + loop.run_until_complete(bridge_runner.run()) + except Exception as e: + print(f"Bridge error: {e}") + finally: + loop.close() + + thread = threading.Thread(target=bridge_thread, daemon=True) + thread.start() + + print("Bridge started in background thread") + print("Open Foxglove Studio and connect to ws://localhost:8765") + print("Press Ctrl+C to exit") + + try: + while True: + threading.Event().wait(1) + except KeyboardInterrupt: + print("Shutting down...") + + +if __name__ == "__main__": + run_bridge_example() \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 5cb8c5be9d..cf6de5810f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,7 +91,11 @@ dependencies = [ # Multiprocess "dask[complete]==2025.5.1", - "lcm_msgs @ git+https://github.com/dimensionalOS/python_lcm_msgs.git@main#egg=lcm_msgs" + "lcm_msgs @ git+https://github.com/dimensionalOS/python_lcm_msgs.git@main#egg=lcm_msgs", + + # LCM / DimOS utilities + "dimos_utils @ git+https://github.com/dimensionalOS/dimos_utils.git@main#egg=dimos_utils", + ] [project.optional-dependencies] From c53cd4d738193bc81c40e697f6a95c2c08bf3db8 Mon Sep 17 00:00:00 2001 From: stash Date: Sat, 12 Jul 2025 18:53:51 -0700 Subject: [PATCH 4/7] test --- .gitignore | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index f6eaac7f5b..6378d36468 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,12 @@ -.venv/ .vscode/ # Ignore Python cache files __pycache__/ *.pyc -.venv* -venv* + +# Ignore virtual environment directories +*venv*/ +.venv*/ .ssh/ # Ignore python tooling dirs From 5f6d1220a70a59bf271bf30922a4de3adacf7d2e Mon Sep 17 00:00:00 2001 From: stash Date: Sat, 12 Jul 2025 23:47:41 -0700 Subject: [PATCH 5/7] lcm_msgs integrated into dimos_utils, import changes --- dimos/msgs/geometry_msgs/Pose.py | 2 +- dimos/msgs/geometry_msgs/PoseStamped.py | 6 +- dimos/msgs/geometry_msgs/Quaternion.py | 2 +- dimos/msgs/geometry_msgs/Vector3.py | 2 +- dimos/msgs/geometry_msgs/test_Pose.py | 2 +- dimos/msgs/geometry_msgs/test_Quaternion.py | 2 +- dimos/msgs/sensor_msgs/Image.py | 4 +- dimos/msgs/sensor_msgs/PointCloud2.py | 8 +- dimos/{robot => utils}/run_foxglove_bridge.py | 28 ++++-- dimos/utils/test_foxglove_bridge.py | 90 +++++++++++++++++++ pyproject.toml | 1 - 11 files changed, 125 insertions(+), 22 deletions(-) rename dimos/{robot => utils}/run_foxglove_bridge.py (60%) create mode 100644 dimos/utils/test_foxglove_bridge.py diff --git a/dimos/msgs/geometry_msgs/Pose.py b/dimos/msgs/geometry_msgs/Pose.py index 33f0ae22a9..12549766c6 100644 --- a/dimos/msgs/geometry_msgs/Pose.py +++ b/dimos/msgs/geometry_msgs/Pose.py @@ -19,7 +19,7 @@ from io import BytesIO from typing import BinaryIO, TypeAlias -from lcm_msgs.geometry_msgs import Pose as LCMPose +from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import Pose as LCMPose from plum import dispatch from dimos.msgs.geometry_msgs.Quaternion import Quaternion, QuaternionConvertable diff --git a/dimos/msgs/geometry_msgs/PoseStamped.py b/dimos/msgs/geometry_msgs/PoseStamped.py index 2a35ccf445..d8752b52f9 100644 --- a/dimos/msgs/geometry_msgs/PoseStamped.py +++ b/dimos/msgs/geometry_msgs/PoseStamped.py @@ -17,9 +17,9 @@ from io import BytesIO from typing import BinaryIO, TypeAlias -from lcm_msgs.geometry_msgs import PoseStamped as LCMPoseStamped -from lcm_msgs.std_msgs import Header as LCMHeader -from lcm_msgs.std_msgs import Time as LCMTime +from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import PoseStamped as LCMPoseStamped +from dimos_utils.python_lcm_msgs.lcm_msgs.std_msgs import Header as LCMHeader +from dimos_utils.python_lcm_msgs.lcm_msgs.std_msgs import Time as LCMTime from plum import dispatch from dimos.msgs.geometry_msgs.Pose import Pose diff --git a/dimos/msgs/geometry_msgs/Quaternion.py b/dimos/msgs/geometry_msgs/Quaternion.py index dfb0e21d95..2b1dd5469c 100644 --- a/dimos/msgs/geometry_msgs/Quaternion.py +++ b/dimos/msgs/geometry_msgs/Quaternion.py @@ -20,7 +20,7 @@ from typing import BinaryIO, TypeAlias import numpy as np -from lcm_msgs.geometry_msgs import Quaternion as LCMQuaternion +from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import Quaternion as LCMQuaternion from plum import dispatch from dimos.msgs.geometry_msgs.Vector3 import Vector3 diff --git a/dimos/msgs/geometry_msgs/Vector3.py b/dimos/msgs/geometry_msgs/Vector3.py index 0d63300505..c045511b2d 100644 --- a/dimos/msgs/geometry_msgs/Vector3.py +++ b/dimos/msgs/geometry_msgs/Vector3.py @@ -20,7 +20,7 @@ from typing import BinaryIO, TypeAlias import numpy as np -from lcm_msgs.geometry_msgs import Vector3 as LCMVector3 +from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import Vector3 as LCMVector3 from plum import dispatch # Types that can be converted to/from Vector diff --git a/dimos/msgs/geometry_msgs/test_Pose.py b/dimos/msgs/geometry_msgs/test_Pose.py index 9dc5330f7f..89b2ed68ed 100644 --- a/dimos/msgs/geometry_msgs/test_Pose.py +++ b/dimos/msgs/geometry_msgs/test_Pose.py @@ -16,7 +16,7 @@ import numpy as np import pytest -from lcm_msgs.geometry_msgs import Pose as LCMPose +from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import Pose as LCMPose from dimos.msgs.geometry_msgs.Pose import Pose, to_pose from dimos.msgs.geometry_msgs.Quaternion import Quaternion diff --git a/dimos/msgs/geometry_msgs/test_Quaternion.py b/dimos/msgs/geometry_msgs/test_Quaternion.py index 7f20143e2c..b63c1ba484 100644 --- a/dimos/msgs/geometry_msgs/test_Quaternion.py +++ b/dimos/msgs/geometry_msgs/test_Quaternion.py @@ -14,7 +14,7 @@ import numpy as np import pytest -from lcm_msgs.geometry_msgs import Quaternion as LCMQuaternion +from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import Quaternion as LCMQuaternion from dimos.msgs.geometry_msgs.Quaternion import Quaternion diff --git a/dimos/msgs/sensor_msgs/Image.py b/dimos/msgs/sensor_msgs/Image.py index e32a838dfc..cf3b264a46 100644 --- a/dimos/msgs/sensor_msgs/Image.py +++ b/dimos/msgs/sensor_msgs/Image.py @@ -21,8 +21,8 @@ import numpy as np # Import LCM types -from lcm_msgs.sensor_msgs.Image import Image as LCMImage -from lcm_msgs.std_msgs.Header import Header +from dimos_utils.python_lcm_msgs.lcm_msgs.sensor_msgs.Image import Image as LCMImage +from dimos_utils.python_lcm_msgs.lcm_msgs.std_msgs.Header import Header from dimos.types.timestamped import Timestamped diff --git a/dimos/msgs/sensor_msgs/PointCloud2.py b/dimos/msgs/sensor_msgs/PointCloud2.py index b2835196ea..4c84b8e0c8 100644 --- a/dimos/msgs/sensor_msgs/PointCloud2.py +++ b/dimos/msgs/sensor_msgs/PointCloud2.py @@ -22,9 +22,11 @@ import open3d as o3d # Import LCM types -from lcm_msgs.sensor_msgs.PointCloud2 import PointCloud2 as LCMPointCloud2 -from lcm_msgs.sensor_msgs.PointField import PointField -from lcm_msgs.std_msgs.Header import Header +from dimos_utils.python_lcm_msgs.lcm_msgs.sensor_msgs.PointCloud2 import ( + PointCloud2 as LCMPointCloud2, +) +from dimos_utils.python_lcm_msgs.lcm_msgs.sensor_msgs.PointField import PointField +from dimos_utils.python_lcm_msgs.lcm_msgs.std_msgs.Header import Header from dimos.types.timestamped import Timestamped diff --git a/dimos/robot/run_foxglove_bridge.py b/dimos/utils/run_foxglove_bridge.py similarity index 60% rename from dimos/robot/run_foxglove_bridge.py rename to dimos/utils/run_foxglove_bridge.py index 6656b61dca..647f46ddc4 100644 --- a/dimos/robot/run_foxglove_bridge.py +++ b/dimos/utils/run_foxglove_bridge.py @@ -1,4 +1,18 @@ #!/usr/bin/env python3 +# Copyright 2025 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + """ use lcm_foxglove_bridge as a module from dimos_utils """ @@ -7,19 +21,17 @@ import threading import dimos_utils.lcm_foxglove_bridge as bridge + def run_bridge_example(): """Example of running the bridge in a separate thread""" - + def bridge_thread(): """Thread function to run the bridge""" loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: bridge_runner = bridge.LcmFoxgloveBridgeRunner( - host="0.0.0.0", - port=8765, - debug=True, - num_threads=4 + host="0.0.0.0", port=8765, debug=True, num_threads=4 ) loop.run_until_complete(bridge_runner.run()) @@ -30,11 +42,11 @@ def bridge_thread(): thread = threading.Thread(target=bridge_thread, daemon=True) thread.start() - + print("Bridge started in background thread") print("Open Foxglove Studio and connect to ws://localhost:8765") print("Press Ctrl+C to exit") - + try: while True: threading.Event().wait(1) @@ -43,4 +55,4 @@ def bridge_thread(): if __name__ == "__main__": - run_bridge_example() \ No newline at end of file + run_bridge_example() diff --git a/dimos/utils/test_foxglove_bridge.py b/dimos/utils/test_foxglove_bridge.py new file mode 100644 index 0000000000..2207dae563 --- /dev/null +++ b/dimos/utils/test_foxglove_bridge.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# Copyright 2025 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Test for foxglove bridge import and basic functionality +""" + +import pytest +import threading +import time +import warnings +from unittest.mock import patch, MagicMock + +warnings.filterwarnings("ignore", category=DeprecationWarning, module="websockets.server") +warnings.filterwarnings("ignore", category=DeprecationWarning, module="websockets.legacy") + + +def test_foxglove_bridge_import(): + """Test that the foxglove bridge can be imported successfully.""" + with pytest.warns(DeprecationWarning): + try: + import dimos_utils.lcm_foxglove_bridge as bridge + + assert hasattr(bridge, "LcmFoxgloveBridgeRunner") + except ImportError as e: + pytest.fail(f"Failed to import foxglove bridge: {e}") + + +def test_foxglove_bridge_runner_init(): + """Test that LcmFoxgloveBridgeRunner can be initialized with default parameters.""" + try: + import dimos_utils.lcm_foxglove_bridge as bridge + + runner = bridge.LcmFoxgloveBridgeRunner( + host="localhost", port=8765, debug=False, num_threads=2 + ) + + # Check that the runner was created successfully + assert runner is not None + + except Exception as e: + pytest.fail(f"Failed to initialize LcmFoxgloveBridgeRunner: {e}") + + +def test_foxglove_bridge_runner_params(): + """Test that LcmFoxgloveBridgeRunner accepts various parameter configurations.""" + try: + import dimos_utils.lcm_foxglove_bridge as bridge + + configs = [ + {"host": "0.0.0.0", "port": 8765, "debug": True, "num_threads": 1}, + {"host": "127.0.0.1", "port": 9090, "debug": False, "num_threads": 4}, + {"host": "localhost", "port": 8080, "debug": True, "num_threads": 2}, + ] + + for config in configs: + runner = bridge.LcmFoxgloveBridgeRunner(**config) + assert runner is not None + + except Exception as e: + pytest.fail(f"Failed to create runner with different configs: {e}") + + +def test_bridge_runner_has_run_method(): + """Test that the bridge runner has a run method that can be called.""" + try: + import dimos_utils.lcm_foxglove_bridge as bridge + + runner = bridge.LcmFoxgloveBridgeRunner( + host="localhost", port=8765, debug=False, num_threads=1 + ) + + # Check that the run method exists + assert hasattr(runner, "run") + assert callable(getattr(runner, "run")) + + except Exception as e: + pytest.fail(f"Failed to verify run method: {e}") diff --git a/pyproject.toml b/pyproject.toml index cf6de5810f..aa1c353f10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,7 +91,6 @@ dependencies = [ # Multiprocess "dask[complete]==2025.5.1", - "lcm_msgs @ git+https://github.com/dimensionalOS/python_lcm_msgs.git@main#egg=lcm_msgs", # LCM / DimOS utilities "dimos_utils @ git+https://github.com/dimensionalOS/dimos_utils.git@main#egg=dimos_utils", From b04ee1e6bb63e0154e2edb2277274107cb05ef13 Mon Sep 17 00:00:00 2001 From: stash Date: Sat, 12 Jul 2025 23:49:40 -0700 Subject: [PATCH 6/7] Pytest for foxglove bridge --- dimos/utils/test_foxglove_bridge.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dimos/utils/test_foxglove_bridge.py b/dimos/utils/test_foxglove_bridge.py index 2207dae563..fc714ae7d6 100644 --- a/dimos/utils/test_foxglove_bridge.py +++ b/dimos/utils/test_foxglove_bridge.py @@ -29,13 +29,12 @@ def test_foxglove_bridge_import(): """Test that the foxglove bridge can be imported successfully.""" - with pytest.warns(DeprecationWarning): - try: - import dimos_utils.lcm_foxglove_bridge as bridge + try: + import dimos_utils.lcm_foxglove_bridge as bridge - assert hasattr(bridge, "LcmFoxgloveBridgeRunner") - except ImportError as e: - pytest.fail(f"Failed to import foxglove bridge: {e}") + assert hasattr(bridge, "LcmFoxgloveBridgeRunner") + except ImportError as e: + pytest.fail(f"Failed to import foxglove bridge: {e}") def test_foxglove_bridge_runner_init(): From e0340968711cfeb9259a5e5e1c352060d4ae5b5c Mon Sep 17 00:00:00 2001 From: stash Date: Mon, 14 Jul 2025 15:21:18 -0700 Subject: [PATCH 7/7] Created dimos-lcm package, added tests --- dimos/msgs/geometry_msgs/Pose.py | 2 +- dimos/msgs/geometry_msgs/PoseStamped.py | 6 +++--- dimos/msgs/geometry_msgs/Quaternion.py | 2 +- dimos/msgs/geometry_msgs/Vector3.py | 2 +- dimos/msgs/geometry_msgs/test_Pose.py | 2 +- dimos/msgs/geometry_msgs/test_Quaternion.py | 2 +- dimos/msgs/sensor_msgs/Image.py | 4 ++-- dimos/msgs/sensor_msgs/PointCloud2.py | 6 +++--- dimos/robot/foxglove_bridge.py | 4 ++-- dimos/utils/run_foxglove_bridge.py | 4 ++-- dimos/utils/test_foxglove_bridge.py | 8 ++++---- pyproject.toml | 2 +- 12 files changed, 22 insertions(+), 22 deletions(-) diff --git a/dimos/msgs/geometry_msgs/Pose.py b/dimos/msgs/geometry_msgs/Pose.py index 12549766c6..eb1e879709 100644 --- a/dimos/msgs/geometry_msgs/Pose.py +++ b/dimos/msgs/geometry_msgs/Pose.py @@ -19,7 +19,7 @@ from io import BytesIO from typing import BinaryIO, TypeAlias -from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import Pose as LCMPose +from dimos_lcm.geometry_msgs import Pose as LCMPose from plum import dispatch from dimos.msgs.geometry_msgs.Quaternion import Quaternion, QuaternionConvertable diff --git a/dimos/msgs/geometry_msgs/PoseStamped.py b/dimos/msgs/geometry_msgs/PoseStamped.py index d8752b52f9..237cf31225 100644 --- a/dimos/msgs/geometry_msgs/PoseStamped.py +++ b/dimos/msgs/geometry_msgs/PoseStamped.py @@ -17,9 +17,9 @@ from io import BytesIO from typing import BinaryIO, TypeAlias -from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import PoseStamped as LCMPoseStamped -from dimos_utils.python_lcm_msgs.lcm_msgs.std_msgs import Header as LCMHeader -from dimos_utils.python_lcm_msgs.lcm_msgs.std_msgs import Time as LCMTime +from dimos_lcm.geometry_msgs import PoseStamped as LCMPoseStamped +from dimos_lcm.std_msgs import Header as LCMHeader +from dimos_lcm.std_msgs import Time as LCMTime from plum import dispatch from dimos.msgs.geometry_msgs.Pose import Pose diff --git a/dimos/msgs/geometry_msgs/Quaternion.py b/dimos/msgs/geometry_msgs/Quaternion.py index 2b1dd5469c..3fb13df532 100644 --- a/dimos/msgs/geometry_msgs/Quaternion.py +++ b/dimos/msgs/geometry_msgs/Quaternion.py @@ -20,7 +20,7 @@ from typing import BinaryIO, TypeAlias import numpy as np -from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import Quaternion as LCMQuaternion +from dimos_lcm.geometry_msgs import Quaternion as LCMQuaternion from plum import dispatch from dimos.msgs.geometry_msgs.Vector3 import Vector3 diff --git a/dimos/msgs/geometry_msgs/Vector3.py b/dimos/msgs/geometry_msgs/Vector3.py index c045511b2d..896d6bc43b 100644 --- a/dimos/msgs/geometry_msgs/Vector3.py +++ b/dimos/msgs/geometry_msgs/Vector3.py @@ -20,7 +20,7 @@ from typing import BinaryIO, TypeAlias import numpy as np -from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import Vector3 as LCMVector3 +from dimos_lcm.geometry_msgs import Vector3 as LCMVector3 from plum import dispatch # Types that can be converted to/from Vector diff --git a/dimos/msgs/geometry_msgs/test_Pose.py b/dimos/msgs/geometry_msgs/test_Pose.py index 89b2ed68ed..590a17549c 100644 --- a/dimos/msgs/geometry_msgs/test_Pose.py +++ b/dimos/msgs/geometry_msgs/test_Pose.py @@ -16,7 +16,7 @@ import numpy as np import pytest -from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import Pose as LCMPose +from dimos_lcm.geometry_msgs import Pose as LCMPose from dimos.msgs.geometry_msgs.Pose import Pose, to_pose from dimos.msgs.geometry_msgs.Quaternion import Quaternion diff --git a/dimos/msgs/geometry_msgs/test_Quaternion.py b/dimos/msgs/geometry_msgs/test_Quaternion.py index b63c1ba484..ab049f809f 100644 --- a/dimos/msgs/geometry_msgs/test_Quaternion.py +++ b/dimos/msgs/geometry_msgs/test_Quaternion.py @@ -14,7 +14,7 @@ import numpy as np import pytest -from dimos_utils.python_lcm_msgs.lcm_msgs.geometry_msgs import Quaternion as LCMQuaternion +from dimos_lcm.geometry_msgs import Quaternion as LCMQuaternion from dimos.msgs.geometry_msgs.Quaternion import Quaternion diff --git a/dimos/msgs/sensor_msgs/Image.py b/dimos/msgs/sensor_msgs/Image.py index cf3b264a46..6179746340 100644 --- a/dimos/msgs/sensor_msgs/Image.py +++ b/dimos/msgs/sensor_msgs/Image.py @@ -21,8 +21,8 @@ import numpy as np # Import LCM types -from dimos_utils.python_lcm_msgs.lcm_msgs.sensor_msgs.Image import Image as LCMImage -from dimos_utils.python_lcm_msgs.lcm_msgs.std_msgs.Header import Header +from dimos_lcm.sensor_msgs.Image import Image as LCMImage +from dimos_lcm.std_msgs.Header import Header from dimos.types.timestamped import Timestamped diff --git a/dimos/msgs/sensor_msgs/PointCloud2.py b/dimos/msgs/sensor_msgs/PointCloud2.py index 4c84b8e0c8..776c81d056 100644 --- a/dimos/msgs/sensor_msgs/PointCloud2.py +++ b/dimos/msgs/sensor_msgs/PointCloud2.py @@ -22,11 +22,11 @@ import open3d as o3d # Import LCM types -from dimos_utils.python_lcm_msgs.lcm_msgs.sensor_msgs.PointCloud2 import ( +from dimos_lcm.sensor_msgs.PointCloud2 import ( PointCloud2 as LCMPointCloud2, ) -from dimos_utils.python_lcm_msgs.lcm_msgs.sensor_msgs.PointField import PointField -from dimos_utils.python_lcm_msgs.lcm_msgs.std_msgs.Header import Header +from dimos_lcm.sensor_msgs.PointField import PointField +from dimos_lcm.std_msgs.Header import Header from dimos.types.timestamped import Timestamped diff --git a/dimos/robot/foxglove_bridge.py b/dimos/robot/foxglove_bridge.py index 5d78fc5396..a0374fc251 100644 --- a/dimos/robot/foxglove_bridge.py +++ b/dimos/robot/foxglove_bridge.py @@ -15,8 +15,8 @@ import asyncio import threading -# this is missing, I'm just trying to import lcm_foxglove_bridge.py from dimos_utils -import dimos_utils.lcm_foxglove_bridge as bridge +# this is missing, I'm just trying to import lcm_foxglove_bridge.py from dimos_lcm +import dimos_lcm.lcm_foxglove_bridge as bridge from dimos.core import Module, rpc diff --git a/dimos/utils/run_foxglove_bridge.py b/dimos/utils/run_foxglove_bridge.py index 647f46ddc4..dadb7c2529 100644 --- a/dimos/utils/run_foxglove_bridge.py +++ b/dimos/utils/run_foxglove_bridge.py @@ -14,12 +14,12 @@ # limitations under the License. """ -use lcm_foxglove_bridge as a module from dimos_utils +use lcm_foxglove_bridge as a module from dimos_lcm """ import asyncio import threading -import dimos_utils.lcm_foxglove_bridge as bridge +import dimos_lcm.lcm_foxglove_bridge as bridge def run_bridge_example(): diff --git a/dimos/utils/test_foxglove_bridge.py b/dimos/utils/test_foxglove_bridge.py index fc714ae7d6..ecedb90573 100644 --- a/dimos/utils/test_foxglove_bridge.py +++ b/dimos/utils/test_foxglove_bridge.py @@ -30,7 +30,7 @@ def test_foxglove_bridge_import(): """Test that the foxglove bridge can be imported successfully.""" try: - import dimos_utils.lcm_foxglove_bridge as bridge + import dimos_lcm.lcm_foxglove_bridge as bridge assert hasattr(bridge, "LcmFoxgloveBridgeRunner") except ImportError as e: @@ -40,7 +40,7 @@ def test_foxglove_bridge_import(): def test_foxglove_bridge_runner_init(): """Test that LcmFoxgloveBridgeRunner can be initialized with default parameters.""" try: - import dimos_utils.lcm_foxglove_bridge as bridge + import dimos_lcm.lcm_foxglove_bridge as bridge runner = bridge.LcmFoxgloveBridgeRunner( host="localhost", port=8765, debug=False, num_threads=2 @@ -56,7 +56,7 @@ def test_foxglove_bridge_runner_init(): def test_foxglove_bridge_runner_params(): """Test that LcmFoxgloveBridgeRunner accepts various parameter configurations.""" try: - import dimos_utils.lcm_foxglove_bridge as bridge + import dimos_lcm.lcm_foxglove_bridge as bridge configs = [ {"host": "0.0.0.0", "port": 8765, "debug": True, "num_threads": 1}, @@ -75,7 +75,7 @@ def test_foxglove_bridge_runner_params(): def test_bridge_runner_has_run_method(): """Test that the bridge runner has a run method that can be called.""" try: - import dimos_utils.lcm_foxglove_bridge as bridge + import dimos_lcm.lcm_foxglove_bridge as bridge runner = bridge.LcmFoxgloveBridgeRunner( host="localhost", port=8765, debug=False, num_threads=1 diff --git a/pyproject.toml b/pyproject.toml index aa1c353f10..2d258827a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,7 +93,7 @@ dependencies = [ "dask[complete]==2025.5.1", # LCM / DimOS utilities - "dimos_utils @ git+https://github.com/dimensionalOS/dimos_utils.git@main#egg=dimos_utils", + "dimos-lcm @ git+https://github.com/dimensionalOS/dimos-lcm.git@main", ]