Allow partial specification of polycoef attribute of equality constraints.
- Usually the user only wants to tweak `polycoef[1]`, after this change `"0 2"` is equivalent to `"0 2 0 0 0"`. - Also improve documentation of this attribute. - Tighten margins of documentation display equations. PiperOrigin-RevId: 639720742 Change-Id: Ibafa0e093cebe1c1c75bf2e47ff3bd2ad7619414
This commit is contained in:
committed by
Copybara-Service
parent
14a3ce5ffa
commit
8fa0fea02d
@@ -4275,11 +4275,15 @@ joint types (slide and hinge) can be used.
|
||||
.. _equality-joint-polycoef:
|
||||
|
||||
:at:`polycoef`: :at-val:`real(5), "0 1 0 0 0"`
|
||||
Coefficients a0 ... a4 of the quartic polynomial. If the two joint values are y and x, and their reference positions
|
||||
(corresponding to the joint values in the initial model configuration) are y0 and x0, the constraint is:
|
||||
y-y0 = a0 + a1*(x-x0) + a2*(x-x0)^2 + a3*(x-x0)^3 + a4*(x-x0)^4.
|
||||
Omitting the second joint is equivalent to setting x = x0, in which case the constraint is y = y0 + a0.
|
||||
Coefficients :math:`a_0 \ldots a_4` of the quartic polynomial. If the joint values of :at:`joint1` and :at:`joint2`
|
||||
are respectively :math:`y` and :math:`x`, and their reference positions (corresponding to the joint values in the
|
||||
initial model configuration) are :math:`y_0` and :math:`x_0`, the constraint is:
|
||||
|
||||
.. math::
|
||||
y-y_0 = a_0 + a_1(x-x_0) + a_2(x-x_0)^2 + a_3(x-x_0)^3 + a_4(x-x_0)^4
|
||||
|
||||
Omitting :at:`joint2` is equivalent to setting :math:`x = x_0`, in which case the constraint is
|
||||
:math:`y = y_0 + a_0`.
|
||||
|
||||
.. _equality-tendon:
|
||||
|
||||
@@ -4315,7 +4319,7 @@ This element constrains the length of one tendon to be a quartic polynomial of a
|
||||
.. _equality-tendon-polycoef:
|
||||
|
||||
:at:`polycoef`: :at-val:`real(5), "0 1 0 0 0"`
|
||||
Same as in the equality/ :ref:`joint <equality-joint>` element above, but applied to tendon lengths instead of joint
|
||||
Same as in the :ref:`equality/joint <equality-joint>` element above, but applied to tendon lengths instead of joint
|
||||
positions.
|
||||
|
||||
|
||||
|
||||
@@ -260,6 +260,12 @@ dt .at {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
/* Reduce top and bottom margins around displayed KaTeX equations */
|
||||
.katex-display {
|
||||
margin-top: 0.3em;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
|
||||
details summary {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -1884,13 +1884,13 @@ void mjXReader::OneEquality(XMLElement* elem, mjsEquality* pequality) {
|
||||
case mjEQ_JOINT:
|
||||
ReadAttrTxt(elem, "joint1", name1, true);
|
||||
ReadAttrTxt(elem, "joint2", name2);
|
||||
ReadAttr(elem, "polycoef", 5, pequality->data, text);
|
||||
ReadAttr(elem, "polycoef", 5, pequality->data, text, false, false);
|
||||
break;
|
||||
|
||||
case mjEQ_TENDON:
|
||||
ReadAttrTxt(elem, "tendon1", name1, true);
|
||||
ReadAttrTxt(elem, "tendon2", name2);
|
||||
ReadAttr(elem, "polycoef", 5, pequality->data, text);
|
||||
ReadAttr(elem, "polycoef", 5, pequality->data, text, false, false);
|
||||
break;
|
||||
|
||||
case mjEQ_FLEX:
|
||||
|
||||
@@ -34,8 +34,13 @@
|
||||
namespace mujoco {
|
||||
namespace {
|
||||
|
||||
std::vector<mjtNum> AsVector(const mjtNum* array, int n) {
|
||||
return std::vector<mjtNum>(array, array + n);
|
||||
}
|
||||
|
||||
using ::std::string;
|
||||
using ::testing::AllOf;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Eq;
|
||||
using ::testing::FloatEq;
|
||||
using ::testing::HasSubstr;
|
||||
@@ -834,8 +839,43 @@ TEST_F(XMLReaderTest, IncludeAbsoluteTest) {
|
||||
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
// ------------------------ test frame parsing ---------------------------------
|
||||
|
||||
TEST_F(XMLReaderTest, ParsePolycoef) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<worldbody>
|
||||
<body>
|
||||
<joint name="0"/>
|
||||
<geom size="1"/>
|
||||
</body>
|
||||
<body>
|
||||
<joint name="1"/>
|
||||
<geom size="1"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
<equality>
|
||||
<joint joint1="0" joint2="1"/>
|
||||
<joint joint1="0" joint2="1" polycoef="2"/>
|
||||
<joint joint1="0" joint2="1" polycoef="3 4"/>
|
||||
<joint joint1="0" joint2="1" polycoef="5 6 7 8 9"/>
|
||||
</equality>
|
||||
</mujoco>
|
||||
)";
|
||||
std::array<char, 1024> error;
|
||||
mjModel* m = LoadModelFromString(xml, error.data(), error.size());
|
||||
EXPECT_THAT(m, NotNull()) << error.data();
|
||||
EXPECT_THAT(AsVector(m->eq_data + 0*mjNEQDATA, 5),
|
||||
ElementsAre(0, 1, 0, 0, 0));
|
||||
EXPECT_THAT(AsVector(m->eq_data + 1*mjNEQDATA, 5),
|
||||
ElementsAre(2, 1, 0, 0, 0));
|
||||
EXPECT_THAT(AsVector(m->eq_data + 2*mjNEQDATA, 5),
|
||||
ElementsAre(3, 4, 0, 0, 0));
|
||||
EXPECT_THAT(AsVector(m->eq_data + 3*mjNEQDATA, 5),
|
||||
ElementsAre(5, 6, 7, 8, 9));
|
||||
mj_deleteModel(m);
|
||||
}
|
||||
|
||||
// ------------------------ test frame parsing ---------------------------------
|
||||
TEST_F(XMLReaderTest, ParseFrame) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
|
||||
Reference in New Issue
Block a user