Go to the documentation of this file.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 };