Navigation.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00010 #include "Navigation.h"
00011 #include "PathType.h"
00012 #include<math.h>
00013 
00014 // Module specification
00015 // <rtc-template block="module_spec">
00016 static const char* navigation_spec[] =
00017   {
00018     "implementation_id", "Navigation",
00019     "type_name",         "Navigation",
00020     "description",       "compornent",
00021     "version",           "1.0",
00022     "vendor",            "MyName",
00023     "category",          "example",
00024     "activity_type",     "DataFlowComponent",
00025     "max_instance",      "10",
00026     "language",          "C++",
00027     "lang_type",         "compile",
00028     // Configuration variables
00029     "conf.default.judge_radius", "0.5",
00030     "conf.default.max_vel", "0.3",
00031 
00032     ""
00033   };
00034 // </rtc-template>
00035 
00036 
00037 enum{
00038   FINISH = 0,
00039   ANGLE_CHECK,
00040   TURNING,
00041   TURNING2,
00042   GOAL_CHECK,
00043   SPEED_DOWN,
00044   STOPPING
00045 };
00046 
00047 Navigation::Navigation(RTC::Manager* manager)
00048   : RTC::DataFlowComponentBase(manager),
00049     // <rtc-template block="initializer">
00050     m_positionIn("position", m_position),
00051     m_min_pathIn("min_path", m_min_path),
00052     m_pathOut("path", m_path),
00053     // add:s 2010.08.17 by rtc-center
00054     m_statusOut("status", m_status),
00055     // add:e 2010.08.17 by rtc-center
00056     // </rtc-template>
00057         dummy(0)
00058 {
00059   // Registration: InPort/OutPort/Service
00060   // <rtc-template block="registration">
00061   // Set InPort buffers
00062   registerInPort("position", m_positionIn);
00063   registerInPort("min_path", m_min_pathIn);
00064   
00065   // Set OutPort buffer
00066   registerOutPort("path", m_pathOut);
00067   // add:s 2010.08.17 by rtc-center
00068   registerOutPort("status", m_statusOut);
00069   // add:e 2010.08.17 by rtc-center
00070 }
00071 
00072 Navigation::~Navigation()
00073 {
00074 }
00075 
00076 
00077 RTC::ReturnCode_t Navigation::onInitialize()
00078 {
00079   bindParameter("judge_radius", m_judge_radius, "0.5");
00080   bindParameter("max_vel", m_max_vel, "0.3");
00081 
00082   printf("Navigation Component ver.0.1\n Initialised\n\n");  
00083   // </rtc-template>
00084   return RTC::RTC_OK;
00085 }
00086 
00087 
00088 
00089 RTC::ReturnCode_t Navigation::onActivated(RTC::UniqueId ec_id)
00090 {
00091     return RTC::RTC_OK;
00092 }
00093 
00094 double angle_diff(double theta, double target){
00095   double theta_diff;
00096   theta_diff = theta-target;
00097 
00098   while(theta_diff < -M_PI)theta_diff+=2*M_PI;
00099   while(theta_diff > M_PI)theta_diff-=2*M_PI;
00100 
00101   return fabs(theta_diff);
00102 }
00103 
00104 double distance(double x, double y, double tx,double ty){
00105   return sqrt((x-tx)*(x-tx)+(y-ty)*(y-ty));
00106 }
00107 
00108 double over_line(double x,double y, double tx, double ty,double ttheta){
00109   double rx,ry;
00110 
00111   rx = (x-tx)*cos(-ttheta)-(y-ty)*sin(-ttheta);
00112   ry = (x-tx)*sin(-ttheta)+(y-ty)*cos(-ttheta);
00113 
00114   return rx;
00115 }
00116 
00117 RTC::ReturnCode_t Navigation::onExecute(RTC::UniqueId ec_id)
00118 {
00119 int i;
00120 
00121 
00122  if(!m_min_pathIn.isEmpty()){
00123    while(!m_min_pathIn.isEmpty())
00124      m_min_pathIn.read();
00125    
00126     path_num = m_min_path.pose.length();
00127     state = ANGLE_CHECK;
00128     current_id = -1;//H.T 20100824
00129                 for(i = 0;i < path_num;i++){
00130       printf("%d %f %f %f\n",i, 
00131              m_min_path.pose[i].position.x,
00132              m_min_path.pose[i].position.y,
00133              m_min_path.pose[i].heading);
00134     }
00135   }
00136 
00137   // H.T 20100824 現在位置・姿勢をもとにパスの初期点を設定し直す.
00138         // 現状ではm_positionInに位置情報が来ない限り動作が始まらないことになっている.
00139   if(current_id == -1){
00140     while(!m_positionIn.isEmpty())
00141       m_positionIn.read();
00142                 m_min_path.pose[0].position.x = m_position.data.position.x;
00143                 m_min_path.pose[0].position.y = m_position.data.position.y;
00144                 m_min_path.pose[0].heading = m_position.data.heading;
00145                 current_id = 0;
00146         }
00147 
00148   /*If odometry is updated*/
00149   if(!m_positionIn.isEmpty()){
00150     while(!m_positionIn.isEmpty())
00151       m_positionIn.read();
00152 
00153         
00154     switch(state){
00155     case ANGLE_CHECK:
00156       if(current_id != path_num-1){
00157                                 if(angle_diff(m_min_path.pose[current_id].heading,m_position.data.heading)> M_PI/6
00158                                          /*&& current_id != 0*/){
00159                                         m_path.type = RUN_SPIN;
00160                                         m_path.theta = m_min_path.pose[current_id].heading;
00161                                         m_path.w = 1;
00162                                         m_pathOut.write();
00163                                         state = TURNING;
00164                                         printf("%d turn\n",current_id);
00165                                 }else{
00166                                         state = GOAL_CHECK;
00167                                         printf("%d no turn\n",current_id);
00168                                 }
00169       }else{/*last*/
00170         m_path.type = RUN_SPIN;
00171         m_path.theta = m_min_path.pose[current_id].heading;
00172         m_path.w = 1;
00173         m_pathOut.write();
00174 
00175         state = TURNING2;
00176       }
00177       break;
00178 
00179     case TURNING:
00180       if(angle_diff(m_min_path.pose[current_id].heading,m_position.data.heading)< M_PI/20){
00181         printf("%d turned\n",current_id);
00182 
00183         state = GOAL_CHECK;
00184       }
00185       break;
00186 
00187     case TURNING2:
00188       if(angle_diff(m_min_path.pose[current_id].heading,m_position.data.heading)< 0.02){
00189         m_path.type = RUN_STOP;
00190         m_pathOut.write();
00191         state = FINISH;
00192 
00193         printf("%d goal\n",current_id);
00194       }
00195       break;
00196 
00197     case GOAL_CHECK:
00198        if(/*1 || */distance(m_min_path.pose[current_id].position.x, //H.T 20100824 1をコメントアウト
00199                         m_min_path.pose[current_id].position.y,
00200                         m_position.data.position.x, m_position.data.position.y)> 0.05){ //H.T 20100825 0.3 -> 0.05
00201         m_path.type = RUN_LINEFOLLOW;
00202         m_path.x = m_min_path.pose[current_id].position.x;
00203         m_path.y = m_min_path.pose[current_id].position.y;
00204         m_path.theta = m_min_path.pose[current_id].heading;
00205         m_path.v = m_max_vel;
00206         m_pathOut.write();
00207         state = SPEED_DOWN;
00208         printf("%d line follow\n",current_id);
00209       } else{
00210         m_path.type = RUN_STOP;
00211         m_pathOut.write();
00212         state = ANGLE_CHECK;
00213         current_id++;
00214       }
00215         break;
00216 
00217     case SPEED_DOWN:
00218       //       if(distance(m_min_path.path_list[current_id].x, m_min_path.path_list[current_id].y,
00219       //         m_position.x, m_position.y)< 1.2){
00220       if(over_line(m_position.data.position.x, m_position.data.position.y,
00221                    m_min_path.pose[current_id].position.x, 
00222                    m_min_path.pose[current_id].position.y,
00223                    m_min_path.pose[current_id].heading)>-m_judge_radius){
00224         m_path.type = RUN_LINEFOLLOW;
00225         m_path.x = m_min_path.pose[current_id].position.x;
00226         m_path.y = m_min_path.pose[current_id].position.y;
00227          m_path.theta = m_min_path.pose[current_id].heading;
00228          m_path.v = 0.1;
00229          m_pathOut.write();
00230          state = STOPPING;
00231          printf("%d stopping\n",current_id);
00232       }
00233       break;
00234 
00235     case STOPPING:
00236         if(over_line(m_position.data.position.x,m_position.data.position.y,
00237                      m_min_path.pose[current_id].position.x, 
00238                      m_min_path.pose[current_id].position.y,
00239                      m_min_path.pose[current_id].heading)>0){
00240           
00241         m_path.type = RUN_STOP;
00242         m_pathOut.write();
00243         state = ANGLE_CHECK;
00244         current_id++;
00245         printf("%d stop\n",current_id);
00246       }else{
00247         printf("%d reach %f\n",current_id,distance(m_min_path.pose[current_id].position.x, m_min_path.pose[current_id].position.y,
00248                   m_position.data.position.x, m_position.data.position.y));    
00249       }
00250       break;
00251 
00252     case FINISH:
00253 
00254       break;
00255     }
00256     //    printf(".\n");
00257   }
00258 
00259   //add:s 2010.08.17 by rtc-center
00260   m_status.data = state;
00261   m_statusOut.write();
00262   //add:e 2010.08.17 by rtc-center
00263 
00264   return RTC::RTC_OK;
00265 }
00266 
00267 
00268 extern "C"
00269 {
00270 
00271   void NavigationInit(RTC::Manager* manager)
00272   {
00273     RTC::Properties profile(navigation_spec);
00274     manager->registerFactory(profile,
00275                              RTC::Create<Navigation>,
00276                              RTC::Delete<Navigation>);
00277   }
00278 
00279 };
00280 
00281 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


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