步骤一:安装GeographicLib
首先,确保你的系统中已安装GeographicLib库。可以通过以下命令在Ubuntu中安装:
sudo apt-get install geographiclib-* # 安装GeographicLib的库 sudo apt-get install libgeographic-* # 安装GeographicLib的依赖库
步骤二:配置C++项目
在你的C++项目中,需要配置CMake以及链接GeographicLib库。
CMakeLists.txt
cmake_minimum_required(VERSION 3.5) set(CMAKE_CXX_STANDARD 11) # 设置项目名称和语言 project(my_test_project LANGUAGES CXX) # 包含GeographicLib的头文件路径 include_directories("/usr/include/GeographicLib") # 设置输出的可执行文件 add_executable(${PROJECT_NAME} main.cpp) # 链接GeographicLib库(根据你的安装调整库名) target_link_libraries(${PROJECT_NAME} Geographic)
步骤三:示例代码
1GNSS转换为ENU
以下是一个简单的示例代码,演示了如何使用GeographicLib将经纬度转换为局部直角坐标系:
main.cpp
GNSS务必是double类型 否则精度保存不到6位米
#include <iostream> #include <GeographicLib/LocalCartesian.hpp> int main() { // 当前点的经纬度和高度,作为局部坐标系的原点 double origin_latitude = 29.116543; // 纬度 double origin_longitude = 111.506270; // 经度 double origin_height = 0.0; // 高度 // 初始化 LocalCartesian 对象,并设置原点 GeographicLib::LocalCartesian geoConverter; geoConverter.Reset(origin_latitude, origin_longitude, origin_height); // 要转换的另一个点的经纬度和高度 double target_latitude = 29.106543; double target_longitude = 111.606270; double target_height = 0.0; // 转换为局部直角坐标系 double x, y, z; geoConverter.Forward(target_latitude, target_longitude, target_height, x, y, z); // 输出转换后的局部坐标 std::cout << "Local Cartesian coordinates: (" << x << ", " << y << ", " << z << ")" << std::endl; return 0; }
编译运行
2ENU转换GNSS
#include <GeographicLib/LocalCartesian.hpp> #include <iostream> int main() { using namespace GeographicLib; // 参考点的经纬度和高度 double lat0 = 37.7749; // 纬度 double lon0 = -122.4194; // 经度 double h0 = 30; // 高度 // 创建LocalCartesian对象 LocalCartesian proj(lat0, lon0, h0); // ENU坐标 double e = 100; // 东 double n = 50; // 北 double u = 10; // 上 // 计算WGS84坐标 double lat, lon, h; proj.Reverse(e, n, u, lat, lon, h); std::cout << "Latitude: " << lat << ", Longitude: " << lon << ", Height: " << h << std::endl; return 0; }
3 ENU转换ECEF
#include <GeographicLib/LocalCartesian.hpp> #include <GeographicLib/Geocentric.hpp> #include <iostream> int main() { using namespace GeographicLib; // 参考点的经纬度和高度 double lat0 = 37.7749; // 纬度 double lon0 = -122.4194; // 经度 double h0 = 30; // 高度 // 创建LocalCartesian对象 LocalCartesian proj(lat0, lon0, h0); // ENU坐标 double e = 100; // 东 double n = 50; // 北 double u = 10; // 上 // 计算WGS84坐标 double lat, lon, h; proj.Reverse(e, n, u, lat, lon, h); // 创建Geocentric对象 Geocentric geo; // 将WGS84坐标转换为ECEF坐标 double x, y, z; geo.Forward(lat, lon, h, x, y, z); std::cout << "ECEF X: " << x << ", ECEF Y: " << y << ", ECEF Z: " << z << std::endl; return 0; }
综合版本
从yaml读取初始位置,转换enu保存ymal
FHY_gps.txt
%YAML:1.0 --- #==============# # Camera Model # #==============# Camera.name: EH2022left monocular Camera.setup: monocular Camera.model: perspective Camera.fx: 1220 Camera.fy: 1220 Camera.cx: 960 Camera.cy: 540 Camera.k1: -0 Camera.k2: 0 Camera.p1: 0 Camera.p2: 0 Camera.k3: -0 Camera.k4: 0 Camera.fps: 10 Camera.cols: 1920 Camera.rows: 1080 Camera.color_order: RGB Initial.lat: 34.2315085 Initial.lon: 108.9263953333333 Initial.alt: 372.933 Feature.max_num_keypoints: 3000 Feature.scale_factor: 1.2 Feature.num_levels: 8 PangolinViewer.keyframe_size: 0.07 PangolinViewer.keyframe_line_width: 2 PangolinViewer.graph_line_width: 1 PangolinViewer.point_size: 2 PangolinViewer.camera_size: 0.08 PangolinViewer.camera_line_width: 3 PangolinViewer.viewpoint_x: 0 PangolinViewer.viewpoint_y: -0.65 PangolinViewer.viewpoint_z: -1.9 PangolinViewer.viewpoint_f: 400 Marker.Num: 0 vAcc: 1.0 hAcc: 1.0 Fixed.altitude_flag: 0 Fixed.altitude: 400.0 Save.newmap: 1 Save.data: 1 op.is_Second_Optimize: 0 op.Second_Optimize_Th: 0 op.Remove_Kayframe_Th: 6.0 op.Global_Optimize_Th: 1.0 Loop_Th: 80.0 Relocalize_Th: 80.0 Relocalize_KF_Th: 3.0 V_Instant_Th: 200.0 Tracking_CF_Th: 10.0
main.cpp
#include <iostream> #include <GeographicLib/LocalCartesian.hpp> #include "opencv2/core.hpp" #include <time.h> using namespace cv; using namespace std; bool API_WriteFromYaml_name_value(String path_yaml,String name,String data){ //创建文件 FileStorage fs(path_yaml, FileStorage::WRITE); fs << name << data; fs.release(); return 0; } //从指定文件读取 指定名字的数据 bool API_ReadFromYaml_name_data(string path_yaml,string name,double *data){ /* 写入(FileStorage::WRITE,覆盖写) 追加(FileStorage::APPEND,追加写) 读取(FileStorage::READ) */ FileStorage fs2(path_yaml, FileStorage::READ); if (!fs2.isOpened()) { std::cerr << "Failed to open FileStorage" << std::endl; return 0; } //std::cerr << "打开成功" << path_yaml << std::endl; //注意数据格式转换 to_string() // second method: use FileNode::operator >> if (!fs2[name].isNone() && !fs2[name].empty()) { *data=(double)fs2[name] ; } else{ *data=-1; } fs2.release(); } int main() { double origin_latitude = 0; // 纬度 double origin_longitude = 0; // 经度 double origin_height = 0.0; // 高度 string path_yaml="../config/FHY_config.yaml"; API_ReadFromYaml_name_data(path_yaml,"Initial.lat", &origin_latitude);// 读取一个数据 API_ReadFromYaml_name_data(path_yaml,"Initial.lon", &origin_longitude);// 读取一个数据 API_ReadFromYaml_name_data(path_yaml,"Initial.alt", &origin_height);// 读取一个数据 cout<< "origin_latitude "<< origin_latitude<<endl; cout<< "origin_longitude "<< origin_longitude<<endl; cout<< "origin_height "<< origin_height<<endl; //API_WriteFromYaml_name_value(path_yaml,"gps","2132312");// 写入一个数据 // 初始化 LocalCartesian 对象,并设置原点 GeographicLib::LocalCartesian geoConverter; geoConverter.Reset(origin_latitude, origin_longitude, origin_height); // 要转换的另一个点的经纬度和高度 double target_latitude = origin_latitude; //26.888 double target_longitude = origin_longitude; //118.323 double target_height = origin_height+100; // 转换为局部直角坐标系 double x, y, z; geoConverter.Forward(target_latitude, target_longitude, target_height, x, y, z); // 输出转换后的局部坐标 std::cout << "Local Cartesian coordinates: (" << x << ", " << y << ", " << z << ")" << std::endl; std::vector<double> gnss_enu = {x,y,z}; string path_save_yaml="../config/gnss_enu.yaml"; FileStorage fs(path_save_yaml, FileStorage::WRITE); fs << "gnss_enu" << gnss_enu; fs.release(); return 0; }
CMakeLists.txt
cmake_minimum_required(VERSION 3.5) set(CMAKE_CXX_STANDARD 11) # 设置项目名称和语言 project(my_test_project LANGUAGES CXX) # 包含GeographicLib的头文件路径 include_directories("/usr/include/GeographicLib") #设置opencv安装路径 #set(CMAKE_PREFIX_PATH "/home/r9000k/v1_software/opencv/opencv349/install") #set(CMAKE_PREFIX_PATH "/home/r9000k/v1_software/opencv/opencv455/install") #包含opencv头文件路径 find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) # 设置输出的可执行文件 add_executable(${PROJECT_NAME} main2.cpp) # 链接GeographicLib库(根据你的安装调整库名) target_link_libraries(${PROJECT_NAME} Geographic ${OpenCV_LIBS})