Go to the documentation of this file.00001 #include <ackermann_controller/odometry.h>
00002
00003 #include <boost/bind.hpp>
00004
00005 namespace ackermann_controller
00006 {
00007 namespace bacc = boost::accumulators;
00008
00009 Odometry::Odometry(size_t velocity_rolling_window_size)
00010 : timestamp_(0.0)
00011 , last_update_timestamp_(0.0)
00012 , x_(0.0)
00013 , y_(0.0)
00014 , heading_(0.0)
00015 , linear_(0.0)
00016 , angular_(0.0)
00017 , track_(0.0)
00018 , front_wheel_radius_(0.0)
00019 , rear_wheel_radius_(0.0)
00020 , wheel_base_(0.0)
00021 , left_wheel_old_pos_(0.0)
00022 , right_wheel_old_pos_(0.0)
00023 , wheel_old_pos_(0.0)
00024 , velocity_rolling_window_size_(velocity_rolling_window_size)
00025 , linear_acc_(RollingWindow::window_size = velocity_rolling_window_size)
00026 , angular_acc_(RollingWindow::window_size = velocity_rolling_window_size)
00027 {
00028 }
00029
00030 void Odometry::init(const ros::Time& time)
00031 {
00032
00033 resetAccumulators();
00034 timestamp_ = time;
00035 last_update_timestamp_ = time;
00036 }
00037
00038 bool Odometry::update(double front_wheel_angular_pos, double front_wheel_angular_vel,
00039 double rear_wheel_angular_pos, double rear_wheel_angular_vel,
00040 double front_steering, const ros::Time &time)
00041 {
00043 const double wheel_cur_pos = rear_wheel_angular_pos * rear_wheel_radius_;
00045 const double wheel_est_diff_pos = wheel_cur_pos - wheel_old_pos_;
00047 wheel_old_pos_ = wheel_cur_pos;
00048
00049 const double angular_diff = wheel_est_diff_pos * tan(front_steering) / wheel_base_;
00051 integrateExact(wheel_est_diff_pos, angular_diff);
00052
00053 linear_ = rear_wheel_angular_vel*rear_wheel_radius_;
00054 angular_ = linear_ * tan(front_steering) / wheel_base_;
00055
00057
00058
00059
00060
00061
00062 return true;
00063 }
00064
00065 void Odometry::updateOpenLoop(double linear, double angular, const ros::Time &time)
00066 {
00068 linear_ = linear;
00069 angular_ = angular;
00070
00072 const double dt = (time - timestamp_).toSec();
00073 timestamp_ = time;
00074 integrateExact(linear * dt, angular * dt);
00075 }
00076
00077 void Odometry::setWheelParams(double track, double front_wheel_radius, double rear_wheel_radius, double wheel_base)
00078 {
00079 track_ = track;
00080 front_wheel_radius_ = front_wheel_radius;
00081 rear_wheel_radius_ = rear_wheel_radius;
00082 wheel_base_ = wheel_base;
00083 }
00084
00085 void Odometry::setVelocityRollingWindowSize(size_t velocity_rolling_window_size)
00086 {
00087 velocity_rolling_window_size_ = velocity_rolling_window_size;
00088
00089 resetAccumulators();
00090 }
00091
00092 void Odometry::integrateRungeKutta2(double linear, double angular)
00093 {
00094 const double direction = heading_ + angular * 0.5;
00095
00097 x_ += linear * cos(direction);
00098 y_ += linear * sin(direction);
00099 heading_ += angular;
00100 }
00101
00107 void Odometry::integrateExact(double linear, double angular)
00108 {
00109 if (fabs(angular) < 1e-6)
00110 {
00111 integrateRungeKutta2(linear, angular);
00112 }
00113 else
00114 {
00116 const double heading_old = heading_;
00117 const double r = linear/angular;
00118 heading_ += angular;
00119 x_ += r * (sin(heading_) - sin(heading_old));
00120 y_ += -r * (cos(heading_) - cos(heading_old));
00121 }
00122 }
00123
00124 void Odometry::resetAccumulators()
00125 {
00126 linear_acc_ = RollingMeanAcc(RollingWindow::window_size = velocity_rolling_window_size_);
00127 angular_acc_ = RollingMeanAcc(RollingWindow::window_size = velocity_rolling_window_size_);
00128 }
00129
00130 }