00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "ucl_drone/path_planning.h"
00017
00018 PathPlanning::PathPlanning()
00019 {
00020
00021 std::string drone_prefix;
00022 ros::param::get("~drone_prefix", drone_prefix);
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 pose_channel = nh.resolveName("pose_estimation");
00033 pose_sub = nh.subscribe(pose_channel, 10, &PathPlanning::poseCb, this);
00034
00035 strategy_channel = nh.resolveName("strategy");
00036 strategy_sub = nh.subscribe(strategy_channel, 10, &PathPlanning::strategyCb, this);
00037
00038
00039 poseref_channel = nh.resolveName("path_planning");
00040 poseref_pub = nh.advertise< ucl_drone::PoseRef >(poseref_channel, 1);
00041
00042
00043 mapcell_channel = nh.resolveName("mapcell");
00044 mapcell_pub = nh.advertise< ucl_drone::cellUpdate >(mapcell_channel, 500);
00045
00046
00047 }
00048
00049
00050
00051 PathPlanning::~PathPlanning()
00052 {
00053 }
00054
00055
00056 void PathPlanning::reset()
00057 {
00058 next_x = 0;
00059 next_y = 0;
00060 next_z = 1.1;
00061 next_rotZ = 0;
00062 i = 0;
00063 landing = false;
00064 takeoff = false;
00065 gridInitialized = false;
00066
00067
00068
00069
00070
00071 XMax = next_z * 0.435 * 0.8 * 0.5;
00072 YMax = next_z * 0.326 * 0.8 * 0.5;
00073 }
00074
00075
00076
00077 void PathPlanning::publish_poseref()
00078 {
00079
00080 ucl_drone::PoseRef poseref_msg;
00081
00082 poseref_msg.x = next_x;
00083 poseref_msg.y = next_y;
00084 poseref_msg.z = next_z;
00085 poseref_msg.rotZ = next_rotZ;
00086 poseref_msg.landAndStop = landing;
00087 poseref_msg.takeoffAndStart = takeoff;
00088
00089 poseref_pub.publish(poseref_msg);
00090 }
00091
00092
00093
00094 void PathPlanning::poseCb(const ucl_drone::Pose3D::ConstPtr posePtr)
00095 {
00096 lastPoseReceived = *posePtr;
00097 }
00098
00099
00100
00101 void PathPlanning::strategyCb(const ucl_drone::StrategyMsg::ConstPtr strategyPtr)
00102 {
00103 lastStrategyReceived = *strategyPtr;
00104 }
00105
00106 template < typename T >
00107 int sgn(T val)
00108 {
00109 return (T(0) < val) - (val < T(0));
00110 }
00111
00112
00113 bool PathPlanning::xy_desired()
00114 {
00115
00116 if (sqrt((lastPoseReceived.x - next_x) * (lastPoseReceived.x - next_x) +
00117 (lastPoseReceived.y - next_y) * (lastPoseReceived.y - next_y) +
00118 (lastPoseReceived.z - next_z) * (lastPoseReceived.z - next_z)) < 0.25)
00119 {
00120 printf("i: %d\n", i);
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 double labyrinth_x[] = {0};
00131 double labyrinth_y[] = {0};
00132
00133 if (i >= sizeof(labyrinth_x) / sizeof(labyrinth_x[0]))
00134 {
00135 int j = i - sizeof(labyrinth_x) / sizeof(labyrinth_x[0]);
00136
00137 double descente_z[] = {1.1};
00138
00139 if (j >= sizeof(descente_z) / sizeof(descente_z[0]))
00140 {
00141
00142 return true;
00143 }
00144
00145 next_z = descente_z[j];
00146 }
00147 else
00148 {
00149 next_x = labyrinth_x[i];
00150 next_y = labyrinth_y[i];
00151 }
00152 i++;
00153
00154 return true;
00155 }
00156 else
00157 {
00158 return false;
00159 }
00160 }
00161
00162
00163
00164
00165
00166
00167
00168 void PathPlanning::InitializeGrid()
00169 {
00170
00171 for (i = 0; i < SIDE * 10; i++)
00172 {
00173 for (j = 0; j < SIDE * 10; j++)
00174 {
00175 myGrid[i][j] = 0;
00176 }
00177 }
00178 gridInitialized = true;
00179 }
00180
00181
00182
00183
00184
00185 bool PathPlanning::ThereIsAWallCell(int i, int j)
00186 {
00187 yfromcell2 = -((j / 10.0) - SIDE / 2.0);
00188 xfromcell2 = SIDE - (i / 10.0);
00189
00190
00191
00192
00193 if (yfromcell2 >= (SIDE / 2.0 - 0.2) || yfromcell2 <= -(SIDE - 0.4) / 2.0)
00194 {
00195 return true;
00196 }
00197 else if (xfromcell2 >= SIDE - 0.2 || xfromcell2 <= 0.2)
00198 {
00199 return true;
00200 }
00201 else
00202 {
00203 return false;
00204 }
00205 }
00206
00207
00208
00209
00210 void PathPlanning::AbsOrdMinMax(double x, double y, int* iMin, int* iMax, int* jMin, int* jMax)
00211 {
00212 printf("I'm calculating AbsOrdMinMax\n");
00213 *jMin = fmax(0, (int)(10 * SIDE / 2.0 - (y + YMax) * 10));
00214 *jMax = fmin((int)(10 * SIDE / 2.0 - (y - YMax) * 10), SIDE * 10);
00215 *iMin = fmax(0, (int)(10 * SIDE - (x + XMax) * 10));
00216 *iMax = fmin((int)(10 * SIDE - (x - XMax) * 10), SIDE * 10);
00217 }
00218
00219
00220 void PathPlanning::CellToXY(int i, int j, double* xfromcell, double* yfromcell)
00221 {
00222 *yfromcell = (double)(SIDE / 2.0 - j / 10.0);
00223 *xfromcell = (double)SIDE - (i / 10.0);
00224 }
00225
00226
00227
00228 void PathPlanning::UpdateMap(double x, double y)
00229 {
00230 ROS_INFO("I'm in the updatemap function");
00231 AbsOrdMinMax(x, y, &myAbsMin, &myAbsMax, &myOrdMin, &myOrdMax);
00232 ROS_INFO("I'm in the updatemap function after absOrdMinMax function");
00233 printf("myOrdMin: %d myOrdMax: %d myAbsMin: %d myAbsMax: %d \n", myOrdMin, myOrdMax,
00234 myAbsMin, myAbsMax);
00235
00236 for (i = myAbsMin; i < myAbsMax; i++)
00237 {
00238 for (j = myOrdMin; j < myOrdMax; j++)
00239 {
00240
00241
00242 if (myGrid[i][j] == 0 || myGrid[i][j] == 2)
00243 {
00244 if (!ThereIsAWallCell(i, j))
00245 {
00246 if (i == myAbsMin || i == myAbsMax - 1 || j == myOrdMin || j == myOrdMax - 1)
00247 {
00248 if (myGrid[i][j] == 2)
00249 {
00250 printf("I put a border cell\n");
00251 }
00252 else
00253 {
00254 printf("I put a NEW border cell\n");
00255 cellUpdateMsg.i = i;
00256 cellUpdateMsg.j = j;
00257 cellUpdateMsg.type = 2;
00258 mapcell_pub.publish(cellUpdateMsg);
00259 }
00260 myGrid[i][j] = 2;
00261 }
00262 else
00263 {
00264 myGrid[i][j] = 1;
00265 printf("I put an explored cell\n");
00266 cellUpdateMsg.i = i;
00267 cellUpdateMsg.j = j;
00268 cellUpdateMsg.type = 1;
00269 mapcell_pub.publish(cellUpdateMsg);
00270 }
00271 }
00272 else
00273 {
00274 myGrid[i][j] = 3;
00275 printf("I put a wall cell\n");
00276 cellUpdateMsg.i = i;
00277 cellUpdateMsg.j = j;
00278 cellUpdateMsg.type = 3;
00279 mapcell_pub.publish(cellUpdateMsg);
00280 }
00281 }
00282 }
00283 }
00284 }
00285
00286
00287 double PathPlanning::distance(int i, int j, int k, int l)
00288 {
00289 return sqrt((i - k) * (i - k) + (j - l) * (j - l));
00290 }
00291
00292
00293
00294
00295 void PathPlanning::advanced_xy_desired(double x, double y, double* k, double* l)
00296 {
00297 int absc = (int)(SIDE - x) * 10;
00298 int ord = (int)(SIDE / 2.0 - y) * 10;
00299 bestDist = 1000000.0;
00300 closestJ = SIDE * 10 / 2.0;
00301 closestI = SIDE * 10;
00302 for (i = 0; i < SIDE * 10; i++)
00303 {
00304 for (j = 0; j < SIDE * 10; j++)
00305 {
00306 if (myGrid[i][j] == 2 && distance(absc, ord, i, j) < bestDist)
00307 {
00308 bestDist = distance(absc, ord, i, j);
00309 closestJ = j;
00310 closestI = i;
00311 }
00312 }
00313 }
00314 if (bestDist == 1000000.0)
00315 {
00316 ROS_INFO("The map was explored completely, there are no more border cells!");
00317 }
00318
00319 CellToXY(closestI, closestJ, k, l);
00320 }
00321
00322
00323 void PathPlanning::SetRef(double x_ref, double y_ref, double z_ref, double rotZ_ref)
00324 {
00325 this->next_x = x_ref;
00326 this->next_y = y_ref;
00327 this->next_z = z_ref;
00328 this->next_rotZ = rotZ_ref;
00329 }
00330
00331
00332
00333 int main(int argc, char** argv)
00334 {
00335 ROS_INFO_STREAM("poseref_sending started!");
00336 ros::init(argc, argv, "path_planning");
00337 PathPlanning myPath;
00338 ros::Rate r(20);
00339 printf("Pathplanning launched");
00340 ROS_DEBUG("path planning initialized");
00341
00342 myPath.reset();
00343 myPath.publish_poseref();
00344 ros::spinOnce();
00345 r.sleep();
00346 ROS_INFO_STREAM("poseref initialized and launched");
00347 while (ros::ok())
00348 {
00349 TIC(path);
00350 if (myPath.lastStrategyReceived.type == 1.0)
00351 {
00352 myPath.takeoff = true;
00353 myPath.publish_poseref();
00354 }
00355
00356
00357
00358
00359
00360
00361 else if (myPath.lastStrategyReceived.type == 2.0)
00362 {
00363 if (myPath.xy_desired() == true)
00364 {
00365 myPath.takeoff = true;
00366 ros::Duration(1.5).sleep();
00367 myPath.publish_poseref();
00368 }
00369 }
00370
00371
00372
00373 else if (myPath.lastStrategyReceived.type == 3.0)
00374 {
00375 myPath.takeoff = true;
00376 myPath.SetRef(myPath.lastStrategyReceived.x, myPath.lastStrategyReceived.y + 0.5,
00377 myPath.next_z,
00378 myPath.next_rotZ);
00379
00380 myPath.publish_poseref();
00381 }
00382
00383
00384 else if (myPath.lastStrategyReceived.type == 4.0)
00385 {
00386 myPath.takeoff = false;
00387 myPath.landing = true;
00388 myPath.publish_poseref();
00389 }
00390
00391
00392
00393 else if (myPath.lastStrategyReceived.type == 5.0)
00394 {
00395 myPath.takeoff = true;
00396 myPath.SetRef(myPath.lastStrategyReceived.x, myPath.lastStrategyReceived.y, myPath.next_z,
00397 myPath.next_rotZ);
00398 myPath.publish_poseref();
00399 }
00400
00401
00402
00403
00404 else if (myPath.lastStrategyReceived.type == 6.0)
00405 {
00406 myPath.next_z = 2;
00407 if (sqrt((myPath.lastPoseReceived.x) * (myPath.lastPoseReceived.x) +
00408 (myPath.lastPoseReceived.y) * (myPath.lastPoseReceived.y)) < 0.15)
00409 {
00410 myPath.takeoff = false;
00411 myPath.landing = true;
00412 }
00413 else if (!myPath.landing)
00414 {
00415 myPath.takeoff = true;
00416 myPath.SetRef(0, 0, myPath.next_z, myPath.next_rotZ);
00417 }
00418 myPath.publish_poseref();
00419 }
00420
00421
00422
00423 else if (myPath.lastStrategyReceived.type == 7.0)
00424 {
00425 if (!myPath.gridInitialized)
00426 {
00427 ROS_INFO("I am initializing the grid");
00428
00429 myPath.InitializeGrid();
00430 }
00431
00432 myPath.takeoff = true;
00433 myPath.UpdateMap(myPath.lastPoseReceived.x, myPath.lastPoseReceived.y);
00434 ROS_INFO("I have updated the map");
00435
00436 myPath.advanced_xy_desired(myPath.lastPoseReceived.x, myPath.lastPoseReceived.y,
00437 &myPath.poseRefX, &myPath.poseRefY);
00438 myPath.SetRef(myPath.poseRefX, myPath.poseRefY, myPath.next_z, myPath.next_rotZ);
00439 ROS_INFO("poseref is : (%lf, %lf)", myPath.poseRefX, myPath.poseRefY);
00440 ros::Duration(1).sleep();
00441 myPath.publish_poseref();
00442 }
00443
00444
00445 else if (myPath.lastStrategyReceived.type == 8.0)
00446 {
00447 myPath.takeoff = true;
00448 myPath.SetRef(0.0, 0.0, 1.0, 0.0);
00449 myPath.publish_poseref();
00450 ros::Duration(15).sleep();
00451 myPath.SetRef(2.0, 0.0, 1.0, 0.0);
00452 myPath.publish_poseref();
00453 ros::Duration(35).sleep();
00454 myPath.SetRef(0.0, 0.0, 1.0, 0.0);
00455 myPath.publish_poseref();
00456 ros::Duration(35).sleep();
00457 myPath.SetRef(-2.0, 0.0, 1.0, 0.0);
00458 myPath.publish_poseref();
00459 ros::Duration(35).sleep();
00460 }
00461
00462 TOC(path, "path planning");
00463 ros::spinOnce();
00464 r.sleep();
00465 }
00466 return 0;
00467 }
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508