20 JacobiSVD<MatrixXd> svd;
25 GainsWorkspace(
int n) : svd(n, n), s(n), kps(n), kds(n) {}
58 std::shared_ptr<OneLevelSolver>
solver;
77 Pimpl(
const std::string& name, std::shared_ptr<Model> m, Feature::Ptr s, Feature::Ptr sdes)
80 , mode(TASK_DEACTIVATED)
81 , gainsWorkspace(s->getDimension())
82 , M( MatrixXd::Identity(s->getDimension(), s->getDimension()) )
83 , M_inverse( MatrixXd::Identity(s->getDimension(), s->getDimension()) )
84 , B( MatrixXd::Zero(s->getDimension(), s->getDimension()) )
85 , K( MatrixXd::Zero(s->getDimension(), s->getDimension()) )
86 , weight( VectorXd::Ones(s->getDimension()) )
87 , frictionOffset(Vector3d::Zero())
91 , contactActive(false)
92 , innerTaskType(UNKNOWNTASK)
93 , innerMetaTaskType(UNKNOWN)
97 , dynamicEquation(0x0)
98 , useReducedProblem(false)
99 , fcVar(name+
".var", s->getDimension())
101 , taskHasBeenInitialized(false)
102 , contactForceConstraintHasBeenSavedInSolver(false)
103 , contactPointHasBeenSavedInModel(false)
104 , frictionConstraintIsRegisteredInConstraint(false)
105 , isRegisteredAsObjective(false)
106 , isRegisteredAsConstraint(false)
107 , innerObjectiveFunction(NULL)
108 , innerTaskAsObjective(NULL)
110 innerTaskAsConstraint.
set(NULL);
117 ContactForceConstraint.
set(
new LinearFunction( fcVar, Eigen::MatrixXd::Identity(3,3), VectorXd::Zero(3) ) );
122 frictionConstraint.
set(NULL);
123 ContactForceConstraint.
set(NULL);
128 if (innerTaskAsObjective)
131 delete innerTaskAsObjective;
137 int featn = feature->getDimension();
138 if (useReducedProblem)
144 innerObjectiveFunction =
new LinearFunction (innerModel->getAccelerationVariable(), Eigen::MatrixXd::Zero(featn, innerModel->nbDofs()), Eigen::VectorXd::Zero(featn));
146 connectFunctionnWithObjectiveAndConstraint();
151 int featn = feature->getDimension();
152 innerObjectiveFunction =
new LinearFunction(innerModel->getJointTorqueVariable(), Eigen::MatrixXd::Zero(featn, innerModel->nbInternalDofs()), Eigen::VectorXd::Zero(featn));
153 connectFunctionnWithObjectiveAndConstraint();
158 int featn = feature->getDimension();
159 innerObjectiveFunction =
new LinearFunction(fcVar, Eigen::MatrixXd::Identity(featn, featn), Eigen::VectorXd::Zero(featn));
160 connectFunctionnWithObjectiveAndConstraint();
166 innerTaskAsConstraint.
set(innerObjectiveFunction);
171 Task::Task(
const std::string& name, std::shared_ptr<Model> model, Feature::Ptr feature, Feature::Ptr featureDes)
173 , pimpl(new
Pimpl(name, model, feature, featureDes))
177 Task::Task(
const std::string& name, std::shared_ptr<Model> model, Feature::Ptr feature)
179 , pimpl(new
Pimpl(name, model, feature, 0x0))
190 pimpl->innerTaskType = newTaskType;
192 std::cout <<
"[warning] can't change a task's type once it has been set." << std::endl;
197 return pimpl->hierarchyLevel;
201 std::cout <<
"\033[1;31m["<<
getName()<<
"]\033[0m Setting hierarchy level to "<<level<< std::endl;
204 std::cout <<
"[warning] Level should be >0 , but you provided "<<level << std::endl;
209 pimpl->hierarchyLevel = level;
211 std::cout <<
"[warning] Can't change a task's level once it has been set." << std::endl;
218 return pimpl->innerTaskType;
224 pimpl->innerMetaTaskType = newMetaTaskType;
226 std::cout <<
"[warning] can't change a task's type once it has been set." << std::endl;
232 return pimpl->innerMetaTaskType;
238 std::string metaTypeString;
244 case Task::POSE: {metaTypeString =
"POSE";}
break;
245 case Task::FORCE: {metaTypeString =
"FORCE";}
break;
246 case Task::COM: {metaTypeString =
"COM";}
break;
253 default: {metaTypeString =
"UNKNOWN";}
break;
286 throw std::runtime_error(std::string(
"[Task::update]: The task type has not been set during creation."));
291 throw std::runtime_error(std::string(
"[Task::update]: Unhandle case of TYPETASK."));
306 if(pimpl->contactActive)
320 if(pimpl->contactActive)
328 if(pimpl->mode == TASK_DEACTIVATED)
336 if(pimpl->contactActive)
340 pimpl->mode = TASK_DEACTIVATED;
355 pimpl->useActualMass =
true;
360 pimpl->useActualMass =
false;
361 pimpl->M = MatrixXd::Zero(pimpl->feature->getDimension(), pimpl->feature->getDimension());
362 pimpl->M.diagonal().setConstant(Md);
367 pimpl->useActualMass =
false;
368 pimpl->M = MatrixXd::Zero(pimpl->feature->getDimension(), pimpl->feature->getDimension());
369 pimpl->M.diagonal() = Md;
374 pimpl->useActualMass =
false;
380 pimpl->B = MatrixXd::Zero(pimpl->feature->getDimension(), pimpl->feature->getDimension());
381 pimpl->B.diagonal().setConstant(B);
386 pimpl->B = MatrixXd::Zero(pimpl->feature->getDimension(), pimpl->feature->getDimension());
387 pimpl->B.diagonal() = B;
397 pimpl->K = MatrixXd::Zero(pimpl->feature->getDimension(), pimpl->feature->getDimension());
398 pimpl->K.diagonal().setConstant(K);
403 pimpl->K = MatrixXd::Zero(pimpl->feature->getDimension(), pimpl->feature->getDimension());
404 pimpl->K.diagonal() = K;
419 JacobiSVD<MatrixXd>& svd = pimpl->gainsWorkspace.svd;
422 const VectorXd& s = svd.singularValues();
423 pimpl->gainsWorkspace.s = (s.array() < massSaturation).select(s, massSaturation);
425 const double w = 2. *
M_PI * freq;
426 VectorXd& kps = pimpl->gainsWorkspace.kps;
427 VectorXd& kds = pimpl->gainsWorkspace.kds;
430 kds = (kps.array()*s.array()).sqrt() * 2.;
432 pimpl->K = svd.matrixU() * kps.asDiagonal() * svd.matrixV().transpose();
433 pimpl->B = svd.matrixU() * kds.asDiagonal() * svd.matrixV().transpose();
438 return pimpl->useActualMass;
443 if(pimpl->useActualMass)
445 if(pimpl->featureDes)
446 return pimpl->feature->computeProjectedMass(*pimpl->featureDes);
448 return pimpl->feature->computeProjectedMass();
455 if(pimpl->useActualMass)
457 if(pimpl->featureDes)
458 return pimpl->feature->computeProjectedMassInverse(*pimpl->featureDes);
460 return pimpl->feature->computeProjectedMassInverse();
462 pimpl->M_inverse = pimpl->M.inverse();
463 return pimpl->M_inverse;
478 if(pimpl->contactActive)
481 if((pimpl->feature->getDimension() != 3) && (pimpl->feature->getDimension() != 6))
482 throw std::runtime_error(
"[Task::activateContactMode] Contact mode is available only for features with dimension 3 or 6");
487 pimpl->contactActive =
true;
492 if(!pimpl->contactActive)
498 pimpl->contactActive =
false;
503 pimpl->weight.setConstant(weight);
509 return pimpl->contactActive;
524 return pimpl->frictionCoeff;
529 return pimpl->margin;
534 return pimpl->frictionOffset;
539 pimpl->frictionCoeff = coeff;
545 pimpl->margin = margin;
551 pimpl->weight = weight;
557 pimpl->frictionOffset = offset;
562 return pimpl->weight;
573 return pimpl->output;
578 pimpl->error = pimpl->featureDes ? pimpl->feature->computeError(*pimpl->featureDes) : pimpl->feature->computeError();
584 pimpl->errorDot = pimpl->featureDes ? pimpl->feature->computeErrorDot(*pimpl->featureDes) : pimpl->feature->computeErrorDot();
585 return pimpl->errorDot;
590 pimpl->errorDdot = pimpl->featureDes ? pimpl->feature->computeAcceleration(*pimpl->featureDes) : pimpl->feature->computeAcceleration();
591 return pimpl->errorDdot;
596 pimpl->effort = pimpl->featureDes ? pimpl->feature->computeEffort(*pimpl->featureDes) : pimpl->feature->computeEffort();
597 return pimpl->effort;
602 pimpl->jacobian = pimpl->featureDes ? pimpl->feature->computeJacobian(*pimpl->featureDes) : pimpl->feature->computeJacobian();
603 return pimpl->jacobian;
608 return pimpl->feature;
613 return pimpl->featureDes;
641 return pimpl->fcVar.getValue();
646 if (pimpl->isRegisteredAsObjective)
648 if(pimpl->innerTaskAsObjective != NULL){
649 pimpl->solver->removeObjective(*pimpl->innerTaskAsObjective);
652 if (pimpl->isRegisteredAsConstraint)
654 pimpl->solver->removeConstraint(pimpl->innerTaskAsConstraint);
657 if (pimpl->frictionConstraintIsRegisteredInConstraint)
659 pimpl->solver->removeConstraint(pimpl->frictionConstraint);
661 if (pimpl->contactForceConstraintHasBeenSavedInSolver)
663 pimpl->solver->removeConstraint(pimpl->ContactForceConstraint);
670 pimpl->solver = solver;
671 pimpl->dynamicEquation = &dynamicEquation;
672 pimpl->useReducedProblem = useReducedProblem;
679 pimpl->setAsAccelerationTask();
685 pimpl->setAsTorqueTask();
690 pimpl->setAsForceTask();
695 pimpl->setAsAccelerationTask();
700 std::string errmsg = std::string(
"[Task::connectToController]: The task type of '") +
getName() + std::string(
"' has not been set during creation.\nCall prior that 'initAsAccelerationTask', 'initAsTorqueTask' or 'initAsForceTask'\n");
701 throw std::runtime_error(std::string(errmsg));
706 throw std::runtime_error(std::string(
"[Task::connectToController]: Unhandle case of TYPETASK for task ")+
getName() );
716 if ( ! pimpl->contactPointHasBeenSavedInModel )
718 pimpl->innerModel->getModelContacts().addContactPoint(pimpl->fcVar, *
getFeature());
719 pimpl->contactPointHasBeenSavedInModel =
true;
722 if ( pimpl->contactForceConstraintHasBeenSavedInSolver )
724 pimpl->solver->removeConstraint(pimpl->ContactForceConstraint);
725 pimpl->contactForceConstraintHasBeenSavedInSolver =
false;
736 if ( ! pimpl->contactForceConstraintHasBeenSavedInSolver )
738 pimpl->solver->addConstraint(pimpl->ContactForceConstraint);
739 pimpl->contactForceConstraintHasBeenSavedInSolver =
true;
779 if (pimpl->useReducedProblem)
781 const Eigen::MatrixXd E2 = - J * pimpl->dynamicEquation->getInertiaMatrixInverseJchiT();
782 const Eigen::VectorXd f2 = accDes + J * pimpl->dynamicEquation->getInertiaMatrixInverseLinNonLinGrav();
784 pimpl->innerObjectiveFunction->changeA(E2);
785 pimpl->innerObjectiveFunction->changeb(f2);
789 pimpl->innerObjectiveFunction->changeA(J);
790 pimpl->innerObjectiveFunction->changeb(accDes);
802 pimpl->innerObjectiveFunction->changeA(J);
803 pimpl->innerObjectiveFunction->changeb(eff);
813 pimpl->innerObjectiveFunction->changeb(eff);
819 const MatrixXd& J = pimpl->innerModel->getCoMAngularJacobian();
822 const VectorXd accDes = - Kd * pimpl->innerModel->getCoMAngularVelocity();
825 if (pimpl->useReducedProblem)
827 const Eigen::MatrixXd E2 = - J * pimpl->dynamicEquation->getInertiaMatrixInverseJchiT();
828 const Eigen::VectorXd f2 = accDes + J * pimpl->dynamicEquation->getInertiaMatrixInverseLinNonLinGrav();
830 pimpl->innerObjectiveFunction->changeA(E2);
831 pimpl->innerObjectiveFunction->changeb(f2);
835 pimpl->innerObjectiveFunction->changeA(J);
836 pimpl->innerObjectiveFunction->changeb(accDes);
845 std::string errmsg = std::string(
"[Task::doActivateAsObjective]: task '") +
getName() + std::string(
"' not connected to any solver; Call prior that 'Controller::addTask' to connect to the solver inside the controller.\n");
846 throw std::runtime_error(std::string(errmsg));
864 pimpl->solver->addConstraint(pimpl->frictionConstraint);
865 pimpl->frictionConstraintIsRegisteredInConstraint =
true;
881 pimpl->solver->removeConstraint(pimpl->frictionConstraint);
882 pimpl->frictionConstraintIsRegisteredInConstraint =
false;
892 pimpl->frictionConstraint.getFunction().setFrictionCoeff(
getFrictionCoeff());
901 pimpl->frictionConstraint.getFunction().setMargin(
getMargin());
919 if(!pimpl->isRegisteredAsObjective)
921 pimpl->solver->addObjective(*pimpl->innerTaskAsObjective);
922 pimpl->isRegisteredAsObjective =
true;
938 if(pimpl->isRegisteredAsObjective)
940 pimpl->solver->removeObjective(*pimpl->innerTaskAsObjective);
941 pimpl->isRegisteredAsObjective =
false;
957 if(!pimpl->isRegisteredAsConstraint)
959 pimpl->solver->addConstraint(pimpl->innerTaskAsConstraint);
960 pimpl->isRegisteredAsConstraint =
true;
975 if(pimpl->isRegisteredAsConstraint)
977 pimpl->solver->removeConstraint(pimpl->innerTaskAsConstraint);
978 pimpl->isRegisteredAsConstraint =
false;
995 if (pimpl->innerTaskAsObjective)
997 pimpl->innerTaskAsObjective->getFunction().changeWeight(
getWeight());
1021 if (pimpl->featureDes) {
void doSetFrictionCoeff()
const Eigen::MatrixXd & getJacobian() const
EqualZeroConstraintPtr< LinearFunction > innerTaskAsConstraint
void doDeactivateAsObjective()
void setDamping(double B)
void setDesiredTaskState(const TaskState &newDesiredTaskState)
Pimpl(const std::string &name, std::shared_ptr< Model > m, Feature::Ptr s, Feature::Ptr sdes)
const Eigen::VectorXd & getErrorDot() const
bool taskHasBeenInitialized
bool frictionConstraintIsRegisteredInConstraint
bool isActiveAsObjective() const
const Eigen::MatrixXd & getDamping() const
const std::string & getName() const
void activateAsConstraint()
const Eigen::VectorXd & getError() const
LinearizedCoulombFunction class.
void doActivateAsConstraint()
Objective< SquaredLinearFunction > * innerTaskAsObjective
void setFrictionConstraintOffset(const Eigen::Vector3d &offset)
void doActivateContactMode()
const Eigen::Vector3d & getFrictionConstraintOffset() const
void setTaskType(Task::TYPETASK newTaskType)
void updateAccelerationTask()
const Eigen::MatrixXd & getDesiredMassInverse() const
void disconnectFromController()
GainsWorkspace gainsWorkspace
const Eigen::VectorXd & getErrorDdot() const
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
Task::META_TASK_TYPE getMetaTaskType()
bool isBodyContactConstraint() const
bool contactForceConstraintHasBeenSavedInSolver
void connectFunctionnWithObjectiveAndConstraint()
Feature::Ptr getFeature() const
bool contactPointHasBeenSavedInModel
void addContactPointInModel()
void setAsAccelerationTask()
void updateCoMMomentumTask()
bool isRegisteredAsObjective
EqualZeroConstraintPtr< LinearFunction > ContactForceConstraint
Task(const std::string &name, std::shared_ptr< Model > model, Feature::Ptr feature, Feature::Ptr featureDes)
virtual T & getFunction(void)
void doDeactivateAsConstraint()
std::string getMetaTaskTypeAsString()
void setAutoGains(double freq)
void checkIfConnectedToController() const
void setDesiredTaskStateDirect(const TaskState &newDesiredTaskState)
Create a linear function that represents the dynamic equation of motion.
SquaredLinearFunction class.
bool isActiveAsConstraint() const
bool isDesiredMassTheActualOne() const
Task::TYPETASK getTaskType()
void setHierarchyLevel(int level)
void setMetaTaskType(Task::META_TASK_TYPE newMetaTaskType)
const Eigen::VectorXd & getComputedForce() const
double getFrictionCoeff() const
void setMargin(double margin)
void setWeight(double weight)
void deactivateContactMode()
void setStiffness(double K)
LinearFunction * innerObjectiveFunction
bool isPointContactTask() const
const FullDynamicEquationFunction * dynamicEquation
void setDesiredMass(double Md)
const Eigen::VectorXd & getEffort() const
void doActivateAsObjective()
std::shared_ptr< Model > innerModel
bool isRegisteredAsConstraint
Feature::Ptr getFeatureDes() const
bool isContactModeActive() const
Variable & getActionVariable() const
void setDesiredMassToActualOne()
void doDeactivateContactMode()
void activateAsObjective()
const Eigen::VectorXd & getOutput() const
const Eigen::VectorXd & getWeight() const
void connectToController(std::shared_ptr< OneLevelSolver > _solver, const FullDynamicEquationFunction &dynamicEquation, bool useReducedProblem)
void removeContactPointInModel()
META_TASK_TYPE innerMetaTaskType
LessThanZeroConstraintPtr< LinearizedCoulombFunction > frictionConstraint
Implements a basic variable.
void doGetOutput(Eigen::VectorXd &output) const
TaskState getDesiredTaskState()
const Eigen::MatrixXd & getStiffness() const
std::shared_ptr< OneLevelSolver > solver
std::string convertToLowerCase(const std::string &originalString)
void activateContactMode()
const Eigen::MatrixXd & getDesiredMass() const
void setFrictionCoeff(double coeff)