Merged
Conversation
Introduce UnitreeGo2- and TurtleBot4-specific odom/rplidar inputs and backgrounds and switch configs to use them. Many config JSON5 files updated to replace generic "Odom"/"RPLidar" types with UnitreeGo2 or TurtleBot4 variants (including renaming fabric_gps -> unitree_go2_fabric_gps and GPS reader to UnitreeGo2GPSOdomReader). Action connectors and background code imports were adjusted to use providers.unitree_go2_* and providers.turtlebot4_* implementations; RPLidar and odom background/input plugins were renamed or added (unitree_go2_rplidar, unitree_go2_odom, turtlebot4_odom, turtlebot4_rplidar). Several legacy test config files and the old generic odom background were removed. Tests and provider references were updated/renamed accordingly to align with the new provider/plugin names.
Refactor test patches to match renamed plugin/provider modules and classes with the unitree_go2_* prefix. Updated patch targets for IOProvider, OdomProvider/UnitreeGo2OdomProvider, RPLidarProvider/UnitreeGo2RPLidarProvider and related time/asyncio imports, adjusted assertion expectations (e.g. add_input source name and provider init args). These changes keep tests aligned with the refactored module and class names.
Rename mock and update references to match the UnitreeGo2RPLidar plugin. Renamed tests/integration/mock_inputs/mock_rplidar.py -> mock_unitree_go2_rplidar.py and class MockRPLidar -> MockUnitreeGo2RPLidar; updated tests/integration/mock_inputs/input_registry.py to import the new mock, register the mock under the "UnitreeGo2RPLidar" key, adjust mock module mappings, and update the unregister list; updated tests/integration/data/test_cases/rplidar_test.json5 to use type "UnitreeGo2RPLidar". This keeps mock names consistent with the real plugin identifier.
Remove Zenoh-related settings from the mock Unitree Go2 RPLidar input: drop the `use_zenoh` flag from the lidar config and remove the conditional handling that added `URID` and logging. This simplifies the test mock by eliminating Zenoh-specific configuration and behavior.
Remove the deprecated simple_paths option from RPLidar configs and providers (TurtleBot4 and Unitree Go2). Simplified path selection logic to always use the single default path and removed related config fields (use_zenoh, URID, machine_type where applicable). Update MoveZenoh connector to import and instantiate the TurtleBot4 RPLidar provider. Rename/cleanup the turtlebot4_odom background and add comprehensive unit tests for TurtleBot4 and Unitree odom and RPLidar backgrounds and inputs.
Add a comprehensive test suite for the TurtleBot4 RPLidar plugin. Tests cover RPLidarConfig defaults and custom values, TurtleBot4RPLidar initialization and provider parameter passing, async polling (_poll) with and without data, _raw_to_text and raw_to_text buffering behavior, formatted_latest_buffer (including buffer clearing and IOProvider interaction), and _extract_lidar_config. Uses unittest.mock and pytest (including async tests).
Add comprehensive unit tests for OdomProviderBase, TurtleBot4OdomProvider, and TurtleBot4RPLidarProvider. New test modules mock multiprocessing/threading and external dependencies (Zenoh, D435, sensor messages) and cover initialization, singleton behavior, start/stop, odometry processing (including quaternion->euler/yaw conversions), file logging, zenoh scan handling, path processing, and RPLidar config. Also remove an unused debug logging line from turtlebot4_rplidar_provider.py to tidy the implementation.
Fix incorrect tuple unpacking in tests/providers/test_turtlebot4_odom_provider.py so mock_process is assigned from the correct position in the mock_multiprocessing fixture. This ensures the test uses the intended mock process object when verifying that logging config is passed to the processor.
Clean up tests/providers/test_turtlebot4_rplidar_provider.py by removing redundant inline comments that described obvious assertions (subscriber declaration and path/angle checks). No functional changes—only test file comment cleanup to reduce noise.
Introduce a new UnitreeG1OdomProvider implementing OdomProviderBase to retrieve odometry/pose from Unitree G1 robots via CycloneDDS. Adds g1_odom_processor (runs in a separate process) which initializes the CycloneDDS channel, subscribes to rt/utlidar/robot_pose (PoseStamped_) and pushes messages into a multiprocessing queue; logging is configurable via existing logging helpers. The provider is a singleton that starts a multiprocessing subscriber and a local thread to process queue data, and includes _update_body_state to derive body height (cm) and RobotState (STANDING/SITTING). Optional imports are guarded with a warning if the Unitree SDK or CycloneDDS are not available. Requires unitree_sdk2py/CycloneDDS to function at runtime.
- Updated unitree_g1_autonomy.json5 to change the robot name from "Bits" to "Iris" and modified the system prompt accordingly. - Introduced UnitreeG1Odom background plugin for odometry data handling. - Added TurtleBot4Battery plugin for battery status monitoring with Zenoh integration. - Implemented UnitreeGo2Battery plugin for battery status with error handling for SDK absence. - Enhanced unit tests for TurtleBot4Battery and UnitreeGo2Battery plugins to ensure proper functionality and error handling.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds “Booster” (K1) support across messaging, autonomy movement, and configs while also hardening local Qwen tool-calling and preventing Kokoro TTS from speaking emoji descriptions.
Changes:
- Add Booster/K1 Zenoh message IDL + new odom provider and input plugin.
- Add Booster autonomy move action connector (Zenoh RPC) plus multiple hw-test utilities/bridges.
- Improve Kokoro TTS text sanitization and QwenLLM request/tool-call reliability; update docker/configs for local/mDNS setups.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| system_hw_test/zenoh_echo.py | Generic Zenoh “topic echo” tool with basic deserialization for new Booster messages. |
| system_hw_test/test_booster_zenoh_odom_sub.py | Minimal subscriber for validating odometer_state transport. |
| system_hw_test/test_booster_move.py | Sends RemoteControllerState commands over Zenoh for movement testing. |
| system_hw_test/test_booster_move_zenoh_service.py | Tests movement via Zenoh query → ROS2 service bridge (RPC-style). |
| system_hw_test/booster_zenoh_ros2_bridge.py | ROS2 service client + Zenoh queryable bridge; also bridges paths/odom topics. |
| system_hw_test/booster_zenoh_mock.py | Mock Zenoh RPC responder for local testing without ROS2. |
| src/zenoh_msgs/idl/booster_interface.py | New Booster/K1 IDL structs (Odometer, RPC request/response, controller state). |
| src/zenoh_msgs/idl/init.py | Exposes booster_interface types from zenoh_msgs.idl. |
| src/zenoh_msgs/init.py | Re-exports Booster/K1 types at top-level zenoh_msgs. |
| src/providers/kokoro_tts_provider.py | Sanitizes text (emoji/shortcodes/emoticons) before sending to Kokoro. |
| src/providers/k1_odom_provider.py | New Zenoh-based OdomProviderBase implementation using the Booster Odometer IDL. |
| src/llm/plugins/qwen_llm.py | Adds config-driven request overrides allowlist + tool-call fallback to text. |
| src/inputs/plugins/booster_odom.py | New input plugin that surfaces odom/moving posture status to the agent. |
| src/actions/speak/connector/kokoro_tts.py | Makes Kokoro base_url configurable via config (instead of hardcoded). |
| src/actions/move_k1_autonomy/interface.py | Defines K1 autonomy movement action interface (turn/move/stop). |
| src/actions/move_k1_autonomy/connector/k1_sdk.py | Zenoh RPC movement connector with lidar/odom gating + tick-based execution. |
| docker-compose.yml | Updates runtime defaults and adds Avahi socket mount / host networking related settings. |
| config/greeting_local.json5 | Removes unused Unitree ethernet config entry. |
| config/greeting_local_omr2.json5 | Adds a local greeting config targeting omr2 endpoints. |
| config/greeting_local_omr1.json5 | Adds a local greeting config tuned for deterministic tool-calling. |
| config/greeting_llm_gemini.json5 | Adds Gemini-based greeting config. |
| config/booster_autonomy.json5 | Adds a Booster autonomy mode config (odom + paths + move + speak). |
| .env.example | Documents optional QWEN/KOKORO base URL overrides. |
Remove legacy greeting config files and trim .env.example. Update docker-compose.yml: set version, change default OM1_COMMAND to unitree_go2_modes, add OM1_SKIP_INTERNET_CHECK env, expose /dev/video0, and adjust container command and networking-related comments. Add a stop() cleanup to BoosterOdom provider. Simplify QwenLLM: inline formatting, tighten tool-call parsing, remove several config-overrides and fallback helpers, and streamline result handling. Simplify KokoroTTSProvider by removing text sanitization and adjusting logging/message handling. Minor formatting and whitespace cleanups across modified files.
Introduce a unitree_ethernet setting in config/greeting_local.json5, mapped to the UNITREE_ETHERNET environment variable with a default of "enP2p1s0". This lets deployments override the Unitree ethernet interface name via env without editing the config file.
Condense multi-line expressions, f-strings and logging calls into single-line forms and tidy up argument formatting across several modules. Changes are purely stylistic and aim to improve readability/consistency (no functional behavior changes). Affected files: src/actions/move_k1_autonomy/connector/k1_sdk.py, src/inputs/plugins/booster_odom.py, src/providers/k1_odom_provider.py, and various system_hw_test scripts (booster_zenoh_mock.py, booster_zenoh_ros2_bridge.py, test_booster_move_zenoh_service.py, test_booster_zenoh_odom_sub.py, zenoh_echo.py).
Add comprehensive unit tests for MoveBoosterZenoh connector and interface (tests/actions/move_k1_autonomy), booster odometer input plugin (tests/inputs/plugins/test_booster_odom.py), and k1 odom provider (tests/providers/test_k1_odom_provider.py). Introduce connector test mocks and many behavioral/unit tests covering initialization, movement handling, ticking, and message formatting. Update FAISS retriever tests to import sys and mark several tests with pytest.mark.skipif on macOS to avoid FAISS aborts. Minor change in src/providers/k1_odom_provider.py removing a redundant comment. New package __init__ files added for test packages.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Solve the issue (speaking out the expression, such as smiling eyes smiling face) in kokoro_tts_provider.py
Solve the issue (Function Call)
Add avahi-daemon for mDNS
Type of change
Changes
Add booster k1_sdk.py
Add booster k1_odom_provider.py
Checklist
Additional Information
Currently, Booster runs locomotion + balance policy on the same Jetson Orin (via systemctl), which takes ~30–50% CPU.
This is different from Unitree’s architecture:
Potential improvements: