Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00037
00038 initializeParams();
00039
00040
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
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
00087 if(!initialized_)
00088 {
00089 initialized_ = true;
00090
00091
00092 pos_ = pos_reading;
00093 q_ = q_reading;
00094
00095
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
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
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
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
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
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
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 }