00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <art_msgs/ArtVehicle.h>
00011 using art_msgs::ArtVehicle;
00012
00013 #include <art/DARPA_rules.h>
00014 #include "navigator_internal.h"
00015 #include "Controller.h"
00016 #include "course.h"
00017 #include "stop_line.h"
00018
00042 StopLine::StopLine(Navigator *navptr, int _verbose):
00043 Controller(navptr, _verbose)
00044 {
00045 reset_me();
00046 };
00047
00048 StopLine::~StopLine() {};
00049
00063 Controller::result_t StopLine::control(pilot_command_t &pcmd,
00064 float topspeed)
00065 {
00066 result_t result = OK;
00067
00068
00069 float wayptdist =
00070 (Euclidean::DistanceToWaypt(MapPose(estimate->pose.pose),
00071 course->stop_waypt)
00072 - ArtVehicle::front_bumper_px + config_->stop_distance);
00073
00074 float abs_speed = fabsf(estimate->twist.twist.linear.x);
00075 float latencydist = abs_speed * config_->stop_latency;
00076 float D = wayptdist - latencydist;
00077
00078
00079
00080
00081 if (abs_speed < Epsilon::speed)
00082 abs_speed = 0.0;
00083
00084 float V = -abs_speed;
00085 float A = V*V/(2.0*D);
00086 ElementID stop_id = course->stop_waypt.id;
00087
00088
00089 if ((D <= config_->min_stop_distance || A >= config_->stop_deceleration)
00090 && !stopping)
00091 {
00092 stopping = true;
00093 initial_speed = fmaxf(topspeed,abs_speed);
00094 ART_MSG(8, "begin stopping for waypoint %s",
00095 stop_id.name().str);
00096 }
00097
00098
00099
00100 if (stopping)
00101 {
00102
00103
00104 Polar front_bumper(0.0, ArtVehicle::front_bumper_px);
00105
00106 if (D <= config_->stop_distance ||
00107 pops->pointInPoly(front_bumper, MapPose(estimate->pose.pose),
00108 course->stop_poly))
00109 {
00110 pcmd.velocity = 0.0;
00111
00112
00113 if (abs_speed < Epsilon::speed)
00114 {
00115
00116 course->new_waypoint_reached(stop_id);
00117 course->stop_waypt.id = ElementID();
00118 result = Finished;
00119 }
00120 }
00121 else if (!creeping && abs_speed >= Epsilon::speed)
00122 {
00123
00124
00125
00126 pcmd.velocity = fminf(pcmd.velocity, abs_speed - A);
00127 pcmd.velocity = fminf(pcmd.velocity, initial_speed);
00128 if (pcmd.velocity < 0.0)
00129 pcmd.velocity = 0.0;
00130 }
00131 else if (D <= config_->max_creep_distance)
00132 {
00133 creeping=true;
00134
00135 pcmd.velocity = fminf(pcmd.velocity, config_->stop_creep_speed);
00136 }
00137
00138 if (verbose >= 2)
00139 {
00140 ART_MSG(8, "stop %.3f m away for waypoint %s (%.3f,%.3f),"
00141 " %.3f m latency",
00142 wayptdist - config_->stop_distance, stop_id.name().str,
00143 course->stop_waypt.map.x, course->stop_waypt.map.y,
00144 latencydist);
00145 ART_MSG(8, "current, desired speed %.3f m/s, %.3f m/s,"
00146 " decel %.3f m/s/s",
00147 abs_speed, pcmd.velocity, A);
00148 }
00149 }
00150
00151 trace("stop_line controller", pcmd, result);
00152 return result;
00153 };
00154
00155
00156 void StopLine::reset(void)
00157 {
00158 trace_reset("StopLine");
00159 reset_me();
00160 };
00161
00162
00163 void StopLine::reset_me(void)
00164 {
00165 stopping = false;
00166 creeping = false;
00167 initial_speed = 0.0;
00168 };