Put sparsity structures in mjModel, don't use them yet.
PiperOrigin-RevId: 795032051 Change-Id: I75c69e881980ff9c308acf00bb3a65f4b2ef12f5
This commit is contained in:
committed by
Copybara-Service
parent
f077fd00a9
commit
7eb13777f8
@@ -979,6 +979,10 @@ struct mjModel_ {
|
|||||||
int nbvhdynamic; // number of dynamic bounding volumes (aabb stored in mjData)
|
int nbvhdynamic; // number of dynamic bounding volumes (aabb stored in mjData)
|
||||||
int noct; // number of total octree cells in all meshes
|
int noct; // number of total octree cells in all meshes
|
||||||
int njnt; // number of joints
|
int njnt; // number of joints
|
||||||
|
int nM; // number of non-zeros in sparse inertia matrix
|
||||||
|
int nB; // number of non-zeros in sparse body-dof matrix
|
||||||
|
int nC; // number of non-zeros in sparse reduced dof-dof matrix
|
||||||
|
int nD; // number of non-zeros in sparse dof-dof matrix
|
||||||
int ngeom; // number of geoms
|
int ngeom; // number of geoms
|
||||||
int nsite; // number of sites
|
int nsite; // number of sites
|
||||||
int ncam; // number of cameras
|
int ncam; // number of cameras
|
||||||
@@ -1042,10 +1046,6 @@ struct mjModel_ {
|
|||||||
|
|
||||||
// sizes set after mjModel construction
|
// sizes set after mjModel construction
|
||||||
int nnames_map; // number of slots in the names hash map
|
int nnames_map; // number of slots in the names hash map
|
||||||
int nM; // number of non-zeros in sparse inertia matrix
|
|
||||||
int nB; // number of non-zeros in sparse body-dof matrix
|
|
||||||
int nC; // number of non-zeros in sparse reduced dof-dof matrix
|
|
||||||
int nD; // number of non-zeros in sparse dof-dof matrix
|
|
||||||
int nJmom; // number of non-zeros in sparse actuator_moment matrix
|
int nJmom; // number of non-zeros in sparse actuator_moment matrix
|
||||||
int ntree; // number of kinematic trees under world body
|
int ntree; // number of kinematic trees under world body
|
||||||
int ngravcomp; // number of bodies with nonzero gravcomp
|
int ngravcomp; // number of bodies with nonzero gravcomp
|
||||||
@@ -1547,6 +1547,21 @@ struct mjModel_ {
|
|||||||
// paths
|
// paths
|
||||||
char* paths; // paths to assets, 0-terminated (npaths x 1)
|
char* paths; // paths to assets, 0-terminated (npaths x 1)
|
||||||
|
|
||||||
|
// sparse structures
|
||||||
|
int* B_rownnz; // body-dof: non-zeros in each row (nbody x 1)
|
||||||
|
int* B_rowadr; // body-dof: row addresses (nbody x 1)
|
||||||
|
int* B_colind; // body-dof: column indices (nB x 1)
|
||||||
|
int* M_rownnz; // reduced inertia: non-zeros in each row (nv x 1)
|
||||||
|
int* M_rowadr; // reduced inertia: row addresses (nv x 1)
|
||||||
|
int* M_colind; // reduced inertia: column indices (nC x 1)
|
||||||
|
int* mapM2M; // index mapping from qM to M (nC x 1)
|
||||||
|
int* D_rownnz; // full inertia: non-zeros in each row (nv x 1)
|
||||||
|
int* D_rowadr; // full inertia: row addresses (nv x 1)
|
||||||
|
int* D_diag; // full inertia: index of diagonal element (nv x 1)
|
||||||
|
int* D_colind; // full inertia: column indices (nD x 1)
|
||||||
|
int* mapM2D; // index mapping from qM to D (nD x 1)
|
||||||
|
int* mapD2M; // index mapping from D to qM (nM x 1)
|
||||||
|
|
||||||
// compilation signature
|
// compilation signature
|
||||||
uint64_t signature; // also held by the mjSpec that compiled this model
|
uint64_t signature; // also held by the mjSpec that compiled this model
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -654,6 +654,10 @@ struct mjModel_ {
|
|||||||
int nbvhdynamic; // number of dynamic bounding volumes (aabb stored in mjData)
|
int nbvhdynamic; // number of dynamic bounding volumes (aabb stored in mjData)
|
||||||
int noct; // number of total octree cells in all meshes
|
int noct; // number of total octree cells in all meshes
|
||||||
int njnt; // number of joints
|
int njnt; // number of joints
|
||||||
|
int nM; // number of non-zeros in sparse inertia matrix
|
||||||
|
int nB; // number of non-zeros in sparse body-dof matrix
|
||||||
|
int nC; // number of non-zeros in sparse reduced dof-dof matrix
|
||||||
|
int nD; // number of non-zeros in sparse dof-dof matrix
|
||||||
int ngeom; // number of geoms
|
int ngeom; // number of geoms
|
||||||
int nsite; // number of sites
|
int nsite; // number of sites
|
||||||
int ncam; // number of cameras
|
int ncam; // number of cameras
|
||||||
@@ -717,10 +721,6 @@ struct mjModel_ {
|
|||||||
|
|
||||||
// sizes set after mjModel construction
|
// sizes set after mjModel construction
|
||||||
int nnames_map; // number of slots in the names hash map
|
int nnames_map; // number of slots in the names hash map
|
||||||
int nM; // number of non-zeros in sparse inertia matrix
|
|
||||||
int nB; // number of non-zeros in sparse body-dof matrix
|
|
||||||
int nC; // number of non-zeros in sparse reduced dof-dof matrix
|
|
||||||
int nD; // number of non-zeros in sparse dof-dof matrix
|
|
||||||
int nJmom; // number of non-zeros in sparse actuator_moment matrix
|
int nJmom; // number of non-zeros in sparse actuator_moment matrix
|
||||||
int ntree; // number of kinematic trees under world body
|
int ntree; // number of kinematic trees under world body
|
||||||
int ngravcomp; // number of bodies with nonzero gravcomp
|
int ngravcomp; // number of bodies with nonzero gravcomp
|
||||||
@@ -1222,6 +1222,21 @@ struct mjModel_ {
|
|||||||
// paths
|
// paths
|
||||||
char* paths; // paths to assets, 0-terminated (npaths x 1)
|
char* paths; // paths to assets, 0-terminated (npaths x 1)
|
||||||
|
|
||||||
|
// sparse structures
|
||||||
|
int* B_rownnz; // body-dof: non-zeros in each row (nbody x 1)
|
||||||
|
int* B_rowadr; // body-dof: row addresses (nbody x 1)
|
||||||
|
int* B_colind; // body-dof: column indices (nB x 1)
|
||||||
|
int* M_rownnz; // reduced inertia: non-zeros in each row (nv x 1)
|
||||||
|
int* M_rowadr; // reduced inertia: row addresses (nv x 1)
|
||||||
|
int* M_colind; // reduced inertia: column indices (nC x 1)
|
||||||
|
int* mapM2M; // index mapping from qM to M (nC x 1)
|
||||||
|
int* D_rownnz; // full inertia: non-zeros in each row (nv x 1)
|
||||||
|
int* D_rowadr; // full inertia: row addresses (nv x 1)
|
||||||
|
int* D_diag; // full inertia: index of diagonal element (nv x 1)
|
||||||
|
int* D_colind; // full inertia: column indices (nD x 1)
|
||||||
|
int* mapM2D; // index mapping from qM to D (nD x 1)
|
||||||
|
int* mapD2M; // index mapping from D to qM (nM x 1)
|
||||||
|
|
||||||
// compilation signature
|
// compilation signature
|
||||||
uint64_t signature; // also held by the mjSpec that compiled this model
|
uint64_t signature; // also held by the mjSpec that compiled this model
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -77,6 +77,10 @@
|
|||||||
X( nbvhdynamic ) \
|
X( nbvhdynamic ) \
|
||||||
X( noct ) \
|
X( noct ) \
|
||||||
X( njnt ) \
|
X( njnt ) \
|
||||||
|
X( nM ) \
|
||||||
|
X( nB ) \
|
||||||
|
X( nC ) \
|
||||||
|
X( nD ) \
|
||||||
X( ngeom ) \
|
X( ngeom ) \
|
||||||
X( nsite ) \
|
X( nsite ) \
|
||||||
X( ncam ) \
|
X( ncam ) \
|
||||||
@@ -138,10 +142,6 @@
|
|||||||
X( nnames ) \
|
X( nnames ) \
|
||||||
X( npaths ) \
|
X( npaths ) \
|
||||||
X( nnames_map ) \
|
X( nnames_map ) \
|
||||||
X( nM ) \
|
|
||||||
X( nB ) \
|
|
||||||
X( nC ) \
|
|
||||||
X( nD ) \
|
|
||||||
X( nJmom ) \
|
X( nJmom ) \
|
||||||
X( ntree ) \
|
X( ntree ) \
|
||||||
X( ngravcomp ) \
|
X( ngravcomp ) \
|
||||||
@@ -597,6 +597,19 @@
|
|||||||
X ( char, names, nnames, 1 ) \
|
X ( char, names, nnames, 1 ) \
|
||||||
X ( int, names_map, nnames_map, 1 ) \
|
X ( int, names_map, nnames_map, 1 ) \
|
||||||
X ( char, paths, npaths, 1 ) \
|
X ( char, paths, npaths, 1 ) \
|
||||||
|
X ( int, B_rownnz, nbody, 1 ) \
|
||||||
|
X ( int, B_rowadr, nbody, 1 ) \
|
||||||
|
X ( int, B_colind, nB, 1 ) \
|
||||||
|
X ( int, M_rownnz, nv, 1 ) \
|
||||||
|
X ( int, M_rowadr, nv, 1 ) \
|
||||||
|
X ( int, M_colind, nC, 1 ) \
|
||||||
|
X ( int, mapM2M, nC, 1 ) \
|
||||||
|
X ( int, D_rownnz, nv, 1 ) \
|
||||||
|
X ( int, D_rowadr, nv, 1 ) \
|
||||||
|
X ( int, D_diag, nv, 1 ) \
|
||||||
|
X ( int, D_colind, nD, 1 ) \
|
||||||
|
X ( int, mapM2D, nD, 1 ) \
|
||||||
|
X ( int, mapD2M, nM, 1 )
|
||||||
|
|
||||||
//-------------------------------- mjData ----------------------------------------------------------
|
//-------------------------------- mjData ----------------------------------------------------------
|
||||||
|
|
||||||
@@ -722,7 +735,7 @@
|
|||||||
X( mjContact, contact, MJ_D(ncon), 1 )
|
X( mjContact, contact, MJ_D(ncon), 1 )
|
||||||
|
|
||||||
// array fields of mjData that are used in the primal problem
|
// array fields of mjData that are used in the primal problem
|
||||||
#define MJDATA_ARENA_POINTERS_SOLVER \
|
#define MJDATA_ARENA_POINTERS_SOLVER \
|
||||||
X ( int, efc_type, MJ_D(nefc), 1 ) \
|
X ( int, efc_type, MJ_D(nefc), 1 ) \
|
||||||
X ( int, efc_id, MJ_D(nefc), 1 ) \
|
X ( int, efc_id, MJ_D(nefc), 1 ) \
|
||||||
XNV( int, efc_J_rownnz, MJ_D(nefc), 1 ) \
|
XNV( int, efc_J_rownnz, MJ_D(nefc), 1 ) \
|
||||||
|
|||||||
@@ -883,6 +883,26 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='number of joints',
|
doc='number of joints',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='nM',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='number of non-zeros in sparse inertia matrix',
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='nB',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='number of non-zeros in sparse body-dof matrix',
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='nC',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='number of non-zeros in sparse reduced dof-dof matrix',
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='nD',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='number of non-zeros in sparse dof-dof matrix',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='ngeom',
|
name='ngeom',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
@@ -1188,26 +1208,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='number of slots in the names hash map',
|
doc='number of slots in the names hash map',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='nM',
|
|
||||||
type=ValueType(name='int'),
|
|
||||||
doc='number of non-zeros in sparse inertia matrix',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
|
||||||
name='nB',
|
|
||||||
type=ValueType(name='int'),
|
|
||||||
doc='number of non-zeros in sparse body-dof matrix',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
|
||||||
name='nC',
|
|
||||||
type=ValueType(name='int'),
|
|
||||||
doc='number of non-zeros in sparse reduced dof-dof matrix',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
|
||||||
name='nD',
|
|
||||||
type=ValueType(name='int'),
|
|
||||||
doc='number of non-zeros in sparse dof-dof matrix',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='nJmom',
|
name='nJmom',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
@@ -4605,6 +4605,110 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
doc='paths to assets, 0-terminated',
|
doc='paths to assets, 0-terminated',
|
||||||
array_extent=('npaths',),
|
array_extent=('npaths',),
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='B_rownnz',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='body-dof: non-zeros in each row',
|
||||||
|
array_extent=('nbody',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='B_rowadr',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='body-dof: row addresses',
|
||||||
|
array_extent=('nbody',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='B_colind',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='body-dof: column indices',
|
||||||
|
array_extent=('nB',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='M_rownnz',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='reduced inertia: non-zeros in each row',
|
||||||
|
array_extent=('nv',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='M_rowadr',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='reduced inertia: row addresses',
|
||||||
|
array_extent=('nv',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='M_colind',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='reduced inertia: column indices',
|
||||||
|
array_extent=('nC',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='mapM2M',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='index mapping from qM to M',
|
||||||
|
array_extent=('nC',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='D_rownnz',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='full inertia: non-zeros in each row',
|
||||||
|
array_extent=('nv',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='D_rowadr',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='full inertia: row addresses',
|
||||||
|
array_extent=('nv',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='D_diag',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='full inertia: index of diagonal element',
|
||||||
|
array_extent=('nv',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='D_colind',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='full inertia: column indices',
|
||||||
|
array_extent=('nD',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='mapM2D',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='index mapping from qM to D',
|
||||||
|
array_extent=('nD',),
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='mapD2M',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
),
|
||||||
|
doc='index mapping from D to qM',
|
||||||
|
array_extent=('nM',),
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='signature',
|
name='signature',
|
||||||
type=ValueType(name='uint64_t'),
|
type=ValueType(name='uint64_t'),
|
||||||
|
|||||||
+117
-124
@@ -463,7 +463,8 @@ static void freeModelBuffers(mjModel* m) {
|
|||||||
// allocate and initialize mjModel structure
|
// allocate and initialize mjModel structure
|
||||||
void mj_makeModel(mjModel** dest,
|
void mj_makeModel(mjModel** dest,
|
||||||
int nq, int nv, int nu, int na, int nbody, int nbvh,
|
int nq, int nv, int nu, int na, int nbody, int nbvh,
|
||||||
int nbvhstatic, int nbvhdynamic, int noct, int njnt, int ngeom, int nsite, int ncam,
|
int nbvhstatic, int nbvhdynamic, int noct, int njnt,
|
||||||
|
int nM, int nB, int nC, int nD, int ngeom, int nsite, int ncam,
|
||||||
int nlight, int nflex, int nflexnode, int nflexvert, int nflexedge, int nflexelem,
|
int nlight, int nflex, int nflexnode, int nflexvert, int nflexedge, int nflexelem,
|
||||||
int nflexelemdata, int nflexelemedge, int nflexshelldata, int nflexevpair, int nflextexcoord,
|
int nflexelemdata, int nflexelemedge, int nflexshelldata, int nflexevpair, int nflextexcoord,
|
||||||
int nmesh, int nmeshvert, int nmeshnormal, int nmeshtexcoord, int nmeshface,
|
int nmesh, int nmeshvert, int nmeshnormal, int nmeshtexcoord, int nmeshface,
|
||||||
@@ -504,6 +505,10 @@ void mj_makeModel(mjModel** dest,
|
|||||||
m->nbvhdynamic = nbvhdynamic;
|
m->nbvhdynamic = nbvhdynamic;
|
||||||
m->noct = noct;
|
m->noct = noct;
|
||||||
m->njnt = njnt;
|
m->njnt = njnt;
|
||||||
|
m->nM = nM;
|
||||||
|
m->nB = nB;
|
||||||
|
m->nC = nC;
|
||||||
|
m->nD = nD;
|
||||||
m->ngeom = ngeom;
|
m->ngeom = ngeom;
|
||||||
m->nsite = nsite;
|
m->nsite = nsite;
|
||||||
m->ncam = ncam;
|
m->ncam = ncam;
|
||||||
@@ -619,7 +624,7 @@ void mj_makeModel(mjModel** dest,
|
|||||||
// clear, set pointers in buffer
|
// clear, set pointers in buffer
|
||||||
memset(m->buffer, 0, m->nbuffer);
|
memset(m->buffer, 0, m->nbuffer);
|
||||||
#ifdef MEMORY_SANITIZER
|
#ifdef MEMORY_SANITIZER
|
||||||
// Tell msan to treat the entire buffer as uninitialized
|
// tell msan to treat the entire buffer as uninitialized
|
||||||
__msan_allocated_memory(m->buffer, m->nbuffer);
|
__msan_allocated_memory(m->buffer, m->nbuffer);
|
||||||
#endif
|
#endif
|
||||||
mj_setPtrModel(m);
|
mj_setPtrModel(m);
|
||||||
@@ -641,23 +646,24 @@ void mj_makeModel(mjModel** dest,
|
|||||||
mjModel* mj_copyModel(mjModel* dest, const mjModel* src) {
|
mjModel* mj_copyModel(mjModel* dest, const mjModel* src) {
|
||||||
// allocate new model if needed
|
// allocate new model if needed
|
||||||
if (!dest) {
|
if (!dest) {
|
||||||
mj_makeModel(&dest,
|
mj_makeModel(
|
||||||
src->nq, src->nv, src->nu, src->na, src->nbody, src->nbvh,
|
&dest, src->nq, src->nv, src->nu, src->na, src->nbody, src->nbvh,
|
||||||
src->nbvhstatic, src->nbvhdynamic, src->noct, src->njnt, src->ngeom, src->nsite,
|
src->nbvhstatic, src->nbvhdynamic, src->noct, src->njnt, src->nM,
|
||||||
src->ncam, src->nlight, src->nflex, src->nflexnode, src->nflexvert, src->nflexedge,
|
src->nB, src->nC, src->nD, src->ngeom, src->nsite, src->ncam,
|
||||||
src->nflexelem, src->nflexelemdata, src->nflexelemedge, src->nflexshelldata,
|
src->nlight, src->nflex, src->nflexnode, src->nflexvert, src->nflexedge,
|
||||||
src->nflexevpair, src->nflextexcoord, src->nmesh, src->nmeshvert,
|
src->nflexelem, src->nflexelemdata, src->nflexelemedge,
|
||||||
src->nmeshnormal, src->nmeshtexcoord, src->nmeshface, src->nmeshgraph,
|
src->nflexshelldata, src->nflexevpair, src->nflextexcoord, src->nmesh,
|
||||||
src->nmeshpoly, src->nmeshpolyvert, src->nmeshpolymap,
|
src->nmeshvert, src->nmeshnormal, src->nmeshtexcoord, src->nmeshface,
|
||||||
src->nskin, src->nskinvert, src->nskintexvert, src->nskinface,
|
src->nmeshgraph, src->nmeshpoly, src->nmeshpolyvert, src->nmeshpolymap,
|
||||||
src->nskinbone, src->nskinbonevert, src->nhfield, src->nhfielddata,
|
src->nskin, src->nskinvert, src->nskintexvert, src->nskinface,
|
||||||
src->ntex, src->ntexdata, src->nmat, src->npair, src->nexclude,
|
src->nskinbone, src->nskinbonevert, src->nhfield, src->nhfielddata,
|
||||||
src->neq, src->ntendon, src->nwrap, src->nsensor, src->nnumeric,
|
src->ntex, src->ntexdata, src->nmat, src->npair, src->nexclude,
|
||||||
src->nnumericdata, src->ntext, src->ntextdata, src->ntuple,
|
src->neq, src->ntendon, src->nwrap, src->nsensor, src->nnumeric,
|
||||||
src->ntupledata, src->nkey, src->nmocap, src->nplugin, src->npluginattr,
|
src->nnumericdata, src->ntext, src->ntextdata, src->ntuple,
|
||||||
src->nuser_body, src->nuser_jnt, src->nuser_geom, src->nuser_site,
|
src->ntupledata, src->nkey, src->nmocap, src->nplugin, src->npluginattr,
|
||||||
src->nuser_cam, src->nuser_tendon, src->nuser_actuator,
|
src->nuser_body, src->nuser_jnt, src->nuser_geom, src->nuser_site,
|
||||||
src->nuser_sensor, src->nnames, src->npaths);
|
src->nuser_cam, src->nuser_tendon, src->nuser_actuator,
|
||||||
|
src->nuser_sensor, src->nnames, src->npaths);
|
||||||
}
|
}
|
||||||
if (!dest) {
|
if (!dest) {
|
||||||
mjERROR("failed to make mjModel. Invalid sizes.");
|
mjERROR("failed to make mjModel. Invalid sizes.");
|
||||||
@@ -838,7 +844,8 @@ mjModel* mj_loadModelBuffer(const void* buffer, int buffer_sz) {
|
|||||||
ints[42], ints[43], ints[44], ints[45], ints[46], ints[47], ints[48],
|
ints[42], ints[43], ints[44], ints[45], ints[46], ints[47], ints[48],
|
||||||
ints[49], ints[50], ints[51], ints[52], ints[53], ints[54], ints[55],
|
ints[49], ints[50], ints[51], ints[52], ints[53], ints[54], ints[55],
|
||||||
ints[56], ints[57], ints[58], ints[59], ints[60], ints[61], ints[62],
|
ints[56], ints[57], ints[58], ints[59], ints[60], ints[61], ints[62],
|
||||||
ints[63], ints[64], ints[65], ints[66], ints[67], ints[68], ints[69]);
|
ints[63], ints[64], ints[65], ints[66], ints[67], ints[68], ints[69],
|
||||||
|
ints[70], ints[71], ints[72], ints[73]);
|
||||||
|
|
||||||
// read mjModel mjtSize fields
|
// read mjModel mjtSize fields
|
||||||
mjtSize sizes[8];
|
mjtSize sizes[8];
|
||||||
@@ -936,19 +943,16 @@ int mj_sizeModel(const mjModel* m) {
|
|||||||
//-------------------------- sparse system matrix construction -------------------------------------
|
//-------------------------- sparse system matrix construction -------------------------------------
|
||||||
|
|
||||||
// construct sparse representation of dof-dof matrix
|
// construct sparse representation of dof-dof matrix
|
||||||
static void makeDofDofSparse(const mjModel* m, mjData* d,
|
void mj_makeDofDofSparse(int nv, int nC, int nD, int nM,
|
||||||
int* rownnz, int* rowadr, int* diag, int* colind,
|
const int* dof_parentid, const int* dof_simplenum,
|
||||||
int reduced, int upper) {
|
int* rownnz, int* rowadr, int* diag, int* colind,
|
||||||
int nv = m->nv;
|
int reduced, int upper,
|
||||||
|
int* remaining) {
|
||||||
// no dofs, nothing to do
|
// no dofs, nothing to do
|
||||||
if (!nv) {
|
if (!nv) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mj_markStack(d);
|
|
||||||
int* remaining = mjSTACKALLOC(d, nv, int);
|
|
||||||
|
|
||||||
// compute rownnz
|
// compute rownnz
|
||||||
mju_zeroInt(rownnz, nv);
|
mju_zeroInt(rownnz, nv);
|
||||||
for (int i = nv - 1; i >= 0; i--) {
|
for (int i = nv - 1; i >= 0; i--) {
|
||||||
@@ -957,8 +961,8 @@ static void makeDofDofSparse(const mjModel* m, mjData* d,
|
|||||||
rownnz[i]++;
|
rownnz[i]++;
|
||||||
|
|
||||||
// process below diagonal unless reduced and dof is simple
|
// process below diagonal unless reduced and dof is simple
|
||||||
if (!(reduced && m->dof_simplenum[i])) {
|
if (!(reduced && dof_simplenum[i])) {
|
||||||
while ((j = m->dof_parentid[j]) >= 0) {
|
while ((j = dof_parentid[j]) >= 0) {
|
||||||
// both reduced and non-reduced have lower triangle
|
// both reduced and non-reduced have lower triangle
|
||||||
rownnz[i]++;
|
rownnz[i]++;
|
||||||
|
|
||||||
@@ -982,9 +986,9 @@ static void makeDofDofSparse(const mjModel* m, mjData* d,
|
|||||||
colind[rowadr[i] + remaining[i]] = i;
|
colind[rowadr[i] + remaining[i]] = i;
|
||||||
|
|
||||||
// process below diagonal unless reduced and dof is simple
|
// process below diagonal unless reduced and dof is simple
|
||||||
if (!(reduced && m->dof_simplenum[i])) {
|
if (!(reduced && dof_simplenum[i])) {
|
||||||
int j = i;
|
int j = i;
|
||||||
while ((j = m->dof_parentid[j]) >= 0) {
|
while ((j = dof_parentid[j]) >= 0) {
|
||||||
remaining[i]--;
|
remaining[i]--;
|
||||||
colind[rowadr[i] + remaining[i]] = j;
|
colind[rowadr[i] + remaining[i]] = j;
|
||||||
|
|
||||||
@@ -1005,7 +1009,7 @@ static void makeDofDofSparse(const mjModel* m, mjData* d,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check total nnz; SHOULD NOT OCCUR
|
// check total nnz; SHOULD NOT OCCUR
|
||||||
int expected_nnz = upper ? m->nD : (reduced ? m->nC : m->nM);
|
int expected_nnz = upper ? nD : (reduced ? nC : nM);
|
||||||
if (rowadr[nv - 1] + rownnz[nv - 1] != expected_nnz) {
|
if (rowadr[nv - 1] + rownnz[nv - 1] != expected_nnz) {
|
||||||
mjERROR("sum of rownnz different from expected");
|
mjERROR("sum of rownnz different from expected");
|
||||||
}
|
}
|
||||||
@@ -1024,99 +1028,91 @@ static void makeDofDofSparse(const mjModel* m, mjData* d,
|
|||||||
diag[i] = j;
|
diag[i] = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mj_freeStack(d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct sparse representation of body-dof matrix
|
// construct sparse representation of body-dof matrix
|
||||||
static void makeBSparse(const mjModel* m, mjData* d) {
|
void mj_makeBSparse(int nv, int nbody, int nB,
|
||||||
int nv = m->nv, nbody = m->nbody;
|
const int* body_dofnum, const int* body_parentid, const int* body_dofadr,
|
||||||
int* rownnz = d->B_rownnz;
|
int* B_rownnz, int* B_rowadr, int* B_colind,
|
||||||
int* rowadr = d->B_rowadr;
|
int* count) {
|
||||||
int* colind = d->B_colind;
|
|
||||||
|
|
||||||
// set rownnz to subtree dofs counts, including self
|
// set rownnz to subtree dofs counts, including self
|
||||||
mju_zeroInt(rownnz, nbody);
|
mju_zeroInt(B_rownnz, nbody);
|
||||||
for (int i = nbody - 1; i > 0; i--) {
|
for (int i = nbody - 1; i > 0; i--) {
|
||||||
rownnz[i] += m->body_dofnum[i];
|
B_rownnz[i] += body_dofnum[i];
|
||||||
rownnz[m->body_parentid[i]] += rownnz[i];
|
B_rownnz[body_parentid[i]] += B_rownnz[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if rownnz[0] != nv; SHOULD NOT OCCUR
|
// check if rownnz[0] != nv; SHOULD NOT OCCUR
|
||||||
if (rownnz[0] != nv) {
|
if (B_rownnz[0] != nv) {
|
||||||
mjERROR("rownnz[0] different from nv");
|
mjERROR("rownnz[0] different from nv");
|
||||||
}
|
}
|
||||||
|
|
||||||
// add dofs in ancestors bodies
|
// add dofs in ancestors bodies
|
||||||
for (int i = 0; i < nbody; i++) {
|
for (int i = 0; i < nbody; i++) {
|
||||||
int j = m->body_parentid[i];
|
int j = body_parentid[i];
|
||||||
while (j > 0) {
|
while (j > 0) {
|
||||||
rownnz[i] += m->body_dofnum[j];
|
B_rownnz[i] += body_dofnum[j];
|
||||||
j = m->body_parentid[j];
|
j = body_parentid[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute rowadr
|
// compute rowadr
|
||||||
rowadr[0] = 0;
|
B_rowadr[0] = 0;
|
||||||
for (int i = 1; i < nbody; i++) {
|
for (int i = 1; i < nbody; i++) {
|
||||||
rowadr[i] = rowadr[i - 1] + rownnz[i - 1];
|
B_rowadr[i] = B_rowadr[i - 1] + B_rownnz[i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if total nnz != nB; SHOULD NOT OCCUR
|
// check if total nnz != nB; SHOULD NOT OCCUR
|
||||||
if (m->nB != rowadr[nbody - 1] + rownnz[nbody - 1]) {
|
if (nB != B_rowadr[nbody - 1] + B_rownnz[nbody - 1]) {
|
||||||
mjERROR("sum of rownnz different from nB");
|
mjERROR("sum of rownnz different from nB");
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate and clear incremental row counts
|
// clear incremental row counts
|
||||||
mj_markStack(d);
|
mju_zeroInt(count, nbody);
|
||||||
int* cnt = mjSTACKALLOC(d, nbody, int);
|
|
||||||
mju_zeroInt(cnt, nbody);
|
|
||||||
|
|
||||||
// add subtree dofs to colind
|
// add subtree dofs to colind
|
||||||
for (int i = nbody - 1; i > 0; i--) {
|
for (int i = nbody - 1; i > 0; i--) {
|
||||||
// add this body's dofs to subtree
|
// add this body's dofs to subtree
|
||||||
for (int n = 0; n < m->body_dofnum[i]; n++) {
|
for (int n = 0; n < body_dofnum[i]; n++) {
|
||||||
colind[rowadr[i] + cnt[i]] = m->body_dofadr[i] + n;
|
B_colind[B_rowadr[i] + count[i]] = body_dofadr[i] + n;
|
||||||
cnt[i]++;
|
count[i]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add body subtree to parent
|
// add body subtree to parent
|
||||||
int par = m->body_parentid[i];
|
int par = body_parentid[i];
|
||||||
for (int n = 0; n < cnt[i]; n++) {
|
for (int n = 0; n < count[i]; n++) {
|
||||||
colind[rowadr[par] + cnt[par]] = colind[rowadr[i] + n];
|
B_colind[B_rowadr[par] + count[par]] = B_colind[B_rowadr[i] + n];
|
||||||
cnt[par]++;
|
count[par]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all ancestor dofs
|
// add all ancestor dofs
|
||||||
for (int i = 0; i < nbody; i++) {
|
for (int i = 0; i < nbody; i++) {
|
||||||
int par = m->body_parentid[i];
|
int par = body_parentid[i];
|
||||||
while (par > 0) {
|
while (par > 0) {
|
||||||
// add ancestor body dofs
|
// add ancestor body dofs
|
||||||
for (int n = 0; n < m->body_dofnum[par]; n++) {
|
for (int n = 0; n < body_dofnum[par]; n++) {
|
||||||
colind[rowadr[i] + cnt[i]] = m->body_dofadr[par] + n;
|
B_colind[B_rowadr[i] + count[i]] = body_dofadr[par] + n;
|
||||||
cnt[i]++;
|
count[i]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// advance to parent
|
// advance to parent
|
||||||
par = m->body_parentid[par];
|
par = body_parentid[par];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// process all bodies
|
// process all bodies
|
||||||
for (int i = 0; i < nbody; i++) {
|
for (int i = 0; i < nbody; i++) {
|
||||||
// make sure cnt = rownnz; SHOULD NOT OCCUR
|
// make sure cnt = rownnz; SHOULD NOT OCCUR
|
||||||
if (rownnz[i] != cnt[i]) {
|
if (B_rownnz[i] != count[i]) {
|
||||||
mjERROR("cnt different from rownnz");
|
mjERROR("cnt different from rownnz");
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort colind in each row
|
// sort colind in each row
|
||||||
if (cnt[i] > 1) {
|
if (count[i] > 1) {
|
||||||
mju_insertionSortInt(colind + rowadr[i], cnt[i]);
|
mju_insertionSortInt(B_colind + B_rowadr[i], count[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mj_freeStack(d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1143,39 +1139,26 @@ static void checkDBSparse(const mjModel* m, mjData* d) {
|
|||||||
|
|
||||||
|
|
||||||
// integer valued dst[D or C or M] = src[M (legacy)], handle different sparsity representations
|
// integer valued dst[D or C or M] = src[M (legacy)], handle different sparsity representations
|
||||||
static void copyM2Sparse(const mjModel* m, mjData* d, int* dst, const int* src,
|
static void copyM2Sparse(int nv,
|
||||||
int reduced, int upper) {
|
const int* dof_Madr, const int* dof_simplenum, const int* dof_parentid,
|
||||||
int nv = m->nv;
|
const int* rownnz, const int* rowadr, const int* src,
|
||||||
const int* rownnz = NULL;
|
int* dst,
|
||||||
const int* rowadr = NULL;
|
int reduced, int upper, int* remaining) {
|
||||||
if (reduced && !upper) {
|
|
||||||
rownnz = d->M_rownnz;
|
|
||||||
rowadr = d->M_rowadr;
|
|
||||||
} else if (!reduced && upper) {
|
|
||||||
rownnz = d->D_rownnz;
|
|
||||||
rowadr = d->D_rowadr;
|
|
||||||
} else {
|
|
||||||
mjERROR("unsupported sparsity structure (reduced + upper)");
|
|
||||||
}
|
|
||||||
|
|
||||||
mj_markStack(d);
|
|
||||||
|
|
||||||
// init remaining
|
// init remaining
|
||||||
int* remaining = mjSTACKALLOC(d, nv, int);
|
|
||||||
mju_copyInt(remaining, rownnz, nv);
|
mju_copyInt(remaining, rownnz, nv);
|
||||||
|
|
||||||
// copy data
|
// copy data
|
||||||
for (int i = nv - 1; i >= 0; i--) {
|
for (int i = nv - 1; i >= 0; i--) {
|
||||||
// init at diagonal
|
// init at diagonal
|
||||||
int adr = m->dof_Madr[i];
|
int adr = dof_Madr[i];
|
||||||
remaining[i]--;
|
remaining[i]--;
|
||||||
dst[rowadr[i] + remaining[i]] = src[adr];
|
dst[rowadr[i] + remaining[i]] = src[adr];
|
||||||
adr++;
|
adr++;
|
||||||
|
|
||||||
// process below diagonal unless reduced and dof is simple
|
// process below diagonal unless reduced and dof is simple
|
||||||
if (!(reduced && m->dof_simplenum[i])) {
|
if (!(reduced && dof_simplenum[i])) {
|
||||||
int j = i;
|
int j = i;
|
||||||
while ((j = m->dof_parentid[j]) >= 0) {
|
while ((j = dof_parentid[j]) >= 0) {
|
||||||
remaining[i]--;
|
remaining[i]--;
|
||||||
dst[rowadr[i] + remaining[i]] = src[adr];
|
dst[rowadr[i] + remaining[i]] = src[adr];
|
||||||
|
|
||||||
@@ -1196,28 +1179,25 @@ static void copyM2Sparse(const mjModel* m, mjData* d, int* dst, const int* src,
|
|||||||
mjERROR("unassigned index");
|
mjERROR("unassigned index");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mj_freeStack(d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// integer valued dst[M] = src[D lower]
|
// integer valued dst[M] = src[D lower]
|
||||||
static void copyD2MSparse(const mjModel* m, const mjData* d, int* dst, const int* src) {
|
static void copyD2MSparse(int nv, const int* dof_Madr, const int* D_colind,
|
||||||
int nv = m->nv;
|
const int* D_rowadr, const int* src, int* dst) {
|
||||||
|
|
||||||
// copy data
|
// copy data
|
||||||
for (int i = nv - 1; i >= 0; i--) {
|
for (int i = nv - 1; i >= 0; i--) {
|
||||||
// find diagonal in qDeriv
|
// find diagonal in qDeriv
|
||||||
int j = 0;
|
int j = 0;
|
||||||
while (d->D_colind[d->D_rowadr[i] + j] < i) {
|
while (D_colind[D_rowadr[i] + j] < i) {
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy
|
// copy
|
||||||
int adr = m->dof_Madr[i];
|
int adr = dof_Madr[i];
|
||||||
while (j >= 0) {
|
while (j >= 0) {
|
||||||
dst[adr] = src[d->D_rowadr[i] + j];
|
dst[adr] = src[D_rowadr[i] + j];
|
||||||
adr++;
|
adr++;
|
||||||
j--;
|
j--;
|
||||||
}
|
}
|
||||||
@@ -1227,48 +1207,47 @@ static void copyD2MSparse(const mjModel* m, const mjData* d, int* dst, const int
|
|||||||
|
|
||||||
|
|
||||||
// construct index mappings between M <-> D, M -> C, M (legacy) -> M (CSR)
|
// construct index mappings between M <-> D, M -> C, M (legacy) -> M (CSR)
|
||||||
static void makeDofDofmaps(const mjModel* m, mjData* d) {
|
void mj_makeDofDofMaps(int nv, int nM, int nC, int nD,
|
||||||
int nM = m->nM, nC = m->nC, nD = m->nD;
|
const int* dof_Madr, const int* dof_simplenum, const int* dof_parentid,
|
||||||
mj_markStack(d);
|
const int* D_rownnz, const int* D_rowadr, const int* D_colind,
|
||||||
|
const int* M_rownnz, const int* M_rowadr,
|
||||||
|
int* mapM2D, int* mapD2M, int* mapM2M,
|
||||||
|
int* remaining, int* M, int* D) {
|
||||||
// make mapM2D
|
// make mapM2D
|
||||||
int* M = mjSTACKALLOC(d, nM, int);
|
|
||||||
for (int i=0; i < nM; i++) M[i] = i;
|
for (int i=0; i < nM; i++) M[i] = i;
|
||||||
for (int i=0; i < nD; i++) d->mapM2D[i] = -1;
|
for (int i=0; i < nD; i++) mapM2D[i] = -1;
|
||||||
copyM2Sparse(m, d, d->mapM2D, M, /*reduced=*/0, /*upper=*/1);
|
copyM2Sparse(nv, dof_Madr, dof_simplenum, dof_parentid, D_rownnz,
|
||||||
|
D_rowadr, M, mapM2D, /*reduced=*/0, /*upper=*/1, remaining);
|
||||||
|
|
||||||
// check that all indices are filled in
|
// check that all indices are filled in
|
||||||
for (int i=0; i < nD; i++) {
|
for (int i=0; i < nD; i++) {
|
||||||
if (d->mapM2D[i] < 0) {
|
if (mapM2D[i] < 0) {
|
||||||
mjERROR("unassigned index in mapM2D");
|
mjERROR("unassigned index in mapM2D");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make mapD2M
|
// make mapD2M
|
||||||
int* D = mjSTACKALLOC(d, nD, int);
|
|
||||||
for (int i=0; i < nD; i++) D[i] = i;
|
for (int i=0; i < nD; i++) D[i] = i;
|
||||||
for (int i=0; i < nM; i++) d->mapD2M[i] = -1;
|
for (int i=0; i < nM; i++) mapD2M[i] = -1;
|
||||||
copyD2MSparse(m, d, d->mapD2M, D);
|
copyD2MSparse(nv, dof_Madr, D_colind, D_rowadr, D, mapD2M);
|
||||||
|
|
||||||
// check that all indices are filled in
|
// check that all indices are filled in
|
||||||
for (int i=0; i < nM; i++) {
|
for (int i=0; i < nM; i++) {
|
||||||
if (d->mapD2M[i] < 0) {
|
if (mapD2M[i] < 0) {
|
||||||
mjERROR("unassigned index in mapD2M");
|
mjERROR("unassigned index in mapD2M");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make mapM2C
|
// make mapM2C
|
||||||
for (int i=0; i < nC; i++) d->mapM2M[i] = -1;
|
for (int i=0; i < nC; i++) mapM2M[i] = -1;
|
||||||
copyM2Sparse(m, d, d->mapM2M, M, /*reduced=*/1, /*upper=*/0);
|
copyM2Sparse(nv, dof_Madr, dof_simplenum, dof_parentid, M_rownnz,
|
||||||
|
M_rowadr, M, mapM2M, /*reduced=*/1, /*upper=*/0, remaining);
|
||||||
// check that all indices are filled in
|
// check that all indices are filled in
|
||||||
for (int i=0; i < nC; i++) {
|
for (int i=0; i < nC; i++) {
|
||||||
if (d->mapM2M[i] < 0) {
|
if (mapM2M[i] < 0) {
|
||||||
mjERROR("unassigned index in mapM2C");
|
mjERROR("unassigned index in mapM2C");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mj_freeStack(d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2027,19 +2006,33 @@ static void _resetData(const mjModel* m, mjData* d, unsigned char debug_value) {
|
|||||||
|
|
||||||
// construct sparse matrix representations
|
// construct sparse matrix representations
|
||||||
if (m->body_dofadr) {
|
if (m->body_dofadr) {
|
||||||
|
mj_markStack(d);
|
||||||
|
int* remaining = mjSTACKALLOC(d, m->nv, int);
|
||||||
|
int* count = mjSTACKALLOC(d, m->nbody, int);
|
||||||
|
int* M = mjSTACKALLOC(d, m->nM, int);
|
||||||
|
int* D = mjSTACKALLOC(d, m->nD, int);
|
||||||
|
|
||||||
// make D
|
// make D
|
||||||
makeDofDofSparse(m, d, d->D_rownnz, d->D_rowadr, d->D_diag, d->D_colind,
|
mj_makeDofDofSparse(m->nv, m->nC, m->nD, m->nM, m->dof_parentid, m->dof_simplenum,
|
||||||
/*reduced=*/0, /*upper=*/1);
|
d->D_rownnz, d->D_rowadr, d->D_diag, d->D_colind,
|
||||||
|
/*reduced=*/0, /*upper=*/1, remaining);
|
||||||
|
|
||||||
// make B, check D and B
|
// make B, check D and B
|
||||||
makeBSparse(m, d);
|
mj_makeBSparse(m->nv, m->nbody, m->nB, m->body_dofnum, m->body_parentid,
|
||||||
|
m->body_dofadr, d->B_rownnz, d->B_rowadr, d->B_colind, count);
|
||||||
checkDBSparse(m, d);
|
checkDBSparse(m, d);
|
||||||
|
|
||||||
// make C
|
// make C
|
||||||
makeDofDofSparse(m, d, d->M_rownnz, d->M_rowadr, NULL, d->M_colind, /*reduced=*/1, /*upper=*/0);
|
mj_makeDofDofSparse(m->nv, m->nC, m->nD, m->nM, m->dof_parentid, m->dof_simplenum,
|
||||||
|
d->M_rownnz, d->M_rowadr, NULL, d->M_colind,
|
||||||
|
/*reduced=*/1, /*upper=*/0, remaining);
|
||||||
|
|
||||||
// make index mappings: mapM2D, mapD2M, mapM2C, mapM2M
|
// make index mappings: mapM2D, mapD2M, mapM2C, mapM2M
|
||||||
makeDofDofmaps(m, d);
|
mj_makeDofDofMaps(m->nv, m->nM, m->nC, m->nD, m->dof_Madr, m->dof_simplenum, m->dof_parentid,
|
||||||
|
d->D_rownnz, d->D_rowadr, d->D_colind, d->M_rownnz, d->M_rowadr,
|
||||||
|
d->mapM2D, d->mapD2M, d->mapM2M, remaining, M, D);
|
||||||
|
|
||||||
|
mj_freeStack(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore pluginstate and plugindata
|
// restore pluginstate and plugindata
|
||||||
|
|||||||
+29
-10
@@ -53,16 +53,16 @@ void mj_defaultStatistic(mjStatistic* stat);
|
|||||||
// allocate mjModel
|
// allocate mjModel
|
||||||
void mj_makeModel(mjModel** dest,
|
void mj_makeModel(mjModel** dest,
|
||||||
int nq, int nv, int nu, int na, int nbody, int nbvh, int nbvhstatic, int nbvhdynamic, int noct,
|
int nq, int nv, int nu, int na, int nbody, int nbvh, int nbvhstatic, int nbvhdynamic, int noct,
|
||||||
int njnt, int ngeom, int nsite, int ncam, int nlight, int nflex, int nflexnode, int nflexvert,
|
int njnt, int nM, int nB, int nC, int nD, int ngeom, int nsite, int ncam, int nlight, int nflex,
|
||||||
int nflexedge, int nflexelem, int nflexelemdata, int nflexelemedge, int nflexshelldata,
|
int nflexnode, int nflexvert, int nflexedge, int nflexelem, int nflexelemdata,
|
||||||
int nflexevpair, int nflextexcoord, int nmesh, int nmeshvert, int nmeshnormal,
|
int nflexelemedge, int nflexshelldata, int nflexevpair, int nflextexcoord, int nmesh,
|
||||||
int nmeshtexcoord, int nmeshface, int nmeshgraph, int nmeshpoly, int nmeshpolyvert,
|
int nmeshvert, int nmeshnormal, int nmeshtexcoord, int nmeshface, int nmeshgraph, int nmeshpoly,
|
||||||
int nmeshpolymap, int nskin, int nskinvert, int nskintexvert, int nskinface, int nskinbone,
|
int nmeshpolyvert, int nmeshpolymap, int nskin, int nskinvert, int nskintexvert, int nskinface,
|
||||||
int nskinbonevert, int nhfield, int nhfielddata, int ntex, int ntexdata, int nmat, int npair,
|
int nskinbone, int nskinbonevert, int nhfield, int nhfielddata, int ntex, int ntexdata,
|
||||||
int nexclude, int neq, int ntendon, int nwrap, int nsensor, int nnumeric, int nnumericdata, int ntext,
|
int nmat, int npair, int nexclude, int neq, int ntendon, int nwrap, int nsensor, int nnumeric,
|
||||||
int ntextdata, int ntuple, int ntupledata, int nkey, int nmocap, int nplugin, int npluginattr,
|
int nnumericdata, int ntext, int ntextdata, int ntuple, int ntupledata, int nkey, int nmocap,
|
||||||
int nuser_body, int nuser_jnt, int nuser_geom, int nuser_site, int nuser_cam, int nuser_tendon,
|
int nplugin, int npluginattr, int nuser_body, int nuser_jnt, int nuser_geom, int nuser_site,
|
||||||
int nuser_actuator, int nuser_sensor, int nnames, int npaths);
|
int nuser_cam, int nuser_tendon, int nuser_actuator, int nuser_sensor, int nnames, int npaths);
|
||||||
|
|
||||||
// copy mjModel; allocate new if dest is NULL
|
// copy mjModel; allocate new if dest is NULL
|
||||||
MJAPI mjModel* mj_copyModel(mjModel* dest, const mjModel* src);
|
MJAPI mjModel* mj_copyModel(mjModel* dest, const mjModel* src);
|
||||||
@@ -85,6 +85,25 @@ MJAPI int mj_sizeModel(const mjModel* m);
|
|||||||
// validate reference fields in a model; return null if valid, error message otherwise
|
// validate reference fields in a model; return null if valid, error message otherwise
|
||||||
MJAPI const char* mj_validateReferences(const mjModel* m);
|
MJAPI const char* mj_validateReferences(const mjModel* m);
|
||||||
|
|
||||||
|
// construct sparse representation of dof-dof matrix
|
||||||
|
MJAPI void mj_makeDofDofSparse(int nv, int nC, int nD, int nM,
|
||||||
|
const int* dof_parentid, const int* dof_simplenum,
|
||||||
|
int* rownnz, int* rowadr, int* diag, int* colind,
|
||||||
|
int reduced, int upper, int* remaining);
|
||||||
|
|
||||||
|
// construct sparse representation of body-dof matrix
|
||||||
|
MJAPI void mj_makeBSparse(int nv, int nbody, int nB,
|
||||||
|
const int* body_dofnum, const int* body_parentid, const int* body_dofadr,
|
||||||
|
int* B_rownnz, int* B_rowadr, int* B_colind,
|
||||||
|
int* count);
|
||||||
|
|
||||||
|
// construct index mappings between M <-> D, M (legacy) -> M (CSR)
|
||||||
|
MJAPI void mj_makeDofDofMaps(int nv, int nM, int nC, int nD,
|
||||||
|
const int* dof_Madr, const int* dof_simplenum, const int* dof_parentid,
|
||||||
|
const int* D_rownnz, const int* D_rowadr, const int* D_colind,
|
||||||
|
const int* M_rownnz, const int* M_rowadr,
|
||||||
|
int* mapM2D, int* mapD2M, int* mapM2M,
|
||||||
|
int* remaining, int* M, int* D);
|
||||||
|
|
||||||
//------------------------------- mjData -----------------------------------------------------------
|
//------------------------------- mjData -----------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -482,7 +482,9 @@ void mj_printFormattedModel(const mjModel* m, const char* filename, const char*
|
|||||||
const int* object_class;
|
const int* object_class;
|
||||||
|
|
||||||
#define X(type, name, num, sz) \
|
#define X(type, name, num, sz) \
|
||||||
if (&m->num == object_class && (strncmp(#name, "name_", 5) != 0) && sz > 0) { \
|
if (&m->num == object_class && strncmp(#name, "name_", 5) && \
|
||||||
|
strncmp(#name, "M_", 2) && strncmp(#name, "B_", 2) && \
|
||||||
|
strncmp(#name, "D_", 2) && sz > 0) { \
|
||||||
const char* format = _Generic(*m->name, \
|
const char* format = _Generic(*m->name, \
|
||||||
double: float_format, \
|
double: float_format, \
|
||||||
float: float_format, \
|
float: float_format, \
|
||||||
@@ -873,6 +875,35 @@ void mj_printFormattedModel(const mjModel* m, const char* filename, const char*
|
|||||||
|
|
||||||
#undef X
|
#undef X
|
||||||
|
|
||||||
|
// B sparse structure
|
||||||
|
mj_printSparsity("B: body-dof matrix", m->nbody, m->nv, m->B_rowadr, NULL, m->B_rownnz, NULL,
|
||||||
|
m->B_colind, fp);
|
||||||
|
printArrayInt("B_ROWNNZ", 1, m->nbody, m->B_rownnz, fp);
|
||||||
|
printArrayInt("B_ROWADR", 1, m->nbody, m->B_rowadr, fp);
|
||||||
|
printArrayInt("B_COLIND", 1, m->nB, m->B_colind, fp);
|
||||||
|
|
||||||
|
// M sparse structure
|
||||||
|
mj_printSparsity("M: reduced inertia matrix", m->nv, m->nv, m->M_rowadr, NULL, m->M_rownnz,
|
||||||
|
NULL, m->M_colind, fp);
|
||||||
|
printArrayInt("M_ROWNNZ", 1, m->nv, m->M_rownnz, fp);
|
||||||
|
printArrayInt("M_ROWADR", 1, m->nv, m->M_rowadr, fp);
|
||||||
|
printArrayInt("M_COLIND", 1, m->nC, m->M_colind, fp);
|
||||||
|
printArrayInt("MAPM2M", 1, m->nC, m->mapM2M, fp);
|
||||||
|
|
||||||
|
// D sparse structure
|
||||||
|
mj_printSparsity("D: dof-dof matrix", m->nv, m->nv,
|
||||||
|
m->D_rowadr, m->D_diag, m->D_rownnz, NULL, m->D_colind, fp);
|
||||||
|
printArrayInt("D_ROWNNZ", 1, m->nv, m->D_rownnz, fp);
|
||||||
|
printArrayInt("D_ROWADR", 1, m->nv, m->D_rowadr, fp);
|
||||||
|
printArrayInt("D_COLIND", 1, m->nD, m->D_colind, fp);
|
||||||
|
printArrayInt("MAPM2D", 1, m->nD, m->mapM2D, fp);
|
||||||
|
printArrayInt("MAPD2M", 1, m->nM, m->mapD2M, fp);
|
||||||
|
|
||||||
|
// signature
|
||||||
|
fprintf(fp, "\nSIGNATURE\n");
|
||||||
|
fprintf(fp, " %lu\n", (unsigned long) m->signature);
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
// BVHs
|
// BVHs
|
||||||
fprintf(fp, "BVH:\n");
|
fprintf(fp, "BVH:\n");
|
||||||
fprintf(fp, " %-8s%-8s%-8s%-10s%-s\n","id", "depth", "nodeid", "child[0]" ,"child[1]");
|
fprintf(fp, " %-8s%-8s%-8s%-10s%-s\n","id", "depth", "nodeid", "child[0]" ,"child[1]");
|
||||||
|
|||||||
+29
-6
@@ -2932,12 +2932,10 @@ void mjCModel::CopyTree(mjModel* m) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nM_post != nM) throw mjCError(0, "nM mismatch: pre %d, post %d", nullptr, nM, nM_post);
|
if (nM_post != nM) throw mjCError(0, "nM mismatch: pre %d, post %d", nullptr, nM, nM_post);
|
||||||
m->nM = nM_post;
|
|
||||||
|
|
||||||
// recompute nD, validate
|
// recompute nD, validate
|
||||||
int nD_post = 2 * m->nM - nv;
|
int nD_post = 2 * m->nM - nv;
|
||||||
if (nD_post != nD) throw mjCError(0, "nD mismatch: pre %d, post %d", nullptr, nD, nD_post);
|
if (nD_post != nD) throw mjCError(0, "nD mismatch: pre %d, post %d", nullptr, nD, nD_post);
|
||||||
m->nD = nD_post;
|
|
||||||
|
|
||||||
// bodies_[]->subtreedofs already computed in ComputeSparseSizes
|
// bodies_[]->subtreedofs already computed in ComputeSparseSizes
|
||||||
|
|
||||||
@@ -2954,7 +2952,6 @@ void mjCModel::CopyTree(mjModel* m) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nB_post != nB) throw mjCError(0, "nB mismatch: pre %d, post %d", nullptr, nB, nB_post);
|
if (nB_post != nB) throw mjCError(0, "nB mismatch: pre %d, post %d", nullptr, nB, nB_post);
|
||||||
m->nB = nB_post;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy plugin data
|
// copy plugin data
|
||||||
@@ -3799,7 +3796,6 @@ void mjCModel::FinalizeSimple(mjModel* m) {
|
|||||||
}
|
}
|
||||||
int nC_post = nOD + nv;
|
int nC_post = nOD + nv;
|
||||||
if (nC_post != nC) throw mjCError(0, "nC mismatch: pre %d, post %d", nullptr, nC, nC_post);
|
if (nC_post != nC) throw mjCError(0, "nC mismatch: pre %d, post %d", nullptr, nC, nC_post);
|
||||||
m->nC = nC_post;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -4774,8 +4770,8 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
|||||||
|
|
||||||
// create low-level model
|
// create low-level model
|
||||||
mj_makeModel(&m,
|
mj_makeModel(&m,
|
||||||
nq, nv, nu, na, nbody, nbvh, nbvhstatic, nbvhdynamic, noct, njnt, ngeom, nsite,
|
nq, nv, nu, na, nbody, nbvh, nbvhstatic, nbvhdynamic, noct, njnt, nM, nB, nC, nD,
|
||||||
ncam, nlight, nflex, nflexnode, nflexvert, nflexedge, nflexelem,
|
ngeom, nsite, ncam, nlight, nflex, nflexnode, nflexvert, nflexedge, nflexelem,
|
||||||
nflexelemdata, nflexelemedge, nflexshelldata, nflexevpair, nflextexcoord,
|
nflexelemdata, nflexelemedge, nflexshelldata, nflexevpair, nflextexcoord,
|
||||||
nmesh, nmeshvert, nmeshnormal, nmeshtexcoord, nmeshface, nmeshgraph, nmeshpoly,
|
nmesh, nmeshvert, nmeshnormal, nmeshtexcoord, nmeshface, nmeshgraph, nmeshpoly,
|
||||||
nmeshpolyvert, nmeshpolymap, nskin, nskinvert, nskintexvert, nskinface, nskinbone,
|
nmeshpolyvert, nmeshpolymap, nskin, nskinvert, nskintexvert, nskinface, nskinbone,
|
||||||
@@ -4852,6 +4848,33 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
|
|||||||
m->narena = kMegabyte * (nstack_mb + residual_mb);
|
m->narena = kMegabyte * (nstack_mb + residual_mb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sparsity structures
|
||||||
|
{
|
||||||
|
std::vector<int> remaining(m->nv);
|
||||||
|
std::vector<int> count(m->nbody);
|
||||||
|
std::vector<int> M(m->nM);
|
||||||
|
std::vector<int> D(m->nD);
|
||||||
|
|
||||||
|
// make D
|
||||||
|
mj_makeDofDofSparse(m->nv, m->nC, m->nD, m->nM, m->dof_parentid, m->dof_simplenum,
|
||||||
|
m->D_rownnz, m->D_rowadr, m->D_diag, m->D_colind,
|
||||||
|
/*reduced=*/0, /*upper=*/1, remaining.data());
|
||||||
|
|
||||||
|
// make B
|
||||||
|
mj_makeBSparse(m->nv, m->nbody, m->nB, m->body_dofnum, m->body_parentid,
|
||||||
|
m->body_dofadr, m->B_rownnz, m->B_rowadr, m->B_colind, count.data());
|
||||||
|
|
||||||
|
// make C
|
||||||
|
mj_makeDofDofSparse(m->nv, m->nC, m->nD, m->nM, m->dof_parentid, m->dof_simplenum,
|
||||||
|
m->M_rownnz, m->M_rowadr, NULL, m->M_colind,
|
||||||
|
/*reduced=*/1, /*upper=*/0, remaining.data());
|
||||||
|
|
||||||
|
// make index mappings: mapM2D, mapD2M, mapM2M
|
||||||
|
mj_makeDofDofMaps(m->nv, m->nM, m->nC, m->nD, m->dof_Madr, m->dof_simplenum, m->dof_parentid,
|
||||||
|
m->D_rownnz, m->D_rowadr, m->D_colind, m->M_rownnz, m->M_rowadr,
|
||||||
|
m->mapM2D, m->mapD2M, m->mapM2M, remaining.data(), M.data(), D.data());
|
||||||
|
}
|
||||||
|
|
||||||
// create data
|
// create data
|
||||||
int disableflags = m->opt.disableflags;
|
int disableflags = m->opt.disableflags;
|
||||||
m->opt.disableflags |= mjDSBL_CONTACT;
|
m->opt.disableflags |= mjDSBL_CONTACT;
|
||||||
|
|||||||
@@ -5267,6 +5267,10 @@ public unsafe struct mjModel_ {
|
|||||||
public int nbvhdynamic;
|
public int nbvhdynamic;
|
||||||
public int noct;
|
public int noct;
|
||||||
public int njnt;
|
public int njnt;
|
||||||
|
public int nM;
|
||||||
|
public int nB;
|
||||||
|
public int nC;
|
||||||
|
public int nD;
|
||||||
public int ngeom;
|
public int ngeom;
|
||||||
public int nsite;
|
public int nsite;
|
||||||
public int ncam;
|
public int ncam;
|
||||||
@@ -5328,10 +5332,6 @@ public unsafe struct mjModel_ {
|
|||||||
public int nnames;
|
public int nnames;
|
||||||
public int npaths;
|
public int npaths;
|
||||||
public int nnames_map;
|
public int nnames_map;
|
||||||
public int nM;
|
|
||||||
public int nB;
|
|
||||||
public int nC;
|
|
||||||
public int nD;
|
|
||||||
public int nJmom;
|
public int nJmom;
|
||||||
public int ntree;
|
public int ntree;
|
||||||
public int ngravcomp;
|
public int ngravcomp;
|
||||||
@@ -5762,6 +5762,19 @@ public unsafe struct mjModel_ {
|
|||||||
public char* names;
|
public char* names;
|
||||||
public int* names_map;
|
public int* names_map;
|
||||||
public char* paths;
|
public char* paths;
|
||||||
|
public int* B_rownnz;
|
||||||
|
public int* B_rowadr;
|
||||||
|
public int* B_colind;
|
||||||
|
public int* M_rownnz;
|
||||||
|
public int* M_rowadr;
|
||||||
|
public int* M_colind;
|
||||||
|
public int* mapM2M;
|
||||||
|
public int* D_rownnz;
|
||||||
|
public int* D_rowadr;
|
||||||
|
public int* D_diag;
|
||||||
|
public int* D_colind;
|
||||||
|
public int* mapM2D;
|
||||||
|
public int* mapD2M;
|
||||||
public UInt64 signature;
|
public UInt64 signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user