diff --git a/dimos/teleop/phone/blueprints.py b/dimos/teleop/phone/blueprints.py index d29c5f77fd..2a41f1dea5 100644 --- a/dimos/teleop/phone/blueprints.py +++ b/dimos/teleop/phone/blueprints.py @@ -14,6 +14,9 @@ # limitations under the License. from dimos.core.coordination.blueprints import autoconnect +from dimos.core.transport import JpegLcmTransport, LCMTransport +from dimos.msgs.geometry_msgs.Twist import Twist +from dimos.msgs.sensor_msgs.Image import Image from dimos.robot.unitree.go2.blueprints.basic.unitree_go2_basic import unitree_go2_basic from dimos.robot.unitree.go2.blueprints.basic.unitree_go2_fleet import unitree_go2_fleet from dimos.teleop.phone.phone_extensions import SimplePhoneTeleop @@ -27,6 +30,14 @@ teleop_phone_go2 = autoconnect( SimplePhoneTeleop.blueprint(), unitree_go2_basic, +).transports( + { + # Browser/Rerun keyboard controls publish tele_cmd_vel; Go2Connection + # listens on cmd_vel in this direct teleop stack. + ("tele_cmd_vel", Twist): LCMTransport("/cmd_vel", Twist), + # RerunBridge listens to LCM pubsubs, so expose the camera over JPEG-LCM. + ("color_image", Image): JpegLcmTransport("/color_image", Image), + } ) # Phone teleop wired to Go2 fleet — twist commands sent to all robots diff --git a/dimos/teleop/phone/test_blueprints.py b/dimos/teleop/phone/test_blueprints.py new file mode 100644 index 0000000000..c7945f5aec --- /dev/null +++ b/dimos/teleop/phone/test_blueprints.py @@ -0,0 +1,34 @@ +# Copyright 2025-2026 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. + +from dimos.core.transport import JpegLcmTransport, LCMTransport +from dimos.msgs.geometry_msgs.Twist import Twist +from dimos.msgs.sensor_msgs.Image import Image +from dimos.teleop.phone.blueprints import teleop_phone_go2 + + +def test_teleop_phone_go2_routes_browser_keyboard_to_go2_cmd_vel() -> None: + transport = teleop_phone_go2.transport_map[("tele_cmd_vel", Twist)] + + assert type(transport) is LCMTransport + assert transport.topic.topic == "/cmd_vel" + assert transport.topic.lcm_type is Twist + + +def test_teleop_phone_go2_exposes_camera_to_rerun_over_jpeg_lcm() -> None: + transport = teleop_phone_go2.transport_map[("color_image", Image)] + + assert isinstance(transport, JpegLcmTransport) + assert transport.topic.topic == "/color_image" + assert transport.topic.lcm_type is Image