@@ -1098,4 +1098,75 @@ BOOST_AUTO_TEST_CASE(test_has_configuration_limit_mimic)
10981098 BOOST_CHECK_EQUAL (model.hasConfigurationLimitInTangent ().size (), 2 );
10991099}
11001100
1101+ // Non regression test for: https://github.com/stack-of-tasks/pinocchio/issues/2805
1102+ // When a frame with non null placement have inertia, the inertia was not well transformed
1103+ // in the support joint.
1104+ BOOST_AUTO_TEST_CASE (test_append_model_issue_2805)
1105+ {
1106+ // Create robot with a fixed joint
1107+ Model model_fixed_joint;
1108+ Inertia I (1000 , Eigen::Vector3d::Zero (), Eigen::Matrix3d::Identity () * 166 );
1109+ SE3 translation (Eigen::Matrix3d::Identity (), Eigen::Vector3d::UnitX ());
1110+ auto root_joint_index = model_fixed_joint.addJoint (
1111+ 0 , pinocchio::JointModel (pinocchio::JointModelFreeFlyer ()), SE3::Identity (), " root_joint" );
1112+ auto root_joint_frame_index =
1113+ model_fixed_joint.addFrame (Frame (" root_joint" , root_joint_index, 0 , SE3::Identity (), JOINT));
1114+ auto link_1_index = model_fixed_joint.addFrame (
1115+ Frame (" link_1" , root_joint_index, root_joint_frame_index, SE3::Identity (), BODY, I));
1116+ auto joint1_fixed_index = model_fixed_joint.addFrame (
1117+ Frame (" urdf_joint_1fixed" , root_joint_index, link_1_index, translation, FIXED_JOINT));
1118+ model_fixed_joint.addFrame (
1119+ Frame (" link_2" , root_joint_index, joint1_fixed_index, translation, BODY, I));
1120+
1121+ Model model_root;
1122+ auto new_model = appendModel (model_root, model_fixed_joint, 0 , SE3::Identity ());
1123+
1124+ BOOST_CHECK (new_model.inertias [1 ].isApprox (model_fixed_joint.inertias [1 ]));
1125+ }
1126+
1127+ // Non regression test for: https://github.com/stack-of-tasks/pinocchio/issues/2805
1128+ // Same test as above but verify the special case of frame attached to universe frame.
1129+ BOOST_AUTO_TEST_CASE (test_append_model_universe_with_inertia_issue_2805)
1130+ {
1131+ Inertia I (1000 , Eigen::Vector3d::Zero (), Eigen::Matrix3d::Identity () * 166 );
1132+ SE3 translation_root_joint (Eigen::Matrix3d::Identity (), Eigen::Vector3d::UnitX ());
1133+ SE3 translation_fixed_link_1 (Eigen::Matrix3d::Identity (), Eigen::Vector3d::UnitY ());
1134+ SE3 translation_fixed_link_2 (Eigen::Matrix3d::Identity (), Eigen::Vector3d (1 ., 0 ., 1 .));
1135+ SE3 translation_AB (Eigen::Matrix3d::Identity (), Eigen::Vector3d::UnitZ ());
1136+
1137+ // Base model
1138+ Model model_a;
1139+ auto model_a_root_joint_index = model_a.addJoint (
1140+ 0 , pinocchio::JointModel (pinocchio::JointModelFreeFlyer ()), SE3::Identity (), " root_joint" );
1141+ auto model_a_root_joint_frame = model_a.addFrame (
1142+ Frame (" root_joint" , model_a_root_joint_index, 0 , translation_root_joint, JOINT));
1143+
1144+ // Model with frame and inertia attached to universe.
1145+ // To reproduce the issue, we must have two frame with inertia attached to universe.
1146+ // With only one frame, some computation will give a 0 mass inertia that will hide the bug.
1147+ Model model_b;
1148+ model_b.addFrame (Frame (" fixed_link_1" , 0 , 0 , translation_fixed_link_1, BODY, I));
1149+ model_b.addFrame (Frame (" fixed_link_2" , 0 , 0 , translation_fixed_link_2, BODY, I));
1150+
1151+ Model expected_model;
1152+ auto expected_model_root_joint_index = expected_model.addJoint (
1153+ 0 , pinocchio::JointModel (pinocchio::JointModelFreeFlyer ()), SE3::Identity (), " root_joint" );
1154+ auto expected_model_root_joint_frame_index = expected_model.addFrame (
1155+ Frame (" root_joint" , expected_model_root_joint_index, 0 , translation_root_joint, JOINT));
1156+ auto fixed_link_1_frame_index = expected_model.addFrame (Frame (
1157+ " fixed_link_1" , expected_model_root_joint_index, expected_model_root_joint_frame_index,
1158+ translation_root_joint.act (translation_AB.act (translation_fixed_link_1)), BODY, I));
1159+ auto fixed_link_2_frame_index = expected_model.addFrame (Frame (
1160+ " fixed_link_2" , expected_model_root_joint_index, expected_model_root_joint_frame_index,
1161+ translation_root_joint.act (translation_AB.act (translation_fixed_link_2)), BODY, I));
1162+
1163+ // Test frame position and inertias attached to root_joint
1164+ auto new_model = appendModel (model_a, model_b, model_a_root_joint_frame, translation_AB);
1165+ BOOST_CHECK (new_model.frames [fixed_link_1_frame_index].placement .isApprox (
1166+ expected_model.frames [fixed_link_1_frame_index].placement ));
1167+ BOOST_CHECK (new_model.frames [fixed_link_2_frame_index].placement .isApprox (
1168+ expected_model.frames [fixed_link_2_frame_index].placement ));
1169+ BOOST_CHECK (new_model.inertias [1 ].isApprox (expected_model.inertias [1 ]));
1170+ }
1171+
11011172BOOST_AUTO_TEST_SUITE_END ()
0 commit comments