00001
00002 #include <stdio.h>
00003 #include <math.h>
00004 #include <unistd.h>
00005 #include <strings.h>
00006 #include <pthread.h>
00007
00008
00009 #include <fcntl.h>
00010 #include <sys/time.h>
00011 #include <time.h>
00012 #include <sys/types.h>
00013 #include <sys/stat.h>
00014
00015
00016 #include <sys/termios.h>
00017
00018 #include "PathFollower.h"
00019 #include "PathType.h"
00020
00021 #define SIGN(x) ((x < 0) ? -1 : 1)
00022
00023
00024 double trans_q(double theta){
00025 while(theta > M_PI)theta -= 2.0*M_PI;
00026 while(theta < -M_PI)theta += 2.0*M_PI;
00027 return theta;
00028 }
00029
00030
00031 double PathFollower::circle_follow(double x,double y, double theta,
00032 double cx, double cy, double cradius,
00033 double v_max){
00034 double d,q,r,ang;
00035
00036 r = sqrt((x - cx)*(x -cx) +(y -cy)*(y -cy));
00037
00038 ang = atan2((y - cy), (x - cx));
00039 ang = trans_q(ang);
00040
00041
00042 d = fabs(cradius) - r;
00043 q = trans_q(theta - (ang + SIGN(cradius) * (M_PI / 2.0)));
00044
00045 return regurator(d, q, cradius, v_max);
00046 }
00047
00048
00049 double PathFollower::line_follow(double x,double y,double theta,
00050 double cx, double cy, double ctheta,
00051 double v_max){
00052 double d,q;
00053
00054 d = -(x-cx)*sin(ctheta) + (y-cy)*cos(ctheta);
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 q = theta - ctheta;
00066 q = trans_q(q);
00067
00068 return regurator(d, q, 1000000, v_max);
00069 }
00070
00071
00072 double PathFollower::regurator(double d, double q, double r, double v_max){
00073 double nv,nw;
00074 double v,w;
00075 double cd;
00076
00077 nv = target_v;
00078 nw = target_w;
00079 v = v_max - SIGN(v_max) * m_line_C1 * fabs(nw);
00080
00081 cd = d;
00082 if(cd > m_line_Dist)cd = m_line_Dist;
00083 if(cd < - m_line_Dist)cd = - m_line_Dist;
00084 w = nw - m_control_cycle*
00085 (SIGN(r)*SIGN(nv) * m_line_K1*cd + m_line_K2*q + m_line_K3*nw);
00086
00087
00088
00089
00090
00091 v = v_max;
00092
00093
00094
00095
00096
00097
00098 robot_speed_smooth(v, w);
00099 return d;
00100 }
00101
00102
00103 double PathFollower::spin(double theta, double target_theta, double w_max){
00104 double q, w_limit;
00105 double w;
00106
00107 q = target_theta - theta;
00108 q = trans_q(q);
00109
00110
00111 w_limit = sqrt(0.1*2*m_max_acc_w*fabs(q)/m_control_cycle);
00112
00113 if(w_max < w_limit){
00114 w = SIGN(q)*w_max;
00115 }else{
00116 w = SIGN(q)*w_limit;
00117 if(fabs(w) < M_PI/90.0)w = M_PI/90.0*SIGN(q);
00118 }
00119
00120 robot_speed_smooth(0, w);
00121 return fabs(q);
00122 }
00123
00124
00125 double PathFollower::dist_pos(double x,double y, double tx, double ty){
00126 double r;
00127 r = sqrt((x -tx)*(x -tx)+(y -ty)*(y -ty));
00128
00129 return r;
00130 }
00131
00132
00133 int PathFollower::to_point(double x,double y,double theta,
00134 double tx, double ty, double ttheta,double max_vel){
00135 double dist,a ;
00136 double vel;
00137 int over;
00138
00139 dist = dist_pos(x,y, tx, ty);
00140
00141 a = (x -tx)*cos(ttheta) + (y-ty)*sin(ttheta);
00142 over = 0;
00143 if(a > 0){
00144 vel = 0;
00145 over = 3;
00146 }else if(dist > max_vel){
00147 vel = max_vel;
00148 }else if(dist > 0.05){
00149 over = 1;
00150 vel = dist;
00151 }else{
00152 over = 2;
00153 vel = dist;
00154 }
00155
00156 line_follow(x,y,theta, tx,ty,ttheta,vel);
00157 return over;
00158 }
00159
00160
00161 int PathFollower::robot_speed_smooth(double v, double w){
00162 int limit;
00163
00164 limit = 15;
00165
00166 if(v > m_max_v){
00167 v = m_max_v;
00168 }else if(v < -m_max_v){
00169 v = -m_max_v;
00170 }else{
00171 limit -=1;
00172 }
00173
00174 if(v > target_v + m_max_acc_v){
00175 v= target_v+ m_max_acc_v;
00176 }else if(v < target_v - m_max_acc_v){
00177 v= target_v - m_max_acc_v;
00178 }else{
00179 limit-= 2;
00180 }
00181
00182
00183 if(w > m_max_w){
00184 w = m_max_w;
00185 }else if(w < -m_max_w){
00186 w = -m_max_w;
00187 }else{
00188 limit -=4;
00189 }
00190
00191 if(w > target_w + m_max_acc_w){
00192 w= target_w + m_max_acc_w;
00193 }else if(w < target_w - m_max_acc_w){
00194 w= target_w - m_max_acc_w;
00195 }else{
00196 limit -= 8;
00197 }
00198
00199 target_v = v;
00200 target_w = w;
00201
00202 return limit;
00203 }
00204 double get_time(void)
00205 {
00206 struct timeval current;
00207
00208 gettimeofday(¤t, NULL);
00209
00210 return current.tv_sec + current.tv_usec/1000000.0;
00211 }
00212
00213
00214
00215 void PathFollower::path_following(double x,double y,double theta){
00216 static double before_time;
00217 double now_time;
00218
00219
00220 now_time = get_time();
00221 if(!m_positionIn.isEmpty())m_positionIn.read();
00222
00223 if(now_time > before_time){
00224
00225
00226
00227
00228 before_time = now_time;
00229
00230
00231 switch(run_mode){
00232 case RUN_STOP:
00233 robot_speed_smooth(0,0);
00234 break;
00235 case RUN_VEL:
00236 robot_speed_smooth(path_v, path_w);
00237 break;
00238 case RUN_LINEFOLLOW:
00239 line_follow(x,y,theta,
00240 path_x, path_y, path_theta,path_v);
00241 break;
00242 case RUN_TO_POINT:
00243 to_point(x,y,theta,
00244 path_x, path_y, path_theta,path_v);
00245 break;
00246 case RUN_CIRCLEFOLLOW:
00247 circle_follow(x, y, theta,
00248 path_x, path_y, path_d,path_v);
00249 break;
00250 case RUN_SPIN:
00251 spin(theta, path_theta, path_w);
00252 break;
00253 }
00254
00255
00256
00257
00258 }else{
00259
00260 }
00261
00262 }
00263
00264
00265 void PathFollower::initPathFollower(void){
00266 do_control = 1;
00267 run_mode = RUN_STOP;
00268
00269 target_v = 0;
00270 target_w = 0;
00271
00272
00273
00274
00275
00276
00277
00278
00279 }
00280
00281
00282 void PathFollower::finalizePathFollower(void){
00283
00284
00285
00286
00287 }