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 }