Atlas Notes
- 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
tasks:
- 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)
c̈ = pd(controller.comgains, e, ė)
setdesired!(controller.linmomtask, m * c̈)
# 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)
end
controller.lowlevel(τ, t, state)
τ
end
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 |
API
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 |
References