SLAM 十四讲(第二版) ch3 (2)中的plotTrajectory.cpp源码详细注释

plotTrajectory.cpp中设计到pangolin的使用,故因先安装pangolin ,同时需要安装可视化工具pcl

该代码实现的功能就是读取一个轨迹文件,然后用pcl显示轨迹(轨迹文件中包含的其实就是相机的位姿势,分别是:时间,平移,四元数(旋转),其中四元数的前三位是虚数,最后一位才是实数)
此代码中,我遇到了一个问题:当读取的轨迹文件不对的时候,会让ubuntu界面卡死,因为OpenGL的原因??

//
// Created by wenbo on 2020/10/23.
//
#include <pangolin/pangolin.h>
#include <Eigen/Core>
#include <unistd.h>

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

using namespace std;
using namespace Eigen;
string trajectory_file = "./examples/trajectory.txt";
//定义一个画轨迹的函数
void DrawTrajectory(vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>>);
int main()
{
    
    
    vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses;// 定义容器  装poses(r到world坐标的变换矩阵)
    //  Eigen::aligned_allocator<Isometry3d> Eigen管理内存和C++11中的方法是不一样的,所以需要单独强调元素的内存分配和管理
    ifstream fin(trajectory_file);
    
    if (!fin)
    {
    
    
        cout<<"cannot find trajectory file at"<<"trajectory_file"<<endl;
    }
    while(!fin.eof())
    {
    
    
        double time ,tx,ty,tz,qx,qy,qz,qw;//定义获取文件中平移和四元数(旋转)的变量
        fin>>time>>tx>>ty>>tz>>qx>>qy>>qz>>qw;
        Isometry3d  Twr(Quaterniond(qw,qx,qy,qz));
                    Twr.pretranslate((Vector3d(tx,ty,tz)));
        poses.push_back(Twr);
    }
    cout<<"read total "<<poses.size()<<" poses entries "<<endl;
    //调用DrawTrajectory()函数
    DrawTrajectory(poses);
    return 0;
}
void DrawTrajectory(vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses)
{
    
    
    // 创建 pangolin 窗口,画轨迹
    //creat and set titles 、 width 、height of windows
    pangolin::CreateWindowAndBind(" Trajectory ", 1024, 768);
    //glEnable(GL_DEPTH_TEST)启用了之后,OpenGL在绘制的时候就会检查,当前像素前面是否有别的像素,如果别的像素挡道了它,那它就不会绘制,也就是说,OpenGL就只绘制最前面的一层。
    //当我们需要绘制透明图片时,就需要关闭它glDisable(GL_DEPTH_TEST);
    //并且打开混合 glEnable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);//??
    glEnable(GL_BLEND);//??
    //glBlendFunc(GLenum sfactor,GLenum dfactor);
    //源因子和目标因子是可以通过glBlendFunc函数来进行设置的。
    // glBlendFunc有两个参数,前者sfactor表示源因子,后者dfactor表示目标因子。
    //前者sfactor表示源颜色,后者dfactor表示目标颜色
    //GL_SRC_ALPHA:表示使用源颜色的alpha值来作为因子
    //GL_ONE_MINUS_SRC_ALPHA:表示用1.0减去源颜色的alpha值来作为因子(1-alpha)
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

    //OpenGlRenderState 创建一个相机的观察视图,模拟相机
    pangolin::OpenGlRenderState s_cam(//定义投影和初始模型视图矩阵
    //ProjectionMatrix 前两个参数是相机的宽高,紧接着四个参数是相机的内参,最后两个是最近和最远视距
            pangolin::ProjectionMatrix(1024,768,500,500,512,389,0.1,1000),
     //ModelViewLookAt 前三个参数是相机的位置,紧接着三个是相机所看的视点的位置,最后三个参数是一个向量,表示相机的的朝向
            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).
     //SetBounds() 前四个参数是视图在视窗中的范围(下 上 左 右)
            SetHandler(new pangolin::Handler3D(s_cam));
    //     SetHandle设置相机的视图句柄,需要用它来显示前面设置的 “相机” 所 “拍摄” 的内容
    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++)
        {
    
    
            //画出每个位子的三个坐标轴
            Vector3d Ow = poses[i].translation();
            Vector3d Xw = poses[i] * (0.1 * Vector3d(1, 0, 0));
            Vector3d Yw = poses[i] * (0.1 * Vector3d(0, 1, 0));
            Vector3d Zw = poses[i] * (0.1 * Vector3d(0, 0, 1));
            glBegin(GL_LINES);
            glColor3f(1.0, 0.0, 0.0);//设置x轴的颜色
            glVertex3d(Ow[0], Ow[1], Ow[2]);
            glVertex3d(Xw[0], Xw[1], Xw[2]);//把两个点连线,后面同理
            glColor3f(0.0, 1.0, 0.0);
            glVertex3d(Ow[0], Ow[1], Ow[2]);
            glVertex3d(Yw[0], Yw[1], Yw[2]);
            glColor3f(0.0, 0.0, 1.0);
            glVertex3d(Ow[0], Ow[1], Ow[2]);
            glVertex3d(Zw[0], Zw[1], Zw[2]);
            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);//休眠5ms
    }

}

运行结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/joun772/article/details/109246680