00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <art/infinity.h>
00012
00013
00014 #include "navigator_internal.h"
00015 #include "course.h"
00016 #include "obstacle.h"
00017
00018
00019 Obstacle::Obstacle(Navigator *_nav, int _verbose)
00020 {
00021 verbose = _verbose;
00022 nav = _nav;
00023
00024
00025 course = nav->course;
00026 estimate = &nav->estimate;
00027 navdata = &nav->navdata;
00028 odom = nav->odometry;
00029 order = &nav->order;
00030 pops = nav->pops;
00031 config_ = &nav->config_;
00032
00033
00034 max_range = 80.0;
00035
00036
00037
00038 obstate.obs.resize(Observers::N_Observers);
00039 prev_obstate.obs.resize(Observers::N_Observers);
00040 for (unsigned i = 0; i < Observers::N_Observers; ++i)
00041 {
00042 obstate.obs[i].clear = true;
00043 obstate.obs[i].applicable = true;
00044 }
00045
00046
00047 blockage_timer = new NavTimer();
00048 was_stopped = false;
00049
00050 reset();
00051 }
00052
00053
00054
00055
00056
00057 bool Obstacle::car_approaching()
00058 {
00059 if (config_->offensive_driving)
00060 return false;
00061
00062 Observation::_oid_type oid = Observers::Nearest_forward;
00063 if (obstate.obs[oid].clear || !obstate.obs[oid].applicable)
00064 {
00065 if (verbose >= 4)
00066 ART_MSG(6, "no known car approaching from ahead");
00067 return false;
00068 }
00069
00070
00071
00072 float rel_speed = obstate.obs[oid].velocity;
00073 float abs_speed = rel_speed - obstate.odom.twist.twist.linear.x;
00074
00075 if (verbose >= 3)
00076 ART_MSG(6, "obstacle observed closing at %.3fm/s, absolute speed %.3f",
00077 rel_speed, abs_speed);
00078
00079 return (abs_speed > config_->min_approach_speed);
00080 }
00081
00082
00083
00084
00085
00086
00087 float Obstacle::closest_ahead_in_plan(void)
00088 {
00089
00090 float retval = Infinite::distance;
00091
00092 #if 0 // ignoring obstacles at the moment
00093
00094 int closest_poly_index = pops->getClosestPoly(course->plan, estimate->pos);
00095 if (closest_poly_index < 0)
00096 {
00097 if (verbose)
00098 ART_MSG(2, "no closest polygon in lane (size %u)",
00099 course->plan.size());
00100 return retval;
00101 }
00102
00103
00104
00105 if (course->aim_poly.poly_id != -1)
00106 {
00107 int aim_index = pops->getPolyIndex(course->plan, course->aim_poly);
00108 if (aim_index >=0 && aim_index < (int) course->plan.size())
00109 closest_poly_index = aim_index;
00110 }
00111
00112 for (uint i=0; i< lasers->all_obstacle_list.size(); i++)
00113 if (in_lane(lasers->all_obstacle_list.at(i),
00114 course->plan, closest_poly_index))
00115 {
00116 if (verbose >4)
00117 ART_MSG(3,"Saw obstacle in lane: obstacle list size %d (velodyne %d, fusion %d) at index %d",lasers->all_obstacle_list.size(), lasers->velodyne_obstacle_list.size(),lasers->fusion_obstacle_list.size(), i);
00118
00119 float distance = course->distance_in_plan(estimate->pos,
00120 lasers->all_obstacle_list.at(i));
00121
00122 if (distance > 0 && distance < retval)
00123 {
00124 retval = distance;
00125 }
00126 }
00127
00128 if (verbose >= 3)
00129 ART_MSG(8, "Closest obstacle in lane %s is %.3f m down the lane",
00130 course->plan.at(closest_poly_index).start_way.lane_name().str,
00131 retval);
00132 #endif // ignoring obstacles
00133
00134 return retval;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 void Obstacle::closest_in_lane(const poly_list_t &lane,
00147 float &ahead, float &behind)
00148 {
00149
00150 ahead = Infinite::distance;
00151 behind = Infinite::distance;
00152
00153 int closest_poly_index =
00154 pops->getClosestPoly(lane, MapPose(estimate->pose.pose));
00155 if (lane.empty() || closest_poly_index < 0)
00156 {
00157 ROS_DEBUG_STREAM("no closest polygon in lane (size "
00158 << lane.size() << ")");
00159 return;
00160 }
00161
00162 #if 0 // ignoring obstacles at the moment
00163
00164 for (uint i=0; i< lasers->all_obstacle_list.size(); i++)
00165 if (in_lane(lasers->all_obstacle_list.at(i), lane, 0))
00166 {
00167 float distance = pops->distanceAlongLane(lane, estimate->pos,
00168 lasers->all_obstacle_list.at(i));
00169 if (distance < 0)
00170 behind = fminf(behind, -distance);
00171 else
00172 ahead = fminf(ahead, distance);
00173 }
00174
00175 #endif // ignoring obstacles at the moment
00176
00177 ROS_DEBUG("Closest obstacles in lane %s are %.3fm ahead and %.3fm behind",
00178 lane.at(closest_poly_index).start_way.lane_name().str,
00179 ahead, behind);
00180 }
00181
00182
00183 bool Obstacle::in_lane(MapXY location, const poly_list_t &lane,
00184 int start_index)
00185 {
00186 start_index=std::max(0,start_index);
00187 start_index=std::min(start_index, int(lane.size()-1));
00188
00189 poly in_poly= lane.at(start_index);
00190
00191
00192 for (unsigned j = start_index; j < lane.size(); j++)
00193 {
00194 poly curPoly = lane[j];
00195 if (pops->pointInPoly_ratio(location, curPoly, config_->lane_width_ratio))
00196 {
00197
00198 if (verbose >= 5)
00199 {
00200 ART_MSG(8, "obstacle at (%.3f, %.3f) is in lane %s, polygon %d",
00201 location.x, location.y,
00202 in_poly.start_way.lane_name().str, curPoly.poly_id);
00203 }
00204 return true;
00205 }
00206 }
00207
00208 if (verbose >= 6)
00209 ART_MSG(8, "obstacle at (%.3f, %.3f) is outside our lane",
00210 location.x, location.y);
00211
00212 return false;
00213 }
00214
00215
00216
00217
00218
00219
00220 void Obstacle::observers_message(Observers *obs_msg)
00221 {
00222 if (obs_msg->obs.size() != Observers::N_Observers)
00223 {
00224
00225 ROS_ERROR_STREAM("ERROR: Observer message size (" << obs_msg->obs.size()
00226 << ") is wrong (ignored)");
00227 return;
00228 }
00229
00230 if (obstate.header.stamp == obs_msg->header.stamp)
00231 return;
00232
00233 prev_obstate = obstate;
00234 obstate = *obs_msg;
00235
00236 if (verbose >= 2)
00237 {
00238 char clear_string[Observers::N_Observers+1];
00239 for (unsigned i = 0; i < Observers::N_Observers; ++i)
00240 {
00241 clear_string[i] = (obstate.obs[i].clear? '1': '0');
00242 if (obstate.obs[i].applicable)
00243 clear_string[i] += 2;
00244 }
00245 clear_string[Observers::N_Observers] = '\0';
00246 ROS_DEBUG("observers report {%s}, pose (%.3f,%.3f,%.3f), "
00247 "(%.3f, %.3f), time %.6f",
00248 clear_string,
00249 obstate.odom.pose.pose.position.x,
00250 obstate.odom.pose.pose.position.y,
00251 tf::getYaw(obstate.odom.pose.pose.orientation),
00252 obstate.odom.twist.twist.linear.x,
00253 obstate.odom.twist.twist.angular.z,
00254 obstate.header.stamp.toSec());
00255 }
00256 }
00257
00258
00259 bool Obstacle::passing_lane_clear(void)
00260 {
00261 if (course->passing_left)
00262 return observer_clear(Observers::Adjacent_left);
00263 else
00264 return observer_clear(Observers::Adjacent_right);
00265 }
00266
00267
00268 void Obstacle::reset(void)
00269 {
00270 unblocked();
00271 }