1 #include <gtest/gtest.h> 48 VectorNd tau1 = VectorNd::Zero(model->qdot_size);
49 VectorNd tau2 = VectorNd::Zero(model->qdot_size);
65 VectorNd Q = VectorNd::Constant((
size_t)model->dof_count, 0.);
66 VectorNd QDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
67 VectorNd QDDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
68 VectorNd Tau = VectorNd::Constant((
size_t)model->dof_count, 0.);
72 EXPECT_EQ(-4.905, QDDot[0]);
85 VectorNd Q = VectorNd::Constant((
size_t)model->dof_count, 0.);
86 VectorNd QDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
87 VectorNd QDDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
88 VectorNd Tau = VectorNd::Constant((
size_t)model->dof_count, 0.);
92 EXPECT_EQ(-2.3544, QDDot[0]);
108 VectorNd Q = VectorNd::Constant((
size_t)model->dof_count, 0.);
109 VectorNd QDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
110 VectorNd QDDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
111 VectorNd Tau = VectorNd::Constant((
size_t)model->dof_count, 0.);
117 EXPECT_NEAR(-5.88600000000000E+00, QDDot[0],
TEST_PREC);
118 EXPECT_NEAR(3.92400000000000E+00, QDDot[1],
TEST_PREC);
139 VectorNd Q = VectorNd::Constant((
size_t)model->dof_count, 0.);
140 VectorNd QDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
141 VectorNd QDDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
142 VectorNd Tau = VectorNd::Constant((
size_t)model->dof_count, 0.);
148 EXPECT_NEAR(-6.03692307692308E+00, QDDot[0],
TEST_PREC);
149 EXPECT_NEAR(3.77307692307692E+00, QDDot[1],
TEST_PREC);
150 EXPECT_NEAR(1.50923076923077E+00, QDDot[2],
TEST_PREC);
166 VectorNd Q = VectorNd::Constant((
size_t)model->dof_count, 0.);
167 VectorNd QDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
168 VectorNd QDDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
169 VectorNd Tau = VectorNd::Constant((
size_t)model->dof_count, 0.);
177 EXPECT_NEAR(-3.92400000000000E+00, QDDot[0],
TEST_PREC);
178 EXPECT_NEAR(0.00000000000000E+00, QDDot[1],
TEST_PREC);
191 model->addBody(1,
Xtrans(
Vector3d(1., 0., 0.)), joint_b1, body_b1);
196 model->addBody(2,
Xtrans(
Vector3d(0., 1., 0.)), joint_c1, body_c1);
201 model->addBody(1,
Xtrans(
Vector3d(-0.5, 0., 0.)), joint_b2, body_b2);
206 model->addBody(4,
Xtrans(
Vector3d(0., -0.5, 0.)), joint_c2, body_c2);
209 VectorNd Q = VectorNd::Constant((
size_t)model->dof_count, 0.);
210 VectorNd QDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
211 VectorNd QDDot = VectorNd::Constant((
size_t)model->dof_count, 0.);
212 VectorNd Tau = VectorNd::Constant((
size_t)model->dof_count, 0.);
220 EXPECT_NEAR(-1.60319066147860E+00, QDDot[0],
TEST_PREC);
221 EXPECT_NEAR(-5.34396887159533E-01, QDDot[1],
TEST_PREC);
222 EXPECT_NEAR(4.10340466926070E+00, QDDot[2],
TEST_PREC);
223 EXPECT_NEAR(2.67198443579767E-01, QDDot[3],
TEST_PREC);
224 EXPECT_NEAR(5.30579766536965E+00, QDDot[4],
TEST_PREC);
233 Joint(
SpatialVector(0., 0., 0., 1., 0., 0.),
SpatialVector(0., 0., 0., 0., 1., 0.),
SpatialVector(0., 0., 0., 0., 0., 1.),
234 SpatialVector(0., 0., 1., 0., 0., 0.),
SpatialVector(0., 1., 0., 0., 0., 0.),
SpatialVector(1., 0., 0., 0., 0., 0.)),
272 EXPECT_EQ(QDDot_aba.size(), QDDot_lagrangian.size());
284 Joint(
SpatialVector(0., 0., 0., 1., 0., 0.),
SpatialVector(0., 0., 0., 0., 1., 0.),
SpatialVector(0., 0., 0., 0., 0., 1.),
285 SpatialVector(0., 0., 1., 0., 0., 0.),
SpatialVector(0., 1., 0., 0., 0., 0.),
SpatialVector(1., 0., 0., 0., 0., 0.)),
324 EXPECT_EQ(QDDot_aba.size(), QDDot_lagrangian.size());
351 unsigned int base_id_rot_z, base_id_rot_y;
370 QDDot_ref[0] = 3.301932144386186;
398 unsigned int base_id_rot_z, base_id_rot_y;
448 Joint joint_trans_z, joint_trans_y, joint_trans_x;
483 unsigned int temp_id;
498 temp_id = model->
addBody(temp_id,
Xtrans(
Vector3d(0., -0.5, 0.)), joint_rot_z, lower_leg_right_body);
502 foot_right_id = temp_id;
516 foot_left_id = temp_id;
534 CS_right.
bind(*model);
535 CS_left.
bind(*model);
536 CS_both.
bind(*model);
554 QDot[0] = -1.77845e-06;
555 QDot[1] = -0.00905283;
556 QDot[2] = -0.000184484;
557 QDot[3] = 0.000183536;
558 QDot[4] = -1.20144e-06;
559 QDot[5] = 9.23727e-05;
560 QDot[6] = 0.000183536;
561 QDot[7] = -1.20144e-06;
562 QDot[8] = 9.23727e-05;
601 QDot_fixed[0] = -3.2;
602 QDot_fixed[1] = -2.3;
604 QDDot_fixed[0] = 1.2;
605 QDDot_fixed[1] = 2.1;
607 Q = CreateDofVectorFromReducedVector(Q_fixed);
608 QDot = CreateDofVectorFromReducedVector(QDot_fixed);
609 QDDot = CreateDofVectorFromReducedVector(QDDot_fixed);
612 inverseDynamics(*model_fixed, Q_fixed, QDot_fixed, QDDot_fixed, Tau_fixed);
615 Tau_2dof[0] =
Tau[0];
616 Tau_2dof[1] =
Tau[2];
623 for (
unsigned int i = 0; i < model->dof_count; i++)
625 Q[i] =
static_cast<double>(i + 1) * 0.1;
626 QDot[i] =
static_cast<double>(i + 1) * 1.1;
627 Tau[i] =
static_cast<double>(i + 1) * -1.2;
630 MatrixNd H(MatrixNd::Zero(model->dof_count, model->dof_count));
631 VectorNd C(VectorNd::Zero(model->dof_count));
635 H = MatrixNd::Zero(model->dof_count, model->dof_count);
636 C = VectorNd::Zero(model->dof_count);
637 VectorNd QDDot_prealloc(VectorNd::Zero(model->dof_count));
645 for (
unsigned int i = 0; i < model->dof_count; i++)
647 Q[i] = rand() /
static_cast<double>(RAND_MAX);
648 QDot[i] = rand() /
static_cast<double>(RAND_MAX);
649 Tau[i] = rand() /
static_cast<double>(RAND_MAX);
652 MatrixNd M(MatrixNd::Zero(model->dof_count, model->dof_count));
665 for (
unsigned int i = 0; i < model->dof_count; i++)
667 Q[i] = rand() /
static_cast<double>(RAND_MAX);
668 QDot[i] = rand() /
static_cast<double>(RAND_MAX);
669 Tau[i] = rand() /
static_cast<double>(RAND_MAX);
673 MatrixNd M(MatrixNd::Zero(model->dof_count, model->dof_count));
686 qddot_solve_llt.setZero();
688 qddot_solve_llt = M.llt().solve(
Tau);
690 qddot_minv.setZero();
698 for (
unsigned int i = 0; i < model->dof_count; i++)
700 Q[i] = rand() /
static_cast<double>(RAND_MAX);
701 Tau[i] = rand() /
static_cast<double>(RAND_MAX);
704 MatrixNd M(MatrixNd::Zero(model->dof_count, model->dof_count));
712 for (
unsigned int j = 0; j < 1; j++)
714 for (
unsigned int i = 0; i < model->dof_count; i++)
716 Tau[i] = rand() /
static_cast<double>(RAND_MAX);
720 qddot_solve_llt = M.llt().solve(
Tau);
729 for (
unsigned int i = 0; i < model->dof_count; i++)
731 Q[i] = rand() /
static_cast<double>(RAND_MAX);
732 QDot[i] = rand() /
static_cast<double>(RAND_MAX);
733 Tau[i] = rand() /
static_cast<double>(RAND_MAX);
737 MatrixNd M(MatrixNd::Zero(model->dof_count, model->dof_count));
744 for (
unsigned int j = 0; j < 1; j++)
746 for (
unsigned int i = 0; i < model->dof_count; i++)
748 Tau[i] = rand() /
static_cast<double>(RAND_MAX);
752 qddot_solve_llt = M.llt().solve(
Tau);
776 G1 = RobotDynamics::Math::VectorNd::Zero(model->dof_count);
777 G2 = RobotDynamics::Math::VectorNd::Zero(model->dof_count);
790 model->gravity =
MotionVector(0., 0., 0., 0., 0., -9.81);
805 for (
unsigned i = 1; i < model->mBodies.size() - 1; i++)
820 if (model->mJoints[i].mDoFCount == 1)
824 else if (model->mJoints[i].mDoFCount == 3)
831 unsigned int k = model->mJoints[i].custom_joint_index;
832 G.block(model->mJoints[i].q_index, 0, model->mCustomJoints[k]->mDoFCount, 1)
842 MatrixNd M(model_emulated->qdot_size, model_emulated->qdot_size);
843 VectorNd N(model_emulated->qdot_size);
847 unsigned int foot_r_id = model_emulated->GetBodyId(
"foot_r");
848 SpatialForce F(model_emulated->bodyFrames[foot_r_id], 0.1, 0.3, -0.8, 82., -23., 500.1);
850 MatrixNd J_r_foot(6, model_emulated->qdot_size);
858 VectorNd qddot_cf(model_emulated->qdot_size), qddot_fd(model_emulated->qdot_size), qddot_test(model_emulated->qdot_size);
861 qddot_cf = M.inverse() * (tau + J_r_foot.transpose() * F - N);
863 std::shared_ptr<Math::SpatialForceV> f_ext(
new Math::SpatialForceV(model_emulated->mBodies.size()));
865 for (
int i = 0; i < model_emulated->mBodies.size(); i++)
867 (*f_ext)[i].setIncludingFrame(model_emulated->bodyFrames[i], 0., 0., 0., 0., 0., 0.);
870 (*f_ext)[i].fx() = F.
fx();
871 (*f_ext)[i].fy() = F.
fy();
872 (*f_ext)[i].fz() = F.
fz();
873 (*f_ext)[i].mx() = F.
mx();
874 (*f_ext)[i].my() = F.
my();
875 (*f_ext)[i].mz() = F.
mz();
883 std::cout << (qddot_cf - qddot_fd).transpose();
893 MatrixNd M(model_emulated->qdot_size, model_emulated->qdot_size);
894 VectorNd N(model_emulated->qdot_size);
898 unsigned int foot_r_id = model_emulated->GetBodyId(
"foot_r");
899 SpatialForce F(model_emulated->bodyFrames[foot_r_id], 0.1, 0.3, -0.8, 82., -23., 500.1);
901 MatrixNd J_r_foot(6, model_emulated->qdot_size);
909 VectorNd qddot_cf(model_emulated->qdot_size), qddot_fd(model_emulated->qdot_size), qddot_test(model_emulated->qdot_size);
912 qddot_cf = M.inverse() * (tau + J_r_foot.transpose() * F - N);
914 std::shared_ptr<Math::SpatialForceV> f_ext(
new Math::SpatialForceV(model_emulated->mBodies.size()));
916 for (
int i = 0; i < model_emulated->mBodies.size(); i++)
918 (*f_ext)[i].setIncludingFrame(model_emulated->bodyFrames[i], 0., 0., 0., 0., 0., 0.);
921 (*f_ext)[i].fx() = F.
fx();
922 (*f_ext)[i].fy() = F.
fy();
923 (*f_ext)[i].fz() = F.
fz();
924 (*f_ext)[i].mx() = F.
mx();
925 (*f_ext)[i].my() = F.
my();
926 (*f_ext)[i].mz() = F.
mz();
930 forwardDynamics(*model_emulated, q, qdot, tau, qddot_fd, f_ext.get(),
false);
934 std::cout << (qddot_cf - qddot_fd).transpose();
944 MatrixNd M(MatrixNd::Zero(model_3dof->dof_count, model_3dof->dof_count));
947 VectorNd qddot_solve_llt = M.llt().solve(tau);
952 for (
unsigned int j = 0; j < 10; j++)
957 qddot_solve_llt = M.llt().solve(tau);
967 model->gravity.SpatialVector::set(0., 0., 0., 0., 0., -9.81);
970 double b1_mass = 0.1;
980 model->appendBody(
Xtrans(
Vector3d(0., 1., -1.)), j_z, b,
"body3");
995 for (
unsigned int i = 0; i < model->qdot_size; i++)
998 q[i] = 0.3 * M_PI * (
static_cast<double>(rand()) / static_cast<double>(RAND_MAX)) - 0.3;
999 qdot[i] = 0.5 * (
static_cast<double>(rand()) / static_cast<double>(RAND_MAX)) - 1.0;
1012 model_emulated->gravity.SpatialVector::set(0., 0., 0., 0., 0., -9.81);
1014 Math::VectorNd N = Math::VectorNd::Zero(model_emulated->qdot_size);
1015 Math::VectorNd G = Math::VectorNd::Zero(model_emulated->qdot_size);
1016 Math::VectorNd C = Math::VectorNd::Zero(model_emulated->qdot_size);
1032 MatrixNd M(MatrixNd::Zero(model_3dof->dof_count, model_3dof->dof_count));
1036 VectorNd qddot_solve_llt = M.llt().solve(tau);
1041 for (
unsigned int j = 0; j < 10; j++)
1047 qddot_solve_llt = M.llt().solve(tau);
1057 ::testing::InitGoogleTest(&argc, argv);
1058 return RUN_ALL_TESTS();
Joint joint_rot_z(SpatialVector(0., 0., 1., 0., 0., 0.))
static bool checkVectorNdEpsilonClose(const RobotDynamics::Math::VectorNd &v1, const RobotDynamics::Math::VectorNd &v2, const double epsilon)
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
3 DoF joint that uses Euler ZYX convention (faster than emulated
Describes all properties of a single body.
unsigned int foot_left_id
User defined joints of varying size.
Fixture that contains two models of which one has one joint fixed.
void coriolisEffects(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, Math::VectorNd &Tau, bool update_kinematics=true)
Computes the coriolis forces.
SpatialTransform Xtrans(const Vector3d &r)
Get pure translation transform.
A ForceVector is a SpatialVector containing 3 moments and 3 linear forces.
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.
bool checkModelZeroVectorsAndMatrices(RobotDynamics::Model &model)
EIGEN_STRONG_INLINE double & fy()
Get reference to y-linear component.
Math::MotionVector gravity
the cartesian vector of the gravity
Body lower_leg_right_body
EIGEN_STRONG_INLINE double & fx()
Get reference to x-linear component.
unsigned int addBody(const unsigned int parent_id, const Math::SpatialTransform &joint_frame, const Joint &joint, const Body &body, std::string body_name="")
Connects a given body to the model.
EIGEN_STRONG_INLINE double & fz()
Get reference to z-linear component.
EIGEN_STRONG_INLINE double & my()
Get reference to y-angular component.
Structure that contains both constraint information and workspace memory.
Describes a joint relative to the predecessor body.
void calcBodyGravityWrench(Model &model, unsigned int body_id, RobotDynamics::Math::SpatialForce &gravity_wrench)
Calculate the wrench due to gravity on a body.
EIGEN_STRONG_INLINE double & mz()
Get reference to z-angular component.
void calcBodySpatialJacobian(Model &model, const Math::VectorNd &Q, unsigned int body_id, Math::MatrixNd &G, bool update_kinematics=true)
Computes the spatial jacobian for a body. The result will be returned via the G argument and represen...
void updateKinematics(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &QDDot)
Updates and computes velocities and accelerations of the bodies.
unsigned int foot_right_id
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.
A 6-DoF joint for floating-base (or freeflyer) systems.
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.
Math types such as vectors and matrices and utility functions.
static bool checkSpatialVectorsEpsilonClose(const RobotDynamics::Math::SpatialVector &v1, const RobotDynamics::Math::SpatialVector &v2, const double epsilon)
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.
EIGEN_STRONG_INLINE double & mx()
Get reference to x-angular component.
TEST_F(Human36, TestNonlinearEffects)
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.
static bool checkVectorNdEq(const RobotDynamics::Math::VectorNd &v1, const RobotDynamics::Math::VectorNd &v2)
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.
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.
Body upper_leg_right_body
int main(int argc, char **argv)