Add policies for global attribute conflict resolution upon attach

For example when loading parent_merge.xml:

```
WARNING: Attach conflict when attaching 'child' to 'parent_merge', policy is 'merge'
timestep: parent has 0.005, child has 0.002, taking the minimum
iterations: parent has 50, child has 100, taking the maximum
flag 'Damper': added from child
```

When loading parent_error.xml:

```
XML Error: Attach conflict when attaching 'child' to 'parent_error', policy is 'error'
timestep: parent has 0.005, child has 0.002
iterations: parent has 50, child has 100
Element 'attach', line 10
```
PiperOrigin-RevId: 933620810
Change-Id: Ib477863b5ef763474d27fb4be5a4148be1d5d500
This commit is contained in:
Yuval Tassa
2026-06-17 03:34:10 -07:00
committed by Copybara-Service
parent 30357c38a3
commit 410c73168c
37 changed files with 2705 additions and 449 deletions
+6
View File
@@ -128,6 +128,11 @@ typedef enum mjtOrientation_ { // type of orientation specifier
mjORIENTATION_EULER, // Euler angles
} mjtOrientation;
typedef enum mjtConflict_ { // conflict resolution for attach
mjCONFLICT_WARNING = 0, // keep parent, warn on conflict
mjCONFLICT_MERGE, // merge: min/max/error per field
mjCONFLICT_ERROR, // error on any conflict
} mjtConflict;
typedef enum mjtCTimer_ { // compiler timing categories
// top-level timers (wall-clock)
@@ -171,6 +176,7 @@ typedef struct mjsCompiler_ { // compiler options
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 conflict; // conflict resolution for attach (mjtConflict)
mjLROpt LRopt; // options for lengthrange computation
mjString* meshdir; // mesh and hfield directory
mjString* texturedir; // texture directory
+21 -21
View File
@@ -25,27 +25,27 @@
//-------------------------------- mjsCompiler -----------------------------------------------------
#define MJSCOMPILER_FIELDS \
X ( mjtByte, autolimits, 1 ) \
X ( double, boundmass, 1 ) \
X ( double, boundinertia, 1 ) \
X ( double, settotalmass, 1 ) \
X ( mjtByte, balanceinertia, 1 ) \
X ( mjtByte, fitaabb, 1 ) \
X ( mjtByte, degree, 1 ) \
XVEC( char, eulerseq, 3 ) \
X ( mjtByte, discardvisual, 1 ) \
X ( mjtByte, usethread, 1 ) \
X ( mjtByte, fusestatic, 1 ) \
X ( int, inertiafromgeom, 1 ) \
XVEC( int, inertiagrouprange, 2 ) \
X ( mjtByte, saveinertial, 1 ) \
X ( int, alignfree, 1 ) \
X ( mjLROpt, LRopt, 1 ) \
X ( mjString*, meshdir, 1 ) \
X ( mjString*, texturedir, 1 ) \
X ( uint64_t, authored, 1 )
#define MJSCOMPILER_FIELDS \
X(mjtByte, autolimits, 1) \
X(double, boundmass, 1) \
X(double, boundinertia, 1) \
X(double, settotalmass, 1) \
X(mjtByte, balanceinertia, 1) \
X(mjtByte, fitaabb, 1) \
X(mjtByte, degree, 1) \
XVEC(char, eulerseq, 3) \
X(mjtByte, discardvisual, 1) \
X(mjtByte, usethread, 1) \
X(mjtByte, fusestatic, 1) \
X(int, inertiafromgeom, 1) \
XVEC(int, inertiagrouprange, 2) \
X(mjtByte, saveinertial, 1) \
X(int, alignfree, 1) \
X(int, conflict, 1) \
X(mjLROpt, LRopt, 1) \
X(mjString*, meshdir, 1) \
X(mjString*, texturedir, 1) \
X(uint64_t, authored, 1)
//-------------------------------- mjSpec ----------------------------------------------------------