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
00039
00040
00041
00042
00043
00044
00045 #ifndef MANEUVERGENERATOR_HPP_
00046 #define MANEUVERGENERATOR_HPP_
00047
00048 #include <labust_mission/labustMission.hpp>
00049 #include <labust_mission/xmlPrinter.hpp>
00050 #include <Eigen/Dense>
00051
00052
00053
00054 using namespace labust::utils;
00055
00056
00057
00058
00059
00060 namespace labust {
00061 namespace maneuver {
00062
00063 class ManeuverGenerator {
00064
00065 public:
00066
00067
00068
00069
00070
00071 ManeuverGenerator();
00072
00073 void generateGoTo(double north, double east, double speed, double victory_radius);
00074
00075 void generateRows(double north, double east, double speed, double victory_radius, double width, double length, double hstep, double alternationPercent,
00076 double curvOff, bool squareCurve, double bearing, double crossAngle, bool invertY);
00077
00078 void generateStationKeeping(double north, double east, double heading);
00079
00080 void writePrimitives(int primitiveID, std::vector<Eigen::Vector4d> points, double heading, double speed, double victoryRadius);
00081
00082 std::vector<Eigen::Vector4d> calcRIPatternPoints(double width, double hstep,
00083 double alternationPercent, double curvOff, bool squareCurve, double bearingRad);
00084
00085 std::vector<Eigen::Vector4d> calcCrossHatchPatternPoints(double width, double hstep,
00086 double curvOff, bool squareCurve, double bearingRad);
00087
00088 std::vector<Eigen::Vector4d> calcRowsPoints(double width, double length, double hstep,
00089 double alternationPercent, double curvOff, bool squareCurve, double bearingRad,
00090 double crossAngleRadians);
00091
00092 std::vector<Eigen::Vector4d> calcRowsPoints(double width, double length, double hstep,
00093 double alternationPercent, double curvOff, bool squareCurve, double bearingRad,
00094 double crossAngleRadians, bool invertY);
00095
00096 std::pair<double,double> rotate(double angleRadians, double x, double y, bool clockwiseRotation);
00097
00098
00099
00100
00101
00102
00103 WriteXML writeXML;
00104 };
00105
00106
00107 ManeuverGenerator::ManeuverGenerator(){}
00108
00109
00110 void ManeuverGenerator::generateGoTo(double north, double east, double speed, double victory_radius)
00111 {
00112 writeXML.addGo2point_FA(north, east, speed, victory_radius);
00113 }
00114
00115 void ManeuverGenerator::generateRows(double north, double east, double speed, double victory_radius, double width, double length, double hstep, double alternationPercent,
00116 double curvOff, bool squareCurve, double bearing, double crossAngle, bool invertY)
00117 {
00118
00119 std::vector<Eigen::Vector4d> tmpPoints;
00120 tmpPoints = calcRowsPoints(width, length, hstep,
00121 alternationPercent/100, curvOff, squareCurve, bearing*M_PI/180,
00122 crossAngle*M_PI/180, invertY);
00123
00124
00125 for(std::vector<Eigen::Vector4d>::iterator it = tmpPoints.begin(); it != tmpPoints.end(); ++it){
00126
00127 Eigen::Vector4d vTmp = *it;
00128 vTmp[X] += north;
00129 vTmp[Y] += east;
00130
00131 *it = vTmp;
00132 }
00133
00134 writePrimitives(go2point_FA, tmpPoints, 0, speed, victory_radius);
00135 }
00136
00137 void ManeuverGenerator::generateStationKeeping(double north, double east, double heading)
00138 {
00139 writeXML.addDynamic_positioning(north, east, heading);
00140 }
00141
00142 void ManeuverGenerator::writePrimitives(int primitiveID, std::vector<Eigen::Vector4d> points, double heading, double speed, double victoryRadius){
00143
00144 switch(primitiveID){
00145
00146 case go2point_FA:
00147
00148 for(std::vector<Eigen::Vector4d>::iterator it = points.begin() ; it != points.end(); ++it){
00149
00150 Eigen::Vector4d vTmp = *it;
00151
00152 writeXML.addGo2point_FA(vTmp[X], vTmp[Y], speed, victoryRadius);
00153
00154 }
00155
00156
00157 break;
00158
00159 case go2point_UA:
00160
00161 for(std::vector<Eigen::Vector4d>::iterator it = points.begin() ; it != points.end(); ++it){
00162
00163 Eigen::Vector4d vTmp = *it;
00164
00165 writeXML.addGo2point_UA(vTmp[X],vTmp[Y], speed, victoryRadius);
00166
00167 }
00168
00169
00170 break;
00171
00172 case dynamic_positioning:
00173
00174
00175
00176 break;
00177
00178 case course_keeping_FA:
00179
00180
00181 break;
00182
00183 case course_keeping_UA:
00184
00185
00186
00187 break;
00188
00189 case none:
00190
00191 break;
00192
00193 }
00194 }
00195
00196
00197 std::vector<Eigen::Vector4d> ManeuverGenerator::calcRIPatternPoints(double width, double hstep,
00198 double alternationPercent, double curvOff, bool squareCurve, double bearingRad) {
00199
00200 std::vector<Eigen::Vector4d> newPoints;
00201
00202 double length = width;
00203 Eigen::Vector4d pointBaseB;
00204 pointBaseB << -length/2.0, -width/2.0, 0, -1;
00205
00206 std::pair<double, double> res = rotate(bearingRad, pointBaseB[X], pointBaseB[Y], false);
00207
00208 Eigen::Vector4d pointBase1;
00209 pointBase1 << res.first, res.second, 0, -1;
00210
00211 res = rotate(bearingRad+(-60*M_PI/180), pointBaseB[X], pointBaseB[Y], false);
00212
00213 Eigen::Vector4d pointBase2;
00214 pointBase2 << res.first, res.second, 0, -1;
00215
00216 res = rotate(bearingRad+(-120*M_PI/180), pointBaseB[X], pointBaseB[Y], false);
00217
00218 Eigen::Vector4d pointBase3;
00219 pointBase3 << res.first, res.second, 0, -1;
00220
00221 std::vector<Eigen::Vector4d> points1 = calcRowsPoints(width, width, hstep, 2-alternationPercent, curvOff,
00222 squareCurve, bearingRad, 0);
00223
00224 for(std::vector<Eigen::Vector4d>::iterator it = points1.begin() ; it != points1.end(); ++it){
00225
00226 Eigen::Vector4d vTmp = *it;
00227 vTmp[X] += pointBase1[X];
00228 vTmp[Y] += pointBase1[Y];
00229
00230 *it = vTmp;
00231 }
00232
00233 std::vector<Eigen::Vector4d> points2 = calcRowsPoints(width, width, hstep, 2-alternationPercent, curvOff,
00234 squareCurve, bearingRad + (-60*M_PI/180), 0);
00235
00236 for(std::vector<Eigen::Vector4d>::iterator it = points2.begin() ; it != points2.end(); ++it){
00237
00238 Eigen::Vector4d vTmp = *it;
00239 vTmp[X] += pointBase2[X];
00240 vTmp[Y] += pointBase2[Y];
00241
00242 *it = vTmp;
00243 }
00244
00245 std::vector<Eigen::Vector4d> points3 = calcRowsPoints(width, width, hstep, 2-alternationPercent, curvOff,
00246 squareCurve, bearingRad + (-120*M_PI/180), 0);
00247
00248 for(std::vector<Eigen::Vector4d>::iterator it = points3.begin() ; it != points3.end(); ++it){
00249
00250 Eigen::Vector4d vTmp = *it;
00251 vTmp[X] += pointBase3[X];
00252 vTmp[Y] += pointBase3[Y];
00253
00254 *it = vTmp;
00255 }
00256
00257
00258 std::vector<Eigen::Vector4d>::iterator it;
00259
00260 it = newPoints.end();
00261 newPoints.insert(it+1, points1.begin(), points1.end());
00262 it = newPoints.end();
00263 newPoints.insert(it+1, points2.begin(), points2.end());
00264 it = newPoints.end();
00265 newPoints.insert(it+1, points3.begin(), points3.end());
00266
00267 return newPoints;
00268 }
00269
00270
00271 std::vector<Eigen::Vector4d> ManeuverGenerator::calcCrossHatchPatternPoints(double width, double hstep,
00272 double curvOff, bool squareCurve, double bearingRad) {
00273
00274 std::vector<Eigen::Vector4d> newPoints;
00275
00276 double length = width;
00277
00278 Eigen::Vector4d pointBase1;
00279 pointBase1 << -length/2., -width/2., 0, -1;
00280
00281 Eigen::Vector4d pointBase2;
00282 pointBase2 << -length/2., width/2., 0, -1;
00283
00284 std::pair<double, double> res = rotate(bearingRad, pointBase1[X], pointBase1[Y], false);
00285
00286 pointBase1 << res.first, res.second, 0, -1;
00287
00288 res = rotate(bearingRad, pointBase2[X], pointBase2[Y], false);
00289
00290 pointBase2 << res.first, res.second, 0, -1;
00291
00292 std::vector<Eigen::Vector4d> points1 = calcRowsPoints(width, width, hstep, 1, curvOff,
00293 squareCurve, bearingRad, 0);
00294
00295 for(std::vector<Eigen::Vector4d>::iterator it = points1.begin() ; it != points1.end(); ++it){
00296
00297 Eigen::Vector4d vTmp = *it;
00298 vTmp[X] += pointBase1[X];
00299 vTmp[Y] += pointBase1[Y];
00300
00301 *it = vTmp;
00302 }
00303
00304 std::vector<Eigen::Vector4d> points2 = calcRowsPoints(width, width, hstep, 1, curvOff,
00305 squareCurve, bearingRad + (-90*M_PI/180), 0);
00306
00307 for(std::vector<Eigen::Vector4d>::iterator it = points2.begin() ; it != points2.end(); ++it){
00308
00309 Eigen::Vector4d vTmp = *it;
00310 vTmp[X] += pointBase2[X];
00311 vTmp[Y] += pointBase2[Y];
00312
00313 *it = vTmp;
00314 }
00315
00316
00317 std::vector<Eigen::Vector4d>::iterator it;
00318
00319 it = newPoints.end();
00320 newPoints.insert(it+1, points1.begin(), points1.end());
00321 it = newPoints.end();
00322 newPoints.insert(it+1, points2.begin(), points2.end());
00323
00324 return newPoints;
00325 }
00326
00327
00328 std::vector<Eigen::Vector4d> ManeuverGenerator::calcRowsPoints(double width, double length, double hstep,
00329 double alternationPercent, double curvOff, bool squareCurve, double bearingRad,
00330 double crossAngleRadians) {
00331 return calcRowsPoints(width, length, hstep, alternationPercent, curvOff, squareCurve,
00332 bearingRad, crossAngleRadians, false);
00333 }
00334
00335
00336 std::vector<Eigen::Vector4d> ManeuverGenerator::calcRowsPoints(double width, double length, double hstep,
00337 double alternationPercent, double curvOff, bool squareCurve, double bearingRad,
00338 double crossAngleRadians, bool invertY) {
00339
00340 width = fabs(width);
00341 length = fabs(length);
00342 hstep = fabs(hstep);
00343
00344 bool direction = true;
00345
00346 std::vector<Eigen::Vector4d> newPoints;
00347
00348 Eigen::Vector4d point;
00349 point<<-curvOff,0,0,-1;
00350
00351 newPoints.push_back(point);
00352
00353
00354 double x2;
00355 for (double y = 0; y <= width; y += hstep) {
00356
00357 if (direction) {
00358
00359 x2 = length + curvOff;
00360 }
00361 else {
00362
00363 x2 = -curvOff;
00364 }
00365 direction = !direction;
00366
00367 double hstepDelta = 0;
00368 if (direction)
00369 hstepDelta = hstep * (1 - alternationPercent);
00370
00371 point << x2, y - hstepDelta, 0, -1;
00372
00373 newPoints.push_back(point);
00374
00375 if (y + hstep <= width) {
00376 double hstepAlt = hstep;
00377 if (!direction)
00378 hstepAlt = hstep * alternationPercent;
00379
00380 point << x2 + (squareCurve ? 0 : 1) * (direction ? curvOff : -curvOff), y + hstepAlt, 0, -1;
00381 newPoints.push_back(point);
00382 }
00383 }
00384
00385 for (std::vector<Eigen::Vector4d>::iterator it = newPoints.begin() ; it != newPoints.end(); ++it){
00386
00387
00388
00389
00390 Eigen::Vector4d vTmp = *it;
00391
00392
00393 std::pair<double,double> res = rotate(-crossAngleRadians, vTmp[0], 0, false);
00394 vTmp[X] = res.first;
00395 vTmp[Y] = vTmp[Y] + res.second;
00396 if (invertY)
00397 vTmp[Y] = -vTmp[Y];
00398 res = rotate(bearingRad + (!invertY ? -1 : 1) * -crossAngleRadians, vTmp[X], vTmp[Y], false);
00399 vTmp[X] = res.first;
00400 vTmp[Y] = res.second;
00401
00402 *it = vTmp;
00403
00404 }
00405
00406 return newPoints;
00407 }
00408
00419 std::pair<double,double> ManeuverGenerator::rotate(double angleRadians, double x, double y, bool clockwiseRotation) {
00420
00421 double sina = sin(angleRadians);
00422 double cosa = cos(angleRadians);
00423
00424 std::pair<double,double> xy;
00425
00426 if (clockwiseRotation) {
00427 xy.first = x * cosa + y * sina;
00428 xy.second = -x * sina + y * cosa;
00429 }
00430 else {
00431 xy.first = x * cosa - y * sina;
00432 xy.second = x * sina + y * cosa;
00433 }
00434 return xy;
00435 }
00436 }
00437 }
00438
00439 #endif