control.cpp
Go to the documentation of this file.
00001 /*high level I/O*/
00002 #include <stdio.h>
00003 #include <math.h>
00004 #include <unistd.h>
00005 #include <strings.h>
00006 #include <pthread.h>
00007 
00008 /*low level I/O*/
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 /*serial*/
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 /*-PI < theta < PIに調整する*/
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   /*yukkuri*/
00057   /*  if(d > 0.5){
00058     d -= 0.5;
00059   }else if(d < -0.5){
00060     d += 0.5;
00061   }else {
00062     d = 0;
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   /*FF*/
00088   //  if(fabs(r)>0.1 )
00089   //  w += 2*nv / r ; 
00090 
00091   v = v_max;
00092   /*#ifdef UTA //UTA Magic
00093   v_ref.w = (vel.w + v_ref_old.w) / 2.0
00094      - period * (SIGN(r) * SIGN(vel.v) * R.K1 * y + R.K2 * q + R.K3 * vel.w);
00095 #endif
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 /*velocity clippung*/
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(&current, NULL); 
00209   
00210   return  current.tv_sec + current.tv_usec/1000000.0;   
00211 }
00212 
00213 /*追従軌跡に応じた処理*/
00214 //void* PathFollower::run_control(void *){
00215 void PathFollower::path_following(double x,double y,double theta){
00216   static double before_time;
00217   double now_time;
00218 
00219   //  while(do_control){
00220   now_time = get_time();
00221   if(!m_positionIn.isEmpty())m_positionIn.read();
00222   
00223   if(now_time > before_time){/*20ms毎?*/
00224     
00225     /*パラメータの変更がおこらないようにブロック*/
00226     //pthread_mutex_lock(&mutex);
00227     
00228     before_time = now_time;      
00229     
00230     /*走行状態に応じた処理*/
00231     switch(run_mode){
00232     case RUN_STOP://ストップする(スピードを0にする)
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     //pthread_mutex_unlock(&mutex);
00257     
00258   }else{
00259     //    usleep(1000);
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   /*  pthread_mutex_init(&mutex, NULL);
00273   printf("starting control thread.\n");
00274 
00275   if(pthread_create(&run_thread, NULL, run_control, NULL)!= 0){
00276     fprintf(stderr, "Can't create command thread\n");
00277   }
00278   */
00279 }
00280 
00281 
00282 void PathFollower::finalizePathFollower(void){
00283   /*
00284   do_control = 0;
00285   printf("Control thread is stopping.\n");
00286   pthread_join(run_thread, NULL);
00287   */}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


RS003
Author(s):
autogenerated on Thu Jun 27 2013 14:58:49