Skip to content

Commit f96f3e1

Browse files
yuvaltassacopybara-github
authored andcommitted
Add XML compiler/saveinertial flag. Fixes #2405
PiperOrigin-RevId: 743607654 Change-Id: I1f2e61be89b79c1995e079f36aa285096f9fb441
1 parent 8941f56 commit f96f3e1

File tree

11 files changed

+47
-10
lines changed

11 files changed

+47
-10
lines changed

doc/XMLreference.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,10 @@ has any effect. The settings here are global and apply to the entire model.
832832
necessary to adjust this attribute and the geom-specific groups so as to exclude world geoms from the inertial
833833
computation.
834834

835+
.. _compiler-saveinertial:
836+
837+
:at:`saveinertial`: :at-val:`[false, true], "false"`
838+
If set to "true", the compiler will save explicit :ref:`inertial <body-inerital>` clauses for all bodies.
835839

836840
.. _compiler-lengthrange:
837841

doc/XMLschema.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
5555
| | | | :ref:`discardvisual<compiler-discardvisual>` | :ref:`usethread<compiler-usethread>` | :ref:`fusestatic<compiler-fusestatic>` | :ref:`inertiafromgeom<compiler-inertiafromgeom>` | |
5656
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
57-
| | | | :ref:`inertiagrouprange<compiler-inertiagrouprange>` | :ref:`assetdir<compiler-assetdir>` | :ref:`alignfree<compiler-alignfree>` | | |
57+
| | | | :ref:`inertiagrouprange<compiler-inertiagrouprange>` | :ref:`saveinertial<compiler-saveinertial>` | :ref:`assetdir<compiler-assetdir>` | :ref:`alignfree<compiler-alignfree>` | |
5858
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
5959
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
6060
| |_| compiler |br| |_| |L| | | .. table:: |

doc/changelog.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ Upcoming version (not yet released)
1515

1616
General
1717
^^^^^^^
18-
- Add :ref:`orientation<body-composite-quat>` parameter to :ref:`composite<body-composite>`. Moreover, allow the
18+
- Added the :ref:`compiler/saveinertial<compiler-saveinertial>` flag, writing explicit inertial clauses for all
19+
bodies when saving to XML.
20+
- Added :ref:`orientation<body-composite-quat>` attribute to :ref:`composite<body-composite>`. Moreover, allow the
1921
composite to be the direct child of a frame.
2022

2123
Bug fixes

doc/includes/references.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,7 @@ typedef struct mjsCompiler_ { // compiler options
17361736
mjtByte fusestatic; // fuse static bodies with parent
17371737
int inertiafromgeom; // use geom inertias (mjtInertiaFromGeom)
17381738
int inertiagrouprange[2]; // range of geom groups used to compute inertia
1739+
mjtByte saveinertial; // save explicit inertial clause for all bodies to XML
17391740
int alignfree; // align free joints with inertial frame
17401741
mjLROpt LRopt; // options for lengthrange computation
17411742
} mjsCompiler;

include/mujoco/mjspec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ typedef struct mjsCompiler_ { // compiler options
138138
mjtByte fusestatic; // fuse static bodies with parent
139139
int inertiafromgeom; // use geom inertias (mjtInertiaFromGeom)
140140
int inertiagrouprange[2]; // range of geom groups used to compute inertia
141+
mjtByte saveinertial; // save explicit inertial clause for all bodies to XML
141142
int alignfree; // align free joints with inertial frame
142143
mjLROpt LRopt; // options for lengthrange computation
143144
} mjsCompiler;

python/mujoco/introspect/structs.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9137,6 +9137,11 @@
91379137
),
91389138
doc='range of geom groups used to compute inertia',
91399139
),
9140+
StructFieldDecl(
9141+
name='saveinertial',
9142+
type=ValueType(name='mjtByte'),
9143+
doc='save explicit inertial clause for all bodies to XML',
9144+
),
91409145
StructFieldDecl(
91419146
name='alignfree',
91429147
type=ValueType(name='int'),

src/user/user_init.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ void mjs_defaultSpec(mjSpec* spec) {
4242
spec->compiler.usethread = 1;
4343
spec->compiler.inertiafromgeom = mjINERTIAFROMGEOM_AUTO;
4444
spec->compiler.inertiagrouprange[1] = mjNGROUP-1;
45+
spec->compiler.saveinertial = 0;
4546
mj_defaultLROpt(&spec->compiler.LRopt);
4647

4748
// engine data

src/xml/xml_native_reader.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,10 @@ static void UpdateString(string& psuffix, int count, int i) {
9797
const char* MJCF[nMJCF][mjXATTRNUM] = {
9898
{"mujoco", "!", "1", "model"},
9999
{"<"},
100-
{"compiler", "*", "19", "autolimits", "boundmass", "boundinertia", "settotalmass",
100+
{"compiler", "*", "20", "autolimits", "boundmass", "boundinertia", "settotalmass",
101101
"balanceinertia", "strippath", "coordinate", "angle", "fitaabb", "eulerseq",
102-
"meshdir", "texturedir", "discardvisual", "usethread",
103-
"fusestatic", "inertiafromgeom", "inertiagrouprange", "assetdir", "alignfree"},
102+
"meshdir", "texturedir", "discardvisual", "usethread", "fusestatic", "inertiafromgeom",
103+
"inertiagrouprange", "saveinertial", "assetdir", "alignfree"},
104104
{"<"},
105105
{"lengthrange", "?", "10", "mode", "useexisting", "uselimit",
106106
"accel", "maxforce", "timeconst", "timestep",
@@ -1015,6 +1015,9 @@ void mjXReader::Compiler(XMLElement* section, mjSpec* spec) {
10151015
if (MapValue(section, "alignfree", &n, bool_map, 2)) {
10161016
spec->compiler.alignfree = (n == 1);
10171017
}
1018+
if (MapValue(section, "saveinertial", &n, bool_map, 2)) {
1019+
spec->compiler.saveinertial = (n == 1);
1020+
}
10181021

10191022
// lengthrange subelement
10201023
XMLElement* elem = FindSubElem(section, "lengthrange");

src/xml/xml_native_writer.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1632,7 +1632,8 @@ void mjXWriter::Body(XMLElement* elem, mjCBody* body, mjCFrame* frame, string_vi
16321632
WriteVector(elem, "user", body->get_userdata());
16331633

16341634
// write inertial
1635-
if (body->explicitinertial && model->compiler.inertiafromgeom != mjINERTIAFROMGEOM_TRUE) {
1635+
if (model->compiler.saveinertial ||
1636+
(body->explicitinertial && model->compiler.inertiafromgeom != mjINERTIAFROMGEOM_TRUE)) {
16361637
XMLElement* inertial = InsertEnd(elem, "inertial");
16371638
WriteAttr(inertial, "pos", 3, body->ipos);
16381639
WriteAttr(inertial, "quat", 4, body->iquat, unitq);

test/xml/xml_native_writer_test.cc

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include <array>
2323
#include <clocale>
2424
#include <cstdio>
25-
#include <filesystem>
25+
#include <filesystem> // NOLINT(build/c++17)
2626
#include <string>
2727
#include <vector>
2828

@@ -32,7 +32,6 @@
3232
#include <mujoco/mjmodel.h>
3333
#include <mujoco/mjtnum.h>
3434
#include <mujoco/mujoco.h>
35-
#include "src/cc/array_safety.h"
3635
#include "src/xml/xml_numeric_format.h"
3736
#include "test/fixture.h"
3837

@@ -135,6 +134,23 @@ TEST_F(XMLWriterTest, SavesDisableSensor) {
135134
mj_deleteModel(model);
136135
}
137136

137+
TEST_F(XMLWriterTest, SavesInertial) {
138+
static constexpr char xml[] = R"(
139+
<mujoco>
140+
<compiler saveinertial="true"/>
141+
<worldbody>
142+
<body>
143+
<geom type="box" size=".05 .05 .05"/>
144+
</body>
145+
</worldbody>
146+
</mujoco>
147+
)";
148+
mjModel* model = LoadModelFromString(xml);
149+
std::string saved_xml = SaveAndReadXml(model);
150+
EXPECT_THAT(saved_xml, HasSubstr("mass=\"1\""));
151+
mj_deleteModel(model);
152+
}
153+
138154
TEST_F(XMLWriterTest, EmptyUserSensor) {
139155
static constexpr char xml[] = R"(
140156
<mujoco>
@@ -957,8 +973,10 @@ TEST_F(XMLWriterTest, WritesSkin) {
957973
ASSERT_THAT(model, NotNull());
958974
EXPECT_THAT(model->nskin, 1);
959975

960-
mjModel* mtemp = LoadModelFromString(SaveAndReadXml(model));
961-
ASSERT_THAT(mtemp, NotNull());
976+
char error[1024];
977+
mjModel* mtemp = LoadModelFromString(SaveAndReadXml(model),
978+
error, sizeof(error));
979+
ASSERT_THAT(mtemp, NotNull()) << error;
962980
EXPECT_THAT(mtemp->nskin, 1);
963981

964982
mj_deleteModel(model);

0 commit comments

Comments
 (0)