mobile_robot_simulator.cpp
Go to the documentation of this file.
1 #include "ros/ros.h"
2 
4 
6 {
7  nh_ptr = nh;
8  // get parameters
9  get_params();
10  odom_pub = nh_ptr->advertise<nav_msgs::Odometry>(odometry_topic,50); // odometry publisher
12 
13  // initialize timers
16  // initialize forst odom message
17  update_odom_from_vel(geometry_msgs::Twist(), ros::Duration(0.1));
18  odom.header.stamp = last_update;
20  // Initialize tf from map to odom
22  {
23  init_pose_sub = nh_ptr->subscribe("/initialpose",5,&MobileRobotSimulator::init_pose_callback,this); // initial pose callback
24  map_trans.frame_id_ = "/map";
26  map_trans.child_frame_id_ = "/odom";
28  }
29 
30  ROS_INFO("Initialized mobile robot simulator");
31 
32 }
33 
35 {
36  if (is_running) stop();
37 }
38 
40 {
41  nh_ptr->param<bool>("publish_map_transform", publish_map_transform , false);
42  nh_ptr->param<double>("publish_rate", publish_rate, 10.0);
43  nh_ptr->param<std::string>("velocity_topic", velocity_topic, "cmd_vel");
44  nh_ptr->param<std::string>("odometry_topic", odometry_topic, "odom");
45  nh_ptr->param<std::string>("base_link_frame", base_link_frame, "base_link");
46 }
47 
48 
50 {
52  loop_timer.start(); // should not be necessary
53  is_running = true;
54  ROS_INFO("Started mobile robot simulator update loop, listening on cmd_vel topic");
55 }
56 
58 {
59  loop_timer.stop();
60  is_running = false;
61  ROS_INFO("Stopped mobile robot simulator");
62 }
63 
65 {
66  last_update = event.current_real;
67  // If we didn't receive a message, send the old odometry info with a new timestamp
68  if (!message_received)
69  {
70  odom.header.stamp = last_update;
72  }
73  // publish odometry and tf
76  tf_broadcaster.sendTransform(odom_trans); // odom -> base_link_frame
77  message_received = false;
78  // should we publish the map transform?
79  if (!publish_map_transform) return;
81  tf_broadcaster.sendTransform(map_trans); // map -> odom
82 }
83 
84 void MobileRobotSimulator::update_odom_from_vel(geometry_msgs::Twist vel, ros::Duration time_diff)
85 {
86  ROS_DEBUG_STREAM("Velocity - x: " << vel.linear.x << " y: " << vel.linear.y << " th: " << vel.angular.z);
87  //compute odometry in a typical way given the velocities of the robot
88  double delta_x = (vel.linear.x * cos(th) - vel.linear.y * sin(th)) * time_diff.toSec();
89  double delta_y = (vel.linear.x * sin(th) + vel.linear.y * cos(th)) * time_diff.toSec();
90  double delta_th = vel.angular.z * time_diff.toSec();
91  ROS_DEBUG_STREAM("Delta - x: " << delta_x << " y: " << delta_y << " th: " << delta_th);
92 
93  // update odometry
94  odom.header.stamp = measure_time;
95  odom.header.frame_id = "odom";
96  odom.pose.pose.position.x += delta_x;
97  odom.pose.pose.position.y += delta_y;
98  // generate quaternion based on current yaw
99  th += delta_th;
100  odom.pose.pose.orientation = tf::createQuaternionMsgFromYaw(th);
101  // set velocity
102  odom.child_frame_id = base_link_frame;
103  odom.twist.twist = vel;
104  ROS_DEBUG_STREAM("Odometry - x: " << odom.pose.pose.position.x << " y: " << odom.pose.pose.position.y << " th: " << th);
105 }
106 
107 void MobileRobotSimulator::get_tf_from_odom(nav_msgs::Odometry odom)
108 {
109  geometry_msgs::TransformStamped odom_tmp;
110  // copy from odmoetry message
111  odom_tmp.header = odom.header;
112  odom_tmp.child_frame_id = odom.child_frame_id;
113  odom_tmp.transform.translation.x = odom.pose.pose.position.x;
114  odom_tmp.transform.translation.y = odom.pose.pose.position.y;
115  odom_tmp.transform.translation.z = 0.0;
116  odom_tmp.transform.rotation = odom.pose.pose.orientation;
117  // convert and update
119 }
120 
121 void MobileRobotSimulator::vel_callback(const geometry_msgs::Twist::ConstPtr& msg)
122 {
123  ROS_DEBUG("Received message on cmd_vel");
127  if (dt >= ros::Duration(0.5)) dt = ros::Duration(0.1);
128  message_received = true;
129  geometry_msgs::Twist vel = *msg;
130  update_odom_from_vel(vel,dt);
131 }
132 
133 void MobileRobotSimulator::init_pose_callback(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr& msg)
134 {
135  if (msg->header.frame_id != "map") {
136  ROS_ERROR("Initial pose not specified in map frame, ignoring");
137  return;
138  }
139  ROS_INFO("Received pose estimate of mobile base");
140 
141  // msg is map -> base_link_frame
142  tf::StampedTransform msg_t;
143  msg_t.setOrigin(tf::Vector3(msg->pose.pose.position.x,msg->pose.pose.position.y,msg->pose.pose.position.z));
144  msg_t.setRotation(tf::Quaternion(msg->pose.pose.orientation.x,msg->pose.pose.orientation.y,msg->pose.pose.orientation.z,msg->pose.pose.orientation.w));
145  ROS_DEBUG_STREAM("map -> base_link_frame - x: " << msg_t.getOrigin().getX() << " y: " << msg_t.getOrigin().getY());
146  // get odom -> base_link_frame
147  ROS_DEBUG_STREAM("odom -> base_link_frame - x: " << odom_trans.getOrigin().getX() << " y: " << odom_trans.getOrigin().getY());
148  // calculate map -> odom and save as stamped
149  tf::StampedTransform map_t = tf::StampedTransform(msg_t * odom_trans.inverse(), msg->header.stamp, "map", "odom");
150  ROS_DEBUG_STREAM("map -> odom - x: " << map_t.getOrigin().getX() << " y: " << map_t.getOrigin().getY());
151  map_trans = map_t;
152 }
153 
154 
155 
tf::StampedTransform::stamp_
ros::Time stamp_
tf::TransformBroadcaster::sendTransform
void sendTransform(const geometry_msgs::TransformStamped &transform)
MobileRobotSimulator::odom_pub
ros::Publisher odom_pub
Definition: mobile_robot_simulator.h:68
MobileRobotSimulator::nh_ptr
ros::NodeHandle * nh_ptr
Definition: mobile_robot_simulator.h:63
MobileRobotSimulator::is_running
bool is_running
Definition: mobile_robot_simulator.h:65
tf::StampedTransform::child_frame_id_
std::string child_frame_id_
ros.h
MobileRobotSimulator::last_vel
ros::Time last_vel
Definition: mobile_robot_simulator.h:59
MobileRobotSimulator::map_trans
tf::StampedTransform map_trans
Definition: mobile_robot_simulator.h:57
MobileRobotSimulator::tf_broadcaster
tf::TransformBroadcaster tf_broadcaster
Definition: mobile_robot_simulator.h:71
ros::Timer::stop
void stop()
MobileRobotSimulator::get_tf_from_odom
void get_tf_from_odom(nav_msgs::Odometry odom)
Definition: mobile_robot_simulator.cpp:107
MobileRobotSimulator::base_link_frame
std::string base_link_frame
Definition: mobile_robot_simulator.h:76
tf::StampedTransform
ROS_DEBUG_STREAM
#define ROS_DEBUG_STREAM(args)
mobile_robot_simulator.h
tf::StampedTransform::frame_id_
std::string frame_id_
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
MobileRobotSimulator::vel_callback
void vel_callback(const geometry_msgs::Twist::ConstPtr &msg)
Definition: mobile_robot_simulator.cpp:121
MobileRobotSimulator::publish_map_transform
bool publish_map_transform
Definition: mobile_robot_simulator.h:30
MobileRobotSimulator::stop
void stop()
Definition: mobile_robot_simulator.cpp:57
MobileRobotSimulator::update_loop
void update_loop(const ros::TimerEvent &event)
Definition: mobile_robot_simulator.cpp:64
tf::Transform::inverse
Transform inverse() const
MobileRobotSimulator::odom
nav_msgs::Odometry odom
Definition: mobile_robot_simulator.h:55
tf::Transform::setRotation
TFSIMD_FORCE_INLINE void setRotation(const Quaternion &q)
MobileRobotSimulator::get_params
void get_params()
Definition: mobile_robot_simulator.cpp:39
ROS_DEBUG
#define ROS_DEBUG(...)
MobileRobotSimulator::~MobileRobotSimulator
~MobileRobotSimulator()
Definition: mobile_robot_simulator.cpp:34
MobileRobotSimulator::init_pose_callback
void init_pose_callback(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr &msg)
Definition: mobile_robot_simulator.cpp:133
MobileRobotSimulator::loop_timer
ros::Timer loop_timer
Definition: mobile_robot_simulator.h:78
MobileRobotSimulator::th
double th
Definition: mobile_robot_simulator.h:80
tf::transformStampedMsgToTF
static void transformStampedMsgToTF(const geometry_msgs::TransformStamped &msg, StampedTransform &bt)
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
ros::TimerEvent
tf::Transform::setOrigin
TFSIMD_FORCE_INLINE void setOrigin(const Vector3 &origin)
MobileRobotSimulator::vel_sub
ros::Subscriber vel_sub
Definition: mobile_robot_simulator.h:69
MobileRobotSimulator::message_received
bool message_received
Definition: mobile_robot_simulator.h:62
MobileRobotSimulator::velocity_topic
std::string velocity_topic
Definition: mobile_robot_simulator.h:74
MobileRobotSimulator::publish_rate
double publish_rate
Definition: mobile_robot_simulator.h:53
MobileRobotSimulator::measure_time
ros::Time measure_time
Definition: mobile_robot_simulator.h:61
ROS_ERROR
#define ROS_ERROR(...)
tf::Transform::setIdentity
void setIdentity()
ros::NodeHandle::param
T param(const std::string &param_name, const T &default_val) const
MobileRobotSimulator::init_pose_sub
ros::Subscriber init_pose_sub
Definition: mobile_robot_simulator.h:70
DurationBase< Duration >::toSec
double toSec() const
MobileRobotSimulator::start
void start()
Definition: mobile_robot_simulator.cpp:49
MobileRobotSimulator::update_odom_from_vel
void update_odom_from_vel(geometry_msgs::Twist vel, ros::Duration time_diff)
Definition: mobile_robot_simulator.cpp:84
ros::Timer::start
void start()
ROS_INFO
#define ROS_INFO(...)
MobileRobotSimulator::last_update
ros::Time last_update
Definition: mobile_robot_simulator.h:60
MobileRobotSimulator::MobileRobotSimulator
MobileRobotSimulator(ros::NodeHandle *nh)
Definition: mobile_robot_simulator.cpp:5
tf::createQuaternionMsgFromYaw
static geometry_msgs::Quaternion createQuaternionMsgFromYaw(double yaw)
ros::NodeHandle::createTimer
Timer createTimer(Duration period, const TimerCallback &callback, bool oneshot=false, bool autostart=true) const
ros::Duration
MobileRobotSimulator::odometry_topic
std::string odometry_topic
Definition: mobile_robot_simulator.h:75
tf::Quaternion
tf::Transform::getOrigin
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
ros::NodeHandle
MobileRobotSimulator::odom_trans
tf::StampedTransform odom_trans
Definition: mobile_robot_simulator.h:56
ros::Time::now
static Time now()


mobile_robot_simulator
Author(s): Mikkel Rath Pedersen
autogenerated on Thu Jun 2 2022 02:16:58