ab_filter_pose.cpp
Go to the documentation of this file.
00001 /*
00002  *  Alpha-Beta Filter
00003  *  Copyright (C) 2011, CCNY Robotics Lab
00004  *  Ivan Dryanovski <ivan.dryanovski@gmail.com>
00005  *
00006  *  http://robotics.ccny.cuny.edu
00007  *
00008  *  This program is free software: you can redistribute it and/or modify
00009  *  it under the terms of the GNU General Public License as published by
00010  *  the Free Software Foundation, either version 3 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  This program is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *  GNU General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU General Public License
00019  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00020  */
00021 
00022 #include "ab_filter/ab_filter_pose.h"
00023 
00024 namespace mav
00025 {
00026 
00027 ABFilterPose::ABFilterPose(ros::NodeHandle nh, ros::NodeHandle nh_private):
00028   nh_(nh), 
00029   nh_private_(nh_private),
00030   initialized_(false)
00031 {
00032   ROS_INFO("Starting ABFilterPose"); 
00033 
00034   ros::NodeHandle nh_mav (nh_, "mav");
00035 
00036   // **** get parameters
00037 
00038   initializeParams();
00039 
00040   // *** register publishers
00041 
00042   pose_publisher_  = nh_mav.advertise<Pose>(
00043     "pose_f", 10);
00044   twist_publisher_  = nh_mav.advertise<Twist>(
00045     "twist_f", 10);
00046 
00047   if (publish_unfiltered_)
00048   {
00049     twist_unf_publisher_ = nh_mav.advertise<Twist>(
00050       "twist_unf", 10);
00051   }
00052 
00053   // **** register subscribers
00054 
00055   subscriber_ = nh_mav.subscribe(
00056     "pose", 10, &ABFilterPose::poseCallback, this);
00057 }
00058 
00059 ABFilterPose::~ABFilterPose()
00060 {
00061   ROS_INFO("Destroying ABFilterPose"); 
00062 
00063 }
00064 
00065 void ABFilterPose::initializeParams()
00066 {
00067   if (!nh_private_.getParam ("alpha", alpha_))
00068     alpha_ = 0.9;
00069   if (!nh_private_.getParam ("beta", beta_))
00070     beta_ = 0.5;
00071   if (!nh_private_.getParam ("publish_unfiltered", publish_unfiltered_))
00072     publish_unfiltered_ = false;
00073 }
00074 
00075 
00076 void ABFilterPose::poseCallback(const Pose::ConstPtr pose_msg)
00077 {
00078   ros::Time time = pose_msg->header.stamp;
00079 
00080   tf::Vector3 pos_reading;
00081   tf::pointMsgToTF(pose_msg->pose.position, pos_reading);
00082 
00083   tf::Quaternion q_reading;
00084   tf::quaternionMsgToTF(pose_msg->pose.orientation, q_reading);
00085 
00086   // first message
00087   if(!initialized_)
00088   {
00089     initialized_ = true;
00090 
00091     // set initial position and orientation to the first pose message
00092     pos_ = pos_reading;
00093     q_   = q_reading;
00094 
00095     // set initial velocities to 0
00096     lin_vel_ = tf::Vector3(0.0, 0.0, 0.0);
00097     ang_vel_ = tf::Vector3(0.0, 0.0, 0.0); 
00098   }
00099   else
00100   {
00101     double dt = (time - last_update_time_).toSec();
00102     double bdt = beta_ / dt;
00103 
00104     if (publish_unfiltered_)
00105     {
00106       lin_vel_unf_ = (pos_reading - pos_) / dt;
00107     }
00108 
00109     // **** calculate position
00110 
00111     tf::Vector3 pos_pred = pos_ + dt * lin_vel_;
00112     tf::Vector3 r_pos = pos_reading - pos_pred;
00113     pos_ = pos_pred + alpha_ * r_pos;
00114     lin_vel_ += bdt * r_pos;
00115 
00116     // **** calculate orientation
00117 
00118     tf::Vector3 w = dt * ang_vel_;
00119     tf::Quaternion qw;
00120     qw.setRPY(w.getX(), w.getY(), w.getZ());
00121 
00122     tf::Quaternion q_pred = qw * q_;
00123     tf::Quaternion q_new = q_pred.slerp(q_reading, alpha_);  
00124 
00125     tf::Quaternion r = q_reading * q_.inverse();
00126     
00127     q_ = q_new;
00128 
00129     double r_roll, r_pitch, r_yaw;
00130     MyMatrix r_m(r);
00131     r_m.getRPY(r_roll, r_pitch, r_yaw);
00132     tf::Vector3 ang_vel_meas(r_roll/dt, r_pitch/dt, r_yaw/dt);
00133 
00134     tf::Vector3 ang_vel_pred = ang_vel_;
00135     
00136     ang_vel_ = (1.0 - beta_) * ang_vel_pred + beta_ * ang_vel_meas;
00137 
00138     // **** calculate unfiltered velocity 
00139     if (publish_unfiltered_)
00140     {
00141       ang_vel_unf_ = ang_vel_meas;
00142     }
00143   }
00144 
00145   last_update_time_ = time;
00146 
00147   publishPose(pose_msg->header);
00148 }
00149 
00150 void ABFilterPose::publishPose(const std_msgs::Header& header)
00151 {
00152   // **** publish pose message
00153 
00154   Pose::Ptr pose = boost::make_shared<Pose>();
00155   pose->header = header;
00156 
00157   tf::pointTFToMsg(pos_, pose->pose.position);
00158   tf::quaternionTFToMsg(q_, pose->pose.orientation);
00159 
00160   pose_publisher_.publish(pose);
00161 
00162   // **** publish twist message
00163 
00164   Twist::Ptr twist = boost::make_shared<Twist>();
00165   twist->header = header;
00166   
00167   tf::vector3TFToMsg(lin_vel_, twist->twist.linear);
00168   tf::vector3TFToMsg(ang_vel_, twist->twist.angular);
00169 
00170   twist_publisher_.publish(twist);
00171 
00172   // **** publish unfiltered twist message
00173 
00174   if (publish_unfiltered_)
00175   {
00176     Twist::Ptr twist_unf = boost::make_shared<Twist>();
00177     twist_unf->header = header;
00178 
00179     tf::vector3TFToMsg(lin_vel_unf_, twist_unf->twist.linear);
00180     tf::vector3TFToMsg(ang_vel_unf_, twist_unf->twist.angular);
00181 
00182     twist_unf_publisher_.publish(twist_unf);
00183   }
00184 }
00185 
00186 void ABFilterPose::normalizeAngle2Pi(double& angle)
00187 {
00188   while (angle  <        0.0) angle += 2.0 * M_PI;
00189   while (angle >= 2.0 * M_PI) angle -= 2.0 * M_PI;
00190 }
00191 
00192 void ABFilterPose::normalizeAnglePi(double& angle)
00193 {
00194   while (angle <= -M_PI) angle += 2.0 * M_PI;
00195   while (angle >   M_PI) angle -= 2.0 * M_PI;
00196 }
00197 
00198 } // end namespace asctec


ab_filter
Author(s): Ivan Dryanovski
autogenerated on Thu Jan 2 2014 11:28:26