项目链接:gitee-飞行器信息系统课程设计
这个题目的说明:无人机路径规划

无人机从红色的起点出发,朝向蓝色的终点飞行,但是事先不知道环境地图(障碍物)的分布。

假设无人机上装备了激光雷达,能够探测一定范围内的障碍物信息

  • 当前探测到的障碍物用红色显示
  • 还未探测到的障碍物用灰色显示
  • 已经探测到的障碍物用黑色显示

无人机利用A * 算法规划当前认为可行的路径,绿色的线段

但是随着探测范围扩大,无人机在飞行过程发现,利用之前规划的路线无法达到目标点,则需要重新规划路径

利用上述方法,不断探测障碍物,并不断规划路径,无人机最终到达目标点

详细的每一步需要参考每个文件夹的README说明文档

这里只放出最后的总结

1 动态地图

即根据自身位置,设置无人机只知道自身某半径范围内的所有地图

2 动态规划

由于截至12-10日,雷达的仿真已经实现,现可以开始最后一步的设计,即动态规划;

需要详细考虑一下数据流

  • 首先,无人机位于起始位置,该点已知;将该点的pos传入雷达地图获取函数;
  • 生成一定半径以内探测到的障碍物grid,应该有两个grid,一个为0-1用于A*,一个保留0-2便于生成图片
  • gridpos用于A*算法,grid应是一个建图的过程;
  • 在每一次建图完成后,跑一次A*,把Path入栈保存;在这次跑完的A star的Path中,断不会有与障碍物重叠的点;
  • 对于pos路径的下一个节点,就是存在Path中的节点,从pos往下的一个,作为pos传给雷达扫描建图函数,更新0-1数组地图;
  • 对于Path中当前点到终点,判断是否有的点在地图上为障碍物了,如果一旦出现,以当前位置为起始位置,再次开始A star,Path入stack

基本是这样;

3 结果

4 Header

//
// Created by hazyparker on 2021/12/10.
//#ifndef INC_5_FINAL_SOLUTION_H
#define INC_5_FINAL_SOLUTION_H
#include "cmath"
#include <array>
#include <chrono>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <stack>
#include <tuple>
#include <vector>
#include <utility>
#include <opencv2/opencv.hpp>using namespace std;
using namespace cv;typedef pair<int, int> Pair;
typedef vector<vector<int>> Vec2int;
typedef tuple<bool, int, int, int> PathVar;class Solution {private:int ROW;int COL;Pair StartPoint;Pair EndPoint;stack<Pair> DynamicPath;// FIXME: cannot define vector in class? like vector<int> vec; have to be vec = vector<int>(100)// reference:// https://stackoverflow.com/questions/70332332/how-to-use-vector-as-a-private-member-in-class-to-store-and-pass-data/70332667#70332667// however, it's still not fixedVec2int map_vector;Vec2int radar_vector;Vec2int check_vector;Vec2int show_vector;public:Solution():ROW{ 100 },COL{ 100 },map_vector(ROW, vector<int>(COL)),radar_vector(ROW, vector<int>(COL)),check_vector(ROW, vector<int>(COL)),show_vector(ROW, vector<int>(COL)),StartPoint({10, 10}),EndPoint({90, 90}){}// A structure to hold the necessary parametersstruct cell {// Row and Column index of its parentPair nodeParent;// f = g + hdouble cost_f, cost_g, cost_h;cell():nodeParent(-1, -1), cost_f(-1), cost_g(-1), cost_h(-1){}};/*** set start point in coordinate position, then trans to array pos* @param x corPos x* @param y corPos y*/void setStartPoint(int x, int y);/*** set end point in coordinate position, then trans to array pos* @param x corPos x* @param y corPos y*/void setEndPoint(int x, int y);/*** transfer coordinate position to (i, j) display in array which starting at [0]* @param corPos pair(STL, C++) coordinate position of a point* @return array position*/static Pair cor2ArrayPos(Pair corPos);/*** check whether given cell (row, col) is a valid cell or not.* @param grid* @param point* @return bool*/bool isValid(const vector<vector <int>> &grid, const Pair& point) const;/*** A Utility Function to check whether the given cell is blocked or not* @param grid* @param point* @return*/bool isUnBlocked(const vector<vector <int>> &grid, const Pair& point) const;/*** A Utility Function to check whether destination cell has been reached or not* @param position* @param dest* @return*/bool isDestination(const Pair& position);/*** A Utility Function to calculate the 'h' heuristics* @param src* @param dest* @return*/static double calculateHValue(const Pair& src, const Pair& dest);/*** transfer vector<vector<int>> to gray scale Mat(image)* @param grid* @return Mat mat*/Mat vector2ObstacleMap(Vec2int &grid) const;/*** read m_map array from file(mapName), write it in map_vector* @param mapName* @return map_vector*/Vec2int getVectorRawGrid(const string& mapName);/*** using erode function in openCV to add boundaries* @param grid* @return vector<vector<int>>*/Vec2int getVectorBoundaryGrid(Vec2int &grid) const;/*** transfer cv::Mat to vector<vector<int>>* @param src* @param m* @param n* @return*/static vector<vector<int>> mat2Vector(Mat &src, int m, int n);/*** transfer vector<vector<int>> to cv::Mat* @param vec* @return*/static Mat vector2Mat(vector<vector<int>> &vec);/*** Lidar Stimulation, fetch data from radar based on position currently* @param pos* @param Vec*/void fetchLidarData(Pair &pos, Vec2int &Vec);/*** merge Intervals* @param newRange* @param intervals* @return*/static vector<pair<double, double>> mergeInterval(const pair<double, double> &newRange,vector<pair<double, double>> &intervals);/*** check if the interval you input is included in intervals that you check* @param newRange* @param intervals* @return*/static bool checkInterval(const pair<double, double> &newRange,vector<pair<double, double>> &intervals);/*** calculate degree range of a RECT* assuming radar located at point_0, target pos is point_d* @param point_0* @param point_d* @return*/static pair<double, double> getThetaRange(Pair point_0, Pair point_d);/*** clear vector maps already scanned* cos 1 means visible and reachable, setting it as 1*/void clearRadarMap();/*** launch radar*/void launchRadar();/*** A star search while pos and grid is changing* @param pos* @param m_grid*/void dynamicSearch(Pair &pos, Vec2int &m_grid);/*** trace path when A star is finished* @param cellDetails* @param pos*/void dynamicTracePath(const vector<vector <cell>> &cellDetails, const Pair &pos);/*** check if there is Obstacle on Path calculated by A star* @param path* @return*/PathVar ifPathObstacle(vector<Pair> &path);/*** show path using openCV*/void showPath();
};#endif //INC_5_FINAL_SOLUTION_H

5 Main函数

#include "Solution.h"using namespace std;
using namespace cv;int main() {vector<vector<int>> grid;Solution solve;solve.getVectorRawGrid("test_1.map");solve.setStartPoint(40, 10);solve.setEndPoint(40, 90);solve.launchRadar();solve.showPath();return 0;
}

6 CMakeList

cmake_minimum_required(VERSION 3.21)
project(5_final)set(CMAKE_CXX_STANDARD 14)#  OpenCV
FIND_PACKAGE(OpenCV REQUIRED)
INCLUDE_DIRECTORIES({OpenCV_INCLUDE_DIRS})add_executable(5_final main.cpp AStarSearch.cpp AStarSearch.h readMap.cpp readMap.h testRadar.cpp testRadar.h Solution.cpp Solution.h)# link
TARGET_LINK_LIBRARIES(5_final ${OpenCV_LIBS})

7 Solution cpp

//
// Created by hazyparker on 2021/12/10.
//#include "Solution.h"
#include "cmath"
#include <array>
#include <chrono>
#include <cstring>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>
#include <utility>
#include <opencv2/opencv.hpp>using namespace std;
using namespace cv;typedef pair<int, int> Pair;
typedef vector<vector<int>> Vec2int;
typedef tuple<double, int, int> Tuple;
typedef tuple<bool, int, int, int> PathVar;vector<Pair> OverallPath;Vec2int Solution::getVectorRawGrid(const string& mapName) {string FILEPATH = "../../maps/" + mapName;const char *filepath = (char*)FILEPATH.data();// read mapint32_t m_mx, m_my, m_startX, m_startY, m_endX, m_endY;int8_t *m_map;Mat img;FILE        *fp;uint32_t    f_magic;// open filefp = fopen(filepath, "rb");if( fp == nullptr ) {printf("ERR: failed to open file %s!\n", filepath);exit(100);}// check file magic numberfread(&f_magic, sizeof(uint32_t), 1, fp);if( f_magic != 0x15432345 ) {printf("ERR: input file format is not correct! %s\n", filepath);goto MAP_LOAD_RET;}// read map nx, nyfread(&m_mx, sizeof(int32_t), 1, fp);fread(&m_my, sizeof(int32_t), 1, fp);ROW = m_mx;COL = m_my;// read mapm_map = new int8_t[m_mx * m_my];fread(m_map, sizeof(int8_t), m_mx * m_my, fp);// read start,end pointfread(&m_startX, sizeof(int32_t), 1, fp);fread(&m_startY, sizeof(int32_t), 1, fp);fread(&m_endX, sizeof(int32_t), 1, fp);fread(&m_endY, sizeof(int32_t), 1, fp);StartPoint = {m_startX, m_startY};EndPoint = {m_endX, m_endY};MAP_LOAD_RET:fclose(fp);int cols = m_mx;// Mat to Vector2intfor (int i = 0; i < m_mx; i++){for (int j = 0; j < m_my; j++){// 1 is reachable// 0 is blockedif (int(m_map[i * cols + j]) == 0){map_vector[i][j] = 1;}if (int(m_map[i * cols + j]) == 1){map_vector[i][j] = 0;}}}return map_vector;
}Pair Solution::cor2ArrayPos(Pair corPos) {Pair ArrayPos;ArrayPos.first = corPos.second - 1;ArrayPos.second = corPos.first - 1;return ArrayPos;
}void Solution::setStartPoint(int x, int y) {Pair corPos;corPos.first = x;corPos.second = y;StartPoint = cor2ArrayPos(corPos);
}void Solution::setEndPoint(int x, int y) {Pair corPos;corPos.first = x;corPos.second = y;EndPoint = cor2ArrayPos(corPos);
}bool Solution::isValid(const vector<vector<int>> &grid, const Pair &point) const {// Returns true if row number and column number is in rangeif (ROW > 0 && COL > 0)return (point.first >= 0) && (point.first < ROW)&& (point.second >= 0)&& (point.second < COL);else return false;
}bool Solution::isUnBlocked(const vector<vector<int>> &grid, const Pair &point) const {// Returns true if the cell is not blocked else falsereturn isValid(grid, point)&& grid[point.first][point.second] == 1;
}bool Solution::isDestination(const Pair &position) {return position == EndPoint;
}double Solution::calculateHValue(const Pair &src, const Pair &dest) {// h is estimated with the two points distance formulareturn sqrt(pow((src.first - dest.first), 2.0)+ pow((src.second - dest.second), 2.0));
}Mat Solution::vector2ObstacleMap(Vec2int &grid) const {Mat img, dst;img = Mat(ROW, COL, CV_8U, Scalar::all(255));// convert m_map to int, sending to imgfor (int i = 0; i < COL; i++){for (int j = 0; j < ROW; j++){img.at<uchar>(i, j) = grid[i][j] * 255;}}// erode, showing the edgeMat element = getStructuringElement(MORPH_RECT, Size(5, 5));erode(img, dst, element);// uplift the gray scale of edgesfor (int i = 0; i < COL; i++){for (int j = 0; j < ROW; j++){if(int(dst.at<uchar>(i, j)) == 0)dst.at<uchar>(i, j) = 200;}}// blend two images, using lower gray scale// consider using addWeight()for (int i = 0; i < COL; i++){for (int j = 0; j < ROW; j++){if(int(dst.at<uchar>(i, j)) == 200 && int(img.at<uchar>(i, j)) == 0)dst.at<uchar>(i, j) = 0;}}return dst;
}Vec2int Solution::getVectorBoundaryGrid(Vec2int &grid) const {Mat img, dst;vector<vector <int>> boundaryGrid(ROW, vector<int>(COL));img = vector2Mat(grid);Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));erode(img, dst, element);boundaryGrid = mat2Vector(dst, ROW, COL);return boundaryGrid;
}vector<vector <int>> Solution::mat2Vector(Mat &src, int m, int n) {vector<vector <int>> transferredVector(m, vector<int>(n));vector<int> flatVector = src.reshape(1,1);// FIXME: how to transfer Mat to vector<vector>
//    transferredVector = flatVector.resize(m, 0);for (int i = 0; i < m; i++){for (int j = 0; j < m; j++){transferredVector[i][j] = int(src.at<uchar>(i, j));}}return transferredVector;
}Mat Solution::vector2Mat(vector<vector <int>> &vec) {Mat dst;dst = Mat(100, 100, CV_8U, Scalar::all(0));for (int i = 0; i < 100; i++){for (int j = 0; j < 100; j++){dst.at<uchar>(i, j) = vec[i][j];}}return dst;
}void Solution::fetchLidarData(Pair &pos, Vec2int &Vec) {// set radiusint radius = 40;int pos_i = pos.first;int pos_j = pos.second;// open Lidarpair<double, double> range;vector<pair<double, double>> degreeInterval;degreeInterval.emplace_back(0.001, 0.002);int i, j;for (int r = 1; r <= radius; r++){for (i = pos_i - r; i <= pos_i + r; i++){for (j = pos_j - r; j <= pos_j +r; j++){if (!isValid(map_vector, {i, j})) continue;if (abs(i - pos_i) + abs(j - pos_j) != r || map_vector[i][j] == 1) continue;range = getThetaRange(pos, {i, j});if (range.second > 314 && range.first < 46 && map_vector[i][j] == 0){degreeInterval = mergeInterval({0.0001, range.first}, degreeInterval);degreeInterval = mergeInterval({range.second, 359.9999}, degreeInterval);Vec[i][j] = 0;continue;}if (checkInterval(range, degreeInterval)){// if totally blocked by other obstacles, UAV was unaware of this obstacle// have to consider another situation, that this [i][j] had been checked before// and set as 0 which means unreachable, we can't make it invisible again in radar_map// however, in image shown as to having used radar, it should be erased again// that step is not necessary(for now)// if (radar_map[i][j] == 0) radar_map[i][j] = 0;// if (radar_map[i][j] == 1) radar_map[i][j] = 1;}else{Vec[i][j] = 0;}degreeInterval = mergeInterval(range, degreeInterval);}}}}vector<pair<double, double>> Solution::mergeInterval(const pair<double, double> &newRange,vector<pair<double, double>> &intervals) {// https://leetcode-cn.com/problems/merge-intervals/solution/he-bing-qu-jian-by-leetcode-solution/intervals.emplace_back(newRange);sort(intervals.begin(), intervals.end());vector<pair<double, double>> merged;for (auto & interval : intervals) {double L = interval.first, R = interval.second;if (merged.empty() || merged.back().second < L) {merged.emplace_back(L, R);}else {merged.back().second = max(merged.back().second, R);}}return merged;
}bool Solution::checkInterval(const pair<double, double> &newRange,vector<pair<double, double>> &intervals) {bool value = false;if (intervals.empty()){return false;}sort(intervals.begin(), intervals.end());double left = newRange.first;double right = newRange.second;for (auto & interval : intervals){if (left >= interval.first && right <= interval.second){value = true;break;}}return value;
}pair<double, double> Solution::getThetaRange(Pair point_0, Pair point_d){// point_0 center// point_d paradouble PI = 3.1415926;pair<double, double> range;int i_0 = point_0.first;int j_0 = point_0.second;int i_d = point_d.first;int j_d = point_d.second;// save thetadouble theta[4] = {0, 0, 0, 0};// range change from (-PI, PI) to (0, 2PI)// FIXME: special definition around -PItheta[0] = atan2(i_d + 0.5 - i_0, j_d + 0.5 - j_0) * 180 / PI + 180;theta[1] = atan2(i_d + 0.5 - i_0, j_d - 0.5 - j_0) * 180 / PI + 180;theta[2] = atan2(i_d - 0.5 - i_0, j_d + 0.5 - j_0) * 180 / PI + 180;theta[3] = atan2(i_d - 0.5 - i_0, j_d - 0.5 - j_0) * 180 / PI + 180;sort(theta, theta + 4);// if theta[3] >= 315, i_0 == i_d (for sure)// send to pair rangerange.second = theta[3];range.first = theta[0];if (theta[3] > 340 && theta[0] < 19){range.second = theta[2];range.first = theta[1];}return range;
}void Solution::clearRadarMap() {cout << "map cleared" << endl;for (int i = 0; i < ROW; i++){for (int j = 0; j < COL; j++){radar_vector[i][j] = 1;check_vector[i][j] = 1;show_vector[i][j] = 1;}}
}void Solution::launchRadar() {// clear all obstacles, forming a new mapclearRadarMap();// initialize start point as StartPointPair pos = StartPoint;fetchLidarData(pos, radar_vector);int number = 0;cout << "into loop launch.." << endl;while(pos != EndPoint){// clear check_vectorfor (int i = 0; i < ROW; i++){for (int j = 0; j < COL; j++){check_vector[i][j] = 1;}}cout << "loop:" << number << endl;number = number + 1;printf("(%d, %d) pos\n", pos.first, pos.second);// store path in stack DynamicStackdynamicSearch(pos, radar_vector);// test if obstacle on pathvector<Pair> path;while(!DynamicPath.empty()){Pair p = DynamicPath.top();DynamicPath.pop();path.emplace_back(p);}cout << "path data read in..." << endl;for (auto & i : path){cout << "data in path:" << i.first << ", " << i.second << endl;}PathVar message = ifPathObstacle(path);cout << get<0>(message) << endl;if (get<0>(message)){// update pos to last onepos = {get<1>(message), get<2>(message)};int num = get<3>(message);for (int i = 0; i <= num; i++){fetchLidarData(path[i], radar_vector);OverallPath.emplace_back(path[i]);cout << path[i].first << ", " << path[i].second << endl;}}if (!get<0>(message)){for (auto & i : path){OverallPath.push_back(i);}pos = EndPoint;cout << "end founded..." << endl;}}}void Solution::dynamicSearch(Pair &pos, Vec2int &m_grid) {// set begin timechrono::steady_clock::time_point t1 = chrono::steady_clock::now();Vec2int grid(ROW, vector<int>(COL));grid = getVectorBoundaryGrid(m_grid);// If the source is out of rangeif (!isValid(grid, StartPoint)) {printf("Source is invalid\n");return;}// If the destination is out of rangeif (!isValid(grid, EndPoint)) {printf("Destination is invalid\n");return;}// Either the source or the destination is blockedif (!isUnBlocked(grid, StartPoint)|| !isUnBlocked(grid, EndPoint)) {printf("Source or the destination is blocked\n");return;}// If the destination cell is the same as source cellif (isDestination(StartPoint)) {printf("We are already at the destination\n");return;}// describe detail of each cell// using struct definedvector<vector <cell>> cellDetails(ROW, vector<cell>(COL));int i, j;// Initialising the parameters of the starting nodei = pos.first, j = pos.second;cellDetails[i][j].cost_f = 0.0;cellDetails[i][j].cost_g = 0.0;cellDetails[i][j].cost_h = 0.0;cellDetails[i][j].nodeParent = {i, j};// Create a closed list and initialise it to falsebool closedList[ROW][COL];memset(closedList, false, sizeof(closedList));/*** Create an open list having information as <f, <i, j>>* where f = g + h,* and i, j are the row and column index of that cell* Note that 0 <= i <= ROW-1 & 0 <= j <= COL-1* This open list is implemented as a set of tuple*/priority_queue<Tuple, vector<Tuple>, greater<> > openList;// Type: Tuple// Container: vector// Functional: greater, least f will be on top of the queueopenList.emplace(0.0, i, j);while(!openList.empty()){const Tuple& p = openList.top(); // first time, it will be start point// Add this vertex to the closed listi = get<1>(p); // second element of tuplej = get<2>(p); // third element of tuple// remove this vertex from open list and send it to close listopenList.pop();closedList[i][j] = true;for (int add_x = -1; add_x <= 1; add_x++) {for (int add_y = -1; add_y <= 1; add_y++) {Pair neighbour(i + add_x, j + add_y);if (!isValid(grid, neighbour)){return;}if (isDestination(neighbour)){// set parent of destination cellcellDetails[neighbour.first][neighbour.second].nodeParent = {i, j};// print pathcout << "destination is found!" << endl;dynamicTracePath(cellDetails, pos);// set end time and showchrono::steady_clock::time_point t2 = chrono::steady_clock::now();chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>(t2 - t1);cout << "solve time cost = " << time_used.count() << " seconds. " << endl;// endreturn;}else if (!closedList[neighbour.first][neighbour.second]&& isUnBlocked(grid, neighbour)){// update weight valuesdouble f_updated, g_updated, h_updated;g_updated = cellDetails[i][j].cost_g + sqrt(pow(add_x, 2.0) + pow(add_y, 2.0));h_updated = calculateHValue(neighbour, EndPoint);f_updated = g_updated + h_updated;// send less f_updated to open listdouble temp_cost_f = cellDetails[neighbour.first][neighbour.second].cost_f;if (f_updated < temp_cost_f || temp_cost_f == -1){// -1 referring that this node doesn't belong to open list, shall be added in// f_updated is less, shall be added in open list// at first I was concerning about the StartPoint, then I just realized that// StartPoint has been thrown into close listopenList.emplace(f_updated, neighbour.first, neighbour.second);// update cost f, g, h and parent node of cellDetailscellDetails[neighbour.first][neighbour.second].cost_f = f_updated;cellDetails[neighbour.first][neighbour.second].cost_g = g_updated;cellDetails[neighbour.first][neighbour.second].cost_h = h_updated;// set parent of successors(not in Close list and is unblocked)cellDetails[i + add_x][j + add_y].nodeParent = {i, j};/*** why updating parent node must exist here?* if you actually put this update under definition of neighbour, some path might be confusing* set updating here can assure that each node parent heading for gradient lifting* namely f in decline*/}}}}}}void Solution::dynamicTracePath(const vector<vector <cell>> &cellDetails, const Pair &pos) {cout << "trace started..." << endl;int i = EndPoint.first;int j = EndPoint.second;Pair temp_node;while(cellDetails[i][j].nodeParent != pos){DynamicPath.push({i, j});temp_node = cellDetails[i][j].nodeParent;// i = cellDetails[i][j].nodeParent.first is illegal!i = temp_node.first;j = temp_node.second;}DynamicPath.push({i, j});// push StartPoint into StackDynamicPath.push(pos);cout << "trace finished" << endl;
}PathVar Solution::ifPathObstacle(vector<Pair> &path){PathVar message;bool seg;// FIXME: check_map not bestfor (int n = 0; n < path.size(); n++){int i = path[n].first;int j = path[n].second;Pair pos = {i, j};fetchLidarData(pos, check_vector);for (auto & k : path){if (check_vector[k.first][k.second] == 0){seg = true;get<1>(message) = i;get<2>(message) = j;get<3>(message) = n;get<0>(message) = seg;printf("(%d, %d) is on obstacle\n", k.first, k.second);return message;}else{seg = false;get<0>(message) = seg;}}}return message;
}void Solution::showPath() {for (int i = 0; i < ROW; i++){for (int j = 0; j < COL; j++){show_vector[i][j] = 1;}}Mat img;img = Mat(100, 100, CV_8UC3, Scalar::all(255));Vec2int temp_map (ROW, vector<int>(COL));for (auto & i : OverallPath){fetchLidarData(i, show_vector);temp_map = getVectorBoundaryGrid(show_vector);for (int x = 0; x < ROW; x++){for (int y = 0; y < COL; y++){if (show_vector[x][y] == 0) img.at<Vec3b>(x, y) = {0, 0, 0};if (show_vector[x][y] == 1 && temp_map[x][y] == 0)img.at<Vec3b>(x, y) = {0, 128, 128};}}img.at<Vec3b>(i.first, i.second) = {0, 255, 0};img.at<Vec3b>(StartPoint.first, StartPoint.second) = {255, 0, 0};img.at<Vec3b>(EndPoint.first, EndPoint.second) = {0, 0, 255};namedWindow("dst", WINDOW_NORMAL);imshow("dst", img);waitKey(100);}}

无人机激光雷达的路径规划仿真相关推荐

  1. ROS 教程2 机器人雷达建图 蒙特卡洛定位 导航 路径规划 仿真

    ros 机器人雷达建图 蒙特卡洛定位 导航 路径规划 仿真 move_base gmapping acml 博文github 一.安装 turtlebot 移动机器人底座 进行导航 1.安装系统依赖 ...

  2. 多无人机任务分配与路径规划算法学习(一)

    本文是阅读"多无人机任务分配与路径规划算法研究_丁家如"文献的学习记录. 记录的第一部分是有关任务分配的知识,各种模型的建立就放到下次来写. 一.多无人机任务分配的本质 目前阅读的 ...

  3. 【A_star二维路径规划】基于matlab A_star算法无人机二维路径规划(起终点障碍物可设置)【含Matlab源码 1321期】

    ⛄一.获取代码方式 获取代码方式1: 通过订阅紫极神光博客付费专栏,凭支付凭证,私信博主,可获得此代码. 获取代码方式2: 完整代码已上传我的资源:[A_star二维路径规划]基于matlab A_s ...

  4. 路径规划仿真平台1.1 MSA*算法

    路径规划仿真平台主要是接下来研究的主要内容,目标是把各种路径规划算法整合到此仿真平台,实现路径规划算法研究.算法应用开发等. pathplan 1.1 内嵌2张自制地图,路经规划算法采用Multi-S ...

  5. 【PSO三维路径规划】基于matlab粒子群算法无人机山地三维路径规划【含Matlab源码 1405期】

    ⛄一.无人机简介 0 引言 随着现代技术的发展,飞行器种类不断变多,应用也日趋专一化.完善化,如专门用作植保的大疆PS-X625无人机,用作街景拍摄与监控巡察的宝鸡行翼航空科技的X8无人机,以及用作水 ...

  6. 一.路径规划---二维路径规划仿真实现-gmapping+amcl+map_server+move_base

    参考http://www.autolabor.com.cn/book/ROSTutorials/chapter1.html 1.首先实现仿真平台在rviz和gazebo的实现: 编写rviz环境下的x ...

  7. 【DE三维路径规划】基于matlab改进的差分算法多无人机协同三维路径规划【含Matlab源码 169期】

    ⛄一.无人机简介 0 引言 随着现代技术的发展,飞行器种类不断变多,应用也日趋专一化.完善化,如专门用作植保的大疆PS-X625无人机,用作街景拍摄与监控巡察的宝鸡行翼航空科技的X8无人机,以及用作水 ...

  8. 【A_star三维路径规划】基于matlab A_star算法无人机山地三维路径规划【含Matlab源码 266期】

    ⛄一.A_star算法简介 0 引言 随着现代技术的发展,飞行器种类不断变多,应用也日趋专一化.完善化,如专门用作植保的大疆PS-X625无人机,用作街景拍摄与监控巡察的宝鸡行翼航空科技的X8无人机, ...

  9. python路径规划仿真实验_【python实战】批量获得路径规划——高德地图API

    1.需求 在上篇中,已经批量获得了经纬度信息,现在需要根据经纬度来进行路径规划,想知道两点之间的距离和路程.花费等信息. 这时候就需要用到高德地图API中的路径规划功能了. 2.过程 1. 构造经纬度 ...

最新文章

  1. 吴恩达老师深度学习视频课笔记:深度学习的实用层面
  2. 测试嵌套JavaScript对象键的存在
  3. /etc/profile 和 ~/.profile 区别是全部用户,和单一用户
  4. chrome Native Client 让你可以使用 C 以及 C++ 语言开发 Web 应用
  5. android点击事件禁用,android-禁用所有视图的触摸事件
  6. php-cgi 68%,php cgi 进程占用太多怎么办
  7. Wiwiz无线Web认证实现限速
  8. linux 检查mps版本,linux_mps启动流程_存储相关.doc
  9. 生成树协议(STP)原理与配置PVST+实现负载均衡
  10. bd3.1 Python 高级
  11. Linux实时监控日志文件的swatchdog
  12. 邮箱显示exchange账号服务器错误,删除监视邮箱Exchange服务器不正常状态
  13. 豆丁网文库下载器,版本:201…
  14. quartz定时任务properties
  15. Windows下如何强制删除文件夹及文件的命令
  16. youtube上下载vr立体声视频及其处理
  17. Linux-CentOS上的服务搭建
  18. openstack出错The server is currently unavailable. Please try again at a later time.(HTTP 503)
  19. 为什么element ui 中表单验证validate验证成功不执行验证成功的逻辑代码
  20. 对一支圆珠笔进行测试,要从哪些方面进行测试?

热门文章

  1. 慢性疲劳免疫失调综合症(CFIDS)
  2. unity 2D游戏开发 制作帧动画的两种方法
  3. Web server failed to start.Port 8082 was already in use端口被占用
  4. Elasticsearch mapping与analysis
  5. 214情人节,使用微信小程序【信鸽相知】写情书吧
  6. 全球与中国婚纱市场深度研究分析报告
  7. Java正则表达式(详解)
  8. golang 字符串随机数_在Go中生成随机数和字符串
  9. 非诚勿扰 11位骗子全是托 愚乐节目 愚弄观众 请勿相信节目内容
  10. 为什么苹果允许「自助修 iPhone」这件事,与每个人息息相关?