odometry.cpp
Go to the documentation of this file.
00001 #include <four_wheel_steering_controller/odometry.h>
00002 
00003 #include <boost/bind.hpp>
00004 
00005 namespace four_wheel_steering_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   , linear_x_(0.0)
00017   , linear_y_(0.0)
00018   , angular_(0.0)
00019   , track_(0.0)
00020   , wheel_radius_(0.0)
00021   , wheel_base_(0.0)
00022   , wheel_old_pos_(0.0)
00023   , velocity_rolling_window_size_(velocity_rolling_window_size)
00024   , linear_acc_(RollingWindow::window_size = velocity_rolling_window_size)
00025   , angular_acc_(RollingWindow::window_size = velocity_rolling_window_size)
00026   {
00027   }
00028 
00029   void Odometry::init(const ros::Time& time)
00030   {
00031     // Reset accumulators and timestamp:
00032     resetAccumulators();
00033     timestamp_ = time;
00034   }
00035 
00036 
00037   bool Odometry::update(const double &fl_speed, const double &fr_speed,
00038                         const double &rl_speed, const double &rr_speed,
00039                         double front_steering, double rear_steering, const ros::Time &time)
00040   {
00041 //    const double front_tmp = cos(front_steering)*(tan(front_steering)-tan(rear_steering))/wheel_base_;
00042 //    const double front_linear_speed = wheel_radius_ * copysign(1.0, fl_speed+fr_speed)*
00043 //        sqrt((pow(fl_speed,2)+pow(fr_speed,2))/(2+pow(track_*front_tmp,2)/2.0));
00044 
00045     const double rear_tmp = cos(rear_steering)*(tan(front_steering)-tan(rear_steering))/wheel_base_;
00046     const double rear_linear_speed = wheel_radius_ * copysign(1.0, rl_speed+rr_speed)*
00047         sqrt((pow(rl_speed,2)+pow(rr_speed,2))/(2+pow(track_*rear_tmp,2)/2.0));
00048 
00049     angular_ = rear_linear_speed*rear_tmp;
00050 
00051     linear_x_ = rear_linear_speed*cos(rear_steering);
00052     linear_y_ = rear_linear_speed*sin(rear_steering)
00053                 + wheel_base_*angular_/2.0;
00054     linear_ =  copysign(1.0, rear_linear_speed)*sqrt(pow(linear_x_,2)+pow(linear_y_,2));
00055 
00057     const double dt = (time - last_update_timestamp_).toSec();
00058     last_update_timestamp_ = time;
00060     integrateXY(linear_x_*dt, linear_y_*dt, angular_*dt);
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 wheel_radius, double wheel_base)
00078   {
00079     track_ = track;
00080     wheel_radius_     = wheel_radius;
00081     wheel_base_       = wheel_base;
00082   }
00083 
00084   void Odometry::setVelocityRollingWindowSize(size_t velocity_rolling_window_size)
00085   {
00086     velocity_rolling_window_size_ = velocity_rolling_window_size;
00087 
00088     resetAccumulators();
00089   }
00090 
00091   void Odometry::integrateXY(double linear_x, double linear_y, double angular)
00092   {
00093     const double delta_x = linear_x*cos(heading_) - linear_y*sin(heading_);
00094     const double delta_y = linear_x*sin(heading_) + linear_y*cos(heading_);
00095 
00096     x_ += delta_x;
00097     y_ += delta_y;
00098     heading_ += angular;
00099   }
00100 
00101   void Odometry::integrateRungeKutta2(double linear, double angular)
00102   {
00103     const double direction = heading_ + angular * 0.5;
00104 
00106     x_       += linear * cos(direction);
00107     y_       += linear * sin(direction);
00108     heading_ += angular;
00109   }
00110 
00111   void Odometry::integrateExact(double linear, double angular)
00112   {
00113     if (fabs(angular) < 1e-6)
00114       integrateRungeKutta2(linear, angular);
00115     else
00116     {
00118       const double heading_old = heading_;
00119       const double r = linear/angular;
00120       heading_ += angular;
00121       x_       +=  r * (sin(heading_) - sin(heading_old));
00122       y_       += -r * (cos(heading_) - cos(heading_old));
00123     }
00124   }
00125 
00126   void Odometry::resetAccumulators()
00127   {
00128     linear_acc_ = RollingMeanAcc(RollingWindow::window_size = velocity_rolling_window_size_);
00129     angular_acc_ = RollingMeanAcc(RollingWindow::window_size = velocity_rolling_window_size_);
00130   }
00131 
00132 } // namespace four_wheel_steering_controller


four_wheel_steering_controller
Author(s): Vincent Rousseau
autogenerated on Sat Jun 8 2019 20:06:24