Add mjModel.sensor_intprm, integer parameters of sensors

PiperOrigin-RevId: 781053754
Change-Id: I90e5ef1cab3f87b894dbc70dccfc8bf0046ce1b6
This commit is contained in:
Yuval Tassa
2025-07-09 07:59:28 -07:00
committed by Copybara-Service
parent 9d64ed9575
commit a3d251f552
9 changed files with 60 additions and 1 deletions
+4
View File
@@ -444,6 +444,10 @@ shown in the table below. Their names are in the format ``mjKEY_XXX``. They corr
- 5
- The maximal number of real-valued parameters used to define the impedance of each scalar constraint.
Determines the size of all ``mjModel.XXX_solimp`` fields.
* - ``mjNSENS``
- 2
- The number of sensor parameters.
Determines the size of ``mjModel.sensor_intprm``.
* - ``mjNSOLVER``
- 200
- The number of iterations where solver statistics can be stored in ``mjData.solver``. This array is used
+2
View File
@@ -1458,6 +1458,7 @@ struct mjModel_ {
int* sensor_objid; // id of sensorized object (nsensor x 1)
int* sensor_reftype; // type of reference frame (mjtObj) (nsensor x 1)
int* sensor_refid; // id of reference frame; -1: global frame (nsensor x 1)
int* sensor_intprm; // sensor parameters (nsensor x mjNSENS)
int* sensor_dim; // number of scalar outputs (nsensor x 1)
int* sensor_adr; // address in sensor array (nsensor x 1)
mjtNum* sensor_cutoff; // cutoff for real and positive; 0: ignore (nsensor x 1)
@@ -2324,6 +2325,7 @@ typedef struct mjsSensor_ { // sensor specification
mjString* objname; // name of sensorized object
mjtObj reftype; // type of referenced object
mjString* refname; // name of referenced object
int intprm[mjNSENS]; // integer parameters
// user-defined sensors
mjtDataType datatype; // data type for sensor measurement
+2
View File
@@ -41,6 +41,7 @@
#define mjNFLUID 12 // number of fluid interaction parameters
#define mjNREF 2 // number of solver reference parameters
#define mjNIMP 5 // number of solver impedance parameters
#define mjNSENS 2 // number of sensor parameters
#define mjNSOLVER 200 // size of one mjData.solver array
#define mjNISLAND 20 // number of mjData.solver arrays
@@ -1130,6 +1131,7 @@ struct mjModel_ {
int* sensor_objid; // id of sensorized object (nsensor x 1)
int* sensor_reftype; // type of reference frame (mjtObj) (nsensor x 1)
int* sensor_refid; // id of reference frame; -1: global frame (nsensor x 1)
int* sensor_intprm; // sensor parameters (nsensor x mjNSENS)
int* sensor_dim; // number of scalar outputs (nsensor x 1)
int* sensor_adr; // address in sensor array (nsensor x 1)
mjtNum* sensor_cutoff; // cutoff for real and positive; 0: ignore (nsensor x 1)
+1
View File
@@ -692,6 +692,7 @@ typedef struct mjsSensor_ { // sensor specification
mjString* objname; // name of sensorized object
mjtObj reftype; // type of referenced object
mjString* refname; // name of referenced object
int intprm[mjNSENS]; // integer parameters
// user-defined sensors
mjtDataType datatype; // data type for sensor measurement
+1
View File
@@ -540,6 +540,7 @@
X ( int, sensor_objid, nsensor, 1 ) \
X ( int, sensor_reftype, nsensor, 1 ) \
X ( int, sensor_refid, nsensor, 1 ) \
X ( int, sensor_intprm, nsensor, mjNSENS ) \
X ( int, sensor_dim, nsensor, 1 ) \
X ( int, sensor_adr, nsensor, 1 ) \
X ( mjtNum, sensor_cutoff, nsensor, 1 ) \
+16
View File
@@ -4149,6 +4149,14 @@ STRUCTS: Mapping[str, StructDecl] = dict([
doc='id of reference frame; -1: global frame',
array_extent=('nsensor',),
),
StructFieldDecl(
name='sensor_intprm',
type=PointerType(
inner_type=ValueType(name='int'),
),
doc='sensor parameters',
array_extent=('nsensor', 'mjNSENS'),
),
StructFieldDecl(
name='sensor_dim',
type=PointerType(
@@ -10388,6 +10396,14 @@ STRUCTS: Mapping[str, StructDecl] = dict([
),
doc='name of referenced object',
),
StructFieldDecl(
name='intprm',
type=ArrayType(
inner_type=ValueType(name='int'),
extents=(2,),
),
doc='integer parameters',
),
StructFieldDecl(
name='datatype',
type=ValueType(name='mjtDataType'),
+1
View File
@@ -3454,6 +3454,7 @@ void mjCModel::CopyObjects(mjModel* m) {
m->sensor_objid[i] = psen->obj ? psen->obj->id : -1;
m->sensor_reftype[i] = psen->reftype;
m->sensor_refid[i] = psen->ref ? psen->ref->id : -1;
mjuu_copyvec(m->sensor_intprm+i*mjNSENS, psen->intprm, mjNSENS);
m->sensor_dim[i] = psen->dim;
m->sensor_cutoff[i] = (mjtNum)psen->cutoff;
m->sensor_noise[i] = (mjtNum)psen->noise;
+31 -1
View File
@@ -544,7 +544,37 @@ TEST_F(SensorTest, Clock) {
mj_deleteModel(model);
}
// test clock sensor
// test that integer parameters pass through
TEST_F(SensorTest, IntPrm) {
constexpr char xml[] = R"(
<mujoco>
<sensor>
<clock name="dummy"/>
</sensor>
</mujoco>
)";
ASSERT_EQ(mjNSENS, 2);
char err[1024];
mjSpec* spec = mj_parseXMLString(xml, 0, err, sizeof(err));
ASSERT_THAT(spec, NotNull()) << err;
mjModel* model = mj_compile(spec, nullptr);
EXPECT_EQ(model->sensor_intprm[0], 0);
EXPECT_EQ(model->sensor_intprm[1], 0);
mj_deleteModel(model);
mjsSensor* s = mjs_asSensor(mjs_findElement(spec, mjOBJ_SENSOR, "dummy"));
s->intprm[0] = 3;
s->intprm[1] = 4;
model = mj_compile(spec, nullptr);
EXPECT_EQ(model->sensor_intprm[0], 3);
EXPECT_EQ(model->sensor_intprm[1], 4);
mj_deleteModel(model);
mj_deleteSpec(spec);
}
// test sequential collision sensors
TEST_F(SensorTest, CollisionSequential) {
constexpr char xml[] = R"(
<mujoco>
+2
View File
@@ -49,6 +49,7 @@ public const int mjNBIAS = 10;
public const int mjNFLUID = 12;
public const int mjNREF = 2;
public const int mjNIMP = 5;
public const int mjNSENS = 2;
public const int mjNSOLVER = 200;
public const int mjNISLAND = 20;
public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJPLUGIN_H_ = true;
@@ -5683,6 +5684,7 @@ public unsafe struct mjModel_ {
public int* sensor_objid;
public int* sensor_reftype;
public int* sensor_refid;
public int* sensor_intprm;
public int* sensor_dim;
public int* sensor_adr;
public double* sensor_cutoff;