19 #include <boost/test/unit_test.hpp>
20 #include <boost/utility/binary.hpp>
24 template<
typename Derived>
25 inline bool isFinite(
const Eigen::MatrixBase<Derived> & x)
27 return ((
x -
x).array() == (
x -
x).array()).all();
30 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
38 BOOST_CHECK(
model.frames.size() >=
size_t(
model.njoints));
39 for (Model::FrameVector::const_iterator
it =
model.frames.begin();
it !=
model.frames.end(); ++
it)
44 BOOST_CHECK(frame_copy ==
frame);
48 std::ostringstream os;
49 os << frame1 << std::endl;
50 BOOST_CHECK(!os.str().empty());
54 BOOST_CHECK(frame1 == frame2);
63 BOOST_CHECK(
frame.cast<
double>().cast<
long double>() ==
frame.cast<
long double>());
66 Frameld frame2(
frame);
68 BOOST_CHECK(frame2 ==
frame.cast<
long double>());
73 using namespace Eigen;
80 const std::string & frame_name = std::string(
model.names[parent_idx] +
"_frame");
81 const SE3 & framePlacement = SE3::Random();
85 VectorXd
q = VectorXd::Ones(
model.nq);
90 data.oMf[
model.getFrameId(frame_name)].isApprox(
data.oMi[parent_idx] * framePlacement));
95 using namespace Eigen;
102 const std::string & frame_name = std::string(
model.names[parent_idx] +
"_frame");
103 const SE3 & framePlacement = SE3::Random();
109 VectorXd
q = VectorXd::Ones(
model.nq);
117 BOOST_CHECK(
data.oMf[frame_idx].isApprox(data_ref.oMf[frame_idx]));
122 using namespace Eigen;
129 const std::string & frame_name = std::string(
model.names[parent_idx] +
"_frame");
130 const SE3 & framePlacement = SE3::Random();
136 VectorXd
q = VectorXd::Ones(
model.nq);
144 BOOST_CHECK(
data.oMf[frame_idx].isApprox(data_ref.oMf[frame_idx]));
149 using namespace Eigen;
156 const std::string & frame_name = std::string(
model.names[parent_idx] +
"_frame");
157 const SE3 & framePlacement = SE3::Random();
162 VectorXd
q = VectorXd::Ones(
model.nq);
164 VectorXd
v = VectorXd::Ones(
model.nv);
169 BOOST_CHECK(vf.isApprox(framePlacement.actInv(
data.v[parent_idx])));
180 BOOST_CHECK(
SE3(data_ref.oMf[frame_idx].rotation(), Eigen::Vector3d::Zero())
187 using namespace Eigen;
194 const std::string & frame_name = std::string(
model.names[parent_idx] +
"_frame");
195 const SE3 & framePlacement = SE3::Random();
200 VectorXd
q = VectorXd::Ones(
model.nq);
202 VectorXd
v = VectorXd::Ones(
model.nv);
203 VectorXd
a = VectorXd::Ones(
model.nv);
208 BOOST_CHECK(af.isApprox(framePlacement.actInv(
data.a[parent_idx])));
217 BOOST_CHECK(data_ref.oMf[frame_idx].act(a_ref).isApprox(
219 BOOST_CHECK(
SE3(data_ref.oMf[frame_idx].rotation(), Eigen::Vector3d::Zero())
226 using namespace Eigen;
233 const std::string & frame_name = std::string(
model.names[parent_idx] +
"_frame");
234 const SE3 & framePlacement = SE3::Random();
239 VectorXd
q = VectorXd::Ones(
model.nq);
241 VectorXd
v = VectorXd::Ones(
model.nv);
242 VectorXd
a = VectorXd::Ones(
model.nv);
245 Motion vel = framePlacement.actInv(
data.v[parent_idx]);
250 linear =
acc.linear() + vel.angular().cross(vel.linear());
251 acc_classical_local.linear() = linear;
255 BOOST_CHECK(af.isApprox(acc_classical_local));
261 SE3 T_ref = data_ref.oMf[frame_idx];
265 Motion acc_classical_local_ref = a_ref;
266 linear = a_ref.linear() +
v_ref.angular().cross(
v_ref.linear());
267 acc_classical_local_ref.linear() = linear;
275 Motion acc_classical_world_ref = T_ref.act(a_ref);
276 linear = acc_classical_world_ref.linear() + vel_world_ref.angular().cross(vel_world_ref.linear());
277 acc_classical_world_ref.linear() = linear;
282 Motion vel_aligned_ref =
SE3(T_ref.rotation(), Eigen::Vector3d::Zero()).act(
v_ref);
283 Motion acc_classical_aligned_ref =
SE3(T_ref.rotation(), Eigen::Vector3d::Zero()).act(a_ref);
285 acc_classical_aligned_ref.linear() + vel_aligned_ref.angular().cross(vel_aligned_ref.linear());
286 acc_classical_aligned_ref.linear() = linear;
288 BOOST_CHECK(acc_classical_aligned_ref.isApprox(
294 using namespace Eigen;
301 Frame(
"Frame1", parentId, 0,
SE3(Matrix3d::Identity(), Vector3d(1.0, 0.0, 0.0)),
OP_FRAME));
317 v_local.linear() = Vector3d(0.0, 1.0, 0.0);
318 v_local.angular() = Vector3d(0.0, 0.0, 1.0);
321 v_world.linear() = Vector3d::Zero();
322 v_world.angular() = Vector3d(0.0, 0.0, 1.0);
325 v_align.linear() = Vector3d(-1.0, 0.0, 0.0);
326 v_align.angular() = Vector3d(0.0, 0.0, 1.0);
330 ac_local.linear() = Vector3d(-1.0, 0.0, 0.0);
331 ac_local.angular() = Vector3d::Zero();
333 Motion ac_world = Motion::Zero();
336 ac_align.linear() = Vector3d(0.0, -1.0, 0.0);
337 ac_align.angular() = Vector3d::Zero();
367 using namespace Eigen;
371 const std::string & frame_name = std::string(
model.names[joint_idx] +
"_frame");
372 const SE3 & framePlacement = SE3::Random();
373 auto frame_idx =
model.addFrame(
Frame(frame_name, joint_idx, 0, framePlacement,
OP_FRAME));
379 model.lowerPositionLimit.head<7>().
fill(-1.);
380 model.upperPositionLimit.head<7>().
fill(1.);
382 VectorXd
v = VectorXd::Random(
model.nv);
394 BOOST_CHECK((J_local *
v).
isApprox(frame_velocity_local.toVector()));
400 BOOST_CHECK((J_world *
v).
isApprox(frame_velocity_world.toVector()));
405 auto frame_velocity_local_world_aligned =
407 BOOST_CHECK((J_local_world_aligned *
v).
isApprox(frame_velocity_local_world_aligned.toVector()));
413 using namespace Eigen;
418 for (
int j = 1; j <
model.njoints; j++)
427 using namespace Eigen;
446 using namespace Eigen;
450 const std::string & frame_name = std::string(
model.names[joint_idx] +
"_frame");
451 const SE3 & framePlacement = SE3::Random();
452 auto frame_idx =
model.addFrame(
Frame(frame_name, joint_idx, 0, framePlacement,
OP_FRAME));
458 model.lowerPositionLimit.head<7>().
fill(-1.);
459 model.upperPositionLimit.head<7>().
fill(1.);
461 VectorXd
v = VectorXd::Random(
model.nv);
470 BOOST_CHECK((J_local *
v).
isApprox(frame_velocity_local.toVector()));
476 BOOST_CHECK((J_world *
v).
isApprox(frame_velocity_world.toVector()));
481 auto frame_velocity_local_world_aligned =
483 BOOST_CHECK((J_local_world_aligned *
v).
isApprox(frame_velocity_local_world_aligned.toVector()));
489 using namespace Eigen;
494 for (
int j = 1; j <
model.njoints; j++)
503 using namespace Eigen;
519 using namespace Eigen;
526 const std::string & frame_name = std::string(
model.names[parent_idx] +
"_frame");
527 const SE3 & framePlacement = SE3::Random();
533 model, -1 * Eigen::VectorXd::Ones(
model.nq), Eigen::VectorXd::Ones(
model.nq));
534 VectorXd
v = VectorXd::Random(
model.nv);
535 VectorXd
a = VectorXd::Random(
model.nv);
547 BOOST_CHECK(
frame.placement.isApprox_impl(framePlacement));
559 const Motion & v_ref_local =
frame.placement.actInv(data_ref.v[parent_idx]);
560 const Motion &
v_ref = data_ref.oMf[idx].act(v_ref_local);
562 const SE3 wMf =
SE3(data_ref.oMf[idx].rotation(), SE3::Vector3::Zero());
563 const Motion v_ref_local_world_aligned = wMf.act(v_ref_local);
564 BOOST_CHECK(v_idx.isApprox(
v_ref));
567 const Motion a_ref_local =
frame.placement.actInv(data_ref.a[parent_idx]);
568 const Motion a_ref = data_ref.oMf[idx].act(a_ref_local);
569 const Motion a_ref_local_world_aligned = wMf.act(a_ref_local);
570 BOOST_CHECK(a_idx.isApprox(a_ref));
578 v_idx = (Motion::Vector6)(
J *
v);
579 BOOST_CHECK(v_idx.isApprox(v_ref_local));
581 a_idx = (Motion::Vector6)(
J *
a + dJ *
v);
582 BOOST_CHECK(a_idx.isApprox(a_ref_local));
588 world_v_frame.linear().setZero();
590 v_idx = (Motion::Vector6)(
J *
v);
591 BOOST_CHECK(v_idx.isApprox(v_ref_local_world_aligned));
593 a_idx = (Motion::Vector6)(
J *
a + dJ *
v);
595 a_idx.isApprox(world_v_frame.cross(wMf.act(v_ref_local)) + a_ref_local_world_aligned));
601 const double alpha = 1e-8;
602 Eigen::VectorXd q_plus(
model.nq);
607 J_ref_local_world_aligned(6,
model.nv);
608 J_ref_world.fill(0.);
609 J_ref_local.fill(0.);
610 J_ref_local_world_aligned.fill(0.);
619 J_ref_plus_local_world_aligned(6,
model.nv);
620 J_ref_plus_world.fill(0.);
621 J_ref_plus_local.fill(0.);
622 J_ref_plus_local_world_aligned.fill(0.);
631 dJ_ref_local_world_aligned(6,
model.nv);
632 dJ_ref_world.fill(0.);
633 dJ_ref_local.fill(0.);
634 dJ_ref_local_world_aligned.fill(0.);
635 dJ_ref_world = (J_ref_plus_world - J_ref_world) /
alpha;
636 dJ_ref_local = (J_ref_plus_local - J_ref_local) /
alpha;
637 dJ_ref_local_world_aligned =
638 (J_ref_plus_local_world_aligned - J_ref_local_world_aligned) /
alpha;
645 dJ_local_world_aligned(6,
model.nv);
648 dJ_local_world_aligned.fill(0.);
653 BOOST_CHECK(dJ_world.isApprox(dJ_ref_world, sqrt(
alpha)));
654 BOOST_CHECK(dJ_local.isApprox(dJ_ref_local, sqrt(
alpha)));
655 BOOST_CHECK(dJ_local_world_aligned.isApprox(dJ_ref_local_world_aligned, sqrt(
alpha)));
661 using namespace Eigen;
667 Data data_free(model_free);
674 const std::string
joint_name =
"chest2_joint";
679 Data data_fix(model_fix);
688 VectorXd v_free(VectorXd::Random(model_free.
nv));
689 VectorXd a_free(VectorXd::Random(model_free.
nv));
692 q_free[joint_idx_q] = 0;
693 v_free[joint_idx_v] = 0;
694 a_free[joint_idx_v] = 0;
697 VectorXd q_fix(model_fix.
nq);
698 q_fix << q_free.head(joint_idx_q), q_free.tail(model_free.
nq - joint_idx_q - 1);
699 VectorXd v_fix(model_fix.
nv);
700 v_fix << v_free.head(joint_idx_v), v_free.tail(model_free.
nv - joint_idx_v - 1);
701 VectorXd a_fix(model_fix.
nv);
702 a_fix << a_free.head(joint_idx_v), a_free.tail(model_free.
nv - joint_idx_v - 1);
710 BOOST_CHECK(inertia_fix.isApprox(inertia_free));
714 BOOST_CHECK(inertia_fix.isApprox(inertia_free));
716 rnea(model_fix, data_fix, q_fix, v_fix, a_fix);
717 rnea(model_free, data_free, q_free, v_free, a_free);
721 BOOST_CHECK(force_fix.isApprox(force_free));
723 BOOST_AUTO_TEST_SUITE_END()