【SLAM学习】基于Pangolin绘制运动轨迹

news2025/1/21 6:36:41

Pangolin是一个轻量级的跨平台视图控制库,主要用于可视化、交互和调试三维数据。该库提供了一系列图形界面工具,包括窗口、OpenGL渲染器、3D相机、图像显示等,可以方便地进行三维数据可视化和交互。

Pangolin库的主要特点如下:

  1. 轻量级:Pangolin库的代码量很少,只依赖于少量的第三方库,因此非常轻量级,可以很容易地集成到其他项目中。

  2. 跨平台:Pangolin库支持跨平台开发,可以在Windows、Linux和Mac OS等操作系统上使用。

  3. 多功能:Pangolin库提供了丰富的图形界面工具,包括窗口、OpenGL渲染器、3D相机、图像显示等,可以满足不同需求的开发者。

  4. 易于使用:Pangolin库的接口简单易用,可以快速搭建三维数据可视化和交互界面,同时还提供了丰富的示例程序和文档,方便开发者上手使用。

  5. 开源免费:Pangolin库是开源的,使用MIT许可证发布,可以免费使用、修改和分发。

Pangolin库下载:

https://github.com/stevenlovegrove/Pangolin/tree/1ec721d59ff6b799b9c24b8817f3b7ad2c929b83

百度网盘下载链接:链接: https://pan.baidu.com/s/1W75vsmctFheksPfExzpU4A 提取码: rwg2 

// pangolin库
#include <pangolin/pangolin.h>
// Eigen库
#include <Eigen/Core>
#include <Eigen/Dense>

#include <unistd.h>

#include <string>
#include <vector>
#include <fstream>

// 演示了如何画出一个预先存储的轨迹

std::string trajectory_file = "./trajectory.txt"; // 轨迹文件
// 格式为:time,tx,ty,tz,qx,qy,qz,qw


void DrawTrajectory(std::vector<Eigen::Isometry3d,Eigen::aligned_allocator<Eigen::Isometry3d>> poses){
    // create pangolin window and plot the trajectory
    pangolin::CreateWindowAndBind("Trajectory Viewer",1024,768); // 创建窗口
    
    glEnable(GL_DEPTH_TEST); // 开启深度测试
    glEnable(GL_BLEND); // 开启混合渲染
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // 设置混合函数

    pangolin::OpenGlRenderState s_cam(
        pangolin::ProjectionMatrix(1024, 768, 500, 500, 512, 389, 0.1, 1000), //投影矩阵
        // 屏幕的宽度、高度、相机的水平视角、垂直视角、相机在z轴上的位置、相机到屏幕的距离的最小值和最大值。
        pangolin::ModelViewLookAt(0, -0.1, -1.8, 0, 0, 0, 0.0, -1.0, 0.0) // 视图矩阵
        // 相机的位置、相机观察的目标点、相机的朝向向量
    );

    pangolin::View &d_cam = pangolin::CreateDisplay()
        .SetBounds(0.0, 1.0, 0.0, 1.0, -1024.0f / 768.0f)
        // 表示窗口在x轴和y轴上的起点和终点位置,以及窗口的宽高比,宽高比为负数,则实际上是768:1024
        .SetHandler(new pangolin::Handler3D(s_cam));

    while (pangolin::ShouldQuit() == false) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清空颜色缓冲区和深度缓冲区
        d_cam.Activate(s_cam); // 激活显示窗口和渲染状态对象
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // 设置清屏颜色
        glLineWidth(2); // 设置线宽

        for (size_t i = 0; i < poses.size(); i++) {
            // 画每个位姿的三个坐标轴
            Eigen::Vector3d Ow = poses[i].translation(); // 获取相机位姿矩阵中的平移部分,即相机的位置。
            Eigen::Vector3d Xw = poses[i] * (0.1 * Eigen::Vector3d(1, 0, 0)); // 获取x轴方向的单位向量,乘以0.1是为了调整坐标轴线段的长度
            Eigen::Vector3d Yw = poses[i] * (0.1 * Eigen::Vector3d(0, 1, 0)); // 获取y轴方向的单位向量
            Eigen::Vector3d Zw = poses[i] * (0.1 * Eigen::Vector3d(0, 0, 1)); // 获取z轴方向的单位向量
            
            glBegin(GL_LINES); // 开始绘制线段
            glColor3f(1.0, 0.0, 0.0); // 设置线段颜色 rgb
            // 绘制线段的两个端点
            glVertex3d(Ow[0], Ow[1], Ow[2]); // 原点的坐标
            glVertex3d(Xw[0], Xw[1], Xw[2]); // x轴方向的坐标    ----> 绘制x轴线段 为红色

            glColor3f(0.0, 1.0, 0.0);
            glVertex3d(Ow[0], Ow[1], Ow[2]);// 原点的坐标
            glVertex3d(Yw[0], Yw[1], Yw[2]);// y轴方向的坐标    ----> 绘制y轴线段 为绿色

            glColor3f(0.0, 0.0, 1.0);
            glVertex3d(Ow[0], Ow[1], Ow[2]);// 原点的坐标
            glVertex3d(Zw[0], Zw[1], Zw[2]);// z轴方向的坐标    ----> 绘制z轴线段 为蓝色
            glEnd(); // 结束绘制
        }
        
        // 画出连线
        for (size_t i = 0; i < poses.size(); i++) {
            glColor3f(0.0, 0.0, 0.0); // 黑色
            glBegin(GL_LINES); // 开始绘制线段
            auto p1 = poses[i], p2 = poses[i + 1]; // 获取相邻相机位姿
            glVertex3d(p1.translation()[0], p1.translation()[1], p1.translation()[2]); // 绘制线段的两个端点(相邻相机位姿的位置)
            glVertex3d(p2.translation()[0], p2.translation()[1], p2.translation()[2]);
            glEnd();
        }
        pangolin::FinishFrame(); // 结束当前帧的绘制
        usleep(5000);   // sleep 5ms ,每5ms绘画一次

    }
}

int main(int argc,char** argv)
{
    std::vector<Eigen::Isometry3d,Eigen::aligned_allocator<Eigen::Isometry3d>> poses;
    
    std::ifstream fin(trajectory_file);
    if(!fin){
        std::cout << "cannot find trajectory file at " << trajectory_file << std::endl;
        return -1;
    }

    while (!fin.eof()) {
        double time, tx, ty, tz, qx, qy, qz, qw;
        fin >> time >> tx >> ty >> tz >> qx >> qy >> qz >> qw;
        Eigen::Isometry3d Twr(Eigen::Quaterniond(qw, qx, qy, qz));
        Twr.pretranslate(Eigen::Vector3d(tx, ty, tz));
        poses.push_back(Twr);
    }
    std::cout << "read total " << poses.size() << " pose entries" << std::endl;

    // draw trajectory in pangolin
    DrawTrajectory(poses);
    
    return 0;
}

 CMakeLists.txt文件:

# 声明要求的cmake最低版本
cmake_minimum_required(VERSION 2.8)

# 声明一个cmake工程
project(Examples)

find_package(Pangolin REQUIRED)

# 添加头文件
include_directories(
    "/usr/include/eigen3"
    ${Pangolin_INCLUDE_DIRS}
)

# 添加可执行程序
add_executable(plotTrajectory plotTrajectory.cc)
target_link_libraries(plotTrajectory ${Pangolin_LIBRARIES})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/511146.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot的多配置文件

文章目录 1.配置文件的命名规则2.配置文件选择3.配置文件的优先级 1.配置文件的命名规则 配置文件一般要求以application开头&#xff0c;可以是.yml结尾的文件&#xff0c;也可以是.properties结尾的文件。 2.配置文件选择 当有多个配置文件&#xff0c;需要指定其中一个生…

关于C语言取余运算的那些大坑

0.前言 您好&#xff0c;这里是limou3434的一篇个人博文&#xff0c;感兴趣的话您也可以看看我的其他文章&#xff0c;本次我想给您带来的是关于C语言操作符‘%’的一些奇怪现象以及背后的原理解释&#xff0c;本章用了一点点python语法&#xff08;比如在python中“//”是整除…

C++开发环境的搭建-Windows:VSCode+mingw64+CMake

文章目录 一、软件安装1. 网址及下载的软件2. VSCode中配置关于C的最简插件&#xff1a; 二、C调试环境的编译要求1. 在编译时要带-g参数2. 多文件编译需要分步编译 三、VSCode的调试配置如下&#xff1a;1. 单文件调试设置4. 多文件调试设置 一、软件安装 1. 网址及下载的软件…

【JavaEE进阶】——第六节.第一个MyBatis程序

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;JavaEE进阶 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目录 前…

计算机视觉(5)—— 图像分类

目录 五、图像分类 5.1 AlexNet 5.2 VGG 5.3 GoogLeNet、Inception 5.3.1 Inception V1 5.3.2 Inception V2 5.3.3 Inception V3 5.3.4 Inception V4 5.4 ResNet 残差网络 5.4.1 ResNet 5.4.2 ResNeXt 5.5 CNN设计准则 五、图像分类 5.1 AlexNet 5.2 VGG 5.3 Go…

【剑指 Offer】05,替换字符创中的空格;难度等级:简单。易错点:C++中 char 和 string 类型的转换

【剑指 Offer】05&#xff0c;替换字符创中的空格&#xff1b;难度等级&#xff1a;简单。 文章目录 一、题目二、题目背景三、我的解答四、易错点五、知识点&#xff1a;char 和 string 类型的转换 一、题目 二、题目背景 在网络编程中&#xff0c;如果 URL 参数中含有特殊字…

消息推送平台的实时数仓?!flink消费kafka消息入到hive

大家好&#xff0c;3y啊。好些天没更新了&#xff0c;并没有偷懒&#xff0c;只不过一直在安装环境&#xff0c;差点都想放弃了。 上一次比较大的更新是做了austin的预览地址&#xff0c;把企业微信的应用和机器人消息各种的消息类型和功能给完善了。上一篇文章也提到了&#…

windows安装Anaconda

Anacond是什么&#xff1f; 和Python有啥关系&#xff1f; 1、Anacond 是一个python的发行版&#xff0c;包括了python和很多常见的软件库, 和一个包管理器conda。常见的科学计算类的库都包含在里面了&#xff0c;使得安装比常规python安装要容易。 2、Anaconda是专注于数据分…

分布式系统概念和设计——时间和全局状态(分布式系统中的时间问题)

分布式系统概念和设计 时间和全局状态 全局物理时间的缺乏使我们很难查明分布式程序的执行时状态。 我们经常需要知道当进程B处在某种状态依赖进程是什么状态&#xff0c;但不能通过依靠物理时钟理解一个同一个时刻到底是什么情况。 维护分布数据一致性算法检查发送给服务器的…

数学(三) -- LC[1010][1015] 可被 K 整除的最小整数

1 可被 K 整除的最小整数 1.1 题目描述 题目链接&#xff1a;https://leetcode.cn/problems/smallest-integer-divisible-by-k/description/ 1.2 思路分析 模运算 如果让你计算 1234 ⋅ 6789 1234 \cdot 6789 1234⋅6789 的个位数&#xff0c;你会如何计算&#xff1f; 由于…

c高级day2

#include <stdio.h> #include <stdlib.h> #include <string.h>int arrMAX_1(void *p,int n,int m,int x,int y); int arrMAX_2(void *p,int n,int m,int x,int y); int main(int argc, const char *argv[]) {int n0,m0;printf("请输入行数i 列数j\n&quo…

Baumer工业相机堡盟工业相机如何进行多个工业相机IP地址配置

Baumer工业相机堡盟工业相机如何进行多个工业相机IP地址配置 Baumer工业相机Baumer工业相机进行多相机IP配置的技术背景Baumer工业相机如何进行多相机IP配置1.配置Baumer工业相机连接的PC端IP地址2.配置Baumer工业相机的IP地址 Baumer工业相机 Baumer工业相机堡盟相机是一种高…

R 中的探索性相关分析

动动发财的小手&#xff0c;点个赞吧&#xff01; 本文[1] 相关分析是探索两个或多个变量之间关系的最基本和最基础的方法之一。您可能已经在某个时候使用 R 执行过相关分析&#xff0c;它可能看起来像这样&#xff1a; cor_results <- cor.test(my_data$x, my_data$y, …

手机上调试pc端电脑上的项目

文章目录 前言1、window r 打开电脑命令窗口并输入cmd点击确定或者敲击回车键2、在cmd命令行面板上输入ipconfig获取本电脑的ip地址3、在手机浏览器中输入http://192.168.XX.XX:8080 即可 前言 手机上调试电脑运行的项目的前提条件是手机和电脑公用一个局域网&#xff08;也就…

APP 性能优化你掌握的怎么样?简单聊聊?

产品性能是每个技术团队比较关心的一件事&#xff0c;不管是产品上线前到上线后&#xff0c;都需要对产品进行性能监控和优化&#xff0c;如果产品在运行过程中出现了问题&#xff0c;是很影响用户的体验感受。 所以在一些大厂技术团队中&#xff0c;是非常看重个人性能优化的…

面向开发人员的 ChatGPT 提示词教程中文版

面向开发人员的 ChatGPT 提示词教程中文版 1. 指南1-1. 提示的指南1-2. 配置1-3. 提示语原则原则 1: 写出清晰而具体的指示技巧 1: 使用分隔符来清楚地表明输入的不同部分技巧 2: 要求提供结构化的输出技巧 3: 要求模型检查条件是否得到满足技巧 4: "少许样本"提示 原…

为你推荐一款最好用的免费截图工具-Snipaste,截图高清、智能模糊还支持滚动长截图!!!

写文章经常需要插入截图&#xff0c; 但是常常很难有顺手的截图工具&#xff0c; 常见的难题是&#xff1a; 很难滚动长屏截图&#xff0c; 截图中马赛克处理很麻烦&#xff0c; 输出的截图图像质量差。 经过大量的工具使用对比&#xff0c; 这里推荐一个最好用的截图工具。 Sn…

Fotran学习:chapter8函数

1.子程序(subrountine)的使用 把常常用于使用、具有特定功能的程序代码独立出来&#xff0c;封装程子程序&#xff0c;以后调用使用call即可。 program chapter4_exercise !主程序implicit nonecall sub1()call sub2()pauseend program chapter4_exercisesubroutine sub1() !子…

产品经理制,互联网公司发扬光大的

产品经理制&#xff0c;在互联网公司发扬光大 张小龙被称作&#xff1a;七星产品经理 其实&#xff0c;中小企业老板基本是首席产品经理 趣讲大白话&#xff1a;像带孩子一样做产品 【趣讲信息科技160期】 **************************** 产品经理制核心问题解决的是&#xff1a…

STM32F4_随机数发生器(RNG)

目录 1. 随机数发生器RNG是什么 2. RNG随机发生器框图 3. 运行RNG 4. RNG寄存器 4.1 RNG控制寄存器&#xff1a;RNG_CR 4.2 RNG状态寄存器&#xff1a;RNG_SR 4.3 RNG数据寄存器&#xff1a;RNG_DR 5. 库函数配置随机数发生器 6. 实验程序 6.1 main.c 6.2 RNG.c 6.…