前言

这篇博客主要记录了我在深蓝学院视觉slam课程中的课后习题,因为是为了统计知识点来方便自己以后查阅,所以有部分知识可能不太严谨,如果给大家造成了困扰请见谅,大家发现了问题也可以私信或者评论给我及时改正,欢迎大家一起探讨。其他章的笔记可以在我的首页文章中查看。

整个作业的代码和文档都可以参考我的GitHub存储库GitHub - 1481588643/vslam

如果想要了解视觉slam其他章节的内容,也可以查阅以下链接

https://blog.csdn.net/m0_61238051/article/details/120603418?spm=1001.2014.3001.5501

视觉slam学习笔记以及课后习题《第二讲三维物体刚体运动》_m0_61238051的博客-CSDN博客

https://blog.csdn.net/m0_61238051/article/details/120813741

一.群的性质 (1 分,约 1 小时)
课上我们讲解了什么是群。请根据群定义,求解以下问题:
1. {Z, +} 是否为群?若是,验证其满足群定义;若不是,说明理由。
2. {N, +} 是否为群?若是,验证其满足群定义;若不是,说明理由。
3. 解释什么是阿贝尔群。并说明矩阵及乘法构成的群是否为阿贝尔群。
其中 Z 为整数集,N 为自然数集。

答:阿贝尔群(Abelian Group),又称交换群或加群,是这样一类群:

它由自身的集合 G 和二元运算 * 构成。它除了满足一般的群公理,即运算的结合律、G 有单位元、所有 G 的元素都有逆元之外,还满足交换律公理。因为阿贝尔群的群运算满足交换律和结合律,群元素乘积的值与乘法运算时的次序无关。

矩阵即使是可逆矩阵,一般不形成在乘法下的阿贝尔群,因为矩阵乘法一般是不可交换的。但是某些矩阵的群是在矩阵乘法下的阿贝尔群 - 一个例子是 2x2 旋转矩阵的群。

三. 验证向量叉乘的李代数性质 (2 分,约 1 小时)
我们说向量和叉乘运算构成了李代数,现在请你验证它。书中对李代数的定义为:李代数由一个集合
V,一个数域 F 和一个二元运算 [, ] 组成。如果它们满足以下几条性质,称 (V, F, [, ]) 为一个李代数,记作
g。
1. 封闭性 ∀X, Y ∈ V, [X, Y ] ∈ V.
2. 双线性 ∀X, Y , Z ∈ V, a, b ∈ F, 有:
[aX + bY , Z] = a[X, Z] + b[Y , Z],
3. 自反性 1
[Z, aX + bY ] = a[Z, X] + b[Z, Y ].
∀X ∈ V, [X, X] = 0.
4. 雅可比等价
∀X, Y , Z ∈ V, [X, [Y , Z]] + [Y , [Z, X]] + [Z, [X, Y ]] = 0.
其中二元运算被称为李括号。
现取集合 V = R 3 ,数域 F = R,李括号为:
[a, b] = a × b.
请验证 g = (R 3 , R, ×) 构成李代数。

 三. 推导 SE(3) 的指数映射 (1 分,约 1 小时)

 四.伴随 (2 分,约 1 小时)

 五.常见函数的求导应用 (2 分,约 2 小时)

六. 轨迹的描绘 (2 分,约 1 小时)
我们通常会记录机器人的运动轨迹,来观察它的运动是否符合预期。大部分数据集都会提供标准轨迹
以供参考,如 kitti、TUM-RGBD 等。这些文件会有各自的格式,但首先你要理解它的内容。记世界坐标
系为 W ,机器人坐标系为 C,那么机器人的运动可以用 T W C 或 T CW 来描述。现在,我们希望画出机器
人在世界当中的运动轨迹,请回答以下问题:
1. 事实上,T W C 的平移部分即构成了机器人的轨迹。它的物理意义是什么?为何画出 T W C 的平移
部分就得到了机器人的轨迹?
2. 我为你准备了一个轨迹文件(code/trajectory.txt)。该文件的每一行由若干个数据组成,格式为
[t, t x , t y , t z , q x , q y , q z , q w ],
其中 t 为时间,t x , t y , t z 为 T W C 的平移部分,q x , q y , q z , q w 是四元数表示的 T W C 的旋转部分,q w
为四元数实部。同时,我为你提供了画图程序 draw_trajectory.cpp 文件。该文件提供了画图部分
的代码,请你完成数据读取部分的代码,然后书写 CMakeLists.txt 以让此程序运行起来。注意我
们需要用到 Pangolin 库来画图,所以你需要事先安装 Pangolin(如果你做了第一次作业,那么现
在已经安装了)。CMakeLists.txt 可以参照 ORB-SLAM2 部分。


#include <unistd.h>
#include <string>
#include <iostream>
#include <fstream>#include <Eigen/Core>
#include <sophus/se3.hpp>// need pangolin for plotting trajectory
#include <pangolin/pangolin.h>using namespace std;// path to trajectory file
string trajectory_file = "../trajectory.txt";// function for plotting trajectory, don't edit this code
// start point is red and end point is blue
void DrawTrajectory(vector<Sophus::SE3d, Eigen::aligned_allocator<Sophus::SE3d>>);int main(int argc, char **argv) {vector<Sophus::SE3d, Eigen::aligned_allocator<Sophus::SE3d>> poses;/// implement pose reading code// start your code here (5~10 lines)ifstream f_str(trajectory_file);if (!f_str){cout << "cannot find the file of trajectory at: " << trajectory_file << endl;return 1;}while(!f_str.eof()) //end of file{double time, tx, ty, tz, qx, qy, qz, w;f_str >> time >> tx >> ty >> tz >> qx >> qy >> qz >> w;Eigen::Quaterniond q= Eigen::Quaterniond(w, qx, qy, qz).normalized();Eigen::Vector3d t(tx, ty, tz);Sophus::SE3d SE3_qt(q, t);poses.push_back(SE3_qt);}cout << "complete it! read total: " << poses.size() << endl;// end your code here// draw trajectory in pangolinDrawTrajectory(poses);return 0;
}void DrawTrajectory(vector<Sophus::SE3d, Eigen::aligned_allocator<Sophus::SE3d>> poses) {if (poses.empty()) {cerr << "Trajectory is empty!" << endl;return;}// create pangolin window and plot the trajectorypangolin::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),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, pangolin::Attach::Pix(175), 1.0, -1024.0f / 768.0f).SetHandler(new pangolin::Handler3D(s_cam));while (!pangolin::ShouldQuit()) {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() - 1; i++) {glColor3f(1 - (float) i / poses.size(), 0.0f, (float) i / poses.size());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}}

七.* 轨迹的误差 (2 分,约 1 小时)

#include <iostream>
#include <fstream>
#include <unistd.h>
#include <pangolin/pangolin.h>
#include <sophus/se3.hpp>using namespace Sophus;
using namespace std;string groundtruth_file = "../groundtruth.txt";
string estimated_file = "../estimated.txt";typedef vector<Sophus::SE3d, Eigen::aligned_allocator<Sophus::SE3d>> TrajectoryType;void DrawTrajectory(const TrajectoryType &gt, const TrajectoryType &esti);TrajectoryType ReadTrajectory(const string &path);int main(int argc, char **argv) {TrajectoryType groundtruth = ReadTrajectory(groundtruth_file);TrajectoryType estimated = ReadTrajectory(estimated_file);assert(!groundtruth.empty() && !estimated.empty());assert(groundtruth.size() == estimated.size());// compute rmsedouble rmse = 0;for (size_t i = 0; i < estimated.size(); i++) {Sophus::SE3d p1 = estimated[i], p2 = groundtruth[i];double error = (p2.inverse() * p1).log().norm();rmse += error * error;}rmse = rmse / double(estimated.size());rmse = sqrt(rmse);cout << "RMSE = " << rmse << endl;DrawTrajectory(groundtruth, estimated);return 0;
}TrajectoryType ReadTrajectory(const string &path) {ifstream fin(path);TrajectoryType trajectory;if (!fin) {cerr << "trajectory " << path << " not found." << endl;return trajectory;}while (!fin.eof()) {double time, tx, ty, tz, qx, qy, qz, qw;fin >> time >> tx >> ty >> tz >> qx >> qy >> qz >> qw;Sophus::SE3d p1(Eigen::Quaterniond(qw, qx, qy, qz), Eigen::Vector3d(tx, ty, tz));trajectory.push_back(p1);}return trajectory;
}void DrawTrajectory(const TrajectoryType &gt, const TrajectoryType &esti) {// create pangolin window and plot the trajectorypangolin::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),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, pangolin::Attach::Pix(175), 1.0, -1024.0f / 768.0f).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 < gt.size() - 1; i++) {glColor3f(0.0f, 0.0f, 1.0f);  // blue for ground truthglBegin(GL_LINES);auto p1 = gt[i], p2 = gt[i + 1];glVertex3d(p1.translation()[0], p1.translation()[1], p1.translation()[2]);glVertex3d(p2.translation()[0], p2.translation()[1], p2.translation()[2]);glEnd();}for (size_t i = 0; i < esti.size() - 1; i++) {glColor3f(1.0f, 0.0f, 0.0f);  // red for estimatedglBegin(GL_LINES);auto p1 = esti[i], p2 = esti[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}}

视觉slam学习笔记以及课后习题《第三讲李群李代数》相关推荐

  1. 视觉slam学习笔记以及课后习题《第五讲特征点法视觉里程计》

    这篇博客主要记录了我在深蓝学院视觉slam课程中的课后习题,因为是为了统计知识点来方便自己以后查阅,所以有部分知识可能不太严谨,如果给大家造成了困扰请见谅,大家发现了问题也可以私信或者评论给我及时改正 ...

  2. 视觉SLAM学习笔记

    中英文对照表 中文 英文 计算机视觉 Computer Vision 人工智能 Artificial Intelligence 单目相机 Monocular 双目相机 Stereo 深度相机 RGB- ...

  3. 《C语言程序设计》谭浩强-学习笔记以及课后习题答案(考前复习/考研/专升本)

    此笔记是几年前为了本人考试而学而写,今日回首感慨良多,便把尘封多年在旧电脑中的学习笔记翻出来分享给大家 此笔记参考书籍: <C语言程序设计>谭浩强 根据前九章内容主要知识点进行梳理 如果有 ...

  4. Ubuntu LInux操作系统 学习笔记及课后习题解答

    1.ubuntu基本使用 1.1 GNU GPL GNU通用公共许可证(general public license),开放.自由的精神,任何软件加上GPL协议后,即成为自由的软件,任何人均可获得,同 ...

  5. 《视觉SLAM十四讲 第二版》笔记及课后习题(第一讲)

    前言 之所以想要写这个系列的博客,是因为想要总结一下高博的<SLAM视觉十四讲第二版>的各章内容以及自己对书后习题的一些做法,也算是对自己学习过程的一个总结和回顾.博客分为两个大部分,即读 ...

  6. 数字电子技术基础第三版杨志忠_阎石数字电子技术基础第6版笔记和课后习题详解...

    阎石<数字电子技术基础>(第6版)笔记和课后习题(含考研真题)详解 第1章 数制和码制 1.1 复习笔记 本章作为<数字电子技术基础>的开篇章节,是数字电路学习的基础.本章介绍 ...

  7. 范里安中级微观经济学(第9版)分析笔记和课后习题答案解析-完整版 范里安《微观经济学:现代观点》(第9版)笔记和课后习题详解!

    范里安中级微观经济学(第9版)分析笔记和课后习题答案解析-完整版  摘自硕达学习网 范里安<微观经济学:现代观点>(第9版)笔记和课后习题详解! 最新电子书(题库) 范里安微观经济学现代观 ...

  8. [杨可桢]机械设计基础题库 机械设计基础习题 2022机械设计基础考试题答案 杨可桢《机械设计基础》(第7版)笔记和课后习题(含考研真题)详解

    [杨可桢]机械设计基础题库  机械设计基础习题  2022机械设计基础考试题答案-硕达学习网 杨可桢<机械设计基础>(第7版)笔记和课后习题(含考研真题)详解 目录 第1章 平面机构的自由 ...

  9. SLAM学习笔记(十九)开源3D激光SLAM总结大全——Cartographer3D,LOAM,Lego-LOAM,LIO-SAM,LVI-SAM,Livox-LOAM的原理解析及区别

    本文为我在浙江省北大信研院-智能计算中心-情感智能机器人实验室-科技委员会所做的一个分享汇报,现在我把它搬运到博客中. 由于参与分享汇报的同事有许多是做其他方向的机器人工程师(包括硬件.控制等各方面并 ...

最新文章

  1. Java基础:正则表达式
  2. 多线程的三种实现方法
  3. python网页登录验证码不显示_进网页需要验证码?不好意思,Python从来不惧各种验证码!...
  4. mysql 锁表 for update,MySQL中select * for update锁表的问题(转)
  5. 凸函数优化问题的相关讨论
  6. 运营商级ICT项目建设之雪亮工程方案,提升群众安全感
  7. 中心极限与大数定理律的关系_21厦大数学考研 | 数列与函数极限复习建议!
  8. 没有超级英雄?自己做一个java漫威英雄手办商城系统
  9. 多节点部署执行定时任务选举单一节点解决方案---redis
  10. java公告栏源码_公告栏view
  11. 运动模糊图像恢复处理-matlab实现
  12. 图片转为pdf怎么弄?发送图片安全高效的格式
  13. 生成自定义时长的静音音频 | Java工具类
  14. 为什么越来越多的网站域名不加www前缀?
  15. matlab feedforward,premnmx(mapminmax) newff (feedforwardnet) tramnmx 如何使用
  16. 2021安庆市地区高考成绩排名查询,安庆中学排名前十名,2021年安庆中学排名一览表...
  17. sql(集合,行专列,上下级)
  18. 大型网站技术架构:核心原理与案例分析pdf
  19. 教你如何用C语言设计一个有趣的猜数字小游戏
  20. 30岁以后的华丽转身

热门文章

  1. Unity3D基础7:Transform组件
  2. bzoj 1124: [POI2008]枪战Maf(贪心)
  3. bzoj 4293: [PA2015]Siano(线段树)
  4. 树状数组--快捷的线段树
  5. bzoj 3798: 特殊的质数(分块打表)
  6. 2016ICPC沈阳站总结
  7. C - 二进制换十进制(简单)
  8. openlayers5学习笔记-001
  9. HDU--1054--Strategic Game【最小点覆盖】
  10. 极验滑动验证码破解分析