mild_fake_odom.cpp
Go to the documentation of this file.
00001 
00018 #include <ros/ros.h>
00019 #include <tf/transform_broadcaster.h>
00020 #include <nav_msgs/Odometry.h>
00021 #include <stdlib.h>
00022 #include <boost/thread/mutex.hpp>
00023 #include "geometry_msgs/Twist.h"
00024 #include "geometry_msgs/PoseWithCovarianceStamped.h"
00025 #include <gazebo_msgs/ModelState.h>
00026 
00027 //This file simulates robot base by shortcircuting BaseController and CanListener. cmd_vel from move_base are converted into odom pose increments for the robot.
00028 
00029 boost::mutex mutex;
00030 
00031 //Input command from move_base to fake robot base.
00032 geometry_msgs::Twist velocity_cmd;
00033 
00034 //State of fake robot base.
00035 //Pose
00036 double x = 0.0;
00037 double y = 0.0;
00038 double th = 0.0;
00039 //Velocities
00040 double vx = 0.0;
00041 double vy = 0.0;
00042 double vth = 0.0;
00043 
00044 //Save velocity command from move base instead of generating motor control commands.
00045 void fakeSetTargetVelocity(const geometry_msgs::Twist &cmd_vel) {
00046   ROS_INFO("fakeSetTargetVelocity");
00047   boost::mutex::scoped_lock scoped_lock(mutex);
00048   velocity_cmd = cmd_vel;
00049 }
00050 
00051 //Accept initial fake base pose from ros topic.
00052 void gotInitialRobotPose(const geometry_msgs::PoseWithCovarianceStamped &initialPose) {
00053   ROS_INFO("initialpose");
00054   x = initialPose.pose.pose.position.x;
00055   y = initialPose.pose.pose.position.y;
00056   th = tf::getYaw(initialPose.pose.pose.orientation);
00057 }
00058 
00059 geometry_msgs::TransformStamped getOdomTF(ros::Time current_time) {
00060   
00061     //since all odometry is 6DOF we'll need a quaternion created from yaw
00062     geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th);
00063 
00064     geometry_msgs::TransformStamped odom_trans;
00065     odom_trans.header.stamp = current_time;
00066     odom_trans.header.frame_id = "odom";
00067     odom_trans.child_frame_id = "base_link";
00068 
00069     odom_trans.transform.translation.x = x;
00070     odom_trans.transform.translation.y = y;
00071     odom_trans.transform.translation.z = 0.0;
00072     odom_trans.transform.rotation = odom_quat;
00073 
00074     return odom_trans;
00075 
00076 }
00077 
00078 nav_msgs::Odometry getOdomMsg(ros::Time current_time) {
00079 
00080     //since all odometry is 6DOF we'll need a quaternion created from yaw
00081     geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th);
00082 
00083     nav_msgs::Odometry odom;
00084     odom.header.stamp = current_time;
00085     odom.header.frame_id = "odom";
00086 
00087     //set the position
00088     odom.pose.pose.position.x = x;
00089     odom.pose.pose.position.y = y;
00090     odom.pose.pose.position.z = 0.0;
00091     odom.pose.pose.orientation = odom_quat;
00092 
00093     //set the velocity
00094     odom.child_frame_id = "base_link";
00095     odom.twist.twist.linear.x = vx;
00096     odom.twist.twist.linear.y = vy;
00097     odom.twist.twist.angular.z = vth;
00098 
00099     return odom;
00100 
00101 }
00102 
00103 gazebo_msgs::ModelState getRobotStateGazebo(){
00104 
00105     //since all odometry is 6DOF we'll need a quaternion created from yaw
00106     geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th);
00107   
00108     gazebo_msgs::ModelState state;
00109     state.model_name = "mild";
00110 
00111     state.pose.position.x = x;
00112     state.pose.position.y = y;
00113     state.pose.position.z = 0.0;
00114     state.pose.orientation = odom_quat;
00115     state.twist.linear.x = vx;
00116     state.twist.linear.y = vy;
00117     state.twist.angular.z = vth;
00118 
00119     return state;
00120 
00121 }
00122 
00123 int main(int argc, char** argv){
00124 
00125   ros::init(argc, argv, "mild_fake_odom");
00126 
00127   ros::NodeHandle n;
00128 
00129   ros::Subscriber twist_sub = n.subscribe("/cmd_vel", 1, fakeSetTargetVelocity);
00130   ros::Subscriber init_sub = n.subscribe("/initialpose", 1, gotInitialRobotPose);
00131 
00132   ros::Publisher odom_pub = n.advertise<nav_msgs::Odometry>("odom", 50);
00133   ros::Publisher gazebo_pub = n.advertise<gazebo_msgs::ModelState>("/gazebo/set_model_state", 50);
00134   tf::TransformBroadcaster odom_broadcaster;
00135 
00136   ros::Time current_time, last_time;
00137   current_time = ros::Time::now();
00138   last_time = ros::Time::now();
00139   ros::Rate r(10);
00140 
00141   while(n.ok()){
00142 
00143     ros::spinOnce();
00144     current_time = ros::Time::now();
00145 
00146     {
00147       boost::mutex::scoped_lock scoped_lock(mutex);
00148 
00149       vx = velocity_cmd.linear.x;
00150       vy = velocity_cmd.linear.y;
00151       vth = velocity_cmd.angular.z;
00152       ROS_INFO("velocity_cmd vx : %f  vy : %f  vz : %f", vx, vy,vth);
00153     }
00154 
00155     //Compute cartesian robot pose (for odometry), given the velocities of the robot. Direct kinematics.
00156     double dt = (current_time - last_time).toSec();
00157     double delta_x = (vx * cos(th) - vy * sin(th)) * dt;
00158     double delta_y = (vx * sin(th) + vy * cos(th)) * dt;
00159     double delta_th = vth * dt;
00160 
00161     x += delta_x;
00162     y += delta_y;
00163     th += delta_th;
00164 
00165     //first, we'll publish the transform over tf
00166     odom_broadcaster.sendTransform(getOdomTF(current_time));
00167 
00168     //next, we'll publish the odometry message over ROS
00169     odom_pub.publish(getOdomMsg(current_time));
00170 
00171     //gazebo simulation
00172     gazebo_pub.publish(getRobotStateGazebo());
00173 
00174     last_time = current_time;
00175     r.sleep();
00176 
00177     //Velocity command processed -> set to zero for no further processing until new command comes from move_base
00178     velocity_cmd.linear.x = 0;
00179     velocity_cmd.linear.y = 0;
00180     velocity_cmd.angular.z = 0;
00181 
00182   }
00183 }


asr_mild_base_fake_driving
Author(s): Dehmani Souheil, Karrenbauer Oliver, Meißner Pascal
autogenerated on Thu Jun 6 2019 20:56:47