参考文章1
参考文章2
#include <pangolin/pangolin.h> #include <Eigen/Core> #include <unistd.h> // 本例演示了如何画出一个预先存储的轨迹 using namespace std; using namespace Eigen; //trajectory文件的路径(可以使用相对路径,也可以使用绝对路径) string trajectory_file = "../trajectory.txt"; //画轨迹函数的声明 void DrawTrajectory(vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>>); int main(int argc, char **argv) { vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses;//容器的方式存储 //因为类型是Eigen的Isometry3d和cpp的类内存分配不一样,所以要指定内存的分配方式 //即:Eigen::aligned_allocator< Isometry3d > ifstream fin(trajectory_file); //读文件 //未成功读取 if (!fin) { cout << "cannot find trajectory file at " << trajectory_file << endl; return 1; } //一行一行读取,直到文件尾标志(efo标志) 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() << " pose entries" << endl; // draw trajectory in pangolin DrawTrajectory(poses); return 0; } /*******************************************************************************************/ void DrawTrajectory(vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses) { // create pangolin window and plot the trajectory pangolin::CreateWindowAndBind("Trajectory Viewer", 1024, 768);//新建窗口,参数分别为:窗口名称、窗口的长和宽 glEnable(GL_DEPTH_TEST);//启用深度渲染,当需要显示3D模型时需要打开,根据目标的远近自动隐藏被遮挡的模型 glEnable(GL_BLEND);//表示窗口使用颜色混合模式,让物体显示半透明效 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /*** 设置颜色RGBA混合因子,前面参数表示源因子,后面参数表示目标因子 GL_ZERO:表示使用0.0作为权重因子 GL_ONE : 表示使用1.0作为权重因子 GL_SRC_ALPHA :表示使用源颜色的alpha值来作为权重因子 GL_DST_ALPHA :表示使用目标颜色的alpha值来作为权重因子 GL_ONE_MINUS_SRC_ALPHA: 表示用1.0-源颜色的alpha的值来作为权重因子 GL_ONE_MINUS_DST_ALPHA: 表示用1.0-目标颜色的alpha的值来作为权重因子 GL_SRC_COLOR>:表示用源颜色的四个分量作为权重因子 在画图的过程中如果程序glClearColor();glColor3f()则后者为源颜色,前者的颜色为目标颜色以上的GL_SRC_ALPHA和GL_ONE_MINUS_SRC_ALPHA是最常用的混合模式 ***/ //创建相机视图 pangolin::OpenGlRenderState s_cam( pangolin::ProjectionMatrix(1024, 768, 500, 500, 512, 389, 0.1, 1000), pangolin::ModelViewLookAt(0, -0.1, -1.8, 0, 0, 0, 0.0, -1.0, 0.0) ); //ProjectionMatrix()设置相机内参,参数分别表示相机分辨率(2),焦距(1),相机光心(3),最远最大距离(2) //ModelViewLookAt()设置观看视角,上文对应的意思是在世界坐标(0,-0.1,-1.8)处观看坐标原点(0,0,0)并设置Y轴向上 /** 另一种解释 定义观测方位向量:观测点位置:(mViewpointX mViewpointY mViewpointZ) 观测目标位置:(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) .SetHandler(new pangolin::Handler3D(s_cam)); /**创建交互视图view,用于显示上一步摄像机所“拍摄”到的内容,,setBounds()函数前四个参数依次表示视图在视窗中的范围(下、上、左、右),显示界面长宽比*/ 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));//0.1是为了让图看起来舒服,不会太大 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); 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); // sleep 5 ms } }
欢迎SLAMers加QQ:258404070 一起学习SLAM
有问题请留言