Humanoid Robot Anatomy and Design
Overviewβ
The physical structure of a humanoid robot defines what it can and cannot do. Unlike humans, whose anatomy evolved through millions of years of natural selection, robot designs must balance multiple competing objectives: stability, dexterity, computational cost, energy efficiency, and manufacturability. This chapter explores how humanoid robots are designed, focusing on joint configurations, actuator types, sensor placement, and the tradeoffs engineers make when building these complex systems.
Anthropomorphic Structure Overviewβ
A humanoid robot typically mirrors human anatomy with distinct body segments:
Head (cameras, microphone)
|
Neck (1-3 DoF)
|
βββββββββββββββββββββββ
| Torso |
β (Spine: 1-3 DoF) β
βββββββββββββββββββββββ
/ \
Left Arm Right Arm
(7 DoF) (7 DoF)
| |
Wrist Wrist
Hand Hand
| |
/ \ / \
/ \ / \
Left Leg Right Leg (6 DoF each + wheels/feet)
Degree of Freedom (DoF) Distributionβ
Different platforms allocate DoF differently based on their mission:
| Platform | Head | Neck | Spine | Arm (Γ2) | Hand | Leg (Γ2) | Total |
|---|---|---|---|---|---|---|---|
| NAO | 2 | 1 | 0 | 5Γ2=10 | 0 | 5Γ2=10 | 25 |
| Pepper | 2 | 1 | 2 | 5Γ2=10 | 2 | 2 (base) | 23 |
| Atlas | 2 | 1 | 0 | 6Γ2=12 | 5Γ2 | 6Γ2=12 | 28 |
| WABOT-1 | 2 | 3 | 1 | 7Γ2=14 | 8Γ2 | 6Γ2=12 | 50 |
Joint Types and Configurationsβ
Revolute Joints (Rotational)β
Most humanoid robots use revolute joints to approximate human movement:
import numpy as np
from scipy.spatial.transform import Rotation as R
# Revolute joint rotation around z-axis
def revolute_joint(angle_degrees, axis='z'):
"""Model revolute joint rotation"""
angle_rad = np.radians(angle_degrees)
if axis == 'z':
rotation_matrix = np.array([
[np.cos(angle_rad), -np.sin(angle_rad), 0],
[np.sin(angle_rad), np.cos(angle_rad), 0],
[0, 0, 1]
])
elif axis == 'x':
rotation_matrix = np.array([
[1, 0, 0],
[0, np.cos(angle_rad), -np.sin(angle_rad)],
[0, np.sin(angle_rad), np.cos(angle_rad)]
])
elif axis == 'y':
rotation_matrix = np.array([
[np.cos(angle_rad), 0, np.sin(angle_rad)],
[0, 1, 0],
[-np.sin(angle_rad), 0, np.cos(angle_rad)]
])
return rotation_matrix
# Example: Hip joint rotation
hip_pitch = revolute_joint(45, axis='x') # Forward/backward movement
print("Hip pitch rotation matrix:\n", hip_pitch)
# Shoulder joint with multiple axes
def shoulder_3dof(roll, pitch, yaw):
"""Model 3-DoF shoulder joint"""
r_roll = revolute_joint(roll, axis='x')
r_pitch = revolute_joint(pitch, axis='y')
r_yaw = revolute_joint(yaw, axis='z')
# Combined rotation: roll β pitch β yaw
combined = r_yaw @ r_pitch @ r_roll
return combined
Prismatic Jointsβ
Less common in humanoid robots but occasionally used for specialized applications:
Where is joint position and is velocity.
Actuator Typesβ
Electric Motors (Most Common)β
Used in most modern humanoid robots:
class ElectricMotor:
"""Model of electric motor for joint actuation"""
def __init__(self, torque_max, velocity_max, efficiency=0.85):
self.torque_max = torque_max # NΒ·m
self.velocity_max = velocity_max # rad/s
self.efficiency = efficiency
def power_required(self, torque, velocity):
"""Calculate instantaneous power"""
# P = Ο Γ Ο
mechanical_power = torque * velocity
electrical_power = mechanical_power / self.efficiency
return electrical_power
def thermal_loss(self, current, resistance):
"""Calculate resistive heating"""
# P_loss = IΒ²R
return current**2 * resistance
# Typical motor for NAO shoulder joint
nao_shoulder = ElectricMotor(
torque_max=1.3, # NΒ·m
velocity_max=9.5, # rad/s
efficiency=0.80
)
print("Max power at rated torque/speed:")
max_power = nao_shoulder.power_required(1.3, 9.5)
print(f" {max_power:.1f} W")
Hydraulic Actuatorsβ
Used in high-performance platforms like Atlas:
- Advantages: High power density, smooth force control
- Disadvantages: Complex plumbing, maintenance, noise, thermal management
- Use case: Atlas can perform dynamic movements requiring rapid force changes
Pneumatic Actuatorsβ
Rarely used in modern humanoid robots due to power efficiency concerns.
Sensor Suiteβ
A typical humanoid robot integrates multiple sensor types:
import json
from dataclasses import dataclass
from typing import Dict, List
@dataclass
class Sensor:
name: str
location: str
sampling_rate: float # Hz
data_type: str
purpose: str
# Typical NAO sensor configuration
nao_sensors = [
Sensor("USB2 Camera (Front)", "Head", 30, "RGB Image", "Object detection"),
Sensor("USB2 Camera (Bottom)", "Foot", 30, "RGB Image", "Ground detection"),
Sensor("Microphone Array", "Head", 16000, "Audio", "Speech recognition"),
Sensor("IMU", "Torso", 100, "Accel + Gyro", "Balance sensing"),
Sensor("Force/Torque Sensors", "Foot (Γ2)", 50, "6-axis F/T", "Ground contact"),
Sensor("Joint Encoders", "All joints", 100, "Angle", "Proprioception"),
Sensor("IR Range Sensors", "Head/Body", 10, "Distance", "Obstacle detection"),
Sensor("Pressure Sensors", "Foot sole", 50, "Pressure map", "Weight distribution"),
]
# Print sensor summary
print("NAO Sensor Suite:")
print("-" * 70)
total_data_rate = 0
for sensor in nao_sensors:
bytes_per_sample = 4 if "RGB" in sensor.data_type else 1
data_rate = sensor.sampling_rate * bytes_per_sample
total_data_rate += data_rate
print(f"{sensor.name:30} | {sensor.sampling_rate:6.0f} Hz | {sensor.purpose}")
print(f"\nEstimated total data rate: {total_data_rate/1e6:.2f} Mbps")
Center of Mass and Balanceβ
A critical design parameter is the location of the center of mass (CoM):
r_CoM = (Ξ£ m_i * r_i) / (Ξ£ m_i)
For bipedal stability, the CoM projection must remain within the support polygon (feet area):
import numpy as np
import matplotlib.pyplot as plt
def calculate_center_of_mass(body_parts):
"""Calculate center of mass from body segments"""
total_mass = sum(m for _, m in body_parts)
weighted_pos = sum(np.array(r) * m for (r, m) in body_parts)
com = weighted_pos / total_mass
return com
# NAO body segments (position in meters, mass in kg)
nao_segments = [
((0, 0, 0.15), 0.4), # Head
((0, 0, 0.10), 1.3), # Torso
((0.1, 0, 0.08), 0.4), # Left arm
((-0.1, 0, 0.08), 0.4), # Right arm
((0.05, 0, -0.1), 0.6), # Left leg
((-0.05, 0, -0.1), 0.6), # Right leg
]
com = calculate_center_of_mass(nao_segments)
print(f"NAO Center of Mass: {com}")
print(f"Height above ground: {com[2]:.3f} m")
Kinematic Chain Representationβ
Humanoid robots use Denavit-Hartenberg (DH) parameters to describe their kinematic structure:
| Joint | ΞΈ (deg) | d (m) | a (m) | Ξ± (deg) |
|---|---|---|---|---|
| Hip Pitch | ΞΈβ | 0 | 0 | -90 |
| Hip Roll | ΞΈβ | 0 | 0 | 0 |
| Knee Pitch | ΞΈβ | 0 | 0.4 | 0 |
| Ankle Pitch | ΞΈβ | 0 | 0.4 | 0 |
| Ankle Roll | ΞΈβ | 0 | 0 | 0 |
Material Selectionβ
Humanoid robot materials must balance multiple properties:
class Material:
def __init__(self, name, density, strength, cost_per_kg):
self.name = name
self.density = density # kg/mΒ³
self.strength = strength # MPa
self.cost_per_kg = cost_per_kg # USD
def specific_strength(self):
"""Strength-to-weight ratio"""
return self.strength / self.density
def cost_per_strength_unit(self):
"""Cost-effectiveness metric"""
return self.cost_per_kg / self.strength
materials = [
Material("Aluminum Alloy", 2700, 310, 2.0),
Material("Titanium Alloy", 4500, 900, 15.0),
Material("Carbon Fiber Composite", 1600, 600, 10.0),
Material("Steel", 7850, 400, 0.5),
]
print("Material Comparison:")
print(f"{'Material':<25} {'Specific Strength':<20} {'Cost/Strength':<15}")
print("-" * 60)
for mat in materials:
ss = mat.specific_strength()
cs = mat.cost_per_strength_unit()
print(f"{mat.name:<25} {ss:>15.3f} MPaΒ·mΒ³/kg {cs:>12.4f} $/MPa")
Exercise 2.1: Design Analysisβ
Objective: Analyze the mechanical design of a humanoid robot.
Task:
- Select a humanoid robot (e.g., HRP-4, REEM-C, or Valkyrie)
- Document its specifications:
- DoF distribution across body segments
- Actuator types and power specifications
- Mass distribution
- Height and reach envelope
- Create a DH parameter table for at least one leg
- Analyze center of mass location relative to the base of support
- Discuss design tradeoffs (speed vs. stability, dexterity vs. simplicity)
Submission: Design report with specification table, DH parameter table, and analysis.
Next Chapter Previewβ
In Chapter 3, we transition from static anatomy to dynamic motion. You'll learn how to mathematically describe robot motion using forward kinematics, how to compute joint velocities and accelerations, and how dynamics equations predict forces and torques required for movement.