@@ -250,35 +250,59 @@ void Sim::set_dynamic_joint_state(const DynamicJointSchema& schema,
250250 throw std::invalid_argument (msg.str ());
251251 }
252252
253+ std::vector<bool > matched_target_joints (this ->dynamic_joint_specs .size (),
254+ false );
253255 int qpos_offset = 0 ;
254256 int qvel_offset = 0 ;
255257 for (size_t i = 0 ; i < joint_count; ++i) {
256258 auto spec_iter =
257259 this ->dynamic_joint_name_to_index .find (schema.joint_names [i]);
258- if (spec_iter != this ->dynamic_joint_name_to_index .end ()) {
259- const DynamicJointSpec& target_spec =
260- this ->dynamic_joint_specs [spec_iter->second ];
261- if (target_spec.type != schema.joint_types [i] ||
262- target_spec.qpos_size != schema.qpos_sizes [i] ||
263- target_spec.qvel_size != schema.qvel_sizes [i]) {
264- std::ostringstream msg;
265- msg << " Dynamic joint schema mismatch for joint '"
266- << schema.joint_names [i] << " '." ;
267- throw std::invalid_argument (msg.str ());
268- }
269-
270- for (int j = 0 ; j < target_spec.qpos_size ; ++j) {
271- this ->d ->qpos [target_spec.qpos_adr + j] = state.qpos [qpos_offset + j];
272- }
273- for (int j = 0 ; j < target_spec.qvel_size ; ++j) {
274- this ->d ->qvel [target_spec.qvel_adr + j] = state.qvel [qvel_offset + j];
275- }
260+ if (spec_iter == this ->dynamic_joint_name_to_index .end ()) {
261+ std::cerr << " WARNING: Recorded dynamic joint '" << schema.joint_names [i]
262+ << " ' is missing in the replay model. Skipping it."
263+ << std::endl;
264+ qpos_offset += schema.qpos_sizes [i];
265+ qvel_offset += schema.qvel_sizes [i];
266+ continue ;
267+ }
268+
269+ const DynamicJointSpec& target_spec =
270+ this ->dynamic_joint_specs [spec_iter->second ];
271+ matched_target_joints[spec_iter->second ] = true ;
272+ if (target_spec.type != schema.joint_types [i] ||
273+ target_spec.qpos_size != schema.qpos_sizes [i] ||
274+ target_spec.qvel_size != schema.qvel_sizes [i]) {
275+ std::ostringstream msg;
276+ msg << " Dynamic joint schema mismatch for joint '"
277+ << schema.joint_names [i] << " ': expected type=" << target_spec.type
278+ << " , qpos_size=" << target_spec.qpos_size
279+ << " , qvel_size=" << target_spec.qvel_size << " but got type="
280+ << schema.joint_types [i] << " , qpos_size=" << schema.qpos_sizes [i]
281+ << " , qvel_size=" << schema.qvel_sizes [i] << " ." ;
282+ throw std::invalid_argument (msg.str ());
283+ }
284+
285+ for (int j = 0 ; j < target_spec.qpos_size ; ++j) {
286+ this ->d ->qpos [target_spec.qpos_adr + j] = state.qpos [qpos_offset + j];
287+ }
288+ for (int j = 0 ; j < target_spec.qvel_size ; ++j) {
289+ this ->d ->qvel [target_spec.qvel_adr + j] = state.qvel [qvel_offset + j];
276290 }
277291
278292 qpos_offset += schema.qpos_sizes [i];
279293 qvel_offset += schema.qvel_sizes [i];
280294 }
281295
296+ for (size_t i = 0 ; i < this ->dynamic_joint_specs .size (); ++i) {
297+ if (!matched_target_joints[i]) {
298+ std::cerr << " WARNING: Replay model dynamic joint '"
299+ << this ->dynamic_joint_specs [i].name
300+ << " ' is missing in the recorded schema. Leaving it at its "
301+ " current value."
302+ << std::endl;
303+ }
304+ }
305+
282306 mj_forward (this ->m , this ->d );
283307}
284308
0 commit comments