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 }