Remove native sensor noise sampling.

PiperOrigin-RevId: 620075316
Change-Id: I6a0a1d63834e7c8bfd290f89d86fea791d794739
This commit is contained in:
Yuval Tassa
2024-03-28 15:31:54 -07:00
committed by Copybara-Service
parent 47ba72ea59
commit 5d26b50fce
14 changed files with 54 additions and 135 deletions
-6
View File
@@ -2129,12 +2129,6 @@ from its default.
When this flag is enabled, :ref:`mj_inverse` will interpret ``qacc`` as having been computed from the difference of
two sequential velocities, and undo the above modification.
.. _option-flag-sensornoise:
:at:`sensornoise`: :at-val:`[disable, enable], "disable"`
This flag enables the simulation of sensor noise. When disabled (which is the default) noise is not added to
sensordata, even if the sensors specify non-zero noise amplitudes. When enabled, zero-mean Gaussian noise is added to
the underlying deterministic sensor data. Its standard deviation is determined by the noise parameter of each sensor.
.. _option-flag-multiccd:
+2 -2
View File
@@ -247,9 +247,9 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`sensor<option-flag-sensor>` | :ref:`midphase<option-flag-midphase>` | :ref:`eulerdamp<option-flag-eulerdamp>` | :ref:`override<option-flag-override>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`energy<option-flag-energy>` | :ref:`fwdinv<option-flag-fwdinv>` | :ref:`invdiscrete<option-flag-invdiscrete>` | :ref:`sensornoise<option-flag-sensornoise>` | |
| | | | :ref:`energy<option-flag-energy>` | :ref:`fwdinv<option-flag-fwdinv>` | :ref:`invdiscrete<option-flag-invdiscrete>` | :ref:`multiccd<option-flag-multiccd>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`multiccd<option-flag-multiccd>` | :ref:`island<option-flag-island>` | | | |
| | | | :ref:`island<option-flag-island>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mujoco |br| |L| | | .. table:: |
+26 -10
View File
@@ -7,29 +7,45 @@ Upcoming version (not yet released)
General
^^^^^^^
1. Added the :ref:`actuatorgravcomp<body-joint-actuatorgravcomp>` joint attribute. When enabled, gravity compensation
.. admonition:: Breaking API changes
:class: attention
1. Removed the ability to natively add noise to sensors. Note that the ``mjModel.sensor_noise`` field and
:ref:`corresponding attribute<CSensor>` are kept and now function as a convenient location for the user to save
standard-deviation information for their own use. This feature was removed because:
- There was no mechanism to seed the randon noise generator.
- It was not thread-safe, even if seeding would have been provided, sampling on multiple threads would lead to
non-reproducible results.
- This feature was seen as overreach by the engine. Adding noise should be the user's responsibility.
- We are not aware of anyone who was actually using the feature.
**Migration:** Add noise to sensor values yourself.
2. Added the :ref:`actuatorgravcomp<body-joint-actuatorgravcomp>` joint attribute. When enabled, gravity compensation
forces on the joint are treated as applied by actuators. See attribute documentation for more details. The example
model
`refsite.xml <https://github.com/google-deepmind/mujoco/blob/main/test/engine/testdata/actuation/refsite.xml>`__,
which demostrates Cartesian actuation of an arm, has been updated to use this attribute.
2. Added support for gmsh format 2.2, as generated by e.g. `fTetwild <https://github.com/wildmeshing/fTetWild>`__.
3. Added support for gmsh format 2.2, as generated by e.g. `fTetwild <https://github.com/wildmeshing/fTetWild>`__.
MJX
^^^
3. Improved performance of SAT for convex collisions.
4. Fixed bug for sphere/capsule-convex deep penetration.
5. Fixed bug where ``mjx.Data`` produced by ``mjx.put_data`` had different treedef than ``mjx.make_data``.
6. Throw an error for margin/gap for convex mesh collisions, since they are not supported.
4. Improved performance of SAT for convex collisions.
5. Fixed bug for sphere/capsule-convex deep penetration.
6. Fixed bug where ``mjx.Data`` produced by ``mjx.put_data`` had different treedef than ``mjx.make_data``.
7. Throw an error for margin/gap for convex mesh collisions, since they are not supported.
Simulate
^^^^^^^^
7. Fixed bug in order of enable flag strings. Before this change, using the simulate UI to toggle the
:ref:`invdiscrete<option-flag-invdiscrete>` or :ref:`sensornoise<option-flag-sensornoise>`
flags would actually toggle the other flag.
8. Fixed bug in order of enable flag strings. Before this change, using the simulate UI to toggle the
:ref:`invdiscrete<option-flag-invdiscrete>` or the (now removed) ``sensornoise`` flags would actually toggle the
other flag.
Python bindings
^^^^^^^^^^^^^^^
8. Added the ``mujoco.minimize`` Python module for nonlinear least-squares, designed for System Identification (sysID).
9. Added the ``mujoco.minimize`` Python module for nonlinear least-squares, designed for System Identification (sysID).
The sysID tutorial is work in progress, but a pedagogical colab notebook with examples, including Inverse
Kinematics, is available here: |ls_colab|
+3 -4
View File
@@ -426,12 +426,11 @@ typedef enum mjtEnableBit_ { // enable optional feature bitflags
mjENBL_ENERGY = 1<<1, // energy computation
mjENBL_FWDINV = 1<<2, // record solver statistics
mjENBL_INVDISCRETE = 1<<3, // discrete-time inverse dynamics
mjENBL_SENSORNOISE = 1<<4, // add noise to sensor data
// experimental features:
mjENBL_MULTICCD = 1<<5, // multi-point convex collision detection
mjENBL_ISLAND = 1<<6, // constraint island discovery
mjENBL_MULTICCD = 1<<4, // multi-point convex collision detection
mjENBL_ISLAND = 1<<5, // constraint island discovery
mjNENABLE = 7 // number of enable flags
mjNENABLE = 6 // number of enable flags
} mjtEnableBit;
typedef enum mjtJoint_ { // type of degree of freedom
mjJNT_FREE = 0, // global position and orientation (quat) (7)
+4 -3
View File
@@ -1057,9 +1057,10 @@ Here we describe the XML attributes common to all sensor types, so as to avoid r
:at:`name`: :at-val:`string, optional`
Name of the sensor.
:at:`noise`: :at-val:`real, "0"`
The standard deviation of zero-mean Gaussian noise added to the sensor output, when the :at:`sensornoise`
attribute of :ref:`flag <option-flag>` is enabled. Sensor noise respects the sensor data type:
quaternions and unit vectors remain normalized, non-negative quantities remain non-negative.
The standard deviation of the noise model of this sensor. In versions prior to 3.1.4, this would lead to noise being
added to the sensors. In release 3.1.4 this feature was removed, see :doc:`3.1.4 changelog <changelog>` for a
detailed justification. As of subsequent versions, this attrbute serves as a convenient location for saving standard
deviation information for later use.
:at:`cutoff`: :at-val:`real, "0"`
When this value is positive, it limits the absolute value of the sensor output. It is also used to normalize the
sensor output in the sensor data plots in :ref:`simulate.cc <saSimulate>`.
+3 -4
View File
@@ -74,12 +74,11 @@ typedef enum mjtEnableBit_ { // enable optional feature bitflags
mjENBL_ENERGY = 1<<1, // energy computation
mjENBL_FWDINV = 1<<2, // record solver statistics
mjENBL_INVDISCRETE = 1<<3, // discrete-time inverse dynamics
mjENBL_SENSORNOISE = 1<<4, // add noise to sensor data
// experimental features:
mjENBL_MULTICCD = 1<<5, // multi-point convex collision detection
mjENBL_ISLAND = 1<<6, // constraint island discovery
mjENBL_MULTICCD = 1<<4, // multi-point convex collision detection
mjENBL_ISLAND = 1<<5, // constraint island discovery
mjNENABLE = 7 // number of enable flags
mjNENABLE = 6 // number of enable flags
} mjtEnableBit;
+3 -4
View File
@@ -54,10 +54,9 @@ ENUMS: Mapping[str, EnumDecl] = dict([
('mjENBL_ENERGY', 2),
('mjENBL_FWDINV', 4),
('mjENBL_INVDISCRETE', 8),
('mjENBL_SENSORNOISE', 16),
('mjENBL_MULTICCD', 32),
('mjENBL_ISLAND', 64),
('mjNENABLE', 7),
('mjENBL_MULTICCD', 16),
('mjENBL_ISLAND', 32),
('mjNENABLE', 6),
]),
)),
('mjtJoint',
+3 -4
View File
@@ -42,10 +42,9 @@ class EnumsTest(absltest.TestCase):
('mjENBL_ENERGY', 1<<1),
('mjENBL_FWDINV', 1<<2),
('mjENBL_INVDISCRETE', 1<<3),
('mjENBL_SENSORNOISE', 1<<4),
('mjENBL_MULTICCD', 1<<5),
('mjENBL_ISLAND', 1<<6),
('mjNENABLE', 7)))
('mjENBL_MULTICCD', 1<<4),
('mjENBL_ISLAND', 1<<5),
('mjNENABLE', 6)))
# values mostly increment by one with occasional overrides
def test_mjtGeom(self): # pylint: disable=invalid-name
+4 -4
View File
@@ -623,7 +623,7 @@ class MuJoCoBindingsTest(parameterized.TestCase):
self.assertEqual(struct, struct2)
self.assertNotEqual(struct, 3)
self.assertNotEqual(struct, None)
self.assertIsNotNone(struct)
# mutable structs shouldn't declare __hash__
with self.assertRaises(TypeError):
@@ -705,7 +705,8 @@ class MuJoCoBindingsTest(parameterized.TestCase):
# Check that the output argument must have the correct dtype.
with self.assertRaises(TypeError):
mujoco.mju_rotVecQuat(vec, quat, res=np.zeros(3, int))
res = np.zeros(3, np.int32)
mujoco.mju_rotVecQuat(res, vec, quat)
def test_getsetstate(self): # pylint: disable=invalid-name
mujoco.mj_step(self.model, self.data)
@@ -850,8 +851,7 @@ Euler integrator, semi-implicit in velocity.
self.assertEqual(mujoco.mjtEnableBit.mjENBL_OVERRIDE, 1<<0)
self.assertEqual(mujoco.mjtEnableBit.mjENBL_ENERGY, 1<<1)
self.assertEqual(mujoco.mjtEnableBit.mjENBL_FWDINV, 1<<2)
self.assertEqual(mujoco.mjtEnableBit.mjENBL_SENSORNOISE, 1<<4)
self.assertEqual(mujoco.mjtEnableBit.mjNENABLE, 7)
self.assertEqual(mujoco.mjtEnableBit.mjNENABLE, 6)
self.assertEqual(mujoco.mjtGeom.mjGEOM_PLANE, 0)
self.assertEqual(mujoco.mjtGeom.mjGEOM_HFIELD, 1)
self.assertEqual(mujoco.mjtGeom.mjGEOM_SPHERE, 2)
+1 -85
View File
@@ -32,78 +32,9 @@
#include "engine/engine_util_spatial.h"
//-------------------------------- utility ---------------------------------------------------------
// add sensor noise after each stage
static void add_noise(const mjModel* m, mjData* d, mjtStage stage) {
int adr, dim;
mjtNum rnd[4], noise, quat[4], res[4];
// process sensors matching stage and having positive noise
for (int i=0; i < m->nsensor; i++) {
if (m->sensor_needstage[i] == stage && m->sensor_noise[i] > 0) {
// get sensor info
adr = m->sensor_adr[i];
dim = m->sensor_dim[i];
noise = m->sensor_noise[i];
// real or positive: add noise directly, with clamp for positive
if (m->sensor_datatype[i] == mjDATATYPE_REAL ||
m->sensor_datatype[i] == mjDATATYPE_POSITIVE) {
for (int j=0; j < dim; j++) {
// get random numbers; use only the first one
rnd[0] = mju_standardNormal(rnd+1);
// positive
if (m->sensor_datatype[i] == mjDATATYPE_POSITIVE) {
// add noise only if positive, keep it positive
if (d->sensordata[adr+j] > 0) {
d->sensordata[adr+j] = mju_max(0, d->sensordata[adr+j]+rnd[0]*noise);
}
}
// real
else {
d->sensordata[adr+j] += rnd[0]*noise;
}
}
}
// axis or quat: rotate around random axis by random angle
else {
// get four random numbers
rnd[0] = mju_standardNormal(rnd+1);
rnd[2] = mju_standardNormal(rnd+3);
// scale angle, normalize axis, make quaternion
rnd[0] *= noise;
mju_normalize3(rnd+1);
mju_axisAngle2Quat(quat, rnd+1, rnd[0]);
// axis
if (m->sensor_datatype[i] == mjDATATYPE_AXIS) {
// apply quaternion rotation to axis, assign
mju_rotVecQuat(res, d->sensordata+adr, quat);
mju_copy3(d->sensordata+adr, res);
}
// quaternion
else if (m->sensor_datatype[i] == mjDATATYPE_QUATERNION) {
// apply quaternion rotation to quaternion, assign
mju_mulQuat(d->sensordata+adr, d->sensordata+adr, quat);
}
// unknown datatype
else {
mjERROR("unknown datatype in sensor %d", i);
}
}
}
}
}
// apply cutoff after each stage
static void apply_cutoff(const mjModel* m, mjData* d, mjtStage stage) {
// process sensors matching stage and having positive cutoff
@@ -442,11 +373,6 @@ void mj_sensorPos(const mjModel* m, mjData* d) {
mjcb_sensor(m, d, mjSTAGE_POS);
}
// add noise if enabled
if (mjENABLED(mjENBL_SENSORNOISE)) {
add_noise(m, d, mjSTAGE_POS);
}
// compute plugin sensor values
if (m->nplugin) {
const int nslot = mjp_pluginCount();
@@ -623,11 +549,6 @@ void mj_sensorVel(const mjModel* m, mjData* d) {
mjcb_sensor(m, d, mjSTAGE_VEL);
}
// add noise if enabled
if (mjENABLED(mjENBL_SENSORNOISE)) {
add_noise(m, d, mjSTAGE_VEL);
}
// trigger computation of plugins
if (m->nplugin) {
const int nslot = mjp_pluginCount();
@@ -839,11 +760,6 @@ void mj_sensorAcc(const mjModel* m, mjData* d) {
mjcb_sensor(m, d, mjSTAGE_ACC);
}
// add noise if enabled
if (mjENABLED(mjENBL_SENSORNOISE)) {
add_noise(m, d, mjSTAGE_ACC);
}
// trigger computation of plugins
if (m->nplugin) {
const int nslot = mjp_pluginCount();
-1
View File
@@ -67,7 +67,6 @@ const char* mjENABLESTRING[mjNENABLE] = {
"Energy",
"Fwdinv",
"InvDiscrete",
"Sensornoise",
"MultiCCD",
"Island"
};
+2 -3
View File
@@ -101,10 +101,10 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
"solver", "iterations", "ls_iterations", "noslip_iterations", "mpr_iterations",
"sdf_iterations", "sdf_initpoints", "actuatorgroupdisable"},
{"<"},
{"flag", "?", "22", "constraint", "equality", "frictionloss", "limit", "contact",
{"flag", "?", "21", "constraint", "equality", "frictionloss", "limit", "contact",
"passive", "gravity", "clampctrl", "warmstart",
"filterparent", "actuation", "refsafe", "sensor", "midphase", "eulerdamp",
"override", "energy", "fwdinv", "invdiscrete", "sensornoise", "multiccd", "island"},
"override", "energy", "fwdinv", "invdiscrete", "multiccd", "island"},
{">"},
{"size", "*", "14", "memory", "njmax", "nconmax", "nstack", "nuserdata", "nkey",
@@ -1091,7 +1091,6 @@ void mjXReader::Option(XMLElement* section, mjOption* opt) {
READENBL("energy", mjENBL_ENERGY)
READENBL("fwdinv", mjENBL_FWDINV)
READENBL("invdiscrete", mjENBL_INVDISCRETE)
READENBL("sensornoise", mjENBL_SENSORNOISE)
READENBL("multiccd", mjENBL_MULTICCD)
READENBL("island", mjENBL_ISLAND)
#undef READENBL
-1
View File
@@ -938,7 +938,6 @@ void mjXWriter::Option(XMLElement* root) {
WRITEENBL("energy", mjENBL_ENERGY)
WRITEENBL("fwdinv", mjENBL_FWDINV)
WRITEENBL("invdiscrete", mjENBL_INVDISCRETE)
WRITEENBL("sensornoise", mjENBL_SENSORNOISE)
WRITEENBL("multiccd", mjENBL_MULTICCD)
WRITEENBL("island", mjENBL_ISLAND)
#undef WRITEENBL
+3 -4
View File
@@ -164,10 +164,9 @@ public enum mjtEnableBit : int{
mjENBL_ENERGY = 2,
mjENBL_FWDINV = 4,
mjENBL_INVDISCRETE = 8,
mjENBL_SENSORNOISE = 16,
mjENBL_MULTICCD = 32,
mjENBL_ISLAND = 64,
mjNENABLE = 7,
mjENBL_MULTICCD = 16,
mjENBL_ISLAND = 32,
mjNENABLE = 6,
}
public enum mjtJoint : int{
mjJNT_FREE = 0,