Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <base_local_planner/footprint_helper.h>
00039
00040 namespace base_local_planner {
00041
00042 FootprintHelper::FootprintHelper() {
00043
00044
00045 }
00046
00047 FootprintHelper::~FootprintHelper() {
00048
00049 }
00050
00051 void FootprintHelper::getLineCells(int x0, int x1, int y0, int y1, std::vector<base_local_planner::Position2DInt>& pts) {
00052
00053 int deltax = abs(x1 - x0);
00054 int deltay = abs(y1 - y0);
00055 int x = x0;
00056 int y = y0;
00057
00058 int xinc1, xinc2, yinc1, yinc2;
00059 int den, num, numadd, numpixels;
00060
00061 base_local_planner::Position2DInt pt;
00062
00063 if (x1 >= x0)
00064 {
00065 xinc1 = 1;
00066 xinc2 = 1;
00067 }
00068 else
00069 {
00070 xinc1 = -1;
00071 xinc2 = -1;
00072 }
00073
00074 if (y1 >= y0)
00075 {
00076 yinc1 = 1;
00077 yinc2 = 1;
00078 }
00079 else
00080 {
00081 yinc1 = -1;
00082 yinc2 = -1;
00083 }
00084
00085 if (deltax >= deltay)
00086 {
00087 xinc1 = 0;
00088 yinc2 = 0;
00089 den = deltax;
00090 num = deltax / 2;
00091 numadd = deltay;
00092 numpixels = deltax;
00093 }
00094 else
00095 {
00096 xinc2 = 0;
00097 yinc1 = 0;
00098 den = deltay;
00099 num = deltay / 2;
00100 numadd = deltax;
00101 numpixels = deltay;
00102 }
00103
00104 for (int curpixel = 0; curpixel <= numpixels; curpixel++)
00105 {
00106 pt.x = x;
00107 pt.y = y;
00108 pts.push_back(pt);
00109
00110 num += numadd;
00111 if (num >= den)
00112 {
00113 num -= den;
00114 x += xinc1;
00115 y += yinc1;
00116 }
00117 x += xinc2;
00118 y += yinc2;
00119 }
00120 }
00121
00122
00123 void FootprintHelper::getFillCells(std::vector<base_local_planner::Position2DInt>& footprint){
00124
00125 base_local_planner::Position2DInt swap, pt;
00126 unsigned int i = 0;
00127 while (i < footprint.size() - 1) {
00128 if (footprint[i].x > footprint[i + 1].x) {
00129 swap = footprint[i];
00130 footprint[i] = footprint[i + 1];
00131 footprint[i + 1] = swap;
00132 if(i > 0) {
00133 --i;
00134 }
00135 } else {
00136 ++i;
00137 }
00138 }
00139
00140 i = 0;
00141 base_local_planner::Position2DInt min_pt;
00142 base_local_planner::Position2DInt max_pt;
00143 unsigned int min_x = footprint[0].x;
00144 unsigned int max_x = footprint[footprint.size() -1].x;
00145
00146 for (unsigned int x = min_x; x <= max_x; ++x) {
00147 if (i >= footprint.size() - 1) {
00148 break;
00149 }
00150 if (footprint[i].y < footprint[i + 1].y) {
00151 min_pt = footprint[i];
00152 max_pt = footprint[i + 1];
00153 } else {
00154 min_pt = footprint[i + 1];
00155 max_pt = footprint[i];
00156 }
00157
00158 i += 2;
00159 while (i < footprint.size() && footprint[i].x == x) {
00160 if(footprint[i].y < min_pt.y) {
00161 min_pt = footprint[i];
00162 } else if(footprint[i].y > max_pt.y) {
00163 max_pt = footprint[i];
00164 }
00165 ++i;
00166 }
00167
00168
00169 for (unsigned int y = min_pt.y; y < max_pt.y; ++y) {
00170 pt.x = x;
00171 pt.y = y;
00172 footprint.push_back(pt);
00173 }
00174 }
00175 }
00176
00180 std::vector<base_local_planner::Position2DInt> FootprintHelper::getFootprintCells(
00181 Eigen::Vector3f pos,
00182 std::vector<geometry_msgs::Point> footprint_spec,
00183 const costmap_2d::Costmap2D& costmap,
00184 bool fill){
00185 double x_i = pos[0];
00186 double y_i = pos[1];
00187 double theta_i = pos[2];
00188 std::vector<base_local_planner::Position2DInt> footprint_cells;
00189
00190
00191 if (footprint_spec.size() <= 1) {
00192 unsigned int mx, my;
00193 if (costmap.worldToMap(x_i, y_i, mx, my)) {
00194 Position2DInt center;
00195 center.x = mx;
00196 center.y = my;
00197 footprint_cells.push_back(center);
00198 }
00199 return footprint_cells;
00200 }
00201
00202
00203 double cos_th = cos(theta_i);
00204 double sin_th = sin(theta_i);
00205 double new_x, new_y;
00206 unsigned int x0, y0, x1, y1;
00207 unsigned int last_index = footprint_spec.size() - 1;
00208
00209 for (unsigned int i = 0; i < last_index; ++i) {
00210
00211 new_x = x_i + (footprint_spec[i].x * cos_th - footprint_spec[i].y * sin_th);
00212 new_y = y_i + (footprint_spec[i].x * sin_th + footprint_spec[i].y * cos_th);
00213 if(!costmap.worldToMap(new_x, new_y, x0, y0)) {
00214 return footprint_cells;
00215 }
00216
00217
00218 new_x = x_i + (footprint_spec[i + 1].x * cos_th - footprint_spec[i + 1].y * sin_th);
00219 new_y = y_i + (footprint_spec[i + 1].x * sin_th + footprint_spec[i + 1].y * cos_th);
00220 if (!costmap.worldToMap(new_x, new_y, x1, y1)) {
00221 return footprint_cells;
00222 }
00223
00224 getLineCells(x0, x1, y0, y1, footprint_cells);
00225 }
00226
00227
00228 new_x = x_i + (footprint_spec[last_index].x * cos_th - footprint_spec[last_index].y * sin_th);
00229 new_y = y_i + (footprint_spec[last_index].x * sin_th + footprint_spec[last_index].y * cos_th);
00230 if (!costmap.worldToMap(new_x, new_y, x0, y0)) {
00231 return footprint_cells;
00232 }
00233 new_x = x_i + (footprint_spec[0].x * cos_th - footprint_spec[0].y * sin_th);
00234 new_y = y_i + (footprint_spec[0].x * sin_th + footprint_spec[0].y * cos_th);
00235 if(!costmap.worldToMap(new_x, new_y, x1, y1)) {
00236 return footprint_cells;
00237 }
00238
00239 getLineCells(x0, x1, y0, y1, footprint_cells);
00240
00241 if(fill) {
00242 getFillCells(footprint_cells);
00243 }
00244
00245 return footprint_cells;
00246 }
00247
00248 }