Add actuator and sensor delays. Fixes #1004
PiperOrigin-RevId: 866478839 Change-Id: Id21a6da0f98454c8fa39ea5af8a5e213d6eae497
This commit is contained in:
committed by
Copybara-Service
parent
84fa527723
commit
6419534bad
@@ -3267,5 +3267,95 @@ TEST_F(XMLReaderTest, CameraOutputDefault) {
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
|
||||
// ------------- test delay attribute parsing ----------------------------------
|
||||
|
||||
TEST_F(ActuatorParseTest, ActuatorDelayParsed) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<option timestep="1"/>
|
||||
<worldbody>
|
||||
<body>
|
||||
<geom size="1"/>
|
||||
<joint name="jnt1"/>
|
||||
<joint name="jnt2"/>
|
||||
<joint name="jnt3"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
<actuator>
|
||||
<motor joint="jnt1"/>
|
||||
<motor joint="jnt2" delay="3" nsample="3" interp="zoh"/>
|
||||
<motor joint="jnt3" delay="10" nsample="10" interp="cubic"/>
|
||||
</actuator>
|
||||
</mujoco>
|
||||
)";
|
||||
std::array<char, 1024> error;
|
||||
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
|
||||
ASSERT_THAT(model, NotNull()) << error.data();
|
||||
ASSERT_EQ(model->nu, 3);
|
||||
// actuator_history[2*i] = nsample, actuator_history[2*i+1] = interp
|
||||
EXPECT_EQ(model->actuator_history[0], 0); // jnt1 nsample
|
||||
EXPECT_EQ(model->actuator_history[1], 0); // jnt1 interp (no buffer, default 0)
|
||||
EXPECT_EQ(model->actuator_history[2], 3); // jnt2 nsample
|
||||
EXPECT_EQ(model->actuator_history[3], 0); // jnt2 interp (ZOH)
|
||||
EXPECT_EQ(model->actuator_history[4], 10); // jnt3 nsample
|
||||
EXPECT_EQ(model->actuator_history[5], 2); // jnt3 interp (cubic)
|
||||
EXPECT_EQ(model->actuator_historyadr[0], -1);
|
||||
EXPECT_EQ(model->actuator_historyadr[1], 0);
|
||||
EXPECT_EQ(model->actuator_historyadr[2], 8); // 2+2*3 = 8
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
|
||||
TEST_F(ActuatorParseTest, ActuatorDelayDefault) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<option timestep="1"/>
|
||||
<default>
|
||||
<motor delay="5" nsample="5"/>
|
||||
</default>
|
||||
<worldbody>
|
||||
<body>
|
||||
<geom size="1"/>
|
||||
<joint name="jnt1"/>
|
||||
<joint name="jnt2"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
<actuator>
|
||||
<motor joint="jnt1"/>
|
||||
<motor joint="jnt2" delay="0" nsample="0"/>
|
||||
</actuator>
|
||||
</mujoco>
|
||||
)";
|
||||
std::array<char, 1024> error;
|
||||
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
|
||||
ASSERT_THAT(model, NotNull()) << error.data();
|
||||
ASSERT_EQ(model->nu, 2);
|
||||
EXPECT_EQ(model->actuator_history[0], 5);
|
||||
EXPECT_EQ(model->actuator_history[2], 0);
|
||||
EXPECT_EQ(model->actuator_historyadr[0], 0);
|
||||
EXPECT_EQ(model->actuator_historyadr[1], -1);
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
|
||||
TEST_F(ActuatorParseTest, ActuatorDelayRequiresHistory) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<worldbody>
|
||||
<body>
|
||||
<geom size="1"/>
|
||||
<joint name="jnt"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
<actuator>
|
||||
<motor joint="jnt" delay="1"/>
|
||||
</actuator>
|
||||
</mujoco>
|
||||
)";
|
||||
std::array<char, 1024> error;
|
||||
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
|
||||
ASSERT_THAT(model, IsNull());
|
||||
EXPECT_THAT(error.data(),
|
||||
HasSubstr("setting delay > 0 without a history buffer"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mujoco
|
||||
|
||||
Reference in New Issue
Block a user