33void SolveLinearSystem (
 
   40unsigned int GetMovableBodyId (Model& model, 
unsigned int id);
 
   50  const char *constraint_name,
 
   51  unsigned int userDefinedId)
 
   53  assert (
bound == 
false);
 
   56  unsigned int insertAtRowInG = 
size();
 
   57  unsigned int rowsInG = insertAtRowInG+1;
 
   60  if(constraint_name != NULL) {
 
   61    nameStr = constraint_name;
 
   72  bool constraintAppended = 
false;
 
   79#ifdef RBDL_USE_CASADI_MATH 
   82      if(pointErr.norm() < std::numeric_limits<double>::epsilon()*100 &&
 
   85        constraintAppended = 
true;
 
   91  if(constraintAppended == 
false) {
 
   94                std::shared_ptr<ContactConstraint>(
 
   95                    new ContactConstraint(body_id,body_point, world_normal, constraint_name,userDefinedId)));
 
  103  name.push_back (nameStr);
 
  107  err[insertAtRowInG] = 0.;
 
  109  errd[insertAtRowInG] = 0.;
 
  112  force[insertAtRowInG] = 0.;
 
  118  v_plus[insertAtRowInG] = 0.;
 
  121                 Math::Vector3d::Zero());
 
  124  if(nameStr.size() > 0) {
 
  125    std::pair< std::map<std::string, unsigned int>::iterator, 
bool > iter;
 
  126    iter = 
nameGroupMap.insert(std::pair<std::string, unsigned int>(
 
  137  if(userDefinedId < std::numeric_limits<unsigned int>::max()) {
 
  138    std::pair< std::map<unsigned int, unsigned int>::iterator, 
bool > iter;
 
  150  std::pair< std::map<unsigned int, unsigned int>::iterator, 
bool > iter;
 
  151  iter = 
idGroupMap.insert(std::pair<unsigned int, unsigned int>(
 
  154  if(iter.second == 
false) {
 
  155    std::cerr << 
"Error: Constraint row entry in system is not unique." 
  156              << 
" (This should not be possible: contact the " 
  157              "maintainer of this code.)" 
  169  unsigned int idPredecessor,
 
  170  unsigned int idSuccessor,
 
  171  const Math::SpatialTransform &XPredecessor,
 
  172  const Math::SpatialTransform &XSuccessor,
 
  175  double stabilizationTimeConstant,
 
  176  const char *constraintName,
 
  177  unsigned int userDefinedId)
 
  179  assert (
bound == 
false);
 
  182  unsigned int insertAtRowInG = unsigned(
size());
 
  183  unsigned int rowsInG = insertAtRowInG+1;
 
  185  double tol = std::numeric_limits<double>::epsilon()*100.;
 
  186  bool constraintAppended = 
false;
 
  194      bool framesNumericallyIdentical=
true;
 
  195      SpatialTransform frameErrorPre, frameErrorSuc;
 
  197      frameErrorPre.r=XPredecessor.r-
loopConstraints[idx]->getBodyFrames()[0].r;
 
  198      frameErrorPre.E=XPredecessor.E-
loopConstraints[idx]->getBodyFrames()[0].E;
 
  200      frameErrorSuc.r=XSuccessor.r  -
loopConstraints[idx]->getBodyFrames()[1].r;
 
  201      frameErrorSuc.E=XSuccessor.E  -
loopConstraints[idx]->getBodyFrames()[1].E;
 
  205#ifndef RBDL_USE_CASADI_MATH 
  206      for(
unsigned int i=0; i<frameErrorPre.r.size(); ++i) {
 
  207        if(
fabs(frameErrorPre.r[i]) > tol || 
fabs(frameErrorSuc.r[i]) > tol) {
 
  208          framesNumericallyIdentical=
false;
 
  210        for(
unsigned int j=0; j<frameErrorPre.E.cols(); ++j) {
 
  211          if(
fabs(frameErrorPre.E(i,j))>tol || 
fabs(frameErrorSuc.E(i,j))>tol) {
 
  212            framesNumericallyIdentical=
false;
 
  218      if(framesNumericallyIdentical
 
  220        constraintAppended = 
true;
 
  221        loopConstraints[idx]->appendConstraintAxis(constraintAxisInPredecessor);
 
  226  if(constraintAppended==
false) {
 
  229                std::shared_ptr<LoopConstraint>(
 
  231                        idPredecessor, idSuccessor,XPredecessor, XSuccessor,
 
  233                        stabilizationTimeConstant,constraintName,userDefinedId)));
 
  244  if (constraintName != NULL) {
 
  245    nameStr = constraintName;
 
  248  name.push_back (nameStr);
 
  252  err[insertAtRowInG] = 0.;
 
  254  errd[insertAtRowInG] = 0.;
 
  257  force[insertAtRowInG] = 0.;
 
  263  v_plus[insertAtRowInG] = 0.;
 
  265  d_multdof3_u = std::vector<Math::Vector3d>(rowsInG, Math::Vector3d::Zero());
 
  268  if(nameStr.size() > 0) {
 
  269    std::pair< std::map<std::string, unsigned int>::iterator, 
bool > iter;
 
  270    iter = 
nameGroupMap.insert(std::pair<std::string, unsigned int>(
 
  282  if(userDefinedId < std::numeric_limits<unsigned int>::max()) {
 
  283    std::pair< std::map<unsigned int, unsigned int>::iterator, 
bool > iter;
 
  295  std::pair< std::map<unsigned int, unsigned int>::iterator, 
bool > iter;
 
  296  iter = 
idGroupMap.insert(std::pair<unsigned int, unsigned int>(
 
  299  if(iter.second == 
false) {
 
  300    std::stringstream errormsg;
 
  301    errormsg << 
"Error: Constraint row entry in system is not unique." 
  302             << 
" (This should not be possible: contact the " 
  303             "maintainer of this code.)" 
  305    throw Errors::RBDLError(errormsg.str());
 
  315  std::shared_ptr<Constraint> customConstraint)
 
  317  unsigned int insertAtRowInG = unsigned(
size());
 
  318  unsigned int rowsInG = insertAtRowInG+customConstraint->getConstraintSize();
 
  322  constraints[cIndex]->addToConstraintSet(insertAtRowInG);
 
  325  std::string nameStr(
"");
 
  326  if(customConstraint->getName() != NULL) {
 
  327    nameStr = customConstraint->getName();
 
  335  d_multdof3_u = std::vector<Math::Vector3d>(rowsInG, Math::Vector3d::Zero());
 
  337  for(
unsigned int i=0; i<customConstraint->getConstraintSize(); ++i) {
 
  340    name.push_back (nameStr);
 
  344    err[      insertAtRowInG+i ] = 0.;
 
  345    errd[     insertAtRowInG+i ] = 0.;
 
  346    force[    insertAtRowInG+i ] = 0.;
 
  347    impulse[  insertAtRowInG+i ] = 0.;
 
  348    v_plus[   insertAtRowInG+i ] = 0.;
 
  352  if(nameStr.size() > 0) {
 
  353    std::pair< std::map<std::string, unsigned int>::iterator, 
bool > iter;
 
  354    iter = 
nameGroupMap.insert(std::pair<std::string, unsigned int>(
 
  357    if(iter.second == 
false) {
 
  358      throw Errors::RBDLError(
"Error: optional name is not unique.\n");
 
  362  if(customConstraint->getUserDefinedId()
 
  363      < std::numeric_limits<unsigned int>::max()) {
 
  364    std::pair< std::map<unsigned int, unsigned int>::iterator, 
bool > iter;
 
  366                                          customConstraint->getUserDefinedId(),
 
  368    if(iter.second == 
false) {
 
  369      throw Errors::RBDLError(
"Error: optional userDefinedId is not unique.\n");
 
  374  std::pair< std::map<unsigned int, unsigned int>::iterator, 
bool > iter;
 
  375  iter = 
idGroupMap.insert(std::pair<unsigned int, unsigned int>(
 
  378  if(iter.second == 
false) {
 
  379    std::stringstream errormsg;
 
  380    errormsg << 
"Error: Constraint row entry into system is not unique." 
  381             << 
" (This should not be possible: contact the " 
  382             "maintainer of this code.)" 
  384    throw Errors::RBDLError(errormsg.str());
 
  395  assert (
bound == 
false);
 
  398    throw Errors::RBDLError(
"Error: binding an already bound constraint set!\n");
 
  421  unsigned int n_constr = 
size();
 
  442  W.
Identity(model.dof_count, model.dof_count);
 
  445#ifndef RBDL_USE_CASADI_MATH 
  460  f_t.resize (n_constr, SpatialVector::Zero());
 
  470  d_pA =std::vector<SpatialVector> (model.mBodies.size(),SpatialVector::Zero());
 
  471  d_a = std::vector<SpatialVector> (model.mBodies.size(),SpatialVector::Zero());
 
  474  d_IA = std::vector<SpatialMatrix> (model.mBodies.size()
 
  475                                     , SpatialMatrix::Identity());
 
  476  d_U = std::vector<SpatialVector> (model.mBodies.size(),SpatialVector::Zero());
 
  479  d_multdof3_u = std::vector<Math::Vector3d> (model.mBodies.size()
 
  480                 , Math::Vector3d::Zero());
 
  489                                    const std::vector<bool> &actuatedDofUpd)
 
  492  assert(actuatedDofUpd.size() == model.dof_count);
 
  494  unsigned int n  = unsigned( 
int( model.dof_count ));
 
  495  unsigned int nc = unsigned( 
int( 
name.size() ));
 
  499  for(
unsigned int i=0; i<actuatedDofUpd.size(); ++i) {
 
  500    if(actuatedDofUpd[i]) {
 
  522  for(
unsigned int i=0; i<model.dof_count; ++i) {
 
  523    if(actuatedDofUpd[i]) {
 
  532  unsigned int dim = n+n+nc+na;
 
  627  for(
unsigned int i=0; i<
f_t.size(); ++i) {
 
  634  for (i = 0; i < 
f_t.size(); i++) {
 
  646  for (i = 0; i < 
d_pA.size(); i++) {
 
  650  for (i = 0; i < 
d_a.size(); i++) {
 
  673  A.
block(0, 0, c.rows(), c.rows()) = 
H;
 
  680  b.
block(0, 0, c.rows(), 1) = c;
 
  683  LOG << 
"A = " << std::endl << 
A << std::endl;
 
  684  LOG << 
"b = " << std::endl << 
b << std::endl;
 
  686#ifdef RBDL_USE_CASADI_MATH 
  687  auto linsol = casadi::Linsol(
"linear_solver", 
"symbolicqr", 
A.sparsity());
 
  688  x = linsol.solve(
A, 
b);
 
  692    x = 
A.partialPivLu().solve(
b);
 
  695    x = 
A.colPivHouseholderQr().solve(
b);
 
  698    x = 
A.householderQr().solve(
b);
 
  701    LOG << 
"Error: Invalid linear solver: " << 
linear_solver << std::endl;
 
  707  LOG << 
"x = " << std::endl << 
x << std::endl;
 
  729  for (
unsigned int i = 0; i < 
Y.
cols(); i++) {
 
  741#ifdef RBDL_USE_CASADI_MATH 
  742  auto linsol = casadi::Linsol(
"linear_solver", 
"symbolicqr", 
K.sparsity());
 
  743  lambda = linsol.solve(
K, 
a);
 
  745  lambda = 
K.llt().solve(
a);
 
  770#ifdef RBDL_USE_CASADI_MATH 
  772    auto linsol = casadi::Linsol(
"linear_solver", 
"symbolicqr", GY.sparsity());
 
  786    LOG << 
"Error: Invalid linear solver: " << 
linear_solver << std::endl;
 
  792#ifdef RBDL_USE_CASADI_MATH 
  794    linsol = casadi::Linsol(
"linear_solver", 
"symbolicqr", ZHZ.sparsity());
 
  801#ifdef RBDL_USE_CASADI_MATH 
  803    linsol = casadi::Linsol(
"linear_solver", 
"symbolicqr", GY.sparsity());
 
  804    lambda = linsol.solve(GY, 
Y.
transpose() * (
H * qddot - c));
 
  808    lambda = (
G * 
Y).partialPivLu().solve (
Y.
transpose() * (
H * qddot - c));
 
  811    lambda = (
G*
Y).colPivHouseholderQr().solve (
Y.
transpose()*(
H*qddot - c));
 
  814    lambda = (
G * 
Y).householderQr().solve (
Y.
transpose() * (
H * qddot - c));
 
  817    LOG << 
"Error: Invalid linear solver: " << 
linear_solver << std::endl;
 
  832  bool update_kinematics
 
  835  assert(
err.
size() == CS.size());
 
  837  if(update_kinematics) {
 
  841  for(
unsigned int i=0; i<CS.constraints.size(); ++i) {
 
  842    CS.constraints[i]->calcPositionError(model,0,Q,
err, CS.cache,
 
  854  bool update_kinematics
 
  857  if (update_kinematics) {
 
  861  for(
unsigned int i=0; i<CS.constraints.size(); ++i) {
 
  862    CS.constraints[i]->calcConstraintJacobian(model,0,Q,CS.cache.vecNZeros,
G,
 
  863        CS.cache,update_kinematics);
 
  875  bool update_kinematics
 
  882  for(
unsigned int i=0; i<CS.constraints.size(); ++i) {
 
  883    CS.constraints[i]->calcVelocityError(model,0,Q,QDot,CS.G,
err,CS.cache,
 
  897  bool update_kinematics,
 
  898  std::vector<Math::SpatialVector> *f_ext
 
  902  if(update_kinematics){
 
  908  assert(CS.H.cols() == model.dof_count && CS.H.rows() == model.dof_count);
 
  924  unsigned int prev_body_id = 0;
 
  925  Vector3d prev_body_point = Vector3d::Zero();
 
  926  Vector3d gamma_i = Vector3d::Zero();
 
  928  CS.QDDot_0.setZero();
 
  932  for(
unsigned int i=0; i<CS.constraints.size(); ++i) {
 
  933    CS.constraints[i]->calcGamma(model,0,Q,QDot,CS.G,CS.gamma,CS.cache);
 
  934    if(CS.constraints[i]->isBaumgarteStabilizationEnabled()) {
 
  935      CS.constraints[i]->addInBaumgarteStabilizationForces(
 
  936        CS.err,CS.errd,CS.gamma);
 
  944#ifndef RBDL_USE_CASADI_MATH 
  953  unsigned int max_iter
 
  957  if(Q.size() != model.q_size) {
 
  958    throw Errors::RBDLDofMismatchError(
"Incorrect Q vector size.\n");
 
  960  if(QInit.size() != model.q_size) {
 
  961    throw Errors::RBDLDofMismatchError(
"Incorrect QInit vector size.\n");
 
  963  if(weights.size() != model.dof_count) {
 
  964    throw Errors::RBDLDofMismatchError(
"Incorrect weights vector size.\n");
 
  968  MatrixNd constraintJac (cs.size(), model.dof_count);
 
  977  for(
unsigned int i = 0; i < weights.size(); ++i) {
 
  984  if (e.norm() < tolerance) {
 
  991  for(
unsigned int it = 0; it < max_iter; ++it) {
 
  993    constraintJac.setZero();
 
  995    A.
block (model.dof_count, 0, cs.size(), model.dof_count) = constraintJac;
 
  996    A.
block (0, model.dof_count, model.dof_count, cs.size())
 
  997      = constraintJac.transpose();
 
  998    b.
block (model.dof_count, 0, cs.size(), 1) = -e;
 
 1001    SolveLinearSystem (
A, 
b, 
x, cs.linear_solver);
 
 1004    d = 
x.
block (0, 0, model.dof_count, 1);
 
 1007    for (
size_t i = 0; i < model.mJoints.size(); ++i) {
 
 1010      if (model.mJoints[i].mJointType == JointTypeSpherical) {
 
 1011        Quaternion quat = model.GetQuaternion(i, QInit);
 
 1012        Vector3d omega = d.block<3,1>(model.mJoints[i].q_index,0);
 
 1015        quat += quat.omegaToQDot(omega);
 
 1017        quat /= quat.norm();
 
 1018        model.SetQuaternion(i, quat, QInit);
 
 1023        unsigned int qIdx = model.mJoints[i].q_index;
 
 1024        for(
size_t j = 0; j < model.mJoints[i].mDoFCount; ++j) {
 
 1025          QInit[qIdx + j] += d[qIdx + j];
 
 1034    if (e.norm() < tolerance && d.norm() < tolerance) {
 
 1057  if(QDot.size() != model.dof_count) {
 
 1058    throw Errors::RBDLDofMismatchError(
"Incorrect QDot vector size.\n");
 
 1060  if(Q.size() != model.q_size) {
 
 1061    throw Errors::RBDLDofMismatchError(
"Incorrect Q vector size.\n");
 
 1063  if(QDotInit.size() != QDot.size()) {
 
 1064    throw Errors::RBDLDofMismatchError(
"Incorrect QDotInit vector size.\n");
 
 1066  if(weights.size() != QDot.size()) {
 
 1067    throw Errors::RBDLDofMismatchError(
"Incorrect weight vector size.\n");
 
 1078  for(
unsigned int i = 0; i < weights.size(); ++i) {
 
 1079    A(i,i) = weights[i];
 
 1080    b[i] = weights[i] * QDotInit[i];
 
 1083  A.
block (model.dof_count, 0, cs.size(), model.dof_count) = constraintJac;
 
 1084  A.
block (0, model.dof_count, model.dof_count, cs.size())
 
 1085    = constraintJac.transpose();
 
 1088  SolveLinearSystem (
A, 
b, 
x, cs.linear_solver);
 
 1091  QDot = 
x.
block (0, 0, model.dof_count, 1);
 
 1103  bool update_kinematics,
 
 1104  std::vector<Math::SpatialVector> *f_ext
 
 1107  LOG << 
"-------- " << __func__ << 
" --------" << std::endl;
 
 1113                                , CS.force, CS.A, CS.b, CS.x, CS.linear_solver);
 
 1116  for (
unsigned int i = 0; i < model.dof_count; i++) {
 
 1121  for (
unsigned int i = 0; i < CS.size(); i++) {
 
 1122    CS.force[i] = -CS.x[model.dof_count + i];
 
 1135  bool update_kinematics,
 
 1136  std::vector<Math::SpatialVector> *f_ext)
 
 1143                                          , CS.gamma, QDDot, CS.force, CS.K, CS.a, CS.linear_solver);
 
 1147#ifndef RBDL_USE_CASADI_MATH 
 1156  bool update_kinematics,
 
 1157  std::vector<Math::SpatialVector> *f_ext
 
 1161  LOG << 
"-------- " << __func__ << 
" --------" << std::endl;
 
 1166  CS.GT_qr.compute (CS.G.transpose());
 
 1167  CS.GT_qr.householderQ().evalTo (CS.GT_qr_Q);
 
 1169  CS.Y = CS.GT_qr_Q.block (0,0,QDot.rows(), CS.G.rows());
 
 1170  CS.Z = CS.GT_qr_Q.block (0,CS.G.rows(),QDot.rows(), QDot.rows() - CS.G.rows());
 
 1173                                   , CS.force, CS.Y, CS.Z, CS.qddot_y, CS.qddot_z, CS.linear_solver);
 
 1197                                , CS.impulse, CS.A, CS.b, CS.x, CS.linear_solver);
 
 1200  for (
unsigned int i = 0; i < model.dof_count; i++) {
 
 1201    QDotPlus[i] = CS.x[i];
 
 1205  for (
unsigned int i = 0; i < CS.size(); i++) {
 
 1206    CS.impulse[i] = CS.x[model.dof_count + i];
 
 1230                                          , CS.v_plus, QDotPlus, CS.impulse, CS.K, CS.a, CS.linear_solver);
 
 1235#ifndef RBDL_USE_CASADI_MATH 
 1253  CS.GT_qr.compute(CS.G.transpose());
 
 1254  CS.GT_qr_Q = CS.GT_qr.householderQ();
 
 1256  CS.Y = CS.GT_qr_Q.block (0,0,QDotMinus.rows(), CS.G.rows());
 
 1257  CS.Z = CS.GT_qr_Q.block (0,CS.G.rows(),QDotMinus.rows(), QDotMinus.rows()
 
 1261                                   , QDotPlus, CS.impulse, CS.Y, CS.Z, CS.qddot_y, CS.qddot_z
 
 1262                                   , CS.linear_solver);
 
 1276void ForwardDynamicsApplyConstraintForces (
 
 1283  LOG << 
"-------- " << __func__ << 
" --------" << std::endl;
 
 1284  assert (QDDot.size() == model.dof_count);
 
 1288  for (i = 1; i < model.mBodies.size(); i++) {
 
 1289    model.IA[i] = model.I[i].toMatrix();;
 
 1290    model.pA[i] = 
crossf(model.v[i],model.I[i] * model.v[i]);
 
 1292#ifdef RBDL_USE_CASADI_MATH 
 1295    if (CS.f_ext_constraints[i] != SpatialVector::Zero()) {
 
 1297      LOG << 
"External force (" << i << 
") = " 
 1298          << model.X_base[i].toMatrixAdjoint() * CS.f_ext_constraints[i]
 
 1300      model.pA[i] -= model.X_base[i].toMatrixAdjoint()*CS.f_ext_constraints[i];
 
 1306  LOG << 
"--- first loop ---" << std::endl;
 
 1308  for (i = model.mBodies.size() - 1; i > 0; i--) {
 
 1309    unsigned int q_index = model.mJoints[i].q_index;
 
 1311    if (model.mJoints[i].mDoFCount == 3
 
 1312        && model.mJoints[i].mJointType != JointTypeCustom) {
 
 1313      unsigned int lambda = model.lambda[i];
 
 1314      model.multdof3_u[i] = 
Vector3d (Tau[q_index],
 
 1317                            - model.multdof3_S[i].transpose() * model.pA[i];
 
 1321                                          * model.multdof3_Dinv[i]
 
 1322                                          * model.multdof3_U[i].transpose());
 
 1325                           + model.multdof3_U[i] * model.multdof3_Dinv[i] * model.multdof3_u[i];
 
 1327#ifdef RBDL_USE_CASADI_MATH 
 1328        model.IA[lambda] += (model.X_lambda[i].toMatrixTranspose()
 
 1329                                       * Ia * model.X_lambda[i].toMatrix());
 
 1330        model.pA[lambda] += model.X_lambda[i].applyTranspose(pa);
 
 1332        model.IA[lambda].noalias() += (model.X_lambda[i].toMatrixTranspose()
 
 1333                                       * Ia * model.X_lambda[i].toMatrix());
 
 1334        model.pA[lambda].noalias() += model.X_lambda[i].applyTranspose(pa);
 
 1337        LOG << 
"pA[" << lambda << 
"] = " << model.pA[lambda].transpose()
 
 1340    } 
else if (model.mJoints[i].mDoFCount == 1
 
 1341               && model.mJoints[i].mJointType != JointTypeCustom) {
 
 1342      model.u[i] = Tau[q_index] - model.S[i].dot(model.pA[i]);
 
 1344      unsigned int lambda = model.lambda[i];
 
 1347                           - model.U[i] * (model.U[i] / model.d[i]).transpose();
 
 1349                            + model.U[i] * model.u[i] / model.d[i];
 
 1350#ifdef RBDL_USE_CASADI_MATH 
 1351        model.IA[lambda] += (model.X_lambda[i].toMatrixTranspose()
 
 1352                                       * Ia * model.X_lambda[i].toMatrix());
 
 1353        model.pA[lambda] += model.X_lambda[i].applyTranspose(pa);
 
 1355        model.IA[lambda].noalias() += (model.X_lambda[i].toMatrixTranspose()
 
 1356                                       * Ia * model.X_lambda[i].toMatrix());
 
 1357        model.pA[lambda].noalias() += model.X_lambda[i].applyTranspose(pa);
 
 1360        LOG << 
"pA[" << lambda << 
"] = " 
 1361            << model.pA[lambda].transpose() << std::endl;
 
 1363    } 
else if(model.mJoints[i].mJointType == JointTypeCustom) {
 
 1365      unsigned int kI     = model.mJoints[i].custom_joint_index;
 
 1366      unsigned int dofI   = model.mCustomJoints[kI]->mDoFCount;
 
 1367      unsigned int lambda = model.lambda[i];
 
 1370      for(
int z=0; z<dofI; ++z) {
 
 1371        tau_temp[z] = Tau[q_index+z];
 
 1374      model.mCustomJoints[kI]->u = tau_temp
 
 1375                                   - (model.mCustomJoints[kI]->S.transpose()
 
 1380                           - (   model.mCustomJoints[kI]->U
 
 1381                                 * model.mCustomJoints[kI]->Dinv
 
 1382                                 * model.mCustomJoints[kI]->U.transpose());
 
 1385                           + ( model.mCustomJoints[kI]->U
 
 1386                               * model.mCustomJoints[kI]->Dinv
 
 1387                               * model.mCustomJoints[kI]->u );
 
 1389#ifdef RBDL_USE_CASADI_MATH 
 1390        model.IA[lambda] += model.X_lambda[i].toMatrixTranspose()
 
 1391                                      * Ia * model.X_lambda[i].toMatrix();
 
 1393        model.pA[lambda] += model.X_lambda[i].applyTranspose(pa);
 
 1395        model.IA[lambda].noalias() += model.X_lambda[i].toMatrixTranspose()
 
 1396                                      * Ia * model.X_lambda[i].toMatrix();
 
 1398        model.pA[lambda].noalias() += model.X_lambda[i].applyTranspose(pa);
 
 1401        LOG << 
"pA[" << lambda << 
"] = " << model.pA[lambda].transpose()
 
 1412  for (i = 1; i < model.mBodies.size(); i++) {
 
 1413    unsigned int q_index = model.mJoints[i].q_index;
 
 1414    unsigned int lambda = model.lambda[i];
 
 1415    SpatialTransform X_lambda = model.X_lambda[i];
 
 1417    model.a[i] = X_lambda.apply(model.a[lambda]) + model.c[i];
 
 1418    LOG << 
"a'[" << i << 
"] = " << model.a[i].transpose() << std::endl;
 
 1420    if (model.mJoints[i].mDoFCount == 3
 
 1421        && model.mJoints[i].mJointType != JointTypeCustom) {
 
 1422      Vector3d qdd_temp = model.multdof3_Dinv[i] *
 
 1423                          (model.multdof3_u[i]
 
 1424                           - model.multdof3_U[i].transpose() * model.a[i]);
 
 1426      QDDot[q_index] = qdd_temp[0];
 
 1427      QDDot[q_index + 1] = qdd_temp[1];
 
 1428      QDDot[q_index + 2] = qdd_temp[2];
 
 1429      model.a[i] = model.a[i] + model.multdof3_S[i] * qdd_temp;
 
 1430    } 
else if (model.mJoints[i].mDoFCount == 1
 
 1431               && model.mJoints[i].mJointType != JointTypeCustom) {
 
 1432      QDDot[q_index] = (1./model.d[i]) * (
 
 1433                         model.u[i] - model.U[i].dot(model.a[i]));
 
 1434      model.a[i] = model.a[i] + model.S[i] * QDDot[q_index];
 
 1435    } 
else if (model.mJoints[i].mJointType == JointTypeCustom) {
 
 1436      unsigned int kI     = model.mJoints[i].custom_joint_index;
 
 1437      unsigned int dofI   = model.mCustomJoints[kI]->mDoFCount;
 
 1440      qdd_temp = model.mCustomJoints[kI]->Dinv
 
 1441                 * (model.mCustomJoints[kI]->u
 
 1442                    - model.mCustomJoints[kI]->U.transpose()
 
 1445      for(
int z=0; z<dofI; ++z) {
 
 1446        QDDot[q_index+z] = qdd_temp[z];
 
 1449      model.a[i] = model.a[i] + (model.mCustomJoints[kI]->S * qdd_temp);
 
 1453  LOG << 
"QDDot = " << QDDot.transpose() << std::endl;
 
 1465void ForwardDynamicsAccelerationDeltas (
 
 1469  const unsigned int body_id,
 
 1470  const std::vector<SpatialVector> &
f_t 
 1473  LOG << 
"-------- " << __func__ << 
" ------" << std::endl;
 
 1475  assert (CS.d_pA.size() == model.mBodies.size());
 
 1476  assert (CS.d_a.size() == model.mBodies.size());
 
 1477  assert (CS.d_u.size() == model.mBodies.size());
 
 1480  for (
unsigned int i = 0; i < model.mBodies.size(); i++) {
 
 1481    CS.d_pA[i].setZero();
 
 1482    CS.d_a[i].setZero();
 
 1484    CS.d_multdof3_u[i].setZero();
 
 1486  for(
unsigned int i=0; i<model.mCustomJoints.size(); i++) {
 
 1487    model.mCustomJoints[i]->d_u.setZero();
 
 1490  for (
unsigned int i = body_id; i > 0; i--) {
 
 1492      CS.d_pA[i] = -model.X_base[i].applyAdjoint(
f_t[i]);
 
 1495    if (model.mJoints[i].mDoFCount == 3
 
 1496        && model.mJoints[i].mJointType != JointTypeCustom) {
 
 1497      CS.d_multdof3_u[i] = - model.multdof3_S[i].transpose() * (CS.d_pA[i]);
 
 1499      unsigned int lambda = model.lambda[i];
 
 1501        CS.d_pA[lambda] =   CS.d_pA[lambda]
 
 1502                            + model.X_lambda[i].applyTranspose (
 
 1503                              CS.d_pA[i] + (model.multdof3_U[i]
 
 1504                                            * model.multdof3_Dinv[i]
 
 1505                                            * CS.d_multdof3_u[i]));
 
 1507    } 
else if(model.mJoints[i].mDoFCount == 1
 
 1508              && model.mJoints[i].mJointType != JointTypeCustom) {
 
 1509      CS.d_u[i] = - model.S[i].dot(CS.d_pA[i]);
 
 1510      unsigned int lambda = model.lambda[i];
 
 1513        CS.d_pA[lambda] = CS.d_pA[lambda]
 
 1514                          + model.X_lambda[i].applyTranspose (
 
 1515                            CS.d_pA[i] + model.U[i] * CS.d_u[i] / model.d[i]);
 
 1517    } 
else if (model.mJoints[i].mJointType == JointTypeCustom) {
 
 1519      unsigned int kI     = model.mJoints[i].custom_joint_index;
 
 1520      unsigned int dofI   = model.mCustomJoints[kI]->mDoFCount;
 
 1522      model.mCustomJoints[kI]->d_u =
 
 1523        - model.mCustomJoints[kI]->S.transpose() * (CS.d_pA[i]);
 
 1524      unsigned int lambda = model.lambda[i];
 
 1528          + model.X_lambda[i].applyTranspose (
 
 1529            CS.d_pA[i] + (   model.mCustomJoints[kI]->U
 
 1530                             * model.mCustomJoints[kI]->Dinv
 
 1531                             * model.mCustomJoints[kI]->d_u)
 
 1537  for (
unsigned int i = 0; i < 
f_t.size(); i++) {
 
 1538    LOG << 
"f_t[" << i << 
"] = " << 
f_t[i].transpose() << std::endl;
 
 1541  for (
unsigned int i = 0; i < model.mBodies.size(); i++) {
 
 1542    LOG << 
"i = " << i << 
": d_pA[i] " << CS.d_pA[i].transpose() << std::endl;
 
 1544  for (
unsigned int i = 0; i < model.mBodies.size(); i++) {
 
 1545    LOG << 
"i = " << i << 
": d_u[i] = " << CS.d_u[i] << std::endl;
 
 1549  CS.d_a[0] = model.a[0];
 
 1551  for (
unsigned int i = 1; i < model.mBodies.size(); i++) {
 
 1552    unsigned int q_index = model.mJoints[i].q_index;
 
 1553    unsigned int lambda = model.lambda[i];
 
 1557    if (model.mJoints[i].mDoFCount == 3
 
 1558        && model.mJoints[i].mJointType != JointTypeCustom) {
 
 1559      Vector3d qdd_temp = model.multdof3_Dinv[i]
 
 1560                          * (CS.d_multdof3_u[i] - model.multdof3_U[i].transpose() * Xa);
 
 1562      QDDot_t[q_index] = qdd_temp[0];
 
 1563      QDDot_t[q_index + 1] = qdd_temp[1];
 
 1564      QDDot_t[q_index + 2] = qdd_temp[2];
 
 1565      model.a[i] = model.a[i] + model.multdof3_S[i] * qdd_temp;
 
 1566      CS.d_a[i] = Xa + model.multdof3_S[i] * qdd_temp;
 
 1567    } 
else if (model.mJoints[i].mDoFCount == 1
 
 1568               && model.mJoints[i].mJointType != JointTypeCustom) {
 
 1570      QDDot_t[q_index] = (CS.d_u[i] - model.U[i].dot(Xa) ) / model.d[i];
 
 1571      CS.d_a[i] = Xa + model.S[i] * 
QDDot_t[q_index];
 
 1572    } 
else if (model.mJoints[i].mJointType == JointTypeCustom) {
 
 1573      unsigned int kI     = model.mJoints[i].custom_joint_index;
 
 1574      unsigned int dofI   = model.mCustomJoints[kI]->mDoFCount;
 
 1577      qdd_temp = model.mCustomJoints[kI]->Dinv
 
 1578                 * (model.mCustomJoints[kI]->d_u
 
 1579                    - model.mCustomJoints[kI]->U.transpose() * Xa);
 
 1581      for(
int z=0; z<dofI; ++z) {
 
 1582        QDDot_t[q_index+z] = qdd_temp[z];
 
 1585      model.a[i] = model.a[i] + model.mCustomJoints[kI]->S * qdd_temp;
 
 1586      CS.d_a[i] = Xa + model.mCustomJoints[kI]->S * qdd_temp;
 
 1589    LOG << 
"QDDot_t[" << i - 1 << 
"] = " << 
QDDot_t[i - 1] << std::endl;
 
 1590    LOG << 
"d_a[i] = " << CS.d_a[i].
transpose() << std::endl;
 
 1594inline void set_zero (std::vector<SpatialVector> &spatial_values)
 
 1596  for (
unsigned int i = 0; i < spatial_values.size(); i++) {
 
 1612  LOG << 
"-------- " << __func__ << 
" ------" << std::endl;
 
 1614  assert (CS.f_ext_constraints.size() == model.mBodies.size());
 
 1615  assert (CS.QDDot_0.size() == model.dof_count);
 
 1616  assert (CS.QDDot_t.size() == model.dof_count);
 
 1617  assert (CS.f_t.size() == CS.size());
 
 1618  assert (CS.point_accel_0.size() == CS.size());
 
 1619  assert (CS.K.rows() == CS.size());
 
 1620  assert (CS.K.cols() == CS.size());
 
 1621  assert (CS.force.size() == CS.size());
 
 1622  assert (CS.a.size() == CS.size());
 
 1624  if(CS.constraints.size() != CS.contactConstraints.size()) {
 
 1625    std::stringstream errormsg;
 
 1626    errormsg << 
"Incompatible constraint types: all constraints" 
 1627             << 
" must be ContactConstraints for the Kokkevis method" 
 1629    throw Errors::RBDLError(errormsg.str());
 
 1634  unsigned int ci = 0; 
 
 1643  LOG << 
"=== Initial Loop Start ===" << std::endl;
 
 1646  unsigned int bi = 0;
 
 1647  for(bi =0; bi < CS.contactConstraints.size(); ++bi) {
 
 1654          << CS.contactConstraints[bi]->getBodyIds()[0]
 
 1657          << CS.contactConstraints[bi]->getBodyFrames()[0].r
 
 1659      LOG << 
"QDDot_0 = " << CS.QDDot_0.transpose() << std::endl;
 
 1663      CS.contactConstraints[bi]->calcPointAccelerations(
 
 1664        model,Q,QDot,CS.QDDot_0,CS.point_accel_0,
false);
 
 1665      CS.contactConstraints[bi]->calcPointAccelerationError(
 
 1666        CS.point_accel_0,CS.a);
 
 1672  unsigned int movable_body_id = 0;
 
 1675  for (bi = 0; bi < CS.contactConstraints.size(); bi++) {
 
 1677    LOG << 
"=== Testforce Loop Start ===" << std::endl;
 
 1679    ci = CS.contactConstraints[bi]->getConstraintIndex();
 
 1681    movable_body_id = GetMovableBodyId(model,
 
 1682                                       CS.contactConstraints[bi]->getBodyIds()[0]);
 
 1685    LOG << 
"point_global = " << point_global.transpose() << std::endl;
 
 1687    CS.contactConstraints[bi]->calcPointForceJacobian(
 
 1688      model,Q,CS.cache,CS.f_t,
false);
 
 1690    for(
unsigned int j = 0; j<CS.contactConstraints[bi]
 
 1691        ->getConstraintNormalVectors().
size(); ++j) {
 
 1693      CS.f_ext_constraints[movable_body_id] = CS.f_t[ci+j];
 
 1695      LOG << 
"f_t[" << movable_body_id << 
"] = " << CS.f_t[ci+j].transpose()
 
 1698        ForwardDynamicsAccelerationDeltas(model, CS, CS.QDDot_t
 
 1699                                          , movable_body_id, CS.f_ext_constraints);
 
 1701        LOG << 
"QDDot_0 = " << CS.QDDot_0.transpose() << std::endl;
 
 1702        LOG << 
"QDDot_t = " << (CS.QDDot_t + CS.QDDot_0).transpose()
 
 1704        LOG << 
"QDDot_t - QDDot_0 = " << (CS.QDDot_t).transpose() << std::endl;
 
 1707      CS.f_ext_constraints[movable_body_id].setZero();
 
 1709      CS.QDDot_t += CS.QDDot_0;
 
 1716      for(
unsigned int dj = 0;
 
 1717          dj < CS.contactConstraints.size(); dj++) {
 
 1719        cj = CS.contactConstraints[dj]->getConstraintIndex();
 
 1722          CS.contactConstraints[dj]->calcPointAccelerations(
 
 1723            model,Q,QDot,CS.QDDot_t,point_accel_t,
false);
 
 1726        LOG << 
"point_accel_0  = " << CS.point_accel_0[ci+j].transpose()
 
 1728        LOG << 
"point_accel_t = " << point_accel_t.transpose() << std::endl;
 
 1729        for(
unsigned int k=0;
 
 1730            k < CS.contactConstraints[dj]
 
 1731            ->getConstraintNormalVectors().
size(); ++k) {
 
 1733          CS.K(ci+j,cj+k) = CS.contactConstraints[dj]
 
 1734                            ->getConstraintNormalVectors()[k].dot(
 
 1735                              point_accel_t - CS.point_accel_0[cj+k]);
 
 1744  LOG << 
"K = " << std::endl << CS.K << std::endl;
 
 1745  LOG << 
"a = " << std::endl << CS.a << std::endl;
 
 1747#ifdef RBDL_USE_CASADI_MATH 
 1748    auto linsol = casadi::Linsol(
"linear_solver", 
"symbolicqr", CS.K.sparsity());
 
 1749    CS.force = linsol.solve(CS.K, CS.a);
 
 1751  switch (CS.linear_solver) {
 
 1753    CS.force = CS.K.partialPivLu().solve(CS.a);
 
 1756    CS.force = CS.K.colPivHouseholderQr().solve(CS.a);
 
 1759    CS.force = CS.K.householderQr().solve(CS.a);
 
 1762    LOG << 
"Error: Invalid linear solver: " << CS.linear_solver << std::endl;
 
 1768  LOG << 
"f = " << CS.force.transpose() << std::endl;
 
 1771  for(bi=0; bi<CS.contactConstraints.size(); ++bi) {
 
 1772    unsigned int body_id =
 
 1773      CS.contactConstraints[bi]->getBodyIds()[0];
 
 1774    unsigned int movable_body_id = body_id;
 
 1776    if (model.IsFixedBodyId(body_id)) {
 
 1777      unsigned int fbody_id = body_id - model.fixed_body_discriminator;
 
 1778      movable_body_id = model.mFixedBodies[fbody_id].mMovableParent;
 
 1780    ci = CS.contactConstraints[bi]->getConstraintIndex();
 
 1782    for(
unsigned int k=0;
 
 1783        k<CS.contactConstraints[bi]->getConstraintSize(); ++k) {
 
 1784      CS.f_ext_constraints[movable_body_id] -= CS.f_t[ci+k] * CS.force[ci+k];
 
 1785      LOG << 
"f_ext[" << movable_body_id << 
"] = " 
 1786          << CS.f_ext_constraints[movable_body_id].transpose() << std::endl;
 
 1795    ForwardDynamicsApplyConstraintForces (model, Tau, CS, QDDot);
 
 1798  LOG << 
"QDDot after applying f_ext: " << QDDot.transpose() << std::endl;
 
 1803#ifndef RBDL_USE_CASADI_MATH 
 1810  bool update_kinematics,
 
 1811  std::vector<Math::SpatialVector> *f_ext)
 
 1814  LOG << 
"-------- " << __func__ << 
" ------" << std::endl;
 
 1817  assert (CS.S.cols()    == QDot.rows());
 
 1819  unsigned int n  = unsigned(    CS.H.rows());
 
 1820  unsigned int nc = unsigned( CS.name.size());
 
 1821  unsigned int na = unsigned(    CS.S.rows());
 
 1822  unsigned int nu = n-na;
 
 1826                                 update_kinematics, f_ext);
 
 1828  CS.GPT = CS.G*CS.P.transpose();
 
 1830  CS.GPT_full_qr.compute(CS.GPT);
 
 1831  unsigned int r = unsigned(CS.GPT_full_qr.rank());
 
 1833  bool isCompatible = 
false;
 
 1835    isCompatible = 
true;
 
 1837    isCompatible = 
false;
 
 1840  return isCompatible;
 
 1854  bool update_kinematics,
 
 1855  std::vector<Math::SpatialVector> *f_ext)
 
 1858  LOG << 
"-------- " << __func__ << 
" ------" << std::endl;
 
 1860  assert (QDot.size()         == QDDotDesired.size());
 
 1861  assert (QDDotDesired.size() == QDot.size());
 
 1862  assert (QDDotOutput.size()  == QDot.size());
 
 1863  assert (TauOutput.size()    == CS.H.rows());
 
 1865  assert (CS.S.cols()     == QDDotDesired.rows());
 
 1867  unsigned int n  = unsigned(    CS.H.rows());
 
 1868  unsigned int nc = unsigned( CS.name.size());
 
 1869  unsigned int na = unsigned(    CS.S.rows());
 
 1870  unsigned int nu = n-na;
 
 1872  TauOutput.setZero();
 
 1885  CS.Ful = CS.S*CS.H*CS.S.transpose();
 
 1886  CS.Fur = CS.S*CS.H*CS.P.transpose();
 
 1887  CS.Fll = CS.P*CS.H*CS.S.transpose();
 
 1888  CS.Flr = CS.P*CS.H*CS.P.transpose();
 
 1890  CS.GTu = CS.S*(CS.G.transpose());
 
 1891  CS.GTl = CS.P*(CS.G.transpose());
 
 1896  CS.u = CS.S*QDDotDesired;
 
 1902  SolveLinearSystem( CS.GTl.transpose(),
 
 1903                     CS.gamma - CS.GTu.transpose()*CS.u,
 
 1904                     CS.v, CS.linear_solver);
 
 1907  SolveLinearSystem(CS.GTl,
 
 1914  for(
unsigned int i=0; i<CS.force.rows(); ++i) {
 
 1915    CS.force[i] *= -1.0;
 
 1919  QDDotOutput = CS.S.transpose()*CS.u + CS.P.transpose()*CS.v;
 
 1922  TauOutput = -CS.S.transpose()*( -CS.S*CS.C
 
 1932#ifndef RBDL_USE_CASADI_MATH 
 1942  bool update_kinematics,
 
 1943  std::vector<Math::SpatialVector> *f_ext)
 
 1945  LOG << 
"-------- " << __func__ << 
" --------" << std::endl;
 
 1948  assert(Q.size()               == model.q_size);
 
 1949  assert(QDot.size()            == model.qdot_size);
 
 1950  assert(QDDotControls.size()    == model.dof_count);
 
 1951  assert(CS.S.cols()            == model.dof_count);
 
 1952  assert(CS.W.rows()            == CS.W.cols());
 
 1953  assert(CS.W.rows()            == CS.S.rows());
 
 1954  assert(QDDotOutput.size()     == model.dof_count);
 
 1956  TauOutput.setZero();
 
 1960  unsigned int n  = unsigned(    CS.H.rows());
 
 1961  unsigned int nc = unsigned( CS.name.size());
 
 1962  unsigned int na = unsigned(    CS.S.rows());
 
 1963  unsigned int nu = n-na;
 
 1989  CS.W = 100.0*CS.S*CS.H*CS.S.transpose();
 
 1990  CS.Winv = CS.W.inverse();
 
 1991  CS.WinvSC = CS.Winv * CS.S * CS.C;
 
 1995  CS.F.block(  0,  0, na, na) = CS.S*CS.H*CS.S.transpose() + CS.W;
 
 1996  CS.F.block(  0, na, na, nu) = CS.S*CS.H*CS.P.transpose();
 
 1997  CS.F.block( na,  0, nu, na) = CS.P*CS.H*CS.S.transpose();
 
 1998  CS.F.block( na, na, nu, nu) = CS.P*CS.H*CS.P.transpose();
 
 2000  CS.GT.block(  0, 0,na, nc) = CS.S*(CS.G.transpose());
 
 2001  CS.GT.block( na, 0,nu, nc) = CS.P*(CS.G.transpose());
 
 2003  CS.GT_qr.compute (CS.GT);
 
 2004  CS.GT_qr.householderQ().evalTo (CS.GT_qr_Q);
 
 2009  CS.R  = CS.GT_qr_Q.transpose()*CS.GT;
 
 2010  CS.Ru = CS.R.block(0,0,nc,nc);
 
 2012  CS.Y = CS.GT_qr_Q.block( 0, 0,  n, nc    );
 
 2013  CS.Z = CS.GT_qr_Q.block( 0, nc, n, (n-nc));
 
 2027  CS.u = CS.S*CS.C - CS.W*(CS.S*(QDDotControls
 
 2028                                 +(CS.S.transpose()*CS.WinvSC)));
 
 2032  for(
unsigned int i=0; i<CS.S.rows(); ++i) {
 
 2035  unsigned int j=CS.S.rows();
 
 2036  for(
unsigned int i=0; i<CS.P.rows(); ++i) {
 
 2042  SolveLinearSystem(CS.Ru.transpose(), CS.gamma, CS.py, CS.linear_solver);
 
 2045  SolveLinearSystem(CS.Z.transpose()*CS.F*CS.Z,
 
 2046                    CS.Z.transpose()*(-CS.F*CS.Y*CS.py-CS.g),
 
 2051  SolveLinearSystem(CS.Ru,
 
 2052                    CS.Y.transpose()*(CS.g + CS.F*CS.Y*CS.py + CS.F*CS.Z*CS.pz),
 
 2053                    CS.force, CS.linear_solver);
 
 2058  QDDotOutput = CS.Y*CS.py + CS.Z*CS.pz;
 
 2059  for(
unsigned int i=0; i<CS.S.rows(); ++i) {
 
 2060    CS.u[i] = QDDotOutput[i];
 
 2063  for(
unsigned int i=0; i<CS.P.rows(); ++i) {
 
 2064    CS.v[i] = QDDotOutput[j];
 
 2068  QDDotOutput = CS.S.transpose()*CS.u
 
 2069                +CS.P.transpose()*CS.v;
 
 2071  TauOutput = (CS.S.transpose()*CS.W*CS.S)*(
 
 2072                QDDotControls+(CS.S.transpose()*CS.WinvSC)
 
 2080void SolveLinearSystem (
 
 2088    throw Errors::RBDLSizeMismatchError(
"Mismatching sizes.\n");
 
 2091#ifdef RBDL_USE_CASADI_MATH 
 2092  auto linsol = casadi::Linsol(
"linear_solver", 
"symbolicqr", 
A.sparsity());
 
 2093  x = linsol.solve(
A, 
b);
 
 2098    x = 
A.partialPivLu().solve(
b);
 
 2101    x = 
A.colPivHouseholderQr().solve(
b);
 
 2104    x = 
A.householderQr().solve(
b);
 
 2107    std::ostringstream errormsg;
 
 2108    errormsg << 
"Error: Invalid linear solver: " << ls << std::endl;
 
 2109    throw Errors::RBDLError(errormsg.str());
 
 2116unsigned int GetMovableBodyId (Model& model, 
unsigned int id)
 
 2118  if(model.IsFixedBodyId(
id)) {
 
 2119    unsigned int fbody_id = 
id - model.fixed_body_discriminator;
 
 2120    return model.mFixedBodies[fbody_id].mMovableParent;
 
 2129  unsigned int groupIndex,
 
 2133  std::vector< unsigned int > &constraintBodyIdsUpd,
 
 2134  std::vector< Math::SpatialTransform > &constraintBodyFramesUpd,
 
 2135  std::vector< Math::SpatialVector > &constraintForcesUpd,
 
 2136  bool resolveAllInRootFrame,
 
 2139  assert(groupIndex <= 
unsigned(
constraints.size()-1));
 
 2146      constraintBodyIdsUpd,
 
 2147      constraintBodyFramesUpd,
 
 2148      constraintForcesUpd,
 
 2150      resolveAllInRootFrame,
 
 2157  unsigned int groupIndex,
 
 2161  std::vector< unsigned int > &constraintBodyIdsUpd,
 
 2162  std::vector< Math::SpatialTransform > &constraintBodyFramesUpd,
 
 2163  std::vector< Math::SpatialVector > &constraintImpulsesUpd,
 
 2164  bool resolveAllInRootFrame,
 
 2167  assert(groupIndex <= 
unsigned(
constraints.size()-1));
 
 2176      constraintBodyIdsUpd,
 
 2177      constraintBodyFramesUpd,
 
 2178      constraintImpulsesUpd,
 
 2180      resolveAllInRootFrame,
 
 2185  for(
unsigned int i=0; i<constraintImpulsesUpd.size(); ++i) {
 
 2186    constraintImpulsesUpd[i] *= -1.0;
 
 2193  unsigned int groupIndex,
 
 2199  assert(groupIndex <= 
unsigned(
constraints.size()-1));
 
 2217  unsigned int groupIndex,
 
 2224  assert(groupIndex <= 
unsigned(
constraints.size()-1));
 
 2246  unsigned int groupIndex,
 
 2252  assert(groupIndex <= 
unsigned(
constraints.size()-1));
 
 2253  assert(positionError.rows() == 
constraints[groupIndex]->getConstraintSize());
 
 2254  assert(velocityError.rows() == 
constraints[groupIndex]->getConstraintSize());
 
 2256  constraints[groupIndex]->getBaumgarteStabilizationForces(positionError,
 
MX_Xd_dynamic transpose() const
 
unsigned int rows() const
 
MX_Xd_dynamic & setZero()
 
unsigned int cols() const
 
void resize(unsigned int newI, unsigned int newJ=1)
 
unsigned int size() const
 
static MX_Xd_dynamic Identity(unsigned int size, unsigned int ignoredSize=0)
 
void conservativeResize(unsigned int nrows, unsigned int ncols=1)
 
static MX_Xd_dynamic Zero(unsigned int nrows, unsigned int ncols=1)
 
MX_Xd_SubMatrix block(unsigned int row_start, unsigned int col_start)
 
std::map< unsigned int, unsigned int > userDefinedIdGroupMap
 
RBDL_DLLAPI void ComputeConstraintImpulsesNullSpace(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDotMinus, ConstraintSet &CS, Math::VectorNd &QDotPlusOutput)
Resolves contact gain using SolveContactSystemNullSpace()
 
void calcVelocityError(unsigned int groupIndex, Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, Math::VectorNd &velocityErrorOutput, bool updateKinematics=false)
calcVelocityError calculates the vector of position errors associated with this constraint....
 
void calcPositionError(unsigned int groupIndex, Model &model, const Math::VectorNd &Q, Math::VectorNd &positionErrorOutput, bool updateKinematics=false)
calcPositionError calculates the vector of position errors associated with this constraint....
 
Math::VectorNd b
Workspace for the Lagrangian right-hand-side.
 
Math::VectorNd QDDot_t
Workspace for the test accelerations.
 
std::vector< Math::SpatialVector > f_ext_constraints
Workspace for the actual spatial forces.
 
std::vector< Math::Vector3d > d_multdof3_u
 
std::vector< std::shared_ptr< LoopConstraint > > loopConstraints
 
Math::VectorNd impulse
Constraint impulses along the constraint directions.
 
size_t size() const
Returns the number of constraints.
 
void calcBaumgarteStabilizationForces(unsigned int groupIndex, Model &model, const Math::VectorNd &positionError, const Math::VectorNd &velocityError, Math::VectorNd &baumgarteForcesOutput)
 
std::vector< std::shared_ptr< ContactConstraint > > contactConstraints
 
Math::VectorNd QDDot_0
Workspace for the default accelerations.
 
RBDL_DLLAPI void CalcConstraintsPositionError(Model &model, const Math::VectorNd &Q, ConstraintSet &CS, Math::VectorNd &errOutput, bool update_kinematics=true)
Computes the position errors for the given ConstraintSet.
 
RBDL_DLLAPI void ForwardDynamicsConstraintsNullSpace(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, ConstraintSet &CS, Math::VectorNd &QDDotOutput, bool update_kinematics=true, std::vector< Math::SpatialVector > *f_ext=NULL)
 
RBDL_DLLAPI void CalcConstraintsVelocityError(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, ConstraintSet &CS, Math::VectorNd &errOutput, bool update_kinematics=true)
Computes the velocity errors for the given ConstraintSet.
 
Math::VectorNd a
Workspace for the accelerations of due to the test forces.
 
RBDL_DLLAPI void InverseDynamicsConstraintsRelaxed(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &QDDotControls, ConstraintSet &CS, Math::VectorNd &QDDotOutput, Math::VectorNd &TauOutput, bool update_kinematics=true, std::vector< Math::SpatialVector > *f_ext=NULL)
A relaxed inverse-dynamics operator that can be applied to under-actuated or fully-actuated constrain...
 
Math::VectorNd x
Workspace for the Lagrangian solution.
 
RBDL_DLLAPI void ForwardDynamicsConstraintsDirect(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, ConstraintSet &CS, Math::VectorNd &QDDotOutput, bool update_kinematics=true, std::vector< Math::SpatialVector > *f_ext=NULL)
Computes forward dynamics with contact by constructing and solving the full lagrangian equation.
 
Math::VectorNd d_d
Workspace when applying constraint forces.
 
std::vector< Math::SpatialVector > d_pA
Workspace for the bias force due to the test force.
 
Math::MatrixNd G
Workspace for the constraint Jacobian.
 
void SetActuationMap(const Model &model, const std::vector< bool > &actuatedDof)
Initializes and allocates memory needed for InverseDynamicsConstraints and InverseDynamicsConstraints...
 
RBDL_DLLAPI void SolveConstrainedSystemDirect(Math::MatrixNd &H, const Math::MatrixNd &G, const Math::VectorNd &c, const Math::VectorNd &gamma, Math::VectorNd &lambda, Math::MatrixNd &A, Math::VectorNd &b, Math::VectorNd &x, Math::LinearSolver &linear_solver)
Solves the full contact system directly, i.e. simultaneously for contact forces and joint acceleratio...
 
std::vector< std::shared_ptr< Constraint > > constraints
 
RBDL_DLLAPI void CalcConstrainedSystemVariables(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, ConstraintSet &CSOutput, bool update_kinematics=true, std::vector< Math::SpatialVector > *f_ext=NULL)
Computes the terms , , and  of the constrained dynamic problem and stores them in the ConstraintSet.
 
RBDL_DLLAPI void InverseDynamicsConstraints(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &QDDotDesired, ConstraintSet &CS, Math::VectorNd &QDDotOutput, Math::VectorNd &TauOutput, bool update_kinematics=true, std::vector< Math::SpatialVector > *f_ext=NULL)
An inverse-dynamics operator that can be applied to fully-actuated constrained systems.
 
RBDL_DLLAPI bool CalcAssemblyQ(Model &model, Math::VectorNd QInit, ConstraintSet &CS, Math::VectorNd &QOutput, const Math::VectorNd &weights, double tolerance=1e-12, unsigned int max_iter=100)
Computes a feasible initial value of the generalized joint positions.
 
unsigned int AddLoopConstraint(unsigned int bodyIdPredecessor, unsigned int bodyIdSuccessor, const Math::SpatialTransform &XPredecessor, const Math::SpatialTransform &XSuccessor, const Math::SpatialVector &constraintAxisInPredecessor, bool enableBaumgarteStabilization=false, double stabilizationTimeConstant=0.1, const char *constraintName=NULL, unsigned int userDefinedId=std::numeric_limits< unsigned int >::max())
Adds a loop constraint to the constraint set.
 
std::vector< ConstraintType > constraintType
 
RBDL_DLLAPI void ComputeConstraintImpulsesDirect(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDotMinus, ConstraintSet &CS, Math::VectorNd &QDotPlusOutput)
Computes contact gain by constructing and solving the full lagrangian equation.
 
std::vector< Math::SpatialMatrix > d_IA
Workspace for the inertia when applying constraint forces.
 
std::vector< std::string > name
 
RBDL_DLLAPI void CalcAssemblyQDot(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDotInit, ConstraintSet &CS, Math::VectorNd &QDotOutput, const Math::VectorNd &weights)
Computes a feasible initial value of the generalized joint velocities.
 
unsigned int AddCustomConstraint(std::shared_ptr< Constraint > customConstraint)
Adds a custom constraint to the constraint set.
 
Math::MatrixNd H
Workspace for the joint space inertia matrix.
 
Math::VectorNd gamma
Workspace of the right hand side of the acceleration equation.
 
Math::MatrixNd P
Selection matrix for the non-actuated parts of the model.
 
std::vector< Math::SpatialVector > d_U
Workspace when applying constraint forces.
 
Math::VectorNd v_plus
The velocities we want to have along the constraint directions.
 
bool bound
Whether the constraint set was bound to a model (mandatory!).
 
Math::LinearSolver linear_solver
Method that should be used to solve internal linear systems.
 
std::vector< Math::SpatialVector > d_a
Workspace for the acceleration due to the test force.
 
RBDL_DLLAPI void SolveConstrainedSystemNullSpace(Math::MatrixNd &H, const Math::MatrixNd &G, const Math::VectorNd &c, const Math::VectorNd &gamma, Math::VectorNd &qddot, Math::VectorNd &lambda, Math::MatrixNd &Y, Math::MatrixNd &Z, Math::VectorNd &qddot_y, Math::VectorNd &qddot_z, Math::LinearSolver &linear_solver)
Solves the contact system by first solving for the joint accelerations and then for the constraint fo...
 
void calcImpulses(unsigned int groupIndex, Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, std::vector< unsigned int > &constraintBodyIdsOutput, std::vector< Math::SpatialTransform > &constraintBodyFramesOutput, std::vector< Math::SpatialVector > &constraintImpulsesOutput, bool resolveAllInRootFrame=false, bool updateKinematics=false)
calcImpulses resolves the generalized impluses generated by this constraint into equivalent spatial i...
 
std::map< unsigned int, unsigned int > idGroupMap
 
unsigned int AddContactConstraint(unsigned int bodyId, const Math::Vector3d &bodyPoint, const Math::Vector3d &worldNormal, const char *constraintName=NULL, unsigned int userDefinedId=std::numeric_limits< unsigned int >::max())
Adds a single contact constraint (point-ground) to the constraint set.
 
Math::VectorNd C
Workspace for the coriolis forces.
 
RBDL_DLLAPI bool isConstrainedSystemFullyActuated(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, ConstraintSet &CS, bool update_kinematics=true, std::vector< Math::SpatialVector > *f_ext=NULL)
A method to evaluate if the constrained system is fully actuated.
 
RBDL_DLLAPI void CalcConstraintsJacobian(Model &model, const Math::VectorNd &Q, ConstraintSet &CS, Math::MatrixNd &GOutput, bool update_kinematics=true)
Computes the Jacobian for the given ConstraintSet.
 
void enableBaumgarteStabilization(unsigned int groupIndex)
 
RBDL_DLLAPI void SolveConstrainedSystemRangeSpaceSparse(Model &model, Math::MatrixNd &H, const Math::MatrixNd &G, const Math::VectorNd &c, const Math::VectorNd &gamma, Math::VectorNd &qddot, Math::VectorNd &lambda, Math::MatrixNd &K, Math::VectorNd &a, Math::LinearSolver linear_solver)
Solves the contact system by first solving for the the joint accelerations and then the contact force...
 
void clear()
Clears all variables in the constraint set.
 
std::vector< Math::SpatialVector > f_t
Workspace for the test forces.
 
RBDL_DLLAPI void ComputeConstraintImpulsesRangeSpaceSparse(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDotMinus, ConstraintSet &CS, Math::VectorNd &QDotPlusOutput)
Resolves contact gain using SolveContactSystemRangeSpaceSparse()
 
RBDL_DLLAPI void ForwardDynamicsConstraintsRangeSpaceSparse(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, ConstraintSet &CS, Math::VectorNd &QDDotOutput, bool update_kinematics=true, std::vector< Math::SpatialVector > *f_ext=NULL)
 
RBDL_DLLAPI void ForwardDynamicsContactsKokkevis(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, ConstraintSet &CS, Math::VectorNd &QDDotOutput)
Computes forward dynamics that accounts for active contacts in ConstraintSet.
 
Eigen::HouseholderQR< Math::MatrixNd > GT_qr
Workspace for the QR decomposition of the null-space method.
 
void calcForces(unsigned int groupIndex, Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, std::vector< unsigned int > &updConstraintBodyIdsOutput, std::vector< Math::SpatialTransform > &updConstraintBodyFramesOutput, std::vector< Math::SpatialVector > &updConstraintForcesOutput, bool resolveAllInRootFrame=false, bool updateKinematics=false)
calcForces resolves the generalized forces generated by this constraint into equivalent spatial force...
 
bool Bind(const Model &model)
Initializes and allocates memory for the constraint set.
 
std::vector< Math::Vector3d > point_accel_0
Workspace for the default point accelerations.
 
Math::MatrixNd K
Workspace for the Inverse Articulated-Body Inertia.
 
std::map< std::string, unsigned int > nameGroupMap
 
Math::MatrixNd A
Workspace for the Lagrangian left-hand-side matrix.
 
RBDL_DLLAPI void NonlinearEffects(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, Math::VectorNd &Tau, std::vector< Math::SpatialVector > *f_ext=NULL)
Computes the coriolis forces.
 
RBDL_DLLAPI void ForwardDynamics(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, Math::VectorNd &QDDot, std::vector< Math::SpatialVector > *f_ext=NULL)
Computes forward dynamics with the Articulated Body Algorithm.
 
RBDL_DLLAPI void CompositeRigidBodyAlgorithm(Model &model, const Math::VectorNd &Q, Math::MatrixNd &H, bool update_kinematics=true)
Computes the joint space inertia matrix by using the Composite Rigid Body Algorithm.
 
RBDL_DLLAPI void UpdateKinematicsCustom(Model &model, const VectorNd *Q, const VectorNd *QDot, const VectorNd *QDDot)
Selectively updates model internal states of body positions, velocities and/or accelerations.
 
SpatialMatrix_t SpatialMatrix
 
SpatialMatrix crossf(const SpatialVector &v)
 
SpatialVector_t SpatialVector
 
RBDL_DLLAPI void SparseFactorizeLTL(Model &model, Math::MatrixNd &H)
 
RBDL_DLLAPI void SparseSolveLx(Model &model, Math::MatrixNd &L, Math::VectorNd &x)
 
RBDL_DLLAPI void SparseSolveLTx(Model &model, Math::MatrixNd &L, Math::VectorNd &x)
 
MX_Xd_dynamic fabs(const MX_Xd_dynamic &m)
 
LinearSolverColPivHouseholderQR
 
LinearSolverHouseholderQR
 
Math::SpatialVector svecB
 
Math::SpatialVector svecA
Working SpatialVectors.
 
Math::SpatialTransform stB
 
Math::SpatialTransform stA
Working SpatialTransforms.
 
Math::VectorNd vecNA
Working vectors that are sized to match the length of qdot.
 
Math::SpatialVector svecD
 
Math::SpatialVector svecE
 
Math::SpatialVector svecF
 
Math::SpatialTransform stD
 
Math::VectorNd vecNZeros
Here N is taken to mean the number of elements in QDot.
 
Math::Vector3d vec3A
Working Vector3d entries.
 
Math::Matrix3d mat3A
Working Matrix3d entries.
 
Math::SpatialVector svecC
 
Math::SpatialTransform stC