126 bool initialize(rclcpp::Node::SharedPtr node,
const std::string& model_path,
const std::string& mujoco_model_topic,
127 double sim_speed_factor,
bool headless);
197 bool set_free_joint_states(
const std::vector<mujoco_ros2_control_msgs::msg::FreeJointState>& free_joints,
198 std::string& error_message);
253 std::vector<mjtNum> qpos;
254 std::vector<mjtNum> qvel;
255 std::vector<mjtNum> act;
256 std::vector<mjtNum> qfrc_actuator;
257 std::vector<mjtNum> sensordata;
258 std::vector<mjtNum> ctrl;
285 RCLCPP_WARN_EXPRESSION(logger_, sim_mutex_ ==
nullptr,
"Sim recursive mutex is still nullptr");
296 return step_count_.load();
305 void apply_staged_control_inputs();
313 void publish_control_state();
322 void refresh_data_snapshot();
332 void publish_clock();
337 void update_sim_display();
342 struct FreeJointWrite
347 mjtNum world_quat[4];
348 mjtNum world_linvel[3];
349 mjtNum world_angvel[3];
359 bool resolve_frame_id(
const std::string& frame_id,
const std::string& field_label,
int& body_id,
360 std::string& error_message);
373 bool resolve_free_joint_write(
const mujoco_ros2_control_msgs::msg::FreeJointState& state, FreeJointWrite& out,
374 std::string& error_message);
377 void reset_world_callback(
const std::shared_ptr<mujoco_ros2_control_msgs::srv::ResetWorld::Request> request,
378 std::shared_ptr<mujoco_ros2_control_msgs::srv::ResetWorld::Response> response);
379 void set_pause_callback(
const std::shared_ptr<mujoco_ros2_control_msgs::srv::SetPause::Request> request,
380 std::shared_ptr<mujoco_ros2_control_msgs::srv::SetPause::Response> response);
381 void step_simulation_callback(
const std::shared_ptr<mujoco_ros2_control_msgs::srv::StepSimulation::Request> request,
382 std::shared_ptr<mujoco_ros2_control_msgs::srv::StepSimulation::Response> response);
384 set_free_joint_state_callback(
const std::shared_ptr<mujoco_ros2_control_msgs::srv::SetFreeJointState::Request> request,
385 std::shared_ptr<mujoco_ros2_control_msgs::srv::SetFreeJointState::Response> response);
387 rclcpp::Logger get_logger()
const
393 rclcpp::Logger logger_ = rclcpp::get_logger(
"MujocoSimulation");
396 rclcpp::Node::SharedPtr node_;
399 std::string model_path_;
400 std::string mujoco_model_topic_;
404 mjModel* mj_model_{
nullptr };
408 mjData* mj_data_{
nullptr };
415 mjData* snapshot_write_{
nullptr };
416 mjData* snapshot_read_{
nullptr };
417 bool snapshot_ready_{
false };
420 std::vector<mjtNum> ctrl_staged_;
421 std::vector<mjtNum> qfrc_applied_staged_;
425 bool control_inputs_staged_{
false };
429 std::vector<mjtNum> xfrc_plugin_desired_;
430 std::vector<mjtNum> xfrc_viewer_capture_;
431 std::vector<mjtNum> xfrc_last_written_;
435 std::mutex data_exchange_mutex_;
440 std::atomic<bool> snapshot_refresh_requested_{
true };
447 std::mutex control_staging_mutex_;
453 ControlState control_state_;
454 std::mutex control_state_mutex_;
463 double sim_speed_factor_{ -1.0 };
466 bool headless_{
false };
469 std::unique_ptr<mujoco::Simulate> sim_;
472 std::thread physics_thread_;
473 std::thread ui_thread_;
476 std::shared_ptr<rclcpp::Publisher<rosgraph_msgs::msg::Clock>> clock_publisher_;
484 std::recursive_mutex* sim_mutex_{
nullptr };
487 rclcpp::CallbackGroup::SharedPtr reset_world_cb_group_;
488 rclcpp::Service<mujoco_ros2_control_msgs::srv::ResetWorld>::SharedPtr reset_world_service_;
491 rclcpp::CallbackGroup::SharedPtr set_pause_cb_group_;
492 rclcpp::Service<mujoco_ros2_control_msgs::srv::SetPause>::SharedPtr set_pause_service_;
495 rclcpp::CallbackGroup::SharedPtr step_simulation_cb_group_;
496 rclcpp::Service<mujoco_ros2_control_msgs::srv::StepSimulation>::SharedPtr step_simulation_service_;
499 rclcpp::CallbackGroup::SharedPtr set_free_joint_state_cb_group_;
500 rclcpp::Service<mujoco_ros2_control_msgs::srv::SetFreeJointState>::SharedPtr set_free_joint_state_service_;
503 std::atomic<uint32_t> pending_steps_{ 0 };
504 std::atomic<bool> step_diverged_{
false };
505 std::atomic<bool> steps_interrupted_{
false };
506 std::atomic<bool> keyboard_step_requested_{
false };
507 std::atomic<uint64_t> step_count_{ 0 };
508 std::mutex steps_cv_mutex_;
509 std::condition_variable steps_cv_;
512 std::vector<mjtNum> initial_qpos_;
513 std::vector<mjtNum> initial_qvel_;
514 std::vector<mjtNum> initial_ctrl_;