/* * RBDL - Rigid Body Dynamics Library * Copyright (c) 2011-2018 Martin Felis * * Licensed under the zlib license. See LICENSE for more details. */ #include #include #include #include #include "rbdl/rbdl_mathutils.h" #include "rbdl/Logging.h" #include "rbdl/Model.h" #include "rbdl/Joint.h" #include "rbdl/Body.h" #include "rbdl/Dynamics.h" #include "rbdl/Kinematics.h" namespace RigidBodyDynamics { using namespace Math; RBDL_DLLAPI void InverseDynamics ( Model &model, const VectorNd &Q, const VectorNd &QDot, const VectorNd &QDDot, VectorNd &Tau, std::vector *f_ext) { LOG << "-------- " << __func__ << " --------" << std::endl; // Reset the velocity of the root body model.v[0].setZero(); model.a[0].set (0., 0., 0., -model.gravity[0], -model.gravity[1], -model.gravity[2]); for (unsigned int i = 1; i < model.mBodies.size(); i++) { unsigned int q_index = model.mJoints[i].q_index; unsigned int lambda = model.lambda[i]; jcalc (model, i, Q, QDot); model.v[i] = model.X_lambda[i].apply(model.v[lambda]) + model.v_J[i]; model.c[i] = model.c_J[i] + crossm(model.v[i],model.v_J[i]); if(model.mJoints[i].mJointType != JointTypeCustom){ if (model.mJoints[i].mDoFCount == 1) { model.a[i] = model.X_lambda[i].apply(model.a[lambda]) + model.c[i] + model.S[i] * QDDot[q_index]; } else if (model.mJoints[i].mDoFCount == 3) { model.a[i] = model.X_lambda[i].apply(model.a[lambda]) + model.c[i] + model.multdof3_S[i] * Vector3d (QDDot[q_index], QDDot[q_index + 1], QDDot[q_index + 2]); } }else if(model.mJoints[i].mJointType == JointTypeCustom){ unsigned int k = model.mJoints[i].custom_joint_index; VectorNd customJointQDDot(model.mCustomJoints[k]->mDoFCount); for(unsigned z = 0; z < model.mCustomJoints[k]->mDoFCount; ++z){ customJointQDDot[z] = QDDot[q_index+z]; } model.a[i] = model.X_lambda[i].apply(model.a[lambda]) + model.c[i] + model.mCustomJoints[k]->S * customJointQDDot; } if (!model.mBodies[i].mIsVirtual) { model.f[i] = model.I[i] * model.a[i] + crossf(model.v[i],model.I[i] * model.v[i]); } else { model.f[i].setZero(); } } if (f_ext != NULL) { for (unsigned int i = 1; i < model.mBodies.size(); i++) { unsigned int lambda = model.lambda[i]; model.X_base[i] = model.X_lambda[i] * model.X_base[lambda]; model.f[i] -= model.X_base[i].toMatrixAdjoint() * (*f_ext)[i]; } } for (unsigned int i = model.mBodies.size() - 1; i > 0; i--) { if(model.mJoints[i].mJointType != JointTypeCustom){ if (model.mJoints[i].mDoFCount == 1) { Tau[model.mJoints[i].q_index] = model.S[i].dot(model.f[i]); } else if (model.mJoints[i].mDoFCount == 3) { Tau.block<3,1>(model.mJoints[i].q_index, 0) = model.multdof3_S[i].transpose() * model.f[i]; } } else if (model.mJoints[i].mJointType == JointTypeCustom) { unsigned int k = model.mJoints[i].custom_joint_index; Tau.block(model.mJoints[i].q_index,0, model.mCustomJoints[k]->mDoFCount, 1) = model.mCustomJoints[k]->S.transpose() * model.f[i]; } if (model.lambda[i] != 0) { model.f[model.lambda[i]] = model.f[model.lambda[i]] + model.X_lambda[i].applyTranspose(model.f[i]); } } } RBDL_DLLAPI void NonlinearEffects ( Model &model, const VectorNd &Q, const VectorNd &QDot, VectorNd &Tau, std::vector *f_ext) { LOG << "-------- " << __func__ << " --------" << std::endl; SpatialVector spatial_gravity (0., 0., 0., -model.gravity[0], -model.gravity[1], -model.gravity[2]); // Reset the velocity of the root body model.v[0].setZero(); model.a[0] = spatial_gravity; for (unsigned int i = 1; i < model.mJointUpdateOrder.size(); i++) { jcalc (model, model.mJointUpdateOrder[i], Q, QDot); } for (unsigned int i = 1; i < model.mBodies.size(); i++) { if (model.lambda[i] == 0) { model.v[i] = model.v_J[i]; model.a[i] = model.X_lambda[i].apply(spatial_gravity); } else { model.v[i] = model.X_lambda[i].apply(model.v[model.lambda[i]]) + model.v_J[i]; model.c[i] = model.c_J[i] + crossm(model.v[i],model.v_J[i]); model.a[i] = model.X_lambda[i].apply(model.a[model.lambda[i]]) + model.c[i]; } if (!model.mBodies[i].mIsVirtual) { model.f[i] = model.I[i] * model.a[i] + crossf(model.v[i],model.I[i] * model.v[i]); if (f_ext != NULL && (*f_ext)[i] != SpatialVector::Zero()) { model.f[i] -= model.X_base[i].toMatrixAdjoint() * (*f_ext)[i]; } } else { model.f[i].setZero(); } } for (unsigned int i = model.mBodies.size() - 1; i > 0; i--) { if(model.mJoints[i].mJointType != JointTypeCustom){ if (model.mJoints[i].mDoFCount == 1) { Tau[model.mJoints[i].q_index] = model.S[i].dot(model.f[i]); } else if (model.mJoints[i].mDoFCount == 3) { Tau.block<3,1>(model.mJoints[i].q_index, 0) = model.multdof3_S[i].transpose() * model.f[i]; } } else if(model.mJoints[i].mJointType == JointTypeCustom) { unsigned int k = model.mJoints[i].custom_joint_index; Tau.block(model.mJoints[i].q_index,0, model.mCustomJoints[k]->mDoFCount, 1) = model.mCustomJoints[k]->S.transpose() * model.f[i]; } if (model.lambda[i] != 0) { model.f[model.lambda[i]] = model.f[model.lambda[i]] + model.X_lambda[i].applyTranspose(model.f[i]); } } } RBDL_DLLAPI void CompositeRigidBodyAlgorithm ( Model& model, const VectorNd &Q, MatrixNd &H, bool update_kinematics) { LOG << "-------- " << __func__ << " --------" << std::endl; assert (H.rows() == model.dof_count && H.cols() == model.dof_count); for (unsigned int i = 1; i < model.mBodies.size(); i++) { if (update_kinematics) { jcalc_X_lambda_S (model, i, Q); } model.Ic[i] = model.I[i]; } for (unsigned int i = model.mBodies.size() - 1; i > 0; i--) { if (model.lambda[i] != 0) { model.Ic[model.lambda[i]] = model.Ic[model.lambda[i]] + model.X_lambda[i].applyTranspose(model.Ic[i]); } unsigned int dof_index_i = model.mJoints[i].q_index; if (model.mJoints[i].mDoFCount == 1 && model.mJoints[i].mJointType != JointTypeCustom) { SpatialVector F = model.Ic[i] * model.S[i]; H(dof_index_i, dof_index_i) = model.S[i].dot(F); unsigned int j = i; unsigned int dof_index_j = dof_index_i; while (model.lambda[j] != 0) { F = model.X_lambda[j].applyTranspose(F); j = model.lambda[j]; dof_index_j = model.mJoints[j].q_index; if(model.mJoints[j].mJointType != JointTypeCustom) { if (model.mJoints[j].mDoFCount == 1) { H(dof_index_i,dof_index_j) = F.dot(model.S[j]); H(dof_index_j,dof_index_i) = H(dof_index_i,dof_index_j); } else if (model.mJoints[j].mDoFCount == 3) { Vector3d H_temp2 = (F.transpose() * model.multdof3_S[j]).transpose(); LOG << F.transpose() << std::endl << model.multdof3_S[j] << std::endl; LOG << H_temp2.transpose() << std::endl; H.block<1,3>(dof_index_i,dof_index_j) = H_temp2.transpose(); H.block<3,1>(dof_index_j,dof_index_i) = H_temp2; } } else if (model.mJoints[j].mJointType == JointTypeCustom){ unsigned int k = model.mJoints[j].custom_joint_index; unsigned int dof = model.mCustomJoints[k]->mDoFCount; VectorNd H_temp2 = (F.transpose() * model.mCustomJoints[k]->S).transpose(); LOG << F.transpose() << std::endl << model.mCustomJoints[j]->S << std::endl; LOG << H_temp2.transpose() << std::endl; H.block(dof_index_i,dof_index_j,1,dof) = H_temp2.transpose(); H.block(dof_index_j,dof_index_i,dof,1) = H_temp2; } } } else if (model.mJoints[i].mDoFCount == 3 && model.mJoints[i].mJointType != JointTypeCustom) { Matrix63 F_63 = model.Ic[i].toMatrix() * model.multdof3_S[i]; H.block<3,3>(dof_index_i, dof_index_i) = model.multdof3_S[i].transpose() * F_63; unsigned int j = i; unsigned int dof_index_j = dof_index_i; while (model.lambda[j] != 0) { F_63 = model.X_lambda[j].toMatrixTranspose() * (F_63); j = model.lambda[j]; dof_index_j = model.mJoints[j].q_index; if(model.mJoints[j].mJointType != JointTypeCustom){ if (model.mJoints[j].mDoFCount == 1) { Vector3d H_temp2 = F_63.transpose() * (model.S[j]); H.block<3,1>(dof_index_i,dof_index_j) = H_temp2; H.block<1,3>(dof_index_j,dof_index_i) = H_temp2.transpose(); } else if (model.mJoints[j].mDoFCount == 3) { Matrix3d H_temp2 = F_63.transpose() * (model.multdof3_S[j]); H.block<3,3>(dof_index_i,dof_index_j) = H_temp2; H.block<3,3>(dof_index_j,dof_index_i) = H_temp2.transpose(); } } else if (model.mJoints[j].mJointType == JointTypeCustom){ unsigned int k = model.mJoints[j].custom_joint_index; unsigned int dof = model.mCustomJoints[k]->mDoFCount; MatrixNd H_temp2 = F_63.transpose() * (model.mCustomJoints[k]->S); H.block(dof_index_i,dof_index_j,3,dof) = H_temp2; H.block(dof_index_j,dof_index_i,dof,3) = H_temp2.transpose(); } } } else if (model.mJoints[i].mJointType == JointTypeCustom) { unsigned int kI = model.mJoints[i].custom_joint_index; unsigned int dofI = model.mCustomJoints[kI]->mDoFCount; MatrixNd F_Nd = model.Ic[i].toMatrix() * model.mCustomJoints[kI]->S; H.block(dof_index_i, dof_index_i,dofI,dofI) = model.mCustomJoints[kI]->S.transpose() * F_Nd; unsigned int j = i; unsigned int dof_index_j = dof_index_i; while (model.lambda[j] != 0) { F_Nd = model.X_lambda[j].toMatrixTranspose() * (F_Nd); j = model.lambda[j]; dof_index_j = model.mJoints[j].q_index; if(model.mJoints[j].mJointType != JointTypeCustom){ if (model.mJoints[j].mDoFCount == 1) { MatrixNd H_temp2 = F_Nd.transpose() * (model.S[j]); H.block( dof_index_i, dof_index_j, H_temp2.rows(),H_temp2.cols()) = H_temp2; H.block(dof_index_j,dof_index_i, H_temp2.cols(),H_temp2.rows()) = H_temp2.transpose(); } else if (model.mJoints[j].mDoFCount == 3) { MatrixNd H_temp2 = F_Nd.transpose() * (model.multdof3_S[j]); H.block(dof_index_i, dof_index_j, H_temp2.rows(),H_temp2.cols()) = H_temp2; H.block(dof_index_j, dof_index_i, H_temp2.cols(),H_temp2.rows()) = H_temp2.transpose(); } } else if (model.mJoints[j].mJointType == JointTypeCustom){ unsigned int k = model.mJoints[j].custom_joint_index; unsigned int dof = model.mCustomJoints[k]->mDoFCount; MatrixNd H_temp2 = F_Nd.transpose() * (model.mCustomJoints[k]->S); H.block(dof_index_i,dof_index_j,3,dof) = H_temp2; H.block(dof_index_j,dof_index_i,dof,3) = H_temp2.transpose(); } } } } } RBDL_DLLAPI void ForwardDynamics ( Model &model, const VectorNd &Q, const VectorNd &QDot, const VectorNd &Tau, VectorNd &QDDot, std::vector *f_ext) { LOG << "-------- " << __func__ << " --------" << std::endl; SpatialVector spatial_gravity (0., 0., 0., model.gravity[0], model.gravity[1], model.gravity[2]); unsigned int i = 0; LOG << "Q = " << Q.transpose() << std::endl; LOG << "QDot = " << QDot.transpose() << std::endl; LOG << "Tau = " << Tau.transpose() << std::endl; LOG << "---" << std::endl; // Reset the velocity of the root body model.v[0].setZero(); for (i = 1; i < model.mBodies.size(); i++) { unsigned int lambda = model.lambda[i]; jcalc (model, i, Q, QDot); if (lambda != 0) model.X_base[i] = model.X_lambda[i] * model.X_base[lambda]; else model.X_base[i] = model.X_lambda[i]; model.v[i] = model.X_lambda[i].apply( model.v[lambda]) + model.v_J[i]; /* LOG << "X_J (" << i << "):" << std::endl << X_J << std::endl; LOG << "v_J (" << i << "):" << std::endl << v_J << std::endl; LOG << "v_lambda" << i << ":" << std::endl << model.v.at(lambda) << std::endl; LOG << "X_base (" << i << "):" << std::endl << model.X_base[i] << std::endl; LOG << "X_lambda (" << i << "):" << std::endl << model.X_lambda[i] << std::endl; LOG << "SpatialVelocity (" << i << "): " << model.v[i] << std::endl; */ model.c[i] = model.c_J[i] + crossm(model.v[i],model.v_J[i]); model.I[i].setSpatialMatrix (model.IA[i]); model.pA[i] = crossf(model.v[i],model.I[i] * model.v[i]); if (f_ext != NULL && (*f_ext)[i] != SpatialVector::Zero()) { LOG << "External force (" << i << ") = " << model.X_base[i].toMatrixAdjoint() * (*f_ext)[i] << std::endl; model.pA[i] -= model.X_base[i].toMatrixAdjoint() * (*f_ext)[i]; } } // ClearLogOutput(); LOG << "--- first loop ---" << std::endl; for (i = model.mBodies.size() - 1; i > 0; i--) { unsigned int q_index = model.mJoints[i].q_index; if (model.mJoints[i].mDoFCount == 1 && model.mJoints[i].mJointType != JointTypeCustom) { model.U[i] = model.IA[i] * model.S[i]; model.d[i] = model.S[i].dot(model.U[i]); model.u[i] = Tau[q_index] - model.S[i].dot(model.pA[i]); // LOG << "u[" << i << "] = " << model.u[i] << std::endl; unsigned int lambda = model.lambda[i]; if (lambda != 0) { SpatialMatrix Ia = model.IA[i] - model.U[i] * (model.U[i] / model.d[i]).transpose(); SpatialVector pa = model.pA[i] + Ia * model.c[i] + model.U[i] * model.u[i] / model.d[i]; #ifdef EIGEN_CORE_H model.IA[lambda].noalias() += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); model.pA[lambda].noalias() += model.X_lambda[i].applyTranspose(pa); #else model.IA[lambda] += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); model.pA[lambda] += model.X_lambda[i].applyTranspose(pa); #endif LOG << "pA[" << lambda << "] = " << model.pA[lambda].transpose() << std::endl; } } else if (model.mJoints[i].mDoFCount == 3 && model.mJoints[i].mJointType != JointTypeCustom) { model.multdof3_U[i] = model.IA[i] * model.multdof3_S[i]; #ifdef EIGEN_CORE_H model.multdof3_Dinv[i] = (model.multdof3_S[i].transpose() * model.multdof3_U[i]).inverse().eval(); #else model.multdof3_Dinv[i] = (model.multdof3_S[i].transpose() * model.multdof3_U[i]).inverse(); #endif Vector3d tau_temp(Tau.block(q_index,0,3,1)); model.multdof3_u[i] = tau_temp - model.multdof3_S[i].transpose() * model.pA[i]; // LOG << "multdof3_u[" << i << "] = " // << model.multdof3_u[i].transpose() << std::endl; unsigned int lambda = model.lambda[i]; if (lambda != 0) { SpatialMatrix Ia = model.IA[i] - model.multdof3_U[i] * model.multdof3_Dinv[i] * model.multdof3_U[i].transpose(); SpatialVector pa = model.pA[i] + Ia * model.c[i] + model.multdof3_U[i] * model.multdof3_Dinv[i] * model.multdof3_u[i]; #ifdef EIGEN_CORE_H model.IA[lambda].noalias() += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); model.pA[lambda].noalias() += model.X_lambda[i].applyTranspose(pa); #else model.IA[lambda] += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); model.pA[lambda] += model.X_lambda[i].applyTranspose(pa); #endif LOG << "pA[" << lambda << "] = " << model.pA[lambda].transpose() << std::endl; } } else if (model.mJoints[i].mJointType == JointTypeCustom) { unsigned int kI = model.mJoints[i].custom_joint_index; unsigned int dofI = model.mCustomJoints[kI]->mDoFCount; model.mCustomJoints[kI]->U = model.IA[i] * model.mCustomJoints[kI]->S; #ifdef EIGEN_CORE_H model.mCustomJoints[kI]->Dinv = (model.mCustomJoints[kI]->S.transpose() * model.mCustomJoints[kI]->U).inverse().eval(); #else model.mCustomJoints[kI]->Dinv = (model.mCustomJoints[kI]->S.transpose() * model.mCustomJoints[kI]->U).inverse(); #endif VectorNd tau_temp(Tau.block(q_index,0,dofI,1)); model.mCustomJoints[kI]->u = tau_temp - model.mCustomJoints[kI]->S.transpose() * model.pA[i]; // LOG << "multdof3_u[" << i << "] = " // << model.multdof3_u[i].transpose() << std::endl; unsigned int lambda = model.lambda[i]; if (lambda != 0) { SpatialMatrix Ia = model.IA[i] - (model.mCustomJoints[kI]->U * model.mCustomJoints[kI]->Dinv * model.mCustomJoints[kI]->U.transpose()); SpatialVector pa = model.pA[i] + Ia * model.c[i] + (model.mCustomJoints[kI]->U * model.mCustomJoints[kI]->Dinv * model.mCustomJoints[kI]->u); #ifdef EIGEN_CORE_H model.IA[lambda].noalias() += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); model.pA[lambda].noalias() += model.X_lambda[i].applyTranspose(pa); #else model.IA[lambda] += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); model.pA[lambda] += model.X_lambda[i].applyTranspose(pa); #endif LOG << "pA[" << lambda << "] = " << model.pA[lambda].transpose() << std::endl; } } } // ClearLogOutput(); model.a[0] = spatial_gravity * -1.; for (i = 1; i < model.mBodies.size(); i++) { unsigned int q_index = model.mJoints[i].q_index; unsigned int lambda = model.lambda[i]; SpatialTransform X_lambda = model.X_lambda[i]; model.a[i] = X_lambda.apply(model.a[lambda]) + model.c[i]; LOG << "a'[" << i << "] = " << model.a[i].transpose() << std::endl; if (model.mJoints[i].mDoFCount == 1 && model.mJoints[i].mJointType != JointTypeCustom) { QDDot[q_index] = (1./model.d[i]) * (model.u[i] - model.U[i].dot(model.a[i])); model.a[i] = model.a[i] + model.S[i] * QDDot[q_index]; } else if (model.mJoints[i].mDoFCount == 3 && model.mJoints[i].mJointType != JointTypeCustom) { Vector3d qdd_temp = model.multdof3_Dinv[i] * (model.multdof3_u[i] - model.multdof3_U[i].transpose() * model.a[i]); QDDot[q_index] = qdd_temp[0]; QDDot[q_index + 1] = qdd_temp[1]; QDDot[q_index + 2] = qdd_temp[2]; model.a[i] = model.a[i] + model.multdof3_S[i] * qdd_temp; } else if (model.mJoints[i].mJointType == JointTypeCustom) { unsigned int kI = model.mJoints[i].custom_joint_index; unsigned int dofI=model.mCustomJoints[kI]->mDoFCount; VectorNd qdd_temp = model.mCustomJoints[kI]->Dinv * ( model.mCustomJoints[kI]->u - model.mCustomJoints[kI]->U.transpose() * model.a[i]); for(unsigned int z=0; z < dofI; ++z){ QDDot[q_index+z] = qdd_temp[z]; } model.a[i] = model.a[i] + model.mCustomJoints[kI]->S * qdd_temp; } } LOG << "QDDot = " << QDDot.transpose() << std::endl; } RBDL_DLLAPI void ForwardDynamicsLagrangian ( Model &model, const VectorNd &Q, const VectorNd &QDot, const VectorNd &Tau, VectorNd &QDDot, Math::LinearSolver linear_solver, std::vector *f_ext, Math::MatrixNd *H, Math::VectorNd *C) { LOG << "-------- " << __func__ << " --------" << std::endl; bool free_H = false; bool free_C = false; if (H == NULL) { H = new MatrixNd (MatrixNd::Zero(model.dof_count, model.dof_count)); free_H = true; } if (C == NULL) { C = new VectorNd (VectorNd::Zero(model.dof_count)); free_C = true; } // we set QDDot to zero to compute C properly with the InverseDynamics // method. QDDot.setZero(); InverseDynamics (model, Q, QDot, QDDot, (*C), f_ext); CompositeRigidBodyAlgorithm (model, Q, *H, false); LOG << "A = " << std::endl << *H << std::endl; LOG << "b = " << std::endl << *C * -1. + Tau << std::endl; switch (linear_solver) { case (LinearSolverPartialPivLU) : QDDot = H->partialPivLu().solve (*C * -1. + Tau); break; case (LinearSolverColPivHouseholderQR) : QDDot = H->colPivHouseholderQr().solve (*C * -1. + Tau); break; case (LinearSolverHouseholderQR) : QDDot = H->householderQr().solve (*C * -1. + Tau); break; case (LinearSolverLLT) : QDDot = H->llt().solve (*C * -1. + Tau); break; default: LOG << "Error: Invalid linear solver: " << linear_solver << std::endl; assert (0); break; } if (free_C) { delete C; } if (free_H) { delete H; } LOG << "x = " << QDDot << std::endl; } RBDL_DLLAPI void CalcMInvTimesTau ( Model &model, const VectorNd &Q, const VectorNd &Tau, VectorNd &QDDot, bool update_kinematics) { LOG << "Q = " << Q.transpose() << std::endl; LOG << "---" << std::endl; // Reset the velocity of the root body model.v[0].setZero(); model.a[0].setZero(); if (update_kinematics) { for (unsigned int i = 1; i < model.mBodies.size(); i++) { jcalc_X_lambda_S (model, model.mJointUpdateOrder[i], Q); model.v_J[i].setZero(); model.v[i].setZero(); model.c[i].setZero(); model.pA[i].setZero(); model.I[i].setSpatialMatrix (model.IA[i]); } } for (unsigned int i = 1; i < model.mBodies.size(); i++) { model.pA[i].setZero(); } // ClearLogOutput(); if (update_kinematics) { // Compute Articulate Body Inertias for (unsigned int i = model.mBodies.size() - 1; i > 0; i--) { // unsigned int q_index = model.mJoints[i].q_index; if (model.mJoints[i].mDoFCount == 1 && model.mJoints[i].mJointType != JointTypeCustom) { model.U[i] = model.IA[i] * model.S[i]; model.d[i] = model.S[i].dot(model.U[i]); // LOG << "u[" << i << "] = " << model.u[i] << std::endl; unsigned int lambda = model.lambda[i]; if (lambda != 0) { SpatialMatrix Ia = model.IA[i] - model.U[i] * (model.U[i] / model.d[i]).transpose(); #ifdef EIGEN_CORE_H model.IA[lambda].noalias() += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); #else model.IA[lambda] += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); #endif } } else if (model.mJoints[i].mDoFCount == 3 && model.mJoints[i].mJointType != JointTypeCustom) { model.multdof3_U[i] = model.IA[i] * model.multdof3_S[i]; #ifdef EIGEN_CORE_H model.multdof3_Dinv[i] = (model.multdof3_S[i].transpose()*model.multdof3_U[i]).inverse().eval(); #else model.multdof3_Dinv[i] = (model.multdof3_S[i].transpose() * model.multdof3_U[i]).inverse(); #endif // LOG << "mCustomJoints[kI]->u[" << i << "] = " //<< model.mCustomJoints[kI]->u[i].transpose() << std::endl; unsigned int lambda = model.lambda[i]; if (lambda != 0) { SpatialMatrix Ia = model.IA[i] - ( model.multdof3_U[i] * model.multdof3_Dinv[i] * model.multdof3_U[i].transpose()); #ifdef EIGEN_CORE_H model.IA[lambda].noalias() += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); #else model.IA[lambda] += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); #endif } } else if (model.mJoints[i].mJointType == JointTypeCustom) { unsigned int kI = model.mJoints[i].custom_joint_index; // unsigned int dofI = model.mCustomJoints[kI]->mDoFCount; model.mCustomJoints[kI]->U = model.IA[i] * model.mCustomJoints[kI]->S; #ifdef EIGEN_CORE_H model.mCustomJoints[kI]->Dinv = (model.mCustomJoints[kI]->S.transpose() * model.mCustomJoints[kI]->U ).inverse().eval(); #else model.mCustomJoints[kI]->Dinv=(model.mCustomJoints[kI]->S.transpose() * model.mCustomJoints[kI]->U ).inverse(); #endif // LOG << "mCustomJoints[kI]->u[" << i << "] = " //<< model.mCustomJoints[kI]->u.transpose() << std::endl; unsigned int lambda = model.lambda[i]; if (lambda != 0) { SpatialMatrix Ia = model.IA[i] - ( model.mCustomJoints[kI]->U * model.mCustomJoints[kI]->Dinv * model.mCustomJoints[kI]->U.transpose()); #ifdef EIGEN_CORE_H model.IA[lambda].noalias() += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); #else model.IA[lambda] += model.X_lambda[i].toMatrixTranspose() * Ia * model.X_lambda[i].toMatrix(); #endif } } } } // compute articulated bias forces for (unsigned int i = model.mBodies.size() - 1; i > 0; i--) { unsigned int q_index = model.mJoints[i].q_index; if (model.mJoints[i].mDoFCount == 1 && model.mJoints[i].mJointType != JointTypeCustom) { model.u[i] = Tau[q_index] - model.S[i].dot(model.pA[i]); // LOG << "u[" << i << "] = " << model.u[i] << std::endl; unsigned int lambda = model.lambda[i]; if (lambda != 0) { SpatialVector pa = model.pA[i] + model.U[i] * model.u[i] / model.d[i]; #ifdef EIGEN_CORE_H model.pA[lambda].noalias() += model.X_lambda[i].applyTranspose(pa); #else model.pA[lambda] += model.X_lambda[i].applyTranspose(pa); #endif LOG << "pA[" << lambda << "] = " << model.pA[lambda].transpose() << std::endl; } } else if (model.mJoints[i].mDoFCount == 3 && model.mJoints[i].mJointType != JointTypeCustom) { Vector3d tau_temp ( Tau[q_index], Tau[q_index + 1], Tau[q_index + 2]); model.multdof3_u[i] = tau_temp - model.multdof3_S[i].transpose()*model.pA[i]; // LOG << "multdof3_u[" << i << "] = " // << model.multdof3_u[i].transpose() << std::endl; unsigned int lambda = model.lambda[i]; if (lambda != 0) { SpatialVector pa = model.pA[i] + model.multdof3_U[i] * model.multdof3_Dinv[i] * model.multdof3_u[i]; #ifdef EIGEN_CORE_H model.pA[lambda].noalias() += model.X_lambda[i].applyTranspose(pa); #else model.pA[lambda] += model.X_lambda[i].applyTranspose(pa); #endif LOG << "pA[" << lambda << "] = " << model.pA[lambda].transpose() << std::endl; } } else if (model.mJoints[i].mJointType == JointTypeCustom) { unsigned int kI = model.mJoints[i].custom_joint_index; unsigned int dofI = model.mCustomJoints[kI]->mDoFCount; VectorNd tau_temp(Tau.block(q_index,0,dofI,1)); model.mCustomJoints[kI]->u = tau_temp - ( model.mCustomJoints[kI]->S.transpose()* model.pA[i]); // LOG << "mCustomJoints[kI]->u" // << model.mCustomJoints[kI]->u.transpose() << std::endl; unsigned int lambda = model.lambda[i]; if (lambda != 0) { SpatialVector pa = model.pA[i] + ( model.mCustomJoints[kI]->U * model.mCustomJoints[kI]->Dinv * model.mCustomJoints[kI]->u); #ifdef EIGEN_CORE_H model.pA[lambda].noalias() += model.X_lambda[i].applyTranspose(pa); #else model.pA[lambda] += model.X_lambda[i].applyTranspose(pa); #endif LOG << "pA[" << lambda << "] = " << model.pA[lambda].transpose() << std::endl; } } } // ClearLogOutput(); for (unsigned int i = 1; i < model.mBodies.size(); i++) { unsigned int q_index = model.mJoints[i].q_index; unsigned int lambda = model.lambda[i]; SpatialTransform X_lambda = model.X_lambda[i]; model.a[i] = X_lambda.apply(model.a[lambda]) + model.c[i]; LOG << "a'[" << i << "] = " << model.a[i].transpose() << std::endl; if (model.mJoints[i].mDoFCount == 1 && model.mJoints[i].mJointType != JointTypeCustom) { QDDot[q_index] = (1./model.d[i])*(model.u[i]-model.U[i].dot(model.a[i])); model.a[i] = model.a[i] + model.S[i] * QDDot[q_index]; } else if (model.mJoints[i].mDoFCount == 3 && model.mJoints[i].mJointType != JointTypeCustom) { Vector3d qdd_temp = model.multdof3_Dinv[i] * (model.multdof3_u[i] - model.multdof3_U[i].transpose()*model.a[i]); QDDot[q_index] = qdd_temp[0]; QDDot[q_index + 1] = qdd_temp[1]; QDDot[q_index + 2] = qdd_temp[2]; model.a[i] = model.a[i] + model.multdof3_S[i] * qdd_temp; } else if (model.mJoints[i].mJointType == JointTypeCustom) { unsigned int kI = model.mJoints[i].custom_joint_index; unsigned int dofI = model.mCustomJoints[kI]->mDoFCount; VectorNd qdd_temp = model.mCustomJoints[kI]->Dinv * ( model.mCustomJoints[kI]->u - model.mCustomJoints[kI]->U.transpose() * model.a[i]); for(unsigned z = 0; z < dofI; ++z){ QDDot[q_index+z] = qdd_temp[z]; } model.a[i] = model.a[i] + model.mCustomJoints[kI]->S * qdd_temp; } } LOG << "QDDot = " << QDDot.transpose() << std::endl; } } /* namespace RigidBodyDynamics */