isaac_ros_humanoid_task_server#
Source code available on GitHub.
Overview#
This package bridges VDA5050 cloud-commanded manipulation tasks to the GR00T deploy inference pipeline on the Unitree G1. It provides two nodes:
GrootOutputGateNode — a passthrough gate on the GR00T deploy pipeline output. GR00T Triton inference runs continuously, but its joint-command and velocity outputs only reach the live control topics while the gate is open. This keeps the robot balanced by the AGILE locomotion policy whenever no manipulation task is active. When the gate closes it publishes a single zero
cmd_velto stop the base while holding the last joint command (freeze-in-place). A heartbeat watchdog automatically closes the gate if the controlling action server stops sending heartbeats, so GR00T output cannot keep flowing to the robot if that process dies.HumanoidTaskActionServer — a ROS 2 action server implementing the
HumanoidTaskaction. On goal accept it opens the gate so GR00T output flows to the robot, publishes feedback while the task runs, and closes the gate again when the task ends (timeout, cancel, or abort). While a task runs it publishes a heartbeat to the gate so the watchdog knows the controller is alive. If the server cannot open the gate on goal accept, it aborts the goal rather than reporting success.
isaac_ros_unitree_g1_cloud_control_bringup
consumes this package and launches both nodes alongside the
unitree_g1_bringup inference graph and the VDA5050 mission client. The VDA5050 client’s Gr00tPolicyActionHandler dispatches manipulation
actions arriving over MQTT as VDA5050 Orders
(actionType: humanoid_manipulation) to the humanoid_task action, which
in turn drives the gate. For the end-to-end system diagram, refer to
isaac_ros_unitree_g1_cloud_control_bringup.
Note
In the current implementation, GrootOutputGateNode is a pure passthrough
gate and HumanoidTaskActionServer only gates GR00T output for
timeout seconds. It does not consume task_category, task_id,
or language_instruction to select or condition the policy. The server
logs and echoes those fields in action feedback for forward compatibility;
the deploy graph controller_group determines the active policy upstream.
Usage#
The cloud control bringup launch file normally starts both nodes. To run them standalone (for testing), launch each node and drive the gate through the action server or directly through the gate service:
ros2 run isaac_ros_humanoid_task_server groot_output_gate_node
ros2 run isaac_ros_humanoid_task_server humanoid_task_action_server
Trigger a task through the action server (the gate opens for the duration of the task and closes on completion or cancel):
ros2 action send_goal /humanoid_task \
isaac_ros_cloud_control_interface/action/HumanoidTask \
'{task_category: "manipulation",
task_id: "apple_to_plate",
language_instruction: "pick up the apple and place it on the plate",
timeout: 15.0}'
Or open and close the gate directly (lowest-level test):
# Open gate — GR00T output flows to the robot
ros2 service call /groot_output_gate_node/set_active std_srvs/srv/SetBool '{data: true}'
# Close gate — a zero cmd_vel is published, then output is blocked
ros2 service call /groot_output_gate_node/set_active std_srvs/srv/SetBool '{data: false}'
Note
timeout (seconds) controls how long the gate stays open. A value of 0
or less falls back to the default_timeout_s parameter (300.0 by
default) so the gate cannot be left open indefinitely on a physical robot.
To opt into a truly unbounded task, set default_timeout_s to 0 (or
less) as well, then cancel the action or close the gate manually to stop
output. Independently, the gate’s own heartbeat watchdog
(watchdog_timeout_sec) closes the gate if the action server stops
publishing heartbeats.
API#
groot_output_gate_node#
ROS Parameters#
Parameter |
Type |
Description |
|---|---|---|
|
|
Topic carrying GR00T deploy pipeline joint-command trajectories.
Default |
|
|
Live control topic the trajectories are republished to when the gate is
open. Default |
|
|
Topic carrying GR00T deploy pipeline velocity commands.
Default |
|
|
Live velocity topic the commands are republished to when the gate is open.
Default |
|
|
Deadman window: while the gate is open it auto-closes if no heartbeat
arrives on |
ROS Topics#
ROS Topic |
Direction |
Description |
|---|---|---|
|
Subscribed |
GR00T joint-command trajectories (input to the gate).
Type |
|
Subscribed |
GR00T base velocity commands (input to the gate). Type |
|
Subscribed |
Heartbeat from the action server. While the gate is open, the
watchdog closes it if no message arrives within |
|
Published |
Joint-command trajectories, forwarded only while the gate is open. On
close the last command is held (freeze-in-place) — no command is
published here. Type |
|
Published |
Base velocity commands, forwarded while open; the node publishes a single
zero |
ROS Services#
ROS Service |
Interface |
Description |
|---|---|---|
|
|
Open ( |
humanoid_task_action_server#
ROS Parameters#
Parameter |
Type |
Description |
|---|---|---|
|
|
Name of the |
|
|
|
|
|
Topic the server publishes heartbeats to while a task runs,
feeding the gate’s deadman watchdog. Default
|
|
|
Rate at which the server publishes action feedback and sends heartbeats
during task execution. Default |
|
|
Safety bound applied when a goal requests |
ROS Topics Subscribed#
ROS Topic |
Description |
|---|---|
|
Latest joint state, forwarded in action feedback and the final result.
Type |
ROS Topics Published#
ROS Topic |
Description |
|---|---|
|
Heartbeat published at |
ROS Service Clients#
ROS Service |
Interface |
Description |
|---|---|---|
|
|
Calls the gate node to open the gate on goal accept and close it when the
task ends. The service name is set by the |
ROS Actions#
ROS Action |
Interface |
Description |
|---|---|---|
|
|
Triggers a GR00T manipulation task; opens the output gate for the task duration. Rejects new goals while a task is already executing. |
HumanoidTask Action Interface#
Goal#
Field |
Type |
Description |
|---|---|---|
|
|
Task category (for example, |
|
|
Task identifier (for example, |
|
|
Target base pose (optional, for locomotion/locomanipulation tasks). |
|
|
Natural-language command (optional, for VLA tasks). |
|
|
Task timeout in seconds. |
|
|
Flexible JSON string for policy-specific input parameters. |
Feedback#
Field |
Type |
Description |
|---|---|---|
|
|
Execution status: |
|
|
Seconds elapsed since the task started. |
|
|
Current robot base pose. |
|
|
Most recent joint state observed on |
|
|
Instruction currently being executed. |
Result#
Field |
Type |
Description |
|---|---|---|
|
|
|
|
|
Human-readable outcome message. |
|
|
Final robot base pose (if applicable). |
|
|
Final robot joint configuration. |
|
|
Total task execution time in seconds. |
|
|
Additional JSON string for policy-specific result data. |