Feat: Arm teleop with Pinocchio - single & dual arm#1246
Conversation
Greptile OverviewGreptile SummaryThis PR adds VR teleop support for any arm on DimOS by introducing a new Key changes:
Breaking changes:
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Quest as Quest Controller
participant ATM as ArmTeleopModule
participant Coord as ControlCoordinator
participant TIK as TeleopIKTask
participant PIK as PinocchioIK
participant HW as Hardware Adapter
Quest->>ATM: Controller pose delta + buttons
ATM->>ATM: Check task_names routing
ATM->>Coord: PoseStamped (frame_id=task_name)
ATM->>Coord: QuestButtons
Coord->>TIK: on_buttons(QuestButtons)
TIK->>TIK: Check hand-specific primary button
alt Primary button pressed
TIK->>TIK: Reset initial_ee_pose (engage)
else Primary button released
TIK->>TIK: Clear target_pose (disengage)
end
Coord->>TIK: on_cartesian_command(pose, t_now)
TIK->>TIK: Store delta_pose, set active
Coord->>Coord: Tick loop (100Hz)
Coord->>TIK: compute(state)
alt Active and not timed out
TIK->>TIK: Capture initial_ee_pose (if first compute)
TIK->>TIK: Apply delta to initial pose
TIK->>PIK: solve(target_pose, q_current)
PIK->>PIK: Damped least-squares IK
PIK-->>TIK: q_solution, converged, error
TIK->>TIK: Safety check: joint delta within limit
alt Delta exceeds limit
TIK-->>Coord: None (reject solution)
else Delta OK
TIK-->>Coord: JointCommandOutput(positions)
end
else Inactive or timed out
TIK-->>Coord: None
end
Coord->>Coord: Arbitrate tasks by priority
Coord->>HW: Send joint commands
HW->>HW: Execute motion
Last reviewed commit: 1c08c76 |
dimos/control/coordinator.py
Outdated
| task.set_target_pose(msg, t_now) # type: ignore[attr-defined] | ||
| else: | ||
| logger.warning(f"Task {task_name} does not support set_target_pose") | ||
| task.on_cartesian_command(msg, t_now) # type: ignore[attr-defined] |
There was a problem hiding this comment.
Missing error handling - if task lacks on_cartesian_command, AttributeError will be raised instead of graceful warning like the old code did with hasattr check.
| task.on_cartesian_command(msg, t_now) # type: ignore[attr-defined] | |
| if hasattr(task, "on_cartesian_command"): | |
| task.on_cartesian_command(msg, t_now) # type: ignore[attr-defined] | |
| else: | |
| logger.warning(f"Task {task_name} does not support on_cartesian_command") |
There was a problem hiding this comment.
Fixed - Added error handling!
| def __init__(self, *args: Any, **kwargs: Any) -> None: | ||
| super().__init__(*args, **kwargs) | ||
| self._prev_primary: dict[Hand, bool] = {Hand.LEFT: False, Hand.RIGHT: False} | ||
| cfg: ArmTeleopConfig = self.config # type: ignore[assignment] |
There was a problem hiding this comment.
This ignore is not needed. You have to define config: ArmTeleopConfig after default_config = ArmTeleopConfig. Then remove this line.
| # ========================================================================= | ||
| # Pose Conversion Helpers | ||
| # ========================================================================= | ||
|
|
||
| @staticmethod | ||
| def pose_to_se3(pose: Pose | PoseStamped) -> pinocchio.SE3: | ||
| """Convert Pose or PoseStamped to pinocchio SE3""" | ||
|
|
||
| position = np.array([pose.x, pose.y, pose.z]) | ||
| quat = pose.orientation | ||
| rotation = pinocchio.Quaternion(quat.w, quat.x, quat.y, quat.z).toRotationMatrix() | ||
| return pinocchio.SE3(rotation, position) | ||
|
|
||
| @staticmethod | ||
| def pose_dict_to_se3(pose: dict[str, float]) -> pinocchio.SE3: | ||
| """Convert a pose dict with RPY to pinocchio SE3""" | ||
|
|
||
| position = np.array([pose["x"], pose["y"], pose["z"]]) | ||
| rotation = pinocchio.rpy.rpyToMatrix(pose["roll"], pose["pitch"], pose["yaw"]) | ||
| return pinocchio.SE3(rotation, position) |
There was a problem hiding this comment.
These should be standalone functions too. They don't use PinocchioIK.
There was a problem hiding this comment.
can write them outside the class. can they be in the same file, along with other standalone methods (check_joint_delta(), get_worst_joint_delta()), or should they go to any utils file, as this is a type conversion?
There was a problem hiding this comment.
Changed it to standalone method
dimos/control/coordinator.py
Outdated
| # Also subscribe to buttons for engage/disengage | ||
| try: | ||
| if self.buttons.transport: | ||
| self._buttons_unsub = self.buttons.subscribe(self._on_buttons) | ||
| logger.info("Subscribed to buttons for engage/disengage") | ||
| except Exception as e: | ||
| logger.debug(f"Could not subscribe to buttons: {e}") |
There was a problem hiding this comment.
I see this a lot (checking if transport is truthy) and I don't think it's good.
In this case, if the button transport isn't working, the application is completely broken, no? Does it actually happen? If it does, that's a problem and we need to fix it.
But also, it's not good to catch an exception and log it as debug. It should be at least a warning.
There was a problem hiding this comment.
This check happens in if has_cartesian_ik or teleop_task. self.buttons.transport returns true for teleop_task and false for cartesian_ik (here, it should not fail, coz we dont need buttons for cartesian_ik).
I changed the structure now. Writing a different check for if has_teleop_task. So that it fails if there's no self.buttons.transport.
There was a problem hiding this comment.
There are three input streams. Joint_command, cartesian_command and buttons.
missing .transport in xase of self.joint_command.transport and self.cartesian_command.transport doesn't mean its broken coz the task methods can be also called via task_invoke RPC, without needing a stream at all. But, if using .transport is bad, I can directly try to subscribe and return a warning in case its missing (and not fail).
But, this should fail for buttons as there is no RPC alternative. implemented this.
@mustafab0 please confirm this won’t affect the manipulation module.
I verified it and nothing should break.
dimos/control/coordinator.py
Outdated
| """Forward button state to all tasks that accept it.""" | ||
| with self._task_lock: | ||
| for task in self._tasks.values(): | ||
| if hasattr(task, "on_buttons"): |
There was a problem hiding this comment.
hasattr is almost always bad. Same with type: ignore[attr-defined]
The code is essentially saying "on the off chance that this object has a on_buttons method, call it with some random param. If the method is changed to require an additional param, mypy will never tell you because it doesn't know about it.
The simplest way to fix this is to define on_buttons in the ControlTask Protocol. This forces you to implement it on all tasks. In most cases, you can just implement the method as pass. (If this is too much code, you can define a BaseControlTask which implements all empty methods for such listeners, and if you inherit from it, only TeleopIKTask has to actually implement on_buttons.)
There was a problem hiding this comment.
yeah, makes sense. So, remove all 'hasattr' from coordinator, which means implementing for all methods in the callbacks in either of ways you mentioned? Implementing this.
Added a BaseTask that implements all methods, and taks overrides and implements respective methods.
dimos/control/coordinator.py
Outdated
| if hasattr(task, "on_cartesian_command"): | ||
| task.on_cartesian_command(msg, t_now) # type: ignore[attr-defined] |
dimos/control/blueprints.py
Outdated
| from dimos.utils.data import get_data | ||
|
|
||
| _PIPER_MODEL_PATH = str( | ||
| get_data("piper_description") / "mujoco_model" / "piper_no_gripper_description.xml" |
There was a problem hiding this comment.
I didn't notice this before, but this calls get_data at import time. Meaning if the user doesn't have the repo, the program blocks here until the repo is downloaded.
I think someone else handled this case before by passing a lambda which is evaluated by the module. @leshy What do you think?
There was a problem hiding this comment.
This was the previous implementation. But, this creates multiple methods everytime. What's the best way
def _get_piper_model_path() -> str
from dimos.utils.data import get_data
piper_path = get_data("piper_description")
return str(piper_path / "mujoco_model" / "piper_no_gripper_description.xml")
There was a problem hiding this comment.
Fixed. used @jeff-hykin LfsPath for lazy loading - get_data() now defers to build time. Fixed bugs in implementation and verified import no longer triggers download.
|
In person notes:
|
|
My bad @ruthwikdasyam looks like the LfsPath I added causes some breakage. I'll work with you on this today so we can it merged. |
| cartesian_command: In[PoseStamped] | ||
|
|
||
| # Input: Teleop buttons for engage/disengage signaling | ||
| buttons: In[QuestButtons] |
There was a problem hiding this comment.
Quest = MetaQuest buttons right? I think this needs to be generic. What would it look like if we were to add PicoButtons?
There was a problem hiding this comment.
buttons stream name is generic, but the message type is QuestButtons since that's the only controller we support right now. Once we add a second device (Pico or VisionPro), the right generic interface will be clearer. abstracting before, without a second device/case usually leads to the wrong API. Keeping as-is for now.
Release v0.0.10: Manipulation Stack, MuJoCo Simulation, DDS Transport, Web and Native Visualization via Rerun ## Highlights 88+ commits, 20 contributors, 700+ files changed. The TLDR: **a complete manipulation stack**, **MuJoCo simulation**, **DDS transport**, and **a rewritten visualization pipeline**. Agents are no longer bolted on top — they're refactored as native modules with direct stream access. The entire ROS message dependency has been removed from core DimOS, and we've added VR, phone, and arm teleoperation stacks. You can now vibecode a pick-and-place task from natural language to motor commands. Installation has been significantly streamlined — no more direnv, simpler setup, and the web viewer is now the default. --- ## 🚀 New Features ### Simulation - **MuJoCo simulation module** — Run any DimOS blueprint in simulation with no hardware. Supports xArm and Unitree embodiments, parses MJCF/URDF for robot properties, monotonic clock timing (no `time.sleep`). `dimos --simulation run unitree-go2` ([#1035](#1035)) by @jca0 - **Simulation teleop blueprints** — Added simulation teleop blueprints for Piper, xArm6, and xArm7. ([#1308](#1308)) by @mustafab0 ### Manipulation - **Modular manipulation stack** — Full planning stack with Drake: FK/IK solvers (Jacobian + Drake optimization), RRT path planning, world model with obstacle monitoring, multi-robot management. xArm6/7 and Piper support. ([#1079](#1079)) by @mustafab0 - **Joint servo and cartesian controllers** — Joint position/velocity controllers and cartesian IK task with Pinocchio solver. PoseStamped stream input for real-time control. ([#1116](#1116)) by @mustafab0 - **GraspGen integration** — Grasp generation via Docker-hosted GPU model. Lazy container startup, thread-safe init, RPC `generate_grasps()` returns ranked PoseArray. ([#1119](#1119), [#1234](#1234)) by @JalajShuklaSS - **Gripper control** — Gripper RPC methods on control coordinator, exposed adapter property for custom implementations. ([#1213](#1213)) by @mustafab0 - **Detection3D and Object support** — Object input topics, TF support on manipulation module, pointcloud-to-convex-hull for Drake imports. ([#1236](#1236)) by @mustafab0 - **Agentic pick and place** — Reimplemented manipulation skills for agent-driven pick-and-place workflows. ([#1237](#1237)) by @mustafab0 ### Teleoperation - **Quest VR teleoperation** — Full WebXR + Deno bridge stack. Quest controller data (pose, trigger, grip) streamed to DimOS modules. Monitor-style locking for control loops. ([#1215](#1215)) by @ruthwikdasyam - **Phone teleoperation** — Control Go2 from your phone with a web-based teleop interface. ([#1280](#1280)) by @ruthwikdasyam - **Arm teleop with Pinocchio IK** — Single and dual arm teleoperation using Pinocchio inverse kinematics. Blueprints for xArm, Piper, and dual configurations. ([#1246](#1246)) by @ruthwikdasyam ### Transports & Infrastructure - **DDS transport protocol** — CycloneDDS transport with configurable QoS (high-throughput and reliable profiles). Optional install, benchmark integration. ([#1174](#1174)) by @Kaweees - **Pubsub pattern subscriptions** — Glob and regex pattern matching for topic subscriptions. `subscribe_all()` for bridge-style consumers. Topic type encoding in channel strings (`/topic#module.ClassName`). ([#1114](#1114)) by @leshy - **LCM raw bytes passthrough** — Skip `lcm_encode()` when message is already bytes. ([#1223](#1223)) by @leshy - **Unified TimeSeriesStore** — Pluggable backends (InMemory, SQLite, Pickle, PostgreSQL) with SortedKeyList for O(log n) operations. Replaces the old replay system and TimestampedCollection. Collection API with slice, range, and streaming methods. ([#1080](#1080)) by @leshy - **DimosROS benchmark tests** — Benchmark suite for ROS transport performance. ([#1087](#1087)) by @leshy ### Navigation - **FASTLIO2 support** — Hardware-verified localization with arm64 support. Docker deployment with FAR Planner, terrain analysis, and bagfile playback mode. Builds or-tools from source on arm64. ([#1149](#1149)) by @baishibona - **Native Livox + FASTLIO2 module** — First-class DimOS native module for Livox Mid-360 lidar with FASTLIO2 localization. ([#1235](#1235)) by @leshy ### Visualization - **RerunBridge module and CLI** — New bridge that subscribes to all LCM messages and logs those with `to_rerun()` to Rerun viewer. GlobalConfig singleton, web viewer support. Replaces the old rerun initialization system. ([#1154](#1154)) by @leshy - **Webcam rerun visualization** — Camera module logs to Rerun with pinhole projection for 3D visualization. ([#1117](#1117)) by @ruthwikdasyam - **Default viewer switched to rerun-web** — Browser-based viewer is now the default for broader compatibility. No native viewer install needed. ([#1324](#1324)) by @spomichter ### Agents - **Agent refactor** — Restructured agent module with cleaner imports and global config integration. ([#1211](#1211)) by @paul-nechifor - **Timestamp knowledge** — Agents now have timestamp awareness in prompts for temporal reasoning. ([#1093](#1093)) by @ClaireBookworm - **Observe skill** — Go2 can now observe (capture and describe) its environment via agent skill. ([#1109](#1109)) by @paul-nechifor ### Platform & Hardware - **G1 without ROS** — Unitree G1 blueprints decoupled from ROS dependency. Lazy imports for fast startup. ([#1221](#1221)) by @jeff-hykin - **ARM (aarch64) support** — DimOS runs on ARM hardware. Platform-conditional dependencies, open3d source builds for arm64. ([#1229](#1229)) by @jeff-hykin - **Universal joint/hardware schema** — `HardwareComponent` dataclass with `JointState`, `JointName` type aliases. Backend registry with auto-discovery for SDK adapters. ([#1040](#1040), [#1067](#1067)) by @mustafab0 --- ## 🔧 Improvements - **Optional Dask** — Start without Dask using `--no-dask` flag. Startup time reduced from ~60s to ~45s. ([#1111](#1111), [#1232](#1232)) by @paul-nechifor - **RPC rework** — Renamed `ModuleBlueprint` → `_BlueprintAtom`, `ModuleBlueprintSet` → `Blueprint`, `ModuleConnection` → `Stream`. Added `ModuleRef`, improved type hints throughout. ([#1143](#1143)) by @jeff-hykin - **Image class simplification** — Rewritten as pure NumPy dataclass. Removed CUDA backend, unused methods (solve_pnp, csrt_tracker), and image_impls/ directory. ([#1161](#1161)) by @leshy - **Odometry message cleanup** — Simplified Odometry message type. ([#1256](#1256)) by @leshy - **Remove all ROS message dependencies** — Purged ROS message types from core DimOS. Refactored rosnav to use ROSTransport. Removed dead ROS bridge code. ([#1230](#1230)) by @alexlin2 - **Removed bad function serialization** — Eliminated unnecessary serialization of Python functions. ([#1121](#1121)) by @paul-nechifor - **Benchmark IEC units** — Switched bandwidth benchmarks from SI to IEC units for accuracy. ([#1147](#1147)) by @leshy - **Pubsub typing improvements** — Thread-safety locks on `subscribe_new_topics` and `subscribe_all`. Proper type params across pubsub stack. ([#1153](#1153)) by @leshy - **Autogenerated blueprint list** — Blueprints are now auto-discovered and listed. ([#1100](#1100)) by @paul-nechifor - **Generic Buttons message** — Renamed `QuestButtons` to `Buttons` with generic field names for cross-platform teleop. ([#1261](#1261)) by @ruthwikdasyam - **Dev container uses ros-dev image** — `./bin/dev` now runs the ROS-enabled dev image. ([#1170](#1170)) by @leshy - **LSP support** — Added python-lsp-server and python-lsp-ruff to dev dependencies. ([#1169](#1169)) by @leshy - **Lazy-load pyrealsense2** — RealSense camera module uses lazy imports to avoid errors in simulation environments without the SDK. ([#1309](#1309)) by @spomichter - **Removed unused mmcv and mmengine** — Dead Detic dependencies removed, eliminating slow source builds from install. ([#1319](#1319)) by @spomichter - **Simplified installation** — Removed direnv requirement, streamlined install instructions across all platforms. ([#1315](#1315)) by @spomichter - **DDS extra excluded from --all-extras** — `cyclonedds` requires a source build, so `dds` is now excluded from `uv sync --all-extras` by default. ([#1318](#1318)) by @spomichter - **Nix pre-commit skip** — Skip pre-commit install if hooks already exist. ([#1162](#1162)) by @leshy - **Removed base-requirements** — Consolidated dependency management. ([#1098](#1098)) by @paul-nechifor - **Removed old graspnet** — Cleaned up deprecated graspnet version. ([#1248](#1248)) by @paul-nechifor - **Code cleanup** — Removed `tofix` markers ([#1216](#1216)), fixed ruff issues ([#1112](#1112)), removed old README_installation.md ([#1101](#1101)) by @paul-nechifor --- ## 🐛 Bug Fixes - Fix LFS updating (move from .local to venv) ([#1090](#1090)) by @jeff-hykin - Launch hotfixes: git clone HTTPS, get_data main branch ([#1091](#1091)) by @spomichter - Fix camera demo not showing in Rerun ([#1148](#1148)) by @jeff-hykin - Default to rerun native viewer ([#1099](#1099)) by @Nabla7 - Fix exploration blocking agent loop ([#1258](#1258)) by @paul-nechifor - Fix person-follow blocking agent loop ([#1278](#1278)) by @paul-nechifor - Skip metric3d tests on unsupported xformers GPUs (Blackwell compute capability >9.0) ([#1225](#1225)) by @leshy - Fix manipulation tests ([#1218](#1218), [#1247](#1247)) by @jeff-hykin, @paul-nechifor - Fix control coordinator e2e test ([#1212](#1212)) by @mustafab0 - Fix xarm7-sim broken e2e tests ([#1294](#1294)) by @paul-nechifor - Pin langchain to restore supported providers ([#1241](#1241)) by @spomichter - Fix missing library dependencies in Nix flake ([#1240](#1240)) by @Kaweees - Fix discord invite link ([#1122](#1122)) by @spomichter - macOS edgecase fix ([#1096](#1096)) by @jeff-hykin - Fix second N in logo ([#1250](#1250)) by @jeff-hykin - Fix Unitree Go2 minor issues ([#1307](#1307)) by @paul-nechifor - Fix broken tests ([#1305](#1305)) by @ruthwikdasyam - Fix `uv sync` for some macOS systems ([#1322](#1322)) by @jeff-hykin - Fix mmcv install ([#1313](#1313)) by @paul-nechifor - Fix mypy issues ([#1150](#1150), [#1167](#1167), [#1257](#1257)) by @leshy, @paul-nechifor, @jeff-hykin - Fix Nix install uv pip extras ([#1321](#1321)) by @spomichter --- ## 📚 Documentation - **Major docs overhaul** — New README with feature grid, hardware table, quickstart. Navigation, transports, data streams, and agent docs. ([#1295](#1295)) by @leshy - **Day 1 docs** — Comprehensive getting started guide, development docs, contributing guide, architecture overview. Executable blueprint docs via md-babel-py. ([#1064](#1064)) by @jeff-hykin - **Arm integration guide** — How-to for integrating new robotic arms with DimOS. ([#1238](#1238)) by @mustafab0 - **MCP documentation update** — Updated MCP install and usage instructions. ([#1251](#1251)) by @Kaweees - **Docker docs** — First pass on Docker deployment documentation. ([#1151](#1151)) by @leshy - **Transports documentation** — Encode/decode mixins, SHM examples, ROS/DDS transport docs. ([#1107](#1107)) by @leshy - **Rerun API examples** — Updated examples for the new RerunBridge API. ([#1262](#1262)) by @jeff-hykin - **PR template** added ([#1172](#1172)) by @christiefhyang - **Simplified install instructions** — Removed direnv, streamlined across all platforms. ([#1315](#1315)) by @spomichter - **Python example restored** — Added back the Python usage example. ([#1317](#1317)) by @jeff-hykin - **Nix install updated** — Replaced uv with pip for Nix compatibility. ([#1326](#1326)) by @ruthwikdasyam - **README improvements** ([#1311](#1311)) by @paul-nechifor - **Simplified writing docs** — Consolidated writing_docs to a single markdown file. ([#1254](#1254)) by @jeff-hykin --- ## 🏗️ CI & Build - **ci-complete gate** — Dynamic branch protection via single aggregated status check. MD-only PRs no longer blocked. ([#1279](#1279)) by @spomichter - **Path-based test filtering** — Test jobs fully skip (no container spin-up) when no relevant code changed. ([#1284](#1284), [#1286](#1286)) by @spomichter - **Navigation docker build workflow** — CI builds for the ROS navigation stack. ([#1259](#1259)) by @spomichter - **CUDA test marker** — `@pytest.mark.cuda` for GPU-dependent tests. ([#1220](#1220)) by @jeff-hykin - **e2e test marker** — Marked end-to-end tests for selective CI runs. ([#1110](#1110)) by @paul-nechifor - **pytest stdin fix** — Added `-s` to default addopts for LCM autoconf compatibility. ([#1320](#1320)) by @spomichter --- ##⚠️ Breaking Changes - **RPC renames**: `ModuleBlueprint` → `_BlueprintAtom`, `ModuleBlueprintSet` → `Blueprint`, `ModuleConnection` → `Stream` ([#1143](#1143)) - **Image class rewrite**: `CudaImage` and `NumpyImage` removed. Image is now a pure NumPy dataclass. Methods like `solve_pnp`, `csrt_tracker`, `from_depth`, `to_depth_meters` removed. ([#1161](#1161)) - **ROS messages removed from core**: All `to_ros`/`from_ros` conversion methods removed. Use `ROSTransport` instead. ([#1230](#1230)) - **QuestButtons → Buttons**: Renamed with generic field names. ([#1261](#1261)) - **RerunBridge replaces old rerun init**: `dimos.dashboard.rerun_init` removed. Use `RerunBridgeModule` or the `rerun-bridge` CLI. ([#1154](#1154)) - **Unitree directory restructuring**: `unitree_go2` → `unitree/go2`, `unitree_g1` → `unitree/g1`. Blueprint names updated. ([#1221](#1221)) - **Default viewer is now rerun-web**: Use `--viewer-backend rerun` to restore native viewer. ([#1324](#1324)) --- ## Quickstart ```bash # Install uv pip install dimos[base,unitree] # Try it (no hardware needed) # NOTE: First run downloads ~2.4 GB from LFS dimos --replay run unitree-go2 # Simulate uv pip install dimos[base,unitree,sim] dimos --simulation run unitree-go2 ``` --- ## New Contributors 🎉 - @ruthwikdasyam — Quest VR teleoperation, phone teleop, arm teleop, webcam rerun viz - @JalajShuklaSS — GraspGen integration - @jca0 — MuJoCo simulation module - @christiefhyang — PR template --- **Full Changelog**: [v0.0.9...v0.0.10](v0.0.9...v0.0.10)
Feature
Problems
Issue - Linear
closes DIM-446
closes DIM-421
closes #1186
Approach/Solution
TeleopIKTask- new control taskAccepts streaming cartesian delta poses from VR controllers, solves IK internally via Pinocchio at 100Hz.
on_buttons()listens toQuestButtons- hold primary to track, release to stopmax_joint_delta_degper tick, auto-disengages on stream timeout"left"/"right"/ both) for dual-arm setupsPinocchioIK- new standalone IK solverLightweight Pinocchio-based solver for real-time control (unlike
JacobianIKwhich requires fullWorldSpec). Provides FK, damped least-squares IK, pose conversion helpers, and safety utilities (check_joint_delta,get_worst_joint_delta).CartesianIKTaskrefactored to usePinocchioIK- replaced inline IK/safety/pose codeControlCoordinator- newbuttons: In[QuestButtons]stream,_on_buttons()handler,teleop_iktask type in factory,handfield onTaskConfigcoordinator_teleop_xarm6,coordinator_teleop_piper,coordinator_teleop_dualarm_teleop_xarm6,arm_teleop_piper,arm_teleop_dualArmTeleopModulereworked - newArmTeleopConfig.task_namesfor per-hand routing viaframe_id, removed old toggle engageBreaking Changes/Info
CartesianIKTask.set_target_pose()->on_cartesian_command()CartesianIKTask.set_target_pose_dict()->on_cartesian_command_dict()CartesianIKTaskConfigremoved:ik_max_iter,ik_eps,ik_damp,ik_dt,max_velocity.CartesianIKTaskinternals_solve_ik(),_safety_check(),_pose_to_se3()moved toPinocchioIKCartesianIKTask._pose_to_se3()removed - Replaced by standalonepose_to_se3()indimos.manipulation.planning.kinematics.pinocchio_ik.Import path changed.How to Test
Blueprint verification (required)
Manual verification
teleop_server.tsand launch a teleop blueprint above with hardware connected