-
Notifications
You must be signed in to change notification settings - Fork 42
jazzy-dev #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
LitheshSari
wants to merge
11
commits into
moveit:main
Choose a base branch
from
LitheshSari:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+434
−225
Open
jazzy-dev #20
Changes from 7 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
b179442
[BUG] update for 22.04 jazzy
LitheshSari 3936178
[BUG] update for 22.04 jazzy
LitheshSari 786c817
[BUG] modify the demo launch.py
LitheshSari 2d498d0
Merge remote-tracking branch 'origin/main'
LitheshSari 0eb9b9e
[Feature] IMU support
LitheshSari 3c6abbd
[Format]: suggestions
LitheshSari d6334d2
[Feature]: about scope_exit and RAII
LitheshSari e030760
[Feature]: rewrite sensors
LitheshSari 3b62b1b
[Bugs]: fix the error
LitheshSari 1123e42
[Merge]: merge CMakeLists.txt from #24
LitheshSari b7c05e1
[Bug]: modify the initializer of MujocoRos2Control
LitheshSari File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,9 @@ build/ | |
| install/ | ||
| log/ | ||
|
|
||
| # clion | ||
| **/cmake-build-debug | ||
| **/.idea | ||
| # vscode | ||
| **/.vscode | ||
| **/.devcontainer | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,100 +6,121 @@ | |
|
|
||
| namespace mujoco_ros2_control | ||
| { | ||
| MujocoRos2Control::MujocoRos2Control(rclcpp::Node::SharedPtr & node, mjModel* mujoco_model, mjData* mujoco_data) | ||
| : node_(node), mj_model_(mujoco_model), mj_data_(mujoco_data), logger_(rclcpp::get_logger(node_->get_name() + std::string(".mujoco_ros2_control"))), | ||
| control_period_(rclcpp::Duration(1, 0)), last_update_sim_time_ros_(0, 0, RCL_ROS_TIME) | ||
| { | ||
| } | ||
|
|
||
| MujocoRos2Control::~MujocoRos2Control() | ||
| { | ||
| stop_cm_thread_ = true; | ||
| cm_executor_->remove_node(controller_manager_); | ||
| cm_executor_->cancel(); | ||
| cm_thread_.join(); | ||
| } | ||
|
|
||
| void MujocoRos2Control::init() | ||
| { | ||
| clock_publisher_ = node_->create_publisher<rosgraph_msgs::msg::Clock>("/clock", 10); | ||
| // Read urdf from ros parameter server then | ||
| // setup actuators and mechanism control node. | ||
| std::string urdf_string; | ||
| std::vector<hardware_interface::HardwareInfo> control_hardware_info; | ||
| try | ||
| class MJResourceManager : public hardware_interface::ResourceManager{ | ||
| public: | ||
| MJResourceManager(rclcpp::Node::SharedPtr& node, mjModel*& mj_model, mjData*& mj_data) | ||
LitheshSari marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| : hardware_interface::ResourceManager(node->get_node_clock_interface(), node->get_node_logging_interface()), | ||
| mj_system_loader_("mujoco_ros2_control", "mujoco_ros2_control::MujocoSystemInterface"), | ||
| logger_(node->get_logger().get_child("MJResourceManager")), mj_model_(mj_model), mj_data_(mj_data) | ||
| { | ||
| urdf_string = node_->get_parameter("robot_description").as_string(); | ||
| control_hardware_info = hardware_interface::parse_control_resources_from_urdf(urdf_string); | ||
| } | ||
| catch (const std::runtime_error & ex) | ||
| { | ||
| RCLCPP_ERROR_STREAM(logger_, "Error parsing URDF : " << ex.what()); | ||
| return; | ||
| } | ||
|
|
||
| try | ||
| { | ||
| robot_hw_sim_loader_.reset( | ||
| new pluginlib::ClassLoader<MujocoSystemInterface>( | ||
| "mujoco_ros2_control", | ||
| "mujoco_ros2_control::MujocoSystemInterface")); | ||
| } | ||
| catch (pluginlib::LibraryLoadException & ex) | ||
| { | ||
| RCLCPP_ERROR_STREAM(logger_, "Failed to create hardware interface loader: " << ex.what()); | ||
| return; | ||
| node_ = node; | ||
| } | ||
|
|
||
| std::unique_ptr<hardware_interface::ResourceManager> resource_manager = | ||
| std::make_unique<hardware_interface::ResourceManager>(); | ||
| MJResourceManager(const MJResourceManager&) = delete; | ||
|
|
||
| try | ||
| { | ||
| resource_manager->load_urdf(urdf_string, false, false); | ||
| } | ||
| catch (...) | ||
| ~MJResourceManager() override | ||
| { | ||
| RCLCPP_ERROR(logger_, "Error while initializing URDF!"); | ||
| // release resources when exit or failure | ||
| mj_deleteModel(mj_model_); | ||
| mj_deleteData(mj_data_); | ||
LitheshSari marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| for (const auto& hardware : control_hardware_info) | ||
| /// Called from ControllerManager when {robot_description} is initialized from callback. | ||
| /** | ||
| * Override from hardware_interface::ResourceManager | ||
| * \param[in] urdf string containing the URDF. | ||
| * \param[in] update_rate Update rate of the controller manager to calculate calling frequency | ||
| * of async components. | ||
| */ | ||
| bool load_and_initialize_components(const std::string& urdf, unsigned int update_rate) override | ||
| { | ||
| std::string robot_hw_sim_type_str_ = hardware.hardware_class_type; | ||
| std::unique_ptr<MujocoSystemInterface> mujoco_system; | ||
| try | ||
| { | ||
| mujoco_system = std::unique_ptr<MujocoSystemInterface>( | ||
| robot_hw_sim_loader_->createUnmanagedInstance(robot_hw_sim_type_str_)); | ||
| components_are_loaded_and_initialized_ = true; | ||
|
|
||
| const auto hardware_info = hardware_interface::parse_control_resources_from_urdf(urdf); | ||
|
|
||
| // generate mj_data_ and mj_model_ for SystemInterface | ||
| auto model_path = node_->get_parameter("mujoco_model_path").as_string(); | ||
| // load and compile model | ||
| char error[1000] = "Could not load binary model"; | ||
| if (std::strlen(model_path.c_str())>4 && !std::strcmp(model_path.c_str()+std::strlen(model_path.c_str())-4, ".mjb")) { | ||
| mj_model_ = mj_loadModel(model_path.c_str(), 0); | ||
LitheshSari marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } else { | ||
| mj_model_ = mj_loadXML(model_path.c_str(), 0, error, 1000); | ||
| } | ||
| catch (pluginlib::PluginlibException & ex) | ||
| { | ||
| RCLCPP_ERROR_STREAM(logger_, "The plugin failed to load. Error: " << ex.what()); | ||
| continue; | ||
| if (!mj_model_) { | ||
| mju_error("Load model error: %s", error); | ||
| return !components_are_loaded_and_initialized_; | ||
| } | ||
| RCLCPP_INFO_STREAM(logger_, "Mujoco model has been successfully loaded !"); | ||
| mj_data_ = mj_makeData(mj_model_); | ||
|
|
||
| urdf::Model urdf_model; | ||
| urdf_model.initString(urdf_string); | ||
| if (!mujoco_system->init_sim(node_, mj_model_, mj_data_, urdf_model, hardware)) | ||
| for (const auto& individual_hardware_info : hardware_info) | ||
| { | ||
| RCLCPP_FATAL(logger_, "Could not initialize robot simulation interface"); | ||
| return; | ||
| std::string robot_hw_sim_type_str_ = individual_hardware_info.hardware_plugin_name; | ||
| RCLCPP_DEBUG(logger_, "Load hardware interface %s ...", robot_hw_sim_type_str_.c_str()); | ||
|
|
||
| // Load hardware | ||
| std::unique_ptr<MujocoSystemInterface> mjSimSystem; | ||
| std::scoped_lock guard(resource_interfaces_lock_, claimed_command_interfaces_lock_); | ||
| try | ||
| { | ||
| mjSimSystem = std::unique_ptr<MujocoSystemInterface>( | ||
| mj_system_loader_.createUnmanagedInstance(robot_hw_sim_type_str_)); | ||
| } catch (pluginlib::PluginlibException & ex) { | ||
| RCLCPP_ERROR_STREAM(logger_, "The plugin failed to load. Error: " << ex.what()); | ||
| continue; | ||
| } | ||
|
|
||
| // initialize simulation required resource from the hardware info. | ||
| urdf::Model urdf_model; | ||
| urdf_model.initString(urdf); | ||
| if(!mjSimSystem->init_sim(node_, mj_model_, mj_data_, urdf_model, individual_hardware_info)) | ||
| { | ||
| RCLCPP_FATAL(logger_, "Could not initialize robot simulation interface"); | ||
| components_are_loaded_and_initialized_ = false; | ||
| break; | ||
| } | ||
| RCLCPP_DEBUG(logger_, "Initialized hardware interface %s !", robot_hw_sim_type_str_.c_str()); | ||
| import_component(std::move(mjSimSystem), individual_hardware_info); | ||
| } | ||
| return components_are_loaded_and_initialized_; | ||
| } | ||
|
|
||
| resource_manager->import_component(std::move(mujoco_system), hardware); | ||
| private: | ||
| std::shared_ptr<rclcpp::Node> node_; | ||
| pluginlib::ClassLoader<MujocoSystemInterface> mj_system_loader_; | ||
| rclcpp::Logger logger_; | ||
| mjModel*& mj_model_; | ||
| mjData*& mj_data_; | ||
| }; | ||
|
|
||
| MujocoRos2Control::MujocoRos2Control(const rclcpp::Node::SharedPtr & node, const rclcpp::NodeOptions & cm_node_option) | ||
| : node_(node), cm_node_option_(cm_node_option), | ||
| logger_(rclcpp::get_logger(node_->get_name() + std::string(".mujoco_ros2_control"))), | ||
| control_period_(rclcpp::Duration(1, 0)), last_update_sim_time_ros_(0, 0, RCL_ROS_TIME) | ||
| { | ||
| } | ||
|
|
||
| rclcpp_lifecycle::State state( | ||
| lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE, | ||
| hardware_interface::lifecycle_state_names::ACTIVE); | ||
| resource_manager->set_component_state(hardware.name, state); | ||
| } | ||
| MujocoRos2Control::~MujocoRos2Control() | ||
| { | ||
| stop_cm_thread_ = true; | ||
| cm_executor_->remove_node(controller_manager_); | ||
| cm_executor_->cancel(); | ||
|
Comment on lines
+116
to
+118
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure whether we need this variable. with |
||
| cm_thread_.join(); | ||
| } | ||
|
|
||
| void MujocoRos2Control::init() | ||
| { | ||
| clock_publisher_ = node_->create_publisher<rosgraph_msgs::msg::Clock>("/clock", 10); | ||
| std::unique_ptr<hardware_interface::ResourceManager> resource_manager = | ||
| std::make_unique<mujoco_ros2_control::MJResourceManager>(node_, mj_model_, mj_data_); | ||
|
|
||
| // Create the controller manager | ||
| RCLCPP_INFO(logger_, "Loading controller_manager"); | ||
| cm_executor_ = std::make_shared<rclcpp::executors::MultiThreadedExecutor>(); | ||
| controller_manager_.reset(new controller_manager::ControllerManager( | ||
| std::move(resource_manager), cm_executor_, | ||
| "controller_manager", node_->get_namespace())); | ||
| "controller_manager", node_->get_namespace(), cm_node_option_)); | ||
|
|
||
| cm_executor_->add_node(controller_manager_); | ||
|
|
||
|
|
@@ -113,27 +134,32 @@ void MujocoRos2Control::init() | |
| std::chrono::duration_cast<std::chrono::nanoseconds>( | ||
| std::chrono::duration<double>(1.0 / static_cast<double>(update_rate)))); | ||
|
|
||
| // Force setting of use_sime_time parameter | ||
| // Force setting of use_sim_time parameter | ||
| controller_manager_->set_parameter(rclcpp::Parameter("use_sim_time", rclcpp::ParameterValue(true))); | ||
|
|
||
| stop_cm_thread_ = false; | ||
| auto spin = [this]() | ||
| { | ||
| while (rclcpp::ok() && !stop_cm_thread_) { | ||
| cm_executor_->spin_once(); | ||
| } | ||
| }; | ||
| { | ||
| while (rclcpp::ok() && !stop_cm_thread_) { | ||
| cm_executor_->spin_once(); | ||
| } | ||
| }; | ||
| cm_thread_ = std::thread(spin); | ||
|
|
||
| // Waiting RM to be initialized through topic robot_description | ||
| // mj_data_ and mj_model_ will be allocated in the RM simultaneously | ||
| while(!controller_manager_->is_resource_manager_initialized()) | ||
| { | ||
| RCLCPP_WARN(logger_, "Waiting RM to load and initialize hardware..."); | ||
| std::this_thread::sleep_for(std::chrono::microseconds (2000000)); | ||
| } | ||
| } | ||
|
|
||
| void MujocoRos2Control::update() | ||
| { | ||
| // Get the simulation time and period | ||
| auto sim_time = mj_data_->time; | ||
| int sim_time_sec = static_cast<int>(sim_time); | ||
| int sim_time_nanosec = static_cast<int>((sim_time - sim_time_sec)*1000000000); | ||
| std::chrono::duration<double> sim_time(static_cast<double>(mj_data_->time)); | ||
|
|
||
| rclcpp::Time sim_time_ros(sim_time_sec, sim_time_nanosec, RCL_ROS_TIME); | ||
| rclcpp::Time sim_time_ros(std::chrono::duration_cast<std::chrono::nanoseconds>(sim_time).count(), RCL_ROS_TIME); | ||
| rclcpp::Duration sim_period = sim_time_ros - last_update_sim_time_ros_; | ||
|
|
||
| publish_sim_time(sim_time_ros); | ||
|
|
@@ -145,13 +171,16 @@ void MujocoRos2Control::update() | |
| controller_manager_->update(sim_time_ros, sim_period); | ||
| last_update_sim_time_ros_ = sim_time_ros; | ||
| } | ||
|
|
||
| // use same time as for read and update call - this is how it is done in ros2_control_node | ||
| controller_manager_->write(sim_time_ros, sim_period); | ||
|
|
||
| mj_step2(mj_model_, mj_data_); | ||
| } | ||
|
|
||
| mjData* MujocoRos2Control::getMjData() {return mj_data_;} | ||
|
|
||
| mjModel* MujocoRos2Control::getMjModel() {return mj_model_;} | ||
|
|
||
| void MujocoRos2Control::publish_sim_time(rclcpp::Time sim_time) | ||
| { | ||
| // TODO | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.