void IDIM::computeY(const MultiBody& mb, const MultiBodyConfig& mbc) { const std::vector<Body>& bodies = mb.bodies(); const std::vector<Joint>& joints = mb.joints(); const std::vector<int>& pred = mb.predecessors(); Eigen::Matrix<double, 6, 10> bodyFPhi; for(int i = static_cast<int>(bodies.size()) - 1; i >= 0; --i) { const sva::MotionVecd& vb_i = mbc.bodyVelB[i]; Eigen::Matrix<double, 6, 10> vb_i_Phi(IMPhi(vb_i)); bodyFPhi.noalias() = IMPhi(mbc.bodyAccB[i]); // bodyFPhi += vb_i x* IMPhi(vb_i) // is faster to convert each col in a ForceVecd // than using sva::vector6ToCrossDualMatrix for(int c = 0; c < 10; ++c) { bodyFPhi.col(c).noalias() += (vb_i.crossDual(sva::ForceVecd(vb_i_Phi.col(c)))).vector(); } int iDofPos = mb.jointPosInDof(i); Y_.block(iDofPos, i*10, joints[i].dof(), 10).noalias() = mbc.motionSubspace[i].transpose()*bodyFPhi; int j = i; while(pred[j] != -1) { const sva::PTransformd& X_p_j = mbc.parentToSon[j]; // bodyFPhi = X_p_j^T bodyFPhi // is faster to convert each col in a ForceVecd // than using X_p_j.inv().dualMatrix() for(int c = 0; c < 10; ++c) { bodyFPhi.col(c) = X_p_j.transMul(sva::ForceVecd(bodyFPhi.col(c))).vector(); } j = pred[j]; int jDofPos = mb.jointPosInDof(j); if(joints[j].dof() != 0) { Y_.block(jDofPos, i*10, joints[j].dof(), 10).noalias() = mbc.motionSubspace[j].transpose()*bodyFPhi; } } } }
void forwardKinematics(const MultiBody& mb, MultiBodyConfig& mbc) { const std::vector<Joint>& joints = mb.joints(); const std::vector<int>& pred = mb.predecessors(); const std::vector<int>& succ = mb.successors(); const std::vector<sva::PTransformd>& Xt = mb.transforms(); for(std::size_t i = 0; i < joints.size(); ++i) { mbc.jointConfig[i] = joints[i].pose(mbc.q[i]); mbc.parentToSon[i] = mbc.jointConfig[i]*Xt[i]; if(pred[i] != -1) mbc.bodyPosW[succ[i]] = mbc.parentToSon[i]*mbc.bodyPosW[pred[i]]; else mbc.bodyPosW[succ[i]] = mbc.parentToSon[i]; } }
void forwardAcceleration(const MultiBody& mb, MultiBodyConfig& mbc, const sva::MotionVecd& A_0) { const std::vector<Joint>& joints = mb.joints(); const std::vector<int>& pred = mb.predecessors(); const std::vector<int>& succ = mb.successors(); for(std::size_t i = 0; i < joints.size(); ++i) { const sva::PTransformd& X_p_i = mbc.parentToSon[i]; const sva::MotionVecd& vj_i = mbc.jointVelocity[i]; sva::MotionVecd ai_tan = joints[i].tanAccel(mbc.alphaD[i]); const sva::MotionVecd& vb_i = mbc.bodyVelB[i]; if(pred[i] != -1) mbc.bodyAccB[succ[i]] = X_p_i*mbc.bodyAccB[pred[i]] + ai_tan + vb_i.cross(vj_i); else mbc.bodyAccB[succ[i]] = X_p_i*A_0 + ai_tan + vb_i.cross(vj_i); } }
void forwardVelocity(const MultiBody& mb, MultiBodyConfig& mbc) { const std::vector<Joint>& joints = mb.joints(); const std::vector<int>& pred = mb.predecessors(); const std::vector<int>& succ = mb.successors(); for(std::size_t i = 0; i < joints.size(); ++i) { const sva::PTransformd& X_p_i = mbc.parentToSon[i]; mbc.jointVelocity[i] = joints[i].motion(mbc.alpha[i]); mbc.motionSubspace[i] = joints[i].motionSubspace(); if(pred[i] != -1) mbc.bodyVelB[succ[i]] = X_p_i*mbc.bodyVelB[pred[i]] + mbc.jointVelocity[i]; else mbc.bodyVelB[succ[i]] = mbc.jointVelocity[i]; sva::PTransformd E_0_i(mbc.bodyPosW[succ[i]].rotation()); mbc.bodyVelW[succ[i]] = E_0_i.invMul(mbc.bodyVelB[succ[i]]); } }