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
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00064
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
00115
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
00187
00188
00189
00190
00191
00192
00193
00194
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
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 }