Add XML compiler/saveinertial flag. Fixes #2405
PiperOrigin-RevId: 743607654 Change-Id: I1f2e61be89b79c1995e079f36aa285096f9fb441
This commit is contained in:
committed by
Copybara-Service
parent
8941f56e86
commit
f96f3e1c22
@@ -832,6 +832,10 @@ has any effect. The settings here are global and apply to the entire model.
|
|||||||
necessary to adjust this attribute and the geom-specific groups so as to exclude world geoms from the inertial
|
necessary to adjust this attribute and the geom-specific groups so as to exclude world geoms from the inertial
|
||||||
computation.
|
computation.
|
||||||
|
|
||||||
|
.. _compiler-saveinertial:
|
||||||
|
|
||||||
|
:at:`saveinertial`: :at-val:`[false, true], "false"`
|
||||||
|
If set to "true", the compiler will save explicit :ref:`inertial <body-inerital>` clauses for all bodies.
|
||||||
|
|
||||||
.. _compiler-lengthrange:
|
.. _compiler-lengthrange:
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@
|
|||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`discardvisual<compiler-discardvisual>` | :ref:`usethread<compiler-usethread>` | :ref:`fusestatic<compiler-fusestatic>` | :ref:`inertiafromgeom<compiler-inertiafromgeom>` | |
|
| | | | :ref:`discardvisual<compiler-discardvisual>` | :ref:`usethread<compiler-usethread>` | :ref:`fusestatic<compiler-fusestatic>` | :ref:`inertiafromgeom<compiler-inertiafromgeom>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`inertiagrouprange<compiler-inertiagrouprange>` | :ref:`assetdir<compiler-assetdir>` | :ref:`alignfree<compiler-alignfree>` | | |
|
| | | | :ref:`inertiagrouprange<compiler-inertiagrouprange>` | :ref:`saveinertial<compiler-saveinertial>` | :ref:`assetdir<compiler-assetdir>` | :ref:`alignfree<compiler-alignfree>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| |_| compiler |br| |_| |L| | | .. table:: |
|
| |_| compiler |br| |_| |L| | | .. table:: |
|
||||||
|
|||||||
+3
-1
@@ -15,7 +15,9 @@ Upcoming version (not yet released)
|
|||||||
|
|
||||||
General
|
General
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
- Add :ref:`orientation<body-composite-quat>` parameter to :ref:`composite<body-composite>`. Moreover, allow the
|
- Added the :ref:`compiler/saveinertial<compiler-saveinertial>` flag, writing explicit inertial clauses for all
|
||||||
|
bodies when saving to XML.
|
||||||
|
- Added :ref:`orientation<body-composite-quat>` attribute to :ref:`composite<body-composite>`. Moreover, allow the
|
||||||
composite to be the direct child of a frame.
|
composite to be the direct child of a frame.
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
|
|||||||
@@ -1736,6 +1736,7 @@ typedef struct mjsCompiler_ { // compiler options
|
|||||||
mjtByte fusestatic; // fuse static bodies with parent
|
mjtByte fusestatic; // fuse static bodies with parent
|
||||||
int inertiafromgeom; // use geom inertias (mjtInertiaFromGeom)
|
int inertiafromgeom; // use geom inertias (mjtInertiaFromGeom)
|
||||||
int inertiagrouprange[2]; // range of geom groups used to compute inertia
|
int inertiagrouprange[2]; // range of geom groups used to compute inertia
|
||||||
|
mjtByte saveinertial; // save explicit inertial clause for all bodies to XML
|
||||||
int alignfree; // align free joints with inertial frame
|
int alignfree; // align free joints with inertial frame
|
||||||
mjLROpt LRopt; // options for lengthrange computation
|
mjLROpt LRopt; // options for lengthrange computation
|
||||||
} mjsCompiler;
|
} mjsCompiler;
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ typedef struct mjsCompiler_ { // compiler options
|
|||||||
mjtByte fusestatic; // fuse static bodies with parent
|
mjtByte fusestatic; // fuse static bodies with parent
|
||||||
int inertiafromgeom; // use geom inertias (mjtInertiaFromGeom)
|
int inertiafromgeom; // use geom inertias (mjtInertiaFromGeom)
|
||||||
int inertiagrouprange[2]; // range of geom groups used to compute inertia
|
int inertiagrouprange[2]; // range of geom groups used to compute inertia
|
||||||
|
mjtByte saveinertial; // save explicit inertial clause for all bodies to XML
|
||||||
int alignfree; // align free joints with inertial frame
|
int alignfree; // align free joints with inertial frame
|
||||||
mjLROpt LRopt; // options for lengthrange computation
|
mjLROpt LRopt; // options for lengthrange computation
|
||||||
} mjsCompiler;
|
} mjsCompiler;
|
||||||
|
|||||||
@@ -9137,6 +9137,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='range of geom groups used to compute inertia',
|
doc='range of geom groups used to compute inertia',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='saveinertial',
|
||||||
|
type=ValueType(name='mjtByte'),
|
||||||
|
doc='save explicit inertial clause for all bodies to XML',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='alignfree',
|
name='alignfree',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ void mjs_defaultSpec(mjSpec* spec) {
|
|||||||
spec->compiler.usethread = 1;
|
spec->compiler.usethread = 1;
|
||||||
spec->compiler.inertiafromgeom = mjINERTIAFROMGEOM_AUTO;
|
spec->compiler.inertiafromgeom = mjINERTIAFROMGEOM_AUTO;
|
||||||
spec->compiler.inertiagrouprange[1] = mjNGROUP-1;
|
spec->compiler.inertiagrouprange[1] = mjNGROUP-1;
|
||||||
|
spec->compiler.saveinertial = 0;
|
||||||
mj_defaultLROpt(&spec->compiler.LRopt);
|
mj_defaultLROpt(&spec->compiler.LRopt);
|
||||||
|
|
||||||
// engine data
|
// engine data
|
||||||
|
|||||||
@@ -97,10 +97,10 @@ static void UpdateString(string& psuffix, int count, int i) {
|
|||||||
const char* MJCF[nMJCF][mjXATTRNUM] = {
|
const char* MJCF[nMJCF][mjXATTRNUM] = {
|
||||||
{"mujoco", "!", "1", "model"},
|
{"mujoco", "!", "1", "model"},
|
||||||
{"<"},
|
{"<"},
|
||||||
{"compiler", "*", "19", "autolimits", "boundmass", "boundinertia", "settotalmass",
|
{"compiler", "*", "20", "autolimits", "boundmass", "boundinertia", "settotalmass",
|
||||||
"balanceinertia", "strippath", "coordinate", "angle", "fitaabb", "eulerseq",
|
"balanceinertia", "strippath", "coordinate", "angle", "fitaabb", "eulerseq",
|
||||||
"meshdir", "texturedir", "discardvisual", "usethread",
|
"meshdir", "texturedir", "discardvisual", "usethread", "fusestatic", "inertiafromgeom",
|
||||||
"fusestatic", "inertiafromgeom", "inertiagrouprange", "assetdir", "alignfree"},
|
"inertiagrouprange", "saveinertial", "assetdir", "alignfree"},
|
||||||
{"<"},
|
{"<"},
|
||||||
{"lengthrange", "?", "10", "mode", "useexisting", "uselimit",
|
{"lengthrange", "?", "10", "mode", "useexisting", "uselimit",
|
||||||
"accel", "maxforce", "timeconst", "timestep",
|
"accel", "maxforce", "timeconst", "timestep",
|
||||||
@@ -1015,6 +1015,9 @@ void mjXReader::Compiler(XMLElement* section, mjSpec* spec) {
|
|||||||
if (MapValue(section, "alignfree", &n, bool_map, 2)) {
|
if (MapValue(section, "alignfree", &n, bool_map, 2)) {
|
||||||
spec->compiler.alignfree = (n == 1);
|
spec->compiler.alignfree = (n == 1);
|
||||||
}
|
}
|
||||||
|
if (MapValue(section, "saveinertial", &n, bool_map, 2)) {
|
||||||
|
spec->compiler.saveinertial = (n == 1);
|
||||||
|
}
|
||||||
|
|
||||||
// lengthrange subelement
|
// lengthrange subelement
|
||||||
XMLElement* elem = FindSubElem(section, "lengthrange");
|
XMLElement* elem = FindSubElem(section, "lengthrange");
|
||||||
|
|||||||
@@ -1632,7 +1632,8 @@ void mjXWriter::Body(XMLElement* elem, mjCBody* body, mjCFrame* frame, string_vi
|
|||||||
WriteVector(elem, "user", body->get_userdata());
|
WriteVector(elem, "user", body->get_userdata());
|
||||||
|
|
||||||
// write inertial
|
// write inertial
|
||||||
if (body->explicitinertial && model->compiler.inertiafromgeom != mjINERTIAFROMGEOM_TRUE) {
|
if (model->compiler.saveinertial ||
|
||||||
|
(body->explicitinertial && model->compiler.inertiafromgeom != mjINERTIAFROMGEOM_TRUE)) {
|
||||||
XMLElement* inertial = InsertEnd(elem, "inertial");
|
XMLElement* inertial = InsertEnd(elem, "inertial");
|
||||||
WriteAttr(inertial, "pos", 3, body->ipos);
|
WriteAttr(inertial, "pos", 3, body->ipos);
|
||||||
WriteAttr(inertial, "quat", 4, body->iquat, unitq);
|
WriteAttr(inertial, "quat", 4, body->iquat, unitq);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <filesystem>
|
#include <filesystem> // NOLINT(build/c++17)
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -32,7 +32,6 @@
|
|||||||
#include <mujoco/mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
#include <mujoco/mjtnum.h>
|
#include <mujoco/mjtnum.h>
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "src/cc/array_safety.h"
|
|
||||||
#include "src/xml/xml_numeric_format.h"
|
#include "src/xml/xml_numeric_format.h"
|
||||||
#include "test/fixture.h"
|
#include "test/fixture.h"
|
||||||
|
|
||||||
@@ -135,6 +134,23 @@ TEST_F(XMLWriterTest, SavesDisableSensor) {
|
|||||||
mj_deleteModel(model);
|
mj_deleteModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(XMLWriterTest, SavesInertial) {
|
||||||
|
static constexpr char xml[] = R"(
|
||||||
|
<mujoco>
|
||||||
|
<compiler saveinertial="true"/>
|
||||||
|
<worldbody>
|
||||||
|
<body>
|
||||||
|
<geom type="box" size=".05 .05 .05"/>
|
||||||
|
</body>
|
||||||
|
</worldbody>
|
||||||
|
</mujoco>
|
||||||
|
)";
|
||||||
|
mjModel* model = LoadModelFromString(xml);
|
||||||
|
std::string saved_xml = SaveAndReadXml(model);
|
||||||
|
EXPECT_THAT(saved_xml, HasSubstr("mass=\"1\""));
|
||||||
|
mj_deleteModel(model);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(XMLWriterTest, EmptyUserSensor) {
|
TEST_F(XMLWriterTest, EmptyUserSensor) {
|
||||||
static constexpr char xml[] = R"(
|
static constexpr char xml[] = R"(
|
||||||
<mujoco>
|
<mujoco>
|
||||||
@@ -957,8 +973,10 @@ TEST_F(XMLWriterTest, WritesSkin) {
|
|||||||
ASSERT_THAT(model, NotNull());
|
ASSERT_THAT(model, NotNull());
|
||||||
EXPECT_THAT(model->nskin, 1);
|
EXPECT_THAT(model->nskin, 1);
|
||||||
|
|
||||||
mjModel* mtemp = LoadModelFromString(SaveAndReadXml(model));
|
char error[1024];
|
||||||
ASSERT_THAT(mtemp, NotNull());
|
mjModel* mtemp = LoadModelFromString(SaveAndReadXml(model),
|
||||||
|
error, sizeof(error));
|
||||||
|
ASSERT_THAT(mtemp, NotNull()) << error;
|
||||||
EXPECT_THAT(mtemp->nskin, 1);
|
EXPECT_THAT(mtemp->nskin, 1);
|
||||||
|
|
||||||
mj_deleteModel(model);
|
mj_deleteModel(model);
|
||||||
|
|||||||
@@ -5765,6 +5765,7 @@ public unsafe struct mjsCompiler_ {
|
|||||||
public byte fusestatic;
|
public byte fusestatic;
|
||||||
public int inertiafromgeom;
|
public int inertiafromgeom;
|
||||||
public fixed int inertiagrouprange[2];
|
public fixed int inertiagrouprange[2];
|
||||||
|
public byte saveinertial;
|
||||||
public int alignfree;
|
public int alignfree;
|
||||||
public mjLROpt_ LRopt;
|
public mjLROpt_ LRopt;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user