Skip to main content
🤝

이 가이드는 인류와 AI가 함께 만드는 지식입니다.

이 콘텐츠는 Human + AI Partnership 철학 아래 모든 사람이 로봇·AI를 배울 수 있도록 무료로 제공됩니다. 당신의 질문과 기여가 다음 학생의 미래를 바꿉니다.

ROS 2 Humanoid Robots Guide 2026

Humanoids are the hardest robots to program — dozens of joints, dynamic balance, and coordinated locomotion plus manipulation. This guide covers the ROS 2 stack that makes it tractable: ros2_control, whole-body control, and MoveIt 2.

1. The Humanoid ROS 2 Stack

A humanoid needs a layered stack from hardware interface up to task planning:

sudo apt-get install -y   ros-humble-ros2-control   ros-humble-ros2-controllers   ros-humble-moveit   ros-humble-controller-manager   ros-humble-joint-state-broadcaster   ros-humble-joint-trajectory-controller

# Stack layers (bottom -> top):
#   1. Hardware interface  (ros2_control HardwareInterface)
#   2. Joint controllers   (effort / position / velocity)
#   3. Whole-body control  (balance + task priorities)
#   4. Locomotion planner  (footstep + gait generation)
#   5. Behavior / task      (MoveIt 2, behavior trees)

2. Describing the Robot: URDF for 25+ DOF

Humanoids have many kinematic chains. Structure the URDF with clear chains for legs, arms, and torso:

<!-- humanoid.urdf.xacro (excerpt) -->
<robot name="humanoid" xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:include filename="leg.xacro"/>
  <xacro:include filename="arm.xacro"/>

  <link name="pelvis"/>              <!-- floating base root -->

  <!-- 6-DOF legs -->
  <xacro:leg prefix="left"  reflect="1"/>
  <xacro:leg prefix="right" reflect="-1"/>

  <!-- 7-DOF arms -->
  <xacro:arm prefix="left"  reflect="1"/>
  <xacro:arm prefix="right" reflect="-1"/>

  <ros2_control name="HumanoidSystem" type="system">
    <hardware>
      <plugin>humanoid_hw/HumanoidHardware</plugin>
    </hardware>
    <!-- each joint exposes command + state interfaces -->
  </ros2_control>
</robot>

3. ros2_control Joint Interfaces

Expose effort/position/velocity interfaces per joint so controllers can command torques for balance:

# controllers.yaml
controller_manager:
  ros__parameters:
    update_rate: 500   # Hz — humanoids need fast control loops
    joint_state_broadcaster:
      type: joint_state_broadcaster/JointStateBroadcaster
    left_leg_controller:
      type: joint_trajectory_controller/JointTrajectoryController
    right_leg_controller:
      type: joint_trajectory_controller/JointTrajectoryController

left_leg_controller:
  ros__parameters:
    joints:
      - left_hip_yaw
      - left_hip_roll
      - left_hip_pitch
      - left_knee
      - left_ankle_pitch
      - left_ankle_roll
    command_interfaces: [effort]
    state_interfaces: [position, velocity]

4. Balance: ZMP & the Support Polygon

Static and dynamic balance both keep the Zero Moment Point inside the support polygon:

import numpy as np

def compute_zmp(com, com_accel, com_height, g=9.81):
    """Cart-table model ZMP from CoM state."""
    zmp_x = com[0] - (com_height / g) * com_accel[0]
    zmp_y = com[1] - (com_height / g) * com_accel[1]
    return np.array([zmp_x, zmp_y])

def is_balanced(zmp, support_polygon):
    """ZMP must stay strictly inside the foot support polygon."""
    return point_in_polygon(zmp, support_polygon)

# If ZMP approaches the polygon edge, the whole-body controller
# must adjust CoM trajectory or trigger a recovery step.

5. Whole-Body Control (Task Priorities)

A whole-body controller solves a QP each cycle, honoring prioritized tasks (balance > posture > reaching):

# Prioritized task stack solved as a hierarchical QP
tasks = [
    BalanceTask(weight=1000),      # highest: keep ZMP in polygon
    FootContactTask(weight=800),   # maintain stance foot contact
    CoMTask(target=com_ref, weight=500),
    RightHandTask(target=grasp_pose, weight=100),
    PostureTask(target=nominal_q, weight=10),   # regularization
]

# Solve for joint accelerations subject to:
#   - dynamics:      M q'' + h = S tau + J_c^T f_c
#   - torque limits: tau_min <= tau <= tau_max
#   - friction cone: contact forces stay in cone
qdd, tau = wbc_solver.solve(tasks, robot_state)

6. Bipedal Locomotion & Footstep Planning

Generate a walking gait from a footstep plan and a preview controller:

def plan_footsteps(start, goal, step_length=0.25, step_width=0.18):
    steps, pos, side = [], np.array(start), 1
    while np.linalg.norm(goal[:2] - pos[:2]) > step_length:
        direction = (goal[:2] - pos[:2])
        direction /= np.linalg.norm(direction)
        pos[:2] += direction * step_length
        foot = pos.copy()
        foot[1] += side * step_width / 2   # alternate feet
        steps.append({'pos': foot.copy(), 'foot': 'left' if side > 0 else 'right'})
        side *= -1
    return steps

# Feed the footstep sequence to a ZMP preview controller
# (Kajita's method) to produce a smooth CoM trajectory.

7. Dual-Arm Manipulation with MoveIt 2

Plan coordinated two-arm motion while the lower body maintains balance:

from moveit.planning import MoveItPy

moveit = MoveItPy(node_name="humanoid_moveit")
both_arms = moveit.get_planning_component("both_arms")

both_arms.set_start_state_to_current_state()
both_arms.set_goal_state(configuration_name="carry_box")

plan = both_arms.plan()
if plan:
    moveit.execute(plan.trajectory, controllers=[])
# The upper-body plan runs on top of the balance controller,
# which continuously corrects the CoM as the arms shift mass.

8. Sim-to-Real: Isaac Sim & MuJoCo

Never tune a humanoid on hardware first. Train and validate in simulation:

# MuJoCo + ROS 2 bridge for fast dynamics
ros2 launch humanoid_sim mujoco_bringup.launch.py   model:=humanoid.xml gui:=true

# Isaac Sim for photorealistic perception + RL locomotion policies
# Domain randomize mass, friction, and latency so a policy trained
# in sim survives the reality gap on Unitree G1 / Figure hardware.

9. Real Hardware: Unitree G1 & Figure

10. Safety for Humanoids

Key Takeaways

Build humanoids on ros2_control with a fast (500Hz+) loop, effort interfaces for the legs, and a whole-body QP that prioritizes balance above all tasks. Keep the ZMP inside the support polygon, plan footsteps with a preview controller, and use MoveIt 2 for dual-arm work layered on top of balance. Validate everything in MuJoCo or Isaac Sim before touching a Unitree G1 or Figure — and treat safety as the first controller, not the last.