robot_localization_utils.cpp
Go to the documentation of this file.
00001 #include <ros/ros.h>
00002 #include <geometry_msgs/Twist.h>
00003 #include <sensor_msgs/Imu.h>
00004 #include <nav_msgs/Odometry.h>
00005 #include <robotnik_msgs/set_odometry.h>  
00006 #include <mavros_msgs/CommandLong.h>     
00007 #include <robot_localization/SetPose.h>
00008 #include <std_srvs/Trigger.h>
00009 
00010 #include <mavros_msgs/CommandLong.h>
00011 
00012 #define MAVLINK_CALIBRATION_COMMAND 241
00013 
00014 /* Provide tools and ROS Services for the Summit series mobile robots dead-reckoning. Namely:
00015    - /reset_odometry. ROS Service to reset both the state estimation of the ekf_localization_node and 
00016      the odometry estimate inside the summit_xl_controller node.
00017      NOTE: If you are not using the ekf_localization_node, you need to call the 
00018      /set_odometry ROS Service instead 
00019 
00020    - /calibrate_imu_gyro, /calibrate_imu_acc, /calibrate_imu_mag, /calibrate_offset. ROS Services
00021      to launch the calibration of PIXHAWK sensors. The feedback of the calibration process is provided
00022      by the mavros_node (if the terminal in which the mavros_node is launched is not displayed, you won't
00023      get any feedback back)
00024  */
00025 
00026 using namespace std;
00027 
00028 class LocalizationUtils{
00029 public:
00030   LocalizationUtils(ros::NodeHandle nh);
00031 
00032   void odomCallback (const nav_msgs::OdometryConstPtr& odom);
00033   void imuCallback (const sensor_msgs::ImuConstPtr& msg);
00034   bool resetOdomCallback(robotnik_msgs::set_odometry::Request &req, robotnik_msgs::set_odometry::Response &resp);
00035 
00036   bool calGyroCallback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &resp);
00037   bool calAccCallback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &resp);
00038   bool calMagCallback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &resp);
00039   bool calOffCallback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &resp);
00040   
00041 private:
00042   ros::NodeHandle nh_;
00043   ros::NodeHandle private_nh_;
00044 
00045   ros::ServiceClient set_odometry_;
00046   ros::ServiceClient set_pose_;
00047   ros::ServiceServer reset_odom_;
00048   
00049   ros::ServiceServer calib_gyro_srv_;
00050   ros::ServiceServer calib_acc_srv_;
00051   ros::ServiceServer calib_mag_srv_;
00052   ros::ServiceServer calib_off_srv_;
00053   ros::ServiceClient mavcmd_client_;
00054   
00055   ros::Subscriber odom_sub_;
00056   ros::Subscriber imu_sub_;
00057   ros::Publisher imu_pub_;
00058   
00059   string odom_topic_;
00060   string imu_topic_;
00061   string imu_output_topic_;
00062 
00063   //FLAGS
00064   //If true, the node subscribes to sensor_msgs/Imu messages and republishes them dynamically adaptating the orientation covariance matrix accordingly to the state of motion of the robot
00065   string dynamic_imu_covariance_;
00066   bool in_motion_;
00067   float angular_vel_;
00068 };
00069 
00070 LocalizationUtils::LocalizationUtils(ros::NodeHandle nh): nh_(nh), private_nh_("~"), 
00071                                                           in_motion_(false), angular_vel_(0.0)
00072 {
00073   private_nh_.param<string>("odom_topic", odom_topic_, "/odom");
00074   private_nh_.param<string>("imu_topic", imu_topic_, "/mavros/imu/data");
00075   private_nh_.param<string>("dynamic_imu_covariance", dynamic_imu_covariance_, "false");
00076   private_nh_.param<string>("imu_outpur_topic", imu_output_topic_, "/mavros/imu/data_adapted");
00077 
00078   if (dynamic_imu_covariance_ == "true"){
00079         ROS_INFO("[LocalizationUtils]: using dynamic Imu covariance");
00080         imu_sub_=nh_.subscribe<sensor_msgs::Imu>(imu_topic_, 1, &LocalizationUtils::imuCallback, this);
00081         odom_sub_=nh_.subscribe<nav_msgs::Odometry>(odom_topic_, 1, &LocalizationUtils::odomCallback, this);
00082         imu_pub_=nh_.advertise<sensor_msgs::Imu>(imu_output_topic_,10);
00083   }
00084 
00085   mavcmd_client_=nh_.serviceClient<mavros_msgs::CommandLong>("/mavros/cmd/command");
00086   calib_gyro_srv_= nh_.advertiseService("calibrate_imu_gyro", &LocalizationUtils::calGyroCallback, this);
00087   calib_acc_srv_= nh_.advertiseService("calibrate_imu_acc", &LocalizationUtils::calAccCallback, this);
00088   calib_mag_srv_= nh_.advertiseService("calibrate_imu_mag", &LocalizationUtils::calMagCallback, this);
00089   calib_off_srv_= nh_.advertiseService("calibrate_imu_off", &LocalizationUtils::calOffCallback, this);
00090   
00091   set_odometry_ = nh_.serviceClient<robotnik_msgs::set_odometry>("/set_odometry");
00092   set_pose_ = nh_.serviceClient<robot_localization::SetPose>("/set_pose");
00093   reset_odom_=nh_.advertiseService("/reset_odometry",&LocalizationUtils::resetOdomCallback,this);
00094 }
00095 
00096 bool LocalizationUtils::calGyroCallback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &resp){
00097 
00098   mavros_msgs::CommandLong::Request req_mavros;
00099   mavros_msgs::CommandLong::Response resp_mavros;
00100 
00101   req_mavros.command=MAVLINK_CALIBRATION_COMMAND;
00102   req_mavros.confirmation=1;
00103   req_mavros.param1=1;
00104   req_mavros.param2=0;
00105   req_mavros.param3=0;
00106   req_mavros.param4=0;
00107   req_mavros.param5=0;
00108   req_mavros.param6=0;    
00109   req_mavros.param7=0;  
00110 
00111   bool success_odom=mavcmd_client_.call(req_mavros,resp_mavros);
00112 
00113   resp.success=resp_mavros.success;
00114   //resp_mavros.result is the raw result returned by COMMAND_ACK
00115   //TODO save resp_mavros.result in resp.message (conversion from unsigned string to int)
00116   
00117   return true;
00118 }
00119 
00120 bool LocalizationUtils::calAccCallback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &resp){
00121   
00122   mavros_msgs::CommandLong::Request req_mavros;
00123   mavros_msgs::CommandLong::Response resp_mavros;
00124 
00125   req_mavros.command=MAVLINK_CALIBRATION_COMMAND;
00126   req_mavros.confirmation=1;
00127   req_mavros.param1=0;
00128   req_mavros.param2=0;
00129   req_mavros.param3=0;
00130   req_mavros.param4=0;
00131   req_mavros.param5=1;
00132   req_mavros.param6=0;    
00133   req_mavros.param7=0;  
00134 
00135   bool success_odom=mavcmd_client_.call(req_mavros,resp_mavros);
00136 
00137   resp.success=resp_mavros.success;
00138   return true;
00139 }
00140 
00141 bool LocalizationUtils::calMagCallback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &resp){
00142   
00143   mavros_msgs::CommandLong::Request req_mavros;
00144   mavros_msgs::CommandLong::Response resp_mavros;
00145 
00146   req_mavros.command=MAVLINK_CALIBRATION_COMMAND;
00147   req_mavros.confirmation=1;
00148   req_mavros.param1=0;
00149   req_mavros.param2=1;
00150   req_mavros.param3=0;
00151   req_mavros.param4=0;
00152   req_mavros.param5=0;
00153   req_mavros.param6=0;    
00154   req_mavros.param7=0;  
00155 
00156   bool success_odom=mavcmd_client_.call(req_mavros,resp_mavros);
00157 
00158   resp.success=resp_mavros.success; 
00159   return true;
00160 }
00161 
00162 bool LocalizationUtils::calOffCallback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &resp){
00163   
00164   mavros_msgs::CommandLong::Request req_mavros;
00165   mavros_msgs::CommandLong::Response resp_mavros;
00166 
00167   req_mavros.command=MAVLINK_CALIBRATION_COMMAND;
00168   req_mavros.confirmation=1;
00169   req_mavros.param1=0;
00170   req_mavros.param2=0;
00171   req_mavros.param3=0;
00172   req_mavros.param4=0;
00173   req_mavros.param5=2;
00174   req_mavros.param6=0;    
00175   req_mavros.param7=0;  
00176 
00177   bool success_odom=mavcmd_client_.call(req_mavros,resp_mavros);
00178 
00179   resp.success=resp_mavros.success; 
00180   return true;
00181 }
00182 
00183 void LocalizationUtils::imuCallback (const sensor_msgs::ImuConstPtr& imu)
00184 {
00185   sensor_msgs::Imu msg=*imu;
00186   /*  if(in_motion_)
00187     {
00188       msg.orientation_covariance[8]=1e9;
00189       ROS_INFO("In_motion, covariance 1e9");
00190     }
00191   else
00192     {
00193       msg.orientation_covariance[8]=1e-9;
00194       ROS_INFO("In_motion, covariance 1e-9");
00195       }*/
00196 
00197   double scaling_factor_=1e6;
00198   msg.orientation_covariance[8]=(angular_vel_>0.8) ? 1e9 : angular_vel_*1e-9*scaling_factor_;
00199   
00200   imu_pub_.publish(msg);
00201 }
00202 
00203 void LocalizationUtils::odomCallback (const nav_msgs::OdometryConstPtr& odom)
00204 {
00205   in_motion_=(fabs(odom->twist.twist.linear.x)>0.01 || fabs(odom->twist.twist.linear.y)>0.01 ||
00206               fabs(odom->twist.twist.angular.z)>0.005) ? true : false;
00207 
00208   angular_vel_=odom->twist.twist.angular.z;
00209 }
00210 
00211 bool LocalizationUtils::resetOdomCallback(robotnik_msgs::set_odometry::Request &req, robotnik_msgs::set_odometry::Response &resp)
00212 {
00213   geometry_msgs::PoseWithCovarianceStamped msg;
00214   
00215   msg.header.stamp = ros::Time::now();
00216   msg.header.frame_id ="odom";
00217   msg.pose.pose.position.x=req.x;
00218   msg.pose.pose.position.y=req.y;
00219   msg.pose.pose.position.z=req.z;
00220 
00221   msg.pose.pose.orientation.x=0.0;
00222   msg.pose.pose.orientation.y=0.0;
00223   msg.pose.pose.orientation.z=0.0;
00224   msg.pose.pose.orientation.w=1.0;
00225 
00226   robotnik_msgs::set_odometry::Request req_odom;
00227   robotnik_msgs::set_odometry::Response resp_odom;
00228 
00229   robot_localization::SetPose::Request req_rl;
00230   robot_localization::SetPose::Response resp_rl;
00231 
00232   req_odom=req;
00233   req_rl.pose=msg;
00234   bool success_odom=set_odometry_.call(req_odom,resp_odom);
00235   bool success_rl=set_pose_.call(req_rl,resp_rl);
00236 
00237   //TODO: sometimes the service needs to be called twice to reset the ekf_localization_node output
00238   resp.ret=(success_odom && success_rl);
00239   
00240   return true;
00241 }
00242 
00243 int main (int argc, char** argv)
00244 {
00245   ros::init(argc, argv, "localization_helper_node");
00246   ros::NodeHandle nh;
00247 
00248   LocalizationUtils utils(nh);
00249   ros::spin();
00250 
00251   return 0;
00252 }


summit_xl_localization
Author(s):
autogenerated on Thu Jun 6 2019 21:18:15