Preparation for MIMO actuators: split actuator counts: nu (inputs), nactuator (objects), nout (outputs).

An actuator now owns a block of consecutive controls
(actuator_ctrladr/ctrlnum, width defined by the actuator type) and a block
of consecutive force outputs (actuator_outadr/outnum, width defined by the
transmission type). Force outputs are the scalars of actuation space: one
force, length, velocity and moment row each. nout = dim(actuator_force) is
derived from transmission types; all current types have width 1, so all
three counts coincide for every existing model and behavior is bit-exact.

Array re-keying: ctrlrange/ctrllimited by nu; forcerange/forcelimited/gear/
acc0/length0/lengthrange and the moment row structure by nout; everything
else per actuator. The mjModel actuator block is re-sorted by size key.

Layout-breaking, not behavior-breaking: saved .mjb files are invalidated
(size list changed) and recompilation is required.

PiperOrigin-RevId: 948351772
Change-Id: Icbc196ffa083cb1eaa6f1a3710869c89d8f62540
This commit is contained in:
Yuval Tassa
2026-07-15 08:29:38 -07:00
committed by Copybara-Service
parent 06f12a9372
commit d507e92198
27 changed files with 750 additions and 538 deletions
+5
View File
@@ -31,6 +31,11 @@ General
error instead of the generic "could not decode content" message.
- Added support for resource writing via :ref:`mju_writeResource` and the ``write`` callback in :ref:`mjpResourceProvider`.
- Added support for :ref:`multiccd <coMultiCCD>` with arbitrarily large meshes.
- Refactored actuator infrastructure in preparation for MIMO (multi-input multi-output) actuator support. Each actuator
now has ``ctrlnum`` (number of controls) and ``outnum`` (number of force outputs). The total counts
``nu = sum(ctrlnum)`` and ``nout = sum(outnum)`` dimension ``mjData.ctrl`` and ``mjData.actuator_force``,
respectively, ``nactuator`` is the number of actuators. For existing actuators ``ctrnum = outnum = 1``, so
``nactuator == nu == nout`` and existing code is unaffected.
.. admonition:: Breaking API changes
:class: attention
+34 -27
View File
@@ -262,12 +262,21 @@ detailed summary of the :ref:`simulation pipeline <Pipeline>` is given at the en
Actuation model
~~~~~~~~~~~~~~~
MuJoCo provides a flexible actuator model. All actuators are single-input-single-output (SISO). The input to actuator
:math:`i` is a scalar control :math:`u_i` specified by the user. The output is a scalar force :math:`p_i` which is
mapped to joint coordinates by a vector of moment arms determined by the transmission. An actuator can also have
activation state :math:`w_i` with its own dynamics. The control inputs for all actuators are stored in ``mjData.ctrl``,
the force outputs are stored in ``mjData.actuator_force``, and the activation states (if any) are stored in
``mjData.act``.
MuJoCo provides a flexible actuator model. Most actuators are single-input-single-output (SISO): the input to
actuator :math:`i` is a scalar control :math:`u_i` specified by the user, and the output is a scalar force
:math:`p_i`, which is mapped to joint coordinates by a vector of moment arms determined by the transmission. An
actuator can also have activation state :math:`w_i` with its own dynamics. The control inputs for all actuators are
stored in ``mjData.ctrl``, the force outputs are stored in ``mjData.actuator_force``, and the activation states (if
any) are stored in ``mjData.act``.
More generally, an actuator can have several control inputs, several force outputs, or both. For example, a servo
which accepts both a position setpoint and a velocity setpoint has two inputs and one output. The number of inputs
is a property of the actuator type, and the number of outputs is a property of its transmission; neither is
specified directly by the user. Since the number of inputs and the number of outputs can vary per actuator, the model
has three separate counts: the number of actuators ``nactuator``, the total number of controls ``nu``, and the total
number of force outputs ``nout``. In a model where all actuators are SISO, all three are equal. Note that outputs are
counted in actuation space, before the mapping to joint coordinates: a tendon actuator with a single force output can
move many joints.
These three components of an actuator -- transmission, activation dynamics, and force generation -- determine how the
actuator works. The user can set them independently for maximum flexibility, or use :ref:`Actuator shortcuts
@@ -278,11 +287,13 @@ actuator works. The user can set them independently for maximum flexibility, or
Transmission
^^^^^^^^^^^^
Each actuator has a scalar length :math:`l_i(q)` defined by the type of transmission and its parameters. The gradient
:math:`\nabla l_i` is an :math:`\nv`-dimensional vector of moment arms. It determines the mapping from scalar
actuator force to joint force. The transmission properties are determined by the MuJoCo object to which the actuator
is attached; the possible attachment object types are :at:`joint`, :at:`tendon`, :at:`jointinparent`,
:at:`slider-crank`, :at:`site`, and :at:`body`.
The transmission attaches the actuator to the rest of the system. Each force output of the actuator has a scalar
length :math:`l_k(q)`, defined by the type of transmission and its parameters, for example the
:ref:`gear<actuator-general-gear>` vector. The gradient :math:`\nabla l_k` is an :math:`\nv`-dimensional vector of
moment arms; it determines the mapping from the scalar output force to joint forces. The number of force outputs is
likewise determined by the transmission; all the types listed below define a single output. The transmission
properties are determined by the MuJoCo object to which the actuator is attached; the possible attachment object
types are :at:`joint`, :at:`tendon`, :at:`jointinparent`, :at:`slider-crank`, :at:`site`, and :at:`body`.
:at:`joint` and :at:`tendon`
The :at:`joint` and :at:`tendon` transmission types act as expected and correspond to the actuator applying forces or
@@ -369,14 +380,10 @@ diverge for :math:`\texttt{t} < h`, while exactly-integrated filters are stable
Force generation
^^^^^^^^^^^^^^^^
Each actuator generates a scalar force :math:`p_i` which is some function
.. math::
p_i \left( u_i, w_i, l_i, \dot{l}_i \right)
Similarly to activation dynamics, the force generation mechanism is actuator-specific and cannot interact with the
other actuators in the model. Currently the force is affine in the activation state when present, and in the control
otherwise:
Each actuator generates a scalar force for each of its outputs, as a function of its controls, activation states,
and lengths and velocities. Similarly to activation dynamics, force generation is actuator-specific: the inputs and
outputs of a single actuator can interact, but different actuators cannot affect each other. For SISO actuators the
force is affine in the activation state when present, and in the control otherwise:
.. math::
p_i = (a w_i \; \text{or} \; a u_i) + b_0 + b_1 l_i + b_2 \dot{l}_i
@@ -384,17 +391,17 @@ otherwise:
Here :math:`a` is an actuator-specific gain parameter and :math:`b_0, b_1, b_2` are actuator-specific bias
parameters, stored in ``mjModel.actuator_gainprm`` and ``mjModel.actuator_biasprm`` respectively. Different settings
of the gain and bias parameters can be used to model direct force control as well as position and velocity servos -in
which case the control/activation has the meaning of reference position or velocity. One can also compute custom gain
and bias terms by installing the callbacks :ref:`mjcb_act_gain` and :ref:`mjcb_act_bias` and setting the gain and
bias type to "user". Note that affine force generation makes it possible to infer the controls/activations from the
applied force computed in inverse dynamics, using the pseudo-inverse of the matrix of moment arms. However some of
the actuators used in the real world are not affine (especially those that have embedded low-level controllers), so
we are considering extensions to the above model.
which case the control/activation has the meaning of reference position or velocity. Multi-input actuator types
define their own force laws. One can also compute custom gain and bias terms for SISO actuators by installing the
callbacks :ref:`mjcb_act_gain` and :ref:`mjcb_act_bias` and setting the gain and bias type to "user". Note that
affine force generation makes it possible to infer the controls/activations from the applied force computed in
inverse dynamics, using the pseudo-inverse of the matrix of moment arms.
Putting all this together, the net force in generalized coordinates contributed by all actuators is
Putting all this together, the net force in generalized coordinates contributed by all actuators is the sum over all
force outputs
.. math::
\sum_i \nabla l_i(q) \; p_i \left(u_i, w_i, l_i(q), \dot{l}_i(q, v) \right)
\sum_k \nabla l_k(q) \; p_k
This quantity is stored in ``mjData.qfrc_actuator``. It is added to the applied force vector :math:`\tau`, together
with any user-defined forces in joint or Cartesian coordinates (which are stored in ``mjData.qfrc_applied`` and
+43 -37
View File
@@ -215,9 +215,9 @@ typedef struct mjData_ {
mjtNum* wrap_xpos; // Cartesian 3D points in all paths (nwrap x 6)
// computed by mj_fwdPosition/mj_transmission
mjtNum* actuator_length; // actuator lengths (nu x 1)
int* moment_rownnz; // number of non-zeros in actuator_moment row (nu x 1)
int* moment_rowadr; // row start address in colind array (nu x 1)
mjtNum* actuator_length; // actuator lengths, one per force output (nout x 1)
int* moment_rownnz; // number of non-zeros in actuator_moment row (nout x 1)
int* moment_rowadr; // row start address in colind array (nout x 1)
int* moment_colind; // column indices in sparse Jacobian (nJmom x 1)
mjtNum* actuator_moment; // actuator moments (nJmom x 1)
@@ -244,7 +244,7 @@ typedef struct mjData_ {
// computed by mj_fwdVelocity
mjtNum* flexedge_velocity; // flex edge velocities (nflexedge x 1)
mjtNum* ten_velocity; // tendon velocities (ntendon x 1)
mjtNum* actuator_velocity; // actuator velocities (nu x 1)
mjtNum* actuator_velocity; // actuator velocities, one per force output (nout x 1)
// computed by mj_fwdVelocity/mj_comVel
mjtNum* cvel; // com-based velocity (rot:lin) (nbody x 6)
@@ -277,8 +277,8 @@ typedef struct mjData_ {
//-------------------- POSITION, VELOCITY, CONTROL/ACCELERATION dependent
// computed by mj_fwdActuation
mjtNum* actuator_force; // actuator force in actuation space (nu x 1)
mjtNum* qfrc_actuator; // actuator force (nv x 1)
mjtNum* actuator_force; // actuator force in actuation space (nout x 1)
mjtNum* qfrc_actuator; // actuator force in joint space (nv x 1)
// computed by mj_fwdAcceleration
mjtNum* qfrc_smooth; // net unconstrained force (nv x 1)
@@ -557,7 +557,9 @@ typedef struct mjModel_ {
// sizes needed at mjModel construction
mjtSize nq; // number of generalized coordinates = dim(qpos)
mjtSize nv; // number of degrees of freedom = dim(qvel)
mjtSize nu; // number of actuators/controls = dim(ctrl)
mjtSize nu; // number of scalar controls = dim(ctrl)
mjtSize nactuator; // number of actuators
mjtSize nout; // number of force outputs, derived from transmission type
mjtSize na; // number of activation states = dim(act)
mjtSize nbody; // number of bodies
mjtSize nbvh; // number of total bounding volumes in all bodies
@@ -1072,37 +1074,41 @@ typedef struct mjModel_ {
mjtNum* wrap_prm; // divisor, joint coef, or site id (nwrap x 1)
// actuators
int* actuator_trntype; // transmission type (mjtTrn) (nu x 1)
int* actuator_dyntype; // dynamics type (mjtDyn) (nu x 1)
int* actuator_gaintype; // gain type (mjtGain) (nu x 1)
int* actuator_biastype; // bias type (mjtBias) (nu x 1)
int* actuator_trnid; // transmission id: joint, tendon, site (nu x 2)
mjtNum* actuator_damping; // linear damping coefficient (nu x 1)
mjtNum* actuator_dampingpoly; // high-order damping coefficients (nu x mjNPOLY)
mjtNum* actuator_armature; // armature added to target (joint, tendon) (nu x 1)
int* actuator_actadr; // first activation address; -1: stateless (nu x 1)
int* actuator_actnum; // number of activation variables (nu x 1)
int* actuator_group; // group for visibility (nu x 1)
int* actuator_history; // history buffer: [nsample, interp] (nu x 2)
int* actuator_historyadr; // address in history buffer; -1: none (nu x 1)
mjtNum* actuator_delay; // delay time in seconds; 0: no delay (nu x 1)
int* actuator_trntype; // transmission type (mjtTrn) (nactuator x 1)
int* actuator_dyntype; // dynamics type (mjtDyn) (nactuator x 1)
int* actuator_gaintype; // gain type (mjtGain) (nactuator x 1)
int* actuator_biastype; // bias type (mjtBias) (nactuator x 1)
int* actuator_ctrladr; // address of first control (nactuator x 1)
int* actuator_ctrlnum; // number of controls (nactuator x 1)
int* actuator_outadr; // address of first force output (nactuator x 1)
int* actuator_outnum; // number of force outputs, from trntype (nactuator x 1)
int* actuator_actadr; // first activation address; -1: stateless (nactuator x 1)
int* actuator_actnum; // number of activation variables (nactuator x 1)
int* actuator_trnid; // transmission id: joint, tendon, site (nactuator x 2)
mjtNum* actuator_cranklength; // crank length for slider-crank (nactuator x 1)
mjtNum* actuator_dynprm; // dynamics parameters (nactuator x mjNDYN)
mjtNum* actuator_gainprm; // gain parameters (nactuator x mjNGAIN)
mjtNum* actuator_biasprm; // bias parameters (nactuator x mjNBIAS)
mjtBool* actuator_actlimited; // is activation limited (nactuator x 1)
mjtNum* actuator_actrange; // range of activations (nactuator x 2)
mjtBool* actuator_actearly; // step activation before force (nactuator x 1)
int* actuator_history; // history buffer: [nsample, interp] (nactuator x 2)
int* actuator_historyadr; // address in history buffer; -1: none (nactuator x 1)
mjtNum* actuator_delay; // delay time; 0: no delay (nactuator x 1)
mjtNum* actuator_damping; // linear damping coefficient (nactuator x 1)
mjtNum* actuator_dampingpoly; // high-order damping coefficients (nactuator x mjNPOLY)
mjtNum* actuator_armature; // armature added to target (joint, tendon) (nactuator x 1)
int* actuator_group; // group for visibility (nactuator x 1)
mjtNum* actuator_user; // user data (nactuator x nuser_actuator)
int* actuator_plugin; // plugin instance id; -1: not a plugin (nactuator x 1)
mjtBool* actuator_ctrllimited; // is control limited (nu x 1)
mjtBool* actuator_forcelimited;// is force limited (nu x 1)
mjtBool* actuator_actlimited; // is activation limited (nu x 1)
mjtNum* actuator_dynprm; // dynamics parameters (nu x mjNDYN)
mjtNum* actuator_gainprm; // gain parameters (nu x mjNGAIN)
mjtNum* actuator_biasprm; // bias parameters (nu x mjNBIAS)
mjtBool* actuator_actearly; // step activation before force (nu x 1)
mjtNum* actuator_ctrlrange; // range of controls (nu x 2)
mjtNum* actuator_forcerange; // range of forces (nu x 2)
mjtNum* actuator_actrange; // range of activations (nu x 2)
mjtNum* actuator_gear; // scale length and transmitted force (nu x 6)
mjtNum* actuator_cranklength; // crank length for slider-crank (nu x 1)
mjtNum* actuator_acc0; // acceleration from unit force in qpos0 (nu x 1)
mjtNum* actuator_length0; // actuator length in qpos0 (nu x 1)
mjtNum* actuator_lengthrange; // feasible actuator length range (nu x 2)
mjtNum* actuator_user; // user data (nu x nuser_actuator)
int* actuator_plugin; // plugin instance id; -1: not a plugin (nu x 1)
mjtNum* actuator_gear; // scale length and transmitted force (nout x 6)
mjtBool* actuator_forcelimited;// is force limited (nout x 1)
mjtNum* actuator_forcerange; // range of forces (nout x 2)
mjtNum* actuator_acc0; // acceleration from unit force in qpos0 (nout x 1)
mjtNum* actuator_length0; // actuator length in qpos0 (nout x 1)
mjtNum* actuator_lengthrange; // feasible actuator length range (nout x 2)
// sensors
int* sensor_type; // sensor type (mjtSensor) (nsensor x 1)
@@ -1174,7 +1180,7 @@ typedef struct mjModel_ {
int* name_excludeadr; // exclude name pointers (nexclude x 1)
int* name_eqadr; // equality constraint name pointers (neq x 1)
int* name_tendonadr; // tendon name pointers (ntendon x 1)
int* name_actuatoradr; // actuator name pointers (nu x 1)
int* name_actuatoradr; // actuator name pointers (nactuator x 1)
int* name_sensoradr; // sensor name pointers (nsensor x 1)
int* name_numericadr; // numeric name pointers (nnumeric x 1)
int* name_textadr; // text name pointers (ntext x 1)
+6 -6
View File
@@ -239,9 +239,9 @@ typedef struct mjData_ {
mjtNum* wrap_xpos; // Cartesian 3D points in all paths (nwrap x 6)
// computed by mj_fwdPosition/mj_transmission
mjtNum* actuator_length; // actuator lengths (nu x 1)
int* moment_rownnz; // number of non-zeros in actuator_moment row (nu x 1)
int* moment_rowadr; // row start address in colind array (nu x 1)
mjtNum* actuator_length; // actuator lengths, one per force output (nout x 1)
int* moment_rownnz; // number of non-zeros in actuator_moment row (nout x 1)
int* moment_rowadr; // row start address in colind array (nout x 1)
int* moment_colind; // column indices in sparse Jacobian (nJmom x 1)
mjtNum* actuator_moment; // actuator moments (nJmom x 1)
@@ -268,7 +268,7 @@ typedef struct mjData_ {
// computed by mj_fwdVelocity
mjtNum* flexedge_velocity; // flex edge velocities (nflexedge x 1)
mjtNum* ten_velocity; // tendon velocities (ntendon x 1)
mjtNum* actuator_velocity; // actuator velocities (nu x 1)
mjtNum* actuator_velocity; // actuator velocities, one per force output (nout x 1)
// computed by mj_fwdVelocity/mj_comVel
mjtNum* cvel; // com-based velocity (rot:lin) (nbody x 6)
@@ -301,8 +301,8 @@ typedef struct mjData_ {
//-------------------- POSITION, VELOCITY, CONTROL/ACCELERATION dependent
// computed by mj_fwdActuation
mjtNum* actuator_force; // actuator force in actuation space (nu x 1)
mjtNum* qfrc_actuator; // actuator force (nv x 1)
mjtNum* actuator_force; // actuator force in actuation space (nout x 1)
mjtNum* qfrc_actuator; // actuator force in joint space (nv x 1)
// computed by mj_fwdAcceleration
mjtNum* qfrc_smooth; // net unconstrained force (nv x 1)
+37 -31
View File
@@ -245,7 +245,9 @@ typedef struct mjModel_ {
// sizes needed at mjModel construction
mjtSize nq; // number of generalized coordinates = dim(qpos)
mjtSize nv; // number of degrees of freedom = dim(qvel)
mjtSize nu; // number of actuators/controls = dim(ctrl)
mjtSize nu; // number of scalar controls = dim(ctrl)
mjtSize nactuator; // number of actuators
mjtSize nout; // number of force outputs, derived from transmission type
mjtSize na; // number of activation states = dim(act)
mjtSize nbody; // number of bodies
mjtSize nbvh; // number of total bounding volumes in all bodies
@@ -760,37 +762,41 @@ typedef struct mjModel_ {
mjtNum* wrap_prm; // divisor, joint coef, or site id (nwrap x 1)
// actuators
int* actuator_trntype; // transmission type (mjtTrn) (nu x 1)
int* actuator_dyntype; // dynamics type (mjtDyn) (nu x 1)
int* actuator_gaintype; // gain type (mjtGain) (nu x 1)
int* actuator_biastype; // bias type (mjtBias) (nu x 1)
int* actuator_trnid; // transmission id: joint, tendon, site (nu x 2)
mjtNum* actuator_damping; // linear damping coefficient (nu x 1)
mjtNum* actuator_dampingpoly; // high-order damping coefficients (nu x mjNPOLY)
mjtNum* actuator_armature; // armature added to target (joint, tendon) (nu x 1)
int* actuator_actadr; // first activation address; -1: stateless (nu x 1)
int* actuator_actnum; // number of activation variables (nu x 1)
int* actuator_group; // group for visibility (nu x 1)
int* actuator_history; // history buffer: [nsample, interp] (nu x 2)
int* actuator_historyadr; // address in history buffer; -1: none (nu x 1)
mjtNum* actuator_delay; // delay time in seconds; 0: no delay (nu x 1)
int* actuator_trntype; // transmission type (mjtTrn) (nactuator x 1)
int* actuator_dyntype; // dynamics type (mjtDyn) (nactuator x 1)
int* actuator_gaintype; // gain type (mjtGain) (nactuator x 1)
int* actuator_biastype; // bias type (mjtBias) (nactuator x 1)
int* actuator_ctrladr; // address of first control (nactuator x 1)
int* actuator_ctrlnum; // number of controls (nactuator x 1)
int* actuator_outadr; // address of first force output (nactuator x 1)
int* actuator_outnum; // number of force outputs, from trntype (nactuator x 1)
int* actuator_actadr; // first activation address; -1: stateless (nactuator x 1)
int* actuator_actnum; // number of activation variables (nactuator x 1)
int* actuator_trnid; // transmission id: joint, tendon, site (nactuator x 2)
mjtNum* actuator_cranklength; // crank length for slider-crank (nactuator x 1)
mjtNum* actuator_dynprm; // dynamics parameters (nactuator x mjNDYN)
mjtNum* actuator_gainprm; // gain parameters (nactuator x mjNGAIN)
mjtNum* actuator_biasprm; // bias parameters (nactuator x mjNBIAS)
mjtBool* actuator_actlimited; // is activation limited (nactuator x 1)
mjtNum* actuator_actrange; // range of activations (nactuator x 2)
mjtBool* actuator_actearly; // step activation before force (nactuator x 1)
int* actuator_history; // history buffer: [nsample, interp] (nactuator x 2)
int* actuator_historyadr; // address in history buffer; -1: none (nactuator x 1)
mjtNum* actuator_delay; // delay time; 0: no delay (nactuator x 1)
mjtNum* actuator_damping; // linear damping coefficient (nactuator x 1)
mjtNum* actuator_dampingpoly; // high-order damping coefficients (nactuator x mjNPOLY)
mjtNum* actuator_armature; // armature added to target (joint, tendon) (nactuator x 1)
int* actuator_group; // group for visibility (nactuator x 1)
mjtNum* actuator_user; // user data (nactuator x nuser_actuator)
int* actuator_plugin; // plugin instance id; -1: not a plugin (nactuator x 1)
mjtBool* actuator_ctrllimited; // is control limited (nu x 1)
mjtBool* actuator_forcelimited;// is force limited (nu x 1)
mjtBool* actuator_actlimited; // is activation limited (nu x 1)
mjtNum* actuator_dynprm; // dynamics parameters (nu x mjNDYN)
mjtNum* actuator_gainprm; // gain parameters (nu x mjNGAIN)
mjtNum* actuator_biasprm; // bias parameters (nu x mjNBIAS)
mjtBool* actuator_actearly; // step activation before force (nu x 1)
mjtNum* actuator_ctrlrange; // range of controls (nu x 2)
mjtNum* actuator_forcerange; // range of forces (nu x 2)
mjtNum* actuator_actrange; // range of activations (nu x 2)
mjtNum* actuator_gear; // scale length and transmitted force (nu x 6)
mjtNum* actuator_cranklength; // crank length for slider-crank (nu x 1)
mjtNum* actuator_acc0; // acceleration from unit force in qpos0 (nu x 1)
mjtNum* actuator_length0; // actuator length in qpos0 (nu x 1)
mjtNum* actuator_lengthrange; // feasible actuator length range (nu x 2)
mjtNum* actuator_user; // user data (nu x nuser_actuator)
int* actuator_plugin; // plugin instance id; -1: not a plugin (nu x 1)
mjtNum* actuator_gear; // scale length and transmitted force (nout x 6)
mjtBool* actuator_forcelimited;// is force limited (nout x 1)
mjtNum* actuator_forcerange; // range of forces (nout x 2)
mjtNum* actuator_acc0; // acceleration from unit force in qpos0 (nout x 1)
mjtNum* actuator_length0; // actuator length in qpos0 (nout x 1)
mjtNum* actuator_lengthrange; // feasible actuator length range (nout x 2)
// sensors
int* sensor_type; // sensor type (mjtSensor) (nsensor x 1)
@@ -862,7 +868,7 @@ typedef struct mjModel_ {
int* name_excludeadr; // exclude name pointers (nexclude x 1)
int* name_eqadr; // equality constraint name pointers (neq x 1)
int* name_tendonadr; // tendon name pointers (ntendon x 1)
int* name_actuatoradr; // actuator name pointers (nu x 1)
int* name_actuatoradr; // actuator name pointers (nactuator x 1)
int* name_sensoradr; // sensor name pointers (nsensor x 1)
int* name_numericadr; // numeric name pointers (nnumeric x 1)
int* name_textadr; // text name pointers (ntext x 1)
+41 -35
View File
@@ -163,6 +163,8 @@
X( nq ) \
X( nv ) \
X( nu ) \
X( nactuator ) \
X( nout ) \
X( na ) \
X( nbody ) \
X( nbvh ) \
@@ -666,37 +668,41 @@
X ( float, tendon_rgba, ntendon, 4 )
#define MJMODEL_POINTERS_ACTUATOR \
X ( int, actuator_trntype, nu, 1 ) \
X ( int, actuator_dyntype, nu, 1 ) \
X ( int, actuator_gaintype, nu, 1 ) \
X ( int, actuator_biastype, nu, 1 ) \
X ( int, actuator_trnid, nu, 2 ) \
X ( mjtNum, actuator_damping, nu, 1 ) \
X ( mjtNum, actuator_dampingpoly, nu, mjNPOLY ) \
X ( mjtNum, actuator_armature, nu, 1 ) \
X ( int, actuator_actadr, nu, 1 ) \
X ( int, actuator_actnum, nu, 1 ) \
X ( int, actuator_group, nu, 1 ) \
X ( int, actuator_history, nu, 2 ) \
X ( int, actuator_historyadr, nu, 1 ) \
X ( mjtNum, actuator_delay, nu, 1 ) \
X ( int, actuator_trntype, nactuator, 1 ) \
X ( int, actuator_dyntype, nactuator, 1 ) \
X ( int, actuator_gaintype, nactuator, 1 ) \
X ( int, actuator_biastype, nactuator, 1 ) \
X ( int, actuator_ctrladr, nactuator, 1 ) \
X ( int, actuator_ctrlnum, nactuator, 1 ) \
X ( int, actuator_outadr, nactuator, 1 ) \
X ( int, actuator_outnum, nactuator, 1 ) \
X ( int, actuator_actadr, nactuator, 1 ) \
X ( int, actuator_actnum, nactuator, 1 ) \
X ( int, actuator_trnid, nactuator, 2 ) \
X ( mjtNum, actuator_cranklength, nactuator, 1 ) \
X ( mjtNum, actuator_dynprm, nactuator, mjNDYN ) \
X ( mjtNum, actuator_gainprm, nactuator, mjNGAIN ) \
X ( mjtNum, actuator_biasprm, nactuator, mjNBIAS ) \
X ( mjtBool, actuator_actlimited, nactuator, 1 ) \
X ( mjtNum, actuator_actrange, nactuator, 2 ) \
X ( mjtBool, actuator_actearly, nactuator, 1 ) \
X ( int, actuator_history, nactuator, 2 ) \
X ( int, actuator_historyadr, nactuator, 1 ) \
X ( mjtNum, actuator_delay, nactuator, 1 ) \
X ( mjtNum, actuator_damping, nactuator, 1 ) \
X ( mjtNum, actuator_dampingpoly, nactuator, mjNPOLY ) \
X ( mjtNum, actuator_armature, nactuator, 1 ) \
X ( int, actuator_group, nactuator, 1 ) \
X ( mjtNum, actuator_user, nactuator, MJ_M(nuser_actuator) ) \
X ( int, actuator_plugin, nactuator, 1 ) \
X ( mjtBool, actuator_ctrllimited, nu, 1 ) \
X ( mjtBool, actuator_forcelimited, nu, 1 ) \
X ( mjtBool, actuator_actlimited, nu, 1 ) \
X ( mjtNum, actuator_dynprm, nu, mjNDYN ) \
X ( mjtNum, actuator_gainprm, nu, mjNGAIN ) \
X ( mjtNum, actuator_biasprm, nu, mjNBIAS ) \
X ( mjtBool, actuator_actearly, nu, 1 ) \
X ( mjtNum, actuator_ctrlrange, nu, 2 ) \
X ( mjtNum, actuator_forcerange, nu, 2 ) \
X ( mjtNum, actuator_actrange, nu, 2 ) \
X ( mjtNum, actuator_gear, nu, 6 ) \
X ( mjtNum, actuator_cranklength, nu, 1 ) \
X ( mjtNum, actuator_acc0, nu, 1 ) \
X ( mjtNum, actuator_length0, nu, 1 ) \
X ( mjtNum, actuator_lengthrange, nu, 2 ) \
X ( mjtNum, actuator_user, nu, MJ_M(nuser_actuator) ) \
X ( int, actuator_plugin, nu, 1 )
X ( mjtNum, actuator_gear, nout, 6 ) \
X ( mjtBool, actuator_forcelimited, nout, 1 ) \
X ( mjtNum, actuator_forcerange, nout, 2 ) \
X ( mjtNum, actuator_acc0, nout, 1 ) \
X ( mjtNum, actuator_length0, nout, 1 ) \
X ( mjtNum, actuator_lengthrange, nout, 2 )
#define MJMODEL_POINTERS_SENSOR \
X ( int, sensor_type, nsensor, 1 ) \
@@ -791,7 +797,7 @@
X ( int, name_excludeadr, nexclude, 1 ) \
X ( int, name_eqadr, neq, 1 ) \
X ( int, name_tendonadr, ntendon, 1 ) \
X ( int, name_actuatoradr, nu, 1 ) \
X ( int, name_actuatoradr, nactuator, 1 ) \
X ( int, name_sensoradr, nsensor, 1 ) \
X ( int, name_numericadr, nnumeric, 1 ) \
X ( int, name_textadr, ntext, 1 ) \
@@ -871,9 +877,9 @@
X ( mjtNum, ten_length, ntendon, 1 ) \
X ( int, wrap_obj, nwrap, 2 ) \
X ( mjtNum, wrap_xpos, nwrap, 6 ) \
X ( mjtNum, actuator_length, nu, 1 ) \
X ( int, moment_rownnz, nu, 1 ) \
X ( int, moment_rowadr, nu, 1 ) \
X ( mjtNum, actuator_length, nout, 1 ) \
X ( int, moment_rownnz, nout, 1 ) \
X ( int, moment_rowadr, nout, 1 ) \
X ( int, moment_colind, nJmom, 1 ) \
X ( mjtNum, actuator_moment, nJmom, 1 ) \
XNV ( mjtNum, crb, nbody, 10 ) \
@@ -888,7 +894,7 @@
X ( int, dof_awake_ind, nv, 1 ) \
X ( mjtNum, flexedge_velocity, nflexedge, 1 ) \
X ( mjtNum, ten_velocity, ntendon, 1 ) \
X ( mjtNum, actuator_velocity, nu, 1 ) \
X ( mjtNum, actuator_velocity, nout, 1 ) \
X ( mjtNum, cvel, nbody, 6 ) \
X ( mjtNum, cdof_dot, nv, 6 ) \
X ( mjtNum, qfrc_bias, nv, 1 ) \
@@ -903,7 +909,7 @@
X ( mjtNum, qHDiagInv, nv, 1 ) \
XNV ( mjtNum, qDeriv, nD, 1 ) \
XNV ( mjtNum, qLU, nD, 1 ) \
X ( mjtNum, actuator_force, nu, 1 ) \
X ( mjtNum, actuator_force, nout, 1 ) \
X ( mjtNum, qfrc_actuator, nv, 1 ) \
X ( mjtNum, qfrc_smooth, nv, 1 ) \
X ( mjtNum, qacc_smooth, nv, 1 ) \
+20 -20
View File
@@ -1266,24 +1266,24 @@ class Model:
actuator_dyntype: dynamics type (DynType) (nu,)
actuator_gaintype: gain type (GainType) (nu,)
actuator_biastype: bias type (BiasType) (nu,)
actuator_trnid: transmission id: joint, tendon, site (nu, 2)
actuator_actadr: first activation address; -1: stateless (nu,)
actuator_actnum: number of activation variables (nu,)
actuator_trnid: transmission id: joint, tendon, site (nu, 2)
actuator_cranklength: crank length for slider-crank (*, nu)
actuator_dynprm: dynamics parameters (*, nu, mjNDYN)
actuator_gainprm: gain parameters (*, nu, mjNGAIN)
actuator_biasprm: bias parameters (*, nu, mjNBIAS)
actuator_actlimited: is activation limited (nu,)
actuator_actrange: range of activations (*, nu, 2)
actuator_actearly: step activation before force (nu,)
actuator_history: history buffer sizes (nu, 2)
actuator_historyadr: history buffer address (nu,)
actuator_delay: delay in seconds (nu,)
actuator_ctrllimited: is control limited (nu,)
actuator_forcelimited: is force limited (nu,)
actuator_actlimited: is activation limited (nu,)
actuator_dynprm: dynamics parameters (*, nu, mjNDYN)
actuator_gainprm: gain parameters (*, nu, mjNGAIN)
actuator_biasprm: bias parameters (*, nu, mjNBIAS)
actuator_actearly: step activation before force (nu,)
actuator_ctrlrange: range of controls (*, nu, 2)
actuator_forcerange: range of forces (*, nu, 2)
actuator_actrange: range of activations (*, nu, 2)
actuator_gear: scale length and transmitted force (*, nu, 6)
actuator_cranklength: crank length for slider-crank (*, nu)
actuator_forcelimited: is force limited (nu,)
actuator_forcerange: range of forces (*, nu, 2)
actuator_acc0: acceleration from unit force in qpos0 (*, nu)
actuator_lengthrange: feasible actuator length range (*, nu, 2)
sensor_type: sensor type (SensorType) (nsensor,)
@@ -1749,24 +1749,24 @@ class Model:
actuator_dyntype: array("nu", int)
actuator_gaintype: array("nu", int)
actuator_biastype: array("nu", int)
actuator_trnid: array("nu", wp.vec2i)
actuator_actadr: array("nu", int)
actuator_actnum: array("nu", int)
actuator_trnid: array("nu", wp.vec2i)
actuator_cranklength: array("*", "nu", float)
actuator_dynprm: array("*", "nu", vec10f)
actuator_gainprm: array("*", "nu", vec10f)
actuator_biasprm: array("*", "nu", vec10f)
actuator_actlimited: array("nu", bool)
actuator_actrange: array("*", "nu", wp.vec2)
actuator_actearly: array("nu", bool)
actuator_history: array("nu", wp.vec2i)
actuator_historyadr: array("nu", int)
actuator_delay: array("nu", float)
actuator_ctrllimited: array("nu", bool)
actuator_forcelimited: array("nu", bool)
actuator_actlimited: array("nu", bool)
actuator_dynprm: array("*", "nu", vec10f)
actuator_gainprm: array("*", "nu", vec10f)
actuator_biasprm: array("*", "nu", vec10f)
actuator_actearly: array("nu", bool)
actuator_ctrlrange: array("*", "nu", wp.vec2)
actuator_forcerange: array("*", "nu", wp.vec2)
actuator_actrange: array("*", "nu", wp.vec2)
actuator_gear: array("*", "nu", wp.spatial_vector)
actuator_cranklength: array("*", "nu", float)
actuator_forcelimited: array("nu", bool)
actuator_forcerange: array("*", "nu", wp.vec2)
actuator_acc0: array("*", "nu", float)
actuator_lengthrange: array("*", "nu", wp.vec2)
sensor_type: array("nsensor", int)
+161 -119
View File
@@ -946,7 +946,17 @@ STRUCTS: Mapping[str, StructDecl] = dict([
StructFieldDecl(
name='nu',
type=ValueType(name='mjtSize'),
doc='number of actuators/controls = dim(ctrl)',
doc='number of scalar controls = dim(ctrl)',
),
StructFieldDecl(
name='nactuator',
type=ValueType(name='mjtSize'),
doc='number of actuators',
),
StructFieldDecl(
name='nout',
type=ValueType(name='mjtSize'),
doc='number of force outputs, derived from transmission type',
),
StructFieldDecl(
name='na',
@@ -4311,7 +4321,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='int'),
),
doc='transmission type (mjtTrn)',
array_extent=('nu',),
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_dyntype',
@@ -4319,7 +4329,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='int'),
),
doc='dynamics type (mjtDyn)',
array_extent=('nu',),
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_gaintype',
@@ -4327,7 +4337,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='int'),
),
doc='gain type (mjtGain)',
array_extent=('nu',),
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_biastype',
@@ -4335,39 +4345,39 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='int'),
),
doc='bias type (mjtBias)',
array_extent=('nu',),
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_trnid',
name='actuator_ctrladr',
type=PointerType(
inner_type=ValueType(name='int'),
),
doc='transmission id: joint, tendon, site',
array_extent=('nu', 2),
doc='address of first control',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_damping',
name='actuator_ctrlnum',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
inner_type=ValueType(name='int'),
),
doc='linear damping coefficient',
array_extent=('nu',),
doc='number of controls',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_dampingpoly',
name='actuator_outadr',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
inner_type=ValueType(name='int'),
),
doc='high-order damping coefficients',
array_extent=('nu', 'mjNPOLY'),
doc='address of first force output',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_armature',
name='actuator_outnum',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
inner_type=ValueType(name='int'),
),
doc='armature added to target (joint, tendon)',
array_extent=('nu',),
doc='number of force outputs, from trntype',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_actadr',
@@ -4375,7 +4385,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='int'),
),
doc='first activation address; -1: stateless',
array_extent=('nu',),
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_actnum',
@@ -4383,63 +4393,23 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='int'),
),
doc='number of activation variables',
array_extent=('nu',),
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_group',
name='actuator_trnid',
type=PointerType(
inner_type=ValueType(name='int'),
),
doc='group for visibility',
array_extent=('nu',),
doc='transmission id: joint, tendon, site',
array_extent=('nactuator', 2),
),
StructFieldDecl(
name='actuator_history',
type=PointerType(
inner_type=ValueType(name='int'),
),
doc='history buffer: [nsample, interp]',
array_extent=('nu', 2),
),
StructFieldDecl(
name='actuator_historyadr',
type=PointerType(
inner_type=ValueType(name='int'),
),
doc='address in history buffer; -1: none',
array_extent=('nu',),
),
StructFieldDecl(
name='actuator_delay',
name='actuator_cranklength',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='delay time in seconds; 0: no delay',
array_extent=('nu',),
),
StructFieldDecl(
name='actuator_ctrllimited',
type=PointerType(
inner_type=ValueType(name='mjtBool'),
),
doc='is control limited',
array_extent=('nu',),
),
StructFieldDecl(
name='actuator_forcelimited',
type=PointerType(
inner_type=ValueType(name='mjtBool'),
),
doc='is force limited',
array_extent=('nu',),
),
StructFieldDecl(
name='actuator_actlimited',
type=PointerType(
inner_type=ValueType(name='mjtBool'),
),
doc='is activation limited',
array_extent=('nu',),
doc='crank length for slider-crank',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_dynprm',
@@ -4447,7 +4417,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='mjtNum'),
),
doc='dynamics parameters',
array_extent=('nu', 'mjNDYN'),
array_extent=('nactuator', 'mjNDYN'),
),
StructFieldDecl(
name='actuator_gainprm',
@@ -4455,7 +4425,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='mjtNum'),
),
doc='gain parameters',
array_extent=('nu', 'mjNGAIN'),
array_extent=('nactuator', 'mjNGAIN'),
),
StructFieldDecl(
name='actuator_biasprm',
@@ -4463,7 +4433,23 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='mjtNum'),
),
doc='bias parameters',
array_extent=('nu', 'mjNBIAS'),
array_extent=('nactuator', 'mjNBIAS'),
),
StructFieldDecl(
name='actuator_actlimited',
type=PointerType(
inner_type=ValueType(name='mjtBool'),
),
doc='is activation limited',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_actrange',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='range of activations',
array_extent=('nactuator', 2),
),
StructFieldDecl(
name='actuator_actearly',
@@ -4471,6 +4457,86 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='mjtBool'),
),
doc='step activation before force',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_history',
type=PointerType(
inner_type=ValueType(name='int'),
),
doc='history buffer: [nsample, interp]',
array_extent=('nactuator', 2),
),
StructFieldDecl(
name='actuator_historyadr',
type=PointerType(
inner_type=ValueType(name='int'),
),
doc='address in history buffer; -1: none',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_delay',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='delay time; 0: no delay',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_damping',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='linear damping coefficient',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_dampingpoly',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='high-order damping coefficients',
array_extent=('nactuator', 'mjNPOLY'),
),
StructFieldDecl(
name='actuator_armature',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='armature added to target (joint, tendon)',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_group',
type=PointerType(
inner_type=ValueType(name='int'),
),
doc='group for visibility',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_user',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='user data',
array_extent=('nactuator', 'nuser_actuator'),
),
StructFieldDecl(
name='actuator_plugin',
type=PointerType(
inner_type=ValueType(name='int'),
),
doc='plugin instance id; -1: not a plugin',
array_extent=('nactuator',),
),
StructFieldDecl(
name='actuator_ctrllimited',
type=PointerType(
inner_type=ValueType(name='mjtBool'),
),
doc='is control limited',
array_extent=('nu',),
),
StructFieldDecl(
@@ -4481,37 +4547,29 @@ STRUCTS: Mapping[str, StructDecl] = dict([
doc='range of controls',
array_extent=('nu', 2),
),
StructFieldDecl(
name='actuator_forcerange',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='range of forces',
array_extent=('nu', 2),
),
StructFieldDecl(
name='actuator_actrange',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='range of activations',
array_extent=('nu', 2),
),
StructFieldDecl(
name='actuator_gear',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='scale length and transmitted force',
array_extent=('nu', 6),
array_extent=('nout', 6),
),
StructFieldDecl(
name='actuator_cranklength',
name='actuator_forcelimited',
type=PointerType(
inner_type=ValueType(name='mjtBool'),
),
doc='is force limited',
array_extent=('nout',),
),
StructFieldDecl(
name='actuator_forcerange',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='crank length for slider-crank',
array_extent=('nu',),
doc='range of forces',
array_extent=('nout', 2),
),
StructFieldDecl(
name='actuator_acc0',
@@ -4519,7 +4577,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='mjtNum'),
),
doc='acceleration from unit force in qpos0',
array_extent=('nu',),
array_extent=('nout',),
),
StructFieldDecl(
name='actuator_length0',
@@ -4527,7 +4585,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='mjtNum'),
),
doc='actuator length in qpos0',
array_extent=('nu',),
array_extent=('nout',),
),
StructFieldDecl(
name='actuator_lengthrange',
@@ -4535,23 +4593,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='mjtNum'),
),
doc='feasible actuator length range',
array_extent=('nu', 2),
),
StructFieldDecl(
name='actuator_user',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='user data',
array_extent=('nu', 'nuser_actuator'),
),
StructFieldDecl(
name='actuator_plugin',
type=PointerType(
inner_type=ValueType(name='int'),
),
doc='plugin instance id; -1: not a plugin',
array_extent=('nu',),
array_extent=('nout', 2),
),
StructFieldDecl(
name='sensor_type',
@@ -5015,7 +5057,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='int'),
),
doc='actuator name pointers',
array_extent=('nu',),
array_extent=('nactuator',),
),
StructFieldDecl(
name='name_sensoradr',
@@ -6082,8 +6124,8 @@ STRUCTS: Mapping[str, StructDecl] = dict([
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='actuator lengths',
array_extent=('nu',),
doc='actuator lengths, one per force output',
array_extent=('nout',),
),
StructFieldDecl(
name='moment_rownnz',
@@ -6091,7 +6133,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='int'),
),
doc='number of non-zeros in actuator_moment row',
array_extent=('nu',),
array_extent=('nout',),
),
StructFieldDecl(
name='moment_rowadr',
@@ -6099,7 +6141,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='int'),
),
doc='row start address in colind array',
array_extent=('nu',),
array_extent=('nout',),
),
StructFieldDecl(
name='moment_colind',
@@ -6218,8 +6260,8 @@ STRUCTS: Mapping[str, StructDecl] = dict([
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='actuator velocities',
array_extent=('nu',),
doc='actuator velocities, one per force output',
array_extent=('nout',),
),
StructFieldDecl(
name='cvel',
@@ -6339,14 +6381,14 @@ STRUCTS: Mapping[str, StructDecl] = dict([
inner_type=ValueType(name='mjtNum'),
),
doc='actuator force in actuation space',
array_extent=('nu',),
array_extent=('nout',),
),
StructFieldDecl(
name='qfrc_actuator',
type=PointerType(
inner_type=ValueType(name='mjtNum'),
),
doc='actuator force',
doc='actuator force in joint space',
array_extent=('nv',),
),
StructFieldDecl(
+28 -26
View File
@@ -1263,10 +1263,10 @@ mjtNum mj_tendonDot(const mjModel* m, mjData* d, int id, const mjtNum* vec) {
// compute actuator/transmission lengths and moments
void mj_transmission(const mjModel* m, mjData* d) {
int nv = m->nv, nu = m->nu;
int nv = m->nv, nactuator = m->nactuator;
// nothing to do
if (!nu) {
if (!nactuator) {
return;
}
@@ -1295,19 +1295,21 @@ void mj_transmission(const mjModel* m, mjData* d) {
int sleep_filter = mjENABLED(mjENBL_SLEEP) && d->nv_awake < nv;
// compute lengths and moments
for (int i=0; i < nu; i++) {
rowadr[i] = i == 0 ? 0 : rowadr[i-1] + rownnz[i-1];
int nnz, adr = rowadr[i];
for (int i=0; i < nactuator; i++) {
// address of the actuator's output block (single row for all current types)
int out = m->actuator_outadr[i];
rowadr[out] = out == 0 ? 0 : rowadr[out-1] + rownnz[out-1];
int nnz, adr = rowadr[out];
// skip sleeping actuator
if (sleep_filter && mj_sleepState(m, d, mjOBJ_ACTUATOR, i) == mjS_ASLEEP) {
rownnz[i] = 0;
rownnz[out] = 0;
continue;
}
// extract info
int id = m->actuator_trnid[2*i];
mjtNum* gear = m->actuator_gear+6*i;
mjtNum* gear = m->actuator_gear+6*out;
// process according to transmission type
switch ((mjtTrn) m->actuator_trntype[i]) {
@@ -1316,10 +1318,10 @@ void mj_transmission(const mjModel* m, mjData* d) {
// slide and hinge joint: scalar gear
if (m->jnt_type[id] == mjJNT_SLIDE || m->jnt_type[id] == mjJNT_HINGE) {
// sparsity
rownnz[i] = 1;
rownnz[out] = 1;
colind[adr] = m->jnt_dofadr[id];
length[i] = d->qpos[m->jnt_qposadr[id]]*gear[0];
length[out] = d->qpos[m->jnt_qposadr[id]]*gear[0];
moment[adr] = gear[0];
}
@@ -1341,7 +1343,7 @@ void mj_transmission(const mjModel* m, mjData* d) {
}
// length: axis*gearAxis
length[i] = mju_dot3(axis, gearAxis);
length[out] = mju_dot3(axis, gearAxis);
// dof start address
int jnt_dofadr = m->jnt_dofadr[id];
@@ -1350,7 +1352,7 @@ void mj_transmission(const mjModel* m, mjData* d) {
for (int j = 0; j < 3; j++) {
colind[adr+j] = jnt_dofadr + j;
}
rownnz[i] = 3;
rownnz[out] = 3;
// moment: gearAxis
mji_copy3(moment+adr, gearAxis);
@@ -1359,7 +1361,7 @@ void mj_transmission(const mjModel* m, mjData* d) {
// free joint: 6D wrench gear
else {
// cannot compute meaningful length, set to 0
length[i] = 0;
length[out] = 0;
// gearAxis: rotate to world frame if necessary
mjtNum gearAxis[3];
@@ -1380,7 +1382,7 @@ void mj_transmission(const mjModel* m, mjData* d) {
for (int j = 0; j < 6; j++) {
colind[adr+j] = jnt_dofadr + j;
}
rownnz[i] = 6;
rownnz[out] = 6;
// moment: gear(tran), gearAxis
mji_copy3(moment+adr, gear);
@@ -1392,7 +1394,7 @@ void mj_transmission(const mjModel* m, mjData* d) {
{
// get data
int idslider = m->actuator_trnid[2*i+1];
mjtNum rod = m->actuator_cranklength[i];
mjtNum rod = m->actuator_cranklength[out];
mjtNum axis[3] = {d->site_xmat[9 * idslider + 2],
d->site_xmat[9 * idslider + 5],
d->site_xmat[9 * idslider + 8]};
@@ -1407,10 +1409,10 @@ void mj_transmission(const mjModel* m, mjData* d) {
if (det <= 0) {
ok = 0;
sdet = 0;
length[i] = av;
length[out] = av;
} else {
sdet = mju_sqrt(det);
length[i] = av - sdet;
length[out] = av - sdet;
}
// compute derivatives of length w.r.t. vec and axis
@@ -1445,7 +1447,7 @@ void mj_transmission(const mjModel* m, mjData* d) {
}
// scale by gear ratio
length[i] *= gear[0];
length[out] *= gear[0];
// sparsity (compress)
nnz = 0;
@@ -1456,18 +1458,18 @@ void mj_transmission(const mjModel* m, mjData* d) {
nnz++;
}
}
rownnz[i] = nnz;
rownnz[out] = nnz;
}
break;
case mjTRN_TENDON: // tendon
length[i] = d->ten_length[id]*gear[0];
length[out] = d->ten_length[id]*gear[0];
// moment
{
int ten_J_rownnz = m->ten_J_rownnz[id];
int ten_J_rowadr = m->ten_J_rowadr[id];
rownnz[i] = ten_J_rownnz;
rownnz[out] = ten_J_rownnz;
mju_copyInt(colind + adr, m->ten_J_colind + ten_J_rowadr, ten_J_rownnz);
mju_scl(moment + adr, d->ten_J + ten_J_rowadr, gear[0], ten_J_rownnz);
@@ -1479,7 +1481,7 @@ void mj_transmission(const mjModel* m, mjData* d) {
mj_jacSite(m, d, jac, jacS, id);
// clear length
length[i] = 0;
length[out] = 0;
if (!moment_row) moment_row = mjSTACKALLOC(d, nv, mjtNum);
@@ -1540,7 +1542,7 @@ void mj_transmission(const mjModel* m, mjData* d) {
mju_mulMatTVec3(vec, d->site_xmat+9*refid, vec);
// length: dot product with gear
length[i] += mju_dot3(vec, gear);
length[out] += mju_dot3(vec, gear);
// jacref: global Jacobian of reference site
mj_jacSite(m, d, jacref, NULL, refid);
@@ -1579,7 +1581,7 @@ void mj_transmission(const mjModel* m, mjData* d) {
mji_subQuat(vec, quat, refquat);
// add length: dot product with gear
length[i] += mju_dot3(vec, gear+3);
length[out] += mju_dot3(vec, gear+3);
// jacref: global rotational Jacobian of reference site
mj_jacSite(m, d, NULL, jacref, refid);
@@ -1616,13 +1618,13 @@ void mj_transmission(const mjModel* m, mjData* d) {
nnz++;
}
}
rownnz[i] = nnz;
rownnz[out] = nnz;
break;
case mjTRN_BODY: // body (adhesive contacts)
// cannot compute meaningful length, set to 0
length[i] = 0;
length[out] = 0;
// clear moment
if (!moment_row) moment_row = mjSTACKALLOC(d, nv, mjtNum);
@@ -1730,7 +1732,7 @@ void mj_transmission(const mjModel* m, mjData* d) {
nnz++;
}
}
rownnz[i] = nnz;
rownnz[out] = nnz;
break;
+6 -6
View File
@@ -1102,7 +1102,7 @@ mjtNum mj_actuatorDamping(const mjModel* m, mjtObj type, int id, mjtNum poly[mjN
// single actuator contributes damping
if (actuatorid >= 0) {
mjtNum gear2 = m->actuator_gear[6*actuatorid] * m->actuator_gear[6*actuatorid];
mjtNum gear2 = m->actuator_gear[6*m->actuator_outadr[actuatorid]] * m->actuator_gear[6*m->actuator_outadr[actuatorid]];
damping = m->actuator_damping[actuatorid] * gear2;
for (int k = 0; k < mjNPOLY; k++) {
poly[k] += m->actuator_dampingpoly[mjNPOLY*actuatorid+k] * gear2;
@@ -1111,7 +1111,7 @@ mjtNum mj_actuatorDamping(const mjModel* m, mjtObj type, int id, mjtNum poly[mjN
// actuatorid < -1: scan all actuators for contributions
else {
for (int k = 0; k < m->nu; k++) {
for (int k = 0; k < m->nactuator; k++) {
// skip actuators that don't actuate the given joint/tendon
if (m->actuator_trnid[2*k] != id) {
continue;
@@ -1126,7 +1126,7 @@ mjtNum mj_actuatorDamping(const mjModel* m, mjtObj type, int id, mjtNum poly[mjN
}
// accumulate damping contribution
mjtNum gear2 = m->actuator_gear[6*k] * m->actuator_gear[6*k];
mjtNum gear2 = m->actuator_gear[6*m->actuator_outadr[k]] * m->actuator_gear[6*m->actuator_outadr[k]];
damping += m->actuator_damping[k] * gear2;
for (int j = 0; j < mjNPOLY; j++) {
poly[j] += m->actuator_dampingpoly[mjNPOLY*k+j] * gear2;
@@ -1157,13 +1157,13 @@ mjtNum mj_actuatorArmature(const mjModel* m, mjtObj type, int id) {
// single actuator contributes armature
if (actuatorid >= 0) {
mjtNum gear2 = m->actuator_gear[6*actuatorid] * m->actuator_gear[6*actuatorid];
mjtNum gear2 = m->actuator_gear[6*m->actuator_outadr[actuatorid]] * m->actuator_gear[6*m->actuator_outadr[actuatorid]];
armature = m->actuator_armature[actuatorid] * gear2;
}
// actuatorid < -1: scan all actuators for contributions
else {
for (int k = 0; k < m->nu; k++) {
for (int k = 0; k < m->nactuator; k++) {
// skip actuators that don't actuate the given joint/tendon
if (m->actuator_trnid[2*k] != id) {
continue;
@@ -1178,7 +1178,7 @@ mjtNum mj_actuatorArmature(const mjModel* m, mjtObj type, int id) {
}
// accumulate armature contribution
mjtNum gear2 = m->actuator_gear[6*k] * m->actuator_gear[6*k];
mjtNum gear2 = m->actuator_gear[6*m->actuator_outadr[k]] * m->actuator_gear[6*m->actuator_outadr[k]];
armature += m->actuator_armature[k] * gear2;
}
}
+13 -10
View File
@@ -1211,7 +1211,7 @@ void mjd_flexBend_mul(const mjModel* m, mjData* d, mjtNum* res, const mjtNum* ve
// add (d qfrc_actuator / d qvel) to qDeriv
void mjd_actuator_vel(const mjModel* m, mjData* d) {
int nu = m->nu;
int nactuator = m->nactuator;
int sleep_filter = mjENABLED(mjENBL_SLEEP) && d->ntree_awake < m->ntree;
// disabled: nothing to add
@@ -1220,7 +1220,10 @@ void mjd_actuator_vel(const mjModel* m, mjData* d) {
}
// process actuators
for (int i=0; i < nu; i++) {
for (int i=0; i < nactuator; i++) {
int uadr = m->actuator_ctrladr[i];
int oadr = m->actuator_outadr[i];
// skip if disabled
if (mj_actuatorDisabled(m, i)) {
continue;
@@ -1233,8 +1236,8 @@ void mjd_actuator_vel(const mjModel* m, mjData* d) {
// skip if force is clamped by forcerange
if (m->actuator_forcelimited[i]) {
mjtNum force = d->actuator_force[i];
mjtNum* range = m->actuator_forcerange + 2*i;
mjtNum force = d->actuator_force[oadr];
mjtNum* range = m->actuator_forcerange + 2*oadr;
if (force <= range[0] || force >= range[1]) {
continue;
}
@@ -1267,10 +1270,10 @@ void mjd_actuator_vel(const mjModel* m, mjData* d) {
// muscle gain
else if (m->actuator_gaintype[i] == mjGAIN_MUSCLE) {
gain_vel = mjd_muscleGain_vel(d->actuator_length[i],
d->actuator_velocity[i],
m->actuator_lengthrange+2*i,
m->actuator_acc0[i],
gain_vel = mjd_muscleGain_vel(d->actuator_length[oadr],
d->actuator_velocity[oadr],
m->actuator_lengthrange+2*oadr,
m->actuator_acc0[oadr],
m->actuator_gainprm + mjNGAIN*i);
}
@@ -1311,7 +1314,7 @@ void mjd_actuator_vel(const mjModel* m, mjData* d) {
// force = gain .* [ctrl/act]
if (gain_vel != 0) {
if (m->actuator_dyntype[i] == mjDYN_NONE) {
bias_vel += gain_vel * d->ctrl[i];
bias_vel += gain_vel * d->ctrl[uadr];
} else {
int act_adr = m->actuator_actadr[i] + m->actuator_actnum[i] - 1;
mjtNum act = d->act[act_adr];
@@ -1327,7 +1330,7 @@ void mjd_actuator_vel(const mjModel* m, mjData* d) {
// add
if (bias_vel != 0) {
addJTBJSparse(m, d, d->actuator_moment, &bias_vel, 1, i,
addJTBJSparse(m, d, d->actuator_moment, &bias_vel, 1, oadr,
d->moment_rownnz, d->moment_rowadr, d->moment_colind);
}
}
+66 -49
View File
@@ -197,10 +197,10 @@ void mj_fwdVelocity(const mjModel* m, mjData* d) {
// actuator velocity: always sparse
if (!mjDISABLED(mjDSBL_ACTUATION)) {
mju_mulMatVecSparse(d->actuator_velocity, d->actuator_moment, d->qvel, m->nu,
mju_mulMatVecSparse(d->actuator_velocity, d->actuator_moment, d->qvel, m->nout,
d->moment_rownnz, d->moment_rowadr, d->moment_colind, NULL);
} else {
mju_zero(d->actuator_velocity, m->nu);
mju_zero(d->actuator_velocity, m->nout);
}
// com-based velocities, passive forces, constraint references
@@ -264,17 +264,17 @@ static void clampVec(mjtNum* vec, const mjtNum* range, const mjtBool* limited, i
// (qpos, qvel, ctrl, act) => (qfrc_actuator, actuator_force, act_dot)
void mj_fwdActuation(const mjModel* m, mjData* d) {
TM_START;
int nv = m->nv, nu = m->nu, ntendon = m->ntendon;
int nv = m->nv, nu = m->nu, nactuator = m->nactuator, nout = m->nout, ntendon = m->ntendon;
mjtNum gain, bias, tau;
mjtNum *force = d->actuator_force;
// clear actuator_force
mju_zero(force, nu);
mju_zero(force, nout);
int sleep_filter = mjENABLED(mjENBL_SLEEP);
// disabled or no actuation: return
if (nu == 0 || mjDISABLED(mjDSBL_ACTUATION)) {
if (nactuator == 0 || mjDISABLED(mjDSBL_ACTUATION)) {
mju_zero(d->qfrc_actuator, nv);
return;
}
@@ -287,9 +287,15 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
mjtNum *ctrl = mjSTACKALLOC(d, nu, mjtNum);
// read from ctrl or history buffer for delayed actuators
for (int i = 0; i < nu; i++) {
int interp = m->actuator_history[2*i+1];
ctrl[i] = m->actuator_delay[i] ? mj_readCtrl(m, d, i, d->time, interp) : d->ctrl[i];
for (int i = 0; i < nactuator; i++) {
int adr = m->actuator_ctrladr[i];
if (m->actuator_delay[i]) {
// delayed: read from history buffer (scalar input)
int interp = m->actuator_history[2*i+1];
ctrl[adr] = mj_readCtrl(m, d, i, d->time, interp);
} else {
mju_copy(ctrl + adr, d->ctrl + adr, m->actuator_ctrlnum[i]);
}
}
// clamp local copy
@@ -307,7 +313,7 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
}
// act_dot for stateful actuators
for (int i=0; i < nu; i++) {
for (int i=0; i < nactuator; i++) {
if (sleep_filter && mj_sleepState(m, d, mjOBJ_ACTUATOR, i) == mjS_ASLEEP) {
continue;
}
@@ -317,6 +323,10 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
continue;
}
// addresses of the actuator's input and output blocks
int uadr = m->actuator_ctrladr[i];
int oadr = m->actuator_outadr[i];
// zero act_dot for actuator plugins
int actnum = m->actuator_actnum[i];
if (actnum) {
@@ -334,17 +344,17 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
// compute act_dot according to dynamics type
switch (dyntype) {
case mjDYN_INTEGRATOR: // simple integrator
d->act_dot[act_last] = ctrl[i];
d->act_dot[act_last] = ctrl[uadr];
break;
case mjDYN_FILTER: // linear filter: dynprm = tau
case mjDYN_FILTEREXACT:
tau = mju_max(mjMINVAL, dynprm[0]);
d->act_dot[act_last] = (ctrl[i] - d->act[act_last]) / tau;
d->act_dot[act_last] = (ctrl[uadr] - d->act[act_last]) / tau;
break;
case mjDYN_MUSCLE: // muscle model: dynprm = (tau_act, tau_deact)
d->act_dot[act_last] = mju_muscleDynamics(ctrl[i], d->act[act_last], dynprm);
d->act_dot[act_last] = mju_muscleDynamics(ctrl[uadr], d->act[act_last], dynprm);
break;
case mjDYN_DCMOTOR: { // DC motor: up to 5 optional states
@@ -356,7 +366,7 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
}
int adr = act_first;
mjtNum velocity = d->actuator_velocity[i];
mjtNum velocity = d->actuator_velocity[oadr];
mjtNum R = gainprm[0]; // resistance
mjtNum K = gainprm[1]; // motor constant
mjtNum ki = gainprm[5]; // integral gain
@@ -369,9 +379,9 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
if (slew_s > 0) {
mjtNum u_prev = d->act[adr];
mjtNum slew = slew_s * m->opt.timestep;
mjtNum u_eff = mju_clip(ctrl[i], u_prev - slew, u_prev + slew);
mjtNum u_eff = mju_clip(ctrl[uadr], u_prev - slew, u_prev + slew);
d->act_dot[adr] = (u_eff - u_prev) / m->opt.timestep;
ctrl[i] = u_eff;
ctrl[uadr] = u_eff;
adr++;
}
@@ -381,11 +391,11 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
x_I = d->act[adr];
int input_mode = (int)gainprm[8];
mjtNum Imax = dynprm[8]; // integral clamp
mjtNum act_dot = ctrl[i]; // default raw accumulator for voltage and velocity modes
mjtNum act_dot = ctrl[uadr]; // default raw accumulator for voltage and velocity modes
// position mode
if (input_mode == 1) {
act_dot = ctrl[i] - d->actuator_length[i];
act_dot = ctrl[uadr] - d->actuator_length[oadr];
}
// clamp act_dot based on integral state
@@ -401,7 +411,7 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
}
// compute physical voltage to feed into current and temperature equations
mjtNum V = dcmotorVoltage(ctrl[i], d->actuator_length[i], velocity, x_I, gainprm);
mjtNum V = dcmotorVoltage(ctrl[uadr], d->actuator_length[oadr], velocity, x_I, gainprm);
// temperature: dT/dt = (R*i^2 - T/RT) / C, where T = delta above ambient
mjtNum RT = dynprm[2]; // thermal resistance
@@ -476,7 +486,7 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
}
// force = gain .* [ctrl/act] + bias
for (int i=0; i < nu; i++) {
for (int i=0; i < nactuator; i++) {
// skip if sleeping
if (sleep_filter && mj_sleepState(m, d, mjOBJ_ACTUATOR, i) == mjS_ASLEEP) {
continue;
@@ -492,6 +502,10 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
continue;
}
// addresses of the actuator's input and output blocks
int uadr = m->actuator_ctrladr[i];
int oadr = m->actuator_outadr[i];
// check for tendon transmission with force limits
if (ntendon && !tendon_frclimited && m->actuator_trntype[i] == mjTRN_TENDON) {
tendon_frclimited = m->tendon_actfrclimited[m->actuator_trnid[2*i]];
@@ -510,14 +524,15 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
break;
case mjGAIN_AFFINE: // affine: prm = [const, kp, kv]
gain = gainprm[0] + gainprm[1]*d->actuator_length[i] + gainprm[2]*d->actuator_velocity[i];
gain = gainprm[0] + gainprm[1]*d->actuator_length[oadr] +
gainprm[2]*d->actuator_velocity[oadr];
break;
case mjGAIN_MUSCLE: // muscle gain
gain = mju_muscleGain(d->actuator_length[i],
d->actuator_velocity[i],
m->actuator_lengthrange+2*i,
m->actuator_acc0[i],
gain = mju_muscleGain(d->actuator_length[oadr],
d->actuator_velocity[oadr],
m->actuator_lengthrange+2*oadr,
m->actuator_acc0[oadr],
gainprm);
break;
@@ -546,11 +561,11 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
// stateless: gain = K/R, force = K/R * ctrl (condition below)
gain = (dynprm[0] > 0) ? K : K / mju_max(mjMINVAL, R);
// controller: compute voltage, override ctrl[i] for force computation
// controller: compute voltage, override ctrl[uadr] for force computation
if ((int)gainprm[8] > 0) {
mjtNum x_I = (slots.integral >= 0) ? d->act[adr + slots.integral] : 0;
ctrl[i] = dcmotorVoltage(ctrl[i], d->actuator_length[i],
d->actuator_velocity[i], x_I, gainprm);
ctrl[uadr] = dcmotorVoltage(ctrl[uadr], d->actuator_length[oadr],
d->actuator_velocity[oadr], x_I, gainprm);
}
break;
}
@@ -568,7 +583,7 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
// DC motor without current state: use ctrl even if other activations exist
int dcmotor_no_current = (gaintype == mjGAIN_DCMOTOR && dynprm[0] <= 0);
if (actnum == 0 || dcmotor_no_current) {
force[i] = gain * ctrl[i];
force[oadr] = gain * ctrl[uadr];
} else {
// use last activation variable associated with actuator i
int act_adr = m->actuator_actadr[i] + actnum - 1;
@@ -579,7 +594,7 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
} else {
act = d->act[act_adr];
}
force[i] = gain * act;
force[oadr] = gain * act;
}
// extract bias info
@@ -593,13 +608,14 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
break;
case mjBIAS_AFFINE: // affine: biasprm = [const, kp, kv]
bias = biasprm[0] + biasprm[1]*d->actuator_length[i] + biasprm[2]*d->actuator_velocity[i];
bias = biasprm[0] + biasprm[1]*d->actuator_length[oadr] +
biasprm[2]*d->actuator_velocity[oadr];
break;
case mjBIAS_MUSCLE: // muscle passive force
bias = mju_muscleBias(d->actuator_length[i],
m->actuator_lengthrange+2*i,
m->actuator_acc0[i],
bias = mju_muscleBias(d->actuator_length[oadr],
m->actuator_lengthrange+2*oadr,
m->actuator_acc0[oadr],
biasprm);
break;
@@ -610,7 +626,7 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
mjtNum te = m->actuator_dynprm[mjNDYN*i]; // electrical time constant
if (te <= 0) {
mjtNum K = gainprm[1]; // motor constant
bias -= gain * K * d->actuator_velocity[i];
bias -= gain * K * d->actuator_velocity[oadr];
}
break;
}
@@ -624,7 +640,7 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
}
// add bias
force[i] += bias;
force[oadr] += bias;
}
// handle actuator plugins
@@ -650,17 +666,17 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
// compute total force for each tendon
mjtNum* tendon_total_force = mjSTACKALLOC(d, ntendon, mjtNum);
mju_zero(tendon_total_force, ntendon);
for (int i=0; i < nu; i++) {
for (int i=0; i < nactuator; i++) {
if (m->actuator_trntype[i] == mjTRN_TENDON) {
int tendon_id = m->actuator_trnid[2*i];
if (m->tendon_actfrclimited[tendon_id]) {
tendon_total_force[tendon_id] += force[i];
tendon_total_force[tendon_id] += force[m->actuator_outadr[i]];
}
}
}
// scale tendon actuator forces if limited and outside range
for (int i=0; i < nu; i++) {
for (int i=0; i < nactuator; i++) {
if (m->actuator_trntype[i] != mjTRN_TENDON) {
continue;
}
@@ -669,19 +685,19 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
if (m->tendon_actfrclimited[tendon_id] && tendon_force) {
const mjtNum* range = m->tendon_actfrcrange + 2 * tendon_id;
if (tendon_force < range[0]) {
force[i] *= range[0] / tendon_force;
force[m->actuator_outadr[i]] *= range[0] / tendon_force;
} else if (tendon_force > range[1]) {
force[i] *= range[1] / tendon_force;
force[m->actuator_outadr[i]] *= range[1] / tendon_force;
}
}
}
}
// clamp actuator_force
clampVec(force, m->actuator_forcerange, m->actuator_forcelimited, nu, NULL);
clampVec(force, m->actuator_forcerange, m->actuator_forcelimited, nout, NULL);
// add DC motor mechanical forces (not subject to current limits)
for (int i=0; i < nu; i++) {
for (int i=0; i < nactuator; i++) {
if (m->actuator_biastype[i] != mjBIAS_DCMOTOR) {
continue;
}
@@ -694,13 +710,14 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
const mjtNum* biasprm = m->actuator_biasprm + mjNBIAS*i;
const mjtNum* dynprm = m->actuator_dynprm + mjNDYN*i;
int oadr = m->actuator_outadr[i];
// cogging torque
mjtNum A = biasprm[0];
if (A != 0) {
mjtNum Np = biasprm[1];
mjtNum phi = biasprm[2];
force[i] += A * mju_sin(Np*d->actuator_length[i] + phi);
force[oadr] += A * mju_sin(Np*d->actuator_length[oadr] + phi);
}
// LuGre friction
@@ -711,12 +728,12 @@ void mj_fwdActuation(const mjModel* m, mjData* d) {
int adr = m->actuator_actadr[i] + slots.bristle;
mjtNum z = d->act[adr];
mjtNum z_dot = d->act_dot[adr];
force[i] -= sigma0 * z + sigma1 * z_dot;
force[oadr] -= sigma0 * z + sigma1 * z_dot;
}
}
// qfrc_actuator = moment' * force
mju_mulMatTVecSparse(d->qfrc_actuator, d->actuator_moment, force, nu, nv,
mju_mulMatTVecSparse(d->qfrc_actuator, d->actuator_moment, force, nout, nv,
d->moment_rownnz, d->moment_rowadr, d->moment_colind);
// actuator-level gravity compensation
@@ -980,18 +997,18 @@ void mj_fwdConstraint(const mjModel* m, mjData* d) {
// qvel: optional velocity used for position integration; if NULL, use d->qvel
static void mj_advance(const mjModel* m, mjData* d,
const mjtNum* act_dot, const mjtNum* qacc, const mjtNum* qvel) {
int nu = m->nu, nsensor = m->nsensor;
int nactuator = m->nactuator, nsensor = m->nsensor;
// advance history buffers
if (m->nhistory > 0) {
// advance ctrl history buffers
for (int i = 0; i < nu; i++) {
for (int i = 0; i < nactuator; i++) {
int nsample = m->actuator_history[2*i];
if (nsample == 0) continue;
// get history buffer pointer and insert ctrl at current time
mjtNum* buf = d->history + m->actuator_historyadr[i];
*mju_historyInsert(buf, nsample, /*dim=*/1, d->time) = d->ctrl[i];
*mju_historyInsert(buf, nsample, /*dim=*/1, d->time) = d->ctrl[m->actuator_ctrladr[i]];
}
// advance sensor history buffers
@@ -1033,7 +1050,7 @@ static void mj_advance(const mjModel* m, mjData* d,
// advance activations
if (m->na && !mjDISABLED(mjDSBL_ACTUATION)) {
for (int i=0; i < nu; i++) {
for (int i=0; i < nactuator; i++) {
int actadr = m->actuator_actadr[i];
int actadr_end = actadr + m->actuator_actnum[i];
for (int j=actadr; j < actadr_end; j++) {
+16 -10
View File
@@ -225,7 +225,8 @@ static void freeModelBuffers(mjModel* m) {
// allocate and initialize mjModel structure
void mj_makeModel(mjModel** dest,
mjtSize nq, mjtSize nv, mjtSize nu, mjtSize na, mjtSize nbody, mjtSize nbvh, mjtSize nbvhstatic,
mjtSize nq, mjtSize nv, mjtSize nu, mjtSize nactuator, mjtSize nout, mjtSize na,
mjtSize nbody, mjtSize nbvh, mjtSize nbvhstatic,
mjtSize nbvhdynamic, mjtSize noct, mjtSize njnt, mjtSize ntree, mjtSize nM, mjtSize nB,
mjtSize nC, mjtSize nD, mjtSize ngeom, mjtSize nsite, mjtSize ncam, mjtSize nlight,
mjtSize nflex, mjtSize nflexnode, mjtSize nflexvert, mjtSize nflexedge, mjtSize nflexelem,
@@ -297,6 +298,8 @@ void mj_makeModel(mjModel** dest,
m->nq = nq;
m->nv = nv;
m->nu = nu;
m->nactuator = nactuator;
m->nout = nout;
m->na = na;
m->nbody = nbody;
m->nbvh = nbvh;
@@ -374,7 +377,7 @@ void mj_makeModel(mjModel** dest,
m->nuser_sensor = nuser_sensor;
m->nnames = nnames;
long nnames_map = (long)nbody + njnt + ngeom + nsite + ncam + nlight + nflex + nmesh + nskin +
nhfield + ntex + nmat + npair + nexclude + neq + ntendon + nu + nsensor +
nhfield + ntex + nmat + npair + nexclude + neq + ntendon + nactuator + nsensor +
nnumeric + ntext + ntuple + nkey + nplugin;
if (nnames_map >= INT_MAX / mjLOAD_MULTIPLE) {
if (allocate) mju_free(m);
@@ -428,7 +431,8 @@ mjModel* mj_copyModel(mjModel* dest, const mjModel* src) {
// allocate new model if needed
if (!dest) {
mj_makeModel(
&dest, src->nq, src->nv, src->nu, src->na, src->nbody, src->nbvh, src->nbvhstatic,
&dest, src->nq, src->nv, src->nu, src->nactuator, src->nout, src->na,
src->nbody, src->nbvh, src->nbvhstatic,
src->nbvhdynamic, src->noct, src->njnt, src->ntree, src->nM, src->nB, src->nC, src->nD,
src->ngeom, src->nsite, src->ncam, src->nlight, src->nflex, src->nflexnode, src->nflexvert,
src->nflexedge, src->nflexelem, src->nflexelemdata, src->nflexstiffness,
@@ -611,7 +615,7 @@ mjModel* mj_loadModelBuffer(const void* buffer, int buffer_sz) {
sizes[56], sizes[57], sizes[58], sizes[59], sizes[60], sizes[61], sizes[62],
sizes[63], sizes[64], sizes[65], sizes[66], sizes[67], sizes[68], sizes[69],
sizes[70], sizes[71], sizes[72], sizes[73], sizes[74], sizes[75], sizes[76],
sizes[77], sizes[78], sizes[79]);
sizes[77], sizes[78], sizes[79], sizes[80], sizes[81]);
// mj_makeModel may fail if the input buffer has invalid sizes
if (!m) {
@@ -1384,7 +1388,7 @@ static void _resetData(const mjModel* m, mjData* d, unsigned char debug_value) {
mju_zero(d->mocap_quat, 4*m->nmocap);
// initialize ctrl history buffers: timestamps at [-n*dt, ..., -dt]
for (int i = 0; i < m->nu; i++) {
for (int i = 0; i < m->nactuator; i++) {
int n = m->actuator_history[2*i];
if (n > 0) {
mjtNum* buf = d->history + m->actuator_historyadr[i];
@@ -1785,7 +1789,7 @@ static int numObjects(const mjModel* m, mjtObj objtype) {
case mjOBJ_TENDON:
return m->ntendon;
case mjOBJ_ACTUATOR:
return m->nu;
return m->nactuator;
case mjOBJ_SENSOR:
return m->nsensor;
case mjOBJ_NUMERIC:
@@ -1871,8 +1875,10 @@ const char* mj_validateReferences(const mjModel* m) {
X(skin_bonevertid, nskinbonevert, nskinvert , 0 ) \
X(pair_geom1, npair, ngeom , 0 ) \
X(pair_geom2, npair, ngeom , 0 ) \
X(actuator_plugin, nu, nplugin , 0 ) \
X(actuator_actadr, nu, na , m->actuator_actnum ) \
X(actuator_plugin, nactuator, nplugin , 0 ) \
X(actuator_actadr, nactuator, na , m->actuator_actnum ) \
X(actuator_ctrladr, nactuator, nu , m->actuator_ctrlnum ) \
X(actuator_outadr, nactuator, nout , m->actuator_outnum ) \
X(sensor_plugin, nsensor, nplugin , 0 ) \
X(plugin_stateadr, nplugin, npluginstate , m->plugin_statenum ) \
X(plugin_attradr, nplugin, npluginattr , 0 ) \
@@ -1897,7 +1903,7 @@ const char* mj_validateReferences(const mjModel* m) {
X(name_excludeadr, nexclude, nnames , 0 ) \
X(name_eqadr, neq, nnames , 0 ) \
X(name_tendonadr, ntendon, nnames , 0 ) \
X(name_actuatoradr, nu, nnames , 0 ) \
X(name_actuatoradr, nactuator, nnames , 0 ) \
X(name_sensoradr, nsensor, nnames , 0 ) \
X(name_numericadr, nnumeric, nnames , 0 ) \
X(name_textadr, ntext, nnames , 0 ) \
@@ -2085,7 +2091,7 @@ const char* mj_validateReferences(const mjModel* m) {
break;
}
}
for (int i=0; i < m->nu; i++) {
for (int i=0; i < m->nactuator; i++) {
int actuator_trntype = m->actuator_trntype[i];
int id = m->actuator_trnid[2*i];
int idslider = m->actuator_trnid[2*i+1];
+2 -1
View File
@@ -48,7 +48,8 @@ void mj_defaultStatistic(mjStatistic* stat);
// allocate mjModel
void mj_makeModel(mjModel** dest,
mjtSize nq, mjtSize nv, mjtSize nu, mjtSize na, mjtSize nbody, mjtSize nbvh, mjtSize nbvhstatic,
mjtSize nq, mjtSize nv, mjtSize nu, mjtSize nactuator, mjtSize nout, mjtSize na,
mjtSize nbody, mjtSize nbvh, mjtSize nbvhstatic,
mjtSize nbvhdynamic, mjtSize noct, mjtSize njnt, mjtSize ntree, mjtSize nM, mjtSize nB,
mjtSize nC, mjtSize nD, mjtSize ngeom, mjtSize nsite, mjtSize ncam, mjtSize nlight,
mjtSize nflex, mjtSize nflexnode, mjtSize nflexvert, mjtSize nflexedge, mjtSize nflexelem,
+2 -2
View File
@@ -160,10 +160,10 @@ static int _getnumadr(const mjModel* m, mjtObj type, int** padr, int* mapadr) {
mjFALLTHROUGH;
case mjOBJ_ACTUATOR:
*mapadr -= mjLOAD_MULTIPLE*m->nu;
*mapadr -= mjLOAD_MULTIPLE*m->nactuator;
if (num < 0) {
*padr = m->name_actuatoradr;
num = m->nu;
num = m->nactuator;
}
mjFALLTHROUGH;
+32 -10
View File
@@ -503,6 +503,7 @@ static bool validateFloatFormat(const char* float_format) {
// print mjModel to text file, specifying format. float_format must be a
// valid printf-style format string for a single float value
// NOLINTBEGIN(readability/fn_size)
void mj_printFormattedModel(const mjModel* m, const char* filename, const char* float_format) {
// get file
FILE* fp;
@@ -938,15 +939,35 @@ void mj_printFormattedModel(const mjModel* m, const char* filename, const char*
}
if (m->ntendon) fprintf(fp, "\n");
// actuators
object_class = &m->nu;
for (int i=0; i < m->nu; i++) {
// actuators: per-actuator fields, then per-input (nu) and per-output (nout) blocks
for (int i=0; i < m->nactuator; i++) {
fprintf(fp, "\nACTUATOR %d:\n", i);
fprintf(fp, " " NAME_FORMAT, "name");
fprintf(fp, " %s\n", m->names + m->name_actuatoradr[i]);
object_class = &m->nactuator;
MJMODEL_POINTERS_ACTUATOR
{
int actuator = i;
int ctrladr = m->actuator_ctrladr[actuator];
int ctrlnum = m->actuator_ctrlnum[actuator];
int outadr = m->actuator_outadr[actuator];
int outnum = m->actuator_outnum[actuator];
object_class = &m->nu;
i = ctrladr;
while (i < ctrladr + ctrlnum) {
MJMODEL_POINTERS_ACTUATOR
i++;
}
object_class = &m->nout;
i = outadr;
while (i < outadr + outnum) {
MJMODEL_POINTERS_ACTUATOR
i++;
}
i = actuator;
}
}
if (m->nu) fprintf(fp, "\n");
if (m->nactuator) fprintf(fp, "\n");
// sensors
object_class = &m->nsensor;
@@ -1170,6 +1191,7 @@ void mj_printFormattedModel(const mjModel* m, const char* filename, const char*
fclose(fp);
}
}
// NOLINTEND(readability/fn_size)
// print mjModel to text file
void mj_printModel(const mjModel* m, const char* filename) {
@@ -1335,7 +1357,7 @@ void mj_printFormattedData(const mjModel* m, const mjData* d, const char* filena
fprintf(fp, "DELAY\n");
// actuator history buffers
for (int i = 0; i < m->nu; i++) {
for (int i = 0; i < m->nactuator; i++) {
int adr = m->actuator_historyadr[i];
if (adr >= 0) {
char name[100];
@@ -1423,10 +1445,10 @@ void mj_printFormattedData(const mjModel* m, const mjData* d, const char* filena
fprintf(fp, "\n");
}
printArray2d("ACTUATOR_LENGTH", m->nu, 1, d->actuator_length, fp, float_format);
mj_printSparsity("actuator_moment", m->nu, m->nv,
printArray2d("ACTUATOR_LENGTH", m->nout, 1, d->actuator_length, fp, float_format);
mj_printSparsity("actuator_moment", m->nout, m->nv,
d->moment_rowadr, NULL, d->moment_rownnz, NULL, d->moment_colind, fp);
printSparse("ACTUATOR_MOMENT", d->actuator_moment, m->nu, d->moment_rownnz,
printSparse("ACTUATOR_MOMENT", d->actuator_moment, m->nout, d->moment_rownnz,
d->moment_rowadr, d->moment_colind, fp, float_format);
printArray2d("CRB", m->nbody, 10, d->crb, fp, float_format);
printSparse("M", d->M, m->nv, m->M_rownnz,
@@ -1568,7 +1590,7 @@ void mj_printFormattedData(const mjModel* m, const mjData* d, const char* filena
printArray2d("FLEXEDGE_VELOCITY", m->nflexedge, 1, d->flexedge_velocity, fp, float_format);
printArray2d("TEN_VELOCITY", m->ntendon, 1, d->ten_velocity, fp, float_format);
printArray2d("ACTUATOR_VELOCITY", m->nu, 1, d->actuator_velocity, fp, float_format);
printArray2d("ACTUATOR_VELOCITY", m->nout, 1, d->actuator_velocity, fp, float_format);
printArray2d("CVEL", m->nbody, 6, d->cvel, fp, float_format);
printArray2d("CDOF_DOT", m->nv, 6, d->cdof_dot, fp, float_format);
@@ -1587,7 +1609,7 @@ void mj_printFormattedData(const mjModel* m, const mjData* d, const char* filena
printArray2d("SUBTREE_LINVEL", m->nbody, 3, d->subtree_linvel, fp, float_format);
printArray2d("SUBTREE_ANGMOM", m->nbody, 3, d->subtree_angmom, fp, float_format);
printArray2d("ACTUATOR_FORCE", m->nu, 1, d->actuator_force, fp, float_format);
printArray2d("ACTUATOR_FORCE", m->nout, 1, d->actuator_force, fp, float_format);
printArray2d("QFRC_ACTUATOR", m->nv, 1, d->qfrc_actuator, fp, float_format);
printArray2d("QFRC_SMOOTH", m->nv, 1, d->qfrc_smooth, fp, float_format);
+6 -6
View File
@@ -650,7 +650,7 @@ static void mj_computeSensorPos(const mjModel* m, mjData* d, int i, mjtNum* sens
break;
case mjSENS_ACTUATORPOS: // actuator position
sensordata[0] = d->actuator_length[objid];
sensordata[0] = d->actuator_length[m->actuator_outadr[objid]];
break;
case mjSENS_BALLQUAT: // ball joint quaternion
@@ -879,7 +879,7 @@ static void mj_computeSensorVel(const mjModel* m, mjData* d, int i, mjtNum* sens
break;
case mjSENS_ACTUATORVEL: // actuator velocity
sensordata[0] = d->actuator_velocity[objid];
sensordata[0] = d->actuator_velocity[m->actuator_outadr[objid]];
break;
case mjSENS_BALLANGVEL: // ball joint angular velocity
@@ -956,7 +956,7 @@ static void mj_computeSensorVel(const mjModel* m, mjData* d, int i, mjtNum* sens
// compute acceleration-stage sensor value, write to data buffer
static void mj_computeSensorAcc(const mjModel* m, mjData* d, int i, mjtNum* sensordata) {
int ne = d->ne, nf = d->nf, nefc = d->nefc, nu = m->nu;
int ne = d->ne, nf = d->nf, nefc = d->nefc, nactuator = m->nactuator;
mjtSensor type = (mjtSensor)m->sensor_type[i];
int objtype = m->sensor_objtype[i];
int objid = m->sensor_objid[i];
@@ -1303,7 +1303,7 @@ static void mj_computeSensorAcc(const mjModel* m, mjData* d, int i, mjtNum* sens
break;
case mjSENS_ACTUATORFRC: // actuator force
sensordata[0] = d->actuator_force[objid];
sensordata[0] = d->actuator_force[m->actuator_outadr[objid]];
break;
case mjSENS_JOINTACTFRC: // actuator force at joint
@@ -1312,9 +1312,9 @@ static void mj_computeSensorAcc(const mjModel* m, mjData* d, int i, mjtNum* sens
case mjSENS_TENDONACTFRC: // actuator force at tendon
frc = 0.0;
for (int j=0; j < nu; j++) {
for (int j=0; j < nactuator; j++) {
if (m->actuator_trntype[j] == mjTRN_TENDON && m->actuator_trnid[2*j] == objid) {
frc += d->actuator_force[j];
frc += d->actuator_force[m->actuator_outadr[j]];
}
}
sensordata[0] = frc;
+27 -25
View File
@@ -212,7 +212,7 @@ static void setFixed(mjModel* m, mjData* d) {
// set jnt_actuatorid and tendon_actuatorid
mju_fillInt(m->jnt_actuatorid, -1, m->njnt);
mju_fillInt(m->tendon_actuatorid, -1, m->ntendon);
for (int i=0; i < m->nu; i++) {
for (int i=0; i < m->nactuator; i++) {
// skip actuator with no damping and no armature
if (m->actuator_damping[i] == 0 &&
mju_isZero(m->actuator_dampingpoly+mjNPOLY*i, mjNPOLY) &&
@@ -312,7 +312,7 @@ static void setFixed(mjModel* m, mjData* d) {
// ----- apply compiler AUTO tree sleep policy
// actuators: trees with any actuated joint, site, body, or tendon do not auto-sleep
for (int i=0; i < m->nu; i++) {
for (int i=0; i < m->nactuator; i++) {
int bodyid = -1;
int tid = m->actuator_trnid[2*i];
switch ((mjtTrn)m->actuator_trntype[i]) {
@@ -868,7 +868,7 @@ static void set0(mjModel* m, mjData* d) {
// copy fields
mju_copy(m->flexedge_length0, d->flexedge_length, m->nflexedge);
mju_copy(m->tendon_length0, d->ten_length, m->ntendon);
mju_copy(m->actuator_length0, d->actuator_length, m->nu);
mju_copy(m->actuator_length0, d->actuator_length, m->nout);
// compute body_invweight0
m->body_invweight0[0] = m->body_invweight0[1] = 0.0;
@@ -1002,8 +1002,8 @@ static void set0(mjModel* m, mjData* d) {
m->tendon_invweight0[i] = mju_dot(tmp, tmp+nv, nv);
}
// compute actuator_acc0
for (int i=0; i < m->nu; i++) {
// compute actuator_acc0, one per force output (moment row)
for (int i=0; i < m->nout; i++) {
mju_sparse2dense(moment, d->actuator_moment, 1, nv, d->moment_rownnz + i,
d->moment_rowadr + i, d->moment_colind);
mj_solveM(m, d, tmp, moment, 1);
@@ -1011,7 +1011,7 @@ static void set0(mjModel* m, mjData* d) {
}
} else {
mju_zero(m->tendon_invweight0, m->ntendon);
mju_zero(m->actuator_acc0, m->nu);
mju_zero(m->actuator_acc0, m->nout);
}
// compute missing eq_data for body constraints
@@ -1101,7 +1101,7 @@ static void set0(mjModel* m, mjData* d) {
}
// compute actuator damping from dampratio
for (int i=0; i < m->nu; i++) {
for (int i=0; i < m->nactuator; i++) {
// get bias, gain parameters
mjtNum* biasprm = m->actuator_biasprm + i*mjNBIAS;
mjtNum* gainprm = m->actuator_gainprm + i*mjNGAIN;
@@ -1119,8 +1119,8 @@ static void set0(mjModel* m, mjData* d) {
// === interpret biasprm[2] > 0 as dampratio for position-like actuators
// "reflected" inertia (inversely scaled by transmission squared)
int rownnz = d->moment_rownnz[i];
int rowadr = d->moment_rowadr[i];
int rownnz = d->moment_rownnz[m->actuator_outadr[i]];
int rowadr = d->moment_rowadr[m->actuator_outadr[i]];
mjtNum* transmission = d->actuator_moment + rowadr;
mjtNum mass = 0;
for (int j=0; j < rownnz; j++) {
@@ -1363,6 +1363,7 @@ void mj_setConst(mjModel* m, mjData* d) {
static mjtNum evalAct(const mjModel* m, mjData* d, int index, int side,
const mjLROpt* opt) {
int nv = m->nv;
int out = m->actuator_outadr[index];
// reduce velocity
mju_scl(d->qvel, d->qvel, mju_exp(-m->opt.timestep/mjMAX(0.01, opt->timeconst)), nv);
@@ -1373,8 +1374,8 @@ static mjtNum evalAct(const mjModel* m, mjData* d, int index, int side,
// dense actuator_moment row
mj_markStack(d);
mjtNum* moment = mjSTACKALLOC(d, nv, mjtNum);
mju_sparse2dense(moment, d->actuator_moment, 1, nv, d->moment_rownnz + index,
d->moment_rowadr + index, d->moment_colind);
mju_sparse2dense(moment, d->actuator_moment, 1, nv, d->moment_rownnz + out,
d->moment_rowadr + out, d->moment_colind);
// set force to generate desired acceleration
mj_solveM(m, d, d->qfrc_applied, moment, 1);
@@ -1393,7 +1394,7 @@ static mjtNum evalAct(const mjModel* m, mjData* d, int index, int side,
mj_freeStack(d);
// return actuator length
return d->actuator_length[index];
return d->actuator_length[out];
}
@@ -1401,9 +1402,10 @@ static mjtNum evalAct(const mjModel* m, mjData* d, int index, int side,
int mj_setLengthRange(mjModel* m, mjData* d, int index,
const mjLROpt* opt, char* error, int error_sz) {
// check index
if (index < 0 || index >= m->nu) {
if (index < 0 || index >= m->nactuator) {
mjERROR("invalid actuator index");
}
int out = m->actuator_outadr[index];
// skip depending on mode and type
int ismuscle = (m->actuator_gaintype[index] == mjGAIN_MUSCLE ||
@@ -1417,7 +1419,7 @@ int mj_setLengthRange(mjModel* m, mjData* d, int index,
}
// use existing length range if available
if (opt->useexisting && (m->actuator_lengthrange[2*index] < m->actuator_lengthrange[2*index+1])) {
if (opt->useexisting && (m->actuator_lengthrange[2*out] < m->actuator_lengthrange[2*out+1])) {
return 1;
}
@@ -1432,8 +1434,8 @@ int mj_setLengthRange(mjModel* m, mjData* d, int index,
// make sure joint is limited
if (m->jnt_limited[threadid]) {
// copy range
m->actuator_lengthrange[2*index] = m->jnt_range[2*threadid];
m->actuator_lengthrange[2*index+1] = m->jnt_range[2*threadid+1];
m->actuator_lengthrange[2*out] = m->jnt_range[2*threadid];
m->actuator_lengthrange[2*out+1] = m->jnt_range[2*threadid+1];
// skip optimization
return 1;
@@ -1445,8 +1447,8 @@ int mj_setLengthRange(mjModel* m, mjData* d, int index,
// make sure tendon is limited
if (m->tendon_limited[threadid]) {
// copy range
m->actuator_lengthrange[2*index] = m->tendon_range[2*threadid];
m->actuator_lengthrange[2*index+1] = m->tendon_range[2*threadid+1];
m->actuator_lengthrange[2*out] = m->tendon_range[2*threadid];
m->actuator_lengthrange[2*out+1] = m->tendon_range[2*threadid+1];
// skip optimization
return 1;
@@ -1491,12 +1493,12 @@ int mj_setLengthRange(mjModel* m, mjData* d, int index,
}
// check range
mjtNum dif = m->actuator_lengthrange[2*index+1] - m->actuator_lengthrange[2*index];
mjtNum dif = m->actuator_lengthrange[2*out+1] - m->actuator_lengthrange[2*out];
if (dif <= 0) {
snprintf(error, error_sz,
"Invalid lengthrange (%g, %g) in actuator %d",
m->actuator_lengthrange[2*index],
m->actuator_lengthrange[2*index+1], index);
m->actuator_lengthrange[2*out],
m->actuator_lengthrange[2*out+1], index);
return 0;
}
@@ -1506,8 +1508,8 @@ int mj_setLengthRange(mjModel* m, mjData* d, int index,
"Lengthrange computation did not converge in actuator %d:\n"
" eval (%g, %g)\n range (%g, %g)",
index, lmin[0], lmax[0],
m->actuator_lengthrange[2*index],
m->actuator_lengthrange[2*index+1]);
m->actuator_lengthrange[2*out],
m->actuator_lengthrange[2*out+1]);
return 0;
}
@@ -1517,8 +1519,8 @@ int mj_setLengthRange(mjModel* m, mjData* d, int index,
"Lengthrange computation did not converge in actuator %d:\n"
" eval (%g, %g)\n range (%g, %g)",
index, lmin[1], lmax[1],
m->actuator_lengthrange[2*index],
m->actuator_lengthrange[2*index+1]);
m->actuator_lengthrange[2*out],
m->actuator_lengthrange[2*out+1]);
return 0;
}
+3 -3
View File
@@ -885,7 +885,7 @@ void mju_camIntrinsics(const mjModel* m, int camid,
// read delayed ctrl value for actuator at given time
mjtNum mj_readCtrl(const mjModel* m, const mjData* d, int id, mjtNum time, int interp) {
// validate actuator id
if (id < 0 || id >= m->nu) {
if (id < 0 || id >= m->nactuator) {
mjERROR("invalid actuator id %d", id);
return 0;
}
@@ -893,7 +893,7 @@ mjtNum mj_readCtrl(const mjModel* m, const mjData* d, int id, mjtNum time, int i
// no delay: return current ctrl value
int nsample = m->actuator_history[2*id];
if (nsample == 0) {
return d->ctrl[id];
return d->ctrl[m->actuator_ctrladr[id]];
}
// resolve interpolation order: use model's interp if argument is -1
@@ -938,7 +938,7 @@ const mjtNum* mj_readSensor(const mjModel* m, const mjData* d, int id, mjtNum ti
void mj_initCtrlHistory(const mjModel* m, mjData* d, int id,
const mjtNum* times, const mjtNum* values) {
// validate actuator id
if (id < 0 || id >= m->nu) {
if (id < 0 || id >= m->nactuator) {
mjERROR("invalid actuator id %d", id);
return;
}
+7 -7
View File
@@ -1116,7 +1116,7 @@ int mjv_isCatenary(const mjModel* m, const mjData* d, int i, mjtNum* length) {
// no actuator
if (draw_catenary) {
for (int j=0; j < m->nu; j++) {
for (int j=0; j < m->nactuator; j++) {
if (m->actuator_trntype[j] == mjTRN_TENDON && m->actuator_trnid[2*j] == i) {
draw_catenary = 0;
break;
@@ -1271,7 +1271,7 @@ static void addSliderCrankGeoms(const mjModel* m, mjData* d, const mjvOption* vo
}
const float scl = m->stat.meansize;
for (int i=0; i < m->nu; i++) {
for (int i=0; i < m->nactuator; i++) {
if (m->actuator_trntype[i] == mjTRN_SLIDERCRANK) {
// get data
int j = m->actuator_trnid[2*i]; // crank
@@ -2077,7 +2077,7 @@ static void addActuatorGeoms(const mjModel* m, mjData* d, const mjvOption* vopt,
}
const float scl = m->stat.meansize;
for (int i=0; i < m->nu; i++) {
for (int i=0; i < m->nactuator; i++) {
if (!vopt->actuatorgroup[mjMAX(0, mjMIN(mjNGROUP-1, m->actuator_group[i]))]) {
continue;
}
@@ -2088,9 +2088,9 @@ static void addActuatorGeoms(const mjModel* m, mjData* d, const mjvOption* vopt,
// determine extended range
mjtNum rng[3] = {-1, 0, +1};
mjtNum rmin = -1, rmax = 1, act = 0;
if (m->actuator_ctrllimited[i]) {
rmin = m->actuator_ctrlrange[2*i];
rmax = m->actuator_ctrlrange[2*i+1];
if (m->actuator_ctrllimited[m->actuator_ctrladr[i]]) {
rmin = m->actuator_ctrlrange[2*m->actuator_ctrladr[i]];
rmax = m->actuator_ctrlrange[2*m->actuator_ctrladr[i]+1];
} else if (vopt->flags[mjVIS_ACTIVATION] && m->actuator_actlimited[i]) {
rmin = m->actuator_actrange[2*i];
rmax = m->actuator_actrange[2*i+1];
@@ -2121,7 +2121,7 @@ static void addActuatorGeoms(const mjModel* m, mjData* d, const mjvOption* vopt,
if (vopt->flags[mjVIS_ACTIVATION] && m->actuator_dyntype[i]) {
act = mju_clip(d->act[m->actuator_actadr[i] + m->actuator_actnum[i] - 1], rng[0], rng[2]);
} else {
act = mju_clip(d->ctrl[i], rng[0], rng[2]);
act = mju_clip(d->ctrl[m->actuator_ctrladr[i]], rng[0], rng[2]);
}
// compute interpolants
+68 -29
View File
@@ -330,6 +330,8 @@ void mjCModel::SaveDofOffsets(bool computesize) {
int qposadr = 0;
int dofadr = 0;
int actadr = 0;
int ctrladr = 0;
int outadr = 0;
int mocapadr = 0;
for (auto joint : joints_) {
@@ -347,6 +349,12 @@ void mjCModel::SaveDofOffsets(bool computesize) {
}
actuator->actadr_ = actuator->actdim_ ? actadr : -1;
actadr += actuator->actdim_;
// input and output blocks; all actuator types are currently 1x1
actuator->ctrladr_ = ctrladr;
ctrladr += actuator->ctrlnum_;
actuator->outadr_ = outadr;
outadr += actuator->outnum_;
}
for (mjCBody* body : bodies_) {
@@ -361,7 +369,9 @@ void mjCModel::SaveDofOffsets(bool computesize) {
nq = qposadr;
nv = dofadr;
na = actadr;
nu = (int)actuators_.size();
nu = ctrladr;
nactuator = (int)actuators_.size();
nout = outadr;
nmocap = mocapadr;
}
}
@@ -1192,6 +1202,8 @@ void mjCModel::Clear() {
nq = 0;
nv = 0;
nu = 0;
nactuator = 0;
nout = 0;
na = 0;
nflexnode = 0;
nflexvert = 0;
@@ -2166,7 +2178,7 @@ void mjCModel::SetSizes() {
ntuple = (int)tuples_.size();
nkey = (int)keys_.size();
nplugin = (int)plugins_.size();
nq = nv = ntree = nu = na = nmocap = 0;
nq = nv = ntree = nu = nactuator = nout = na = nmocap = 0;
// nq, nv, ntree
for (int i=0; i < njnt; i++) {
@@ -2195,9 +2207,11 @@ void mjCModel::SetSizes() {
}
}
// nu, na
// nu, nactuator, nout, na; all actuator types are currently 1x1
for (int i=0; i < actuators_.size(); i++) {
nu++;
nactuator++;
nu += actuators_[i]->ctrlnum_;
nout += actuators_[i]->outnum_;
na += actuators_[i]->actdim;
}
@@ -2373,7 +2387,7 @@ void mjCModel::SetSizes() {
for (int i=0; i < nexclude; i++) nnames += (int)excludes_[i]->name.length() + 1;
for (int i=0; i < neq; i++) nnames += (int)equalities_[i]->name.length() + 1;
for (int i=0; i < ntendon; i++) nnames += (int)tendons_[i]->name.length() + 1;
for (int i=0; i < nu; i++) nnames += (int)actuators_[i]->name.length() + 1;
for (int i=0; i < nactuator; i++) nnames += (int)actuators_[i]->name.length() + 1;
for (int i=0; i < nsensor; i++) nnames += (int)sensors_[i]->name.length() + 1;
for (int i=0; i < nnumeric; i++) nnames += (int)numerics_[i]->name.length() + 1;
for (int i=0; i < ntext; i++) nnames += (int)texts_[i]->name.length() + 1;
@@ -2465,7 +2479,7 @@ void* LRfunc(void* arg) {
LRThreadArg* larg = (LRThreadArg*)arg;
for (int i=larg->start; i < larg->start+larg->num; i++) {
if (i < larg->m->nu) {
if (i < larg->m->nactuator) {
if (!mj_setLengthRange(larg->m, larg->data, i, larg->LRopt, larg->error, larg->error_sz)) {
return nullptr;
}
@@ -2488,7 +2502,7 @@ void mjCModel::LengthRange(mjModel* m, mjData* data) {
// count actuators that need computation
int cnt = 0;
for (int i=0; i < m->nu; i++) {
for (int i=0; i < m->nactuator; i++) {
// skip depending on mode and type
int ismuscle = (m->actuator_gaintype[i] == mjGAIN_MUSCLE ||
m->actuator_biastype[i] == mjBIAS_MUSCLE);
@@ -2515,7 +2529,7 @@ void mjCModel::LengthRange(mjModel* m, mjData* data) {
// single thread
if (!compiler.usethread || cnt < 2 || nthread < 2) {
char err[200];
for (int i=0; i < m->nu; i++) {
for (int i=0; i < m->nactuator; i++) {
if (!mj_setLengthRange(m, data, i, &compiler.LRopt, err, 200)) {
throw mjCError(0, "%s", err);
}
@@ -2535,8 +2549,8 @@ void mjCModel::LengthRange(mjModel* m, mjData* data) {
}
// number of actuators per thread
int num = m->nu / nthread;
while (num*nthread < m->nu) {
int num = m->nactuator / nthread;
while (num*nthread < m->nactuator) {
num++;
}
@@ -3178,7 +3192,7 @@ void mjCModel::CopyPlugins(mjModel* m) {
{
// set actuator_plugin to the plugin instance ID
std::vector<std::vector<int> > plugin_to_actuators(nplugin);
for (int i = 0; i < nu; ++i) {
for (int i = 0; i < nactuator; ++i) {
if (actuators_[i]->plugin.active) {
int actuator_plugin = static_cast<mjCPlugin*>(actuators_[i]->plugin.element)->id;
m->actuator_plugin[i] = actuator_plugin;
@@ -3287,11 +3301,11 @@ int mjCModel::CountTendonDofs(const mjModel* m, int id) {
}
int mjCModel::CountNJmom(const mjModel* m) {
int nu = m->nu;
int nactuator = m->nactuator;
int nv = m->nv;
int count = 0;
for (int i = 0; i < nu; i++) {
for (int i = 0; i < nactuator; i++) {
// extract info
int id = m->actuator_trnid[2 * i];
@@ -3363,6 +3377,7 @@ int mjCModel::CountNJten(const mjModel* m) {
}
// copy objects outside kinematic tree
// NOLINTBEGIN(readability/fn_size)
void mjCModel::CopyObjects(mjModel* m) {
mjtSize adr, bone_adr, vert_adr, node_adr, normal_adr, face_adr, texcoord_adr, oct_adr;
mjtSize stiffness_adr, bending_adr;
@@ -3905,7 +3920,9 @@ void mjCModel::CopyObjects(mjModel* m) {
// actuators
adr = 0;
int delay_adr = 0;
for (int i=0; i < nu; i++) {
int ctrladr = 0;
int outadr = 0;
for (int i=0; i < nactuator; i++) {
// get pointer
mjCActuator* pac = actuators_[i];
@@ -3923,6 +3940,16 @@ void mjCModel::CopyObjects(mjModel* m) {
adr += m->actuator_actnum[i];
m->actuator_group[i] = pac->group;
// input and output blocks; all actuator types are currently 1x1
m->actuator_ctrladr[i] = ctrladr;
m->actuator_ctrlnum[i] = pac->ctrlnum_;
pac->ctrladr_ = ctrladr;
ctrladr += pac->ctrlnum_;
m->actuator_outadr[i] = outadr;
m->actuator_outnum[i] = pac->outnum_;
pac->outadr_ = outadr;
outadr += pac->outnum_;
// historyadr
m->actuator_delay[i] = (mjtNum)pac->delay;
m->actuator_history[2*i] = pac->nsample;
@@ -3934,23 +3961,32 @@ void mjCModel::CopyObjects(mjModel* m) {
m->actuator_historyadr[i] = -1;
}
m->actuator_ctrllimited[i] = (mjtBool)pac->is_ctrllimited();
m->actuator_forcelimited[i] = (mjtBool)pac->is_forcelimited();
m->actuator_actlimited[i] = (mjtBool)pac->is_actlimited();
m->actuator_actearly[i] = pac->actearly;
m->actuator_cranklength[i] = (mjtNum)pac->cranklength;
mjuu_copyvec(m->actuator_gear + 6*i, pac->gear, 6);
m->actuator_damping[i] = (mjtNum)pac->damping[0];
mjuu_copyvec(m->actuator_dampingpoly + mjNPOLY*i, pac->damping + 1, mjNPOLY);
m->actuator_armature[i] = (mjtNum)pac->armature;
mjuu_copyvec(m->actuator_dynprm + mjNDYN*i, pac->dynprm, mjNDYN);
mjuu_copyvec(m->actuator_gainprm + mjNGAIN*i, pac->gainprm, mjNGAIN);
mjuu_copyvec(m->actuator_biasprm + mjNBIAS*i, pac->biasprm, mjNBIAS);
mjuu_copyvec(m->actuator_ctrlrange + 2*i, pac->ctrlrange, 2);
mjuu_copyvec(m->actuator_forcerange + 2*i, pac->forcerange, 2);
mjuu_copyvec(m->actuator_actrange + 2*i, pac->actrange, 2);
mjuu_copyvec(m->actuator_lengthrange + 2*i, pac->lengthrange, 2);
mjuu_copyvec(m->actuator_user+nuser_actuator*i, pac->get_userdata().data(), nuser_actuator);
// per-input arrays, at the actuator's ctrl block
for (int j = m->actuator_ctrladr[i];
j < m->actuator_ctrladr[i] + m->actuator_ctrlnum[i]; j++) {
m->actuator_ctrllimited[j] = (mjtBool)pac->is_ctrllimited();
mjuu_copyvec(m->actuator_ctrlrange + 2 * j, pac->ctrlrange, 2);
}
// per-output arrays, at the actuator's output block
for (int j=m->actuator_outadr[i]; j < m->actuator_outadr[i]+m->actuator_outnum[i]; j++) {
m->actuator_forcelimited[j] = (mjtBool)pac->is_forcelimited();
mjuu_copyvec(m->actuator_forcerange + 2*j, pac->forcerange, 2);
mjuu_copyvec(m->actuator_gear + 6*j, pac->gear, 6);
mjuu_copyvec(m->actuator_lengthrange + 2*j, pac->lengthrange, 2);
}
}
// sensors
@@ -4084,6 +4120,7 @@ void mjCModel::CopyObjects(mjModel* m) {
mjuu_copyvec(body_pos0.data(), m->body_pos, 3*nbody);
mjuu_copyvec(body_quat0.data(), m->body_quat, 4*nbody);
}
// NOLINTEND(readability/fn_size)
@@ -4309,7 +4346,7 @@ void mjCModel::StoreKeyframes(mjCModel* dest) {
}
if (!compiled) {
nq = nv = na = nu = nmocap = 0;
nq = nv = na = nu = nactuator = nout = nmocap = 0;
}
}
@@ -4958,7 +4995,7 @@ void mjCModel::ExpandAllKeyframes() {
for (auto* key : keys_) {
ExpandKeyframe(key, qpos0.data(), body_pos0.data(), body_quat0.data());
}
nq = nv = na = nu = nmocap = 0;
nq = nv = na = nu = nactuator = nout = nmocap = 0;
}
@@ -5239,7 +5276,8 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
// create low-level model
mj_makeModel(&m,
nq, nv, nu, na, nbody, nbvh, nbvhstatic, nbvhdynamic, noct, njnt, ntree, nM, nB, nC,
nq, nv, nu, nactuator, nout, na,
nbody, nbvh, nbvhstatic, nbvhdynamic, noct, njnt, ntree, nM, nB, nC,
nD, ngeom, nsite, ncam, nlight, nflex, nflexnode, nflexvert, nflexedge, nflexelem,
nflexelemdata, nflexstiffness, nflexbending, nflexelemedge, nflexshelldata,
nflexevpair, nflextexcoord, nJfe, nJfv, nmesh, nmeshvert, nmeshnormal, nmeshtexcoord,
@@ -5603,7 +5641,8 @@ bool mjCModel::CopyBack(const mjModel* m) {
}
// make sure sizes match
if (nq != m->nq || nv != m->nv || nu != m->nu || na != m->na ||
if (nq != m->nq || nv != m->nv || nu != m->nu || nactuator != m->nactuator ||
nout != m->nout || na != m->na ||
nbody != m->nbody ||njnt != m->njnt || ngeom != m->ngeom || nsite != m->nsite ||
ncam != m->ncam || nlight != m->nlight || nmesh != m->nmesh ||
nskin != m->nskin || nhfield != m->nhfield ||
@@ -5838,17 +5877,17 @@ bool mjCModel::CopyBack(const mjModel* m) {
// actuators
mjCActuator* pa;
for (int i=0; i < nu; i++) {
for (int i=0; i < nactuator; i++) {
pa = actuators_[i];
mjuu_copyvec(pa->dynprm, m->actuator_dynprm+i*mjNDYN, mjNDYN);
mjuu_copyvec(pa->gainprm, m->actuator_gainprm+i*mjNGAIN, mjNGAIN);
mjuu_copyvec(pa->biasprm, m->actuator_biasprm+i*mjNBIAS, mjNBIAS);
mjuu_copyvec(pa->ctrlrange, m->actuator_ctrlrange+2*i, 2);
mjuu_copyvec(pa->forcerange, m->actuator_forcerange+2*i, 2);
mjuu_copyvec(pa->ctrlrange, m->actuator_ctrlrange+2*m->actuator_ctrladr[i], 2);
mjuu_copyvec(pa->forcerange, m->actuator_forcerange+2*m->actuator_outadr[i], 2);
mjuu_copyvec(pa->actrange, m->actuator_actrange+2*i, 2);
mjuu_copyvec(pa->lengthrange, m->actuator_lengthrange+2*i, 2);
mjuu_copyvec(pa->gear, m->actuator_gear+6*i, 6);
mjuu_copyvec(pa->lengthrange, m->actuator_lengthrange+2*m->actuator_outadr[i], 2);
mjuu_copyvec(pa->gear, m->actuator_gear+6*m->actuator_outadr[i], 6);
pa->damping[0] = (double)m->actuator_damping[i];
mjuu_copyvec(pa->damping + 1, m->actuator_dampingpoly + mjNPOLY*i, mjNPOLY);
pa->armature = (double)m->actuator_armature[i];
+3 -1
View File
@@ -84,7 +84,9 @@ class mjCModel_ : public mjsElement {
// sizes computed by Compile
mjtSize nq; // number of generalized coordinates = dim(qpos)
mjtSize nv; // number of degrees of freedom = dim(qvel)
mjtSize nu; // number of actuators/controls
mjtSize nu; // number of scalar controls = dim(ctrl)
mjtSize nactuator; // number of actuators
mjtSize nout; // number of force outputs = dim(actuator_force)
mjtSize na; // number of activation variables
mjtSize ntree; // number of trees
mjtSize nbvh; // number of total boundary volume hierarchies
+6
View File
@@ -6908,6 +6908,12 @@ mjCActuator::mjCActuator(mjCModel* _model, mjCDef* _def) {
// no previous state when an actuator is created
actadr_ = -1;
actdim_ = -1;
// input and output blocks, set by mjCModel; all actuator types are currently 1x1
ctrladr_ = -1;
ctrlnum_ = 1;
outadr_ = -1;
outnum_ = 1;
}
+4
View File
@@ -1810,6 +1810,10 @@ class mjCActuator_ : public mjCBase {
// variable used for temporarily storing the state of the actuator
int actadr_; // address of dof in data->act
int actdim_; // number of dofs in data->act
int ctrladr_; // address of first control in data->ctrl
int ctrlnum_; // number of controls
int outadr_; // address of first force output
int outnum_; // number of force outputs, from trntype
std::map<std::string, std::vector<mjtNum>> act_; // act at the previous step
std::map<std::string, mjtNum> ctrl_; // ctrl at the previous step
+23 -17
View File
@@ -1021,6 +1021,8 @@ public unsafe struct mjModel_ {
public UInt64 nq;
public UInt64 nv;
public UInt64 nu;
public UInt64 nactuator;
public UInt64 nout;
public UInt64 na;
public UInt64 nbody;
public UInt64 nbvh;
@@ -1480,33 +1482,37 @@ public unsafe struct mjModel_ {
public int* actuator_dyntype;
public int* actuator_gaintype;
public int* actuator_biastype;
public int* actuator_trnid;
public double* actuator_damping;
public double* actuator_dampingpoly;
public double* actuator_armature;
public int* actuator_ctrladr;
public int* actuator_ctrlnum;
public int* actuator_outadr;
public int* actuator_outnum;
public int* actuator_actadr;
public int* actuator_actnum;
public int* actuator_group;
public int* actuator_history;
public int* actuator_historyadr;
public double* actuator_delay;
public byte* actuator_ctrllimited;
public byte* actuator_forcelimited;
public byte* actuator_actlimited;
public int* actuator_trnid;
public double* actuator_cranklength;
public double* actuator_dynprm;
public double* actuator_gainprm;
public double* actuator_biasprm;
public byte* actuator_actearly;
public double* actuator_ctrlrange;
public double* actuator_forcerange;
public byte* actuator_actlimited;
public double* actuator_actrange;
public byte* actuator_actearly;
public int* actuator_history;
public int* actuator_historyadr;
public double* actuator_delay;
public double* actuator_damping;
public double* actuator_dampingpoly;
public double* actuator_armature;
public int* actuator_group;
public double* actuator_user;
public int* actuator_plugin;
public byte* actuator_ctrllimited;
public double* actuator_ctrlrange;
public double* actuator_gear;
public double* actuator_cranklength;
public byte* actuator_forcelimited;
public double* actuator_forcerange;
public double* actuator_acc0;
public double* actuator_length0;
public double* actuator_lengthrange;
public double* actuator_user;
public int* actuator_plugin;
public int* sensor_type;
public int* sensor_datatype;
public int* sensor_needstage;
+6
View File
@@ -4785,7 +4785,9 @@ EMSCRIPTEN_BINDINGS(mujoco_bindings) {
.property("actuator_biasprm", &MjModel::actuator_biasprm)
.property("actuator_biastype", &MjModel::actuator_biastype)
.property("actuator_cranklength", &MjModel::actuator_cranklength)
.property("actuator_ctrladr", &MjModel::actuator_ctrladr)
.property("actuator_ctrllimited", &MjModel::actuator_ctrllimited)
.property("actuator_ctrlnum", &MjModel::actuator_ctrlnum)
.property("actuator_ctrlrange", &MjModel::actuator_ctrlrange)
.property("actuator_damping", &MjModel::actuator_damping)
.property("actuator_dampingpoly", &MjModel::actuator_dampingpoly)
@@ -4802,6 +4804,8 @@ EMSCRIPTEN_BINDINGS(mujoco_bindings) {
.property("actuator_historyadr", &MjModel::actuator_historyadr)
.property("actuator_length0", &MjModel::actuator_length0)
.property("actuator_lengthrange", &MjModel::actuator_lengthrange)
.property("actuator_outadr", &MjModel::actuator_outadr)
.property("actuator_outnum", &MjModel::actuator_outnum)
.property("actuator_plugin", &MjModel::actuator_plugin)
.property("actuator_trnid", &MjModel::actuator_trnid)
.property("actuator_trntype", &MjModel::actuator_trntype)
@@ -5091,6 +5095,7 @@ EMSCRIPTEN_BINDINGS(mujoco_bindings) {
.property("nJten", &MjModel::nJten, &MjModel::set_nJten, reference())
.property("nM", &MjModel::nM, &MjModel::set_nM, reference())
.property("na", &MjModel::na, &MjModel::set_na, reference())
.property("nactuator", &MjModel::nactuator, &MjModel::set_nactuator, reference())
.property("name_actuatoradr", &MjModel::name_actuatoradr)
.property("name_bodyadr", &MjModel::name_bodyadr)
.property("name_camadr", &MjModel::name_camadr)
@@ -5165,6 +5170,7 @@ EMSCRIPTEN_BINDINGS(mujoco_bindings) {
.property("nnumeric", &MjModel::nnumeric, &MjModel::set_nnumeric, reference())
.property("nnumericdata", &MjModel::nnumericdata, &MjModel::set_nnumericdata, reference())
.property("noct", &MjModel::noct, &MjModel::set_noct, reference())
.property("nout", &MjModel::nout, &MjModel::set_nout, reference())
.property("npair", &MjModel::npair, &MjModel::set_npair, reference())
.property("npaths", &MjModel::npaths, &MjModel::set_npaths, reference())
.property("nplugin", &MjModel::nplugin, &MjModel::set_nplugin, reference())
+85 -61
View File
@@ -3723,6 +3723,18 @@ struct MjModel {
void set_nu(int value) {
ptr_->nu = static_cast<mjtSize>(value);
}
int nactuator() const {
return static_cast<int>(ptr_->nactuator);
}
void set_nactuator(int value) {
ptr_->nactuator = static_cast<mjtSize>(value);
}
int nout() const {
return static_cast<int>(ptr_->nout);
}
void set_nout(int value) {
ptr_->nout = static_cast<mjtSize>(value);
}
int na() const {
return static_cast<int>(ptr_->na);
}
@@ -5353,97 +5365,109 @@ struct MjModel {
return emscripten::val(emscripten::typed_memory_view(ptr_->nwrap, ptr_->wrap_prm));
}
emscripten::val actuator_trntype() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_trntype));
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_trntype));
}
emscripten::val actuator_dyntype() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_dyntype));
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_dyntype));
}
emscripten::val actuator_gaintype() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_gaintype));
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_gaintype));
}
emscripten::val actuator_biastype() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_biastype));
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_biastype));
}
emscripten::val actuator_trnid() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * 2, ptr_->actuator_trnid));
emscripten::val actuator_ctrladr() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_ctrladr));
}
emscripten::val actuator_damping() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_damping));
emscripten::val actuator_ctrlnum() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_ctrlnum));
}
emscripten::val actuator_dampingpoly() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * mjNPOLY, ptr_->actuator_dampingpoly));
emscripten::val actuator_outadr() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_outadr));
}
emscripten::val actuator_armature() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_armature));
emscripten::val actuator_outnum() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_outnum));
}
emscripten::val actuator_actadr() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_actadr));
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_actadr));
}
emscripten::val actuator_actnum() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_actnum));
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_actnum));
}
emscripten::val actuator_group() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_group));
emscripten::val actuator_trnid() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator * 2, ptr_->actuator_trnid));
}
emscripten::val actuator_cranklength() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_cranklength));
}
emscripten::val actuator_dynprm() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator * mjNDYN, ptr_->actuator_dynprm));
}
emscripten::val actuator_gainprm() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator * mjNGAIN, ptr_->actuator_gainprm));
}
emscripten::val actuator_biasprm() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator * mjNBIAS, ptr_->actuator_biasprm));
}
emscripten::val actuator_actlimited() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_actlimited));
}
emscripten::val actuator_actrange() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator * 2, ptr_->actuator_actrange));
}
emscripten::val actuator_actearly() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_actearly));
}
emscripten::val actuator_history() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * 2, ptr_->actuator_history));
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator * 2, ptr_->actuator_history));
}
emscripten::val actuator_historyadr() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_historyadr));
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_historyadr));
}
emscripten::val actuator_delay() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_delay));
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_delay));
}
emscripten::val actuator_damping() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_damping));
}
emscripten::val actuator_dampingpoly() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator * mjNPOLY, ptr_->actuator_dampingpoly));
}
emscripten::val actuator_armature() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_armature));
}
emscripten::val actuator_group() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_group));
}
emscripten::val actuator_user() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator * ptr_->nuser_actuator, ptr_->actuator_user));
}
emscripten::val actuator_plugin() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->actuator_plugin));
}
emscripten::val actuator_ctrllimited() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_ctrllimited));
}
emscripten::val actuator_forcelimited() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_forcelimited));
}
emscripten::val actuator_actlimited() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_actlimited));
}
emscripten::val actuator_dynprm() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * mjNDYN, ptr_->actuator_dynprm));
}
emscripten::val actuator_gainprm() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * mjNGAIN, ptr_->actuator_gainprm));
}
emscripten::val actuator_biasprm() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * mjNBIAS, ptr_->actuator_biasprm));
}
emscripten::val actuator_actearly() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_actearly));
}
emscripten::val actuator_ctrlrange() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * 2, ptr_->actuator_ctrlrange));
}
emscripten::val actuator_forcerange() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * 2, ptr_->actuator_forcerange));
}
emscripten::val actuator_actrange() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * 2, ptr_->actuator_actrange));
}
emscripten::val actuator_gear() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * 6, ptr_->actuator_gear));
return emscripten::val(emscripten::typed_memory_view(ptr_->nout * 6, ptr_->actuator_gear));
}
emscripten::val actuator_cranklength() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_cranklength));
emscripten::val actuator_forcelimited() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nout, ptr_->actuator_forcelimited));
}
emscripten::val actuator_forcerange() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nout * 2, ptr_->actuator_forcerange));
}
emscripten::val actuator_acc0() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_acc0));
return emscripten::val(emscripten::typed_memory_view(ptr_->nout, ptr_->actuator_acc0));
}
emscripten::val actuator_length0() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_length0));
return emscripten::val(emscripten::typed_memory_view(ptr_->nout, ptr_->actuator_length0));
}
emscripten::val actuator_lengthrange() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * 2, ptr_->actuator_lengthrange));
}
emscripten::val actuator_user() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu * ptr_->nuser_actuator, ptr_->actuator_user));
}
emscripten::val actuator_plugin() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->actuator_plugin));
return emscripten::val(emscripten::typed_memory_view(ptr_->nout * 2, ptr_->actuator_lengthrange));
}
emscripten::val sensor_type() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nsensor, ptr_->sensor_type));
@@ -5617,7 +5641,7 @@ struct MjModel {
return emscripten::val(emscripten::typed_memory_view(ptr_->ntendon, ptr_->name_tendonadr));
}
emscripten::val name_actuatoradr() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nu, ptr_->name_actuatoradr));
return emscripten::val(emscripten::typed_memory_view(ptr_->nactuator, ptr_->name_actuatoradr));
}
emscripten::val name_sensoradr() const {
return emscripten::val(emscripten::typed_memory_view(ptr_->nsensor, ptr_->name_sensoradr));
@@ -6870,13 +6894,13 @@ struct MjData {
return emscripten::val(emscripten::typed_memory_view(model->nwrap * 6, ptr_->wrap_xpos));
}
emscripten::val actuator_length() const {
return emscripten::val(emscripten::typed_memory_view(model->nu, ptr_->actuator_length));
return emscripten::val(emscripten::typed_memory_view(model->nout, ptr_->actuator_length));
}
emscripten::val moment_rownnz() const {
return emscripten::val(emscripten::typed_memory_view(model->nu, ptr_->moment_rownnz));
return emscripten::val(emscripten::typed_memory_view(model->nout, ptr_->moment_rownnz));
}
emscripten::val moment_rowadr() const {
return emscripten::val(emscripten::typed_memory_view(model->nu, ptr_->moment_rowadr));
return emscripten::val(emscripten::typed_memory_view(model->nout, ptr_->moment_rowadr));
}
emscripten::val moment_colind() const {
return emscripten::val(emscripten::typed_memory_view(model->nJmom, ptr_->moment_colind));
@@ -6921,7 +6945,7 @@ struct MjData {
return emscripten::val(emscripten::typed_memory_view(model->ntendon, ptr_->ten_velocity));
}
emscripten::val actuator_velocity() const {
return emscripten::val(emscripten::typed_memory_view(model->nu, ptr_->actuator_velocity));
return emscripten::val(emscripten::typed_memory_view(model->nout, ptr_->actuator_velocity));
}
emscripten::val cvel() const {
return emscripten::val(emscripten::typed_memory_view(model->nbody * 6, ptr_->cvel));
@@ -6966,7 +6990,7 @@ struct MjData {
return emscripten::val(emscripten::typed_memory_view(model->nD, ptr_->qLU));
}
emscripten::val actuator_force() const {
return emscripten::val(emscripten::typed_memory_view(model->nu, ptr_->actuator_force));
return emscripten::val(emscripten::typed_memory_view(model->nout, ptr_->actuator_force));
}
emscripten::val qfrc_actuator() const {
return emscripten::val(emscripten::typed_memory_view(model->nv, ptr_->qfrc_actuator));