利用平面进行位姿约束优化

embedded/2025/1/16 8:47:31/
/*** 设位姿pose存在误差,利用观测到的平面进行位姿pose优化,只优化位姿pose的z轴平移和roll,pitch,yaw四个变量,要求优化后的pose,z轴与平面的z一致。请修改代码实现这个功能* * */
#include <gtsam/slam/PriorFactor.h>
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
#include <gtsam/nonlinear/Values.h>
#include <gtsam/nonlinear/GaussNewtonOptimizer.h>
#include <gtsam/geometry/OrientedPlane3.h>
#include <gtsam/geometry/Pose3.h>
#include <gtsam/inference/Symbol.h>
#include <boost/optional.hpp>
#include <iostream>using namespace gtsam;// 自定义因子类
class CustomOrientedPlane3Factor : public NoiseModelFactor1<Pose3> {OrientedPlane3 measured_;public:CustomOrientedPlane3Factor(const OrientedPlane3& measured, const SharedNoiseModel& model, Key poseKey): NoiseModelFactor1<Pose3>(model, poseKey), measured_(measured) {}// 误差评估函数Vector evaluateError(const Pose3& pose, boost::optional<Matrix&> H = boost::none) const override {OrientedPlane3 transformedPlane = measured_.transform(pose, H); // 变换平面// 单独定义误差据向量double zError = pose.translation().z() - transformedPlane.planeCoefficients()(3);Vector3 normalError = transformedPlane.planeCoefficients().head<3>() - measured_.planeCoefficients().head<3>();Vector error(4); // 定义为4维向量error << normalError, zError; // 确保合并的正确顺序if (H) {*H = Matrix::Zero(4, 6); // 初始化 4x6 矩阵(*H)(3, 5) = 1.0; // 对z方向的偏导数// 这里需要自行计算剩余的angular部分根据误差函数的特定定义}return error; // 返回误差}
};int main() {NonlinearFactorGraph graph;// 初始位姿,只允许z的平移以及旋转freedomPose3 initialPose(Rot3::Ypr(0.1, 0.1, 0.1), Point3(10.5, 20.4, 1.2));Vector6 poseConstraint;poseConstraint << 0.0, 0.0, 1.0, 1.0, 1.0, 1.0; // 仅允许调整z, roll, pitch, yawauto poseNoise = noiseModel::Diagonal::Sigmas(poseConstraint * 0.1);graph.add(PriorFactor<Pose3>(Symbol('x', 0), initialPose, poseNoise));// 输出初始位姿std::cout << "Initial Pose:\n" << initialPose << std::endl;// 观测到的平面// OrientedPlane3 observedPlane1(0, 0, 1, -1.0); // 假设z是我们的目标// 添加多个观测平面std::vector<OrientedPlane3> observedPlanes = {OrientedPlane3(0, 0, 1, -1.5),  // 平面 1OrientedPlane3(0, 0, 1, -2.0),  // 平面 2OrientedPlane3(0, 0, 1, -1.0),  // 平面 3OrientedPlane3(0, 0, 1, -0.5)   // 平面 4// 其他平面可根据需求添加};auto planeNoise = noiseModel::Isotropic::Sigma(4, 1e-3);// 添加因子// graph.add(boost::make_shared<CustomOrientedPlane3Factor>(observedPlane1, planeNoise, Symbol('x', 0)));// 为所有平面添加因子for (size_t i = 0; i < observedPlanes.size(); ++i) {graph.add(boost::make_shared<CustomOrientedPlane3Factor>(observedPlanes[i], planeNoise, Symbol('x', 0)));}Values initialEstimate;initialEstimate.insert(Symbol('x', 0), initialPose);GaussNewtonParams params;params.setMaxIterations(10);params.setRelativeErrorTol(1e-5);GaussNewtonOptimizer optimizer(graph, initialEstimate, params);Values result = optimizer.optimize();// 输出优化结果std::cout << "Optimized Pose:\n" << result.at<Pose3>(Symbol('x', 0)) << std::endl;return 0;
}

http://www.ppmy.cn/embedded/154352.html

相关文章

计算机后端学习路径(精华版)

这张计算机后端学习路径图就像是你的私人导航&#xff0c;指引你从掌握基础语言开始&#xff0c;如Python或Java&#xff0c;一路升级到理解服务器、数据库和API设计的奥秘。随着你的进步&#xff0c;它还会教你如何处理更酷炫的东西&#xff0c;比如云端服务、安全措施以及怎样…

基于CANoe16的新书《CANoe开发与CAPL编程实践》

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

SQL记录

1、FIND_IN_SET(BASE_CODE,#{baseCode}) FIND_IN_SET 函数用于在一个逗号分隔的字符串列表中查找一个指定的字符串&#xff0c;并返回其在列表中的位置。如果找到该字符串&#xff0c;则返回其在列表中的位置&#xff08;从1开始计数&#xff09;&#xff1b;如果没有找到或参…

Linux中通过frp实现内网穿透

1、准备工作 准备一台公网服务器&#xff08;云服务器&#xff09;&#xff0c;推荐阿里云或者腾讯云都可以 需要下载好frp安装包Linux端的和Windows端的安装包 网址&#xff1a;Releases fatedier/frp (github.com)https://github.com/fatedier/frp/releases 2、下载frp_0…

《基于深度学习的多色光度巡天项目天文目标检测框架》论文精读

A deep learning based astronomical target detection framework for multi-colour photometry sky survey projects 摘要 多色测光巡天项目将利用广角望远镜和几种不同的滤光片获得不同颜色的天体图像。不同颜色的图像可以揭示天体的不同组成部分。我们将能够利用这些图像研…

ros2-6.4.4 两轮差速控制机器人(问题解决)

ros2-6.4.4 两轮差速控制机器人的问题-CSDN博客 上次遇到的问题&#xff0c;经过查看ros2 node list 之后&#xff0c;发现有多个 /robot_state_publisher 这是不正常的&#xff0c;应该是我看视频6.2 的没有及时关闭导致冲突了。 没有修改代码&#xff0c;单纯的重启就解决…

密码机服务器在云计算中的应用与挑战

随着云计算技术的迅猛发展和普及&#xff0c;密码机服务器作为一种高效、专业的数据安全解决方案&#xff0c;正在云计算领域中扮演着越来越重要的角色。本文将探讨密码机服务器在云计算中的应用及其面临的挑战。 云计算技术涉及大量的数据传输和存储&#xff0c;数据的安全性和…

Qt C++ QStatusbar 显示表示状态的图片

1、前言 在C Qt编程中默认主窗口MainWindow底下自带控件QStatusbar&#xff0c;很多情况下都使用其显示程序的连接状态或开关状态&#xff0c;因为时常需要将图片设置为圆形显示&#xff0c;所以这里记录一下常用的设置的代码&#xff0c;方便以后复制粘贴。 2、封装设置状态…