Add kv damping attribute to position and intvelocity actuator shortcuts.

PiperOrigin-RevId: 588377097
Change-Id: I8ded2ff982e52ed8673019979e29b706ef65c743
This commit is contained in:
Yuval Tassa
2023-12-06 04:27:34 -08:00
committed by Copybara-Service
parent b3ccf67ebf
commit 762371c3e4
8 changed files with 250 additions and 142 deletions
+28 -11
View File
@@ -5317,13 +5317,13 @@ This element does not have custom attributes. It only has common attributes, whi
This element creates a position servo. The underlying :el:`general` attributes are set as follows: This element creates a position servo. The underlying :el:`general` attributes are set as follows:
========= ======= ========= ======= ========= ======= ========= =========
Attribute Setting Attribute Setting Attribute Setting Attribute Setting
========= ======= ========= ======= ========= ======= ========= =========
dyntype none dynprm 1 0 0 dyntype none dynprm 1 0 0
gaintype fixed gainprm kp 0 0 gaintype fixed gainprm kp 0 0
biastype affine biasprm 0 -kp 0 biastype affine biasprm 0 -kp -kv
========= ======= ========= ======= ========= ======= ========= =========
This element has one custom attribute in addition to the common attributes: This element has one custom attribute in addition to the common attributes:
@@ -5377,6 +5377,11 @@ This element has one custom attribute in addition to the common attributes:
:at:`kp`: :at-val:`real, "1"` :at:`kp`: :at-val:`real, "1"`
Position feedback gain. Position feedback gain.
.. _actuator-position-kv:
:at:`kv`: :at-val:`real, "0"`
Damping applied by the actuator.
When using this attribute, it is recommended to use the implicitfast or implicit :ref:`integrators<geIntegration>`.
.. _actuator-velocity: .. _actuator-velocity:
@@ -5385,7 +5390,9 @@ This element has one custom attribute in addition to the common attributes:
This element creates a velocity servo. Note that in order create a PD controller, one has to define two actuators: a This element creates a velocity servo. Note that in order create a PD controller, one has to define two actuators: a
position servo and a velocity servo. This is because MuJoCo actuators are SISO while a PD controller takes two control position servo and a velocity servo. This is because MuJoCo actuators are SISO while a PD controller takes two control
inputs (reference position and reference velocity). The underlying :el:`general` attributes are set as follows: inputs (reference position and reference velocity).
When using this actuator, it is recommended to use the implicitfast or implicit :ref:`integrators<geIntegration>`.
The underlying :el:`general` attributes are set as follows:
========= ======= ========= ======= ========= ======= ========= =======
Attribute Setting Attribute Setting Attribute Setting Attribute Setting
@@ -5456,14 +5463,14 @@ This element creates an integrated-velocity servo. For more information, see the
:ref:`Activation clamping <CActRange>` section of the Modeling chapter. The underlying :ref:`Activation clamping <CActRange>` section of the Modeling chapter. The underlying
:el:`general` attributes are set as follows: :el:`general` attributes are set as follows:
========== =========== ========= ======= ========== =========== ========= =========
Attribute Setting Attribute Setting Attribute Setting Attribute Setting
========== =========== ========= ======= ========== =========== ========= =========
dyntype integrator dynprm 1 0 0 dyntype integrator dynprm 1 0 0
gaintype fixed gainprm kp 0 0 gaintype fixed gainprm kp 0 0
biastype affine biasprm 0 -kp 0 biastype affine biasprm 0 -kp -kv
actlimited true actlimited true
========== =========== ========= ======= ========== =========== ========= =========
This element has one custom attribute in addition to the common attributes: This element has one custom attribute in addition to the common attributes:
@@ -5518,6 +5525,11 @@ This element has one custom attribute in addition to the common attributes:
:at:`kp`: :at-val:`real, "1"` :at:`kp`: :at-val:`real, "1"`
Position feedback gain. Position feedback gain.
.. _actuator-intvelocity-kv:
:at:`kv`: :at-val:`real, "0"`
Damping applied by the actuator.
When using this attribute, it is recommended to use the implicitfast or implicit :ref:`integrators<geIntegration>`.
.. _actuator-damper: .. _actuator-damper:
@@ -5525,8 +5537,9 @@ This element has one custom attribute in addition to the common attributes:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This element is an active damper which produces a force proportional to both velocity and control: ``F = - kv * velocity This element is an active damper which produces a force proportional to both velocity and control: ``F = - kv * velocity
* control``, where ``kv`` must be nonnegative. :at:`ctrlrange` is required and must also be nonnegative. The underlying * control``, where ``kv`` must be nonnegative. :at:`ctrlrange` is required and must also be nonnegative.
:el:`general` attributes are set as follows: When using this actuator, it is recommended to use the implicitfast or implicit :ref:`integrators<geIntegration>`.
The underlying :el:`general` attributes are set as follows:
=========== ======= ========= ======= =========== ======= ========= =======
Attribute Setting Attribute Setting Attribute Setting Attribute Setting
@@ -7680,6 +7693,8 @@ slidersite, cranksite.
.. _default-position-kp: .. _default-position-kp:
.. _default-position-kv:
:el-prefix:`default/` |-| **position** (?) :el-prefix:`default/` |-| **position** (?)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7736,6 +7751,8 @@ tendon, slidersite, cranksite.
.. _default-intvelocity-kp: .. _default-intvelocity-kp:
.. _default-intvelocity-kv:
:el-prefix:`default/` |-| **intvelocity** (?) :el-prefix:`default/` |-| **intvelocity** (?)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+5 -3
View File
@@ -778,7 +778,7 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`jointinparent<actuator-position-jointinparent>` | :ref:`tendon<actuator-position-tendon>` | :ref:`slidersite<actuator-position-slidersite>` | :ref:`cranksite<actuator-position-cranksite>` | | | | | | :ref:`jointinparent<actuator-position-jointinparent>` | :ref:`tendon<actuator-position-tendon>` | :ref:`slidersite<actuator-position-slidersite>` | :ref:`cranksite<actuator-position-cranksite>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`site<actuator-position-site>` | :ref:`refsite<actuator-position-refsite>` | :ref:`kp<actuator-position-kp>` | | | | | | | :ref:`site<actuator-position-site>` | :ref:`refsite<actuator-position-refsite>` | :ref:`kp<actuator-position-kp>` | :ref:`kv<actuator-position-kv>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| actuator |br| |_| |L| | | .. table:: | | |_| actuator |br| |_| |L| | | .. table:: |
@@ -810,6 +810,8 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`cranksite<actuator-intvelocity-cranksite>` | :ref:`site<actuator-intvelocity-site>` | :ref:`refsite<actuator-intvelocity-refsite>` | :ref:`kp<actuator-intvelocity-kp>` | | | | | | :ref:`cranksite<actuator-intvelocity-cranksite>` | :ref:`site<actuator-intvelocity-site>` | :ref:`refsite<actuator-intvelocity-refsite>` | :ref:`kp<actuator-intvelocity-kp>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`kv<actuator-intvelocity-kv>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| actuator |br| |_| |L| | | .. table:: | | |_| actuator |br| |_| |L| | | .. table:: |
| :ref:`damper | \* | :class: mjcf-attributes | | :ref:`damper | \* | :class: mjcf-attributes |
@@ -1440,7 +1442,7 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`gear<default-position-gear>` | :ref:`cranklength<default-position-cranklength>` | :ref:`user<default-position-user>` | :ref:`group<default-position-group>` | | | | | | :ref:`gear<default-position-gear>` | :ref:`cranklength<default-position-cranklength>` | :ref:`user<default-position-user>` | :ref:`group<default-position-group>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`kp<default-position-kp>` | | | | | | | | | :ref:`kp<default-position-kp>` | :ref:`kv<default-position-kv>` | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| default |br| |_| |L| | | .. table:: | | |_| default |br| |_| |L| | | .. table:: |
@@ -1462,7 +1464,7 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`actrange<default-intvelocity-actrange>` | :ref:`gear<default-intvelocity-gear>` | :ref:`cranklength<default-intvelocity-cranklength>` | :ref:`user<default-intvelocity-user>` | | | | | | :ref:`actrange<default-intvelocity-actrange>` | :ref:`gear<default-intvelocity-gear>` | :ref:`cranklength<default-intvelocity-cranklength>` | :ref:`user<default-intvelocity-user>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`group<default-intvelocity-group>` | :ref:`kp<default-intvelocity-kp>` | | | | | | | | :ref:`group<default-intvelocity-group>` | :ref:`kp<default-intvelocity-kp>` | :ref:`kv<default-intvelocity-kv>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| default |br| |_| |L| | | .. table:: | | |_| default |br| |_| |L| | | .. table:: |
+4
View File
@@ -12,6 +12,10 @@ General
robust for very small or large geom sizes. robust for very small or large geom sizes.
- Added :ref:`frame<frame>` to MJCF, a :ref:`meta-element<meta-element>` which defines a pure coordinate transformation - Added :ref:`frame<frame>` to MJCF, a :ref:`meta-element<meta-element>` which defines a pure coordinate transformation
on its direct children, without requiring a :ref:`body<body>`. on its direct children, without requiring a :ref:`body<body>`.
- Added the :at:`kv` attribute to the :ref:`position<actuator-position>` and :ref:`intvelocity<actuator-intvelocity>`
actuators, for specifying actuator-applied damping. This can be used to implement a PD controller with 0 reference
velocity. When using this attribute, it is recommended to use the implicitfast or implicit
:ref:`integrators<geIntegration>`.
Plugins Plugins
^^^^^^^ ^^^^^^^
+1 -1
View File
@@ -3876,7 +3876,7 @@ void mjCActuator::Compile(void) {
throw mjCError(this, "invalid control range for actuator '%s' (id = %d)", name.c_str(), id); throw mjCError(this, "invalid control range for actuator '%s' (id = %d)", name.c_str(), id);
} }
if (actrange[0]>=actrange[1] && actlimited) { if (actrange[0]>=actrange[1] && actlimited) {
throw mjCError(this, "invalid activation range for actuator '%s' (id = %d)", name.c_str(), id); throw mjCError(this, "invalid actrange for actuator '%s' (id = %d)", name.c_str(), id);
} }
if (actlimited && dyntype == mjDYN_NONE) { if (actlimited && dyntype == mjDYN_NONE) {
throw mjCError(this, "actrange specified but dyntype is 'none' in actuator '%s' (id = %d)", throw mjCError(this, "actrange specified but dyntype is 'none' in actuator '%s' (id = %d)",
+21 -30
View File
@@ -166,16 +166,16 @@ static const char* MJCF[nMJCF][mjXATTRNUM] = {
"dyntype", "gaintype", "biastype", "dynprm", "gainprm", "biasprm", "actearly"}, "dyntype", "gaintype", "biastype", "dynprm", "gainprm", "biasprm", "actearly"},
{"motor", "?", "8", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", {"motor", "?", "8", "ctrllimited", "forcelimited", "ctrlrange", "forcerange",
"gear", "cranklength", "user", "group"}, "gear", "cranklength", "user", "group"},
{"position", "?", "9", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", {"position", "?", "10", "ctrllimited", "forcelimited", "ctrlrange", "forcerange",
"gear", "cranklength", "user", "group", "gear", "cranklength", "user", "group",
"kp"}, "kp", "kv"},
{"velocity", "?", "9", "ctrllimited", "forcelimited", "ctrlrange", "forcerange", {"velocity", "?", "9", "ctrllimited", "forcelimited", "ctrlrange", "forcerange",
"gear", "cranklength", "user", "group", "gear", "cranklength", "user", "group",
"kv"}, "kv"},
{"intvelocity", "?", "10", "ctrllimited", "forcelimited", {"intvelocity", "?", "11", "ctrllimited", "forcelimited",
"ctrlrange", "forcerange", "actrange", "ctrlrange", "forcerange", "actrange",
"gear", "cranklength", "user", "group", "gear", "cranklength", "user", "group",
"kp"}, "kp", "kv"},
{"damper", "?", "8", "forcelimited", "ctrlrange", "forcerange", {"damper", "?", "8", "forcelimited", "ctrlrange", "forcerange",
"gear", "cranklength", "user", "group", "gear", "cranklength", "user", "group",
"kv"}, "kv"},
@@ -379,22 +379,22 @@ static const char* MJCF[nMJCF][mjXATTRNUM] = {
"ctrllimited", "forcelimited", "ctrlrange", "forcerange", "ctrllimited", "forcelimited", "ctrlrange", "forcerange",
"lengthrange", "gear", "cranklength", "user", "lengthrange", "gear", "cranklength", "user",
"joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite"}, "joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite"},
{"position", "*", "19", "name", "class", "group", {"position", "*", "20", "name", "class", "group",
"ctrllimited", "forcelimited", "ctrlrange", "forcerange", "ctrllimited", "forcelimited", "ctrlrange", "forcerange",
"lengthrange", "gear", "cranklength", "user", "lengthrange", "gear", "cranklength", "user",
"joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite", "joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite",
"kp"}, "kp", "kv"},
{"velocity", "*", "19", "name", "class", "group", {"velocity", "*", "19", "name", "class", "group",
"ctrllimited", "forcelimited", "ctrlrange", "forcerange", "ctrllimited", "forcelimited", "ctrlrange", "forcerange",
"lengthrange", "gear", "cranklength", "user", "lengthrange", "gear", "cranklength", "user",
"joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite", "joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite",
"kv"}, "kv"},
{"intvelocity", "*", "20", "name", "class", "group", {"intvelocity", "*", "21", "name", "class", "group",
"ctrllimited", "forcelimited", "ctrllimited", "forcelimited",
"ctrlrange", "forcerange", "actrange", "lengthrange", "ctrlrange", "forcerange", "actrange", "lengthrange",
"gear", "cranklength", "user", "gear", "cranklength", "user",
"joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite", "joint", "jointinparent", "tendon", "slidersite", "cranksite", "site", "refsite",
"kp"}, "kp", "kv"},
{"damper", "*", "18", "name", "class", "group", {"damper", "*", "18", "name", "class", "group",
"forcelimited", "ctrlrange", "forcerange", "forcelimited", "ctrlrange", "forcerange",
"lengthrange", "gear", "cranklength", "user", "lengthrange", "gear", "cranklength", "user",
@@ -1895,19 +1895,26 @@ void mjXReader::OneActuator(XMLElement* elem, mjCActuator* pact) {
pact->biastype = mjBIAS_NONE; pact->biastype = mjBIAS_NONE;
} }
// position servo // position or integrated velocity servo
else if (type=="position") { else if (type=="position" || type=="intvelocity") {
// clear bias
mjuu_zerovec(pact->biasprm, mjNBIAS);
// explicit attributes // explicit attributes
ReadAttr(elem, "kp", 1, pact->gainprm, text); ReadAttr(elem, "kp", 1, pact->gainprm, text);
pact->biasprm[1] = -pact->gainprm[0]; pact->biasprm[1] = -pact->gainprm[0];
if (ReadAttr(elem, "kv", 1, pact->biasprm + 2, text)) {
if (pact->biasprm[2] < 0)
throw mjXError(elem, "kv cannot be negative");
pact->biasprm[2] *= -1;
}
// implied parameters // implied parameters
pact->dyntype = mjDYN_NONE;
pact->gaintype = mjGAIN_FIXED; pact->gaintype = mjGAIN_FIXED;
pact->biastype = mjBIAS_AFFINE; pact->biastype = mjBIAS_AFFINE;
if (type=="intvelocity") {
pact->dyntype = mjDYN_INTEGRATOR;
pact->actlimited = 1;
}
} }
// velocity servo // velocity servo
@@ -1925,22 +1932,6 @@ void mjXReader::OneActuator(XMLElement* elem, mjCActuator* pact) {
pact->biastype = mjBIAS_AFFINE; pact->biastype = mjBIAS_AFFINE;
} }
// integrated velocity
else if (type=="intvelocity") {
// clear bias
mjuu_zerovec(pact->biasprm, mjNBIAS);
// explicit attributes
ReadAttr(elem, "kp", 1, pact->gainprm, text);
// implied parameters
pact->dyntype = mjDYN_INTEGRATOR;
pact->gaintype = mjGAIN_FIXED;
pact->biastype = mjBIAS_AFFINE;
pact->actlimited = 1;
pact->biasprm[1] = -pact->gainprm[0];
}
// damper // damper
else if (type=="damper") { else if (type=="damper") {
// clear gain // clear gain
+8 -8
View File
@@ -13,7 +13,7 @@
<default> <default>
<default class="translation"> <default class="translation">
<general gainprm="100" biasprm="0 -100 -10" biastype="affine" ctrlrange="-.25 .25"/> <position kp="100" kv="10" ctrlrange="-.25 .25"/>
</default> </default>
<default class="rotation"> <default class="rotation">
<!-- <!--
@@ -22,7 +22,7 @@
Increase this range to pi or bigger in order to see the instabillity. Increase this range to pi or bigger in order to see the instabillity.
See here for more details https://mujoco.readthedocs.io/en/latest/XMLreference.html#actuator See here for more details https://mujoco.readthedocs.io/en/latest/XMLreference.html#actuator
--> -->
<general gainprm=".5" biasprm="0 -.5 -.05" biastype="affine" ctrlrange="-1.571 1.571"/> <position kp=".5" kv=".05" ctrlrange="-1.571 1.571"/>
</default> </default>
<!-- <!--
Clamping the total actuator torque at the joints means that the motion produced by the Cartesian Clamping the total actuator torque at the joints means that the motion produced by the Cartesian
@@ -62,11 +62,11 @@
</worldbody> </worldbody>
<actuator> <actuator>
<general name="x" site="end_effector" refsite="reference" gear="1 0 0 0 0 0" class="translation"/> <position name="x" site="end_effector" refsite="reference" gear="1 0 0 0 0 0" class="translation"/>
<general name="y" site="end_effector" refsite="reference" gear="0 1 0 0 0 0" class="translation"/> <position name="y" site="end_effector" refsite="reference" gear="0 1 0 0 0 0" class="translation"/>
<general name="z" site="end_effector" refsite="reference" gear="0 0 1 0 0 0" class="translation"/> <position name="z" site="end_effector" refsite="reference" gear="0 0 1 0 0 0" class="translation"/>
<general name="rx" site="end_effector" refsite="reference" gear="0 0 0 1 0 0" class="rotation"/> <position name="rx" site="end_effector" refsite="reference" gear="0 0 0 1 0 0" class="rotation"/>
<general name="ry" site="end_effector" refsite="reference" gear="0 0 0 0 1 0" class="rotation"/> <position name="ry" site="end_effector" refsite="reference" gear="0 0 0 0 1 0" class="rotation"/>
<general name="rz" site="end_effector" refsite="reference" gear="0 0 0 0 0 1" class="rotation"/> <position name="rz" site="end_effector" refsite="reference" gear="0 0 0 0 0 1" class="rotation"/>
</actuator> </actuator>
</mujoco> </mujoco>
+2 -2
View File
@@ -940,7 +940,7 @@ TEST_F(ActRangeTest, ActRangeBad) {
std::array<char, 1024> error; std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size()); mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, IsNull()); ASSERT_THAT(model, IsNull());
EXPECT_THAT(error.data(), HasSubstr("invalid activation range")); EXPECT_THAT(error.data(), HasSubstr("invalid actrange"));
} }
TEST_F(ActRangeTest, ActRangeUndefined) { TEST_F(ActRangeTest, ActRangeUndefined) {
@@ -960,7 +960,7 @@ TEST_F(ActRangeTest, ActRangeUndefined) {
std::array<char, 1024> error; std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size()); mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, IsNull()); ASSERT_THAT(model, IsNull());
EXPECT_THAT(error.data(), HasSubstr("invalid activation range")); EXPECT_THAT(error.data(), HasSubstr("invalid actrange"));
} }
TEST_F(ActRangeTest, ActRangeNoDyntype) { TEST_F(ActRangeTest, ActRangeNoDyntype) {
+181 -87
View File
@@ -531,92 +531,6 @@ TEST_F(XMLReaderTest, ReadShellParameter) {
mj_deleteModel(model); mj_deleteModel(model);
} }
TEST_F(XMLReaderTest, ReadsDamper) {
static constexpr char xml[] = R"(
<mujoco>
<compiler autolimits="true"/>
<worldbody>
<body>
<geom size="1"/>
<joint name="jnt" type="slide" axis="1 0 0" range="-10 10"/>
</body>
</worldbody>
<actuator>
<damper joint="jnt" ctrlrange="0 1"/>
<general joint="jnt" ctrllimited="true" ctrlrange="0 1" gaintype="affine" biastype="none"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, NotNull());
EXPECT_THAT(model->actuator_gaintype[0], Eq(mjGAIN_AFFINE));
EXPECT_THAT(model->actuator_gaintype[1], Eq(mjGAIN_AFFINE));
EXPECT_THAT(model->actuator_biastype[0], Eq(mjBIAS_NONE));
EXPECT_THAT(model->actuator_biastype[1], Eq(mjBIAS_NONE));
mj_deleteModel(model);
}
TEST_F(XMLReaderTest, RequiresPoisitiveDamping) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body>
<geom size="1"/>
<joint name="jnt" type="slide" axis="1 0 0" range="-10 10"/>
</body>
</worldbody>
<actuator>
<damper joint="jnt" kv="-1"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, IsNull());
EXPECT_THAT(error.data(),
HasSubstr("damping coefficient cannot be negative"));
}
TEST_F(XMLReaderTest, RequiresControlRange) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body>
<geom size="1"/>
<joint name="jnt" type="slide" axis="1 0 0" range="-10 10" limited="true"/>
</body>
</worldbody>
<actuator>
<damper joint="jnt" kv="1"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, IsNull());
EXPECT_THAT(error.data(), HasSubstr("invalid control range"));
}
TEST_F(XMLReaderTest, PositiveControlRange) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body>
<geom size="1"/>
<joint name="jnt" type="slide" axis="1 0 0" range="-10 10"/>
</body>
</worldbody>
<actuator>
<damper joint="jnt" kv="1" ctrlrange="-1 0"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, IsNull());
EXPECT_THAT(error.data(), HasSubstr("control range cannot be negative"));
}
TEST_F(XMLReaderTest, ReadsSkinGroups) { TEST_F(XMLReaderTest, ReadsSkinGroups) {
static constexpr char xml[] = R"( static constexpr char xml[] = R"(
@@ -779,6 +693,186 @@ TEST_F(ActuatorTest, ReadsByte) {
using ActuatorParseTest = MujocoTest; using ActuatorParseTest = MujocoTest;
TEST_F(ActuatorParseTest, ReadsDamper) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body>
<geom size="1"/>
<joint name="jnt" type="slide" axis="1 0 0" range="-10 10"/>
</body>
</worldbody>
<actuator>
<damper joint="jnt" ctrlrange="0 1"/>
<general joint="jnt" ctrllimited="true" ctrlrange="0 1" gaintype="affine" biastype="none"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, NotNull());
EXPECT_THAT(model->actuator_gaintype[0], Eq(mjGAIN_AFFINE));
EXPECT_THAT(model->actuator_gaintype[1], Eq(mjGAIN_AFFINE));
EXPECT_THAT(model->actuator_biastype[0], Eq(mjBIAS_NONE));
EXPECT_THAT(model->actuator_biastype[1], Eq(mjBIAS_NONE));
mj_deleteModel(model);
}
TEST_F(ActuatorParseTest, DamperRequiresPositiveDamping) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body>
<geom size="1"/>
<joint name="jnt" type="slide" axis="1 0 0" range="-10 10"/>
</body>
</worldbody>
<actuator>
<damper joint="jnt" kv="-1"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, IsNull());
EXPECT_THAT(error.data(),
HasSubstr("damping coefficient cannot be negative"));
}
TEST_F(ActuatorParseTest, DamperRequiresControlRange) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body>
<geom size="1"/>
<joint name="jnt" type="slide" axis="1 0 0" range="-10 10" limited="true"/>
</body>
</worldbody>
<actuator>
<damper joint="jnt" kv="1"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, IsNull());
EXPECT_THAT(error.data(), HasSubstr("invalid control range"));
}
TEST_F(ActuatorParseTest, DamperPositiveControlRange) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body>
<geom size="1"/>
<joint name="jnt" type="slide" axis="1 0 0" range="-10 10"/>
</body>
</worldbody>
<actuator>
<damper joint="jnt" kv="1" ctrlrange="-1 0"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, IsNull());
EXPECT_THAT(error.data(), HasSubstr("control range cannot be negative"));
}
TEST_F(ActuatorParseTest, ReadsPositionIntvelKv) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body>
<geom size="1"/>
<joint name="jnt" type="slide" axis="1 0 0"/>
</body>
</worldbody>
<actuator>
<position joint="jnt" kv="2"/>
<intvelocity joint="jnt" actrange="-1 1" kv="3"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, NotNull());
EXPECT_THAT(model->actuator_biasprm[0*mjNBIAS + 2], Eq(-2.0));
EXPECT_THAT(model->actuator_biasprm[1*mjNBIAS + 2], Eq(-3.0));
mj_deleteModel(model);
}
TEST_F(ActuatorParseTest, RequirePositiveKv) {
static constexpr char xml[] = R"(
<mujoco>
<worldbody>
<body>
<geom size="1"/>
<joint name="jnt" type="slide" axis="1 0 0"/>
</body>
</worldbody>
<actuator>
<position joint="jnt" kv="-2"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, IsNull());
EXPECT_THAT(error.data(), HasSubstr("kv cannot be negative"));
}
TEST_F(ActuatorParseTest, PositionIntvelocityVelocityDefaultsPropagate) {
static constexpr char xml[] = R"(
<mujoco>
<default>
<default class="position">
<position kp="3" kv="4"/>
</default>
<default class="intvelocity">
<intvelocity kp="5" kv="6" actrange="-1 1"/>
</default>
<default class="velocity">
<velocity kv="7"/>
</default>
</default>
<worldbody>
<body>
<geom size="1"/>
<joint name="jnt" type="slide" axis="1 0 0"/>
</body>
</worldbody>
<actuator>
<position joint="jnt" class="position"/>
<intvelocity joint="jnt" class="intvelocity"/>
<velocity joint="jnt" class="velocity"/>
</actuator>
</mujoco>
)";
std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, NotNull()) << error.data();
EXPECT_EQ(model->actuator_gainprm[0*mjNGAIN + 0], 3.0);
EXPECT_EQ(model->actuator_biasprm[0*mjNBIAS + 1], -3.0);
EXPECT_EQ(model->actuator_biasprm[0*mjNBIAS + 2], -4.0);
EXPECT_EQ(model->actuator_gainprm[1*mjNGAIN + 0], 5.0);
EXPECT_EQ(model->actuator_biasprm[1*mjNBIAS + 1], -5.0);
EXPECT_EQ(model->actuator_biasprm[1*mjNBIAS + 2], -6.0);
EXPECT_EQ(model->actuator_gainprm[2*mjNGAIN + 0], 7.0);
EXPECT_EQ(model->actuator_biasprm[2*mjNBIAS + 1], 0.0);
EXPECT_EQ(model->actuator_biasprm[2*mjNBIAS + 2], -7.0);
for (int i = 0; i < model->nu; i++) {
for (int j = 3; j < mjNBIAS; j++) {
EXPECT_EQ(model->actuator_biasprm[i*mjNBIAS + j], 0.0);
}
for (int j = 3; j < mjNGAIN; j++) {
EXPECT_EQ(model->actuator_gainprm[i*mjNGAIN + j], 0.0);
}
}
mj_deleteModel(model);
}
TEST_F(ActuatorParseTest, IntvelocityCheckEquivalence) { TEST_F(ActuatorParseTest, IntvelocityCheckEquivalence) {
static constexpr char xml[] = R"( static constexpr char xml[] = R"(
<mujoco> <mujoco>
@@ -871,7 +965,7 @@ TEST_F(ActuatorParseTest, IntvelocityNoActrangeThrowsError) {
std::array<char, 1024> error; std::array<char, 1024> error;
mjModel* model = LoadModelFromString(xml, error.data(), error.size()); mjModel* model = LoadModelFromString(xml, error.data(), error.size());
ASSERT_THAT(model, IsNull()); ASSERT_THAT(model, IsNull());
EXPECT_THAT(error.data(), HasSubstr("invalid activation range for actuator")); EXPECT_THAT(error.data(), HasSubstr("invalid actrange for actuator"));
} }
TEST_F(ActuatorParseTest, IntvelocityDefaultsPropagate) { TEST_F(ActuatorParseTest, IntvelocityDefaultsPropagate) {