From 0ea51140b68ae8f78963f185c5646ed7881631bc Mon Sep 17 00:00:00 2001 From: Alex Fernandes Neves Date: Wed, 14 Aug 2019 16:48:19 -0300 Subject: [PATCH 1/5] Adding option to select the frame where the force will be applied A new parameter was added on the plugin with the options 'world' and 'link' frame. The default value is 'world'. Internally the AddRelativeForce() and torque functions are used instead of the AddForce() when the body option is selected. --- .../gazebo_plugins/gazebo_ros_force.hpp | 6 +++++ gazebo_plugins/src/gazebo_ros_force.cpp | 27 ++++++++++++++++++- .../test/worlds/gazebo_ros_force.world | 5 ++-- .../worlds/gazebo_ros_force_demo.world | 6 +++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/gazebo_plugins/include/gazebo_plugins/gazebo_ros_force.hpp b/gazebo_plugins/include/gazebo_plugins/gazebo_ros_force.hpp index ae77e5cd6..27290dc4c 100644 --- a/gazebo_plugins/include/gazebo_plugins/gazebo_ros_force.hpp +++ b/gazebo_plugins/include/gazebo_plugins/gazebo_ros_force.hpp @@ -46,6 +46,9 @@ class GazeboRosForcePrivate; link + + link + \endcode */ @@ -66,6 +69,9 @@ class GazeboRosForce : public gazebo::ModelPlugin /// Optional callback to be called at every simulation iteration. virtual void OnUpdate(); + /// Optional callback to be called at every simulation iteration when the force is applied on the body frame. + virtual void OnUpdateRelative(); + private: /// Callback when a ROS Wrench message is received /// \param[in] msg The Incoming ROS message representing the new force to diff --git a/gazebo_plugins/src/gazebo_ros_force.cpp b/gazebo_plugins/src/gazebo_ros_force.cpp index 3abfe9d0e..21e82b341 100644 --- a/gazebo_plugins/src/gazebo_ros_force.cpp +++ b/gazebo_plugins/src/gazebo_ros_force.cpp @@ -72,6 +72,24 @@ void GazeboRosForce::Load(gazebo::physics::ModelPtr model, sdf::ElementPtr sdf) return; } + // Force frame + bool force_on_world_frame; + if (!sdf->HasElement("force_frame")) { + RCLCPP_WARN(logger, "Force plugin missing wasn't set, therefore it's been set as 'world'. The other option is 'link'."); + force_on_world_frame = true; + } + else { + auto force_frame = sdf->GetElement("force_frame")->Get(); + if (force_frame == "world") + force_on_world_frame = true; + else if (force_frame == "link") + force_on_world_frame = false; + else { + RCLCPP_ERROR(logger, "Force plugin can only be 'world' or 'link'"); + return; + } + } + // Subscribe to wrench messages impl_->ros_node_ = gazebo_ros::Node::Get(sdf); @@ -81,7 +99,8 @@ void GazeboRosForce::Load(gazebo::physics::ModelPtr model, sdf::ElementPtr sdf) // Callback on every iteration impl_->update_connection_ = gazebo::event::Events::ConnectWorldUpdateBegin( - std::bind(&GazeboRosForce::OnUpdate, this)); + force_on_world_frame ? std::bind(&GazeboRosForce::OnUpdate, this) + : std::bind(&GazeboRosForce::OnUpdateRelative, this)); } void GazeboRosForce::OnRosWrenchMsg(const geometry_msgs::msg::Wrench::SharedPtr msg) @@ -100,5 +119,11 @@ void GazeboRosForce::OnUpdate() impl_->link_->AddTorque(gazebo_ros::Convert(impl_->wrench_msg_.torque)); } +void GazeboRosForce::OnUpdateRelative() +{ + impl_->link_->AddRelativeForce(gazebo_ros::Convert(impl_->wrench_msg_.force)); + impl_->link_->AddRelativeTorque(gazebo_ros::Convert(impl_->wrench_msg_.torque)); +} + GZ_REGISTER_MODEL_PLUGIN(GazeboRosForce) } // namespace gazebo_plugins diff --git a/gazebo_plugins/test/worlds/gazebo_ros_force.world b/gazebo_plugins/test/worlds/gazebo_ros_force.world index 74ba8d8fc..03a53e0b4 100644 --- a/gazebo_plugins/test/worlds/gazebo_ros_force.world +++ b/gazebo_plugins/test/worlds/gazebo_ros_force.world @@ -9,7 +9,7 @@ 0 0 0.5 0 0 0 - + @@ -30,7 +30,8 @@ /test gazebo_ros_force:=force_test - link + box_link + world diff --git a/gazebo_plugins/worlds/gazebo_ros_force_demo.world b/gazebo_plugins/worlds/gazebo_ros_force_demo.world index ba09d7532..3c480ae15 100644 --- a/gazebo_plugins/worlds/gazebo_ros_force_demo.world +++ b/gazebo_plugins/worlds/gazebo_ros_force_demo.world @@ -2,6 +2,11 @@ link - + link diff --git a/gazebo_plugins/src/gazebo_ros_force.cpp b/gazebo_plugins/src/gazebo_ros_force.cpp index 62e5dfb5d..09af745da 100644 --- a/gazebo_plugins/src/gazebo_ros_force.cpp +++ b/gazebo_plugins/src/gazebo_ros_force.cpp @@ -44,7 +44,7 @@ class GazeboRosForcePrivate // Pointer to the update event connection gazebo::event::ConnectionPtr update_connection_; - /// Indicates that the force should be applied on the world frame instead of the body frame + /// Indicates that the force should be applied on the world frame instead of the link frame bool force_on_world_frame_; }; @@ -77,7 +77,7 @@ void GazeboRosForce::Load(gazebo::physics::ModelPtr model, sdf::ElementPtr sdf) // Force frame if (!sdf->HasElement("force_frame")) { - RCLCPP_WARN(logger, "Force plugin missing wasn't set," + RCLCPP_INFO(logger, "Force plugin missing wasn't set," "therefore it's been set as 'world'. The other option is 'link'."); impl_->force_on_world_frame_ = true; } else { diff --git a/gazebo_plugins/worlds/gazebo_ros_force_demo.world b/gazebo_plugins/worlds/gazebo_ros_force_demo.world index a1d81c782..1fdc2d211 100644 --- a/gazebo_plugins/worlds/gazebo_ros_force_demo.world +++ b/gazebo_plugins/worlds/gazebo_ros_force_demo.world @@ -9,7 +9,11 @@ Try for example: - ros2 topic pub -1 /demo/force_demo geometry_msgs/Wrench "force: {x: 10.0}" + ros2 topic pub -1 /demo/world/force_demo geometry_msgs/Wrench "force: {x: 10.0}" + + and + + ros2 topic pub -1 /demo/link/force_demo geometry_msgs/Wrench "force: {x: 10.0}" --> @@ -19,8 +23,8 @@ model://sun - - 0 0 0.5 0 0 0 + + 0 3 0.5 0 0 1.57 @@ -39,12 +43,39 @@ - /demo + /demo/world gazebo_ros_force:=force_demo link world + + 0 -3 0.5 0 0 1.57 + + + + + 1 1 1 + + + + + + + 1 1 1 + + + + + + + /demo/link + gazebo_ros_force:=force_demo + + link + link + +