differential_drive.cpp
Go to the documentation of this file.
1 
9 /*****************************************************************************
10 ** Includes
11 *****************************************************************************/
12 
13 #include <ecl/linear_algebra.hpp>
14 #include <ecl/geometry/angle.hpp>
16 #include "../../../include/ecl/mobile_robot/kinematics/differential_drive.hpp"
17 
18 /*****************************************************************************
19 ** Namespaces
20 *****************************************************************************/
21 
22 namespace ecl {
23 namespace mobile_robot {
24 
25 /*****************************************************************************
26 ** Using
27 *****************************************************************************/
28 
29 using ecl::Angle;
30 using ecl::linear_algebra::Vector2d;
31 using ecl::linear_algebra::Vector3d;
32 using ecl::linear_algebra::Rotation2D;
33 
34 /*****************************************************************************
35 ** Implementation [Kinematics]
36 *****************************************************************************/
37 
38 ecl::LegacyPose2D<double> DifferentialDriveKinematics::forward(const double &dleft, const double& dright) const {
39 
40  LegacyPose2D<double> pose_update;
41  double ds = radius*(dleft+dright)/2.0;
42  double domega = radius*(dright-dleft)/bias;
43  // Local robot frame of reference has the x axis pointing forward
44  // Since the pose update is using the robot frame of reference, the y update is zero
45  pose_update.translation(ds, 0);
46  pose_update.rotation(domega);
47  return pose_update;
48 }
49 
50 ecl::LegacyPose2D<double> DifferentialDriveKinematics::forwardWithPlatformVelocity(const double & linearVelocity, const double & angularVelocity ) const
51 {
52  ecl::LegacyPose2D<double> pose_update;
53  // Local robot frame of reference has the x axis pointing forward
54  // Since the pose update is using the robot frame of reference, the y update is zero
55  pose_update.translation(linearVelocity, 0);
56  pose_update.rotation(angularVelocity);
57  return pose_update;
58 }
59 
60 Vector2d DifferentialDriveKinematics::inverse(const double &linear_velocity, const double &angular_velocity) const {
61 // radius*(theta_dot_l+theta_dot_r)/2.0 = linear_velocity
62 // radius*(theta_dot_r-theta_dot_l)/bias = angular_velocity
63  Vector2d rates;
64  double right = (2*linear_velocity+angular_velocity*bias)/(2*radius);
65  double left = 2*linear_velocity/radius - right;
66  rates << left, right;
67  return rates;
68 }
69 
70 Vector2d DifferentialDriveKinematics::PartialInverse(const ecl::LegacyPose2D<double> &a,
72 {
73  Vector2d diff;
74  diff << b.x() - a.x(), b.y() - a.y();
75 // This rotation doesn't affect the magnitude of ds,
76 // but it so the sign can work out properly
77  Vector2d dr = a.rotationMatrix().inverse()*diff;
78  double ds = sqrt(dr(0)*dr(0)+dr(1)*dr(1));
79  if ( dr(0) < 0.0 ) {
80  ds = -ds;
81  }
82  double dtheta = b.heading() - a.heading(); // difference in headings
83  ecl::wrap_angle(dtheta);
84 
85 // diff << ds, dtheta;
86  return (diff << ds, dtheta).finished();
87 }
88 
89 // Depracated
90 
91 Vector2d DifferentialDriveKinematics::Inverse(const Vector3d &a, const Vector3d &b) {
92  Vector2d diff;
93  Vector2d dxy;
94  ecl::LegacyPose2D<double> posea(a[2], a.segment<2>(0));
95  ecl::LegacyPose2D<double> poseb(b[2], b.segment<2>(0));
96  dxy << poseb.x() - posea.x(), poseb.y() - posea.y();
97 // This rotation doesn't affect the magnitude of ds,
98 // but it so the sign can work out properly
99  Rotation2D<double> rotation(-posea.heading());
100  Vector2d dr = rotation*dxy;
101 // New LegacyPose2D class can extract the rotation matrix directly.
102 // Vector2d dr = a.rotationMatrix().inverse()*dxy;
103  double ds = sqrt(dr(0)*dr(0)+dr(1)*dr(1));
104  if ( dr(0) < 0.0 ) {
105  ds = -ds;
106  }
107  double dtheta = b[2] - a[2]; // difference in headings
108  ecl::wrap_angle(dtheta);
109 
110  diff << ds, dtheta;
111  return diff;
112 }
113 
114 } // namespace mobile_robot
115 } // namespace ecl
ecl_geometry_PUBLIC const float & wrap_angle(float &angle)


ecl_mobile_robot
Author(s): Daniel Stonier
autogenerated on Mon Jun 10 2019 13:08:52