29 for (
unsigned int i = 1; i < model.
mBodies.size(); i++)
31 unsigned int q_index = model.
mJoints[i].q_index;
32 unsigned int lambda = model.
lambda[i];
35 if (update_kinematics)
37 jcalc(model, i, Q, QDot);
39 model.
v[i].set(model.
v[lambda].transform_copy(bodyFrame->getTransformFromParent()) + model.
v_J[i]);
40 model.
c[i] = model.
c_J[i] + model.
v[i] % model.
v_J[i];
45 if (model.
mJoints[i].mDoFCount == 1)
47 model.
a[i].set(model.
a[lambda].transform_copy(bodyFrame->getTransformFromParent()) + model.
c[i] + model.
S[i] * QDDot[q_index]);
49 else if (model.
mJoints[i].mDoFCount == 3)
51 model.
a[i].set(bodyFrame->getTransformFromParent().apply(model.
a[lambda]) + model.
c[i] +
52 model.
multdof3_S[i] *
Vector3d(QDDot[q_index], QDDot[q_index + 1], QDDot[q_index + 2]));
57 unsigned int k = model.
mJoints[i].custom_joint_index;
58 model.
a[i].set(bodyFrame->getTransformFromParent().apply(model.
a[lambda]) + model.
c[i] +
62 if (!model.
mBodies[i].mIsVirtual)
66 (*f_ext)[i].changeFrameAndCopy(bodyFrame));
70 model.
f_b[i].setIncludingFrame(bodyFrame, 0., 0., 0., 0., 0., 0.);
74 for (
unsigned int i = model.
mBodies.size() - 1; i > 0; i--)
78 if (model.
mJoints[i].mDoFCount == 1)
80 Tau[model.
mJoints[i].q_index] = model.
S[i].dot(model.
f_b[i]);
82 else if (model.
mJoints[i].mDoFCount == 3)
89 unsigned int k = model.
mJoints[i].custom_joint_index;
102 for (
unsigned int i = 1; i < model.
mBodies.size(); i++)
105 if (!model.
mBodies[i].mIsVirtual)
111 model.
f_b[i].setIncludingFrame(frame, 0., 0., 0., 0., 0., 0.);
115 for (
unsigned int i = model.
mBodies.size() - 1; i > 0; i--)
119 if (model.
mJoints[i].mDoFCount == 1)
121 Tau[model.
mJoints[i].q_index] = model.
S[i].dot(model.
f_b[i]);
123 else if (model.
mJoints[i].mDoFCount == 3)
130 unsigned int k = model.
mJoints[i].custom_joint_index;
143 model.
v[0].setZero();
144 model.
a[0].setZero();
146 for (
unsigned int i = 1; i < model.
mBodies.size(); i++)
151 if (update_kinematics)
153 jcalc(model, i, Q, QDot);
154 model.
v[i].set(model.
v_J[i]);
157 model.
a[i].setZero();
161 if (update_kinematics)
163 jcalc(model, i, Q, QDot);
164 model.
v[i].set(model.
v[model.
lambda[i]].transform_copy(model.
bodyFrames[i]->getTransformFromParent()) + model.
v_J[i]);
165 model.
c[i] = model.
c_J[i] + model.
v[i] % model.
v_J[i];
168 model.
a[i].set(model.
a[model.
lambda[i]].transform_copy(bodyFrame->getTransformFromParent()) + model.
c[i]);
171 if (!model.
mBodies[i].mIsVirtual)
173 model.
f_b[i].setIncludingFrame(bodyFrame, model.
I[i] * model.
a[i] + model.
v[i] % (
Math::Momentum(model.
I[i], model.
v[i])));
177 model.
f_b[i].setIncludingFrame(bodyFrame, 0., 0., 0., 0., 0., 0.);
181 for (
unsigned int i = model.
mBodies.size() - 1; i > 0; i--)
185 if (model.
mJoints[i].mDoFCount == 1)
187 Tau[model.
mJoints[i].q_index] = model.
S[i].dot(model.
f_b[i]);
189 else if (model.
mJoints[i].mDoFCount == 3)
196 unsigned int k = model.
mJoints[i].custom_joint_index;
212 for (
unsigned int i = 1; i < model.
mBodies.size(); i++)
215 if (!model.
mBodies[i].mIsVirtual)
221 model.
f_b[i].setIncludingFrame(frame, 0., 0., 0., 0., 0., 0.);
225 unsigned int i = model.
mBodies.size() - 1;
233 gravity_wrench = model.
f_b[body_id];
238 model.
v[0].setZero();
241 for (
unsigned int i = 1; i < model.
mBodies.size(); i++)
246 if (update_kinematics)
248 jcalc(model, i, Q, QDot);
249 model.
v[i].set(model.
v_J[i]);
256 if (update_kinematics)
258 jcalc(model, i, Q, QDot);
259 model.
v[i].set(model.
v[model.
lambda[i]].transform_copy(frame->getTransformFromParent()) + model.
v_J[i]);
260 model.
c[i] = model.
c_J[i] + model.
v[i] % model.
v_J[i];
263 model.
a[i].set(model.
a[model.
lambda[i]].transform_copy(frame->getTransformFromParent()) + model.
c[i]);
266 if (!model.
mBodies[i].mIsVirtual)
268 model.
f_b[i].setIncludingFrame(frame, model.
I[i] * model.
a[i] + model.
v[i] % (model.
I[i] * model.
v[i]));
272 model.
f_b[i].setIncludingFrame(frame, 0., 0., 0., 0., 0., 0.);
276 for (
unsigned int i = model.
mBodies.size() - 1; i > 0; i--)
280 if (model.
mJoints[i].mDoFCount == 1)
282 Tau[model.
mJoints[i].q_index] = model.
S[i].dot(model.
f_b[i]);
284 else if (model.
mJoints[i].mDoFCount == 3)
291 unsigned int k = model.
mJoints[i].custom_joint_index;
306 for (
unsigned int i = 1; i < model.
mBodies.size(); i++)
308 if (update_kinematics)
312 model.
Ic[i] = model.
I[i];
315 for (
unsigned int i = model.
mBodies.size() - 1; i > 0; i--)
322 unsigned int dof_index_i = model.
mJoints[i].q_index;
327 H(dof_index_i, dof_index_i) = model.
S[i].dot(F);
330 unsigned int dof_index_j = dof_index_i;
332 while (model.
lambda[j] != 0)
336 dof_index_j = model.
mJoints[j].q_index;
340 if (model.
mJoints[j].mDoFCount == 1)
342 H(dof_index_i, dof_index_j) = F.dot(model.
S[j]);
343 H(dof_index_j, dof_index_i) = H(dof_index_i, dof_index_j);
345 else if (model.
mJoints[j].mDoFCount == 3)
349 H.block<1, 3>(dof_index_i, dof_index_j) = H_temp2.transpose();
350 H.block<3, 1>(dof_index_j, dof_index_i) = H_temp2;
355 unsigned int k = model.
mJoints[j].custom_joint_index;
359 H.block(dof_index_i, dof_index_j, 1, dof) = H_temp2.transpose();
360 H.block(dof_index_j, dof_index_i, dof, 1) = H_temp2;
367 H.block<3, 3>(dof_index_i, dof_index_i) = model.
multdof3_S[i].transpose() * F_63;
370 unsigned int dof_index_j = dof_index_i;
372 while (model.
lambda[j] != 0)
374 F_63 = model.
bodyFrames[j]->getTransformFromParent().toMatrixTranspose() * (F_63);
376 dof_index_j = model.
mJoints[j].q_index;
380 if (model.
mJoints[j].mDoFCount == 1)
382 Vector3d H_temp2 = F_63.transpose() * (model.
S[j]);
384 H.block<3, 1>(dof_index_i, dof_index_j) = H_temp2;
385 H.block<1, 3>(dof_index_j, dof_index_i) = H_temp2.transpose();
387 else if (model.
mJoints[j].mDoFCount == 3)
391 H.block<3, 3>(dof_index_i, dof_index_j) = H_temp2;
392 H.block<3, 3>(dof_index_j, dof_index_i) = H_temp2.transpose();
397 unsigned int k = model.
mJoints[j].custom_joint_index;
402 H.block(dof_index_i, dof_index_j, 3, dof) = H_temp2;
403 H.block(dof_index_j, dof_index_i, dof, 3) = H_temp2.transpose();
409 unsigned int kI = model.
mJoints[i].custom_joint_index;
414 H.block(dof_index_i, dof_index_i, dofI, dofI) = model.
mCustomJoints[kI]->S.transpose() * F_Nd;
417 unsigned int dof_index_j = dof_index_i;
419 while (model.
lambda[j] != 0)
421 F_Nd = model.
bodyFrames[j]->getTransformFromParent().toMatrixTranspose() * (F_Nd);
423 dof_index_j = model.
mJoints[j].q_index;
427 if (model.
mJoints[j].mDoFCount == 1)
429 MatrixNd H_temp2 = F_Nd.transpose() * (model.
S[j]);
430 H.block(dof_index_i, dof_index_j, H_temp2.rows(), H_temp2.cols()) = H_temp2;
431 H.block(dof_index_j, dof_index_i, H_temp2.cols(), H_temp2.rows()) = H_temp2.transpose();
433 else if (model.
mJoints[j].mDoFCount == 3)
436 H.block(dof_index_i, dof_index_j, H_temp2.rows(), H_temp2.cols()) = H_temp2;
437 H.block(dof_index_j, dof_index_i, H_temp2.cols(), H_temp2.rows()) = H_temp2.transpose();
442 unsigned int k = model.
mJoints[j].custom_joint_index;
447 H.block(dof_index_i, dof_index_j, 3, dof) = H_temp2;
448 H.block(dof_index_j, dof_index_i, dof, 3) = H_temp2.transpose();
458 model.
v[0].setZero();
460 for (
unsigned int i = 1; i < model.
mBodies.size(); i++)
462 unsigned int lambda = model.
lambda[i];
465 if (update_kinematics)
467 jcalc(model, i, Q, QDot);
468 model.
v[i].set(model.
v[lambda].transform_copy(bodyFrame->getTransformFromParent()) + model.
v_J[i]);
472 model.
I[i].setSpatialMatrix(model.
IA[i]);
473 model.
pA[i].setIncludingFrame(bodyFrame, f_ext ==
nullptr ? model.
v[i].cross(model.
I[i] * model.
v[i]) :
474 model.
v[i].cross(model.
I[i] * model.
v[i]) - (*f_ext)[i].changeFrameAndCopy(bodyFrame));
477 for (
unsigned int i = model.
mBodies.size() - 1; i > 0; i--)
479 unsigned int q_index = model.
mJoints[i].q_index;
484 model.
U[i] = model.
IA[i] * model.
S[i];
485 model.
d[i] = model.
S[i].dot(model.
U[i]);
486 model.
u[i] = Tau[q_index] - model.
S[i].dot(model.
pA[i]);
488 unsigned int lambda = model.
lambda[i];
494 model.
IA[lambda].noalias() += bodyFrame->getTransformFromParent().toMatrixTranspose() * Ia * bodyFrame->getTransformFromParent().toMatrix();
504 Vector3d tau_temp(Tau[q_index], Tau[q_index + 1], Tau[q_index + 2]);
507 unsigned int lambda = model.
lambda[i];
514 model.
IA[lambda].noalias() += bodyFrame->getTransformFromParent().toMatrixTranspose() * Ia * bodyFrame->getTransformFromParent().toMatrix();
520 unsigned int kI = model.
mJoints[i].custom_joint_index;
527 unsigned int lambda = model.
lambda[i];
535 model.
IA[lambda].noalias() += bodyFrame->getTransformFromParent().toMatrixTranspose() * Ia * bodyFrame->getTransformFromParent().toMatrix();
541 model.
a[0].set(model.
gravity * -1.);
543 for (
unsigned int i = 1; i < model.
mBodies.size(); i++)
545 unsigned int q_index = model.
mJoints[i].q_index;
547 model.
a[i].set(model.
a[model.
lambda[i]].transform_copy(model.
bodyFrames[i]->getTransformFromParent()) + model.
c[i]);
551 QDDot[q_index] = (1. / model.
d[i]) * (model.
u[i] - model.
U[i].dot(model.
a[i]));
552 model.
a[i].set(model.
a[i] + model.
S[i] * QDDot[q_index]);
557 QDDot[q_index] = qdd_temp[0];
558 QDDot[q_index + 1] = qdd_temp[1];
559 QDDot[q_index + 2] = qdd_temp[2];
560 model.
a[i].set(model.
a[i] + model.
multdof3_S[i] * qdd_temp);
564 unsigned int kI = model.
mJoints[i].custom_joint_index;
569 for (
unsigned int z = 0; z < dofI; ++z)
571 QDDot[q_index + z] = qdd_temp[z];
593 assert(solve_successful);
598 model.
v[0].setZero();
599 model.
a[0].setZero();
601 for (
unsigned int i = 1; i < model.
mBodies.size(); i++)
603 if (update_kinematics)
608 model.
pA[i].setIncludingFrame(model.
bodyFrames[i], 0., 0., 0., 0., 0., 0.);
609 model.
I[i].setSpatialMatrix(model.
IA[i]);
613 for (
unsigned int i = model.
mBodies.size() - 1; i > 0; i--)
618 model.
U[i] = model.
IA[i] * model.
S[i];
619 model.
d[i] = model.
S[i].dot(model.
U[i]);
620 unsigned int lambda = model.
lambda[i];
625 model.
IA[lambda].noalias() += frame->getTransformFromParent().toMatrixTranspose() * Ia * frame->getTransformFromParent().toMatrix();
633 unsigned int lambda = model.
lambda[i];
638 model.
IA[lambda].noalias() += frame->getTransformFromParent().toMatrixTranspose() * Ia * frame->getTransformFromParent().toMatrix();
643 unsigned int kI = model.
mJoints[i].custom_joint_index;
647 unsigned int lambda = model.
lambda[i];
652 model.
IA[lambda].noalias() += frame->getTransformFromParent().toMatrixTranspose() * Ia * frame->getTransformFromParent().toMatrix();
658 for (
unsigned int i = model.
mBodies.size() - 1; i > 0; i--)
660 unsigned int q_index = model.
mJoints[i].q_index;
665 model.
u[i] = Tau[q_index] - model.
S[i].dot(model.
pA[i]);
666 unsigned int lambda = model.
lambda[i];
675 Vector3d tau_temp(Tau[q_index], Tau[q_index + 1], Tau[q_index + 2]);
677 unsigned int lambda = model.
lambda[i];
688 unsigned int kI = model.
mJoints[i].custom_joint_index;
692 for (
unsigned int z = 0; z < dofI; ++z)
694 tau_temp(z) = Tau[q_index + z];
698 unsigned int lambda = model.
lambda[i];
709 for (
unsigned int i = 1; i < model.
mBodies.size(); i++)
711 unsigned int q_index = model.
mJoints[i].q_index;
712 unsigned int lambda = model.
lambda[i];
714 model.
a[i].set(model.
bodyFrames[i]->getTransformFromParent().apply(model.
a[lambda]));
718 QDDot[q_index] = (1. / model.
d[i]) * (model.
u[i] - model.
U[i].dot(model.
a[i]));
719 model.
a[i].set(model.
a[i] + model.
S[i] * QDDot[q_index]);
725 QDDot[q_index] = qdd_temp[0];
726 QDDot[q_index + 1] = qdd_temp[1];
727 QDDot[q_index + 2] = qdd_temp[2];
728 model.
a[i].set(model.
a[i] + model.
multdof3_S[i] * qdd_temp);
732 unsigned int kI = model.
mJoints[i].custom_joint_index;
737 for (
unsigned int z = 0; z < dofI; ++z)
739 QDDot[q_index + z] = qdd_temp[z];
std::vector< Math::SpatialMatrix > IA
The spatial inertia of the bodies.
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.
std::vector< SpatialForce, Eigen::aligned_allocator< SpatialForce > > SpatialForceV
std::vector< Joint > mJoints
All joints.
Math::VectorNd u
Temporary variable u (RBDA p. 130)
std::vector< Math::SpatialVector > c_J
User defined joints of varying size.
std::vector< Math::Matrix63 > multdof3_U
std::vector< unsigned int > lambda
bool linSolveGaussElimPivot(MatrixNd A, VectorNd b, VectorNd &x)
Solves a linear system using gaussian elimination with pivoting.
void coriolisEffects(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, Math::VectorNd &Tau, bool update_kinematics=true)
Computes the coriolis forces.
void jcalc(Model &model, unsigned int joint_id, const Math::VectorNd &q, const Math::VectorNd &qdot)
Computes all variables for a joint model and updates the body frame as well as the body's center of m...
Math::MotionVector gravity
the cartesian vector of the gravity
void transform(const SpatialTransform &X)
Performs the following in place transform .
std::vector< ReferenceFramePtr > bodyFrames
ReferenceFramePtr worldFrame
LinearSolver
Available solver methods for the linear systems.
std::shared_ptr< ReferenceFrame > ReferenceFramePtr
bool IsBodyId(unsigned int id) const
Momentum is mass/inertia multiplied by velocity.
Math::SpatialForceV pA
The spatial bias force.
std::vector< Body > mBodies
All bodies 0 ... N_B, including the base.
void calcBodyGravityWrench(Model &model, unsigned int body_id, RobotDynamics::Math::SpatialForce &gravity_wrench)
Calculate the wrench due to gravity on a body.
Math::VectorNd d
Temporary variable D_i (RBDA p. 130)
Math::SpatialAccelerationV a
The spatial velocity of the bodies.
std::vector< CustomJoint * > mCustomJoints
std::vector< Math::Matrix3d > multdof3_Dinv
void calcMInvTimesTau(Model &model, const Math::VectorNd &Q, const Math::VectorNd &Tau, Math::VectorNd &QDDot, bool update_kinematics=true)
Computes the effect of multiplying the inverse of the joint space inertia matrix with a vector in lin...
Contains all information about the rigid body model.
std::vector< Math::SpatialVector > U
Temporary variable U_i (RBDA p. 130)
void jcalc_X_lambda_S(Model &model, unsigned int joint_id, const Math::VectorNd &q)
std::vector< Math::SpatialVector > c
The velocity dependent spatial acceleration.
Eigen::Matrix< double, 6, 3 > Matrix63
Math::RigidBodyInertiaV Ic
A SpatialForce is a spatial vector with the angular part being three moments and the linear part bein...
void gravityEffects(Model &model, Math::VectorNd &Tau)
Computes the gravity vector.
std::vector< Math::Matrix63 > multdof3_S
Motion subspace for joints with 3 degrees of freedom.
void inverseDynamics(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &QDDot, Math::VectorNd &Tau, Math::SpatialForceV *f_ext=nullptr, bool update_kinematics=true)
void forwardDynamics(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, Math::VectorNd &QDDot, Math::SpatialForceV *f_ext=nullptr, bool update_kinematics=true)
Computes forward dynamics with the Articulated Body Algorithm.
MotionVector transform_copy(const SpatialTransform &X) const
Copies, transforms, and returns a MotionVector. Performs .
std::vector< Math::Vector3d > multdof3_u
void forwardDynamicsLagrangian(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, Math::VectorNd &QDDot, Math::MatrixNd &H, Math::VectorNd &C, Math::LinearSolver linear_solver=Math::LinearSolverColPivHouseholderQR, Math::SpatialForceV *f_ext=nullptr, bool update_kinematics=true)
Computes forward dynamics by building and solving the full Lagrangian equation.
SpatialForce changeFrameAndCopy(ReferenceFramePtr referenceFrame) const
Copy and change frame.
void nonlinearEffects(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, Math::VectorNd &Tau, bool update_kinematics=true)
Computes the coriolis forces.
unsigned int dof_count
number of degrees of freedoms of the model
Namespace for all structures of the RobotDynamics library.