How it is built
Architecture overview
A humanoid robot is a tall, narrow machine with a floating base that must stay upright on two feet while its arms and hands do useful work. Its software has to solve three problems at very different speeds. At the bottom, motor drivers close current loops at tens of kilohertz. Above them, a whole-body controller runs at hundreds to a thousand hertz and decides every joint torque so the robot balances, keeps its feet where planned and moves its hands. Above that, a planner or a learned policy runs at tens of hertz and decides what to do: step here, grasp that.
Two schools exist for the upper layers and real systems mix them. The model-based school plans footsteps and centre-of-mass motion with model-predictive control and tracks them with a whole-body optimisation. The learned school trains a neural policy in simulation by reinforcement learning, which outputs joint targets directly, and more recently adds a vision-language-action model that turns camera images and an instruction into actions. Perception and state estimation feed both; a safety layer and an update mechanism surround everything.
Parts:
- Whole-body controller — turns task goals into joint torques under dynamics and contact constraints — whole-body-control (no page yet), built on quadratic-programming (no page yet), rigid-body-dynamics-algorithms (no page yet) and inverse-kinematics (no page yet)
- Balance and gait planner — footsteps and centre-of-mass motion over a horizon — Model-predictive control and gait-phase-scheduling (no page yet)
- Compliance layer — behave like a spring at the contacts — impedance-control (no page yet), built on PID control
- Joint drives — current, torque and position loops at the motor — field-oriented-control (no page yet), built on PWM generation and Phase-locked loop, plus real-time-fieldbus (no page yet)
- Control scheduling — the loops run on a fixed clock — Fixed-rate control loop
- State estimation — base pose, velocity, contact state — Extended Kalman filter and visual-inertial-odometry (no page yet)
- Learned locomotion and skills — policies trained in simulation — Policy gradient and PPO and domain-randomization (no page yet)
- Learned manipulation and vision-language-action — policies from demonstrations and foundation models — imitation-learning (no page yet), action-chunking (no page yet), action-tokenization (no page yet), Transformer block, vision-transformer (no page yet) and Weight quantization
- Battery management — how much energy is left and how much power is allowed — battery-state-estimation (no page yet)
- Safety monitor — independent checker with the authority to stop — safety-monitor-architecture (no page yet)
- Software updates — replace the software safely, roll back on failure — A/B partition OTA updates
- On-board operations and assurance — keeps the software processes running, measured and tested, and the fleet link secure — Process supervision, Graceful draining, Mutual TLS,
hdr-histogram(no page yet), Deterministic simulation testing, Coverage-guided fuzzing
cameras ─► VIO / perception ─────────────────────────► task level (VLA policy or planner, ~10-50 Hz)
IMU, encoders, foot contacts ─► EKF base-state estimate ──┐ │ footsteps, hand goals, or action chunks
▼ ▼
MPC / gait phase scheduler ─► reference: CoM, feet, hands ─► whole-body controller (QP, ~kHz)
learned locomotion policy (obs → joint targets) ─────── alternative path ────────────────┤ torques / joint targets
▼
impedance + joint loops ─► field-oriented current control ─► motors (fieldbus, fixed rate)
battery estimate ─► power limits ─────────────────────────────────────────────────────────┘
safety monitor (independent): speed, torque, tilt, E-stop, watchdog ──► cuts torque
OTA updater: A/B slots + signed images ──► swaps the whole software stack
Two profiles share the stack. A research and development profile runs large models off-board or on a strong onboard computer and tolerates falls. A product profile adds the safety layer, power limits, remote update and service diagnostics, and constrains what the learned parts may do.
How the parts fit together
Whole-body controller
whole-body-control (no page yet) answers: given the desired motion of the centre of mass, the feet and the hands, which joint accelerations and contact forces achieve them? It uses the full model of the robot from rigid-body-dynamics-algorithms (no page yet): recursive algorithms (Featherstone's family) compute the mass matrix, the bias forces and the contact Jacobians for a tree of links in time linear in the number of joints. The tasks are prioritised: balance and contact constraints first, foot placement second, hands third, posture last. The problem each cycle is a quadratic program (quadratic-programming, no page yet) with friction-cone and torque limits as constraints, solved by an active-set or interior-point method in well under a millisecond for a modest number of joints (order of; depends on the solver). The Atlas control work of Kuindersma et al. is a published example of this optimisation-based approach. Inverse-kinematics (no page yet) is used inside and around it: Jacobian-based solvers turn a hand pose into joint targets, damped near singularities, and the same machinery generates the reference posture for the QP.
Balance and gait planner
The planner looks ahead. Model-predictive control solves a small optimisation every cycle over a short horizon, applies the first step and re-plans; for walking the model is deliberately simple (a point mass with feet, or a single rigid body), so the problem is small enough for the control rate. Di Carlo et al. showed on the Cheetah 3 quadruped that convex MPC over such a simplified model is enough to run and balance with a fast solver. gait-phase-scheduling (no page yet) provides the schedule: which foot is in stance or swing and for how long, from fixed timers or from a phase oscillator that is adjusted by contact events. The MPC chooses contact forces for the feet that are in stance; the swing foot gets a trajectory to the planned foothold; the whole-body controller realises both.
Compliance layer
Stiff position control makes a humanoid fall hard if the ground is not where it expected, and breaks things in a collision. impedance-control (no page yet) makes joints and end effectors behave as spring-damper systems around their targets: the commanded torque is a function of the position error, velocity error and a feed-forward term from the dynamics model. Stiffness and damping are chosen per task: soft at the feet and hands in contact, stiff in free swing. Underneath, PID loops in the joint drives regulate torque or position. For arms and hands the same layer lets the robot push on a surface without having to know its location to the millimetre.
Joint drives
Each joint is a brushless motor with a gearbox, an encoder and a driver. field-oriented-control (no page yet) (FOC) controls the motor current in a rotating reference frame: the three phase currents are transformed with the Clarke and Park transforms into torque-producing and flux-producing components, each regulated by a PI controller, and the result is turned back into three phase voltages that PWM outputs of the driver chip generate. The electrical angle comes from the encoder, or from a phase-locked loop that tracks it when the signal is noisy or sensorless. The current loop runs at the PWM rate, the fastest loop in the robot; the torque or position loop above it runs at the controller rate.
The drives connect to the main computer through real-time-fieldbus (no page yet), a deterministic cyclic fieldbus such as EtherCAT, where one frame circulates through all slaves each cycle, reads their inputs and writes their outputs on the fly. That gives synchronised joint commands and feedback at a fixed cycle time with a small jitter, and a master such as SOEM implements the master side in open source.
Control scheduling
All of the above loops depend on a clock that does not skip. The whole-body loop and the fieldbus cycle run under a
fixed-rate control loop: an exact period against absolute deadlines, a constant dt for
integrators, and a measured, logged overrun count. The loop runs on a real-time thread with preallocated memory;
anything slow (logging, networking, the neural network inference) runs in lower-priority threads and hands over
data through lock-free queues. A missed deadline in a balancing robot can mean a fall, so overruns trigger a defined response.
State estimation
Control needs the base pose and velocity, which no sensor measures directly. An extended Kalman filter fuses the IMU (prediction at its full rate), joint encoders with leg kinematics (a stance foot is assumed not to slip, so it gives a velocity measurement) and foot contact detection. The filter also estimates IMU biases. For position over longer times and for navigation, visual-inertial-odometry (no page yet) adds the cameras: feature tracks from the image sequence are fused with preintegrated IMU measurements, so that scale and gravity direction are observable and drift stays bounded over short distances. VINS-Mono and OpenVINS are open implementations. Camera calibration, including the transform from camera to IMU, is a prerequisite, and a time offset between camera and IMU is a typical source of drift.
Learned locomotion and skills
A neural policy maps proprioception (joint angles and velocities, base orientation and angular velocity, the previous action, a command such as a desired velocity) to joint position targets, at tens of hertz, tracked by the joint controllers. It is trained with reinforcement learning, in practice with PPO, in a simulator that runs thousands of robots in parallel on one GPU: Rudin et al. report learning to walk in minutes on a single workstation GPU for a quadruped, and the Isaac Gym paper describes the simulator design. The reward shapes the gait: track the commanded velocity, penalise energy, falls and jerk. domain-randomization (no page yet) varies mass, friction, motor strength, latency and sensor noise during training, which is what lets the policy transfer to the physical robot without further training; Radosavovic et al. trained a causal transformer policy this way for a full-size humanoid and deployed it zero-shot. Open training environments such as Isaac Lab and unitree_rl_gym give a starting point.
Learned manipulation and vision-language-action
For hands and tasks that are hard to specify, the policy learns from demonstrations. imitation-learning (no page yet) trains on teleoperated data; action-chunking (no page yet) has the policy output a short sequence of future actions per inference so that a slow model can drive a fast controller; and the head of the policy can be a diffusion or flow-matching model for multi-modal action distributions. Large models take this further. A vision-language-action (VLA) model has an image encoder (vision-transformer, no page yet), a language transformer backbone, and an action head. Published examples include RT-2, OpenVLA, π0 and NVIDIA's GR00T N1, which is aimed at humanoids and pairs a slower vision-language module with a fast diffusion-transformer action module. To feed a language model, continuous actions may be turned into discrete tokens by action-tokenization (no page yet); the FAST method compresses action chunks with a discrete cosine transform before tokenizing. These models are too large for the robot's real-time computer in full precision, so weight quantization to 8 or 4 bits and a split (slow model on a GPU module, fast controller on the real-time side) are the usual deployment answers. Output actions go to the whole-body controller or the joint targets and pass through the same limit checks as any other command.
Battery management
A humanoid draws large, highly variable power: standing still costs little, a step or a lift costs a lot, and peaks can sag the pack voltage. battery-state-estimation (no page yet) estimates the state of charge by combining coulomb counting (integrating current) with a voltage-based correction through a battery model, typically an extended Kalman filter over an equivalent-circuit model; it also tracks health and temperature. Its outputs set the power budget for the controller (limit peak current, reduce speed, refuse to start a heavy task) and warn the operator.
Safety monitor
A learned policy can output anything. safety-monitor-architecture (no page yet) keeps a separate, simple checker between the planners and the actuators, or beside them: it knows the joint limits, the maximum torque and speed, the body tilt beyond which a fall is unavoidable, and the emergency stop. It runs on separate hardware with its own sensors and a watchdog so that a crash of the main computer is detected within a bounded time. Its actions are limited and predictable: reduce torque, lower the robot into a controlled crouch, switch to damping mode, cut power. It does not try to be clever, which is why it can be trusted. Redundant channels (redundancy-voting, no page yet) and message protection (end-to-end-protection-e2e, no page yet) apply where a single fault must not go unseen.
Software updates
A robot in the field is updated remotely, and a failed update must not leave it unable to boot. A/B partition OTA updates keep two complete system slots: the update is written to the inactive slot, the bootloader tries it once, and if the new system does not report healthy within a time limit, a watchdog reset returns to the old slot. The images are signed and verified before they are installed (see secure boot chain and signed update metadata). A new policy network is rolled out the same way, as a versioned file with the previous one kept for rollback. RAUC is an open update framework for embedded Linux that implements this pattern.
On-board operations and assurance
Process supervision runs the non-real-time services on the robot computer (perception, the policy runner, logging, the update agent): a parent starts them, reaps exits and restarts them under a delay and burst limit. It never restarts the balancing loop silently; a dead control process is a safety event, which the watchdog and safety monitor handle. Graceful draining is how the robot stops work before an update or a shutdown: stop accepting new tasks, finish or abandon the current one, bring the robot to a posture it can hold with the power off or with damping, tell the fleet service it is going away, and only then reboot into the new slot.
Mutual TLS is the identity of the robot towards its fleet and update services: the robot presents a certificate key, the server presents its own, so update bundles, policy files and telemetry flow only between known parties and a stolen robot or a rogue server is refused. It sits on the link to the fleet, never inside the control loops.
hdr-histogram (no page yet) records loop timing as percentiles, such as the whole-body loop period and its overruns, the
fieldbus cycle and the policy inference time, because a balancing robot fails on the tail of these distributions, not on the
average. Deterministic simulation testing runs the scheduler, the queues between loops and
the update agent under a seeded simulated clock, with injected late cycles, lost messages and power cuts, so a rare ordering
bug replays from its seed (the physics simulator used for policy training is a separate tool). Coverage-guided fuzzing
targets the parsers on the robot that read outside bytes: fieldbus frames, instruction text, camera frames and update bundles.
Data and control flow
One balancing cycle (about 1 kHz):
- The fieldbus master receives joint encoder and torque feedback and the IMU sample in one cycle.
- The estimator updates base orientation, velocity and contact flags.
- The gait scheduler and MPC (at a lower rate) supply the reference for the centre of mass and the feet.
- The whole-body controller solves for joint torques that realise the references under the contact constraints.
- The impedance layer adds compliance; the torque commands go out on the fieldbus in the same cycle.
- In each drive, the FOC loop turns the torque command into phase currents at the PWM rate.
- The safety monitor sees the same state through its own path and approves it by its heartbeat.
One task step (learned skill, about 10 to 50 Hz): cameras and proprioception go into the policy; it returns an action chunk; the first part is sent as targets to the whole-body or joint layer; the next chunk is computed while the first plays.
Update: new image downloaded and verified, written to the inactive slot, reboot on the new slot, health check within the time window, commit or roll back.
Scaling
Limits, in the order they bite:
- Onboard compute and thermal limits: a humanoid carries a computer that has to run the controller, the estimator and the large models. Levers: quantization, splitting fast and slow models, running perception off the real-time cores.
- Energy: battery capacity and peak power set how long and how hard the robot works. Levers: efficient gait, actuator choice, power-aware planning.
- Number of joints drives the QP size. Levers: warm starts from the previous solution, hierarchical solvers.
- Training throughput for learned policies: bound by simulation speed. Levers: GPU-parallel simulators, curricula, fewer randomized parameters at first.
- Data for manipulation: demonstrations are costly. Levers: teleoperation tooling, pooling data across robots, simulation.
Failure modes
| Failure | Symptom | Cause | Fix |
|---|---|---|---|
| Fall from a missed deadline | sudden collapse, an overrun counter increments | the control thread blocked on logging or allocation | real-time thread, preallocated memory, overrun response |
| Estimator drift | the robot leans or walks in a curve | bad IMU bias, foot slip assumed to be zero, camera-IMU time offset | bias estimation, contact detection, online time offset |
| Sim-to-real gap | works in simulation, shakes or falls on hardware | motor model, latency or friction not randomized | randomize, model actuator dynamics and delays, test in stages |
| QP infeasible | controller returns no solution near joint or friction limits | conflicting tasks, contact flags wrong | task priorities with slack, fallback to the previous solution, safe mode |
| Fieldbus loss | joints go limp or freeze | a cable or a slave dropped out of the ring | watchdog on each slave, a defined safe state on loss |
| Current-loop instability | whine, motor heating | wrong electrical angle or offset, saturated current loop | recalibrate the angle offset, check the current sensing |
| Policy acts out of distribution | odd motions on new surfaces or objects | the situation was not in training | randomization, a safety envelope, a fallback to a stable stance |
| Battery brown-out | reset in the middle of a motion | sag under load not modelled | power budget, voltage-aware limits |
| Bad update | robot does not come up after an update | image corrupt or incompatible | A/B slots, signature check, boot counter and rollback |
Real implementations
| name | what it is | repo | licence | notes |
|---|---|---|---|---|
| Pinocchio | rigid-body dynamics algorithms, Jacobians | stack-of-tasks/pinocchio | BSD-2-Clause | basis for several controllers |
| Crocoddyl | optimal control for robots, MPC | loco-3d/crocoddyl | BSD-3-Clause | |
| OCS2 | optimal-control and MPC toolbox for legged robots | leggedrobotics/ocs2 | BSD-3-Clause | |
| Isaac Lab | GPU-parallel robot learning framework | isaac-sim/IsaacLab | see repo | |
| unitree_rl_gym | RL locomotion for Unitree robots | unitreerobotics/unitree_rl_gym | BSD-3-Clause | |
| SOEM | EtherCAT master | OpenEtherCATsociety/SOEM | see repo | |
| OpenVINS | visual-inertial estimation | rpng/open_vins | GPL-3.0 | |
| RAUC | A/B update controller for embedded Linux | rauc/rauc | LGPL-2.1 | |
| LeRobot | datasets and policies for robot learning | huggingface/lerobot | Apache-2.0 |
The alternative: a purely model-based stack (MPC plus whole-body control, no neural network) is predictable and analysable, but it needs an accurate model and a lot of manual tuning for each terrain. A purely learned stack is quick to build for locomotion and gives agile behaviour, but offers no guarantees by itself. Most current systems keep the model-based controller and the safety layer, and use learning for locomotion policies and for manipulation skills.
Sources
- S. Kuindersma et al., Optimization-based locomotion planning, estimation, and control design for the Atlas humanoid robot, Autonomous Robots, 2016. DOI
- J. Di Carlo et al., Dynamic locomotion in the MIT Cheetah 3 through convex model-predictive control, IROS 2018. DOI
- N. Rudin et al., Learning to Walk in Minutes Using Massively Parallel Deep Reinforcement Learning, 2021. paper
- V. Makoviychuk et al., Isaac Gym: High Performance GPU-Based Physics Simulation For Robot Learning, 2021. paper
- I. Radosavovic et al., Real-World Humanoid Locomotion with Reinforcement Learning, 2023. paper
- NVIDIA, GR00T N1: An Open Foundation Model for Generalist Humanoid Robots, 2025. paper
- K. Black et al., π0: A Vision-Language-Action Flow Model for General Robot Control, 2024. paper
- A. Brohan et al., RT-2: Vision-Language-Action Models Transfer Web Knowledge to Robotic Control, 2023. paper
- M. Kim et al., OpenVLA: An Open-Source Vision-Language-Action Model, 2024. paper
- K. Pertsch et al., FAST: Efficient Action Tokenization for Vision-Language-Action Models, 2025. paper
- T. Qin, P. Li and S. Shen, VINS-Mono: A Robust and Versatile Monocular Visual-Inertial State Estimator, 2017. paper