CMakeLists.txt
# 设置 CMake 的最小版本要求 cmake_minimum_required(VERSION 3.10) # 设置项目名称和版本 project(PoseSaver VERSION 1.0) # 设置 C++ 标准为 C++11 set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True) # 查找 Eigen 库 find_package(Eigen3 3.3 REQUIRED NO_MODULE) # 添加可执行文件 add_executable(PoseSaver main.cpp) # 链接 Eigen3 库 target_link_libraries(PoseSaver Eigen3::Eigen) # 可选:设置编译器选项(根据需要) # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") # 可选:设置输出目录 # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
main.cpp
#include <iostream> #include <fstream> #include <sstream> #include <vector> #include <iomanip> // For std::setprecision #include <Eigen/Dense> #include <map> // 包含 map 头文件 using namespace std; using namespace Eigen; /* 函数功能: 读取 时间戳和Eigen::Vector3d位置t(没有旋转R)信息到filename的txt中 输入: 文件名 filename 列表 map<double, Vector3d> &dataMap 时间戳或者ID列表 timestamps 位姿 std::vector<Eigen::Vector3d>& poses 输出: 1.000000000 14.000000000 15.000000000 16.000000000 2.000000000 24.000000000 25.000000000 26.000000000 3.000000000 34.000000000 35.000000000 36.000000000 */ void Read_poses_t3x3FromFile(const string& filename,map<double, Vector3d> &dataMap) { ifstream file(filename); if (!file.is_open()) { cout << "Error opening file: " << filename << endl; } std::string line; while (std::getline(file, line)) { std::stringstream ss(line); std::string token; std::vector<std::string> row; /* 1.000000000 14.000000000 15.000000000 16.000000000 2.000000000 24.000000000 25.000000000 26.000000000 3.000000000 34.000000000 35.000000000 36.000000000 */ while (std::getline(ss, token, ' ')) { // 空格分割字符串 row.push_back(token); } double timestamp=stod(row[0]); double x = stod(row[1]); double y = stod(row[2]); double z = stod(row[3]); Vector3d position(x, y, z); dataMap[timestamp] = position; } // string line; // while (getline(file, line)) { // stringstream ss(line); // double timestamp; // double x, y, z; // if (!(ss >> timestamp >> x >> y >> z)) { // cerr << "Error reading line: " << line << endl; // continue; // } // Vector3d position(x, y, z); // dataMap[timestamp] = position; // } file.close(); } /* 函数功能: 读取 时间戳和Eigen::Vector3d位置t + 旋转 信息到filename的txt中 输入: 文件名 filename 列表 map<double, Matrix4d> &dataMap 时间戳或者ID列表 timestamps 位姿 std::vector<Eigen::Matrix4d>& poses 输出: 1.000000000000000 11.123456789 0.000000001 0.000000000 14.000000000 0.000000000 12.987654321 0.000000000 15.000000000 0.000000000 0.000000000 13.234567890 16.000000000 0.000000000 0.000000000 0.000000000 1.000000000 2.000000000000000 21.111111111 0.000000000 0.000000000 24.000000000 0.000000000 22.222222222 0.000000000 25.000000000 0.000000000 0.000000000 23.333333333 26.000000000 0.000000000 0.000000000 0.000000000 1.000000000 3.000000000000000 31.444444444 0.000000000 0.000000000 34.000000000 0.000000000 32.555555555 0.000000000 35.000000000 0.000000000 0.000000000 33.666666666 36.000000000 0.000000000 0.000000000 0.000000000 1.000000000 */ void Read_poses_T4x4FromFile(const string& filename,map<double, Eigen::Matrix4d> &dataMap) { ifstream file(filename); if (!file.is_open()) { cerr << "Error opening file: " << filename << endl; } std::string line; while (std::getline(file, line)) { std::stringstream ss(line); std::string token; std::vector<std::string> row; while (std::getline(ss, token, ' ')) { // 空格分割字符串 row.push_back(token); } if(row.size()!=17){ cout<< " 无效数据 "<< row[0] << " "<< row.size() <<endl; continue; } double timestamp=stod(row[0]); Eigen::Matrix4d matrix; matrix(0, 0) = stod(row[1]); matrix(0, 1) = stod(row[2]); matrix(0, 2) = stod(row[3]); matrix(0, 3) = stod(row[4]); matrix(1, 0) = stod(row[5]); matrix(1, 1) = stod(row[6]); matrix(1, 2) = stod(row[7]); matrix(1, 3) = stod(row[8]); matrix(2, 0) = stod(row[9]); matrix(2, 1) = stod(row[10]); matrix(2, 2) = stod(row[11]); matrix(2, 3) = stod(row[12]); matrix(3, 0) = stod(row[13]); matrix(3, 1) = stod(row[14]); matrix(3, 2) = stod(row[15]); matrix(3, 3) = stod(row[16]); dataMap[timestamp] = matrix; } file.close(); // std::string line; // while (std::getline(file, line)) { // std::istringstream ss(line); // double timestamp; // Eigen::Matrix4d matrix; // // Read timestamp // ss >> timestamp; // // Read matrix // for (int i = 0; i < 4; ++i) { // for (int j = 0; j < 4; ++j) { // ss >> matrix(i, j); // } // } // // Insert into map // dataMap[timestamp] = matrix; // } } /* 函数功能: 读取 时间戳和Eigen::Vector3d位置t + 旋转四元数 信息到filename的txt中 输入: 文件名 filename 列表 map<double, Matrix4d> &dataMap 时间戳或者ID列表 timestamps 位姿 std::vector<Eigen::Matrix4d>& poses 输出:时间戳 t q 1.000000000000000 11.123456789 0.000000001 0.000000000 14.000000000 0.000000000 12.987654321 0.000000000 15.000000000 0.000000000 0.000000000 13.234567890 16.000000000 0.000000000 0.000000000 0.000000000 1.000000000 2.000000000000000 21.111111111 0.000000000 0.000000000 24.000000000 0.000000000 22.222222222 0.000000000 25.000000000 0.000000000 0.000000000 23.333333333 26.000000000 0.000000000 0.000000000 0.000000000 1.000000000 3.000000000000000 31.444444444 0.000000000 0.000000000 34.000000000 0.000000000 32.555555555 0.000000000 35.000000000 0.000000000 0.000000000 33.666666666 36.000000000 0.000000000 0.000000000 0.000000000 1.000000000 */ void Read_poses_Qt4x4FromFile(const string& filename,map<double, Eigen::Matrix4d> &dataMap) { ifstream file(filename); if (!file.is_open()) { cerr << "Error opening file: " << filename << endl; } std::string line; while (std::getline(file, line)) { std::stringstream ss(line); std::string token; std::vector<std::string> row; while (std::getline(ss, token, ' ')) { // 空格分割字符串 row.push_back(token); } if(row.size()!= 8){ cout<< " 无效数据 "<< row[0] << " "<< row.size() <<endl; continue; } double timestamp=stod(row[0]); const Eigen::Vector3d trans_wc(stod(row[1]),stod(row[2]),stod(row[3])); const Eigen::Quaterniond quat_wc(stod(row[4]),stod(row[5]),stod(row[6]),stod(row[7])) ; // 从四元数构建旋转矩阵 Eigen::Matrix3d rot_wc = quat_wc.toRotationMatrix(); // 创建一个4x4变换矩阵 Eigen::Matrix4d transformationMatrix = Eigen::Matrix4d::Identity(); // 填充旋转部分 transformationMatrix.block<3, 3>(0, 0) = rot_wc; // 填充平移部分 transformationMatrix.block<3, 1>(0, 3) = trans_wc; dataMap[timestamp] = transformationMatrix; } file.close(); } /* 函数功能: 保存时间戳和Eigen::Vector3d位置t(没有旋转R)信息到filename的txt中 输入: 文件名 filename 时间戳或者ID列表 timestamps 位姿 std::vector<Eigen::Vector3d>& poses 输出: 1.000000000 14.000000000 15.000000000 16.000000000 2.000000000 24.000000000 25.000000000 26.000000000 3.000000000 34.000000000 35.000000000 36.000000000 */ void savePoses_t3x1ToFile(const std::string& filename, const std::vector<double>& timestamps, const std::vector<Eigen::Vector3d>& poses) { if (timestamps.size() != poses.size()) { std::cerr << "Error: Number of timestamps does not match number of poses." << std::endl; return; } std::ofstream file(filename, std::ios::out); if (!file.is_open()) { std::cerr << "打开文件失败: " << filename << std::endl; return; } // Set the precision for the output stream file << std::fixed << std::setprecision(9); // Write each timestamp and its corresponding matrix for (size_t i = 0; i < timestamps.size(); ++i) { file << timestamps[i] << " "; const Eigen::Vector3d& matrix = poses[i]; file << matrix(0) << " " << matrix(1) << " " << matrix(2) << " " << std::endl; } file.close(); } /* 函数功能: 保存时间戳和Eigen::Matrix4d位置t(没有旋转R)信息到filename的txt中 输入: 文件名 filename 时间戳或者ID列表 timestamps 位姿 std::vector<Eigen::Matrix4d>& poses 输出: 1.000000000 14.000000000 15.000000000 16.000000000 2.000000000 24.000000000 25.000000000 26.000000000 3.000000000 34.000000000 35.000000000 36.000000000 */ // Function to save timestamps and matrices to file with precision void savePoses_t3x1ToFile(const std::string& filename, const std::vector<double>& timestamps, const std::vector<Eigen::Matrix4d>& poses) { if (timestamps.size() != poses.size()) { std::cerr << "Error: Number of timestamps does not match number of poses." << std::endl; return; } std::ofstream file(filename, std::ios::out); if (!file.is_open()) { std::cerr << "打开文件失败: " << filename << std::endl; return; } // Set the precision for the output stream file << std::fixed << std::setprecision(9); // Write each timestamp and its corresponding matrix for (size_t i = 0; i < timestamps.size(); ++i) { file << timestamps[i] << " "; const Eigen::Matrix4d& matrix = poses[i]; file << matrix(0, 3) << " " << matrix(1, 3) << " " << matrix(2, 3) << " " << std::endl; } file.close(); } /* 函数功能: 保存时间戳和Eigen::Matrix4d旋转R和位置t信息到filename的txt中 输入: 文件名 filename 时间戳或者ID列表 timestamps 位姿 std::vector<Eigen::Matrix4d>& poses 输出: 1.000000000000000 11.123456789 0.000000001 0.000000000 14.000000000 0.000000000 12.987654321 0.000000000 15.000000000 0.000000000 0.000000000 13.234567890 16.000000000 0.000000000 0.000000000 0.000000000 1.000000000 2.000000000000000 21.111111111 0.000000000 0.000000000 24.000000000 0.000000000 22.222222222 0.000000000 25.000000000 0.000000000 0.000000000 23.333333333 26.000000000 0.000000000 0.000000000 0.000000000 1.000000000 3.000000000000000 31.444444444 0.000000000 0.000000000 34.000000000 0.000000000 32.555555555 0.000000000 35.000000000 0.000000000 0.000000000 33.666666666 36.000000000 0.000000000 0.000000000 0.000000000 1.000000000 */ void savePoses_T4x4ToFile(const std::string& filename, const std::vector<double>& timestamps, const std::vector<Eigen::Matrix4d>& poses) { if (timestamps.size() != poses.size()) { std::cerr << "Error: Number of timestamps does not match number of poses." << std::endl; return; } std::ofstream file(filename, std::ios::out); if (!file.is_open()) { std::cerr << "打开文件失败: " << filename << std::endl; return; } // Set the precision for the output stream file << std::fixed << std::setprecision(9); // Write each timestamp and its corresponding matrix for (size_t i = 0; i < timestamps.size(); ++i) { const Eigen::Matrix4d& matrix = poses[i]; file << std::setprecision(15) << timestamps[i]<< " " << std::setprecision(9) << matrix(0, 0) << " " << matrix(0, 1) << " " << matrix(0, 2) << " " << matrix(0, 3) << " " << matrix(1, 0) << " " << matrix(1, 1) << " " << matrix(1, 2) << " " << matrix(1, 3) << " " << matrix(2, 0) << " " << matrix(2, 1) << " " << matrix(2, 2) << " " << matrix(2, 3) << " " << matrix(3, 0) << " " << matrix(3, 1) << " " << matrix(3, 2) << " " << matrix(3, 3) << std::endl; } file.close(); } /* 函数功能: 保存时间戳和Eigen::Matrix4d 位置t 和 旋转四元数q信息到filename的txt中 输入: 文件名 filename 时间戳或者ID列表 timestamps 位姿 std::vector<Eigen::Matrix4d>& poses 输出: 1.000000000000000 14.000000000 15.000000000 16.000000000 0.000000000 0.000000000 -0.000000000 3.096194398 2.000000000000000 24.000000000 25.000000000 26.000000000 0.000000000 0.000000000 0.000000000 4.112987560 3.000000000000000 34.000000000 35.000000000 36.000000000 0.000000000 0.000000000 0.000000000 4.966554809 */ void savePoses_Qt4x4ToFile(const std::string& filename, const std::vector<double>& timestamps, const std::vector<Eigen::Matrix4d>& poses) { if (timestamps.size() != poses.size()) { std::cerr << "Error: Number of timestamps does not match number of poses." << std::endl; return; } std::ofstream file(filename, std::ios::out); if (!file.is_open()) { std::cerr << "打开文件失败: " << filename << std::endl; return; } // Set the precision for the output stream file << std::fixed << std::setprecision(9); // Write each timestamp and its corresponding matrix for (size_t i = 0; i < timestamps.size(); ++i) { const Eigen::Matrix4d& cam_pose_wc = poses[i];// 相机到世界位姿== 相机在世界坐标系下的世界位姿 const Eigen::Matrix3d& rot_wc = cam_pose_wc.block<3, 3>(0, 0); const Eigen::Vector3d& trans_wc = cam_pose_wc.block<3, 1>(0, 3); const Eigen::Quaterniond quat_wc = Eigen::Quaterniond(rot_wc); file << std::setprecision(15) << timestamps[i]<< " " << std::setprecision(9) << trans_wc(0) << " " << trans_wc(1) << " " << trans_wc(2) << " " << quat_wc.x() << " " << quat_wc.y() << " " << quat_wc.z() << " " << quat_wc.w() << std::endl; } file.close(); } int main() { // Example data std::vector<double> timestamps = {1.0, 2.0, 3.0}; // Initialize example poses with some values Eigen::Matrix4d pose1, pose2, pose3; pose1 << 11.123456789, 0.000000001, 0.000000000, 14.000000000, 0.000000000, 12.987654321, 0.000000000, 15.000000000, 0.000000000, 0.000000000, 13.234567890, 16.000000000, 0.000000000, 0.000000000, 0.000000000, 1.000000000; pose2 << 21.111111111, 0.000000000, 0.000000000, 24.000000000, 0.000000000, 22.222222222, 0.000000000, 25.000000000, 0.000000000, 0.000000000, 23.333333333, 26.000000000, 0.000000000, 0.000000000, 0.000000000, 1.000000000; pose3 << 31.444444444, 0.000000000, 0.000000000, 34.000000000, 0.000000000, 32.555555555, 0.000000000, 35.000000000, 0.000000000, 0.000000000, 33.666666666, 36.000000000, 0.000000000, 0.000000000, 0.000000000, 1.000000000; // Store matrices in a vectorsavePoses_T4x4ToFile std::vector<Eigen::Matrix4d> poses = {pose1, pose2, pose3}; // Save to file savePoses_Qt4x4ToFile("poses_Qt4x4.txt", timestamps, poses); savePoses_T4x4ToFile("poses_T4x4.txt", timestamps, poses); savePoses_t3x1ToFile("poses_t3x3.txt", timestamps, poses); map<double, Eigen::Vector3d> poses_t3x3 ; Read_poses_t3x3FromFile("poses_t3x3.txt",poses_t3x3); // 输出读取的数据 for (const auto& entry : poses_t3x3) { cout << "Timestamp: " << entry.first << ", Position: (" << entry.second.x() << ", " << entry.second.y() << ", " << entry.second.z() << ")" << endl; } map<double, Eigen::Matrix4d> poses_T4x4 ; Read_poses_T4x4FromFile("poses_T4x4.txt",poses_T4x4); // Example output to verify correctness for (const auto& pair : poses_T4x4) { std::cout << "Timestamp: " << pair.first << std::endl; std::cout << "Matrix:\n" << pair.second << std::endl; } map<double, Eigen::Matrix4d> poses_T4x4_qt ; Read_poses_Qt4x4FromFile("poses_Qt4x4.txt",poses_T4x4_qt); // Example output to verify correctness for (const auto& pair : poses_T4x4_qt) { std::cout << "Timestamp: " << pair.first << std::endl; std::cout << "Matrix:\n" << pair.second << std::endl; } return 0; }