28 double normal_acceleration)
30 assert(bound ==
false);
33 if (constraint_name != NULL)
35 name_str = constraint_name;
38 name.push_back(name_str);
39 body.push_back(body_id);
40 point.push_back(body_point);
41 normal.push_back(world_normal);
43 unsigned int n_constr = acceleration.size() + 1;
45 acceleration.conservativeResize(n_constr);
46 acceleration[n_constr - 1] = normal_acceleration;
48 force.conservativeResize(n_constr);
49 force[n_constr - 1] = 0.;
51 impulse.conservativeResize(n_constr);
52 impulse[n_constr - 1] = 0.;
54 v_plus.conservativeResize(n_constr);
55 v_plus[n_constr - 1] = 0.;
57 d_multdof3_u = std::vector<Math::Vector3d>(n_constr, Math::Vector3d::Zero());
64 assert(bound ==
false);
68 std::cerr <<
"Error: binding an already bound constraint set!" << std::endl;
71 unsigned int n_constr = size();
77 gamma.conservativeResize(n_constr);
79 G.conservativeResize(n_constr, model.
dof_count);
83 b.conservativeResize(model.
dof_count + n_constr);
85 x.conservativeResize(model.
dof_count + n_constr);
88 GT_qr = Eigen::HouseholderQR<Math::MatrixNd>(G.transpose());
90 Y = MatrixNd::Zero(model.
dof_count, G.rows());
95 K.conservativeResize(n_constr, n_constr);
97 a.conservativeResize(n_constr);
102 f_t.resize(n_constr);
103 f_ext_constraints.resize(model.
mBodies.size());
105 for(
unsigned int i = 0; i < model.
mBodies.size(); i++)
107 f_ext_constraints[i].setIncludingFrame(model.
bodyFrames[i], 0., 0., 0., 0., 0., 0.);
110 point_accel_0.resize(n_constr, Vector3d::Zero());
112 d_pA.resize(model.
mBodies.size());
120 d_multdof3_u = std::vector<Math::Vector3d>(model.
mBodies.size(), Math::Vector3d::Zero());
129 acceleration.setZero();
147 for (i = 0; i < f_t.size(); i++)
152 for (i = 0; i < f_ext_constraints.size(); i++)
154 f_ext_constraints[i].setZero();
157 for (i = 0; i < point_accel_0.size(); i++)
159 point_accel_0[i].setZero();
162 for (i = 0; i < d_pA.size(); i++)
167 for (i = 0; i < d_a.size(); i++)
179 A.block(0, 0, c.rows(), c.rows()) = H;
182 A.block(0, c.rows(), c.rows(), gamma.rows()) = G.transpose();
183 A.block(c.rows(), 0, gamma.rows(), c.rows()) = G;
186 b.block(0, 0, c.rows(), 1) = c;
187 b.block(c.rows(), 0, gamma.rows(), 1) = gamma;
189 switch (linear_solver)
192 x = A.partialPivLu().solve(b);
195 x = A.colPivHouseholderQr().solve(b);
198 x = A.householderQr().solve(b);
213 for (
unsigned int i = 0; i < Y.cols(); i++)
215 VectorNd Y_col = Y.block(0, i, Y.rows(), 1);
217 Y.block(0, i, Y.rows(), 1) = Y_col;
223 K = Y.transpose() * Y;
225 a = gamma - Y.transpose() * z;
227 lambda = K.llt().solve(a);
229 qddot = c + G.transpose() * lambda;
238 switch (linear_solver)
241 qddot_y = (G * Y).partialPivLu().solve(gamma);
244 qddot_y = (G * Y).colPivHouseholderQr().solve(gamma);
247 qddot_y = (G * Y).householderQr().solve(gamma);
254 qddot_z = (Z.transpose() * H * Z).llt().solve(Z.transpose() * (c - H * Y * qddot_y));
256 qddot = Y * qddot_y + Z * qddot_z;
258 switch (linear_solver)
261 lambda = (G * Y).partialPivLu().solve(Y.transpose() * (H * qddot - c));
264 lambda = (G * Y).colPivHouseholderQr().solve(Y.transpose() * (H * qddot - c));
267 lambda = (G * Y).householderQr().solve(Y.transpose() * (H * qddot - c));
277 if (update_kinematics)
285 unsigned int prev_body_id = 0;
286 Vector3d prev_body_point = Vector3d::Zero();
289 for (i = 0; i < CS.
size(); i++)
292 if (prev_body_id != CS.
body[i] || prev_body_point != CS.
point[i])
296 prev_body_id = CS.
body[i];
297 prev_body_point = CS.
point[i];
302 Vector3d gaxis(Gi(0, j), Gi(1, j), Gi(2, j));
303 G(i, j) = gaxis.transpose() * CS.
normal[i];
320 unsigned int prev_body_id = 0;
321 Vector3d prev_body_point = Vector3d::Zero();
322 Vector3d gamma_i = Vector3d::Zero();
327 for (
unsigned int i = 0; i < CS.
size(); i++)
330 if (prev_body_id != CS.
body[i] || prev_body_point != CS.
point[i])
333 prev_body_id = CS.
body[i];
334 prev_body_point = CS.
point[i];
350 for (
unsigned int i = 0; i < model.
dof_count; i++)
356 for (
unsigned int i = 0; i < CS.
size(); i++)
374 CS.
GT_qr.compute(CS.
G.transpose());
377 CS.
Y = CS.
GT_qr_Q.block(0, 0, QDot.rows(), CS.
G.rows());
378 CS.
Z = CS.
GT_qr_Q.block(0, CS.
G.rows(), QDot.rows(), QDot.rows() - CS.
G.rows());
380 solveContactSystemNullSpace(CS.
H, CS.
G, Tau - CS.
C, CS.
gamma, QDDot, CS.
force, CS.
Y, CS.
Z, CS.
qddot_y, CS.
qddot_z, CS.
linear_solver);
395 for (
unsigned int i = 0; i < model.
dof_count; i++)
397 QDotPlus[i] = CS.
x[i];
401 for (
unsigned int i = 0; i < CS.
size(); i++)
428 CS.
GT_qr.compute(CS.
G.transpose());
431 CS.
Y = CS.
GT_qr_Q.block(0, 0, QDotMinus.rows(), CS.
G.rows());
432 CS.
Z = CS.
GT_qr_Q.block(0, CS.
G.rows(), QDotMinus.rows(), QDotMinus.rows() - CS.
G.rows());
434 solveContactSystemNullSpace(CS.
H, CS.
G, CS.
H * QDotMinus, CS.
v_plus, QDotPlus, CS.
impulse, CS.
Y, CS.
Z, CS.
qddot_y, CS.
qddot_z, CS.
linear_solver);
451 for (i = 1; i < model.
mBodies.size(); i++)
453 model.
I[i].setSpatialMatrix(model.
IA[i]);
457 for (i = model.
mBodies.size() - 1; i > 0; i--)
459 unsigned int q_index = model.
mJoints[i].q_index;
464 unsigned int lambda = model.
lambda[i];
475 model.
IA[lambda].noalias() += (bodyFrame->getTransformFromParent().toMatrixTranspose() * Ia * bodyFrame->getTransformFromParent().toMatrix());
481 model.
u[i] = Tau[q_index] - model.
S[i].dot(model.
pA[i]);
483 unsigned int lambda = model.
lambda[i];
490 model.
IA[lambda].noalias() += (bodyFrame->getTransformFromParent().toMatrixTranspose() * Ia * bodyFrame->getTransformFromParent().toMatrix());
496 unsigned int kI = model.
mJoints[i].custom_joint_index;
498 unsigned int lambda = model.
lambda[i];
499 VectorNd tau_temp = VectorNd::Zero(dofI);
501 for (
unsigned int z = 0; z < dofI; ++z)
503 tau_temp[z] = Tau[q_index + z];
515 model.
IA[lambda].noalias() += bodyFrame->getTransformFromParent().toMatrixTranspose() * Ia * bodyFrame->getTransformFromParent().toMatrix();
523 for (i = 1; i < model.
mBodies.size(); i++)
525 unsigned int q_index = model.
mJoints[i].q_index;
526 unsigned int lambda = model.
lambda[i];
528 model.
a[i].set(model.
a[lambda].transform_copy(model.
bodyFrames[i]->getTransformFromParent()) + model.
c[i]);
534 QDDot[q_index] = qdd_temp[0];
535 QDDot[q_index + 1] = qdd_temp[1];
536 QDDot[q_index + 2] = qdd_temp[2];
537 model.
a[i].set(model.
a[i] + model.
multdof3_S[i] * qdd_temp);
541 QDDot[q_index] = (1. / model.
d[i]) * (model.
u[i] - model.
U[i].dot(model.
a[i]));
542 model.
a[i].set(model.
a[i] + model.
S[i] * QDDot[q_index]);
546 unsigned int kI = model.
mJoints[i].custom_joint_index;
551 for (
unsigned int z = 0; z < dofI; ++z)
553 QDDot[q_index + z] = qdd_temp[z];
571 assert(CS.
d_a.size() == model.
mBodies.size());
572 assert(CS.
d_u.size() == model.
mBodies.size());
575 for (
unsigned int i = 0; i < model.
mBodies.size(); i++)
577 CS.
d_pA[i].setIncludingFrame(model.
bodyFrames[i], 0., 0., 0., 0., 0., 0.);
582 for (
unsigned int i = 0; i < model.
mCustomJoints.size(); i++)
587 for (
unsigned int i = body_id; i > 0; i--)
598 unsigned int lambda = model.
lambda[i];
607 CS.
d_u[i] = -model.
S[i].dot(CS.
d_pA[i]);
608 unsigned int lambda = model.
lambda[i];
618 unsigned int kI = model.
mJoints[i].custom_joint_index;
621 unsigned int lambda = model.
lambda[i];
632 CS.
d_a[0] = model.
a[0];
634 for (
unsigned int i = 1; i < model.
mBodies.size(); i++)
636 unsigned int q_index = model.
mJoints[i].q_index;
637 unsigned int lambda = model.
lambda[i];
645 QDDot_t[q_index] = qdd_temp[0];
646 QDDot_t[q_index + 1] = qdd_temp[1];
647 QDDot_t[q_index + 2] = qdd_temp[2];
648 model.
a[i].set(model.
a[i] + model.
multdof3_S[i] * qdd_temp);
653 QDDot_t[q_index] = (CS.
d_u[i] - model.
U[i].dot(Xa)) / model.
d[i];
654 CS.
d_a[i] = Xa + model.
S[i] * QDDot_t[q_index];
658 unsigned int kI = model.
mJoints[i].custom_joint_index;
663 for (
unsigned int z = 0; z < dofI; ++z)
665 QDDot_t[q_index + z] = qdd_temp[z];
674 inline void set_zero(std::vector<SpatialVector>& spatial_values)
676 for (
unsigned int i = 0; i < spatial_values.size(); i++)
678 spatial_values[i].setZero();
687 assert(CS.
f_t.size() == CS.
size());
689 assert(CS.
K.rows() == CS.
size());
690 assert(CS.
K.cols() == CS.
size());
692 assert(CS.
a.size() == CS.
size());
703 for (ci = 0; ci < CS.
size(); ci++)
705 unsigned int body_id = CS.
body[ci];
719 for (ci = 0; ci < CS.
size(); ci++)
721 unsigned int body_id = CS.
body[ci];
725 unsigned int movable_body_id = body_id;
729 movable_body_id = model.
mFixedBodies[fbody_id].mMovableParent;
740 CS.
f_t[ci].setIncludingFrame(model.
worldFrame, p.
vec().cross(-normal), -normal);
752 for (
unsigned int cj = 0; cj < CS.
size(); cj++)
761 assert(solve_successful);
762 for (ci = 0; ci < CS.
size(); ci++)
764 unsigned int body_id = CS.
body[ci];
765 unsigned int movable_body_id = body_id;
770 movable_body_id = model.
mFixedBodies[fbody_id].mMovableParent;
Math::VectorNd C
Workspace for the coriolis forces.
Math::SpatialForceV f_t
Workspace for the test forces.
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.
Math::SpatialForceV f_ext_constraints
Workspace for the actual spatial forces.
bool IsFixedBodyId(unsigned int body_id) const
Checks whether the body is rigidly attached to another body.
std::vector< SpatialForce, Eigen::aligned_allocator< SpatialForce > > SpatialForceV
File containing the FramePoint<T> object definition.
void calcPointJacobian(Model &model, const Math::VectorNd &Q, unsigned int body_id, const Math::Vector3d &point_position, Math::MatrixNd &G, bool update_kinematics=true)
Computes the 3D point jacobian for a point on a body.
Math::VectorNd b
Workspace for the Lagrangian right-hand-side.
std::vector< Joint > mJoints
All joints.
SpatialVector SpatialVectorZero
A FramePoint is a 3D point that is expressed in a ReferenceFrame. To change the ReferenceFrame a Fram...
Math::VectorNd u
Temporary variable u (RBDA p. 130)
User defined joints of varying size.
void clear()
Clears all variables in the constraint set.
Math::VectorNd a
Workspace for the accelerations of due to the test forces.
std::vector< Math::Matrix63 > multdof3_U
std::vector< FixedBody > mFixedBodies
All bodies that are attached to a body via a fixed joint.
std::vector< unsigned int > lambda
bool linSolveGaussElimPivot(MatrixNd A, VectorNd b, VectorNd &x)
Solves a linear system using gaussian elimination with pivoting.
void set_zero(std::vector< SpatialVector > &spatial_values)
Math::SpatialForceV d_pA
Workspace for the bias force due to the test force.
unsigned int addConstraint(unsigned int body_id, const Math::Vector3d &body_point, const Math::Vector3d &world_normal, const char *constraint_name=NULL, double normal_acceleration=0.)
Adds a constraint to the constraint set.
std::vector< Math::Vector3d > point
Math::MatrixNd A
Workspace for the Lagrangian left-hand-side matrix.
Math::FrameVector calcPointAcceleration(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &QDDot, unsigned int body_id, const Math::Vector3d &point_position, bool update_kinematics=true)
Computes the linear acceleration of a point on a body.
Math::MotionVector gravity
the cartesian vector of the gravity
Math::VectorNd acceleration
std::vector< ReferenceFramePtr > bodyFrames
Math::VectorNd nbodies0_vec
ReferenceFramePtr worldFrame
Math::VectorNd QDDot_t
Workspace for the test accelerations.
std::vector< Math::Vector3d > d_multdof3_u
EIGEN_STRONG_INLINE void setIncludingFrame(const Math::Vector3d &v, ReferenceFramePtr referenceFrame)
Set both the ReferenceFrame this object is expressed in as well as the (x,y,z) coordinates of the poi...
LinearSolver
Available solver methods for the linear systems.
EIGEN_STRONG_INLINE Math::Vector3d vec() const
std::shared_ptr< ReferenceFrame > ReferenceFramePtr
Structure that contains both constraint information and workspace memory.
virtual void changeFrame(ReferenceFramePtr desiredFrame)
Change the ReferenceFrame this FrameObject is expressed in.
Math::SpatialForceV pA
The spatial bias force.
std::vector< Body > mBodies
All bodies 0 ... N_B, including the base.
Math::VectorNd gamma
Workspace of the lower part of b.
std::vector< unsigned int > body
std::vector< Math::Vector3d > point_accel_0
Workspace for the default point accelerations.
Math::VectorNd d
Temporary variable D_i (RBDA p. 130)
Math::VectorNd QDDot_0
Workspace for the default accelerations.
Math::SpatialAccelerationV a
The spatial velocity of the bodies.
std::vector< CustomJoint * > mCustomJoints
std::vector< Math::Matrix3d > multdof3_Dinv
Contains all information about the rigid body model.
void updateKinematicsCustom(Model &model, const Math::VectorNd *Q, const Math::VectorNd *QDot=nullptr, const Math::VectorNd *QDDot=nullptr)
Selectively updates model internal states of body positions, velocities and/or accelerations.
bool bind(const Model &model)
Initializes and allocates memory for the constraint set.
std::vector< Math::SpatialVector > U
Temporary variable U_i (RBDA p. 130)
void SparseFactorizeLTL(Model &model, Math::MatrixNd &H)
std::vector< Math::SpatialVector > c
The velocity dependent spatial acceleration.
unsigned int fixed_body_discriminator
Value that is used to discriminate between fixed and movable bodies.
Eigen::HouseholderQR< Math::MatrixNd > GT_qr
Workspace for the QR decomposition of the null-space method.
SpatialMatrix SpatialMatrixIdentity
Math::MatrixNd K
Workspace for the Inverse Articulated-Body Inertia.
A SpatialForce is a spatial vector with the angular part being three moments and the linear part bein...
std::vector< Math::SpatialVector > d_a
Workspace for the acceleration due to the test force.
void SparseSolveLTx(Model &model, Math::MatrixNd &L, Math::VectorNd &x)
Math::LinearSolver linear_solver
Method that should be used to solve internal linear systems.
std::vector< Math::Matrix63 > multdof3_S
Motion subspace for joints with 3 degrees of freedom.
void updateAccelerations(Model &model, const Math::VectorNd &QDDot)
Computes only the accelerations of the bodies.
std::vector< ReferenceFramePtr > fixedBodyFrames
void SparseSolveLx(Model &model, Math::MatrixNd &L, Math::VectorNd &x)
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.
void forwardDynamicsAccelerationDeltas(Model &model, ConstraintSet &CS, VectorNd &QDDot_t, const unsigned int body_id, const SpatialForceV &f_t)
Computes the effect of external forces on the generalized accelerations.
std::vector< Math::Vector3d > multdof3_u
SpatialForce changeFrameAndCopy(ReferenceFramePtr referenceFrame) const
Copy and change frame.
void forwardDynamicsApplyConstraintForces(Model &model, const VectorNd &Tau, ConstraintSet &CS, VectorNd &QDDot)
Compute only the effects of external forces on the generalized accelerations.
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.
Math::VectorNd x
Workspace for the Lagrangian solution.
Math::MatrixNd H
Workspace for the joint space inertia matrix.
std::vector< Math::Vector3d > normal
size_t size() const
Returns the number of constraints.