00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <float.h>
00011
00012 #include <art/epsilon.h>
00013 #include <art/steering.h>
00014 #include <art_map/coordinates.h>
00015
00016 #include "navigator_internal.h"
00017 #include "Controller.h"
00018 #include "course.h"
00019 #include "slow_for_curves.h"
00020
00021 Controller::result_t SlowForCurves::control(pilot_command_t &pcmd)
00022 {
00023
00024 if (pcmd.velocity < config_->min_speed_for_curves)
00025 {
00026 ROS_DEBUG("Already going slow: %.3f", pcmd.velocity);
00027 return OK;
00028 }
00029
00030
00031
00032 int start_index = pops->getClosestPoly(course->plan,
00033 MapPose(estimate->pose.pose));
00034
00035
00036 int stop_index = pops->index_of_downstream_poly(course->plan,
00037 start_index,
00038 config_->lookahead_distance);
00039
00040 float max_speed = max_safe_speed(course->plan,
00041 start_index,
00042 stop_index,
00043 pcmd.velocity);
00044
00045
00046
00047 max_speed = fmaxf(config_->min_speed_for_curves, max_speed);
00048
00049
00050
00051
00052
00053
00054
00055 pcmd.velocity = max_speed;
00056
00057 trace("slow_for_curves controller", pcmd);
00058
00059 return OK;
00060 }
00061
00062 float SlowForCurves::max_safe_speed(const std::vector<poly>& polygons,
00063 const int& start_index,
00064 const int& stop_index,
00065 const float& max) {
00066
00067 if (start_index < 0
00068 || start_index >= (int)polygons.size()
00069 || stop_index < 0
00070 || stop_index >= (int)polygons.size()
00071 || start_index >= stop_index)
00072 {
00073 ROS_INFO("bogus input: start_index %d and stop_index %d",
00074 start_index, stop_index);
00075 return -1;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 if (verbose >= 4)
00090 ART_MSG(8, "slow_for_curves: searching over polygons %d(%s) to %d(%s)",
00091 polygons.at(start_index).poly_id,
00092 polygons.at(start_index).start_way.name().str,
00093 polygons.at(stop_index).poly_id,
00094 polygons.at(stop_index).start_way.name().str);
00095
00096 float distance = 0;
00097 float max_speed = 100;
00098
00099 char limiting_string[512] = "";
00100 int limiting_id = 0;
00101
00102 for(int begin = start_index; begin < stop_index; begin++) {
00103 distance += (polygons.at(begin).length +
00104 polygons.at(begin+1).length)/2.0;
00105
00106 float length = 0;
00107 int end = begin;
00108 while(end < stop_index && length < config_->min_curve_length) {
00109 length += (polygons.at(end).length +
00110 polygons.at(end+1).length)/2.0;
00111 end++;
00112 }
00113
00114 float dheading =
00115 Coordinates::normalize(polygons[end].heading - polygons[begin].heading);
00116
00117 float max_then =
00118 fmaxf(config_->min_speed_for_curves,
00119 course->max_speed_for_change_in_heading(dheading, length,
00120 max_speed, config_->max_yaw_rate));
00121
00122 float max_now =
00123 course->max_speed_for_slow_down(max_then, distance,
00124 max_speed, config_->max_deceleration);
00125
00126 if (max_now < max_speed) {
00127 limiting_id = polygons.at(begin).poly_id;
00128 sprintf(limiting_string, "Polygons: %d(%s)->%d(%s), (dheading: %.3f, length: %.3f, max_then: %.3f) Max speed now is %.3f for curve in %.3f meters.",
00129 polygons.at(begin).poly_id,
00130 polygons.at(begin).start_way.name().str,
00131 polygons.at(end).poly_id,
00132 polygons.at(end).start_way.name().str,
00133 dheading,
00134 length,
00135 max_then,
00136 max_now,
00137 distance);
00138 }
00139
00140 max_speed = fminf(max_speed, max_now);
00141 if (Epsilon::equal(max_speed,0.0))
00142 return 0.0;
00143 }
00144
00145 if(verbose >= 4 && current_limiting_id != limiting_id) {
00146 ART_MSG(2, "new limiting_factor: %s", limiting_string);
00147 current_limiting_id = limiting_id;
00148 }
00149
00150 max_speed = fminf(max_speed, max);
00151
00152 return max_speed;
00153 }
00154
00155
00156 void SlowForCurves::reset(void) {
00157 trace_reset("SlowForCurves");
00158 current_limiting_id = 0;
00159 }