NOpenSoT:
RT Whole-Body Control Framework
Enrico Mingo Hoffman, Arturo Laurenzi and Luca Muratore
Fondazione Istituto Italiano di Tecnologia
OpenSoT
OpenSoT Features
| Easy To Use: ease formulation of different control problems | | Model Independent: use your own model library |
| Standards: based on Eigen and KDL, framework independent | | Robot Independent: integrate easily robots through URDF |
| Interfaces: common interfaces to write you own Tasks, Constraints and Solvers | | Fast and RT Safe: C++ API for optimal RT performances |
| Solvers, Tasks and Constraints: ready to use for common robotic control problems | | Tools: for log, debug and mathematical utilities
|
OpenSoT Components
MODEL
TASKS & CONSTRAINTS
SOLVERS
UTILITIES
Controller Structure
model.update()
tasks.update()
constraints.update()
solver.solve()
control
state
Real-Time safe & fast (~1-10 ms)
Inverse Dynamics
Cartesian Impedance Ctrl
Operational Space
Controller Structure
model.update()
tasks.update()
constraints.update()
solver.solve()
state
Real-Time safe & fast (~1-10 ms)
Open-Loop IK
control
Controller Structure
model.update()
tasks.update()
constraints.update()
solver.solve()
state ol
Real-Time safe & fast (~1-10 ms)
state cl
Admittance Ctrl
Partial Feedback IK
control
Model
ModelInterface
ModelInterface
srdf
urdf
update()
setJointPosition()
getJacobian()
...
ModelInterfaceRBDL
RBDL
Tasks and Constraints
Cost Function
Constraints (Linear)
Cartesian Velocity Task:
Joint Velocity Limits Constraint:
Tasks and Constraints C++ API
TaskInterface
update()
_A, _b, _c, _W, ...
...
ConstraintInterface
update()
_Aineq, _bLower, _bUpper, _Aeq, ...
...
CartesianImpedance
Self-Collision Avoidance
...
...
object
Utilities: Variables
A Variable is an Affine transformation:
which can be used to model optimization variables.
Joint Accelerations + Contact Forces:
//// Update aux task matrices and vectors
_A = …
_b = ...
///// HERE A and b are updated
auto v = _A*_qdot - _b
A = v.getM();
b = -v.getq();
///////////
update()
Utilities: Math of Tasks
Math of Tasks: C++ operators to handle Tasks and Constraints in synthetic but detailed way.
SYMBOL | EFFECT | SYNTAX |
+ | SOFT priority between Tasks (Task Augmentation) | T3 = T1 + T2 |
/ | HARD priority between Tasks (Null-Space) | S1 = T1/T2 |
* | Relative Task Gain | W*T1 |
% | Select Task Rows | T2 = T1%{1,2} |
<< | Insert Constraint | |
T1<<C1
S1<<C1
Floating Base Robots
Augmented joint-space
Constraint: contacts
c1
c2
w
bl
1st priority task: CoM
2nd priority task: end-effectors
3rd priority task: postural
Utilities: Math of Tasks
Math of Tasks: C++ operators to handle Tasks and Constraints in synthetic but detailed way.
Whole-Body IK Example:
API Example
left_arm.reset(new Cartesian("left_arm", q, *model, “l_ee”, “base”));
right_arm.reset(new Cartesian("right_arm", q, *model, “r_ee”, “base”));
postural.reset(new Postural(q));
joint_lims.reset(new JointLimits(q, qmax, qmin));
vel_lims.reset(new VelocityLimits(2., dT, q.size()));
self_collision_avoidance.reset(new SelfCollisionAvoidance(q, *model, “base”));
self_collision_avoidance->setCollisionWhiteList(whiteList);
auto_stack = (left_arm + right_arm)/(postural)<<joint_lims<<vel_lims<<self_collision_avoidance;
Solvers
FRONT-END
BACK-END
Prepare Problems
Solve Problems
MoT Problem
Solution
Solvers: Front-End iHQP/LP
BACK-END
solution 0
problem 0
solution 1
problem 1
problem 2
Solvers: C++ API
SolverInterface
solve()
Back-End
init()
solve()
getOptions()
iHQP/LP (Front-End)
qpOASESBackEnd
...
plugin
object
API Example
left_arm.reset(new Cartesian("left_arm", q, *model, “l_ee”, “base”));
right_arm.reset(new Cartesian("right_arm", q, *model, “r_ee”, “base”));
postural.reset(new Postural(q));
joint_lims.reset(new JointLimits(q, qmax, qmin));
vel_lims.reset(new VelocityLimits(2., dT, q.size()));
self_collision_avoidance.reset(new SelfCollisionAvoidance(q, *model, “base”));
self_collision_avoidance->setCollisionWhiteList(whiteList);
auto_stack = (left_arm + right_arm)/(postural)<<joint_lims<<vel_lims<<self_collision_avoidance;
solver.reset(new iHQP(auto_stack->getStack(), auto_stack->getBounds(),1e9, OSQP));
while(ros::ok()){
model->setJointPosition(q);
model->update();
auto_stack->update(q);
if(solver->solve(dq))
q+=dq;
}
API Example
Other Formulations
Other Formulations
THANK YOU!
QUESTIONS?