Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 #include "navigator_internal.h"
00012 #include "Controller.h"
00013 #include "course.h"
00014 #include "obstacle.h"
00015 #include "follow_lane.h"
00016 
00017 #include "avoid.h"
00018 #include "follow_safely.h"
00019 #include "slow_for_curves.h"
00020 #include "stop_area.h"
00021 #include "stop_line.h"
00022 
00023 typedef struct
00024 {
00025   const char *name;
00026   bool  do_stop;
00027 } way_table_t;
00028   
00029 static const way_table_t way_table[] =
00030   {
00031     {"Lane", false},
00032     {"LaneChange", true},
00033     {"Merge", true},
00034     {"Stop", true},
00035     {"Uturn", true},
00036     {"Zone", false},    
00037     {"ZoneExit", true}, 
00038   };
00039 
00040 
00041 
00042 
00043 
00044 FollowLane::way_type_t
00045 FollowLane::approaching_waypoint_type(WayPointNode &stop_point)
00046 {
00047   way_type_t wtype = Lane;
00048   unsigned i = 0;
00049   while (++i < Order::N_WAYPTS)
00050     {
00051       
00052       if (!course->same_lane(order->waypt[1].id, order->waypt[i].id))
00053         break;
00054       if (order->waypt[i].is_perimeter &&
00055           order->waypt[i].is_exit)
00056         {
00057           wtype = ZoneExit;
00058           break;
00059         }
00060       else if (order->waypt[i].is_perimeter)
00061         {
00062           wtype = Zone;
00063           break;
00064         }
00065       else if (order->waypt[i].is_stop)
00066         {
00067           wtype = Stop;
00068           break;
00069         }
00070       else if (course->uturn_waypt(i))
00071         {
00072           wtype = Uturn;
00073           break;
00074         }
00075       else if (order->waypt[i].is_lane_change)
00076         {
00077           wtype = LaneChange;
00078           break;
00079         }
00080       else if (order->waypt[i].is_exit
00081                && i+1 < Order::N_WAYPTS
00082                && order->waypt[i+1].is_entry
00083                && !course->same_lane(order->waypt[i].id,
00084                                      order->waypt[i+1].id))
00085         {
00086           if (course->nqe_special(i,i+1))
00087             ART_MSG(3, "Not going to merge for special case");
00088           else
00089             {
00090               
00091               
00092               
00093               
00094               
00095               
00096               
00097               
00098               
00099               wtype = Merge;
00100               break;
00101             }
00102         }
00103     }
00104 
00105   if (way_table[wtype].do_stop)
00106     stop_point = order->waypt[i];
00107   else
00108     stop_point.id = ElementID();
00109 
00110   return wtype;
00111 }
00112 
00113 FollowLane::FollowLane(Navigator *navptr, int _verbose):
00114   Controller(navptr, _verbose)
00115 {
00116   
00117   follow_safely = new FollowSafely(navptr, _verbose);
00118   slow_for_curves = new SlowForCurves(navptr, _verbose);
00119   stop_area =   new StopArea(navptr, _verbose);
00120   stop_line =   new StopLine(navptr, _verbose);
00121   reset_me();
00122 };
00123 
00124 FollowLane::~FollowLane()
00125 {
00126   
00127   delete follow_safely;
00128   delete slow_for_curves;
00129   delete stop_area;
00130   delete stop_line;
00131 };
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 Controller::result_t FollowLane::control(pilot_command_t &pcmd)
00142 {
00143   if (order->waypt[1].is_perimeter)
00144     pcmd.velocity=fminf(pcmd.velocity,1.0); 
00145 
00146 
00147 #if 0 // not doing avoid right now
00148   pilot_command_t incmd = pcmd;         
00149 #endif // not doing avoid right now
00150 
00151   
00152   way_type_t wtype = approaching_waypoint_type(course->stop_waypt);
00153 
00154   
00155   
00156   bool in_intersection = (!course->same_lane(order->waypt[0].id,
00157                                              order->waypt[1].id)
00158                           || order->waypt[0].is_stop);
00159 
00160   
00161   if (course->in_lane(MapPose(estimate->pose.pose))) 
00162     {
00163       if (in_intersection)
00164         {
00165           ROS_DEBUG("Cross intersection to waypoint %s (%s ahead)",
00166                     ElementID(order->waypt[1].id).name().str,
00167                     way_table[wtype].name);
00168           
00169           
00170         }
00171       else
00172         {
00173           ROS_DEBUG("Follow lane to waypoint %s (%s ahead)",
00174                     ElementID(order->waypt[1].id).name().str,
00175                     way_table[wtype].name);
00176       
00177           
00178           course->turn_signals_off();
00179         }
00180 
00181       
00182       course->find_travel_lane(false);  
00183     }
00184   else
00185     {
00186       
00187       ROS_DEBUG("Go to lane containing waypoint %s (%s ahead)",
00188                 ElementID(order->waypt[1].id).name().str,
00189                 way_table[wtype].name);
00190 
00191       
00192       course->find_travel_lane(true);   
00193     }
00194 
00195   
00196   if (course->plan.empty())
00197     nav->reduce_speed_with_min(pcmd, config_->lost_speed);
00198 
00199   bool in_safety_area = (in_intersection
00200                          || stop_area->control(pcmd) == OK);
00201 
00202   
00203   result_t result = follow_safely->control(pcmd);
00204 
00205   
00206   slow_for_curves->control(pcmd);
00207 
00208   if (in_safety_area)
00209     {
00210       
00211       
00212       if (result == Blocked)
00213         {
00214           
00215           if (!in_intersection)
00216             {
00217 
00218 
00219 
00220 
00221               obstacle->blocked();
00222 
00223             }
00224           
00225           result = Unsafe;
00226         }
00227       else if (result == Collision)
00228         result = Unsafe;
00229     }
00230   
00231   if (way_table[wtype].do_stop)         
00232     {
00233       result_t stop_result = stop_line->control(pcmd);
00234       if (stop_result == Finished)      
00235         result = stop_result;           
00236     }
00237 
00238   
00239   course->desired_heading(pcmd);
00240 
00241   
00242   course->lane_waypoint_reached();
00243 
00244 #if 0 // not doing avoid right now
00245   if (result == OK)                     
00246     {
00247       result = avoid->control(pcmd, incmd);
00248       if (result == Blocked)
00249         result = Unsafe;                
00250     }
00251 #endif // not doing avoid right now
00252 
00253   trace("follow_lane controller", pcmd, result);
00254 
00255   return result;
00256 };
00257 
00258 
00259 void FollowLane::reset(void)
00260 {
00261   trace_reset("FollowLane");
00262   reset_me();
00263   
00264   follow_safely->reset();
00265   slow_for_curves->reset();
00266   stop_area->reset();
00267   stop_line->reset();
00268 }
00269 
00270 
00271 void FollowLane::reset_me(void)
00272 {
00273   navdata->reverse = false;
00274 }