00001
00010 #include "Navigation.h"
00011 #include "PathType.h"
00012 #include<math.h>
00013
00014
00015
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
00029 "conf.default.judge_radius", "0.5",
00030 "conf.default.max_vel", "0.3",
00031
00032 ""
00033 };
00034
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
00050 m_positionIn("position", m_position),
00051 m_min_pathIn("min_path", m_min_path),
00052 m_pathOut("path", m_path),
00053
00054 m_statusOut("status", m_status),
00055
00056
00057 dummy(0)
00058 {
00059
00060
00061
00062 registerInPort("position", m_positionIn);
00063 registerInPort("min_path", m_min_pathIn);
00064
00065
00066 registerOutPort("path", m_pathOut);
00067
00068 registerOutPort("status", m_statusOut);
00069
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
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;
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
00138
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
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 ){
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{
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(distance(m_min_path.pose[current_id].position.x,
00199 m_min_path.pose[current_id].position.y,
00200 m_position.data.position.x, m_position.data.position.y)> 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
00219
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
00257 }
00258
00259
00260 m_status.data = state;
00261 m_statusOut.write();
00262
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