odom_interface.cpp
Go to the documentation of this file.
00001 #include "mav_odom_interface/odom_interface.h"
00002 
00003 namespace mav {
00004 
00005 OdomInterface::OdomInterface(ros::NodeHandle nh, ros::NodeHandle nh_private):
00006   nh_(nh), 
00007   nh_private_(nh_private)
00008 {
00009   ROS_INFO("Starting OdomInterface"); 
00010 
00011   // ****  initialize variables
00012    
00013   pose_.pose.position.x = 0.0;
00014   pose_.pose.position.y = 0.0;
00015   pose_.pose.position.z = 0.0;
00016 
00017   tf::Quaternion q;
00018   q.setRPY(0,0,0);
00019   tf::quaternionTFToMsg(q, pose_.pose.orientation);
00020 
00021   ros::NodeHandle nh_mav (nh_, "mav");
00022 
00023   // **** parameters
00024 
00025   if (!nh_private_.getParam ("fixed_frame", fixed_frame_))
00026     fixed_frame_ = "odom";
00027   if (!nh_private_.getParam ("base_frame", base_frame_))
00028     base_frame_ = "base_link";
00029 
00030   pose_.header.frame_id = fixed_frame_;
00031 
00032   // **** ros publishers
00033 
00034   pose_publisher_ = nh_mav.advertise<geometry_msgs::PoseStamped>(
00035     "pose", 1);
00036   odom_publisher_ = nh_mav.advertise<nav_msgs::Odometry>(
00037     "odom", 1);
00038 
00039   // **** ros subscribers
00040 
00041   laser_pose_subscriber_ = nh_mav.subscribe(
00042     "laser_pose", 1, &OdomInterface::laserPoseCallback, this);
00043   imu_subscriber_ = nh_mav.subscribe(
00044     "imu/data", 1, &OdomInterface::imuCallback, this);
00045   height_subscriber_ = nh_mav.subscribe(
00046     "height_to_base", 1, &OdomInterface::heightCallback, this);
00047 
00048   // publish initial identity pose
00049   pose_.header.stamp = ros::Time::now();
00050   publishPose();
00051 }
00052 
00053 OdomInterface::~OdomInterface()
00054 {
00055   ROS_INFO("Destroying QuadPoseEst"); 
00056 }
00057 
00058 void OdomInterface::laserPoseCallback(const PoseStamped::ConstPtr& laser_pose_msg)
00059 {
00060   pose_mutex_.lock();
00061 
00062   // use x and y from laser
00063   pose_.pose.position.x = laser_pose_msg->pose.position.x;
00064   pose_.pose.position.y = laser_pose_msg->pose.position.y;
00065 
00066   // use roll and pitch from IMU
00067   double roll, pitch, unused;
00068   tf::Quaternion q_pose;
00069   tf::quaternionMsgToTF(pose_.pose.orientation, q_pose);
00070   MyMatrix m_pose(q_pose);
00071   m_pose.getRPY(roll, pitch, unused);
00072 
00073   // use yaw from laser
00074   double yaw = tf::getYaw(laser_pose_msg->pose.orientation);
00075 
00076   // combine r, p, y
00077   tf::Quaternion q_result;
00078   q_result.setRPY(roll, pitch, yaw);
00079   tf::quaternionTFToMsg(q_result, pose_.pose.orientation);
00080 
00081   // publish with the timestamp from this message
00082   pose_.header.stamp = laser_pose_msg->header.stamp;
00083   publishPose();
00084 
00085   pose_mutex_.unlock();
00086 }
00087 
00088 void OdomInterface::imuCallback (const sensor_msgs::Imu::ConstPtr& imu_msg)
00089 {
00090   pose_mutex_.lock();
00091 
00092   // use roll and pitch from IMU, and yaw from laser
00093 
00094   double r, p, y, unused;
00095 
00096   tf::Quaternion q_imu;
00097   tf::quaternionMsgToTF(imu_msg->orientation, q_imu);
00098   MyMatrix m_imu(q_imu);
00099   m_imu.getRPY(r, p, unused);
00100 
00101   tf::Quaternion q_pose;
00102   tf::quaternionMsgToTF(pose_.pose.orientation, q_pose);
00103   MyMatrix m_pose(q_pose);
00104   m_pose.getRPY(unused, unused, y);
00105 
00106   tf::Quaternion q_result;
00107   q_result.setRPY(r, p, y);
00108   tf::quaternionTFToMsg(q_result, pose_.pose.orientation);
00109 
00110   // publish with the timestamp from this message
00111 
00112   pose_.header.stamp = imu_msg->header.stamp;
00113   //publishPose();
00114 
00115   pose_mutex_.unlock();
00116 }
00117 
00118 void OdomInterface::heightCallback (const mav_msgs::Height::ConstPtr& height_msg)
00119 {
00120   pose_mutex_.lock();
00121 
00122   // use z from the height message
00123 
00124   pose_.pose.position.z = height_msg->height;
00125 
00126   // publish with the timestamp from this message
00127 
00128   pose_.header.stamp = height_msg->header.stamp;
00129   publishPose();
00130 
00131   pose_mutex_.unlock();
00132 }
00133 
00134 void OdomInterface::publishPose()
00135 {
00136   // **** create a copy of the pose and publish as shared pointer
00137 
00138   geometry_msgs::PoseStamped::Ptr pose_message = 
00139     boost::make_shared<geometry_msgs::PoseStamped>(pose_);
00140 
00141   pose_publisher_.publish(pose_message);
00142 
00143   // **** broadcast the transform
00144 
00145   tf::Stamped<tf::Pose> tf_pose;
00146   tf::poseStampedMsgToTF(pose_, tf_pose);
00147   tf::StampedTransform odom_to_base_link_tf(
00148     tf_pose, pose_.header.stamp, fixed_frame_, base_frame_);
00149   tf_broadcaster_.sendTransform(odom_to_base_link_tf);
00150 
00151   // *** publish odometry message
00152   // TODO: add velociyies from ab filters
00153   
00154   nav_msgs::Odometry::Ptr odom_message = 
00155     boost::make_shared<nav_msgs::Odometry>();
00156 
00157   odom_message->header = pose_.header;
00158   odom_message->child_frame_id = "base_link";
00159   odom_message->pose.pose = pose_message->pose;
00160   
00161   odom_publisher_.publish(odom_message);
00162 }
00163 
00164 } // namespace mav
00165 


mav_odom_interface
Author(s): Ivan Dryanovski
autogenerated on Thu Jan 2 2014 11:28:16