45 if (!sdf->HasElement(
"robotNamespace"))
47 ROS_INFO(
"ForceBasedPlugin missing <robotNamespace>, " 53 sdf->GetElement(
"robotNamespace")->Get<std::string>();
57 if (!sdf->HasElement(
"commandTopic"))
59 ROS_WARN(
"ForceBasedPlugin (ns = %s) missing <commandTopic>, " 65 command_topic_ = sdf->GetElement(
"commandTopic")->Get<std::string>();
69 if (!sdf->HasElement(
"odometryTopic"))
71 ROS_WARN(
"ForceBasedPlugin (ns = %s) missing <odometryTopic>, " 77 odometry_topic_ = sdf->GetElement(
"odometryTopic")->Get<std::string>();
81 if (!sdf->HasElement(
"odometryFrame"))
83 ROS_WARN(
"ForceBasedPlugin (ns = %s) missing <odometryFrame>, " 89 odometry_frame_ = sdf->GetElement(
"odometryFrame")->Get<std::string>();
97 if (sdf->HasElement(
"yaw_velocity_p_gain"))
98 (sdf->GetElement(
"yaw_velocity_p_gain")->GetValue()->Get(torque_yaw_velocity_p_gain_));
100 if (sdf->HasElement(
"x_velocity_p_gain"))
103 if (sdf->HasElement(
"y_velocity_p_gain"))
106 ROS_INFO_STREAM(
"ForceBasedMove using gains: yaw: " << torque_yaw_velocity_p_gain_ <<
111 if (!sdf->HasElement(
"robotBaseFrame"))
113 ROS_WARN(
"ForceBasedPlugin (ns = %s) missing <robotBaseFrame>, " 114 "defaults to \"%s\"",
127 if (!sdf->HasElement(
"odometryRate"))
129 ROS_WARN(
"ForceBasedPlugin (ns = %s) missing <odometryRate>, " 139 if (!sdf->HasElement(
"cmdVelTimeOut"))
141 ROS_WARN(
"ForceBasedPlugin (ns = %s) missing <cmdVelTimeOut>, " 147 cmd_vel_time_out_ = sdf->GetElement(
"cmdVelTimeOut")->Get<
double>();
151 if (!sdf->HasElement(
"publishOdometryTf")) {
152 ROS_WARN(
"ForceBasedPlugin Plugin (ns = %s) missing <publishOdometryTf>, defaults to %s",
153 this->
robot_namespace_.c_str(), this->publish_odometry_tf_ ?
"true" :
"false");
155 this->publish_odometry_tf_ = sdf->GetElement(
"publishOdometryTf")->Get<
bool>();
171 <<
"). A ROS node for Gazebo has not been initialized, " 172 <<
"unable to load plugin. Load the Gazebo system plugin " 173 <<
"'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
183 if (publish_odometry_tf_)
188 ros::SubscribeOptions::create<geometry_msgs::Twist>(
command_topic_, 1,
201 event::Events::ConnectWorldUpdateBegin(
209 boost::mutex::scoped_lock scoped_lock(
lock);
210 math::Pose pose =
parent_->GetWorldPose();
218 math::Vector3 angular_vel =
parent_->GetWorldAngularVel();
219 link_->AddTorque(math::Vector3(0.0,
225 math::Vector3 linear_vel =
parent_->GetRelativeLinearVel();
238 common::Time current_time =
parent_->GetWorld()->GetSimTime();
239 double seconds_since_last_update =
258 const geometry_msgs::Twist::ConstPtr& cmd_msg)
260 boost::mutex::scoped_lock scoped_lock(
lock);
261 x_ = cmd_msg->linear.x;
262 y_ = cmd_msg->linear.y;
263 rot_ = cmd_msg->angular.z;
269 static const double timeout = 0.01;
281 std::string base_footprint_frame =
284 math::Vector3 angular_vel =
parent_->GetRelativeAngularVel();
285 math::Vector3 linear_vel =
parent_->GetRelativeLinearVel();
290 odom_.twist.twist.angular.z = angular_vel.z;
291 odom_.twist.twist.linear.x = linear_vel.x;
293 odom_.header.stamp = current_time;
294 odom_.header.frame_id = odom_frame;
295 odom_.child_frame_id = base_footprint_frame;
300 base_footprint_frame));
303 odom_.pose.covariance[0] = 0.001;
304 odom_.pose.covariance[7] = 0.001;
305 odom_.pose.covariance[14] = 1000000000000.0;
306 odom_.pose.covariance[21] = 1000000000000.0;
307 odom_.pose.covariance[28] = 1000000000000.0;
309 if (std::abs(angular_vel.z) < 0.0001) {
310 odom_.pose.covariance[35] = 0.01;
312 odom_.pose.covariance[35] = 100.0;
315 odom_.twist.covariance[0] = 0.001;
316 odom_.twist.covariance[7] = 0.001;
317 odom_.twist.covariance[14] = 0.001;
318 odom_.twist.covariance[21] = 1000000000000.0;
319 odom_.twist.covariance[28] = 1000000000000.0;
321 if (std::abs(angular_vel.z) < 0.0001) {
322 odom_.twist.covariance[35] = 0.01;
324 odom_.twist.covariance[35] = 100.0;
339 if (std::abs(angular_vel) < 0.0001) {
344 double distChange = linear_vel_x * timeSeconds;
345 double angleChange = angular_vel * timeSeconds;
347 double arcRadius = distChange / angleChange;
350 arcRadius - std::cos(angleChange) * arcRadius,
virtual void UpdateChild()
common::Time last_cmd_vel_time_
boost::shared_ptr< ros::NodeHandle > rosnode_
std::string command_topic_
void publish(const boost::shared_ptr< M > &message) const
double force_y_velocity_p_gain_
std::string getPrefixParam(ros::NodeHandle &nh)
physics::LinkPtr link_
A pointer to the Link, where force is applied.
ROSCPP_DECL bool isInitialized()
ros::Publisher odometry_pub_
tf::Transform getTransformForMotion(double linear_vel_x, double angular_vel, double timeSeconds) const
physics::ModelPtr parent_
void publishOdometry(double step_time)
std::string resolve(const std::string &prefix, const std::string &frame_name)
ros::CallbackQueue queue_
std::string robot_namespace_
math::Pose last_odom_pose_
static Quaternion createQuaternionFromYaw(double yaw)
#define ROS_FATAL_STREAM(args)
std::string odometry_topic_
tf::Transform odom_transform_
std::string odometry_frame_
std::string robot_base_frame_
void Load(physics::ModelPtr parent, sdf::ElementPtr sdf)
boost::shared_ptr< tf::TransformBroadcaster > transform_broadcaster_
common::Time last_odom_publish_time_
event::ConnectionPtr update_connection_
bool publish_odometry_tf_
static void poseTFToMsg(const Pose &bt, geometry_msgs::Pose &msg)
#define ROS_INFO_STREAM(args)
~GazeboRosForceBasedMove()
double force_x_velocity_p_gain_
void cmdVelCallback(const geometry_msgs::Twist::ConstPtr &cmd_msg)
boost::thread callback_queue_thread_
boost::shared_ptr< void > VoidPtr
double torque_yaw_velocity_p_gain_
GazeboRosForceBasedMove()