44 if (!sdf->HasElement(
"robotNamespace"))
46 ROS_INFO_NAMED(
"planar_move",
"PlanarMovePlugin missing <robotNamespace>, " 52 sdf->GetElement(
"robotNamespace")->Get<std::string>();
56 if (!sdf->HasElement(
"commandTopic"))
58 ROS_WARN_NAMED(
"planar_move",
"PlanarMovePlugin (ns = %s) missing <commandTopic>, " 64 command_topic_ = sdf->GetElement(
"commandTopic")->Get<std::string>();
68 if (!sdf->HasElement(
"odometryTopic"))
70 ROS_WARN_NAMED(
"planar_move",
"PlanarMovePlugin (ns = %s) missing <odometryTopic>, " 76 odometry_topic_ = sdf->GetElement(
"odometryTopic")->Get<std::string>();
80 if (!sdf->HasElement(
"odometryFrame"))
82 ROS_WARN_NAMED(
"planar_move",
"PlanarMovePlugin (ns = %s) missing <odometryFrame>, " 88 odometry_frame_ = sdf->GetElement(
"odometryFrame")->Get<std::string>();
92 if (!sdf->HasElement(
"robotBaseFrame"))
94 ROS_WARN_NAMED(
"planar_move",
"PlanarMovePlugin (ns = %s) missing <robotBaseFrame>, " 100 robot_base_frame_ = sdf->GetElement(
"robotBaseFrame")->Get<std::string>();
104 if (!sdf->HasElement(
"odometryRate"))
106 ROS_WARN_NAMED(
"planar_move",
"PlanarMovePlugin (ns = %s) missing <odometryRate>, " 112 odometry_rate_ = sdf->GetElement(
"odometryRate")->Get<
double>();
115 #if GAZEBO_MAJOR_VERSION >= 8 118 last_odom_publish_time_ =
parent_->GetWorld()->GetSimTime();
120 #if GAZEBO_MAJOR_VERSION >= 8 134 <<
"). A ROS node for Gazebo has not been initialized, " 135 <<
"unable to load plugin. Load the Gazebo system plugin " 136 <<
"'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
149 ros::SubscribeOptions::create<geometry_msgs::Twist>(
command_topic_, 1,
162 event::Events::ConnectWorldUpdateBegin(
170 boost::mutex::scoped_lock scoped_lock(
lock);
171 #if GAZEBO_MAJOR_VERSION >= 8 172 ignition::math::Pose3d pose =
parent_->WorldPose();
174 ignition::math::Pose3d pose =
parent_->GetWorldPose().Ign();
176 float yaw = pose.Rot().Yaw();
177 parent_->SetLinearVel(ignition::math::Vector3d(
178 x_ * cosf(yaw) -
y_ * sinf(yaw),
179 y_ * cosf(yaw) +
x_ * sinf(yaw),
181 parent_->SetAngularVel(ignition::math::Vector3d(0, 0,
rot_));
183 #if GAZEBO_MAJOR_VERSION >= 8 184 common::Time current_time =
parent_->GetWorld()->SimTime();
186 common::Time current_time =
parent_->GetWorld()->GetSimTime();
188 double seconds_since_last_update =
207 const geometry_msgs::Twist::ConstPtr& cmd_msg)
209 boost::mutex::scoped_lock scoped_lock(
lock);
210 x_ = cmd_msg->linear.x;
211 y_ = cmd_msg->linear.y;
212 rot_ = cmd_msg->angular.z;
217 static const double timeout = 0.01;
229 std::string base_footprint_frame =
233 #if GAZEBO_MAJOR_VERSION >= 8 234 ignition::math::Pose3d pose = this->
parent_->WorldPose();
236 ignition::math::Pose3d pose = this->
parent_->GetWorldPose().Ign();
239 tf::Quaternion qt(pose.Rot().X(), pose.Rot().Y(), pose.Rot().Z(), pose.Rot().W());
240 tf::Vector3 vt(pose.Pos().X(), pose.Pos().Y(), pose.Pos().Z());
245 base_footprint_frame));
248 odom_.pose.pose.position.x = pose.Pos().X();
249 odom_.pose.pose.position.y = pose.Pos().Y();
251 odom_.pose.pose.orientation.x = pose.Rot().X();
252 odom_.pose.pose.orientation.y = pose.Rot().Y();
253 odom_.pose.pose.orientation.z = pose.Rot().Z();
254 odom_.pose.pose.orientation.w = pose.Rot().W();
255 odom_.pose.covariance[0] = 0.00001;
256 odom_.pose.covariance[7] = 0.00001;
257 odom_.pose.covariance[14] = 1000000000000.0;
258 odom_.pose.covariance[21] = 1000000000000.0;
259 odom_.pose.covariance[28] = 1000000000000.0;
260 odom_.pose.covariance[35] = 0.001;
263 ignition::math::Vector3d linear;
266 if (
rot_ > M_PI / step_time)
274 float current_yaw = pose.Rot().Yaw();
275 while (current_yaw < last_yaw - M_PI) current_yaw += 2 * M_PI;
276 while (current_yaw > last_yaw + M_PI) current_yaw -= 2 * M_PI;
277 float angular_diff = current_yaw - last_yaw;
278 odom_.twist.twist.angular.z = angular_diff / step_time;
283 float yaw = pose.Rot().Yaw();
284 odom_.twist.twist.linear.x = cosf(yaw) * linear.X() + sinf(yaw) * linear.Y();
285 odom_.twist.twist.linear.y = cosf(yaw) * linear.Y() - sinf(yaw) * linear.X();
287 odom_.header.stamp = current_time;
288 odom_.header.frame_id = odom_frame;
289 odom_.child_frame_id = base_footprint_frame;
boost::shared_ptr< ros::NodeHandle > rosnode_
ignition::math::Pose3d last_odom_pose_
#define ROS_INFO_NAMED(name,...)
void publish(const boost::shared_ptr< M > &message) const
std::string getPrefixParam(ros::NodeHandle &nh)
#define ROS_WARN_NAMED(name,...)
void publishOdometry(double step_time)
ROSCPP_DECL bool isInitialized()
ros::CallbackQueue queue_
boost::thread callback_queue_thread_
virtual void UpdateChild()
std::string resolve(const std::string &prefix, const std::string &frame_name)
physics::ModelPtr parent_
#define ROS_DEBUG_NAMED(name,...)
GZ_REGISTER_MODEL_PLUGIN(GazeboRosF3D)
void Load(physics::ModelPtr parent, sdf::ElementPtr sdf)
void cmdVelCallback(const geometry_msgs::Twist::ConstPtr &cmd_msg)
#define ROS_FATAL_STREAM_NAMED(name, args)
event::ConnectionPtr update_connection_
std::string odometry_frame_
std::string robot_base_frame_
common::Time last_odom_publish_time_
ros::Publisher odometry_pub_
boost::shared_ptr< tf::TransformBroadcaster > transform_broadcaster_
std::string odometry_topic_
std::string command_topic_
boost::shared_ptr< void > VoidPtr
std::string robot_namespace_