mild_fake_odom.cpp
Go to the documentation of this file.
1 
18 #include <ros/ros.h>
20 #include <nav_msgs/Odometry.h>
21 #include <stdlib.h>
22 #include <boost/thread/mutex.hpp>
23 #include "geometry_msgs/Twist.h"
24 #include "geometry_msgs/PoseWithCovarianceStamped.h"
25 #include <gazebo_msgs/ModelState.h>
26 
27 //This file simulates robot base by shortcircuting BaseController and CanListener. cmd_vel from move_base are converted into odom pose increments for the robot.
28 
30 
31 //Input command from move_base to fake robot base.
32 geometry_msgs::Twist velocity_cmd;
33 
34 //State of fake robot base.
35 //Pose
36 double x = 0.0;
37 double y = 0.0;
38 double th = 0.0;
39 //Velocities
40 double vx = 0.0;
41 double vy = 0.0;
42 double vth = 0.0;
43 
44 //Save velocity command from move base instead of generating motor control commands.
45 void fakeSetTargetVelocity(const geometry_msgs::Twist &cmd_vel) {
46  ROS_INFO("fakeSetTargetVelocity");
47  boost::mutex::scoped_lock scoped_lock(mutex);
48  velocity_cmd = cmd_vel;
49 }
50 
51 //Accept initial fake base pose from ros topic.
52 void gotInitialRobotPose(const geometry_msgs::PoseWithCovarianceStamped &initialPose) {
53  ROS_INFO("initialpose");
54  x = initialPose.pose.pose.position.x;
55  y = initialPose.pose.pose.position.y;
56  th = tf::getYaw(initialPose.pose.pose.orientation);
57 }
58 
59 geometry_msgs::TransformStamped getOdomTF(ros::Time current_time) {
60 
61  //since all odometry is 6DOF we'll need a quaternion created from yaw
62  geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th);
63 
64  geometry_msgs::TransformStamped odom_trans;
65  odom_trans.header.stamp = current_time;
66  odom_trans.header.frame_id = "odom";
67  odom_trans.child_frame_id = "base_link";
68 
69  odom_trans.transform.translation.x = x;
70  odom_trans.transform.translation.y = y;
71  odom_trans.transform.translation.z = 0.0;
72  odom_trans.transform.rotation = odom_quat;
73 
74  return odom_trans;
75 
76 }
77 
78 nav_msgs::Odometry getOdomMsg(ros::Time current_time) {
79 
80  //since all odometry is 6DOF we'll need a quaternion created from yaw
81  geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th);
82 
83  nav_msgs::Odometry odom;
84  odom.header.stamp = current_time;
85  odom.header.frame_id = "odom";
86 
87  //set the position
88  odom.pose.pose.position.x = x;
89  odom.pose.pose.position.y = y;
90  odom.pose.pose.position.z = 0.0;
91  odom.pose.pose.orientation = odom_quat;
92 
93  //set the velocity
94  odom.child_frame_id = "base_link";
95  odom.twist.twist.linear.x = vx;
96  odom.twist.twist.linear.y = vy;
97  odom.twist.twist.angular.z = vth;
98 
99  return odom;
100 
101 }
102 
103 gazebo_msgs::ModelState getRobotStateGazebo(){
104 
105  //since all odometry is 6DOF we'll need a quaternion created from yaw
106  geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th);
107 
108  gazebo_msgs::ModelState state;
109  state.model_name = "mild";
110 
111  state.pose.position.x = x;
112  state.pose.position.y = y;
113  state.pose.position.z = 0.0;
114  state.pose.orientation = odom_quat;
115  state.twist.linear.x = vx;
116  state.twist.linear.y = vy;
117  state.twist.angular.z = vth;
118 
119  return state;
120 
121 }
122 
123 int main(int argc, char** argv){
124 
125  ros::init(argc, argv, "mild_fake_odom");
126 
127  ros::NodeHandle n;
128 
129  ros::Subscriber twist_sub = n.subscribe("/cmd_vel", 1, fakeSetTargetVelocity);
130  ros::Subscriber init_sub = n.subscribe("/initialpose", 1, gotInitialRobotPose);
131 
132  ros::Publisher odom_pub = n.advertise<nav_msgs::Odometry>("odom", 50);
133  ros::Publisher gazebo_pub = n.advertise<gazebo_msgs::ModelState>("/gazebo/set_model_state", 50);
134  tf::TransformBroadcaster odom_broadcaster;
135 
136  ros::Time current_time, last_time;
137  current_time = ros::Time::now();
138  last_time = ros::Time::now();
139  ros::Rate r(10);
140 
141  while(n.ok()){
142 
143  ros::spinOnce();
144  current_time = ros::Time::now();
145 
146  {
147  boost::mutex::scoped_lock scoped_lock(mutex);
148 
149  vx = velocity_cmd.linear.x;
150  vy = velocity_cmd.linear.y;
151  vth = velocity_cmd.angular.z;
152  ROS_INFO("velocity_cmd vx : %f vy : %f vz : %f", vx, vy,vth);
153  }
154 
155  //Compute cartesian robot pose (for odometry), given the velocities of the robot. Direct kinematics.
156  double dt = (current_time - last_time).toSec();
157  double delta_x = (vx * cos(th) - vy * sin(th)) * dt;
158  double delta_y = (vx * sin(th) + vy * cos(th)) * dt;
159  double delta_th = vth * dt;
160 
161  x += delta_x;
162  y += delta_y;
163  th += delta_th;
164 
165  //first, we'll publish the transform over tf
166  odom_broadcaster.sendTransform(getOdomTF(current_time));
167 
168  //next, we'll publish the odometry message over ROS
169  odom_pub.publish(getOdomMsg(current_time));
170 
171  //gazebo simulation
172  gazebo_pub.publish(getRobotStateGazebo());
173 
174  last_time = current_time;
175  r.sleep();
176 
177  //Velocity command processed -> set to zero for no further processing until new command comes from move_base
178  velocity_cmd.linear.x = 0;
179  velocity_cmd.linear.y = 0;
180  velocity_cmd.angular.z = 0;
181 
182  }
183 }
double x
nav_msgs::Odometry getOdomMsg(ros::Time current_time)
void publish(const boost::shared_ptr< M > &message) const
gazebo_msgs::ModelState getRobotStateGazebo()
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
boost::mutex mutex
geometry_msgs::Twist velocity_cmd
static double getYaw(const Quaternion &bt_q)
double vth
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void fakeSetTargetVelocity(const geometry_msgs::Twist &cmd_vel)
double y
#define ROS_INFO(...)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool sleep()
double vx
double th
static geometry_msgs::Quaternion createQuaternionMsgFromYaw(double yaw)
geometry_msgs::TransformStamped getOdomTF(ros::Time current_time)
static Time now()
int main(int argc, char **argv)
bool ok() const
ROSCPP_DECL void spinOnce()
double vy
void gotInitialRobotPose(const geometry_msgs::PoseWithCovarianceStamped &initialPose)


asr_mild_base_fake_driving
Author(s): Dehmani Souheil, Karrenbauer Oliver, Meißner Pascal
autogenerated on Wed Feb 19 2020 04:03:13