Add mj_geomDistance API function and sensors for geometric distance, normal direction and segment between between two geoms. Fixes #51
PiperOrigin-RevId: 632458301 Change-Id: I65b7e5bb0df59008028114cf4a07e0d6365ff3d3
This commit is contained in:
committed by
Copybara-Service
parent
31de1dad9d
commit
02d015458c
@@ -57,8 +57,8 @@ Main simulation
|
||||
|
||||
These are the main entry points to the simulator. Most users will only need to call :ref:`mj_step`, which computes
|
||||
everything and advanced the simulation state by one time step. Controls and applied forces must either be set in advance
|
||||
(in mjData.{ctrl, qfrc_applied, xfrc_applied}), or a control callback :ref:`mjcb_control` must be installed which will be
|
||||
called just before the controls and applied forces are needed. Alternatively, one can use :ref:`mj_step1` and
|
||||
(in mjData.{ctrl, qfrc_applied, xfrc_applied}), or a control callback :ref:`mjcb_control` must be installed which will
|
||||
be called just before the controls and applied forces are needed. Alternatively, one can use :ref:`mj_step1` and
|
||||
:ref:`mj_step2` which break down the simulation pipeline into computations that are executed before and after the
|
||||
controls are needed; in this way one can set controls that depend on the results from :ref:`mj_step1`. Keep in mind
|
||||
though that the RK4 solver does not work with mj_step1/2.
|
||||
@@ -72,8 +72,8 @@ be set before calling this function. Given the state (qpos, qvel, act), mj_forwa
|
||||
while mj_inverse maps from acceleration to force. Mathematically these functions are inverse of each other, but
|
||||
numerically this may not always be the case because the forward dynamics rely on a constraint optimization algorithm
|
||||
which is usually terminated early. The difference between the results of forward and inverse dynamics can be computed
|
||||
with the function :ref:`mj_compareFwdInv`, which can be thought of as another solver accuracy check (as well as a general
|
||||
sanity check).
|
||||
with the function :ref:`mj_compareFwdInv`, which can be thought of as another solver accuracy check (as well as a
|
||||
general sanity check).
|
||||
|
||||
The skip version of :ref:`mj_forward` and :ref:`mj_inverse` are useful for example when qpos was unchanged but qvel was
|
||||
changed (usually in the context of finite differencing). Then there is no point repeating the computations that only
|
||||
@@ -408,6 +408,28 @@ Compute object 6D acceleration (rot:lin) in object-centered frame, world/local o
|
||||
sensors are not present in the model, :ref:`mj_rnePostConstraint` must be manually called in order to calculate
|
||||
mjData.cacc -- the total body acceleration, including contributions from the constraint solver.
|
||||
|
||||
.. _mj_geomDistance:
|
||||
|
||||
mj_geomDistance
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
.. mujoco-include:: mj_geomDistance
|
||||
|
||||
Returns the smallest signed distance between two geoms and optionally the segment from ``geom1`` to ``geom2``.
|
||||
Returned distances are bounded from above by ``distmax``. |br| If no collision of distance smaller than ``distmax`` is
|
||||
found, the function will return ``distmax`` and ``fromto``, if given, will be set to (0, 0, 0, 0, 0, 0).
|
||||
|
||||
.. admonition:: Positive ``distmax`` values
|
||||
:class: note
|
||||
|
||||
.. TODO: b/339596989 - Improve mjc_Convex.
|
||||
|
||||
For some colliders, a large, positive ``distmax`` will result in an accurate measurement. However, for collision
|
||||
pairs which use the general ``mjc_Convex`` collider, the result will be approximate and likely innacurate.
|
||||
This is considered a bug to be fixed in a future release.
|
||||
In order to determine whether a geom pair uses ``mjc_Convex``, inspect the table at the top of
|
||||
`engine_collision_driver.c <https://github.com/google-deepmind/mujoco/blob/main/src/engine/engine_collision_driver.c>`__.
|
||||
|
||||
.. _mj_contactForce:
|
||||
|
||||
mj_contactForce
|
||||
|
||||
@@ -33,8 +33,8 @@ The model and all files referenced in it can be loaded from disk or from a VFS w
|
||||
|
||||
These are the main entry points to the simulator. Most users will only need to call :ref:`mj_step`, which computes
|
||||
everything and advanced the simulation state by one time step. Controls and applied forces must either be set in advance
|
||||
(in mjData.{ctrl, qfrc_applied, xfrc_applied}), or a control callback :ref:`mjcb_control` must be installed which will be
|
||||
called just before the controls and applied forces are needed. Alternatively, one can use :ref:`mj_step1` and
|
||||
(in mjData.{ctrl, qfrc_applied, xfrc_applied}), or a control callback :ref:`mjcb_control` must be installed which will
|
||||
be called just before the controls and applied forces are needed. Alternatively, one can use :ref:`mj_step1` and
|
||||
:ref:`mj_step2` which break down the simulation pipeline into computations that are executed before and after the
|
||||
controls are needed; in this way one can set controls that depend on the results from :ref:`mj_step1`. Keep in mind
|
||||
though that the RK4 solver does not work with mj_step1/2.
|
||||
@@ -48,8 +48,8 @@ be set before calling this function. Given the state (qpos, qvel, act), mj_forwa
|
||||
while mj_inverse maps from acceleration to force. Mathematically these functions are inverse of each other, but
|
||||
numerically this may not always be the case because the forward dynamics rely on a constraint optimization algorithm
|
||||
which is usually terminated early. The difference between the results of forward and inverse dynamics can be computed
|
||||
with the function :ref:`mj_compareFwdInv`, which can be thought of as another solver accuracy check (as well as a general
|
||||
sanity check).
|
||||
with the function :ref:`mj_compareFwdInv`, which can be thought of as another solver accuracy check (as well as a
|
||||
general sanity check).
|
||||
|
||||
The skip version of :ref:`mj_forward` and :ref:`mj_inverse` are useful for example when qpos was unchanged but qvel was
|
||||
changed (usually in the context of finite differencing). Then there is no point repeating the computations that only
|
||||
@@ -180,6 +180,23 @@ generalized velocities to subtree angular momentum. More precisely if :math:`h`
|
||||
body index ``body`` in ``mjData.subtree_angmom`` (reported by the :ref:`subtreeangmom<sensor-subtreeangmom>` sensor)
|
||||
and :math:`\dot q` is the generalized velocity ``mjData.qvel``, then :math:`h = H \dot q`.
|
||||
|
||||
.. _mj_geomDistance:
|
||||
|
||||
Returns the smallest signed distance between two geoms and optionally the segment from ``geom1`` to ``geom2``.
|
||||
Returned distances are bounded from above by ``distmax``. |br| If no collision of distance smaller than ``distmax`` is
|
||||
found, the function will return ``distmax`` and ``fromto``, if given, will be set to (0, 0, 0, 0, 0, 0).
|
||||
|
||||
.. admonition:: Positive ``distmax`` values
|
||||
:class: note
|
||||
|
||||
.. TODO: b/339596989 - Improve mjc_Convex.
|
||||
|
||||
For some colliders, a large, positive ``distmax`` will result in an accurate measurement. However, for collision
|
||||
pairs which use the general ``mjc_Convex`` collider, the result will be approximate and likely innacurate.
|
||||
This is considered a bug to be fixed in a future release.
|
||||
In order to determine whether a geom pair uses ``mjc_Convex``, inspect the table at the top of
|
||||
`engine_collision_driver.c <https://github.com/google-deepmind/mujoco/blob/main/src/engine/engine_collision_driver.c>`__.
|
||||
|
||||
.. _mj_mulM:
|
||||
|
||||
This function multiplies the joint-space inertia matrix stored in mjData.qM by a vector. qM has a custom sparse format
|
||||
|
||||
@@ -6723,6 +6723,186 @@ The presence of this sensor in a model triggers a call to :ref:`mj_subtreeVel` d
|
||||
:at:`body`: :at-val:`string, required`
|
||||
Name of the body where the kinematic subtree is rooted.
|
||||
|
||||
.. _collision-sensors:
|
||||
|
||||
collision sensors
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
The following 3 sensor types, :ref:`sensor/distance<sensor-distance>`, :ref:`sensor/normal<sensor-normal>` and
|
||||
:ref:`sensor/fromto<sensor-fromto>`, respectively measure the distance, normal direction and line segment of the
|
||||
smallest signed distance between the surfaces of two geoms using the narrow-phase geom-geom colliders. The collision
|
||||
computation is always performed, independently of the standard collision :ref:`selection and filtering<coSelection>`
|
||||
pipeline. These 3 sensors share some common properties:
|
||||
|
||||
.. _collision-sensors-cutoff:
|
||||
|
||||
:at:`cutoff`
|
||||
For most sensors, the :at:`cutoff` attribute simply defines a clipping operation on sensor values. For collision
|
||||
sensors, it defines the maximum distance at which collisions will be detected, corresponding to the ``dismax``
|
||||
argument of :ref:`mj_geomDistance`. For example, at the default value of 0, only negative distances (corresponding
|
||||
to geom-geom penetration) will be reported by :ref:`sensor/distance<sensor-distance>`.
|
||||
In order to determine collision properties of non-penetrating geom pairs, a positive :at:`cutoff` is required.
|
||||
|
||||
.. admonition:: Positive cutoff values
|
||||
:class: note
|
||||
|
||||
.. TODO: b/339596989 - Improve mjc_Convex.
|
||||
|
||||
For some colliders, a positive :at:`cutoff` will result in an accurate measurement. However, for collision
|
||||
pairs which use the general ``mjc_Convex`` collider, the result will be approximate and likely innacurate.
|
||||
This is considered a bug to be fixed in a future release.
|
||||
In order to determine whether a geom pair uses ``mjc_Convex``, inspect the table at the top of
|
||||
`engine_collision_driver.c <https://github.com/google-deepmind/mujoco/blob/main/src/engine/engine_collision_driver.c>`__.
|
||||
|
||||
:at:`geom1`, :at:`geom2`, :at:`body1`, :at:`body2`
|
||||
For all 3 collision sensor types, the two colliding geoms can be specified explicitly using the :at:`geom1` and
|
||||
:at:`geom2` attributes or implicitly, using :at:`body1`, :at:`body2`. In the latter case the sensor will iterate over
|
||||
all geoms of the specified body or bodies (mixed specification like :at:`geom1`, :at:`body2` are allowed), and
|
||||
select the collision with the smallest signed distance.
|
||||
|
||||
sequential sensors
|
||||
When multiple collision sensors are defined sequentially and have identical attributes (:at:`geom1`, :at:`body1`,
|
||||
:at:`geom2`, :at:`body2`, :at:`cutoff`), for example when both distance and normal are queried for the same geom
|
||||
pair, the collision functions will be called once for the whole sensor block, avoiding repeated computation.
|
||||
|
||||
.. _sensor-distance:
|
||||
|
||||
:el-prefix:`sensor/` |-| **distance** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This element creates a sensor that returns the smallest signed distance between the surfaces of two geoms.
|
||||
See :ref:`collision-sensors` for more details about sensors of this type.
|
||||
|
||||
.. _sensor-distance-cutoff:
|
||||
|
||||
:at:`cutoff`
|
||||
See :ref:`collision-sensors` for the sematics of this attribute, which is different than for other sensor catagories.
|
||||
If no collision is detected, the distance sensor returns the :at:`cutoff` value, so in this case
|
||||
:at:`cutoff` acts as a maximum clipping value, in addition to the special semantics.
|
||||
|
||||
.. _sensor-distance-geom1:
|
||||
|
||||
:at:`geom1`: :at-val:`string, optional`
|
||||
Name of the first geom. Exactly one of (:at:`geom1`, :at:`body1`) must be specified.
|
||||
|
||||
.. _sensor-distance-geom2:
|
||||
|
||||
:at:`geom2`: :at-val:`string, optional`
|
||||
Name of the second geom. Exactly one of (:at:`geom2`, :at:`body2`) must be specified.
|
||||
|
||||
.. _sensor-distance-body1:
|
||||
|
||||
:at:`body1`: :at-val:`string, optional`
|
||||
Name of the first body. Exactly one of (:at:`geom1`, :at:`body1`) must be specified.
|
||||
|
||||
.. _sensor-distance-body2:
|
||||
|
||||
:at:`body2`: :at-val:`string, optional`
|
||||
Name of the second body. Exactly one of (:at:`geom2`, :at:`body2`) must be specified.
|
||||
|
||||
.. _sensor-distance-name:
|
||||
|
||||
.. _sensor-distance-noise:
|
||||
|
||||
.. _sensor-distance-user:
|
||||
|
||||
:at:`name`, :at:`noise`, :at:`user`
|
||||
See :ref:`CSensor`.
|
||||
|
||||
|
||||
.. _sensor-normal:
|
||||
|
||||
:el-prefix:`sensor/` |-| **normal** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This element creates a sensor that returns the normal direction of the smallest signed distance between the surfaces of
|
||||
two geoms. It is guaranteed to point from the surface of geom1 to the surface of geom2, though note that in the case of
|
||||
penetration, this direction is generally in the opposite direction to that of the centroids.
|
||||
See :ref:`collision-sensors` for more details about sensors of this type.
|
||||
|
||||
.. _sensor-normal-cutoff:
|
||||
|
||||
:at:`cutoff`
|
||||
See :ref:`collision-sensors` for the sematics of this attribute, which is different than for other sensor catagories.
|
||||
If no collision is detected, the :ref:`normal<sensor-normal>` sensor returns (0, 0, 0), otherwise it returns a
|
||||
normalized direction vector. For this sensor, :at:`cutoff` does not lead to any clamping.
|
||||
|
||||
.. _sensor-normal-geom1:
|
||||
|
||||
:at:`geom1`: :at-val:`string, optional`
|
||||
Name of the first geom. Exactly one of (:at:`geom1`, :at:`body1`) must be specified.
|
||||
|
||||
.. _sensor-normal-geom2:
|
||||
|
||||
:at:`geom2`: :at-val:`string, optional`
|
||||
Name of the second geom. Exactly one of (:at:`geom2`, :at:`body2`) must be specified.
|
||||
|
||||
.. _sensor-normal-body1:
|
||||
|
||||
:at:`body1`: :at-val:`string, optional`
|
||||
Name of the first body. Exactly one of (:at:`geom1`, :at:`body1`) must be specified.
|
||||
|
||||
.. _sensor-normal-body2:
|
||||
|
||||
:at:`body2`: :at-val:`string, optional`
|
||||
Name of the second body. Exactly one of (:at:`geom2`, :at:`body2`) must be specified.
|
||||
|
||||
.. _sensor-normal-name:
|
||||
|
||||
.. _sensor-normal-noise:
|
||||
|
||||
.. _sensor-normal-user:
|
||||
|
||||
:at:`name`, :at:`noise`, :at:`user`
|
||||
See :ref:`CSensor`.
|
||||
|
||||
|
||||
.. _sensor-fromto:
|
||||
|
||||
:el-prefix:`sensor/` |-| **fromto** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This element creates a sensor that returns the segment defining the smallest signed distance between the surfaces of two
|
||||
geoms. The segment is defined by 6 numbers (x1, y1, z1, x2, y2, z2) corresponding to two points in the world frame.
|
||||
(x1, y1, z1) is on the surface of geom1, (x2, y2, z2) is on the surface of geom2. When this sensor is present and the
|
||||
:ref:`mjVIS_RANGEFINDER<mjtVisFlag>` visualization flag is set, segments will be visualized as rangefinder rays.
|
||||
See :ref:`collision-sensors` for more details about sensors of this type.
|
||||
|
||||
.. _sensor-fromto-cutoff:
|
||||
|
||||
:at:`cutoff`
|
||||
See :ref:`collision-sensors` for the sematics of this attribute, which is different than for other sensor catagories.
|
||||
If no collision is detected, the :ref:`fromto<sensor-fromto>` sensor returns 6 zeros.
|
||||
For this sensor, :at:`cutoff` does not lead to any clamping.
|
||||
|
||||
.. _sensor-fromto-geom1:
|
||||
|
||||
:at:`geom1`: :at-val:`string, optional`
|
||||
Name of the first geom. Exactly one of (:at:`geom1`, :at:`body1`) must be specified.
|
||||
|
||||
.. _sensor-fromto-geom2:
|
||||
|
||||
:at:`geom2`: :at-val:`string, optional`
|
||||
Name of the second geom. Exactly one of (:at:`geom2`, :at:`body2`) must be specified.
|
||||
|
||||
.. _sensor-fromto-body1:
|
||||
|
||||
:at:`body1`: :at-val:`string, optional`
|
||||
Name of the first body. Exactly one of (:at:`geom1`, :at:`body1`) must be specified.
|
||||
|
||||
.. _sensor-fromto-body2:
|
||||
|
||||
:at:`body2`: :at-val:`string, optional`
|
||||
Name of the second body. Exactly one of (:at:`geom2`, :at:`body2`) must be specified.
|
||||
|
||||
.. _sensor-fromto-name:
|
||||
|
||||
.. _sensor-fromto-noise:
|
||||
|
||||
.. _sensor-fromto-user:
|
||||
|
||||
:at:`name`, :at:`noise`, :at:`user`
|
||||
See :ref:`CSensor`.
|
||||
|
||||
.. _sensor-clock:
|
||||
|
||||
|
||||
@@ -1163,6 +1163,33 @@
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |_| sensor |br| |_| |L| | | .. table:: |
|
||||
| :ref:`distance | \* | :class: mjcf-attributes |
|
||||
| <sensor-distance>` | | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`name<sensor-distance-name>` | :ref:`geom1<sensor-distance-geom1>` | :ref:`geom2<sensor-distance-geom2>` | :ref:`body1<sensor-distance-body1>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`body2<sensor-distance-body2>` | :ref:`cutoff<sensor-distance-cutoff>` | :ref:`noise<sensor-distance-noise>` | :ref:`user<sensor-distance-user>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |_| sensor |br| |_| |L| | | .. table:: |
|
||||
| :ref:`normal | \* | :class: mjcf-attributes |
|
||||
| <sensor-normal>` | | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`name<sensor-normal-name>` | :ref:`geom1<sensor-normal-geom1>` | :ref:`geom2<sensor-normal-geom2>` | :ref:`body1<sensor-normal-body1>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`body2<sensor-normal-body2>` | :ref:`cutoff<sensor-normal-cutoff>` | :ref:`noise<sensor-normal-noise>` | :ref:`user<sensor-normal-user>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |_| sensor |br| |_| |L| | | .. table:: |
|
||||
| :ref:`fromto | \* | :class: mjcf-attributes |
|
||||
| <sensor-fromto>` | | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`name<sensor-fromto-name>` | :ref:`geom1<sensor-fromto-geom1>` | :ref:`geom2<sensor-fromto-geom2>` | :ref:`body1<sensor-fromto-body1>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`body2<sensor-fromto-body2>` | :ref:`cutoff<sensor-fromto-cutoff>` | :ref:`noise<sensor-fromto-noise>` | :ref:`user<sensor-fromto-user>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |_| sensor |br| |_| |L| | | .. table:: |
|
||||
| :ref:`clock | \* | :class: mjcf-attributes |
|
||||
| <sensor-clock>` | | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
|
||||
+9
-2
@@ -5,12 +5,19 @@ Changelog
|
||||
Upcoming version (not yet released)
|
||||
-----------------------------------
|
||||
|
||||
General
|
||||
^^^^^^^
|
||||
|
||||
1. Added :ref:`mj_geomDistance` for computing the shortest signed distance between two geoms and optionally a segment
|
||||
connecting them. Relatedly, added the 3 sensors: :ref:`distance<sensor-distance>`, :ref:`normal<sensor-normal>`,
|
||||
:ref:`fromto<sensor-fromto>`. See the function and sensor documentation for details. Fixes :github:issue:`51`.
|
||||
|
||||
Bug fixes
|
||||
^^^^^^^^^
|
||||
|
||||
1. Fixed a bug the could cause collisions to be missed when :ref:`fusestatic<compiler-fusestatic>` is enabled, as is
|
||||
2. Fixed a bug the could cause collisions to be missed when :ref:`fusestatic<compiler-fusestatic>` is enabled, as is
|
||||
often the case for URDF imports. Fixes :github:issue:`1069`, :github:issue:`1577`.
|
||||
2. Fixed a bug that was causing the visualization of SDF iterations to write outside the size of the vector storing
|
||||
3. Fixed a bug that was causing the visualization of SDF iterations to write outside the size of the vector storing
|
||||
them. Fixes :github:issue:`1539`.
|
||||
|
||||
Version 3.1.5 (May 7, 2024)
|
||||
|
||||
@@ -643,6 +643,11 @@ typedef enum mjtSensor_ { // type of sensor
|
||||
mjSENS_SUBTREELINVEL, // 3D linear velocity of subtree
|
||||
mjSENS_SUBTREEANGMOM, // 3D angular momentum of subtree
|
||||
|
||||
// sensors for geometric distance; attached to geoms or bodies
|
||||
mjSENS_GEOMDIST, // signed distance between two geoms
|
||||
mjSENS_GEOMNORMAL, // normal direction between two geoms
|
||||
mjSENS_GEOMFROMTO, // segment between two geoms
|
||||
|
||||
// global sensors
|
||||
mjSENS_CLOCK, // simulation time
|
||||
|
||||
@@ -2542,6 +2547,8 @@ void mj_objectVelocity(const mjModel* m, const mjData* d,
|
||||
int objtype, int objid, mjtNum res[6], int flg_local);
|
||||
void mj_objectAcceleration(const mjModel* m, const mjData* d,
|
||||
int objtype, int objid, mjtNum res[6], int flg_local);
|
||||
mjtNum mj_geomDistance(const mjModel* m, const mjData* d, int geom1, int geom2,
|
||||
mjtNum distmax, mjtNum fromto[6]);
|
||||
void mj_contactForce(const mjModel* m, const mjData* d, int id, mjtNum result[6]);
|
||||
void mj_differentiatePos(const mjModel* m, mjtNum* qvel, mjtNum dt,
|
||||
const mjtNum* qpos1, const mjtNum* qpos2);
|
||||
|
||||
Reference in New Issue
Block a user