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 pilot_command_t incmd = pcmd;
00148
00149
00150 way_type_t wtype = approaching_waypoint_type(course->stop_waypt);
00151
00152
00153
00154 bool in_intersection = (!course->same_lane(order->waypt[0].id,
00155 order->waypt[1].id)
00156 || order->waypt[0].is_stop);
00157
00158
00159 if (course->in_lane(MapPose(estimate->pose.pose)))
00160 {
00161 if (in_intersection)
00162 {
00163 ROS_DEBUG("Cross intersection to waypoint %s (%s ahead)",
00164 ElementID(order->waypt[1].id).name().str,
00165 way_table[wtype].name);
00166
00167
00168 }
00169 else
00170 {
00171 ROS_DEBUG("Follow lane to waypoint %s (%s ahead)",
00172 ElementID(order->waypt[1].id).name().str,
00173 way_table[wtype].name);
00174
00175
00176 course->turn_signals_off();
00177 }
00178
00179
00180 course->find_travel_lane(false);
00181 }
00182 else
00183 {
00184
00185 ROS_DEBUG("Go to lane containing waypoint %s (%s ahead)",
00186 ElementID(order->waypt[1].id).name().str,
00187 way_table[wtype].name);
00188
00189
00190 course->find_travel_lane(true);
00191 }
00192
00193
00194 if (course->plan.empty())
00195 nav->reduce_speed_with_min(pcmd, config_->lost_speed);
00196
00197 bool in_safety_area = (in_intersection
00198 || stop_area->control(pcmd) == OK);
00199
00200
00201 result_t result = follow_safely->control(pcmd);
00202
00203
00204 slow_for_curves->control(pcmd);
00205
00206 if (in_safety_area)
00207 {
00208
00209
00210 if (result == Blocked)
00211 {
00212
00213 if (!in_intersection)
00214 {
00215
00216
00217
00218
00219 obstacle->blocked();
00220
00221 }
00222
00223 result = Unsafe;
00224 }
00225 else if (result == Collision)
00226 result = Unsafe;
00227 }
00228
00229 if (way_table[wtype].do_stop)
00230 {
00231 result_t stop_result = stop_line->control(pcmd);
00232 if (stop_result == Finished)
00233 result = stop_result;
00234 }
00235
00236
00237 course->desired_heading(pcmd);
00238
00239
00240 course->lane_waypoint_reached();
00241
00242 #if 0 // not doing avoid right now
00243 if (result == OK)
00244 {
00245 result = avoid->control(pcmd, incmd);
00246 if (result == Blocked)
00247 result = Unsafe;
00248 }
00249 #endif // not doing avoid right now
00250
00251 trace("follow_lane controller", pcmd, result);
00252
00253 return result;
00254 };
00255
00256
00257 void FollowLane::reset(void)
00258 {
00259 trace_reset("FollowLane");
00260 reset_me();
00261
00262 follow_safely->reset();
00263 slow_for_curves->reset();
00264 stop_area->reset();
00265 stop_line->reset();
00266 }
00267
00268
00269 void FollowLane::reset_me(void)
00270 {
00271 navdata->reverse = false;
00272 }