기술나눔

지상 이동 표적의 UAV 포지셔닝---표적의 이동 방향과 속도 획득

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

목차

1. 소개

우리는 단안 드론을 사용하여 동일한 시간 간격으로 사진을 촬영하여 지상에서 움직이는 표적의 위치를 ​​확인합니다. 현재 각 사진에서 표적의 3차원 좌표를 얻었으며 비행 중에 사진을 찍는 드론의 위치를 ​​알 수 있습니다. .시간 간격을 사용하면 특정 계산을 통해 대상의 이동 방향과 속도를 얻을 수 있습니다.

2. 코드 설명

1. 가져온 데이터는 사진 이름과 대상 지점의 3차원 데이터로 구성된 txt 파일이므로 txt 파일의 데이터를 얻으려면 문자열 분할 기능을 설정해야 합니다.

2. 파이 값 정의

3. 방향 계산 기능 정의

4. txt 파일에서 필수 정보 추출

5. 인접한 사진 사이에서 대상의 방향 변경 각도를 계산합니다.

6. 인접한 사진 사이에서 대상의 이동 거리와 속도를 계산합니다.

3. 완전한 코드 표시

4. 결과 표시

이 기사의 모든 코드는 CSDN 사용자 CV-X.WANG에서 제공한 것입니다. 개인이나 그룹은 상업적 활동이나 교육 활동을 수행할 수 없습니다.


1. 소개

        우리는 단안 드론을 사용하여 동일한 시간 간격으로 사진을 촬영하여 지상에서 움직이는 표적의 위치를 ​​확인합니다. 현재 각 사진에서 표적의 3차원 좌표를 얻었으며 비행 중에 사진을 찍는 드론의 위치를 ​​알 수 있습니다. .시간 간격을 사용하면 특정 계산을 통해 대상의 이동 방향과 속도를 얻을 수 있습니다.

2. 코드 설명

1. 가져온 데이터는 사진 이름과 대상 지점의 3차원 데이터로 구성된 txt 파일이므로 txt 파일의 데이터를 얻으려면 문자열 분할 기능을 설정해야 합니다.

  1. //字符串分割
  2. vector<string> split(const string &s, char delimiter) {
  3. vector<string> tokens;
  4. string token;
  5. istringstream tokenStream(s);
  6. while (getline(tokenStream, token, delimiter)) {
  7. tokens.push_back(token);
  8. }
  9. return tokens;
  10. }

2. 파이 값 정의

#define M_PI       3.14159265358979323846   // pi

3. 방향 계산 기능 정의

본 논문에서는 표적의 이동 방향을 평면 방향으로 획득하기 위해 군사 분야에서 흔히 사용되는 360° 방향 방식을 채택하고 있다. 즉, 진북은 0° 방향이고 시계 방향은 0-360°입니다. 예를 들어 진동 방향은 우리 방향 시스템에서는 90° 방향입니다.

일부,

더블 lon1_rad = lon1 * M_PI / 180.0;
이중 lat1_rad = lat1 * M_PI / 180.0;
더블 lon2_rad = lon2 * M_PI / 180.0;
이중 lat2_rad = lat2 * M_PI / 180.0;

라디안 단위입니다.

  1. //方向函数
  2. double calculateDirectionAngle(double lon1, double lat1, double lon2, double lat2) {
  3. // Convert degrees to radians
  4. double lon1_rad = lon1 * M_PI / 180.0;
  5. double lat1_rad = lat1 * M_PI / 180.0;
  6. double lon2_rad = lon2 * M_PI / 180.0;
  7. double lat2_rad = lat2 * M_PI / 180.0;
  8. // Calculate delta longitude and convert to radians
  9. double delta_lon_rad = (lon2 - lon1) * M_PI / 180.0;
  10. // Calculate y and x components
  11. double y = sin(delta_lon_rad) * cos(lat2_rad);
  12. double x = cos(lat1_rad) * sin(lat2_rad) - sin(lat1_rad) * cos(lat2_rad) * cos(delta_lon_rad);
  13. // Calculate direction angle in radians
  14. double direction_rad = atan2(y, x);
  15. // Convert direction angle to degrees
  16. double direction_deg = direction_rad * 180.0 / M_PI;
  17. // Ensure direction angle is within [0, 360) degrees
  18. if (direction_deg < 0) {
  19. direction_deg += 360.0;
  20. }
  21. return direction_deg;
  22. }

4. txt 파일에서 필수 정보 추출

  1. ifstream file("LBH.txt");
  2. if (!file.is_open()) {
  3. cerr << "Could not open the file!" << endl;
  4. return 1;
  5. }
  6. string line;
  7. // Skip the header line
  8. getline(file, line);
  9. vector<vector<string>> extractedData;
  10. // Read each line from the file
  11. while (getline(file, line)) {
  12. vector<string> columns = split(line, 't');
  13. if (columns.size() < 16) {
  14. cerr << "Invalid line format" << endl;
  15. continue;
  16. }
  17. // Extract the required columns: 0, 13, 14, 15
  18. vector<string> extractedColumns;
  19. extractedColumns.push_back(columns[0]); // Image Name
  20. extractedColumns.push_back(columns[13]); // Longitude
  21. extractedColumns.push_back(columns[14]); // Latitude
  22. extractedColumns.push_back(columns[15]); // Altitude
  23. extractedData.push_back(extractedColumns);
  24. }
  25. file.close();

5. 인접한 사진 사이에서 대상의 방향 변경 각도를 계산합니다.

  1. cout << "Direction angles between adjacent image centers:" << endl;
  2. for (size_t i = 1; i < extractedData.size(); ++i) {
  3. //三角函数计算用弧度制
  4. double lon1 = (stod(extractedData[i - 1][1]))* M_PI/180; // Longitude
  5. double lat1 = (stod(extractedData[i - 1][2]))* M_PI / 180; // Latitude
  6. double lon2 = (stod(extractedData[i][1]))* M_PI / 180; // Longitude
  7. double lat2 = (stod(extractedData[i][2]))* M_PI / 180; // Latitude
  8. //计算方向变化角也要用弧度制
  9. double direction_angle = calculateDirectionAngle(lon1, lat1, lon2, lat2);
  10. cout << "lon1=" << lon1 << endl << "lat1=" << lat1 << endl << "lon2=" << lon2 << endl << "lat2=" << lat2 << endl;
  11. // Output Direction
  12. cout << "Direction from " << extractedData[i - 1][0] << " to " << extractedData[i][0] << ": " << direction_angle << " degrees" << endl;

6. 인접한 사진 사이에서 대상의 이동 거리와 속도를 계산합니다.

참고: 여기서 얻은 거리의 계산 공식은 다음과 같습니다.

이는 가장 간단한 설명일 뿐입니다. 실제 상황에서는 보다 정확한 거리를 얻으려면 좌표계, 측정 영역 위치 등 일련의 조건을 고려해야 합니다.

  1. double lon2_1 = lon2 - lon1;
  2. double lat2_1 = lat2 - lat1;
  3. double lon_ = lon2_1 / 2;//1/2的Δlon
  4. double lat_ = lat2_1 / 2; //1 / 2的Δlat
  5. double sin2lon_ = sin(lon_)*sin(lon_);//sin²(1/2Δlon)
  6. double sin2lat_ = sin(lat_)*sin(lat_); //sin²(1 / 2Δlat)
  7. double cos_lat1 = cos(lat1);
  8. double cos_lat2 = cos(lat2);
  9. double sqrtA = sqrt(sin2lat_+ cos_lat1* cos_lat2*sin2lon_);
  10. //cout << "Direction from " << extractedData[i - 1][0] << " to " << extractedData[i][0] << ": " << "sqrtA =" << sqrtA << endl;
  11. double asinA = asin(sqrtA);
  12. //长半轴 短半轴 单位是m
  13. int a_r = 6378137.0;
  14. int b_r = 6356752;
  15. double Earth_R = (2 * a_r + b_r) / 3;
  16. double Distance = 2 * Earth_R*asinA;
  17. cout << "Distance From " << extractedData[i - 1][0] << " to " << extractedData[i][0] << ": " << "=" << Distance <<" meter"<< endl;
  18. int time = 3;//拍照间隔 s
  19. double speed = Distance / time;
  20. cout << "Speed From " << extractedData[i - 1][0] << " to " << extractedData[i][0] << ": " << "=" << speed << " meter per second" << endl;
  21. }

3. 완전한 코드 표시

  1. #include <iostream>
  2. #include <fstream>
  3. #include <sstream>
  4. #include <vector>
  5. #include <cmath>
  6. using namespace std;
  7. #define M_PI 3.14159265358979323846 // pi
  8. // Function to split a string by a delimiter
  9. vector<string> split(const string &s, char delimiter) {
  10. vector<string> tokens;
  11. string token;
  12. istringstream tokenStream(s);
  13. while (getline(tokenStream, token, delimiter)) {
  14. tokens.push_back(token);
  15. }
  16. return tokens;
  17. }
  18. // direction angle in degrees
  19. //原理是 在平面上以正北方向为0°方向,顺时针为0-360°
  20. double calculateDirectionAngle(double lon1, double lat1, double lon2, double lat2) {
  21. // Convert degrees to radians
  22. double lon1_rad = lon1 * M_PI / 180.0;
  23. double lat1_rad = lat1 * M_PI / 180.0;
  24. double lon2_rad = lon2 * M_PI / 180.0;
  25. double lat2_rad = lat2 * M_PI / 180.0;
  26. // Calculate delta longitude and convert to radians
  27. double delta_lon_rad = (lon2 - lon1) * M_PI / 180.0;
  28. // Calculate y and x components
  29. double y = sin(delta_lon_rad) * cos(lat2_rad);
  30. double x = cos(lat1_rad) * sin(lat2_rad) - sin(lat1_rad) * cos(lat2_rad) * cos(delta_lon_rad);
  31. // Calculate direction angle in radians
  32. double direction_rad = atan2(y, x);
  33. // Convert direction angle to degrees
  34. double direction_deg = direction_rad * 180.0 / M_PI;
  35. // Ensure direction angle is within [0, 360) degrees
  36. if (direction_deg < 0) {
  37. direction_deg += 360.0;
  38. }
  39. return direction_deg;
  40. }
  41. int main() {
  42. ifstream file("LBH.txt");
  43. if (!file.is_open()) {
  44. cerr << "Could not open the file!" << endl;
  45. return 1;
  46. }
  47. string line;
  48. // Skip the header line
  49. getline(file, line);
  50. vector<vector<string>> extractedData;
  51. // Read each line from the file
  52. while (getline(file, line)) {
  53. vector<string> columns = split(line, 't');
  54. if (columns.size() < 16) {
  55. cerr << "Invalid line format" << endl;
  56. continue;
  57. }
  58. // Extract the required columns: 0, 13, 14, 15
  59. vector<string> extractedColumns;
  60. extractedColumns.push_back(columns[0]); // Image Name
  61. extractedColumns.push_back(columns[13]); // Longitude
  62. extractedColumns.push_back(columns[14]); // Latitude
  63. extractedColumns.push_back(columns[15]); // Altitude
  64. extractedData.push_back(extractedColumns);
  65. }
  66. file.close();
  67. // Calculate direction angles between adjacent image centers
  68. cout << "Direction angles between adjacent image centers:" << endl;
  69. for (size_t i = 1; i < extractedData.size(); ++i) {
  70. //三角函数计算用弧度制
  71. double lon1 = (stod(extractedData[i - 1][1]))* M_PI/180; // Longitude
  72. double lat1 = (stod(extractedData[i - 1][2]))* M_PI / 180; // Latitude
  73. double lon2 = (stod(extractedData[i][1]))* M_PI / 180; // Longitude
  74. double lat2 = (stod(extractedData[i][2]))* M_PI / 180; // Latitude
  75. //计算方向变化角也要用弧度制
  76. double direction_angle = calculateDirectionAngle(lon1, lat1, lon2, lat2);
  77. cout << "lon1=" << lon1 << endl << "lat1=" << lat1 << endl << "lon2=" << lon2 << endl << "lat2=" << lat2 << endl;
  78. // Output Direction
  79. cout << "Direction from " << extractedData[i - 1][0] << " to " << extractedData[i][0] << ": " << direction_angle << " degrees" << endl;
  80. double lon2_1 = lon2 - lon1;
  81. double lat2_1 = lat2 - lat1;
  82. double lon_ = lon2_1 / 2;//1/2的Δlon
  83. double lat_ = lat2_1 / 2; //1 / 2的Δlat
  84. double sin2lon_ = sin(lon_)*sin(lon_);//sin²(1/2Δlon)
  85. double sin2lat_ = sin(lat_)*sin(lat_); //sin²(1 / 2Δlat)
  86. double cos_lat1 = cos(lat1);
  87. double cos_lat2 = cos(lat2);
  88. double sqrtA = sqrt(sin2lat_+ cos_lat1* cos_lat2*sin2lon_);
  89. //cout << "Direction from " << extractedData[i - 1][0] << " to " << extractedData[i][0] << ": " << "sqrtA =" << sqrtA << endl;
  90. double asinA = asin(sqrtA);
  91. //长半轴 短半轴 单位是m
  92. int a_r = 6378137.0;
  93. int b_r = 6356752;
  94. double Earth_R = (2 * a_r + b_r) / 3;
  95. double Distance = 2 * Earth_R*asinA;
  96. cout << "Distance From " << extractedData[i - 1][0] << " to " << extractedData[i][0] << ": " << "=" << Distance <<" meter"<< endl;
  97. int time = 3;//拍照间隔 s
  98. double speed = Distance / time;
  99. cout << "Speed From " << extractedData[i - 1][0] << " to " << extractedData[i][0] << ": " << "=" << speed << " meter per second" << endl;
  100. }
  101. //cin.get();
  102. return 0;
  103. }

4. 결과 표시

이 문서의 모든 코드는 CSDN 사용자 CV-X.WANG이 제공합니다., 어떠한 개인이나 단체도 상업적, 교육적 활동을 할 수 없으며, 인용문이나 부분 인용문은 허가를 받아야 합니다.