00001
00002
00003
00004
00005
00006
00007
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
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
00082
00083
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
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
00101
00102 if (stopping)
00103 {
00104
00105 if (D <= threshold)
00106 {
00107 pcmd.velocity = 0.0;
00108
00109
00110 if (abs_speed < Epsilon::speed)
00111 result = Finished;
00112 }
00113 else if (!creeping && abs_speed >= Epsilon::speed)
00114 {
00115
00116
00117
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;
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
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
00146 void Stop::reset(void)
00147 {
00148 stopping = false;
00149 creeping = false;
00150 initial_speed = 0.0;
00151 };