|
33 | 33 |
|
34 | 34 | MODEL = assets.get_contents('cartpole.xml') |
35 | 35 | MODEL_NO_NAMES = assets.get_contents('cartpole_no_names.xml') |
| 36 | +MODEL_3RD_ORDER_ACTUATORS = assets.get_contents( |
| 37 | + 'model_with_third_order_actuators.xml') |
| 38 | +MODEL_INCORRECT_ACTUATOR_ORDER = assets.get_contents( |
| 39 | + 'model_incorrect_actuator_order.xml') |
36 | 40 |
|
37 | 41 | FIELD_REPR = { |
38 | 42 | 'act': ('FieldIndexer(act):\n' |
@@ -145,6 +149,42 @@ def testDataNamedIndexing(self, field_name, key, numeric_key): |
145 | 149 | # indexing. |
146 | 150 | np.testing.assert_array_equal(field[numeric_key], indexer[key]) |
147 | 151 |
|
| 152 | + @parameterized.parameters( |
| 153 | + # (field name, named index key, expected integer index key) |
| 154 | + ('act', 'cylinder', 0), |
| 155 | + ('act_dot', 'general', 1), |
| 156 | + ('act', ['general', 'cylinder', 'general'], [1, 0, 1])) |
| 157 | + def testIndexThirdOrderActuators(self, field_name, key, numeric_key): |
| 158 | + model = wrapper.MjModel.from_xml_string(MODEL_3RD_ORDER_ACTUATORS) |
| 159 | + data = wrapper.MjData(model) |
| 160 | + size_to_axis_indexer = index.make_axis_indexers(model) |
| 161 | + data_indexers = index.struct_indexer(data, 'mjdata', size_to_axis_indexer) |
| 162 | + |
| 163 | + indexer = getattr(data_indexers, field_name) |
| 164 | + field = getattr(data, field_name) |
| 165 | + |
| 166 | + # Explicit check that the converted key matches the numeric key. |
| 167 | + converted_key = indexer._convert_key(key) |
| 168 | + self.assertIndexExpressionEqual(numeric_key, converted_key) |
| 169 | + |
| 170 | + # This writes unique values to the underlying buffer to prevent false |
| 171 | + # negatives. |
| 172 | + field.flat[:] = np.arange(field.size) |
| 173 | + |
| 174 | + # Check that the result of named indexing matches the result of numeric |
| 175 | + # indexing. |
| 176 | + np.testing.assert_array_equal(field[numeric_key], indexer[key]) |
| 177 | + |
| 178 | + def testIncorrectActuatorOrder(self): |
| 179 | + # Our indexing of third-order actuators relies on an undocumented |
| 180 | + # requirement of MuJoCo's compiler that all third-order actuators come after |
| 181 | + # all second-order actuators. This test ensures that the rule still holds |
| 182 | + # (e.g. in future versions of MuJoCo). |
| 183 | + with self.assertRaisesRegexp( |
| 184 | + wrapper.Error, |
| 185 | + '2nd-order actuators must come before 3rd-order'): |
| 186 | + wrapper.MjModel.from_xml_string(MODEL_INCORRECT_ACTUATOR_ORDER) |
| 187 | + |
148 | 188 | @parameterized.parameters( |
149 | 189 | # (field name, named index key) |
150 | 190 | ('xpos', 'pole'), |
|
0 commit comments