Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mjcf : Fix parsing of armature parameters #2477

Merged
merged 10 commits into from
Nov 13, 2024
3 changes: 2 additions & 1 deletion include/pinocchio/parsers/mjcf/mjcf-graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ namespace pinocchio
Eigen::VectorXd damping;

// Armature inertia created by this joint
double armature = 0.;
Eigen::VectorXd armature;
// Dry friction.
double frictionLoss = 0.;

Expand All @@ -152,6 +152,7 @@ namespace pinocchio
;
friction = Eigen::VectorXd::Constant(1, 0.);
damping = Eigen::VectorXd::Constant(1, 0.);
armature = Eigen::VectorXd::Constant(1, 0.);
}

/// @brief Set dimension to the limits to match the joint nq and nv.
Expand Down
13 changes: 9 additions & 4 deletions src/parsers/mjcf/mjcf-graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ namespace pinocchio
ret.minConfig = Vector::Constant(Nq, -1.01);
ret.friction = Vector::Constant(Nv, 0.);
ret.damping = Vector::Constant(Nv, 0.);
ret.armature = armature;
ret.armature = Vector::Constant(Nv, armature[0]);
ret.frictionLoss = frictionLoss;
ret.springStiffness = springStiffness;
ret.springReference = springReference;
Expand All @@ -137,6 +137,7 @@ namespace pinocchio
template<int Nq, int Nv>
RangeJoint RangeJoint::concatenate(const RangeJoint & range) const
{
typedef UrdfVisitor::Vector Vector;
assert(range.maxEffort.size() == Nv);
assert(range.minConfig.size() == Nq);

Expand All @@ -160,6 +161,10 @@ namespace pinocchio
ret.springReference.tail(1) = range.springReference;
ret.springStiffness.conservativeResize(springStiffness.size() + 1);
ret.springStiffness.tail(1) = range.springStiffness;

ret.armature.conservativeResize(armature.size() + Nv);
ret.armature.tail(Nv) = Vector::Constant(Nv, range.armature[0]);

return ret;
}

Expand Down Expand Up @@ -208,7 +213,7 @@ namespace pinocchio

value = el.get_optional<double>("<xmlattr>.armature");
if (value)
range.armature = *value;
range.armature[0] = *value;

// friction loss
value = el.get_optional<double>("<xmlattr>.frictionloss");
Expand Down Expand Up @@ -898,7 +903,7 @@ namespace pinocchio

// Add armature info
JointIndex j_id = urdfVisitor.getJointId(joint.jointName);
urdfVisitor.model.armature[static_cast<Eigen::Index>(j_id) - 1] = range.armature;
urdfVisitor.model.armature.segment(urdfVisitor.model.joints[j_id].idx_v(), urdfVisitor.model.joints[j_id].nv()) = range.armature;
}

void MjcfGraph::fillModel(const std::string & nameOfBody)
Expand Down Expand Up @@ -1007,7 +1012,7 @@ namespace pinocchio
FrameIndex jointFrameId = urdfVisitor.model.addJointFrame(joint_id, (int)parentFrameId);
urdfVisitor.appendBodyToJoint(jointFrameId, inert, bodyInJoint, nameOfBody);

urdfVisitor.model.armature[static_cast<Eigen::Index>(joint_id) - 1] = rangeCompo.armature;
urdfVisitor.model.armature.segment(urdfVisitor.model.joints[joint_id].idx_q(), urdfVisitor.model.joints[joint_id].nq()) = rangeCompo.armature;
}

FrameIndex previousFrameId = urdfVisitor.model.frames.size();
Expand Down
38 changes: 38 additions & 0 deletions unittest/mjcf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,44 @@ BOOST_AUTO_TEST_CASE(joint_and_inertias)
BOOST_CHECK(model_m.inertias[1].isApprox(real_inertia));
}

BOOST_AUTO_TEST_CASE(armature)
{
typedef pinocchio::SE3::Vector3 Vector3;
typedef pinocchio::SE3::Matrix3 Matrix3;

std::istringstream xmlData(R"(
<mujoco model="model_RX">
<worldbody>
<body name="link0">
<body name="link1" pos="0 0 0">
<joint name="joint1" type="hinge" axis="1 0 0" armature="1.3"/>
<joint name="joint2" type="hinge" axis="0 1 0" armature="2.4"/>
<joint name="joint3" type="hinge" axis="0 0 1" armature="0.4"/>
<body pos=".2 0 0" name="body2">
<joint type="ball" armature=".1"/>
</body>
</body>
</body>
</worldbody>
</mujoco>)");

auto namefile = createTempFile(xmlData);

typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
pinocchio::Model model_m;
MjcfGraph::UrdfVisitor visitor(model_m);

MjcfGraph graph(visitor, "fakeMjcf");
graph.parseGraphFromXML(namefile.name());
graph.parseRootTree();

Eigen::VectorXd armature_real(model_m.nv);
armature_real << 1.3, 2.4, 0.4, 0.1, 0.1, 0.1;

for (size_t i = 0; i < size_t(model_m.nv); i++)
BOOST_CHECK_EQUAL(model_m.armature[i], armature_real[i]);
}

// Test reference positions and how it's included in keyframe
BOOST_AUTO_TEST_CASE(reference_positions)
{
Expand Down
Loading