$search
00001 /* 00002 * Navigator stop controller 00003 * 00004 * Copyright (C) 2007, 2010, Austin Robot Technology 00005 * License: Modified BSD Software License Agreement 00006 * 00007 * $Id: stop.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 "navigator_internal.h" 00014 #include "Controller.h" 00015 #include "stop.h" 00016 00043 Stop::Stop(Navigator *navptr, int _verbose): 00044 Controller(navptr, _verbose) 00045 { 00046 reset(); 00047 }; 00048 00049 Stop::~Stop() {}; 00050 00051 Controller::result_t Stop::control(pilot_command_t &pcmd) 00052 { 00053 ART_ERROR("Stop::control() requires a float distance parameter,"); 00054 ART_ERROR(" regular control() interface not supported."); 00055 return NotApplicable; 00056 } 00057 00069 Controller::result_t Stop::control(pilot_command_t &pcmd, 00070 float distance, 00071 float threshold, 00072 float topspeed) 00073 { 00074 result_t result = OK; 00075 00076 // stop_latency compensates for latency in the braking system. 00077 float abs_speed = fabsf(estimate->twist.twist.linear.x); 00078 float latencydist = abs_speed * config_->stop_latency; 00079 float D = distance - latencydist; 00080 00081 // According to the model, deceleration should be constant, but in 00082 // the real world latency will cause it to vary, so apply feedback 00083 // and recompute the model every cycle. 00084 if (abs_speed < Epsilon::speed) 00085 abs_speed = 0.0; 00086 00087 float V = -abs_speed; 00088 float A = V*V/(2.0*D); 00089 00090 // see if it is time to begin stopping 00091 if ((D <= config_->min_stop_distance || A >= config_->stop_deceleration) 00092 && !stopping) 00093 { 00094 stopping = true; 00095 initial_speed = fmaxf(topspeed,abs_speed); 00096 if (verbose) 00097 ART_MSG(2, "begin stopping while %.3fm distant", distance); 00098 } 00099 00100 // Once stopping is initiated, keep doing it until reset(), no 00101 // matter how V changes. 00102 if (stopping) 00103 { 00104 00105 if (D <= threshold) 00106 { 00107 pcmd.velocity = 0.0; // halt immediately. 00108 00109 // report Finished when stopped within stop polygon 00110 if (abs_speed < Epsilon::speed) 00111 result = Finished; 00112 } 00113 else if (!creeping && abs_speed >= Epsilon::speed) 00114 { 00115 // Not there yet. Do not let the requested speed increase 00116 // above initial speed when stopping began, even when the 00117 // car was accelerating. 00118 pcmd.velocity = fminf(pcmd.velocity, abs_speed - A); 00119 pcmd.velocity = fminf(pcmd.velocity, initial_speed); 00120 if (pcmd.velocity < 0.0) 00121 pcmd.velocity = 0.0; // do not change direction 00122 } 00123 else if (D <= config_->max_creep_distance) 00124 { 00125 if (!creeping && verbose) 00126 ART_MSG(2, "begin creeping while %.3fm distant", distance); 00127 creeping = true; 00128 // stopped too soon, keep creeping forward 00129 pcmd.velocity = fminf(pcmd.velocity, config_->stop_creep_speed); 00130 } 00131 00132 if (verbose >= 2) 00133 { 00134 ART_MSG(5, "current, desired speed %.3f m/s, %.3f, decel %.3f m/s/s", 00135 abs_speed, pcmd.velocity, A); 00136 ART_MSG(5, "distance %.3f m, threshold %.3f, latency %.3f", 00137 distance, threshold, latencydist); 00138 } 00139 } 00140 00141 trace("stop controller", pcmd, result); 00142 return result; 00143 }; 00144 00145 // reset controller 00146 void Stop::reset(void) 00147 { 00148 stopping = false; 00149 creeping = false; 00150 initial_speed = 0.0; 00151 };