00001
00002
00003
00004
00005
00006
00007
00015 #include <art/conversions.h>
00016 #include <art_msgs/ArtHertz.h>
00017 #include "speed.h"
00018
00023 namespace ControlMatrix
00024 {
00025
00026
00027 static const int N_DELTAS = 13;
00028 static const int DELTA_0 = (N_DELTAS-1)/2;
00029 static const int N_SPEEDS = 6;
00030
00031
00032 typedef struct
00033 {
00034 float brake_delta;
00035 float throttle_delta;
00036 } accel_parms_t;
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 static const accel_parms_t accel_matrix[N_DELTAS][N_SPEEDS] =
00047 {
00048 {{1000,-90}, {12,-30}, {12,-30}, {12,-40}, {12,-50}, {20,-70}},
00049 {{1000,-60}, { 6,-20}, { 6,-20}, { 6,-30}, { 6,-40}, {10,-55}},
00050 {{1000,-40}, { 4,-15}, { 4,-15}, { 4,-20}, { 4,-30}, { 7,-40}},
00051 { {500,-20}, { 3,-10}, { 3,-10}, { 3,-10}, { 3,-20}, { 5,-25}},
00052 { {200,-10}, {2,-5}, {2,-5}, {2,-5}, {2,-10}, {3,-10}},
00053 { {100,-5}, {1,-2}, {1,-2}, {1,-2}, {1,-5}, {1,-5} },
00054 { {100,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0} },
00055 {{-100,1}, {-2,2}, {-2,2}, {-2,2}, {-2,5}, {-2,5} },
00056 {{-200,2}, {-5,5}, {-5,5}, {-5,5}, {-5,10}, {-5,10}},
00057 {{-300,3}, {-10,10}, {-10,10}, {-10,10}, {-10,20}, {-10,25}},
00058 {{-500,4}, {-15,15}, {-15,15}, {-15,20}, {-15,30}, {-15,40}},
00059 {{-1000,5}, {-20,20}, {-20,20}, {-20,30}, {-20,40}, {-20,55}},
00060 {{-1000,6}, {-30,30}, {-30,30}, {-30,40}, {-30,50}, {-30,70}}
00061 };
00062
00063
00064
00065
00066 static inline int
00067 delta_row(float mph)
00068 {
00069 int row;
00070 static float row_limits[DELTA_0+1] = {0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0};
00071 int mph_sign = 1;
00072
00073 if (mph < 0)
00074 mph_sign = -1;
00075
00076 float abs_mph = mph * mph_sign;
00077
00078 for (row = 0; row < DELTA_0+1; ++row)
00079 {
00080 if (abs_mph <= row_limits[row])
00081 return DELTA_0 + mph_sign * row;
00082 }
00083
00084
00085 return DELTA_0 + mph_sign * DELTA_0;
00086 }
00087
00088 static inline int
00089 speed_col(float mph)
00090 {
00091 int col;
00092 static float col_limits[N_SPEEDS] = {0.0, 4.0, 8.0, 16.0, 32.0, 64.0};
00093
00094 for (col = 0; col < N_SPEEDS; ++col)
00095 {
00096 if (mph <= col_limits[col])
00097 return col;
00098 }
00099
00100
00101 return N_SPEEDS-1;
00102 }
00103 };
00104
00106 SpeedControlMatrix::SpeedControlMatrix():
00107 SpeedControl(),
00108 velpid_(new Pid("speed", 2.0, 0.0, 32.0))
00109 {
00110
00111
00112
00113
00114
00115
00116 reset();
00117 }
00118
00120 SpeedControlMatrix::~SpeedControlMatrix()
00121 {}
00122
00135 void SpeedControlMatrix::adjust(float speed, float error,
00136 float *brake_req, float *throttle_req)
00137 {
00138 using namespace ControlMatrix;
00139
00140 float delta = velpid_->Update(error, speed);
00141 float delta_mph = mps2mph(delta);
00142
00143
00144 int row = delta_row(delta_mph);
00145 int col = speed_col(mps2mph(speed));
00146 float brake_delta =
00147 (accel_matrix[row][col].brake_delta / art_msgs::ArtHertz::PILOT)
00148 / 100.0;
00149 float throttle_delta =
00150 (accel_matrix[row][col].throttle_delta / art_msgs::ArtHertz::PILOT)
00151 / 100.0;
00152
00153 ROS_DEBUG("accel_matrix[%d][%d] contains {%.3f, %.3f}",
00154 row, col, brake_delta, throttle_delta);
00155
00156
00157
00158 if (*throttle_req > 0.0 && brake_delta > 0.0)
00159 brake_delta = 0.0;
00160 if (*brake_req > 0.0 && throttle_delta > 0.0)
00161 throttle_delta = 0.0;
00162 *brake_req += brake_delta;
00163 *throttle_req += throttle_delta;
00164 }
00165
00167 void SpeedControlMatrix::configure(art_pilot::PilotConfig &newconfig)
00168 {
00169 velpid_->Configure(node_);
00170 }
00171
00173 void SpeedControlMatrix::reset(void)
00174 {
00175 velpid_->Clear();
00176 }
00177
00186 SpeedControlPID::SpeedControlPID():
00187 SpeedControl(),
00188 braking_(true),
00189 brake_pid_(new Pid("brake", -0.2, -0.0002, -1.6, 1.0, 0.0, 5000.0)),
00190 throttle_pid_(new Pid("throttle", 0.12, 0.001, 0.54, 0.4, 0.0, 5000.0))
00191 {
00192 reset();
00193 }
00194
00196 SpeedControlPID::~SpeedControlPID()
00197 {};
00198
00212 void SpeedControlPID::adjust(float speed, float error,
00213 float *brake_req, float *throttle_req)
00214 {
00215 if (braking_)
00216 {
00217
00218 *brake_req = brake_pid_->Update(error, speed);
00219 *throttle_req = 0.0;
00220
00221
00222 #if 1
00223
00224
00225
00226
00227 if ((brake_position_ < EPSILON_BRAKE) && (*brake_req < EPSILON_BRAKE))
00228 {
00229 *brake_req = 0.0;
00230 braking_ = false;
00231 throttle_pid_->Clear();
00232 }
00233 #else
00234
00235
00236 if ((*brake_req < EPSILON_BRAKE))
00237 {
00238 *brake_req = 0.0;
00239 braking_ = false;
00240 throttle_pid_->Clear();
00241 }
00242 #endif
00243 }
00244 else
00245 {
00246
00247 *throttle_req = throttle_pid_->Update(error, speed);
00248 *brake_req = 0.0;
00249
00250
00251
00252
00253
00254
00255
00256 if (*throttle_req < EPSILON_THROTTLE)
00257 {
00258 *throttle_req = 0.0;
00259 braking_ = true;
00260 brake_pid_->Clear();
00261 }
00262 }
00263 }
00264
00266 void SpeedControlPID::configure(art_pilot::PilotConfig &newconfig)
00267 {
00268 brake_pid_->Configure(newconfig.brake_kp,
00269 newconfig.brake_ki,
00270 newconfig.brake_kd);
00271 throttle_pid_->Configure(newconfig.throttle_kp,
00272 newconfig.throttle_ki,
00273 newconfig.throttle_kd);
00274 }
00275
00277 void SpeedControlPID::reset(void)
00278 {
00279 brake_pid_->Clear();
00280 throttle_pid_->Clear();
00281 }