stop_line.cc
Go to the documentation of this file.
00001 /*
00002  *  Navigator stop line controller
00003  *
00004  *  Copyright (C) 2007, 2010, Austin Robot Technology
00005  *  License: Modified BSD Software License Agreement
00006  *
00007  *  $Id: stop_line.cc 872 2010-11-28 13:31:07Z jack.oquin $
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   // distance from front bumper to stop way-point
00069   float wayptdist =
00070     (Euclidean::DistanceToWaypt(MapPose(estimate->pose.pose),
00071                                 course->stop_waypt)
00072      - ArtVehicle::front_bumper_px + config_->stop_distance);
00073   // stop_latency compensates for latency in the braking system.
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   // According to the model, deceleration should be constant, but in
00079   // the real world control latency will cause it to vary, so apply
00080   // feedback and recompute the model every cycle.
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   // see if it is time to begin stopping
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   // Once stopping is initiated, keep doing it until reset(), no
00099   // matter how V changes.
00100   if (stopping)
00101     {
00102 
00103       // check whether front bumper is within stop way-point polygon
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;          // halt immediately.
00111 
00112           // report Finished when stopped within stop polygon
00113           if (abs_speed < Epsilon::speed)
00114             {
00115               // Consider this way-point "reached".
00116               course->new_waypoint_reached(stop_id);
00117               course->stop_waypt.id = ElementID(); // reset way-point
00118               result = Finished;
00119             }
00120         }
00121       else if (!creeping && abs_speed >= Epsilon::speed)
00122         {
00123           // Not there yet.  Do not let the requested speed increase
00124           // above initial speed when stopping began, even when the
00125           // car was accelerating.
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;        // do not change direction
00130         }
00131       else if (D <= config_->max_creep_distance)
00132         {
00133           creeping=true;
00134           // stopped too soon, keep creeping forward
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 // reset controller and any subordinates
00156 void StopLine::reset(void)
00157 {
00158   trace_reset("StopLine");
00159   reset_me();
00160 };
00161 
00162 // reset this controller only
00163 void StopLine::reset_me(void)
00164 {
00165   stopping = false;
00166   creeping = false;
00167   initial_speed = 0.0;
00168 };


art_nav
Author(s): Austin Robot Technology, Jack O'Quin
autogenerated on Fri Jan 3 2014 11:08:43