diff_drive.cpp
Go to the documentation of this file.
1 
10 /*****************************************************************************
11 ** Includes
12 *****************************************************************************/
13 
14 #include "../../include/kobuki_driver/modules/diff_drive.hpp"
15 
16 /*****************************************************************************
17 ** Namespaces
18 *****************************************************************************/
19 
20 namespace kobuki {
21 
22 /*****************************************************************************
23 ** Implementation
24 *****************************************************************************/
26  last_velocity_left(0.0),
27  last_velocity_right(0.0),
28  last_tick_left(0),
29  last_tick_right(0),
30  last_rad_left(0.0),
31  last_rad_right(0.0),
32 // v(0.0), w(0.0), // command velocities, in [m/s] and [rad/s]
33  radius(0.0), speed(0.0), // command velocities, in [mm] and [mm/s]
34  point_velocity(2,0.0), // command velocities, in [m/s] and [rad/s]
35  bias(0.23), // wheelbase, wheel_to_wheel, in [m]
36  wheel_radius(0.035), // radius of main wheel, in [m]
37  tick_to_rad(0.002436916871363930187454f),
38  diff_drive_kinematics(bias, wheel_radius)
39 {}
40 
52 void DiffDrive::update(const uint16_t &time_stamp,
53  const uint16_t &left_encoder,
54  const uint16_t &right_encoder,
55  ecl::LegacyPose2D<double> &pose_update,
56  ecl::linear_algebra::Vector3d &pose_update_rates) {
57  state_mutex.lock();
58  static bool init_l = false;
59  static bool init_r = false;
60  double left_diff_ticks = 0.0f;
61  double right_diff_ticks = 0.0f;
62  unsigned short curr_tick_left = 0;
63  unsigned short curr_tick_right = 0;
64  unsigned short curr_timestamp = 0;
65  curr_timestamp = time_stamp;
66  curr_tick_left = left_encoder;
67  if (!init_l)
68  {
69  last_tick_left = curr_tick_left;
70  init_l = true;
71  }
72  left_diff_ticks = (double)(short)((curr_tick_left - last_tick_left) & 0xffff);
73  last_tick_left = curr_tick_left;
74  last_rad_left += tick_to_rad * left_diff_ticks;
75 
76  curr_tick_right = right_encoder;
77  if (!init_r)
78  {
79  last_tick_right = curr_tick_right;
80  init_r = true;
81  }
82  right_diff_ticks = (double)(short)((curr_tick_right - last_tick_right) & 0xffff);
83  last_tick_right = curr_tick_right;
84  last_rad_right += tick_to_rad * right_diff_ticks;
85 
86  // TODO this line and the last statements are really ugly; refactor, put in another place
87  pose_update = diff_drive_kinematics.forward(tick_to_rad * left_diff_ticks, tick_to_rad * right_diff_ticks);
88 
89  if (curr_timestamp != last_timestamp)
90  {
91  last_diff_time = ((double)(short)((curr_timestamp - last_timestamp) & 0xffff)) / 1000.0f;
92  last_timestamp = curr_timestamp;
93  last_velocity_left = (tick_to_rad * left_diff_ticks) / last_diff_time;
94  last_velocity_right = (tick_to_rad * right_diff_ticks) / last_diff_time;
95  } else {
96  // we need to set the last_velocity_xxx to zero?
97  }
98 
99  pose_update_rates << pose_update.x()/last_diff_time,
100  pose_update.y()/last_diff_time,
101  pose_update.heading()/last_diff_time;
102  state_mutex.unlock();
103 }
104 
106  state_mutex.lock();
107  last_rad_left = 0.0;
108  last_rad_right = 0.0;
109  last_velocity_left = 0.0;
110  last_velocity_right = 0.0;
111  state_mutex.unlock();
112 }
113 
114 void DiffDrive::getWheelJointStates(double &wheel_left_angle, double &wheel_left_angle_rate,
115  double &wheel_right_angle, double &wheel_right_angle_rate) {
116  state_mutex.lock();
117  wheel_left_angle = last_rad_left;
118  wheel_right_angle = last_rad_right;
119  wheel_left_angle_rate = last_velocity_left;
120  wheel_right_angle_rate = last_velocity_right;
121  state_mutex.unlock();
122 }
123 
124 void DiffDrive::setVelocityCommands(const double &vx, const double &wz) {
125  // vx: in m/s
126  // wz: in rad/s
127  std::vector<double> cmd_vel;
128  cmd_vel.push_back(vx);
129  cmd_vel.push_back(wz);
130  point_velocity = cmd_vel;
131 }
132 
133 void DiffDrive::velocityCommands(const double &vx, const double &wz) {
134  // vx: in m/s
135  // wz: in rad/s
136  velocity_mutex.lock();
137  const double epsilon = 0.0001;
138 
139  // Special Case #1 : Straight Run
140  if( std::abs(wz) < epsilon ) {
141  radius = 0.0f;
142  speed = 1000.0f * vx;
143  velocity_mutex.unlock();
144  return;
145  }
146 
147  radius = vx * 1000.0f / wz;
148  // Special Case #2 : Pure Rotation or Radius is less than or equal to 1.0 mm
149  if( std::abs(vx) < epsilon || std::abs(radius) <= 1.0f ) {
150  speed = 1000.0f * bias * wz / 2.0f;
151  radius = 1.0f;
152  velocity_mutex.unlock();
153  return;
154  }
155 
156  // General Case :
157  if( radius > 0.0f ) {
158  speed = (radius + 1000.0f * bias / 2.0f) * wz;
159  } else {
160  speed = (radius - 1000.0f * bias / 2.0f) * wz;
161  }
162  velocity_mutex.unlock();
163  return;
164 }
165 
166 void DiffDrive::velocityCommands(const short &cmd_speed, const short &cmd_radius) {
167  velocity_mutex.lock();
168  speed = static_cast<double>(cmd_speed); // In [mm/s]
169  radius = static_cast<double>(cmd_radius); // In [mm]
170  velocity_mutex.unlock();
171  return;
172 }
173 
174 std::vector<short> DiffDrive::velocityCommands() {
175  velocity_mutex.lock();
176  std::vector<short> cmd(2);
177  cmd[0] = bound(speed); // In [mm/s]
178  cmd[1] = bound(radius); // In [mm]
179  velocity_mutex.unlock();
180  return cmd;
181 }
182 
183 std::vector<double> DiffDrive::pointVelocity() const {
184  return point_velocity;
185 }
186 
187 short DiffDrive::bound(const double &value) {
188  if (value > static_cast<double>(SHRT_MAX)) return SHRT_MAX;
189  if (value < static_cast<double>(SHRT_MIN)) return SHRT_MIN;
190  return static_cast<short>(value);
191 }
192 
193 } // namespace kobuki
double radius
short bound(const double &value)
Definition: diff_drive.cpp:187
ecl::Mutex velocity_mutex
Definition: diff_drive.hpp:85
std::vector< double > point_velocity
Definition: diff_drive.hpp:76
ecl::Mutex state_mutex
Definition: diff_drive.hpp:85
double speed
unsigned short last_tick_left
Definition: diff_drive.hpp:72
void getWheelJointStates(double &wheel_left_angle, double &wheel_left_angle_rate, double &wheel_right_angle, double &wheel_right_angle_rate)
Definition: diff_drive.cpp:114
const double tick_to_rad
Definition: diff_drive.hpp:82
ecl::DifferentialDrive::Kinematics diff_drive_kinematics
Definition: diff_drive.hpp:84
double bias
std::vector< double > pointVelocity() const
Definition: diff_drive.cpp:183
std::vector< short > velocityCommands()
Definition: diff_drive.cpp:174
unsigned short last_timestamp
Definition: diff_drive.hpp:68
double last_velocity_left
Definition: diff_drive.hpp:69
void update(const uint16_t &time_stamp, const uint16_t &left_encoder, const uint16_t &right_encoder, ecl::LegacyPose2D< double > &pose_update, ecl::linear_algebra::Vector3d &pose_update_rates)
Updates the odometry from firmware stamps and encoders.
Definition: diff_drive.cpp:52
unsigned short last_tick_right
Definition: diff_drive.hpp:72
double last_velocity_right
Definition: diff_drive.hpp:69
void setVelocityCommands(const double &vx, const double &wz)
Definition: diff_drive.cpp:124


kobuki_driver
Author(s): Daniel Stonier , Younghun Ju , Jorge Santos Simon
autogenerated on Mon Mar 27 2017 01:02:59