Dynamically allocate contact and efc_ arrays on a new memory arena.

- Add private function `mj_arenaAlloc`. This is used internally to allocate memory from the arena.

- Add private function `mj_nefc` to count constraints. This function returns a tight upper bound on `d->nefc`. The number of counted constraints can be slightly bigger than exact `d->nefc` in the case of constraints with empty Jacobian, as when placing a frictional tendon between two world sites.

- Add new `memory` attribute to the `size` XML element for specification of arena memory size. This attribute is mutually exclusive with `nstack` and `njmax` specifications, which are now deprecated (but left around for the time being for legacy compatibility).

- Move `d->stack` to the end of the new arena space. The stack now grows in reverse from the end.

PiperOrigin-RevId: 479341539
Change-Id: Ie019c202e0908577ffc6f833a37920858116f667
This commit is contained in:
Saran Tunyasuvunakool
2022-10-06 10:02:35 -07:00
committed by Copybara-Service
parent 4d85a464cc
commit 58fd72f53d
29 changed files with 1281 additions and 433 deletions
+48 -39
View File
@@ -15,6 +15,7 @@
#ifndef MUJOCO_MJDATA_H_
#define MUJOCO_MJDATA_H_
#include <stddef.h>
#include <stdint.h>
#include <mujoco/mjtnum.h>
@@ -124,15 +125,19 @@ typedef struct mjSolverStat_ mjSolverStat;
struct mjData_ {
// constant sizes
int nstack; // number of mjtNums that can fit in stack
int nstack; // number of mjtNums that can fit in the arena+stack space
int nbuffer; // size of main buffer in bytes
int nplugin; // number of plugin instances
// stack pointer
int pstack; // first available mjtNum address in stack
size_t pstack; // first available mjtNum address in stack
// arena pointer
size_t parena; // first available byte in arena
// memory utilization stats
int maxuse_stack; // maximum stack allocation
size_t maxuse_arena; // maximum arena allocation
int maxuse_con; // maximum number of contacts
int maxuse_efc; // maximum number of scalar constraints
@@ -157,8 +162,8 @@ struct mjData_ {
//-------------------------------- end of info header
// buffers
void* buffer; // main buffer; all pointers point in it (nbuffer bytes)
mjtNum* stack; // stack buffer (nstack mjtNums)
void* buffer; // main buffer; all pointers point in it (nbuffer bytes)
void* arena; // arena+stack buffer (nstack*sizeof(mjtNum) bytes)
//-------------------------------- main inputs and outputs of the computation
@@ -240,36 +245,6 @@ struct mjData_ {
mjtNum* qLDiagInv; // 1/diag(D) (nv x 1)
mjtNum* qLDiagSqrtInv; // 1/sqrt(diag(D)) (nv x 1)
// computed by mj_fwdPosition/mj_collision
mjContact* contact; // list of all detected contacts (nconmax x 1)
// computed by mj_fwdPosition/mj_makeConstraint
int* efc_type; // constraint type (mjtConstraint) (njmax x 1)
int* efc_id; // id of object of specified type (njmax x 1)
int* efc_J_rownnz; // number of non-zeros in Jacobian row (njmax x 1)
int* efc_J_rowadr; // row start address in colind array (njmax x 1)
int* efc_J_rowsuper; // number of subsequent rows in supernode (njmax x 1)
int* efc_J_colind; // column indices in Jacobian (njmax x nv)
int* efc_JT_rownnz; // number of non-zeros in Jacobian row T (nv x 1)
int* efc_JT_rowadr; // row start address in colind array T (nv x 1)
int* efc_JT_rowsuper; // number of subsequent rows in supernode T (nv x 1)
int* efc_JT_colind; // column indices in Jacobian T (nv x njmax)
mjtNum* efc_J; // constraint Jacobian (njmax x nv)
mjtNum* efc_JT; // constraint Jacobian transposed (nv x njmax)
mjtNum* efc_pos; // constraint position (equality, contact) (njmax x 1)
mjtNum* efc_margin; // inclusion margin (contact) (njmax x 1)
mjtNum* efc_frictionloss; // frictionloss (friction) (njmax x 1)
mjtNum* efc_diagApprox; // approximation to diagonal of A (njmax x 1)
mjtNum* efc_KBIP; // stiffness, damping, impedance, imp' (njmax x 4)
mjtNum* efc_D; // constraint mass (njmax x 1)
mjtNum* efc_R; // inverse constraint mass (njmax x 1)
// computed by mj_fwdPosition/mj_projectConstraint
int* efc_AR_rownnz; // number of non-zeros in AR (njmax x 1)
int* efc_AR_rowadr; // row start address in colind array (njmax x 1)
int* efc_AR_colind; // column indices in sparse AR (njmax x njmax)
mjtNum* efc_AR; // J*inv(M)*J' + R (njmax x njmax)
//-------------------------------- POSITION, VELOCITY dependent
// computed by mj_fwdVelocity
@@ -287,8 +262,8 @@ struct mjData_ {
mjtNum* qfrc_passive; // passive force (nv x 1)
// computed by mj_fwdVelocity/mj_referenceConstraint
mjtNum* efc_vel; // velocity in constraint space: J*qvel (njmax x 1)
mjtNum* efc_aref; // reference pseudo-acceleration (njmax x 1)
mjtNum* efc_vel; // velocity in constraint space: J*qvel (nefc x 1)
mjtNum* efc_aref; // reference pseudo-acceleration (nefc x 1)
// computed by mj_sensorVel/mj_subtreeVel if needed
mjtNum* subtree_linvel; // linear velocity of subtree com (nbody x 3)
@@ -320,9 +295,6 @@ struct mjData_ {
mjtNum* qacc_smooth; // unconstrained acceleration (nv x 1)
// computed by mj_fwdConstraint/mj_inverse
mjtNum* efc_b; // linear cost term: J*qacc_smooth - aref (njmax x 1)
mjtNum* efc_force; // constraint force in constraint space (njmax x 1)
int* efc_state; // constraint state (mjtConstraintState) (njmax x 1)
mjtNum* qfrc_constraint; // constraint force (nv x 1)
// computed by mj_inverse
@@ -333,6 +305,43 @@ struct mjData_ {
mjtNum* cacc; // com-based acceleration (nbody x 6)
mjtNum* cfrc_int; // com-based interaction force with parent (nbody x 6)
mjtNum* cfrc_ext; // com-based external force on body (nbody x 6)
//-------------------------------- ARENA-ALLOCATED ARRAYS
// computed by mj_collision
mjContact* contact; // list of all detected contacts (ncon x 1)
// computed by mj_makeConstraint
int* efc_type; // constraint type (mjtConstraint) (nefc x 1)
int* efc_id; // id of object of specified type (nefc x 1)
int* efc_J_rownnz; // number of non-zeros in Jacobian row (nefc x 1)
int* efc_J_rowadr; // row start address in colind array (nefc x 1)
int* efc_J_rowsuper; // number of subsequent rows in supernode (nefc x 1)
int* efc_J_colind; // column indices in Jacobian (nefc x nv)
int* efc_JT_rownnz; // number of non-zeros in Jacobian row T (nv x 1)
int* efc_JT_rowadr; // row start address in colind array T (nv x 1)
int* efc_JT_rowsuper; // number of subsequent rows in supernode T (nv x 1)
int* efc_JT_colind; // column indices in Jacobian T (nv x nefc)
mjtNum* efc_J; // constraint Jacobian (nefc x nv)
mjtNum* efc_JT; // constraint Jacobian transposed (nv x nefc)
mjtNum* efc_pos; // constraint position (equality, contact) (nefc x 1)
mjtNum* efc_margin; // inclusion margin (contact) (nefc x 1)
mjtNum* efc_frictionloss; // frictionloss (friction) (nefc x 1)
mjtNum* efc_diagApprox; // approximation to diagonal of A (nefc x 1)
mjtNum* efc_KBIP; // stiffness, damping, impedance, imp' (nefc x 4)
mjtNum* efc_D; // constraint mass (nefc x 1)
mjtNum* efc_R; // inverse constraint mass (nefc x 1)
// computed by mj_fwdConstraint/mj_inverse
mjtNum* efc_b; // linear cost term: J*qacc_smooth - aref (nefc x 1)
mjtNum* efc_force; // constraint force in constraint space (nefc x 1)
int* efc_state; // constraint state (mjtConstraintState) (nefc x 1)
// computed by mj_projectConstraint
int* efc_AR_rownnz; // number of non-zeros in AR (nefc x 1)
int* efc_AR_rowadr; // row start address in colind array (nefc x 1)
int* efc_AR_colind; // column indices in sparse AR (nefc x nefc)
mjtNum* efc_AR; // J*inv(M)*J' + R (nefc x nefc)
};
typedef struct mjData_ mjData;