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 "evade.h"
00015 #include "obstacle.h"
00016 
00017 #include "halt.h"
00018 #include "lane_edge.h"
00019 #include "safety.h"
00020 #include "ntimer.h"
00021 
00022 static const char *state_name[] =
00023   {
00024     "Init",
00025     "Leave",
00026     "Wait",
00027     "Return",
00028   };
00029 
00030 Evade::Evade(Navigator *navptr, int _verbose):
00031   Controller(navptr, _verbose)
00032 {
00033   evade_timer = new NavTimer(nav->cycle);
00034   halt = new Halt(navptr, _verbose);
00035   lane_edge = new LaneEdge(navptr, _verbose);
00036   safety = new Safety(navptr, verbose);
00037   reset_me();
00038 }
00039 
00040 Evade::~Evade()
00041 {
00042   delete evade_timer;
00043   delete halt;
00044   delete lane_edge;
00045   delete safety;
00046 }
00047 
00048 void Evade::configure()
00049 {
00050   evade_delay = cf->ReadFloat(section, "evade_delay", 7.0);
00051   ART_MSG(2, "\tevade delay is %.1f seconds", evade_delay);
00052 
00053   evade_offset_ratio = cf->ReadFloat(section, "evade_offset_ratio", -2.0);
00054   ART_MSG(2, "\tevade offset ratio is %.3f", evade_offset_ratio);
00055 
00056   evasion_speed = cf->ReadFloat(section, "evasion_speed", 3.0);
00057   ART_MSG(2, "\tevasion speed is %.1f m/s", evasion_speed);
00058 
00059   halt->configure(cf, section);
00060   lane_edge->configure(cf, section);
00061   safety->configure(cf, section);
00062 }
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 Controller::result_t Evade::control(pilot_command_t &pcmd)
00072 {
00073   result_t result = Blocked;
00074 
00075   if (verbose >= 4)
00076     ART_MSG(2, "Evade state is %s", state_name[state]);
00077 
00078   switch (state)
00079     {
00080     case Init:
00081       
00082       if (verbose)
00083         ART_MSG(1, "Begin emergency obstacle evasion");
00084       course->turn_signal_on(false);    
00085       set_state(Leave);
00086       
00087 
00088     case Leave:
00089       if (course->in_lane(estimate->pos))       
00090         {
00091           
00092           if (obstacle->car_approaching())
00093             {
00094               result = leave_lane_right(pcmd);
00095             }
00096           else
00097             {
00098               if (verbose)
00099                 ART_MSG(1, "No longer need to evade approaching car");
00100               halt->control(pcmd);
00101               course->turn_signal_on(true); 
00102               result = Finished;
00103             }
00104           break;                        
00105         }
00106 
00107       if (verbose)
00108         ART_MSG(1, "Left travel lane while evading");
00109       set_state(Wait);
00110       
00111       
00112       course->turn_signals_both_on();
00113       evade_timer->Start(evade_delay);
00114       
00115 
00116     case Wait:
00117       
00118       result = halt->control(pcmd);
00119       if (evade_timer->Check())         
00120         {
00121           if (verbose)
00122             ART_MSG(1, "Emergency obstacle evasion timeout");
00123           course->turn_signal_on(true); 
00124           set_state(Return);
00125         }
00126       break;
00127 
00128     case Return:
00129       
00130       evade_timer->Cancel();
00131       halt->control(pcmd);
00132 
00133       
00134       
00135       if (obstacle->car_approaching())
00136         result = OK;
00137       else
00138         result = Finished;
00139       break;
00140     }
00141 
00142   
00143   course->lane_waypoint_reached();
00144 
00145   if (result == Blocked)
00146     result = Unsafe;                    
00147 
00148   trace("evade controller", pcmd, result);
00149   return result;
00150 }
00151 
00152 
00153 
00154 
00155 Controller::result_t Evade::leave_lane_right(pilot_command_t &pcmd)
00156 {
00157   
00158   pcmd.velocity = fminf(pcmd.velocity, evasion_speed);
00159 
00160   result_t result = Unsafe;
00161   if (obstacle->observer_clear(ObserverID::Adjacent_right))
00162     {
00163       result = lane_edge->control(pcmd, evade_offset_ratio);
00164       if (result < Unsafe)
00165         {
00166           
00167           if (verbose >= 2)
00168             ART_MSG(5, "leaving lane to right");
00169         }
00170     }
00171   else if (verbose >= 2)
00172     ART_MSG(5, "right lane blocked, not heading for that lane");
00173   return result;
00174 }
00175 
00176 
00177 void Evade::reset(void)
00178 {
00179   trace_reset("Evade");
00180   reset_me();
00181   halt->reset();
00182   lane_edge->reset();
00183   safety->reset();
00184 }
00185 
00186 
00187 void Evade::reset_me(void)
00188 {
00189   evade_timer->Cancel();
00190   state = Init;
00191 }
00192 
00193 
00194 void Evade::set_state(state_t newstate)
00195 {
00196   if (state != newstate)
00197     {
00198       if (verbose)
00199         ART_MSG(4, "Evade state changing from %s to %s",
00200                 state_name[state], state_name[newstate]);
00201       state = newstate;
00202     }
00203 }