Robin Deits

  • Dance forces us to think about how precise and dexterous the whole-body motion can be.
  • Parkour forces us to understand the physical limitations of the robot.
  • Manipulation is forcing us to take that information and interpret it in terms of how we can get the hands to do something specific.
  • What’s important about the Atlas project is that we don’t let go of any of those other things we’ve learned.

Behavior Libraries as Planner

Designing behaviors offline via trajectory optimization allows our engineers to explore the limits of the robot’s capabilities interactively ahead of time and reduce the amount of computation we have to do on the robot.

MPC as Controller

Atlas’ controller is what’s known as a model-predictive controller (MPC) because it uses a model of the robot’s dynamics to predict how its motion will evolve into the future. The controller works by solving an optimization that computes the best thing to do right now to produce the best possible motion over time. The controller adjusts details like force, posture, and behavior timing to cope with differences in the environment geometry, foot slips, or other real-time factors.

QPControl.jl: StandingController


  • foottasks
  • linmomtask
  • pelvistask
  • jointtasks
function (controller::StandingController)(τ::AbstractVector, t::Number, state::MechanismState)
    # Linear momentum control
    m = controller.robotmass
    c = center_of_mass(state)
    centroidal = centroidal_frame(controller.lowlevel)
    world_to_centroidal = Transform3D(c.frame, centroidal, -c.v)
    e = FreeVector3D(centroidal, -transform(controller.comref, world_to_centroidal).v)
    ė = FreeVector3D(centroidal, linear(transform(momentum(state), world_to_centroidal)) / m)
     = pd(controller.comgains, e, ė)
    setdesired!(controller.linmomtask, m * )

    # Pelvis orientation control
    pelvistask = controller.pelvistask
    pelvisgains = controller.pelvisgains
    pelvis = target(pelvistask.path)
    Hpelvis = transform_to_root(state, pelvis)
    Tpelvis = transform(twist_wrt_world(state, pelvis), inv(Hpelvis))
    ωdesired = FreeVector3D(Tpelvis.frame, pd(pelvisgains, rotation(Hpelvis), Tpelvis.angular))
    setdesired!(pelvistask, ωdesired)

    # Joint position control
    for jointid in keys(controller.jointtasks)
        task = controller.jointtasks[jointid]
        gains = controller.jointgains[jointid]
        ref = controller.jointrefs[jointid]
        v̇desired = pd(gains, configuration(state, jointid)[1], ref, velocity(state, jointid)[1], 0.0)
        setdesired!(task, v̇desired)

    controller.lowlevel(τ, t, state)


atlas v5 joint name max torque
r_leg_hpx 530
r_leg_hpy 840
r_leg_hpz 275
r_leg_kny 890
r_leg_akx 360
r_leg_aky 740



func name usage
addtask(controller, task) (hard)constraint
addtask(controller, task, weight) (soft)cost
setdesired(task, desired)  
task type weight controller p/d
end_effector_tasks SpatialAccelerationTask 10 ST ang:0/15 lin:0/0
SW ang:100/(2√100) lin:100/(2√100)
linmomtask LinearMomentumRateTask 1 zgains:10/(2√10)
pelvistask AngularAccelerationTask 10 xyz:100/(2√100),100/(2√100),50/(2√50)
jointtasks (!ee)JointAccelerationTask 10 100