145 bool initialize(rclcpp::Node::SharedPtr node,
const std::string& model_path,
const std::string& mujoco_model_topic,
146 double sim_speed_factor,
bool headless);
225 bool set_free_joint_states(
const std::vector<mujoco_ros2_control_msgs::msg::FreeJointState>& free_joints,
226 std::string& error_message);
281 std::vector<mjtNum> qpos;
282 std::vector<mjtNum> qvel;
283 std::vector<mjtNum> act;
284 std::vector<mjtNum> qfrc_actuator;
285 std::vector<mjtNum> sensordata;
286 std::vector<mjtNum> ctrl;
314 RCLCPP_WARN_EXPRESSION(logger_, sim_mutex_ ==
nullptr,
"Sim recursive mutex is still nullptr");
325 return step_count_.load();
334 void apply_staged_control_inputs();
342 void publish_control_state();
351 void refresh_data_snapshot();
361 void publish_clock();
366 void update_sim_display();
378 void reset_world_state(
bool fill_initial_state,
const mujoco_ros2_control_msgs::msg::SimulationState& state_overrides);
387 int frame_body_id(
const std::string& frame_id)
const;
395 bool validate_frame_id(
const std::string& frame_id,
const std::string& field_label, std::string& error_message)
const;
400 int find_free_joint_id(
int body_id)
const;
410 bool validate_free_joint_states(
const std::vector<mujoco_ros2_control_msgs::msg::FreeJointState>& free_joints,
411 std::string& error_message);
421 void apply_free_joint_states(
const std::vector<mujoco_ros2_control_msgs::msg::FreeJointState>& free_joints);
433 bool validate_joint_state_overrides(
const sensor_msgs::msg::JointState& joint_state, std::string& error_message);
441 void apply_joint_state_overrides(
const sensor_msgs::msg::JointState& joint_state);
444 void reset_world_callback(
const std::shared_ptr<mujoco_ros2_control_msgs::srv::ResetWorld::Request> request,
445 std::shared_ptr<mujoco_ros2_control_msgs::srv::ResetWorld::Response> response);
446 void set_pause_callback(
const std::shared_ptr<mujoco_ros2_control_msgs::srv::SetPause::Request> request,
447 std::shared_ptr<mujoco_ros2_control_msgs::srv::SetPause::Response> response);
448 void step_simulation_callback(
const std::shared_ptr<mujoco_ros2_control_msgs::srv::StepSimulation::Request> request,
449 std::shared_ptr<mujoco_ros2_control_msgs::srv::StepSimulation::Response> response);
451 set_free_joint_state_callback(
const std::shared_ptr<mujoco_ros2_control_msgs::srv::SetFreeJointState::Request> request,
452 std::shared_ptr<mujoco_ros2_control_msgs::srv::SetFreeJointState::Response> response);
454 rclcpp::Logger get_logger()
const
460 rclcpp::Logger logger_ = rclcpp::get_logger(
"MujocoSimulation");
463 rclcpp::Node::SharedPtr node_;
466 std::string model_path_;
467 std::string mujoco_model_topic_;
471 mjModel* mj_model_{
nullptr };
475 mjData* mj_data_{
nullptr };
482 mjData* snapshot_write_{
nullptr };
483 mjData* snapshot_read_{
nullptr };
484 bool snapshot_ready_{
false };
487 std::vector<mjtNum> ctrl_staged_;
488 std::vector<mjtNum> qfrc_applied_staged_;
492 bool control_inputs_staged_{
false };
496 std::mutex data_exchange_mutex_;
501 std::atomic<bool> snapshot_refresh_requested_{
true };
508 std::mutex control_staging_mutex_;
514 ControlState control_state_;
515 std::mutex control_state_mutex_;
524 double sim_speed_factor_{ -1.0 };
527 bool headless_{
false };
530 std::unique_ptr<mujoco::Simulate> sim_;
533 std::thread physics_thread_;
534 std::thread ui_thread_;
537 std::shared_ptr<rclcpp::Publisher<rosgraph_msgs::msg::Clock>> clock_publisher_;
545 std::recursive_mutex* sim_mutex_{
nullptr };
548 rclcpp::CallbackGroup::SharedPtr reset_world_cb_group_;
549 rclcpp::Service<mujoco_ros2_control_msgs::srv::ResetWorld>::SharedPtr reset_world_service_;
552 rclcpp::CallbackGroup::SharedPtr set_pause_cb_group_;
553 rclcpp::Service<mujoco_ros2_control_msgs::srv::SetPause>::SharedPtr set_pause_service_;
556 rclcpp::CallbackGroup::SharedPtr step_simulation_cb_group_;
557 rclcpp::Service<mujoco_ros2_control_msgs::srv::StepSimulation>::SharedPtr step_simulation_service_;
560 rclcpp::CallbackGroup::SharedPtr set_free_joint_state_cb_group_;
561 rclcpp::Service<mujoco_ros2_control_msgs::srv::SetFreeJointState>::SharedPtr set_free_joint_state_service_;
564 std::atomic<uint32_t> pending_steps_{ 0 };
565 std::atomic<bool> step_diverged_{
false };
566 std::atomic<bool> steps_interrupted_{
false };
567 std::atomic<bool> keyboard_step_requested_{
false };
568 std::atomic<uint64_t> step_count_{ 0 };
569 std::mutex steps_cv_mutex_;
570 std::condition_variable steps_cv_;
573 std::vector<mjtNum> initial_qpos_;
574 std::vector<mjtNum> initial_qvel_;
575 std::vector<mjtNum> initial_ctrl_;