odometry.cpp
Go to the documentation of this file.
1 
10 #include <boost/bind.hpp>
11 
12 namespace ackermann_controller
13 {
14 
15 namespace bacc = boost::accumulators;
16 
17 Odometry::Odometry(size_t velocity_rolling_window_size)
18  : timestamp_(0.0)
19  , x_(0.0)
20  , y_(0.0)
21  , heading_(0.0)
22  , linear_(0.0)
23  , angular_(0.0)
24  , wheelbase_(1.0)
25  , velocity_rolling_window_size_(velocity_rolling_window_size)
26  , linear_acc_(RollingWindow::window_size = velocity_rolling_window_size)
27  , angular_acc_(RollingWindow::window_size = velocity_rolling_window_size)
28  , integrate_fun_(boost::bind(&Odometry::integrateExact, this, _1, _2))
29 {
30 }
31 
32 void Odometry::init(const ros::Time& time)
33 {
34  // Reset accumulators and timestamp:
36  timestamp_ = time;
37 }
38 
40  const std::vector<ActuatedJoint>& steering_joints,
41  const std::vector<Wheel>& odometry_joints,
42  const ros::Time &time)
43 {
44  double linear_sum = 0.0;
45  double angular_sum = 0.0;
46  double steering_angle_sum = 0.0;
47 
48  const double dt = (time - timestamp_).toSec();
49  timestamp_ = time;
50 
51  for (std::vector<Wheel>::const_iterator it = odometry_joints.begin(); it != odometry_joints.end(); ++it)
52  {
53  const double wheel_est_vel = it->handle_.getVelocity() * dt;
54  linear_sum += wheel_est_vel * it->radius_;
55  }
56 
57  const double linear = linear_sum / odometry_joints.size();
58 
59  for (std::vector<ActuatedJoint>::const_iterator it = steering_joints.begin(); it != steering_joints.end(); ++it)
60  {
61  const double steering_angle = it->getPosition();
62  double virtual_steering_angle = std::atan(wheelbase_ * std::tan(steering_angle)/std::abs(wheelbase_ + it->lateral_deviation_ * std::tan(steering_angle)));
63  steering_angle_sum += virtual_steering_angle;
64  angular_sum += linear * tan(virtual_steering_angle) / wheelbase_;
65  }
66 
67  const double angular = angular_sum / steering_joints.size();
68  const double steering_angle = steering_angle_sum / steering_joints.size();
69 
71  const double curvature_radius = wheelbase_ / cos(M_PI/2.0 - steering_angle);
72 
73  if (fabs(curvature_radius) > 0.0001)
74  {
75  const double elapsed_distance = linear;
76  const double elapsed_angle = elapsed_distance / curvature_radius;
77  const double x_curvature = curvature_radius * sin(elapsed_angle);
78  const double y_curvature = curvature_radius * (cos(elapsed_angle) - 1.0);
79  const double wheel_heading = heading_ + steering_angle;
80  y_ += x_curvature * sin(wheel_heading) + y_curvature * cos(wheel_heading);
81  x_ += x_curvature * cos(wheel_heading) - y_curvature * sin(wheel_heading);
82  heading_ += elapsed_angle;
83  }
84 
85  if (dt < 0.0001)
86  return false; // Interval too small to integrate with
87 
89  linear_acc_(linear/dt);
90  angular_acc_(angular/dt);
91 
92  linear_ = bacc::rolling_mean(linear_acc_);
93  angular_ = bacc::rolling_mean(angular_acc_);
94 
95  return true;
96 }
97 
98 void Odometry::updateOpenLoop(double linear, double angular, const ros::Time &time)
99 {
101  linear_ = linear;
102  angular_ = angular;
103 
105  const double dt = (time - timestamp_).toSec();
106  timestamp_ = time;
107  integrate_fun_(linear * dt, angular * dt);
108 }
109 
110 void Odometry::setVelocityRollingWindowSize(size_t velocity_rolling_window_size)
111 {
112  velocity_rolling_window_size_ = velocity_rolling_window_size;
113 
115 }
116 
117 void Odometry::integrateRungeKutta2(double linear, double angular)
118 {
119  const double direction = heading_ + angular * 0.5;
120 
122  x_ += linear * cos(direction);
123  y_ += linear * sin(direction);
124  heading_ += angular;
125 }
126 
132 void Odometry::integrateExact(double linear, double angular)
133 {
134  if (fabs(angular) < 1e-6)
135  integrateRungeKutta2(linear, angular);
136  else
137  {
139  const double heading_old = heading_;
140  const double r = linear/angular;
141  heading_ += angular;
142  x_ += r * (sin(heading_) - sin(heading_old));
143  y_ += -r * (cos(heading_) - cos(heading_old));
144  }
145 }
146 
148 {
149  linear_acc_ = RollingMeanAcc(RollingWindow::window_size = velocity_rolling_window_size_);
150  angular_acc_ = RollingMeanAcc(RollingWindow::window_size = velocity_rolling_window_size_);
151 }
152 
153 }
bool update(const std::vector< ActuatedJoint > &steering_joints, const std::vector< Wheel > &odometry_joints, const ros::Time &time)
Updates the odometry class with latest wheels position.
Definition: odometry.cpp:39
IntegrationFunction integrate_fun_
Integration funcion, used to integrate the odometry:
Definition: odometry.h:170
ros::Time timestamp_
Current timestamp:
Definition: odometry.h:148
double x_
Current pose:
Definition: odometry.h:151
void setVelocityRollingWindowSize(size_t velocity_rolling_window_size)
Velocity rolling window size setter.
Definition: odometry.cpp:110
size_t velocity_rolling_window_size_
Rolling mean accumulators for the linar and angular velocities:
Definition: odometry.h:165
double linear_
Current velocity:
Definition: odometry.h:156
RollingMeanAcc angular_acc_
Definition: odometry.h:167
void integrateExact(double linear, double angular)
Integrates the velocities (linear and angular) using exact method.
Definition: odometry.cpp:132
void updateOpenLoop(double linear, double angular, const ros::Time &time)
Updates the odometry class with latest velocity command.
Definition: odometry.cpp:98
Odometry(size_t velocity_rolling_window_size=10)
Constructor Timestamp will get the current time value Value will be set to zero.
Definition: odometry.cpp:17
bacc::accumulator_set< double, bacc::stats< bacc::tag::rolling_mean > > RollingMeanAcc
Rolling mean accumulator and window:
Definition: odometry.h:125
void integrateRungeKutta2(double linear, double angular)
Integrates the velocities (linear and angular) using 2nd order Runge-Kutta.
Definition: odometry.cpp:117
void init(const ros::Time &time)
Initialize the odometry.
Definition: odometry.cpp:32
void resetAccumulators()
Reset linear and angular accumulators.
Definition: odometry.cpp:147
bacc::tag::rolling_window RollingWindow
Definition: odometry.h:126
The Odometry class handles odometry readings (2D pose and velocity with related timestamp) ...
Definition: odometry.h:27
RollingMeanAcc linear_acc_
Definition: odometry.h:166


ackermann_controller
Author(s): GĂ©rald Lelong
autogenerated on Mon Jun 10 2019 12:44:49