Go to the documentation of this file.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 using art_msgs::Observation;
00020
00021
00022 Obstacle::Obstacle(Navigator *_nav, int _verbose)
00023 {
00024 verbose = _verbose;
00025 nav = _nav;
00026
00027
00028 course = nav->course;
00029 estimate = &nav->estimate;
00030 navdata = &nav->navdata;
00031 odom = nav->odometry;
00032 order = &nav->order;
00033 pops = nav->pops;
00034 config_ = &nav->config_;
00035
00036
00037 max_range = 80.0;
00038
00039
00040
00041 obstate.obs.resize(Observation::N_Observers);
00042 for (unsigned i = 0; i < Observation::N_Observers; ++i)
00043 {
00044 obstate.obs[i].oid = i;
00045 obstate.obs[i].clear = true;
00046 obstate.obs[i].applicable = true;
00047 }
00048
00049
00050 obstate.obs[Observation::Nearest_forward].applicable = false;
00051
00052
00053 blockage_timer = new NavTimer();
00054 was_stopped = false;
00055
00056 reset();
00057
00058 ros::NodeHandle node;
00059 obs_sub_ = node.subscribe("observations", 10,
00060 &Obstacle::observers_message, this,
00061 ros::TransportHints().tcpNoDelay(true));
00062 }
00063
00064
00065
00066
00067
00068 bool Obstacle::car_approaching()
00069 {
00070 if (config_->offensive_driving)
00071 return false;
00072
00073 Observation::_oid_type oid = Observation::Nearest_forward;
00074 if (obstate.obs[oid].clear || !obstate.obs[oid].applicable)
00075 {
00076 if (verbose >= 4)
00077 ART_MSG(6, "no known car approaching from ahead");
00078 return false;
00079 }
00080
00081
00082
00083 float rel_speed = obstate.obs[oid].velocity;
00084 #if 0
00085
00086 float abs_speed = rel_speed - obstate.odom.twist.twist.linear.x;
00087 #else
00088
00089 float abs_speed = rel_speed - odom->twist.twist.linear.x;
00090 #endif
00091
00092 if (verbose >= 3)
00093 ART_MSG(6, "obstacle observed closing at %.3fm/s, absolute speed %.3f",
00094 rel_speed, abs_speed);
00095
00096 return (abs_speed > config_->min_approach_speed);
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 void Obstacle::closest_in_lane(const poly_list_t &lane,
00109 float &ahead, float &behind)
00110 {
00111
00112 ahead = Infinite::distance;
00113 behind = Infinite::distance;
00114
00115 int closest_poly_index =
00116 pops->getClosestPoly(lane, MapPose(estimate->pose.pose));
00117 if (lane.empty() || closest_poly_index < 0)
00118 {
00119 ROS_DEBUG_STREAM("no closest polygon in lane (size "
00120 << lane.size() << ")");
00121 return;
00122 }
00123
00124 #if 0 // ignoring obstacles at the moment
00125
00126 for (uint i=0; i< lasers->all_obstacle_list.size(); i++)
00127 if (in_lane(lasers->all_obstacle_list.at(i), lane, 0))
00128 {
00129 float distance = pops->distanceAlongLane(lane, estimate->pos,
00130 lasers->all_obstacle_list.at(i));
00131 if (distance < 0)
00132 behind = fminf(behind, -distance);
00133 else
00134 ahead = fminf(ahead, distance);
00135 }
00136
00137 #endif // ignoring obstacles at the moment
00138
00139 ROS_DEBUG("Closest obstacles in lane %s are %.3fm ahead and %.3fm behind",
00140 lane.at(closest_poly_index).start_way.lane_name().str,
00141 ahead, behind);
00142 }
00143
00144
00145 bool Obstacle::in_lane(MapXY location, const poly_list_t &lane,
00146 int start_index)
00147 {
00148 start_index=std::max(0,start_index);
00149 start_index=std::min(start_index, int(lane.size()-1));
00150
00151 poly in_poly= lane.at(start_index);
00152
00153
00154 for (unsigned j = start_index; j < lane.size(); j++)
00155 {
00156 poly curPoly = lane[j];
00157 if (pops->pointInPoly_ratio(location, curPoly, config_->lane_width_ratio))
00158 {
00159
00160 if (verbose >= 5)
00161 {
00162 ART_MSG(8, "obstacle at (%.3f, %.3f) is in lane %s, polygon %d",
00163 location.x, location.y,
00164 in_poly.start_way.lane_name().str, curPoly.poly_id);
00165 }
00166 return true;
00167 }
00168 }
00169
00170 if (verbose >= 6)
00171 ART_MSG(8, "obstacle at (%.3f, %.3f) is outside our lane",
00172 location.x, location.y);
00173
00174 return false;
00175 }
00176
00181 void
00182 Obstacle::observers_message(const art_msgs::ObservationArrayConstPtr obs_msg)
00183 {
00184
00185
00186 obstate.header.stamp = std::max(obstate.header.stamp,
00187 obs_msg->header.stamp);
00188
00189
00190
00191 for (uint32_t i = 0; i < obs_msg->obs.size(); ++i)
00192 {
00193 obstate.obs[obs_msg->obs[i].oid] = obs_msg->obs[i];
00194
00195 }
00196 }
00197
00198
00199 bool Obstacle::passing_lane_clear(void)
00200 {
00201 if (course->passing_left)
00202 return observer_clear(Observation::Adjacent_left);
00203 else
00204 return observer_clear(Observation::Adjacent_right);
00205 }
00206
00207
00208 void Obstacle::reset(void)
00209 {
00210 unblocked();
00211 }