├── .dockerignore
├── .github
└── ISSUE_TEMPLATE
│ └── bug-report.md
├── .gitignore
├── README.md
├── doc
└── development-environment.png
├── docker-compose.yml
├── docker
├── .dockerignore
├── README.md
├── cpu.Dockerfile
├── doc
│ ├── 01-launch-instance.png
│ ├── 02-service-health-check.png
│ ├── 03-access-workspace.png
│ └── 04-mount-native-workspace-into-docker.png
├── environment
│ └── requirements.txt
├── image
│ ├── etc
│ │ ├── apt-fast.conf
│ │ ├── apt
│ │ │ ├── sources.list
│ │ │ └── sources.list.d
│ │ │ │ └── ros-latest.list
│ │ ├── default
│ │ │ └── keyboard
│ │ ├── hosts
│ │ ├── nginx
│ │ │ └── sites-enabled
│ │ │ │ └── default
│ │ ├── pip.conf
│ │ ├── resolv.conf
│ │ └── supervisor
│ │ │ ├── conf.d
│ │ │ ├── lxde.conf
│ │ │ └── webportal.conf
│ │ │ └── supervisord.conf
│ ├── root
│ │ ├── .gtkrc-2.0
│ │ └── Desktop
│ │ │ └── terminator.desktop
│ ├── startup.sh
│ ├── usr
│ │ ├── lib
│ │ │ └── webportal
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── app.ini
│ │ │ │ ├── app.py
│ │ │ │ ├── application
│ │ │ │ ├── __init__.py
│ │ │ │ ├── main
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── views.py
│ │ │ │ ├── static
│ │ │ │ │ └── tic.jpg
│ │ │ │ ├── templates
│ │ │ │ │ ├── aboutus.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── redirect.html
│ │ │ │ └── utils
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── log.py
│ │ │ │ ├── config.py
│ │ │ │ └── requirements.txt
│ │ └── share
│ │ │ └── doro-lxde-wallpapers
│ │ │ ├── desktop-items-0.conf
│ │ │ └── theme.jpeg
│ └── workspace
│ │ ├── data
│ │ └── nginx
│ │ │ └── noVNC.log
│ │ └── requirements.txt
└── installers
│ └── download-tini.sh
├── ubuntu-setup
├── README.md
└── doc
│ ├── external-disk
│ ├── README.md
│ └── images
│ │ ├── 00-cleanup-a-installer-disk.jpg
│ │ ├── 00-cleanup-b-ubuntu-disk.jpg
│ │ ├── 00-cleanup-format-disks.png
│ │ ├── 01-startup-disk-create--confirm.png
│ │ ├── 01-startup-disk-create--existing-ubuntu.png
│ │ ├── 01-startup-disk-create--select-device.png
│ │ ├── 02-BIOS-boot-config.jpg
│ │ ├── 02-BIOS-boot-sequence.jpg
│ │ ├── 02-BIOS-enter.jpg
│ │ ├── 02-BIOS-setup.jpg
│ │ ├── 02-BIOS-start-installation.jpg
│ │ ├── 03-install-ubuntu-a-keyboard.png
│ │ ├── 03-install-ubuntu-a-language.png
│ │ ├── 03-install-ubuntu-c-network.png
│ │ ├── 03-install-ubuntu-d-option.png
│ │ ├── 03-install-ubuntu-e-type.png
│ │ ├── 03-install-ubuntu-f-create-new-partition-confirm.png
│ │ ├── 03-install-ubuntu-f-create-new-partition-result.png
│ │ ├── 03-install-ubuntu-f-create-new-partition.png
│ │ ├── 03-install-ubuntu-g-02-boot.png
│ │ ├── 03-install-ubuntu-g-03-root.png
│ │ ├── 03-install-ubuntu-g-result.png
│ │ ├── 03-install-ubuntu-h-confirm.png
│ │ ├── 03-install-ubuntu-i-region.png
│ │ ├── 03-install-ubuntu-k-config.png
│ │ └── 03-install-ubuntu-l-finish.png
│ └── ubuntu-windows
│ └── Ubuntu双系统.pdf
└── workspace
├── .gitignore
├── README.md
├── assignments
├── .gitignore
├── 01-introduction
│ ├── .gitignore
│ ├── README.md
│ ├── doc
│ │ ├── demo.png
│ │ └── terminator.png
│ └── src
│ │ ├── CMakeLists.txt
│ │ └── lidar_localization
│ │ ├── .gitignore
│ │ ├── CMakeLists.txt
│ │ ├── cmake
│ │ ├── PCL.cmake
│ │ ├── geographic.cmake
│ │ ├── global_defination.cmake
│ │ └── glog.cmake
│ │ ├── include
│ │ └── lidar_localization
│ │ │ ├── global_defination
│ │ │ └── global_defination.h.in
│ │ │ ├── publisher
│ │ │ ├── cloud_publisher.hpp
│ │ │ ├── odometry_publisher.hpp
│ │ │ └── tf_broadcaster.hpp
│ │ │ ├── sensor_data
│ │ │ ├── cloud_data.hpp
│ │ │ ├── gnss_data.hpp
│ │ │ └── imu_data.hpp
│ │ │ └── subscriber
│ │ │ ├── cloud_subscriber.hpp
│ │ │ ├── gnss_subscriber.hpp
│ │ │ ├── imu_subscriber.hpp
│ │ │ └── tf_listener.hpp
│ │ ├── launch
│ │ └── hello_kitti.launch
│ │ ├── package.xml
│ │ ├── rviz
│ │ └── hello_kitti.rviz
│ │ ├── slam_data
│ │ └── .gitignore
│ │ └── src
│ │ ├── hello_kitti_node.cpp
│ │ ├── publisher
│ │ ├── cloud_publisher.cpp
│ │ ├── odometry_publisher.cpp
│ │ └── tf_broadcaster.cpp
│ │ ├── sensor_data
│ │ ├── gnss_data.cpp
│ │ └── imu_data.cpp
│ │ └── subscriber
│ │ ├── cloud_subscriber.cpp
│ │ ├── gnss_subscriber.cpp
│ │ ├── imu_subscriber.cpp
│ │ └── tf_lisener.cpp
└── README.md
└── data
└── kitti
├── .gitignore
└── README.md
/.dockerignore:
--------------------------------------------------------------------------------
1 | doc
2 | ubuntu-setup
3 | workspace
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug-report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug Report
3 | about: Create a report to help the framework improve
4 | title: "[BUG]-[WEEK]-[CONCISE_DESCRIPTION]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Please provide the info below to ensure the bug can be reproduced:
15 | * **Week / Assignment Name**
16 | * **Relative Path to File**
17 | * **Line Number**
18 |
19 | **Expected behavior**
20 | A clear and concise description of what you expected to happen.
21 |
22 | **Screenshots**
23 | If applicable, add screenshots to help explain your problem.
24 |
25 | **Additional context**
26 | Add any other context about the problem here.
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Multi-Sensor Fusion for Localization & Mapping -- 多传感器融合定位与建图
2 |
3 | 深蓝学院[多传感器融合定位与建图/Multi-Sensor Fusion for Localization & Mapping](https://www.shenlanxueyuan.com/course/324)学习环境.
4 |
5 | Maintained by **Ge Yao**, alexgecontrol@qq.com
6 |
7 | ---
8 |
9 | ## 先修课程与准备知识检查
10 |
11 | 我在学习这门课程时,已经完成如下深蓝学院课程的学习:
12 |
13 | * [机器人学中的状态估计](https://www.shenlanxueyuan.com/course/421)
14 | * [视觉SLAM理论与实践](https://www.shenlanxueyuan.com/course/433)
15 | * [视觉SLAM进阶-从零开始手写VIO](https://www.shenlanxueyuan.com/course/388)
16 | * [激光SLAM理论与实践](https://www.shenlanxueyuan.com/course/348)
17 |
18 | 且有多年的机器人系统开发经验, 熟悉以下的基础理论, 开发语言/框架/工具:
19 |
20 | * **State Estimation for Robotics** [Reference Book](https://www.amazon.com/State-Estimation-Robotics-Timothy-Barfoot/dp/1107159393/ref=sr_1_1?crid=3A1AU9FS3OA4U&keywords=state+estimation+for+robotics&qid=1639835747&sprefix=state+estimation+for+robotic%2Caps%2C501&sr=8-1)
21 | * **Modern C++ (11 and above)** [Reference Book](https://www.amazon.com/Effective-Modern-Specific-Ways-Improve/dp/1491903996/ref=sr_1_1?crid=3FBSOVE5S7DG2&keywords=effective+modern+c%2B%2B&qid=1639809190&sprefix=effective+modern+c%2B%2Caps%2C573&sr=8-1)
22 | * Python [Reference Book](https://www.amazon.com/Fluent-Python-Concise-Effective-Programming/dp/1491946008/ref=sr_1_2?crid=1N4TWSFVKTSUC&keywords=fluent+python+2nd+edition&qid=1639911762&sprefix=fluent+python%27%2Caps%2C332&sr=8-2)
23 | * **ROS** [深蓝学院参考课程](https://www.shenlanxueyuan.com/course/364)
24 | * **Git/GitHub, Markdown**与LaTeX [Coursera参考课程](https://www.coursera.org/professional-certificates/google-it-automation#courses)
25 |
26 | ---
27 |
28 | ## Before You Start...
29 |
30 | 在开始前, 请自行通过百度, 或者我推荐的[Coursera参考课程](https://www.coursera.org/professional-certificates/google-it-automation#courses), 自行学习, 熟悉以下工具的基本概念与操作. **否则你可能连这篇文档都读得稀里糊涂**
31 |
32 | 1. git
33 | 2. GitHub
34 | 3. MarkDown语法与README.md的书写
35 | 4. VSCode使用
36 |
37 | 当且仅当你完成上述基本工具的学习后,再继续阅读,**否则你可能连这篇文档都读得稀里糊涂**
38 |
39 | ---
40 |
41 | ## Docker Env - Up & Running
42 |
43 | ### WARNING - About Environment
44 |
45 | **若您坚持在Native Ubuntu上进行开发**, 此处**将默认您有足够的定位&建图开发环境运维经验, 能够自定义开发环境, 并且自主解决由于环境依赖冲突导致的各种问题**. 课程的重点在多传感融合定位算法, 并非基于Docker的环境搭建. 如果感兴趣, 请根据以下提示, 自行学习.**本框架只确保Docker环境的开箱即用, 不提供任何本地环境配置冲突解决的帮助**.
46 |
47 | * 确保熟悉Docker与Docker-Compose的开发使用
48 | * 根据Dockerfile [Click Here](docker/cpu.Dockerfile)自行准备开发环境
49 | * 熟悉其中的各个依赖库, 有能力在出现依赖问题时, 自行搜索, 查询相关资料, 修复依赖冲突
50 |
51 | ### WARNING - On This Guide
52 |
53 | **请您务必按照本指南, 一步一步操作, 当且仅当您在对本环境足够熟悉的情况下,再自由发挥**
54 |
55 | ### Overview
56 |
57 | 本Repo为基于**ROS melodic** @ **Ubuntu 18.04**的[多传感器融合定位与建图/Multi-Sensor Fusion for Localization & Mapping](https://www.shenlanxueyuan.com/course/324)学习环境.
58 |
59 | 定位与建图是一个复杂的工程. **每一个解决方案, 都有较为复杂的环境依赖**. 然而:
60 |
61 | * 部分依赖项由于网络原因(Great Fire Wall & Server IP Block)难以直接获得
62 |
63 | * 由于课程依赖项的版本, 与本地现有依赖项的版本, 可能有所不同, 直接冒然安装, 可能会导致本地开发环境被破坏
64 |
65 | 故: 本课程的学习环境将以**Docker Image**的形式提供, 以实现与Native PC环境的隔离.
66 |
67 | * 本项目Native PC的操作系统选择**Ubuntu**. Windows与Mac不推荐使用, 若有意尝试, 请自行搜索相关解决方案.
68 |
69 | ---
70 |
71 | ### 安装Ubuntu
72 |
73 | 首先请确保您可以访问**Ubuntu**开发环境. 如果没有**Ubuntu**环境, 请按照[点击链接进入](ubuntu-setup/README.md)指南, 在本地PC上安装配置**Ubuntu**环境.
74 |
75 | ---
76 |
77 | ### **针对国内同学** 将Ubuntu APT源换为阿里云源
78 |
79 | 为了保证本地Native环境APT安装速度, 请根据[This CSDN Post](https://blog.csdn.net/zhangjiahao14/article/details/80554616), 将Ubuntu上默认的APT源切换为阿里云源.
80 |
81 | ---
82 |
83 | ### Fetch This Git Repo.
84 |
85 | **感谢第5期同学的分享** 如果在国内, 因DNS污染等原因, 导致GitHub访问受限, 可以通过[GitHub Proxy代理](https://ghproxy.com/)进行加速
86 |
87 | ```bash
88 | # 1. direct clone:
89 | git clone https://github.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware
90 | # 2. use GitHub proxy for acceleration:
91 | git clone https://ghproxy.com/https://github.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware
92 | ```
93 |
94 | ---
95 |
96 | ### 获取Docker开发环境
97 |
98 | 本课程推荐使用配套的Docker环境[点击链接进入](docker/README.md)完成课程学习. Docker提供了一个轻量级的标准化开发环境, 能够避免本地已有环境的差异导致的奇怪问题, 避免环境配置调试的巨额时间浪费.
99 |
100 | ---
101 |
102 | ### JFYI: Dependency Overview
103 |
104 | * **C++**
105 | * **Google Protobuf**, [Click Here](https://github.com/google/protobuf.git), **branch 3.14.x**
106 | * **GeographicLib**, [Click Here](https://nchc.dl.sourceforge.net/project/geographiclib/distrib/GeographicLib-1.50.1.zip), **version 1.50.1**
107 | * **GeographicLib**, [Click Here](https://nchc.dl.sourceforge.net/project/geographiclib/distrib/GeographicLib-1.50.1.zip), **version 1.50.1**
108 | * **Sophus**, [Click Here](https://github.com/strasdat/Sophus.git), **commit id 49a7e1286910019f74fb4f0bb3e213c909f8e1b7**
109 | * **Google Ceres**, [Click Here](https://github.com/ceres-solver/ceres-solver.git), **commit id c2fab6502e5a341ff644c2bb2c5171ebd882b2d6**
110 | * **G2O**, [Click Here](https://github.com/RainerKuemmerle/g2o.git), **tag 20200410_git**
111 | * **GTSAM**, [Click Here](https://github.com/borglab/gtsam.git), **tag 4.0.3**
112 |
113 | * **Python**
114 | * **kitti2bag**, [Click Here](https://pypi.org/project/kitti2bag/), **1.5**
115 | * **evo**, [Click Here](https://pypi.org/project/evo/), **1.12.0**
116 | ---
117 |
118 | ### Workspace
119 |
120 | 当Native PC与Course Docker Environment均准备就绪时, 即可开始使用本开发环境:
121 |
122 | * **第一次使用时, 请首先下载课程配套的KITTI测试数据**[here](workspace/data/kitti/README.md).
123 |
124 | * 之后, 即可通过**本地VSCode开发, Docker内部编译测试**的模式, 完成课程作业.
125 |
126 | #### 获取课程数据
127 |
128 | 在第一次使用时, 需要将**课程配套的修复后KITTI数据**下载至本地文件系统. 具体操作方法参考[点击链接进入](workspace/data/kitti/README.md)
129 |
130 | #### 安装Native Ubuntu IDE
131 |
132 | 本课程推荐使用[VSCode](https://code.visualstudio.com/)进行开发. 请按照链接,完成VSCode的安装. **安装VSCode之后,请继续安装以下VSCode Plug-Ins**:
133 |
134 | * **C/C++** by **Microsoft**, 用于**完成作业时加速C++开发**.
135 |
136 | * **Markdown All in One** by **Yu Zhang**, 用于**在VSCode中查看课程中所有的README.md, (Shift+Ctrl+V)**.
137 |
138 | #### 开发, 编译与测试
139 |
140 | 启动Docker环境后, **Docker**中的/workspace目录, 会被映射到**当前Repo**中的workspace目录.
141 |
142 | 使用该Workspace进行开发, 编译与测试的方法如下:
143 |
144 | * 在**当前Repo的workspace**下, 启动[VSCode](https://code.visualstudio.com/), 编辑源代码:
145 |
146 |
147 |
148 | * 在**Docker /workspace**下, 进行编译. 具体的编译方法, 请参考[作业1 环境搭建](workspace/assignments/01-introduction/README.md)
149 |
150 | ---
151 |
152 | ### Assignments
153 |
154 | 请各位执行如下的分支切换指令, 完成各周对应的作业.
155 |
156 | #### Week 02, Lidar Odometry, Basic
157 |
158 | ```bash
159 | git checkout 02-lidar-odometry-basic
160 | ```
161 |
162 | #### Week 03, Lidar Odometry, Advanced
163 |
164 | ```bash
165 | git checkout 03-lidar-odometry-advanced
166 | ```
167 |
168 | #### Week 04, Mapping and Matching
169 |
170 | ```bash
171 | git checkout 04-mapping-and-matching
172 | ```
173 |
174 | #### Week 05, IMU Calibration
175 |
176 | ```bash
177 | git checkout 05-imu-calib
178 | ```
179 |
180 | #### Week 06, IMU Navigation
181 |
182 | ```bash
183 | git checkout 06-imu-navigation
184 | ```
185 |
186 | #### Week 07, Filtering, Basic
187 |
188 | ```bash
189 | git checkout 07-filtering-basic
190 | ```
191 |
192 | #### Week 08, Filtering Advanced
193 |
194 | ```bash
195 | git checkout 08-filtering-advanced
196 | ```
197 |
198 | #### Week 09, Graph Optimization
199 |
200 | ```bash
201 | git checkout 09-graph-optimization
202 | ```
203 |
204 | #### Week 10, Sliding Window
205 |
206 | ```bash
207 | git checkout 10-sliding-window
208 | ```
209 |
210 | #### Week 11, Capstone - Do It Own Your Own!
211 |
212 | ---
213 |
214 | Keep Learning & Keep Coding
215 |
216 | Ge Yao, alexgecontrol@qq.com
--------------------------------------------------------------------------------
/doc/development-environment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/doc/development-environment.png
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.4'
2 | services:
3 | # cpu development:
4 | workspace-bionic-cpu-vnc:
5 | build:
6 | context: docker
7 | dockerfile: cpu.Dockerfile
8 | network: host
9 | image: registry.cn-shanghai.aliyuncs.com/shenlanxueyuan/sensor-fusion-workspace:bionic-cpu-vnc
10 | container_name: sensor-fusion-workspace-cpu
11 | privileged: true
12 | environment:
13 | # set VNC login password here:
14 | - VNC_PASSWORD=sensorfusion
15 | volumes:
16 | # mount your workspace here:
17 | - $PWD/workspace:/workspace
18 | ports:
19 | # HTML5 VNC:
20 | - 40080:80
21 | # standard VNC client:
22 | - 45901:5901
23 | # supervisord admin:
24 | - 49001:9001
25 | # ROS master:
26 | - 11311:11311
--------------------------------------------------------------------------------
/docker/.dockerignore:
--------------------------------------------------------------------------------
1 | doc
--------------------------------------------------------------------------------
/docker/README.md:
--------------------------------------------------------------------------------
1 | # Docker Environment for Sensor Fusion
2 |
3 | 基于Docker的[多传感器融合定位/Sensor Fusion](https://www.shenlanxueyuan.com/my/course/261)学习环境.
4 |
5 | ---
6 |
7 | ## Overview
8 |
9 | 本文档旨在提供**多传感器融合定位**的标准开发环境, 减轻环境配置的工作量
10 |
11 | ---
12 |
13 | ## 安装配置Docker以及Docker-Compose
14 |
15 | 在开始使用前,首先需要在本地配置`Docker`以及`Docker-Compose`环境.
16 |
17 | ---
18 |
19 | ### 安装Docker
20 |
21 | 请参考[Docker官方文档](https://docs.docker.com/engine/install/ubuntu/)完成`Docker`环境的安装
22 |
23 | **安装完成后, 请务必进行如下操作**, 以保证可以无脑跟随后续文档进行操作:
24 |
25 | #### 将当前用户加入Docker Group
26 |
27 | 为了能在非`sudo`模式下使用`Docker`, 需要将当前用户加入`Docker Group`.
28 |
29 | 1. 执行命令:
30 |
31 | ```bash
32 | sudo usermod -aG docker $USER
33 | ```
34 |
35 | 2. **为了使上述变更生效,请先Logout,再Login**
36 |
37 | ---
38 |
39 | ### 安装Docker-Compose
40 |
41 | `Docker-Compose`是基于Docker解决方案的Orchestrator.
42 |
43 | 请参考[Docker Compose官方文档](https://docs.docker.com/compose/install/)完成`Docker-Compose`环境的安装
44 |
45 | ---
46 |
47 | ## 获取镜像
48 |
49 | 在安装完成`Docker`以及`Docker-Compose`之后,需要从`阿里云`源上获得所需镜像.
50 |
51 | **注意**: 执行第1条命令时,**需要输入密码!!!需要输入密码!!!需要输入密码!!!**, 密码请看**命令上方注释行的绿字!!!命令上方注释行的绿字!!!命令上方注释行的绿字!!!***
52 |
53 | ```bash
54 | # 1. login to Alibaba Cloud Docker registry -- default password is shenlansf20210122:
55 | docker login --username=937570601@qq.com registry.cn-shanghai.aliyuncs.com
56 | # 2. then download images:
57 | docker pull registry.cn-shanghai.aliyuncs.com/shenlanxueyuan/sensor-fusion-workspace:bionic-cpu-vnc
58 | ```
59 |
60 | ---
61 |
62 | ### 启动实例
63 |
64 | 在当前Repo`根目录`下(即**docker-compose.yml**所在的那个文件夹), 启动Terminal, 执行命令, 启动Docker Workspace:
65 |
66 | ```bash
67 | docker-compose down && docker-compose up
68 | ```
69 |
70 | ---
71 |
72 | ### Service Health Check
73 |
74 | 然后打开`Chrome`浏览器, 访问URL`http://localhost:49001/`, 默认账号/密码为`sensorfusion/sensorfusion`, 确保所有服务成功启动.
75 |
76 | 若**所有服务成功启动**, 系统状态如下图所示:
77 |
78 |
79 |
80 | ---
81 |
82 | ### 访问工作空间
83 |
84 | 接着在`Chrome`浏览器中, 访问URL`http://localhost:40080/`, 默认登录密码为`sensorfusion`, 访问Docker Workspace
85 |
86 |
87 |
88 | 该Workspace可理解为一个在浏览器中的`Ubuntu 18.04 Bionic`环境. 可在其中进行一切Ubuntu环境下的开发操作.
89 |
90 | ---
91 |
92 | ### 编译作业
93 |
94 | 请将作业所需的`源代码`与`数据`, 分别放到当前Repo`workspace/assignments`与`workspace/data`目录下. Docker Workspace会将当前Repo`workspace`文件夹映射到Docker Instance`/workspace`目录下.
95 |
96 | 可在Docker Workspace中执行如下命令, 确保两者--`当前Repo workspace文件夹`与`Docker Instance /workspace`文件夹--的一致性
97 |
98 |
99 |
100 | ---
101 |
102 | ### 常见问题
103 |
104 | 1. Docker运行时默认用户为`root`, 运行过程中可能导致`当前Repo workspace文件夹`的User以及Group变更为`root`, 从而使本地文件IO操作因`Permission Denied`失败. 解决方案: 使用chown命令, 变更User-Group:
105 |
106 | ```bash
107 | sudo chown [CURRENT_USER]:[CURRENT GROUP] workspace
108 | ```
109 |
--------------------------------------------------------------------------------
/docker/cpu.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:18.04
2 |
3 | # ------ powered by Ge Yao, alexgecontrol@qq.com ------
4 |
5 | LABEL maintainer="alexgecontrol@qq.com"
6 |
7 | # ------ USER ROOT HAS BEEN ACTIVATED ------
8 |
9 | # use root for dependency installation:
10 | USER root
11 |
12 | # ------ PART 0: set environment variables ------
13 |
14 | # set up environment:
15 | ENV DEBIAN_FRONTEND noninteractive
16 | ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
17 | ENV HOME=/root SHELL=/bin/bash
18 |
19 | # ------ PART 1: set up CN sources ------
20 |
21 | # Ubuntu:
22 | COPY ${PWD}/image/etc/apt/sources.list /etc/apt/sources.list
23 | RUN rm -f /etc/apt/sources.list.d/*
24 |
25 | # Python:
26 | COPY ${PWD}/image/etc/pip.conf /root/.pip/pip.conf
27 |
28 | # ------ PART 2: set up apt-fast -- NEED PROXY DUE TO UNSTABLE CN CONNECTION ------
29 |
30 | # install:
31 | RUN apt-get update -q --fix-missing && \
32 | apt-get install -y --no-install-recommends --allow-unauthenticated \
33 | # PPA utilities:
34 | software-properties-common \
35 | # certificates management:
36 | dirmngr gnupg2 \
37 | # download utilities:
38 | axel aria2 && \
39 | apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-keys 1EE2FF37CA8DA16B && \
40 | add-apt-repository ppa:apt-fast/stable && \
41 | apt-get update -q --fix-missing && \
42 | apt-get install -y --no-install-recommends --allow-unauthenticated apt-fast && \
43 | rm -rf /var/lib/apt/lists/*
44 |
45 | # CN config:
46 | COPY ${PWD}/image/etc/apt-fast.conf /etc/apt-fast.conf
47 |
48 | # ------ PART 3: add external repositories ------
49 |
50 | # ROS:
51 | RUN apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
52 | COPY ${PWD}/image/etc/apt/sources.list.d/ /etc/apt/sources.list.d/
53 | # libsparse:
54 | RUN add-apt-repository -r ppa:bzindovic/suitesparse-bugfix-1319687
55 |
56 | # ------ PART 4: install packages ------
57 |
58 | RUN apt-fast update --fix-missing && \
59 | apt-fast install -y --no-install-recommends --allow-unauthenticated \
60 | # package utils:
61 | sudo dpkg pkg-config apt-utils \
62 | # security:
63 | openssh-server pwgen ca-certificates \
64 | # network utils:
65 | curl wget iputils-ping net-tools \
66 | # command line:
67 | vim grep sed patch \
68 | # io:
69 | pv zip unzip bzip2 \
70 | # version control:
71 | git mercurial subversion \
72 | # daemon & services:
73 | supervisor nginx \
74 | # dev. tools:
75 | terminator \
76 | firefox \
77 | # potential image & rich text IO:
78 | libsdl1.2-dev libsdl-net1.2-dev libsdl-image1.2-dev \
79 | lxde \
80 | gnome-themes-standard \
81 | xvfb dbus-x11 x11-utils libxext6 libsm6 x11vnc \
82 | gtk2-engines-pixbuf gtk2-engines-murrine pinta ttf-ubuntu-font-family \
83 | mesa-utils libgl1-mesa-dri libxrender1 \
84 | gnuplot \
85 | texlive-latex-extra \
86 | #
87 | # general development:
88 | #
89 | # a. c++:
90 | gcc g++ \
91 | make cmake build-essential autoconf automake libtool \
92 | libglib2.0-dev libboost-dev libboost-all-dev \
93 | libomp-dev libtbb-dev \
94 | libgoogle-glog-dev \
95 | # b. Python 2:
96 | python-pip python-dev python-tk \
97 | # c. lua:
98 | lua5.3 liblua5.3-dev libluabind-dev \
99 | #
100 | # numerical optimization:
101 | #
102 | coinor-libcoinutils-dev \
103 | coinor-libcbc-dev \
104 | libeigen3-dev \
105 | gfortran \
106 | libopenblas-dev liblapack-dev \
107 | libdw-dev libatlas-base-dev libsuitesparse-dev \
108 | libcholmod3 libcxsparse3 \
109 | libmetis-dev \
110 | #
111 | # 3D graphics:
112 | #
113 | freeglut3-dev \
114 | libqt4-dev libqt4-opengl-dev \
115 | qt5-default qt5-qmake \
116 | qtdeclarative5-dev libqglviewer-dev-qt5 \
117 | #
118 | # ROS melodic:
119 | #
120 | ros-melodic-desktop-full \
121 | ros-melodic-ecl-threads \
122 | ros-melodic-rosbridge-server \
123 | ros-melodic-tf2 ros-melodic-tf2-ros ros-melodic-tf2-sensor-msgs \
124 | ros-melodic-teleop-twist-keyboard \
125 | ros-melodic-rviz-visual-tools \
126 | ros-melodic-plotjuggler \
127 | python-catkin-tools python-rosdep python-rosinstall python-rosinstall-generator python-wstool \
128 | ninja-build \
129 | # imu:
130 | ros-melodic-imu-complementary-filter ros-melodic-imu-filter-madgwick ros-melodic-rviz-imu-plugin \
131 | # lidar:
132 | ros-melodic-laser-pipeline \
133 | ros-melodic-perception-pcl && \
134 | apt-fast autoclean && \
135 | apt-fast autoremove && \
136 | rm -rf /var/lib/apt/lists/*
137 |
138 | # ordered startup fix for supervisord:
139 | RUN pip install ordered-startup-supervisord
140 |
141 | # ------ PART 5: set up ROS environments ------
142 |
143 | # initialize rosdep
144 | #
145 | # NOTE:
146 | # be careful about DNS resolution problem caused by https://raw.githubusercontent.com
147 | # get the latest IP address of the site from Baidu and Google search engine
148 | #
149 | RUN rosdep fix-permissions && \
150 | rosdep init && \
151 | rosdep update
152 |
153 | # activate ros environment:
154 | RUN echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
155 |
156 | # for remote debugging:
157 | EXPOSE 11311
158 |
159 | # ------ PART 6: set up VNC servers ------
160 |
161 | COPY image /
162 |
163 | WORKDIR /usr/lib/
164 |
165 | RUN git clone https://github.com/novnc/noVNC.git -o noVNC
166 |
167 | WORKDIR /usr/lib/noVNC/utils
168 |
169 | RUN git clone https://github.com/novnc/websockify.git -o websockify
170 |
171 | WORKDIR /usr/lib/webportal
172 |
173 | RUN pip install --upgrade pip && pip install -r requirements.txt
174 |
175 | EXPOSE 80 5901 9001
176 |
177 |
178 | # ------ PART 7: library dependencies ------
179 |
180 | # load installers:
181 | COPY ${PWD}/installers /tmp/installers
182 | WORKDIR /tmp/installers
183 |
184 | # install Google Protobuf -- 3.14.x:
185 | RUN git clone https://github.com/google/protobuf.git -b 3.14.x -o protobuf && cd protobuf && \
186 | # sync:
187 | git submodule update --init --recursive && \
188 | # config:
189 | ./autogen.sh && ./configure && \
190 | # build:
191 | make -j8 && \
192 | # install:
193 | make install
194 |
195 | # install Aceinna GNSS/IMU sim IMU-GNSS-Odo simulation with customized error modes:
196 | RUN git clone https://github.com/AlexGeControl/GNSS-INS-SIM-Extended.git && cd GNSS-INS-SIM-Extended && \
197 | # install:
198 | python setup.py install
199 |
200 | # install GeographicLib -- 1.50.1
201 | RUN wget https://nchc.dl.sourceforge.net/project/geographiclib/distrib/GeographicLib-1.50.1.zip && \
202 | unzip -q GeographicLib-1.50.1.zip && cd GeographicLib-1.50.1 && \
203 | mkdir build && cd build && \
204 | # config:
205 | cmake .. && \
206 | # build:
207 | make -j8 && \
208 | # install:
209 | make install
210 |
211 | # install sophus -- commit id 49a7e1286910019f74fb4f0bb3e213c909f8e1b7:
212 | RUN git clone https://github.com/strasdat/Sophus.git -o Sophus && cd Sophus && \
213 | # align version:
214 | git fetch --all --tags && git checkout 49a7e1286910019f74fb4f0bb3e213c909f8e1b7 && \
215 | # start to build
216 | mkdir build && cd build && \
217 | # config:
218 | cmake .. && \
219 | # build:
220 | make -j8 && \
221 | # install:
222 | make install
223 |
224 | # install ceres -- commit id c2fab6502e5a341ff644c2bb2c5171ebd882b2d6:
225 | RUN git clone https://github.com/ceres-solver/ceres-solver.git -o ceres-solver && cd ceres-solver && \
226 | # align version:
227 | git fetch --all --tags && git checkout c2fab6502e5a341ff644c2bb2c5171ebd882b2d6 && cd /tmp/installers/ && \
228 | # config:
229 | mkdir ceres-bin && cd ceres-bin && cmake ../ceres-solver && \
230 | # build:
231 | make -j8 && \
232 | # install:
233 | make install
234 |
235 | # install g2o -- release 20200410_git:
236 | RUN git clone https://github.com/RainerKuemmerle/g2o.git -o g2o && cd g2o && \
237 | # align version:
238 | git fetch --all --tags && git checkout tags/20200410_git -b release-20200410 && \
239 | # start to build:
240 | mkdir build && cd build && \
241 | # config:
242 | cmake .. && \
243 | # build:
244 | make -j8 && \
245 | # install:
246 | make install
247 |
248 | # install gtsam -- 4.0.3:
249 | RUN git clone https://github.com/borglab/gtsam.git -o gtsam && cd gtsam && \
250 | # align version:
251 | git fetch --all --tags && git checkout tags/4.0.3 -b release-4.0.3 && \
252 | # start to build:
253 | mkdir build && cd build && \
254 | # config:
255 | cmake .. && \
256 | # build:
257 | make -j8 && \
258 | # install:
259 | make install
260 |
261 | # install tini:
262 | RUN chmod u+x ./download-tini.sh && ./download-tini.sh && dpkg -i tini.deb && \
263 | apt-get clean
264 |
265 | RUN rm -rf /tmp/installers
266 |
267 | # ------ PART 8: Python dependencies ------
268 |
269 | COPY environment /workspace
270 |
271 | WORKDIR /workspace
272 |
273 | RUN pip install -r requirements.txt
274 |
275 | # ------------------ DONE -----------------------
276 |
277 | # enable dependency lib linking:
278 | ENV LD_LIBRARY_PATH=/usr/local/lib
279 |
280 | ENTRYPOINT ["/startup.sh"]
--------------------------------------------------------------------------------
/docker/doc/01-launch-instance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/docker/doc/01-launch-instance.png
--------------------------------------------------------------------------------
/docker/doc/02-service-health-check.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/docker/doc/02-service-health-check.png
--------------------------------------------------------------------------------
/docker/doc/03-access-workspace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/docker/doc/03-access-workspace.png
--------------------------------------------------------------------------------
/docker/doc/04-mount-native-workspace-into-docker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/docker/doc/04-mount-native-workspace-into-docker.png
--------------------------------------------------------------------------------
/docker/environment/requirements.txt:
--------------------------------------------------------------------------------
1 | kitti2bag==1.5
2 | evo==1.12.0
--------------------------------------------------------------------------------
/docker/image/etc/apt-fast.conf:
--------------------------------------------------------------------------------
1 | ###################################################################
2 | # CONFIGURATION OPTIONS
3 | ###################################################################
4 | # Every item has a default value besides MIRRORS (which is unset).
5 |
6 | # Use aptitude, apt-get, or apt?
7 | # Note that apt-get is used as a fallback for outputting the
8 | # package URI list for e.g. aptitude, which can't do this
9 | # Optionally add the FULLPATH to apt-get or apt-rpm or aptitude
10 | # e.g. /usr/bin/aptitude
11 | #
12 | # Default: apt-get
13 | #
14 | _APTMGR=apt-get
15 |
16 |
17 | # Enable DOWNLOADBEFORE to suppress apt-fast confirmation dialog and download
18 | # packages directly.
19 | #
20 | # Default: dialog enabled
21 | #
22 | DOWNLOADBEFORE=true
23 |
24 |
25 | # Choose mirror list to speed up downloads from same archive. To select some
26 | # mirrors take a look at your distribution's archive mirror lists.
27 | # Debian: http://www.debian.org/mirror/list
28 | # Ubuntu: https://launchpad.net/ubuntu/+archivemirrors
29 | #
30 | # It is required to add mirrors in the sources.list to this array as well, so
31 | # apt-fast can destinguish between different distributions.
32 | #
33 | # Examples:
34 | #
35 | # Different distributions (as in operating systems):
36 | #
37 | # sources.list:
38 | # deb http://deb.debian.org/debian/ unstable main non-free contrib
39 | # deb http://de.archive.ubuntu.com/ubuntu/ bionic main universe
40 | #
41 | # apt-fast.conf:
42 | # MIRRORS=( 'http://deb.debian.org/debian','http://ftp.debian.org/debian,http://ftp2.de.debian.org/debian,http://ftp.de.debian.org/debian,ftp://ftp.uni-kl.de/debian'
43 | # 'http://archive.ubuntu.com/ubuntu,http://de.archive.ubuntu.com/ubuntu,http://ftp.halifax.rwth-aachen.de/ubuntu,http://ftp.uni-kl.de/pub/linux/ubuntu,http://mirror.informatik.uni-mannheim.de/pub/linux/distributions/ubuntu/' )
44 | #
45 | #
46 | # Single distribution:
47 | #
48 | # sources.list:
49 | # deb http://fr.archive.ubuntu.com/ubuntu/ bionic main
50 | # deb http://fr.archive.ubuntu.com/ubuntu/ artful main
51 | #
52 | # apt-fast.conf:
53 | # MIRRORS=( 'http://fr.archive.ubuntu.com/ubuntu,http://bouyguestelecom.ubuntu.lafibre.info/ubuntu,http://mirror.ovh.net/ubuntu,http://ubuntu-archive.mirrors.proxad.net/ubuntu' )
54 | #
55 | # Default: disabled
56 | #
57 |
58 | #
59 | # line 1. general ubuntu packages -- aliyun, stju, tsinghua
60 | # line 2. ROS packages -- ustc, tsinghua, bfsu
61 | #
62 | MIRRORS=(
63 | 'http://mirrors.aliyun.com/ubuntu,http://ftp.sjtu.edu.cn/ubuntu,http://mirrors.tuna.tsinghua.edu.cn/ubuntu'
64 | 'http://mirrors.ustc.edu.cn/ros/ubuntu/,http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/,http://mirrors.bfsu.edu.cn/ros/ubuntu/'
65 | )
66 |
67 |
68 | # Maximum number of connections
69 | # You can use this value in _DOWNLOADER command. Escape with ${}: ${_MAXNUM}
70 | #
71 | # Default: 5
72 | #
73 | _MAXNUM=8
74 |
75 |
76 | # Maximum number of connections per server
77 | # Default: 10
78 | #
79 | _MAXCONPERSRV=10
80 |
81 |
82 | # Download file using given number of connections
83 | # If more than N URIs are given, first N URIs are used and remaining URIs are used for backup.
84 | # If less than N URIs are given, those URIs are used more than once so that N connections total are made simultaneously.
85 | #
86 | _SPLITCON=8
87 |
88 |
89 | # Split size i.e. size of each piece
90 | # Possible Values: 1M-1024M
91 | #
92 | _MINSPLITSZ=1M
93 |
94 |
95 | # Piece selection algorithm to use
96 | # Available values are: default, inorder, geom
97 | # default: selects piece so that it reduces the number of establishing connection, reasonable for most cases
98 | # inorder: selects pieces in sequential order starting from first piece
99 | # geom: selects piece which has minimum index like inorder, but it exponentially increasingly keeps space from previously selected pieces
100 | #
101 | _PIECEALGO=default
102 |
103 |
104 | # Downloadmanager listfile
105 | # You can use this value in _DOWNLOADER command. Escape with ${}: ${DLLIST}
106 | #
107 | # Default: /tmp/apt-fast.list
108 | #
109 | DLLIST='/tmp/apt-fast.list'
110 |
111 |
112 | # Download command to use. Temporary download list is designed for aria2. But
113 | # you can choose another download command or download manager. It has to
114 | # support following input file syntax (\t is tab character):
115 | #
116 | # # Comment
117 | # MIRROR1\tMIRROR2\tMIRROR3...
118 | # out=FILENAME1
119 | # MIRROR1\tMIRROR2\tMIRROR3...
120 | # out=FILENAME2
121 | # ...
122 | #
123 | # Examples:
124 | # aria2c with a proxy (set username, proxy, ip and password!)
125 | # _DOWNLOADER='aria2c --no-conf -c -j ${_MAXNUM} -x ${_MAXCONPERSRV} -s ${_SPLITCON} --min-split-size=${_MINSPLITSZ} --stream-piece-selector=${_PIECEALGO} --http-proxy=http://username:password@proxy_ip:proxy_port -i ${DLLIST} --connect-timeout=600 --timeout=600 -m0 --header "Accept: */*"'
126 | #
127 | # Default: _DOWNLOADER='aria2c --no-conf -c -j ${_MAXNUM} -x ${_MAXCONPERSRV} -s ${_SPLITCON} --min-split-size=${_MINSPLITSZ} --stream-piece-selector=${_PIECEALGO} -i ${DLLIST} --connect-timeout=600 --timeout=600 -m0 --header "Accept: */*"'
128 | #
129 | _DOWNLOADER='aria2c --no-conf -c -j ${_MAXNUM} -x ${_MAXCONPERSRV} -s ${_SPLITCON} --min-split-size=${_MINSPLITSZ} --stream-piece-selector=${_PIECEALGO} -i ${DLLIST} --connect-timeout=600 --timeout=600 -m0 --header "Accept: */*"'
130 |
131 |
132 | # Temporary download folder for download manager.
133 | #
134 | # Default: /var/cache/apt/apt-fast
135 | #
136 | DLDIR='/var/cache/apt/apt-fast'
137 |
138 |
139 | # APT archives cache directory
140 | #
141 | # Default /var/cache/apt/archives
142 | # (APT configuration items Dir::Cache and Dir::Cache::archives)
143 | #
144 | APTCACHE='/var/cache/apt/archives'
145 |
146 |
147 | # apt-fast colors
148 | # Colors are disabled when not using a terminal.
149 | #
150 | # Default colors are:
151 | # cGreen='\e[0;32m'
152 | # cRed='\e[0;31m'
153 | # cBlue='\e[0;34m'
154 | # endColor='\e[0m'
155 |
--------------------------------------------------------------------------------
/docker/image/etc/apt/sources.list:
--------------------------------------------------------------------------------
1 | # See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
2 | # newer versions of the distribution.
3 | deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted
4 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted
5 |
6 | ## Major bug fix updates produced after the final release of the
7 | ## distribution.
8 | deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted
9 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted
10 |
11 | ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
12 | ## team. Also, please note that software in universe WILL NOT receive any
13 | ## review or updates from the Ubuntu security team.
14 | deb http://mirrors.aliyun.com/ubuntu/ bionic universe
15 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic universe
16 | deb http://mirrors.aliyun.com/ubuntu/ bionic-updates universe
17 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates universe
18 |
19 | ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
20 | ## team, and may not be under a free licence. Please satisfy yourself as to
21 | ## your rights to use the software. Also, please note that software in
22 | ## multiverse WILL NOT receive any review or updates from the Ubuntu
23 | ## security team.
24 | deb http://mirrors.aliyun.com/ubuntu/ bionic multiverse
25 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic multiverse
26 | deb http://mirrors.aliyun.com/ubuntu/ bionic-updates multiverse
27 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates multiverse
28 |
29 | ## N.B. software from this repository may not have been tested as
30 | ## extensively as that contained in the main release, although it includes
31 | ## newer versions of some applications which may provide useful features.
32 | ## Also, please note that software in backports WILL NOT receive any review
33 | ## or updates from the Ubuntu security team.
34 | deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
35 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
36 |
37 | ## Uncomment the following two lines to add software from Canonical's
38 | ## 'partner' repository.
39 | ## This software is not part of Ubuntu, but is offered by Canonical and the
40 | ## respective vendors as a service to Ubuntu users.
41 | # deb http://archive.canonical.com/ubuntu bionic partner
42 | # deb-src http://archive.canonical.com/ubuntu bionic partner
43 |
44 | deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted
45 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted
46 | deb http://mirrors.aliyun.com/ubuntu/ bionic-security universe
47 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security universe
48 | deb http://mirrors.aliyun.com/ubuntu/ bionic-security multiverse
49 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security multiverse
--------------------------------------------------------------------------------
/docker/image/etc/apt/sources.list.d/ros-latest.list:
--------------------------------------------------------------------------------
1 | deb http://mirrors.ustc.edu.cn/ros/ubuntu/ bionic main
--------------------------------------------------------------------------------
/docker/image/etc/default/keyboard:
--------------------------------------------------------------------------------
1 | # KEYBOARD CONFIGURATION FILE
2 |
3 | # Consult the keyboard(5) manual page.
4 |
5 | XKBMODEL="pc105"
6 | XKBLAYOUT="us"
7 | XKBVARIANT=""
8 | XKBOPTIONS=""
9 |
10 | BACKSPACE="guess"
11 |
--------------------------------------------------------------------------------
/docker/image/etc/hosts:
--------------------------------------------------------------------------------
1 |
2 | 151.101.228.133 raw.githubusercontent.com
3 | 151.101.108.133 raw.githubusercontent.com
4 | 151.101.52.133 raw.githubusercontent.com
5 | 151.101.68.133 raw.githubusercontent.com
6 | 199.232.68.133 raw.githubusercontent.com
7 |
--------------------------------------------------------------------------------
/docker/image/etc/nginx/sites-enabled/default:
--------------------------------------------------------------------------------
1 | map $http_upgrade $connection_upgrade {
2 | default upgrade;
3 | '' close;
4 | }
5 |
6 | server {
7 | listen 80;
8 | server_name _;
9 |
10 | location = / {
11 | try_files $uri @webportal;
12 | }
13 |
14 | location = /redirect.html {
15 | try_files $uri @webportal;
16 | }
17 |
18 | location / {
19 | try_files $uri @novnc;
20 | }
21 |
22 | location @webportal {
23 | include uwsgi_params;
24 | proxy_set_header X-Real-IP $remote_addr;
25 | proxy_set_header X-Forwarded-For $remote_addr;
26 | proxy_set_header Host $host;
27 | uwsgi_pass unix:/usr/lib/webportal/webportal.sock;
28 | max_ranges 0;
29 | }
30 |
31 | location @novnc {
32 | proxy_http_version 1.1;
33 |
34 | proxy_set_header Upgrade $http_upgrade;
35 | proxy_set_header Connection $connection_upgrade;
36 |
37 | proxy_pass http://127.0.0.1:6081;
38 | }
39 | }
--------------------------------------------------------------------------------
/docker/image/etc/pip.conf:
--------------------------------------------------------------------------------
1 | [global]
2 | index-url = http://mirrors.aliyun.com/pypi/simple/
3 | [install]
4 | trusted-host=mirrors.aliyun.com
5 | [list]
6 | format=columns
--------------------------------------------------------------------------------
/docker/image/etc/resolv.conf:
--------------------------------------------------------------------------------
1 | nameserver 8.8.8.8 #google DNS
2 | nameserver 8.8.4.4 #google DNS
--------------------------------------------------------------------------------
/docker/image/etc/supervisor/conf.d/lxde.conf:
--------------------------------------------------------------------------------
1 | [program:xvfb]
2 | priority=10
3 | directory=/
4 | command=/usr/bin/Xvfb :1 -screen 0 1920x1200x16
5 | user=root
6 | autostart=true
7 | autorestart=true
8 | stopsignal=QUIT
9 | stdout_logfile=/var/log/xvfb.log
10 | redirect_stderr=true
11 |
12 | [program:lxsession]
13 | priority=15
14 | directory=/root
15 | command=/usr/bin/openbox
16 | user=root
17 | autostart=true
18 | autorestart=true
19 | stopsignal=QUIT
20 | environment=DISPLAY=":1",HOME="/root",USER="root"
21 | stdout_logfile=/var/log/openbox.log
22 | redirect_stderr=true
23 |
24 | [program:lxpanel]
25 | priority=15
26 | directory=/root
27 | command=/usr/bin/lxpanel --profile LXDE
28 | user=root
29 | autostart=true
30 | autorestart=true
31 | stopsignal=QUIT
32 | environment=DISPLAY=":1",HOME="/root",USER="root"
33 | stdout_logfile=/var/log/lxpanel.log
34 | redirect_stderr=true
35 |
36 | [program:pcmanfm]
37 | priority=15
38 | directory=/root
39 | command=/usr/bin/pcmanfm --desktop --profile LXDE
40 | user=root
41 | autostart=true
42 | autorestart=true
43 | stopsignal=QUIT
44 | environment=DISPLAY=":1",HOME="/root",USER="root"
45 | stdout_logfile=/var/log/pcmanfm.log
46 |
47 | [program:x11vnc]
48 | priority=20
49 | directory=/
50 | command=x11vnc -display :1 -xkb -forever -shared -repeat -rfbport 5901
51 | user=root
52 | autostart=true
53 | autorestart=true
54 | stopsignal=QUIT
55 | stdout_logfile=/var/log/x11vnc.log
56 | redirect_stderr=true
57 |
58 | [program:novnc]
59 | priority=25
60 | directory=/usr/lib/noVNC/
61 | command=/usr/lib/noVNC/utils/novnc_proxy --listen 6081 --vnc localhost:5901
62 | user=root
63 | autostart=true
64 | autorestart=true
65 | stopsignal=QUIT
66 | stdout_logfile=/var/log/novnc.log
67 | redirect_stderr=true
68 | stopasgroup=true
--------------------------------------------------------------------------------
/docker/image/etc/supervisor/conf.d/webportal.conf:
--------------------------------------------------------------------------------
1 | [program:uwsgi]
2 | priority=30
3 | directory=/usr/lib/webportal/
4 | command=/usr/local/bin/uwsgi --ini /usr/lib/webportal/app.ini
5 | stdout_logfile=/dev/stdout
6 | stdout_logfile_maxbytes=0
7 | stderr_logfile=/dev/stderr
8 | stderr_logfile_maxbytes=0
9 |
10 | [program:nginx]
11 | priority=30
12 | command=/usr/sbin/nginx -c /etc/nginx/nginx.conf -g "daemon off;"
13 | stdout_logfile=/dev/stdout
14 | stdout_logfile_maxbytes=0
15 | stderr_logfile=/dev/stderr
16 | stderr_logfile_maxbytes=0
17 | # Graceful stop, see http://nginx.org/en/docs/control.html
18 | stopsignal=QUIT
--------------------------------------------------------------------------------
/docker/image/etc/supervisor/supervisord.conf:
--------------------------------------------------------------------------------
1 | [supervisord]
2 | logfile=/root/supervisord.log ; supervisord log file
3 | logfile_maxbytes=50MB ; maximum size of logfile before rotation
4 | logfile_backups=10 ; number of backed up logfiles
5 | loglevel=error ; info, debug, warn, trace
6 | pidfile=/var/run/supervisord.pid ; pidfile location
7 | minfds=1024 ; number of startup file descriptors
8 | minprocs=200 ; number of process descriptors
9 | user=root ; default user
10 | childlogdir=/root ; where child log files will live
11 |
12 | [supervisorctl]
13 | serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
14 |
15 | [inet_http_server]
16 | port=*:9001 ; (ip_address:port specifier, *:port for all iface)
17 | username=sensorfusion ; (default is no username (open server))
18 | password=sensorfusion ; (default is no password (open server))
19 |
20 | [unix_http_server]
21 | file=/var/run/supervisor.sock ; (the path to the socket file)
22 | chmod=0700 ; sockef file mode (default 0700)
23 |
24 | [rpcinterface:supervisor]
25 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
26 |
27 | [eventlistener:inorder]
28 | command=/usr/local/bin/ordered-startup-listener
29 | autostart=true
30 | events=PROCESS_STATE
31 |
32 | [include]
33 | files=/etc/supervisor/conf.d/*.conf
--------------------------------------------------------------------------------
/docker/image/root/.gtkrc-2.0:
--------------------------------------------------------------------------------
1 | # DO NOT EDIT! This file will be overwritten by LXAppearance.
2 | # Any customization should be done in ~/.gtkrc-2.0.mine instead.
3 | include "/usr/share/themes/Arc/gtk-2.0/gtkrc"
4 |
5 | gtk-theme-name="Arc"
6 | gtk-icon-theme-name="GNOME"
7 | gtk-font-name="Sans 10"
8 | gtk-cursor-theme-name="DMZ-White"
9 | gtk-cursor-theme-size=18
10 | gtk-toolbar-style=GTK_TOOLBAR_BOTH_HORIZ
11 | gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
12 | gtk-button-images=1
13 | gtk-menu-images=1
14 | gtk-enable-event-sounds=0
15 | gtk-enable-input-feedback-sounds=0
16 | gtk-xft-antialias=1
17 | gtk-xft-hinting=1
18 | gtk-xft-hintstyle="hintslight"
19 | gtk-xft-rgba="rgb"
20 | include "/root/.gtkrc-2.0.mine"
21 |
--------------------------------------------------------------------------------
/docker/image/root/Desktop/terminator.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Name=Terminator
3 | Comment=Multiple terminals in one window
4 | TryExec=terminator
5 | Exec=terminator
6 | Icon=terminator
7 | Type=Application
8 | Categories=GNOME;GTK;Utility;TerminalEmulator;System;
9 | StartupNotify=true
10 | X-Ubuntu-Gettext-Domain=terminator
11 | X-Ayatana-Desktop-Shortcuts=NewWindow;
12 | Keywords=terminal;shell;prompt;command;commandline;
13 | [NewWindow Shortcut Group]
14 | Name=Open a New Window
15 | Exec=terminator
16 | TargetEnvironment=Unity
17 |
--------------------------------------------------------------------------------
/docker/image/startup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mkdir -p /var/run/sshd
4 |
5 | chown -R root:root /root
6 | mkdir -p /root/.config/pcmanfm/LXDE/
7 | cp /usr/share/doro-lxde-wallpapers/desktop-items-0.conf /root/.config/pcmanfm/LXDE/
8 |
9 | if [ -n "$VNC_PASSWORD" ]; then
10 | echo -n "$VNC_PASSWORD" > /.password1
11 | x11vnc -storepasswd $(cat /.password1) /.password2
12 | chmod 400 /.password*
13 | sed -i 's/^command=x11vnc.*/& -rfbauth \/.password2/' /etc/supervisor/conf.d/lxde.conf
14 | export VNC_PASSWORD=
15 | fi
16 |
17 | # launch all:
18 | exec /usr/bin/tini -- /usr/bin/supervisord -n
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | app.log
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/README.md:
--------------------------------------------------------------------------------
1 | # Configuration Webportal for noVNC
2 |
3 | noVNC Configuration Webportal powered by Flask
4 |
5 | ---
6 |
7 |
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/app.ini:
--------------------------------------------------------------------------------
1 | [uwsgi]
2 | # entrypoint -- app object in app.py:
3 | module = app:app
4 | # start up in master mode and spawn 2 worker processes to serve actual requests:
5 | master = true
6 | processes = 2
7 | # enable read and write on socket for nginx:
8 | socket = webportal.sock
9 | chown-socket = www-data:www-data
10 | chmod-socket = 664
11 | # clean up the socket when the process stops:
12 | vacuum = true
13 | # kill the process on signal term:
14 | die-on-term = true
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/app.py:
--------------------------------------------------------------------------------
1 | import os
2 | from application import create_app
3 |
4 | app = create_app(os.getenv('FLASK_CONFIG') or 'default')
5 |
6 | if __name__ == '__main__':
7 | app.run(host='0.0.0.0', port=80, debug=True)
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/application/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from flask import Flask
4 |
5 | from config import basedir, config
6 |
7 | def create_app(config_name):
8 | # init app:
9 | app = Flask(
10 | __name__,
11 | static_url_path = '/static', static_folder = 'static'
12 | )
13 |
14 | # apply configs:
15 | app.config.from_object(config[config_name])
16 | config[config_name].init_app(app)
17 |
18 | # logging
19 | # ----------------------------------------------------------------
20 | import logging
21 | from .utils.log import LoggingConfiguration
22 | LoggingConfiguration.set(
23 | logging.DEBUG if os.getenv('DEBUG') else logging.INFO,
24 | 'app.log', name='WebPortal'
25 | )
26 |
27 | # views
28 | # ----------------------------------------------------------------
29 | from .main import bp as blueprint_main
30 | app.register_blueprint(blueprint_main)
31 |
32 | return app
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/application/main/__init__.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint
2 |
3 | bp = Blueprint('main', __name__)
4 |
5 | from . import views
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/application/main/views.py:
--------------------------------------------------------------------------------
1 | from flask import request, render_template
2 |
3 | from flask import current_app
4 | from . import bp
5 |
6 | import subprocess
7 | import time
8 |
9 |
10 | @bp.route('/')
11 | def index():
12 | """ Get client view portal size for noVNC
13 | """
14 | current_app.logger.info('Get client view portal size.')
15 |
16 | return render_template('index.html')
17 |
18 |
19 | @bp.route('/redirect.html')
20 | def redirect():
21 | """ Render noVNC portal
22 | """
23 | if current_app.config['VIEW_PORTAL_INITIALIZED']:
24 | current_app.logger.info('Use existing view portal configuration.')
25 | return render_template('redirect.html')
26 |
27 | # parse view portal size:
28 | env = {'width': 1024, 'height': 768}
29 | if 'width' in request.args:
30 | env['width'] = request.args['width']
31 | if 'height' in request.args:
32 | env['height'] = request.args['height']
33 |
34 | # change desktop resolution:
35 | subprocess.check_call(
36 | r"sed -i 's#^command=/usr/bin/Xvfb.*$#command=/usr/bin/Xvfb :1 -screen 0 {width}x{height}x16#' /etc/supervisor/conf.d/lxde.conf".format(**env),
37 | shell=True
38 | )
39 |
40 | # reload desktop:
41 | subprocess.check_call(r"supervisorctl update", shell=True)
42 |
43 | # make sure all the daemon processes are running:
44 | for i in range(current_app.config['MAX_TRYOUT']):
45 | # get the number of running supervisord processes:
46 | num_running = subprocess.check_output(r"supervisorctl status | grep RUNNING | wc -l", shell=True)
47 | if num_running.strip() == str(current_app.config['NUM_RUNNING']):
48 | # mark as initialized:
49 | current_app.config['VIEW_PORTAL_INITIALIZED'] = True
50 | current_app.logger.info(
51 | (
52 | 'Set view portal size to (%d, %d) '
53 | 'after tryout %d'
54 | ),
55 | int(env['width']), int(env['height']), i + 1
56 | )
57 | return render_template('redirect.html')
58 | # sleep and try again:
59 | time.sleep(current_app.config['WAIT_TIME'])
60 |
61 | return render_template('redirect.html')
62 |
63 | @bp.route('/aboutus.html')
64 | def aboutus():
65 | """ General info for testing
66 | """
67 | current_app.logger.info('Get aboutus general info.')
68 |
69 | return render_template('aboutus.html')
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/application/static/tic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/docker/image/usr/lib/webportal/application/static/tic.jpg
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/application/templates/aboutus.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Sensor Fusion Workspace
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/application/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
20 | Init VNC Portal
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/application/templates/redirect.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 | Page Redirection
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/application/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/docker/image/usr/lib/webportal/application/utils/__init__.py
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/application/utils/log.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import logging
3 | import logging.handlers
4 |
5 |
6 | #These are the sequences need to get colored ouput
7 | RESET_SEQ = "\033[0m"
8 | COLOR_SEQ = "\033[1;%dm"
9 | BOLD_SEQ = "\033[1m"
10 |
11 |
12 | class ColoredFormatter(logging.Formatter):
13 | # the terminal has 8 colors with codes from 0 to 7
14 | BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
15 |
16 | # the background is set with 40 plus the number of the color,
17 | # and the foreground with 30
18 | COLORS = {
19 | 'WARNING': COLOR_SEQ % (30 + YELLOW) + 'WARN' + RESET_SEQ,
20 | 'INFO': COLOR_SEQ % (30 + WHITE) + 'INFO' + RESET_SEQ,
21 | 'DEBUG': COLOR_SEQ % (30 + BLUE) + 'DEBUG' + RESET_SEQ,
22 | 'CRITICAL': COLOR_SEQ % (30 + YELLOW) + 'CRITI' + RESET_SEQ,
23 | 'ERROR': COLOR_SEQ % (30 + RED) + 'ERROR' + RESET_SEQ,
24 | }
25 |
26 | def __init__(self, msg, use_color=True):
27 | logging.Formatter.__init__(self, msg)
28 | self.use_color = use_color
29 |
30 | def format(self, record):
31 | if self.use_color:
32 | # defaults to plain text with no color:
33 | record.levelname = self.COLORS.get(record.levelname, record.levelname)
34 | return logging.Formatter.format(self, record)
35 |
36 |
37 | class LoggingConfiguration(object):
38 | COLOR_FORMAT = (
39 | "[%(asctime)s][%(threadName)-9s][%(levelname)s] "
40 | "%(message)s (" + BOLD_SEQ + "%(filename)s" + RESET_SEQ + ":%(lineno)d)"
41 | )
42 | NO_COLOR_FORMAT = (
43 | "[%(asctime)s][%(threadName)-9s][%(levelname)s] "
44 | "%(message)s " + "(%(filename)s:%(lineno)d)"
45 | )
46 | FILE_FORMAT = (
47 | "[%(asctime)s][%(threadName)-9s][%(levelname)s] "
48 | "%(message)s "
49 | )
50 |
51 | @classmethod
52 | def set(cls, log_level, log_filename, append=None, **kwargs):
53 | """ configure a rotating file logging
54 | """
55 | logger = logging.getLogger()
56 | logger.setLevel(log_level)
57 |
58 | COLOR_FORMAT = cls.COLOR_FORMAT
59 | NO_COLOR_FORMAT = cls.NO_COLOR_FORMAT
60 | FILE_FORMAT = cls.FILE_FORMAT
61 | if 'name' in kwargs:
62 | COLOR_FORMAT = COLOR_FORMAT.replace(
63 | '%(threadName)-9s', '%-9s' % (kwargs['name'])
64 | )
65 | NO_COLOR_FORMAT = NO_COLOR_FORMAT.replace(
66 | '%(threadName)-9s', '%-9s' % (kwargs['name'])
67 | )
68 | FILE_FORMAT = FILE_FORMAT.replace(
69 | '%(threadName)-9s', '%s' % (kwargs['name'])
70 | )
71 |
72 | # log to rotating file
73 | try:
74 | log_handler = logging.handlers.RotatingFileHandler(
75 | log_filename,
76 | mode='a+',
77 | backupCount=3
78 | )
79 | log_handler = logging.FileHandler(
80 | log_filename,
81 | mode='a+'
82 | )
83 | log_handler.setFormatter(ColoredFormatter(FILE_FORMAT, False))
84 | log_handler.setLevel(log_level)
85 | logger.addHandler(log_handler)
86 | if not append:
87 | # create a new log file:
88 | log_handler.doRollover()
89 | except:
90 | pass
91 |
92 | # log to sys.stderr using log level passed through command line
93 | if log_level != logging.NOTSET:
94 | log_handler = logging.StreamHandler(sys.stdout)
95 | if sys.platform.find('linux') >= 0:
96 | formatter = ColoredFormatter(COLOR_FORMAT)
97 | else:
98 | formatter = ColoredFormatter(NO_COLOR_FORMAT, False)
99 | log_handler.setFormatter(formatter)
100 | log_handler.setLevel(log_level)
101 | logger.addHandler(log_handler)
102 |
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/config.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | # root dir of app:
4 | basedir = os.path.abspath(os.path.dirname(__file__))
5 |
6 | class Config:
7 | # security:
8 | SECRET_KEY = os.environ.get('SECRET_KEY') or os.urandom(32)
9 |
10 | # view portal initialization:
11 | VIEW_PORTAL_INITIALIZED = False
12 | # the number of running supervisord processes:
13 | NUM_RUNNING = 6
14 | # max num. of tryouts:
15 | MAX_TRYOUT = 20
16 | WAIT_TIME = 1
17 |
18 | @staticmethod
19 | def init_app(app):
20 | """ integrate with app factory
21 | """
22 | pass
23 |
24 |
25 | class DevelopmentConfig(Config):
26 | DEBUG = True
27 |
28 |
29 | class TestingConfig(Config):
30 | TESTING = True
31 |
32 |
33 | class ProductionConfig(Config):
34 | PRODUCTION=True
35 |
36 |
37 | # configs:
38 | config = {
39 | 'development': DevelopmentConfig,
40 | 'testing': TestingConfig,
41 | 'production': ProductionConfig,
42 |
43 | 'default': DevelopmentConfig
44 | }
--------------------------------------------------------------------------------
/docker/image/usr/lib/webportal/requirements.txt:
--------------------------------------------------------------------------------
1 | flask==1.1.2
2 | uwsgi==2.0.19.1
--------------------------------------------------------------------------------
/docker/image/usr/share/doro-lxde-wallpapers/desktop-items-0.conf:
--------------------------------------------------------------------------------
1 | [*]
2 | wallpaper_mode=fit
3 | wallpaper_common=0
4 | wallpapers_configured=1
5 | wallpaper0=/usr/share/doro-lxde-wallpapers/theme.jpeg
6 | desktop_bg=#000000
7 | desktop_fg=#ffffff
8 | desktop_shadow=#111111
9 | desktop_font=Sans 12
10 | show_wm_menu=0
11 | sort=mtime;ascending;mingle;
12 | show_documents=0
13 | show_trash=0
14 | show_mounts=0
15 |
--------------------------------------------------------------------------------
/docker/image/usr/share/doro-lxde-wallpapers/theme.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/docker/image/usr/share/doro-lxde-wallpapers/theme.jpeg
--------------------------------------------------------------------------------
/docker/image/workspace/data/nginx/noVNC.log:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/docker/image/workspace/data/nginx/noVNC.log
--------------------------------------------------------------------------------
/docker/image/workspace/requirements.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/docker/image/workspace/requirements.txt
--------------------------------------------------------------------------------
/docker/installers/download-tini.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | TINI_VERSION=`curl https://github.com/krallin/tini/releases/latest | grep -o "/v.*\"" | sed 's:^..\(.*\).$:\1:'`
4 |
5 | curl -L "https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini_${TINI_VERSION}.deb" > ./tini.deb
--------------------------------------------------------------------------------
/ubuntu-setup/README.md:
--------------------------------------------------------------------------------
1 | # Ubuntu Setup Guide
2 |
3 | 如何安装Ubuntu系统
4 |
5 | ---
6 |
7 | ## Overview
8 |
9 | 本文档旨在提供Ubuntu操作系统Native安装配置指导, 支持某些对系统性能要求较高, 使用虚拟机无法满足性能要求的Linux开发工作
10 |
11 | ---
12 |
13 | ## Contents
14 |
15 | * [基础版, 本地磁盘双系统](doc/ubuntu-windows/Ubuntu双系统.pdf)
16 |
17 | * [进阶版, 外接硬盘安装](doc/external-disk/README.md)
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/README.md:
--------------------------------------------------------------------------------
1 | # Ubuntu Setup Guide
2 |
3 | 如何在外接SSD/NVME上安装Ubuntu系统
4 |
5 | ---
6 |
7 | ## Contents
8 |
9 | * [基础准备工作](https://www.shenlanxueyuan.com/my/course/303)
10 |
11 | * [重新启动并配置BIOS](https://www.shenlanxueyuan.com/my/course/303)
12 |
13 | * [安装Ubuntu, Part 1](https://www.shenlanxueyuan.com/my/course/303)
14 |
15 | * [安装Ubuntu, 配置分区表](https://www.shenlanxueyuan.com/my/course/303)
16 |
17 | * [安装Ubuntu, Part 2](https://www.shenlanxueyuan.com/my/course/303)
18 |
19 | * [配置阿里云源](https://www.shenlanxueyuan.com/my/course/303)
20 |
21 | ---
22 |
23 | ## 基础准备工作
24 |
25 | 首先, 准备两个硬盘:
26 |
27 | * 一个为**小容量USB Disk**, 用于制作Ubuntu Startup Disk, 作为**Ubuntu Installer**, 记录设备名称, 此处为**SanDisk USB**
28 |
29 |
30 |
31 | * 一个为**大容量SSD/NVMe Disk**, 用于Ubuntu Workspace Disk, 作为**Ubuntu Workspace**, 此处为**SAMSUNG SSD T3**
32 |
33 |
34 |
35 | 接着, 将两个硬盘, 全部**格式化**. 格式化时目标文件系统为**Linux EXT4**. 此处以Ubuntu平台为示例, Windows与Mac用户请自行百度, 两系统均存在类似工具.
36 |
37 |
38 |
39 | 最后, 使用工具, 在**小容量USB Disk**上制作**Ubuntu Installer**. 此处以Ubuntu平台为示例, Windows与Mac用户请自行百度, 两系统均存在类似工具.
40 |
41 | # **WARNING** 请务必仔细检查**设备名称**!!!确保选择了**正确的目标设备**!!!否则有可能**抹去现有系统盘上的数据**
42 |
43 | * 启动Creator:
44 |
45 |
46 |
47 | * 选择设备:
48 |
49 |
50 |
51 | * 确认制作:
52 |
53 |
54 |
55 | ---
56 |
57 | ## 重新启动, 配置BIOS
58 |
59 | 在Ubuntu Installer制作完成后, 将上述两USB Disk全部连接PC, 然后重新启动PC. 在系统上电时, 进入BIOS. **进入BIOS的方式和使用设备高度相关, 此处仅作示意**
60 |
61 | 此处目标设备为ThinkPad P73. 在出现OEM Logo时, 按下提示键, 进入BIOS:
62 |
63 |
64 |
65 |
66 |
67 | 选择**Boot Config**:
68 |
69 |
70 |
71 | 将启动优先级调整为**USB Device First**. 调整结束后:
72 |
73 |
74 |
75 | * 首选的启动媒介为外接USB
76 | * USB设备名称有2个:
77 |
78 | * 其中一个为**Ubuntu Installer, SanDisk USB**, 它有Bootloader, 能够引导PC进入Ubuntu系统
79 | * 另一个为**Ubuntu Workspace, SAMSUNG SSD T3**, 它没有Bootloader, 不会引导PC进入Ubuntu系统
80 |
81 | * 保存BIOS设置, 重新启动设备, 若配置成功, 应当能看到如下的GRUB界面:
82 |
83 |
84 |
85 | ---
86 |
87 | ## 安装Ubuntu
88 |
89 | 接下来进入Ubuntu安装
90 |
91 | 选择语言:
92 |
93 |
94 |
95 | 选择键盘Layout:
96 |
97 |
98 |
99 | 选择**No Network Connnection**
100 |
101 |
102 |
103 | 安装类型选择**Normal Installation & Device Drivers**
104 |
105 |
106 |
107 | 硬盘分区选择**Something Else**, 自定义分区类型.
108 |
109 |
110 |
111 | ---
112 |
113 | ## 创建分区表
114 |
115 | 接下来进入最重要的环节, 创建**Partiton Table**
116 |
117 | # **WARNING** 请务必仔细检查**设备名称**!!!确保选择了**正确的目标设备**!!!否则有可能**抹去现有系统盘上的数据**
118 |
119 | 首先, 选择正确的目标设备, 此处为**Ubuntu Workspace Disk, SAMSUNG SSD T3**, 点击**New Partition Table**
120 |
121 |
122 |
123 | # **WARNING** 请务必仔细检查**设备名称**!!!确保选择了**正确的目标设备**!!!否则有可能**抹去现有系统盘上的数据**
124 |
125 | 确认:
126 |
127 |
128 |
129 | 执行完成后, **Ubuntu Workspace Disk**会全部变成Freespace
130 |
131 |
132 |
133 | 接下来**创建分区**. 个人习惯如下, 分区按照**创建先后顺序排列**:
134 |
135 | * swap, **New Partition Type**为**Primary**, **Use As**为**swap**, 推荐大小**与PC物理内存相同**.
136 |
137 |
138 |
139 | * boot, **New Partition Type**为**Logical**, **Use As**为**EXT4 Filesystem**, 推荐大小**128/256MB**.
140 |
141 |
142 |
143 | * root, **New Partition Type**为**Logical**, **Use As**为**EXT4 Filesystem**, 推荐大小为**剩余的全部Free Space**
144 |
145 |
146 |
147 | 完成后目标设备上的分区表如下图所示, 点击**Install Now**, 启动安装:
148 |
149 |
150 |
151 | ---
152 |
153 | ## 安装Ubuntu
154 |
155 | 接下来, 完成剩余的配置, 等待安装成功:
156 |
157 | 选择区域:
158 |
159 |
160 |
161 | 设置设备名, 账号/密码:
162 |
163 |
164 |
165 | 等待安装结束:
166 |
167 |
168 |
169 | 按照提示重启PC, 完成安装.
170 |
171 | ---
172 |
173 | ## 配置阿里云源
174 |
175 | 在设备下电后, 断开**Ubuntu Installer**与PC的链接, 仅保留**Ubuntu Workspace**与PC的链接, 启动Ubuntu.
176 |
177 | 接下来还需要进行最后一步: **配置阿里云源, 更新系统软件**. 此处**至关重要**, 有些设备只有在获取最新驱动后, 才能够正常使用Ubuntu
178 |
179 | 首先, 打开**etc-apt-source.list**
180 |
181 | ```bash
182 | sudo gedit /etc/apt/sources.list
183 | ```
184 |
185 | 删除系统默认配置, 将以下阿里云源配置写入, 保存:
186 |
187 | ```bash
188 | # See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
189 | # newer versions of the distribution.
190 | deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted
191 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted
192 |
193 | ## Major bug fix updates produced after the final release of the
194 | ## distribution.
195 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted
196 |
197 | ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
198 | ## team. Also, please note that software in universe WILL NOT receive any
199 | ## review or updates from the Ubuntu security team.
200 | deb http://mirrors.aliyun.com/ubuntu/ bionic universe
201 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic universe
202 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates universe
203 |
204 | ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
205 | ## team, and may not be under a free licence. Please satisfy yourself as to
206 | ## your rights to use the software. Also, please note that software in
207 | ## multiverse WILL NOT receive any review or updates from the Ubuntu
208 | ## security team.
209 | deb http://mirrors.aliyun.com/ubuntu/ bionic multiverse
210 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic multiverse
211 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates multiverse
212 |
213 | ## N.B. software from this repository may not have been tested as
214 | ## extensively as that contained in the main release, although it includes
215 | ## newer versions of some applications which may provide useful features.
216 | ## Also, please note that software in backports WILL NOT receive any review
217 | ## or updates from the Ubuntu security team.
218 | deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
219 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
220 |
221 | ## Uncomment the following two lines to add software from Canonical's
222 | ## 'partner' repository.
223 | ## This software is not part of Ubuntu, but is offered by Canonical and the
224 | ## respective vendors as a service to Ubuntu users.
225 | # deb http://archive.canonical.com/ubuntu bionic partner
226 | # deb-src http://archive.canonical.com/ubuntu bionic partner
227 |
228 | deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted
229 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted
230 | deb http://mirrors.aliyun.com/ubuntu/ bionic-security universe
231 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security universe
232 | deb http://mirrors.aliyun.com/ubuntu/ bionic-security multiverse
233 | # deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security multiverse
234 | deb http://mirrors.aliyun.com/ubuntu/ bionic-updates multiverse restricted universe main
235 | ```
236 |
237 | 然后执行系统更新:
238 |
239 | ```bash
240 | sudo apt-get update && sudo apt-get update
241 | ```
242 |
243 | 配置成功后, 可以看到Packge URL均为阿里云源. 该设置能大幅提升相关依赖安装速度.
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/00-cleanup-a-installer-disk.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/00-cleanup-a-installer-disk.jpg
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/00-cleanup-b-ubuntu-disk.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/00-cleanup-b-ubuntu-disk.jpg
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/00-cleanup-format-disks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/00-cleanup-format-disks.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/01-startup-disk-create--confirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/01-startup-disk-create--confirm.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/01-startup-disk-create--existing-ubuntu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/01-startup-disk-create--existing-ubuntu.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/01-startup-disk-create--select-device.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/01-startup-disk-create--select-device.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/02-BIOS-boot-config.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/02-BIOS-boot-config.jpg
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/02-BIOS-boot-sequence.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/02-BIOS-boot-sequence.jpg
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/02-BIOS-enter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/02-BIOS-enter.jpg
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/02-BIOS-setup.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/02-BIOS-setup.jpg
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/02-BIOS-start-installation.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/02-BIOS-start-installation.jpg
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-a-keyboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-a-keyboard.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-a-language.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-a-language.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-c-network.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-c-network.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-d-option.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-d-option.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-e-type.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-e-type.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-f-create-new-partition-confirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-f-create-new-partition-confirm.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-f-create-new-partition-result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-f-create-new-partition-result.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-f-create-new-partition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-f-create-new-partition.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-g-02-boot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-g-02-boot.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-g-03-root.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-g-03-root.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-g-result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-g-result.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-h-confirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-h-confirm.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-i-region.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-i-region.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-k-config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-k-config.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-l-finish.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/external-disk/images/03-install-ubuntu-l-finish.png
--------------------------------------------------------------------------------
/ubuntu-setup/doc/ubuntu-windows/Ubuntu双系统.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/ubuntu-setup/doc/ubuntu-windows/Ubuntu双系统.pdf
--------------------------------------------------------------------------------
/workspace/.gitignore:
--------------------------------------------------------------------------------
1 | ordered_startup.log
--------------------------------------------------------------------------------
/workspace/README.md:
--------------------------------------------------------------------------------
1 | # Sensor Fusion for Localization and Mapping Workspace
2 |
3 | 本目录为Docker Workspace中 /workspace 在本地的挂载点.
4 |
--------------------------------------------------------------------------------
/workspace/assignments/.gitignore:
--------------------------------------------------------------------------------
1 | image_based_modelling
2 | ImageBasedModellingEdu
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/.gitignore:
--------------------------------------------------------------------------------
1 | .catkin_tools
2 | build
3 | devel
4 | install
5 | logs
6 | output
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/README.md:
--------------------------------------------------------------------------------
1 | # Multi-Sensor Fusion for Localization & Mapping -- 多传感器融合定位与建图: Introduction
2 |
3 | 深蓝学院多传感器融合定位与建图第1节Environment Setup作业框架.
4 |
5 | ---
6 |
7 | ## Overview
8 |
9 | 本作业旨在引导您:
10 |
11 | * 验证环境配置的正确性
12 | * 熟悉课程教学框架
13 |
14 | ---
15 |
16 | ## Getting Started
17 |
18 | 启动Docker后, 打开浏览器, 前往localhost:40080, 进入Web Workspace. **若需要提高清晰度, 可以更改URL中的quality参数**. 启动Terminator, 将两个Shell的工作目录切换如下:
19 |
20 |
21 |
22 | 在**上侧**的Shell中, 输入如下命令, **编译catkin_workspace**
23 |
24 | ```bash
25 | # build
26 | catkin config --install && catkin build
27 | ```
28 |
29 | 然后**启动解决方案**
30 |
31 | ```bash
32 | # set up session:
33 | source install/setup.bash
34 | # launch:
35 | roslaunch lidar_localization hello_kitti.launch
36 | ```
37 |
38 | 在**下侧**的Shell中, 输入如下命令, **Play KITTI ROS Bag**
39 |
40 | ```bash
41 | # play ROS bag
42 | rosbag play kitti_2011_10_03_drive_0027_synced.bag
43 | ```
44 |
45 | 成功后, 可以看到如下的RViz界面:
46 |
47 |
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/doc/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/workspace/assignments/01-introduction/doc/demo.png
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/doc/terminator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlexGeControl/Sensor-Fusion-for-Localization-Courseware/e1d8ea2ad00a4f4314d059630e729e540a0ad08e/workspace/assignments/01-introduction/doc/terminator.png
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | /opt/ros/melodic/share/catkin/cmake/toplevel.cmake
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | Log
3 |
4 | *.INFO
5 | *.INFO.*
6 |
7 | # Prerequisites
8 | *.d
9 |
10 | # Compiled Object files
11 | *.slo
12 | *.lo
13 | *.o
14 | *.obj
15 |
16 | # Precompiled Headers
17 | *.gch
18 | *.pch
19 |
20 | # Compiled Dynamic libraries
21 | *.so
22 | *.dylib
23 | *.dll
24 |
25 | # Fortran module files
26 | *.mod
27 | *.smod
28 |
29 | # Compiled Static libraries
30 | *.lai
31 | *.la
32 | *.a
33 | *.lib
34 |
35 | # Executables
36 | *.exe
37 | *.out
38 | *.app
39 |
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10.2)
2 | project(lidar_localization)
3 |
4 | SET(CMAKE_BUILD_TYPE "Release")
5 | SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
6 | add_compile_options(-std=c++14)
7 | add_definitions(-std=c++14)
8 |
9 | find_package(catkin REQUIRED COMPONENTS
10 | roscpp
11 | rospy
12 | std_msgs
13 | pcl_ros
14 | geometry_msgs
15 | tf
16 | eigen_conversions
17 | message_generation
18 | std_srvs
19 | )
20 |
21 | set(ALL_TARGET_LIBRARIES "")
22 |
23 | include(cmake/glog.cmake)
24 | include(cmake/PCL.cmake)
25 | include(cmake/geographic.cmake)
26 |
27 | include_directories(include ${catkin_INCLUDE_DIRS})
28 |
29 | include(cmake/global_defination.cmake)
30 | catkin_package()
31 |
32 | file(GLOB_RECURSE ALL_SRCS "*.cpp")
33 | file(GLOB_RECURSE NODE_SRCS "src/*_node.cpp")
34 |
35 | list(REMOVE_ITEM ALL_SRCS ${NODE_SRCS})
36 |
37 | add_executable(hello_kitti_node src/hello_kitti_node.cpp ${ALL_SRCS})
38 | target_link_libraries(hello_kitti_node ${catkin_LIBRARIES} ${ALL_TARGET_LIBRARIES})
39 |
40 | #############
41 | ## Install ##
42 | #############
43 |
44 | # all install targets should use catkin DESTINATION variables
45 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
46 |
47 | ## Mark executable scripts (Python etc.) for installation
48 | ## in contrast to setup.py, you can choose the destination
49 | # catkin_install_python(PROGRAMS
50 | # scripts/my_python_script
51 | # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
52 | # )
53 |
54 | ## Mark executables for installation
55 | ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
56 |
57 | install(
58 | TARGETS
59 | hello_kitti_node
60 | RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
61 | )
62 |
63 | ## Mark cpp header files for installation
64 | install(
65 | DIRECTORY
66 | include/
67 | DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
68 | FILES_MATCHING PATTERN "*.h"
69 | PATTERN ".svn" EXCLUDE
70 | )
71 |
72 | ## Mark other directories for installation:
73 | install(
74 | DIRECTORY
75 | launch/
76 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
77 | FILES_MATCHING PATTERN "*.launch"
78 | )
79 | install(
80 | DIRECTORY
81 | config/
82 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/config
83 | FILES_MATCHING PATTERN "*.yaml"
84 | )
85 | install(
86 | DIRECTORY
87 | rviz/
88 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/rviz
89 | FILES_MATCHING PATTERN "*.rviz"
90 | )
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/cmake/PCL.cmake:
--------------------------------------------------------------------------------
1 | find_package(PCL 1.7 REQUIRED)
2 | list(REMOVE_ITEM PCL_LIBRARIES "vtkproj4")
3 |
4 | include_directories(${PCL_INCLUDE_DIRS})
5 | list(APPEND ALL_TARGET_LIBRARIES ${PCL_LIBRARIES})
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/cmake/geographic.cmake:
--------------------------------------------------------------------------------
1 | find_package (GeographicLib REQUIRED)
2 |
3 | include_directories(${GeographicLib_INCLUDE_DIRS})
4 | list(APPEND ALL_TARGET_LIBRARIES ${GeographicLib_LIBRARIES})
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/cmake/global_defination.cmake:
--------------------------------------------------------------------------------
1 | set(WORK_SPACE_PATH ${PROJECT_SOURCE_DIR})
2 | configure_file (
3 | ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}/global_defination/global_defination.h.in
4 | ${PROJECT_BINARY_DIR}/include/${PROJECT_NAME}/global_defination/global_defination.h)
5 | include_directories(${PROJECT_BINARY_DIR}/include)
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/cmake/glog.cmake:
--------------------------------------------------------------------------------
1 | include(FindPackageHandleStandardArgs)
2 |
3 | set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog")
4 |
5 | if(WIN32)
6 | find_path(GLOG_INCLUDE_DIR glog/logging.h
7 | PATHS ${GLOG_ROOT_DIR}/src/windows)
8 | else()
9 | find_path(GLOG_INCLUDE_DIR glog/logging.h
10 | PATHS ${GLOG_ROOT_DIR})
11 | endif()
12 |
13 | if(MSVC)
14 | find_library(GLOG_LIBRARY_RELEASE libglog_static
15 | PATHS ${GLOG_ROOT_DIR}
16 | PATH_SUFFIXES Release)
17 |
18 | find_library(GLOG_LIBRARY_DEBUG libglog_static
19 | PATHS ${GLOG_ROOT_DIR}
20 | PATH_SUFFIXES Debug)
21 |
22 | set(GLOG_LIBRARY optimized ${GLOG_LIBRARY_RELEASE} debug ${GLOG_LIBRARY_DEBUG})
23 | else()
24 | find_library(GLOG_LIBRARY glog
25 | PATHS ${GLOG_ROOT_DIR}
26 | PATH_SUFFIXES lib lib64)
27 | endif()
28 |
29 | find_package_handle_standard_args(Glog DEFAULT_MSG GLOG_INCLUDE_DIR GLOG_LIBRARY)
30 |
31 | if(GLOG_FOUND)
32 | set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR})
33 | set(GLOG_LIBRARIES ${GLOG_LIBRARY})
34 | message(STATUS "Found glog (include: ${GLOG_INCLUDE_DIR}, library: ${GLOG_LIBRARY})")
35 | mark_as_advanced(GLOG_ROOT_DIR GLOG_LIBRARY_RELEASE GLOG_LIBRARY_DEBUG
36 | GLOG_LIBRARY GLOG_INCLUDE_DIR)
37 | endif()
38 |
39 | include_directories(${GLOG_INCLUDE_DIRS})
40 | list(APPEND ALL_TARGET_LIBRARIES ${GLOG_LIBRARIES})
41 |
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/include/lidar_localization/global_defination/global_defination.h.in:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description:
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-05 02:27:30
5 | */
6 | #ifndef LIDAR_LOCALIZATION_GLOBAL_DEFINATION_H_IN_
7 | #define LIDAR_LOCALIZATION_GLOBAL_DEFINATION_H_IN_
8 |
9 | #include
10 |
11 | namespace lidar_localization {
12 | const std::string WORK_SPACE_PATH = "@WORK_SPACE_PATH@";
13 | }
14 | #endif
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/include/lidar_localization/publisher/cloud_publisher.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: 在ros中发布点云
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-05 02:27:30
5 | */
6 |
7 | #ifndef LIDAR_LOCALIZATION_PUBLISHER_CLOUD_PUBLISHER_HPP_
8 | #define LIDAR_LOCALIZATION_PUBLISHER_CLOUD_PUBLISHER_HPP_
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #include "lidar_localization/sensor_data/cloud_data.hpp"
16 |
17 | namespace lidar_localization {
18 | class CloudPublisher {
19 | public:
20 | CloudPublisher(ros::NodeHandle& nh,
21 | std::string topic_name,
22 | size_t buff_size,
23 | std::string frame_id);
24 | CloudPublisher() = default;
25 | void Publish(CloudData::CLOUD_PTR cloud_ptr_input);
26 |
27 | private:
28 | ros::NodeHandle nh_;
29 | ros::Publisher publisher_;
30 | std::string frame_id_;
31 | };
32 | }
33 | #endif
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/include/lidar_localization/publisher/odometry_publisher.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: odometry 信息发布
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-06 21:05:47
5 | */
6 | #ifndef LIDAR_LOCALIZATION_PUBLISHER_ODOMETRY_PUBLISHER_HPP_
7 | #define LIDAR_LOCALIZATION_PUBLISHER_ODOMETRY_PUBLISHER_HPP_
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | namespace lidar_localization {
16 | class OdometryPublisher {
17 | public:
18 | OdometryPublisher(ros::NodeHandle& nh,
19 | std::string topic_name,
20 | std::string base_frame_id,
21 | std::string child_frame_id,
22 | int buff_size);
23 | OdometryPublisher() = default;
24 |
25 | void Publish(const Eigen::Matrix4f& transform_matrix);
26 |
27 | private:
28 | ros::NodeHandle nh_;
29 | ros::Publisher publisher_;
30 | nav_msgs::Odometry odometry_;
31 | };
32 | }
33 | #endif
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/include/lidar_localization/publisher/tf_broadcaster.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: TF broadcaster
3 | * @Author: Ren Qian
4 | * @Date: 2020-03-05 15:23:26
5 | */
6 |
7 | #ifndef LIDAR_LOCALIZATION_PUBLISHER_TF_BROADCASTER_HPP_
8 | #define LIDAR_LOCALIZATION_PUBLISHER_TF_BROADCASTER_HPP_
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | namespace lidar_localization {
17 |
18 | class TFBroadCaster {
19 | public:
20 | TFBroadCaster(std::string frame_id, std::string child_frame_id);
21 | TFBroadCaster() = default;
22 | void SendTransform(Eigen::Matrix4f pose, double time);
23 | protected:
24 | tf::StampedTransform transform_;
25 | tf::TransformBroadcaster broadcaster_;
26 | };
27 |
28 | }
29 |
30 | #endif // namespace lidar_localization
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/include/lidar_localization/sensor_data/cloud_data.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description:
3 | * @Author: Ren Qian
4 | * @Date: 2019-07-17 18:17:49
5 | */
6 | #ifndef LIDAR_LOCALIZATION_SENSOR_DATA_CLOUD_DATA_HPP_
7 | #define LIDAR_LOCALIZATION_SENSOR_DATA_CLOUD_DATA_HPP_
8 |
9 | #include
10 | #include
11 |
12 | namespace lidar_localization {
13 | class CloudData {
14 | public:
15 | using POINT = pcl::PointXYZ;
16 | using CLOUD = pcl::PointCloud;
17 | using CLOUD_PTR = CLOUD::Ptr;
18 |
19 | public:
20 | CloudData()
21 | :cloud_ptr(new CLOUD()) {
22 | }
23 |
24 | public:
25 | double time = 0.0;
26 | CLOUD_PTR cloud_ptr;
27 | };
28 | }
29 |
30 | #endif
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/include/lidar_localization/sensor_data/gnss_data.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description:
3 | * @Author: Ren Qian
4 | * @Date: 2019-07-17 18:25:13
5 | */
6 | #ifndef LIDAR_LOCALIZATION_SENSOR_DATA_GNSS_DATA_HPP_
7 | #define LIDAR_LOCALIZATION_SENSOR_DATA_GNSS_DATA_HPP_
8 |
9 | #include
10 |
11 | #include
12 |
13 | namespace lidar_localization {
14 | class GNSSData {
15 | public:
16 | double time = 0.0;
17 | double longitude = 0.0;
18 | double latitude = 0.0;
19 | double altitude = 0.0;
20 | double local_E = 0.0;
21 | double local_N = 0.0;
22 | double local_U = 0.0;
23 | int status = 0;
24 | int service = 0;
25 |
26 | private:
27 | static GeographicLib::LocalCartesian geo_converter;
28 | static bool origin_position_inited;
29 |
30 | public:
31 | void InitOriginPosition();
32 | void UpdateXYZ();
33 | static bool SyncData(std::deque& UnsyncedData, std::deque& SyncedData, double sync_time);
34 | };
35 | }
36 | #endif
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/include/lidar_localization/sensor_data/imu_data.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description:
3 | * @Author: Ren Qian
4 | * @Date: 2019-07-17 18:27:40
5 | */
6 | #ifndef LIDAR_LOCALIZATION_SENSOR_DATA_IMU_DATA_HPP_
7 | #define LIDAR_LOCALIZATION_SENSOR_DATA_IMU_DATA_HPP_
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | namespace lidar_localization {
14 | class IMUData {
15 | public:
16 | struct LinearAcceleration {
17 | double x = 0.0;
18 | double y = 0.0;
19 | double z = 0.0;
20 | };
21 |
22 | struct AngularVelocity {
23 | double x = 0.0;
24 | double y = 0.0;
25 | double z = 0.0;
26 | };
27 |
28 | class Orientation {
29 | public:
30 | double x = 0.0;
31 | double y = 0.0;
32 | double z = 0.0;
33 | double w = 0.0;
34 |
35 | public:
36 | void Normlize() {
37 | double norm = sqrt(pow(x, 2.0) + pow(y, 2.0) + pow(z, 2.0) + pow(w, 2.0));
38 | x /= norm;
39 | y /= norm;
40 | z /= norm;
41 | w /= norm;
42 | }
43 | };
44 |
45 | double time = 0.0;
46 | LinearAcceleration linear_acceleration;
47 | AngularVelocity angular_velocity;
48 | Orientation orientation;
49 |
50 | public:
51 | // 把四元数转换成旋转矩阵送出去
52 | Eigen::Matrix3f GetOrientationMatrix();
53 | static bool SyncData(std::deque& UnsyncedData, std::deque& SyncedData, double sync_time);
54 | };
55 | }
56 | #endif
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/include/lidar_localization/subscriber/cloud_subscriber.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: 订阅激光点云信息,并解析数据
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-05 02:27:30
5 | */
6 |
7 | #ifndef LIDAR_LOCALIZATION_SUBSCRIBER_CLOUD_SUBSCRIBER_HPP_
8 | #define LIDAR_LOCALIZATION_SUBSCRIBER_CLOUD_SUBSCRIBER_HPP_
9 |
10 | #include
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | #include "lidar_localization/sensor_data/cloud_data.hpp"
19 |
20 | namespace lidar_localization {
21 | class CloudSubscriber {
22 | public:
23 | CloudSubscriber(ros::NodeHandle& nh, std::string topic_name, size_t buff_size);
24 | CloudSubscriber() = default;
25 | void ParseData(std::deque& deque_cloud_data);
26 |
27 | private:
28 | void msg_callback(const sensor_msgs::PointCloud2::ConstPtr& cloud_msg_ptr);
29 |
30 | private:
31 | ros::NodeHandle nh_;
32 | ros::Subscriber subscriber_;
33 |
34 | std::deque new_cloud_data_;
35 | };
36 | }
37 |
38 | #endif
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/include/lidar_localization/subscriber/gnss_subscriber.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description:
3 | * @Author: Ren Qian
4 | * @Date: 2019-03-31 12:58:10
5 | */
6 | #ifndef LIDAR_LOCALIZATION_SUBSCRIBER_GNSS_SUBSCRIBER_HPP_
7 | #define LIDAR_LOCALIZATION_SUBSCRIBER_GNSS_SUBSCRIBER_HPP_
8 |
9 | #include
10 | #include
11 | #include "sensor_msgs/NavSatFix.h"
12 | #include "lidar_localization/sensor_data/gnss_data.hpp"
13 |
14 | namespace lidar_localization {
15 | class GNSSSubscriber {
16 | public:
17 | GNSSSubscriber(ros::NodeHandle& nh, std::string topic_name, size_t buff_size);
18 | GNSSSubscriber() = default;
19 | void ParseData(std::deque& deque_gnss_data);
20 |
21 | private:
22 | void msg_callback(const sensor_msgs::NavSatFixConstPtr& nav_sat_fix_ptr);
23 |
24 | private:
25 | ros::NodeHandle nh_;
26 | ros::Subscriber subscriber_;
27 |
28 | std::deque new_gnss_data_;
29 | };
30 | }
31 | #endif
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/include/lidar_localization/subscriber/imu_subscriber.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: 订阅imu数据
3 | * @Author: Ren Qian
4 | * @Date: 2019-08-19 19:22:17
5 | */
6 | #ifndef LIDAR_LOCALIZATION_SUBSCRIBER_IMU_SUBSCRIBER_HPP_
7 | #define LIDAR_LOCALIZATION_SUBSCRIBER_IMU_SUBSCRIBER_HPP_
8 |
9 | #include
10 | #include
11 | #include "sensor_msgs/Imu.h"
12 | #include "lidar_localization/sensor_data/imu_data.hpp"
13 |
14 | namespace lidar_localization {
15 | class IMUSubscriber {
16 | public:
17 | IMUSubscriber(ros::NodeHandle& nh, std::string topic_name, size_t buff_size);
18 | IMUSubscriber() = default;
19 | void ParseData(std::deque& deque_imu_data);
20 |
21 | private:
22 | void msg_callback(const sensor_msgs::ImuConstPtr& imu_msg_ptr);
23 |
24 | private:
25 | ros::NodeHandle nh_;
26 | ros::Subscriber subscriber_;
27 |
28 | std::deque new_imu_data_;
29 | };
30 | }
31 | #endif
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/include/lidar_localization/subscriber/tf_listener.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: TF listener
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-06 16:01:21
5 | */
6 | #ifndef LIDAR_LOCALIZATION_TF_LISTENER_HPP_
7 | #define LIDAR_LOCALIZATION_TF_LISTENER_HPP_
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | namespace lidar_localization {
16 | class TFListener {
17 | public:
18 | TFListener(ros::NodeHandle& nh, std::string base_frame_id, std::string child_frame_id);
19 | TFListener() = default;
20 |
21 | bool LookupData(Eigen::Matrix4f& transform_matrix);
22 |
23 | private:
24 | bool TransformToMatrix(const tf::StampedTransform& transform, Eigen::Matrix4f& transform_matrix);
25 |
26 | private:
27 | ros::NodeHandle nh_;
28 | tf::TransformListener listener_;
29 | std::string base_frame_id_;
30 | std::string child_frame_id_;
31 | };
32 | }
33 |
34 | #endif
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/launch/hello_kitti.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | lidar_localization
4 | 0.0.0
5 | The lidar_localization package
6 |
7 |
8 |
9 |
10 | rq
11 |
12 |
13 |
14 |
15 |
16 | TODO
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | catkin
52 | roscpp
53 | rospy
54 | roscpp
55 | rospy
56 | roscpp
57 | rospy
58 |
59 | message_generation
60 | message_runtime
61 |
62 | sensor_msgs
63 | pcl_ros
64 | std_msgs
65 | geometry_msgs
66 | tf
67 | eigen_conversions
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/rviz/hello_kitti.rviz:
--------------------------------------------------------------------------------
1 | Panels:
2 | - Class: rviz/Displays
3 | Help Height: 78
4 | Name: Displays
5 | Property Tree Widget:
6 | Expanded:
7 | - /Global Options1
8 | - /Status1
9 | - /current_scan1/Autocompute Value Bounds1
10 | Splitter Ratio: 0.5
11 | Tree Height: 237
12 | - Class: rviz/Selection
13 | Name: Selection
14 | - Class: rviz/Tool Properties
15 | Expanded:
16 | - /2D Pose Estimate1
17 | - /2D Nav Goal1
18 | - /Publish Point1
19 | Name: Tool Properties
20 | Splitter Ratio: 0.5886790156364441
21 | - Class: rviz/Views
22 | Expanded:
23 | - /Current View1
24 | Name: Views
25 | Splitter Ratio: 0.5
26 | - Class: rviz/Time
27 | Experimental: false
28 | Name: Time
29 | SyncMode: 0
30 | SyncSource: current_scan
31 | Preferences:
32 | PromptSaveOnExit: true
33 | Toolbars:
34 | toolButtonStyle: 2
35 | Visualization Manager:
36 | Class: ""
37 | Displays:
38 | - Alpha: 0.5
39 | Cell Size: 1
40 | Class: rviz/Grid
41 | Color: 160; 160; 164
42 | Enabled: true
43 | Line Style:
44 | Line Width: 0.029999999329447746
45 | Value: Lines
46 | Name: Grid
47 | Normal Cell Count: 0
48 | Offset:
49 | X: 0
50 | Y: 0
51 | Z: 0
52 | Plane: XY
53 | Plane Cell Count: 10
54 | Reference Frame:
55 | Value: true
56 | - Class: rviz/Image
57 | Enabled: true
58 | Image Topic: /kitti/camera_color_left/image_raw
59 | Max Value: 1
60 | Median window: 5
61 | Min Value: 0
62 | Name: Image
63 | Normalize Range: true
64 | Queue Size: 2
65 | Transport Hint: raw
66 | Unreliable: false
67 | Value: true
68 | - Alpha: 0.20000000298023224
69 | Autocompute Intensity Bounds: true
70 | Autocompute Value Bounds:
71 | Max Value: 4.7789998054504395
72 | Min Value: -9.574000358581543
73 | Value: false
74 | Axis: Z
75 | Channel Name: intensity
76 | Class: rviz/PointCloud2
77 | Color: 255; 255; 255
78 | Color Transformer: AxisColor
79 | Decay Time: 0
80 | Enabled: true
81 | Invert Rainbow: false
82 | Max Color: 255; 255; 255
83 | Max Intensity: 255
84 | Min Color: 0; 0; 0
85 | Min Intensity: 7
86 | Name: current_scan
87 | Position Transformer: XYZ
88 | Queue Size: 10
89 | Selectable: true
90 | Size (Pixels): 2
91 | Size (m): 0.5
92 | Style: Points
93 | Topic: /current_scan
94 | Unreliable: false
95 | Use Fixed Frame: true
96 | Use rainbow: true
97 | Value: true
98 | - Angle Tolerance: 1
99 | Class: rviz/Odometry
100 | Covariance:
101 | Orientation:
102 | Alpha: 0.5
103 | Color: 255; 255; 127
104 | Color Style: Unique
105 | Frame: Local
106 | Offset: 1
107 | Scale: 1
108 | Value: true
109 | Position:
110 | Alpha: 0.30000001192092896
111 | Color: 204; 51; 204
112 | Scale: 1
113 | Value: true
114 | Value: true
115 | Enabled: true
116 | Keep: 10000000
117 | Name: reference_odometry
118 | Position Tolerance: 1
119 | Shape:
120 | Alpha: 1
121 | Axes Length: 1
122 | Axes Radius: 0.10000000149011612
123 | Color: 255; 25; 0
124 | Head Length: 5
125 | Head Radius: 1
126 | Shaft Length: 1
127 | Shaft Radius: 0.10000000149011612
128 | Value: Arrow
129 | Topic: /lidar_odom
130 | Unreliable: false
131 | Value: true
132 | Enabled: true
133 | Global Options:
134 | Background Color: 48; 48; 48
135 | Default Light: true
136 | Fixed Frame: map
137 | Frame Rate: 30
138 | Name: root
139 | Tools:
140 | - Class: rviz/Interact
141 | Hide Inactive Objects: true
142 | - Class: rviz/MoveCamera
143 | - Class: rviz/Select
144 | - Class: rviz/FocusCamera
145 | - Class: rviz/Measure
146 | - Class: rviz/SetInitialPose
147 | Theta std deviation: 0.2617993950843811
148 | Topic: /initialpose
149 | X std deviation: 0.5
150 | Y std deviation: 0.5
151 | - Class: rviz/SetGoal
152 | Topic: /move_base_simple/goal
153 | - Class: rviz/PublishPoint
154 | Single click: true
155 | Topic: /clicked_point
156 | Value: true
157 | Views:
158 | Current:
159 | Class: rviz/Orbit
160 | Distance: 141.82858276367188
161 | Enable Stereo Rendering:
162 | Stereo Eye Separation: 0.05999999865889549
163 | Stereo Focal Distance: 1
164 | Swap Stereo Eyes: false
165 | Value: false
166 | Focal Point:
167 | X: -0.40340137481689453
168 | Y: 93.0905532836914
169 | Z: -1.8055267333984375
170 | Focal Shape Fixed Size: false
171 | Focal Shape Size: 0.05000000074505806
172 | Invert Z Axis: false
173 | Name: Current View
174 | Near Clip Distance: 0.009999999776482582
175 | Pitch: 1.5697963237762451
176 | Target Frame: base_link
177 | Value: Orbit (rviz)
178 | Yaw: 4.203584671020508
179 | Saved: ~
180 | Window Geometry:
181 | Displays:
182 | collapsed: false
183 | Height: 551
184 | Hide Left Dock: false
185 | Hide Right Dock: true
186 | Image:
187 | collapsed: false
188 | QMainWindow State: 000000ff00000000fd00000004000000000000016a000001ccfc020000000cfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005d00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001b300000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003e00000178000000cb00fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d00610067006501000001bc0000004e0000001600fffffffb0000000a0049006d00610067006500000002f4000000ca0000000000000000fb0000000a0049006d00610067006500000002c8000000f60000000000000000fb0000000a0049006d00610067006501000002f4000000ca0000000000000000000000010000010f00000188fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003e00000188000000a500fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004d30000003efc0100000002fb0000000800540069006d00650000000000000004d30000026c00fffffffb0000000800540069006d0065010000000000000450000000000000000000000363000001cc00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
189 | Selection:
190 | collapsed: false
191 | Time:
192 | collapsed: false
193 | Tool Properties:
194 | collapsed: false
195 | Views:
196 | collapsed: true
197 | Width: 1235
198 | X: 0
199 | Y: 0
200 |
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/slam_data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/src/hello_kitti_node.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description:
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-05 02:56:27
5 | */
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #include "lidar_localization/global_defination/global_defination.h"
12 | #include "glog/logging.h"
13 |
14 | //
15 | // TF tree:
16 | //
17 | #include "lidar_localization/subscriber/tf_listener.hpp"
18 | #include "lidar_localization/publisher/tf_broadcaster.hpp"
19 |
20 | //
21 | // subscribers:
22 | //
23 | #include "lidar_localization/subscriber/cloud_subscriber.hpp"
24 | #include "lidar_localization/subscriber/imu_subscriber.hpp"
25 | #include "lidar_localization/subscriber/gnss_subscriber.hpp"
26 | //
27 | // publishers:
28 | //
29 | #include "lidar_localization/publisher/cloud_publisher.hpp"
30 | #include "lidar_localization/publisher/odometry_publisher.hpp"
31 |
32 | using namespace lidar_localization;
33 |
34 | void GetTransformIMUToMap(
35 | GNSSData &gnss_data, IMUData &imu_data,
36 | Eigen::Matrix4f &imu_to_map
37 | ) {
38 | //
39 | // init
40 | //
41 | gnss_data.UpdateXYZ();
42 | //
43 | // a. set position:
44 | //
45 | imu_to_map(0,3) = gnss_data.local_E;
46 | imu_to_map(1,3) = gnss_data.local_N;
47 | imu_to_map(2,3) = gnss_data.local_U;
48 | //
49 | // b. set orientation:
50 | //
51 | imu_to_map.block<3,3>(0,0) = imu_data.GetOrientationMatrix();
52 | }
53 |
54 |
55 | int main(
56 | int argc,
57 | char *argv[]
58 | ) {
59 | google::InitGoogleLogging(argv[0]);
60 |
61 | FLAGS_log_dir = WORK_SPACE_PATH + "/Log";
62 | FLAGS_alsologtostderr = 1;
63 |
64 | ros::init(argc, argv, "hello_kitti_node");
65 | ros::NodeHandle nh;
66 |
67 | //
68 | // get TF:
69 | //
70 | std::shared_ptr lidar_to_imu_tf_sub_ptr = std::make_shared(nh, "/imu_link", "/velo_link");
71 | std::shared_ptr lidar_to_map_tf_pub_ptr = std::make_shared("/map", "/velo_link");
72 |
73 | //
74 | // subscribe to topics:
75 | //
76 | std::shared_ptr cloud_sub_ptr = std::make_shared(nh, "/kitti/velo/pointcloud", 100000);
77 | std::shared_ptr imu_sub_ptr = std::make_shared(nh, "/kitti/oxts/imu", 1000000);
78 | std::shared_ptr gnss_sub_ptr = std::make_shared(nh, "/kitti/oxts/gps/fix", 1000000);
79 |
80 | //
81 | // register publishers:
82 | //
83 | std::shared_ptr cloud_pub_ptr = std::make_shared(nh, "current_scan", 100, "/map");
84 | std::shared_ptr odom_pub_ptr = std::make_shared(nh, "lidar_odom", "/map", "velo_link", 100);
85 |
86 | std::deque cloud_data_buff;
87 | std::deque imu_data_buff;
88 | std::deque gnss_data_buff;
89 |
90 | Eigen::Matrix4f lidar_to_imu = Eigen::Matrix4f::Identity();
91 | Eigen::Matrix4f imu_to_map = Eigen::Matrix4f::Identity();
92 |
93 | bool transform_received = false;
94 | bool gnss_origin_position_inited = false;
95 |
96 | ros::Rate rate(100);
97 |
98 | while (ros::ok()) {
99 | ros::spinOnce();
100 |
101 | cloud_sub_ptr->ParseData(cloud_data_buff);
102 | imu_sub_ptr->ParseData(imu_data_buff);
103 | gnss_sub_ptr->ParseData(gnss_data_buff);
104 |
105 | if (!transform_received) {
106 | if (lidar_to_imu_tf_sub_ptr->LookupData(lidar_to_imu)) {
107 | transform_received = true;
108 | }
109 | } else {
110 | while (
111 | !cloud_data_buff.empty() &&
112 | !imu_data_buff.empty() &&
113 | !gnss_data_buff.empty()
114 | ) {
115 | CloudData cloud_data = cloud_data_buff.front();
116 | IMUData imu_data = imu_data_buff.front();
117 | GNSSData gnss_data = gnss_data_buff.front();
118 |
119 | double d_time = cloud_data.time - imu_data.time;
120 |
121 | if (d_time < -0.05) {
122 | cloud_data_buff.pop_front();
123 | } else if (d_time > 0.05) {
124 | imu_data_buff.pop_front();
125 | gnss_data_buff.pop_front();
126 | } else {
127 | cloud_data_buff.pop_front();
128 | imu_data_buff.pop_front();
129 | gnss_data_buff.pop_front();
130 |
131 | if (!gnss_origin_position_inited) {
132 | gnss_data.InitOriginPosition();
133 | gnss_origin_position_inited = true;
134 | }
135 |
136 | GetTransformIMUToMap(
137 | gnss_data, imu_data,
138 | imu_to_map
139 | );
140 |
141 | // lidar pose in map frame:
142 | Eigen::Matrix4f lidar_odometry = imu_to_map * lidar_to_imu;
143 | // lidar measurement in map frame:
144 | pcl::transformPointCloud(
145 | *cloud_data.cloud_ptr, *cloud_data.cloud_ptr,
146 | lidar_odometry
147 | );
148 |
149 | cloud_pub_ptr->Publish(cloud_data.cloud_ptr);
150 | odom_pub_ptr->Publish(lidar_odometry);
151 |
152 | //
153 | // publish TF: lidar -> map
154 | //
155 | lidar_to_map_tf_pub_ptr->SendTransform(lidar_odometry, cloud_data.time);
156 | }
157 | }
158 | }
159 |
160 | rate.sleep();
161 | }
162 |
163 | return EXIT_SUCCESS;
164 | }
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/src/publisher/cloud_publisher.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: 通过ros发布点云
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-05 02:27:30
5 | */
6 |
7 | #include "lidar_localization/publisher/cloud_publisher.hpp"
8 |
9 | namespace lidar_localization {
10 | CloudPublisher::CloudPublisher(ros::NodeHandle& nh,
11 | std::string topic_name,
12 | size_t buff_size,
13 | std::string frame_id)
14 | :nh_(nh), frame_id_(frame_id) {
15 | publisher_ = nh_.advertise(topic_name, buff_size);
16 | }
17 |
18 | void CloudPublisher::Publish(CloudData::CLOUD_PTR cloud_ptr_input) {
19 | sensor_msgs::PointCloud2Ptr cloud_ptr_output(new sensor_msgs::PointCloud2());
20 | pcl::toROSMsg(*cloud_ptr_input, *cloud_ptr_output);
21 | cloud_ptr_output->header.stamp = ros::Time::now();
22 | cloud_ptr_output->header.frame_id = frame_id_;
23 | publisher_.publish(*cloud_ptr_output);
24 | }
25 |
26 | } // namespace data_output
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/src/publisher/odometry_publisher.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: 里程计信息发布
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-06 21:11:44
5 | */
6 | #include "lidar_localization/publisher/odometry_publisher.hpp"
7 |
8 | namespace lidar_localization {
9 | OdometryPublisher::OdometryPublisher(ros::NodeHandle& nh,
10 | std::string topic_name,
11 | std::string base_frame_id,
12 | std::string child_frame_id,
13 | int buff_size)
14 | :nh_(nh) {
15 |
16 | publisher_ = nh_.advertise(topic_name, buff_size);
17 | odometry_.header.frame_id = base_frame_id;
18 | odometry_.child_frame_id = child_frame_id;
19 | }
20 |
21 | void OdometryPublisher::Publish(const Eigen::Matrix4f& transform_matrix) {
22 | odometry_.header.stamp = ros::Time::now();
23 |
24 | //set the position
25 | odometry_.pose.pose.position.x = transform_matrix(0,3);
26 | odometry_.pose.pose.position.y = transform_matrix(1,3);
27 | odometry_.pose.pose.position.z = transform_matrix(2,3);
28 |
29 | Eigen::Quaternionf q;
30 | q = transform_matrix.block<3,3>(0,0);
31 | odometry_.pose.pose.orientation.x = q.x();
32 | odometry_.pose.pose.orientation.y = q.y();
33 | odometry_.pose.pose.orientation.z = q.z();
34 | odometry_.pose.pose.orientation.w = q.w();
35 |
36 | publisher_.publish(odometry_);
37 | }
38 | }
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/src/publisher/tf_broadcaster.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: TF broadcaster
3 | * @Author: Ren Qian
4 | * @Date: 2020-03-05 15:23:26
5 | */
6 |
7 | #include "lidar_localization/publisher/tf_broadcaster.hpp"
8 |
9 | namespace lidar_localization {
10 |
11 | TFBroadCaster::TFBroadCaster(std::string frame_id, std::string child_frame_id) {
12 | transform_.frame_id_ = frame_id;
13 | transform_.child_frame_id_ = child_frame_id;
14 | }
15 |
16 | void TFBroadCaster::SendTransform(Eigen::Matrix4f pose, double time) {
17 | Eigen::Quaternionf q(pose.block<3,3>(0,0));
18 | ros::Time ros_time(time);
19 | transform_.stamp_ = ros_time;
20 | transform_.setRotation(tf::Quaternion(q.x(), q.y(), q.z(), q.w()));
21 | transform_.setOrigin(tf::Vector3(pose(0,3), pose(1,3), pose(2,3)));
22 | broadcaster_.sendTransform(transform_);
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/src/sensor_data/gnss_data.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description:
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-06 20:42:23
5 | */
6 | #include "lidar_localization/sensor_data/gnss_data.hpp"
7 |
8 | #include "glog/logging.h"
9 |
10 | //静态成员变量必须在类外初始化
11 | bool lidar_localization::GNSSData::origin_position_inited = false;
12 | GeographicLib::LocalCartesian lidar_localization::GNSSData::geo_converter;
13 |
14 | namespace lidar_localization {
15 | void GNSSData::InitOriginPosition() {
16 | geo_converter.Reset(latitude, longitude, altitude);
17 | origin_position_inited = true;
18 | }
19 |
20 | void GNSSData::UpdateXYZ() {
21 | if (!origin_position_inited) {
22 | LOG(WARNING) << "GeoConverter has not set origin position";
23 | }
24 | geo_converter.Forward(latitude, longitude, altitude, local_E, local_N, local_U);
25 | }
26 |
27 | bool GNSSData::SyncData(std::deque& UnsyncedData, std::deque& SyncedData, double sync_time) {
28 | // 传感器数据按时间序列排列,在传感器数据中为同步的时间点找到合适的时间位置
29 | // 即找到与同步时间相邻的左右两个数据
30 | // 需要注意的是,如果左右相邻数据有一个离同步时间差值比较大,则说明数据有丢失,时间离得太远不适合做差值
31 | while (UnsyncedData.size() >= 2) {
32 | if (UnsyncedData.front().time > sync_time)
33 | return false;
34 | if (UnsyncedData.at(1).time < sync_time) {
35 | UnsyncedData.pop_front();
36 | continue;
37 | }
38 | if (sync_time - UnsyncedData.front().time > 0.2) {
39 | UnsyncedData.pop_front();
40 | return false;
41 | }
42 | if (UnsyncedData.at(1).time - sync_time > 0.2) {
43 | return false;
44 | }
45 | break;
46 | }
47 | if (UnsyncedData.size() < 2)
48 | return false;
49 |
50 | GNSSData front_data = UnsyncedData.at(0);
51 | GNSSData back_data = UnsyncedData.at(1);
52 | GNSSData synced_data;
53 |
54 | double front_scale = (back_data.time - sync_time) / (back_data.time - front_data.time);
55 | double back_scale = (sync_time - front_data.time) / (back_data.time - front_data.time);
56 | synced_data.time = sync_time;
57 | synced_data.status = back_data.status;
58 | synced_data.longitude = front_data.longitude * front_scale + back_data.longitude * back_scale;
59 | synced_data.latitude = front_data.latitude * front_scale + back_data.latitude * back_scale;
60 | synced_data.altitude = front_data.altitude * front_scale + back_data.altitude * back_scale;
61 | synced_data.local_E = front_data.local_E * front_scale + back_data.local_E * back_scale;
62 | synced_data.local_N = front_data.local_N * front_scale + back_data.local_N * back_scale;
63 | synced_data.local_U = front_data.local_U * front_scale + back_data.local_U * back_scale;
64 |
65 | SyncedData.push_back(synced_data);
66 |
67 | return true;
68 | }
69 | }
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/src/sensor_data/imu_data.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: imu data
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-23 22:20:41
5 | */
6 | #include "lidar_localization/sensor_data/imu_data.hpp"
7 |
8 | #include
9 | #include "glog/logging.h"
10 |
11 | namespace lidar_localization {
12 | Eigen::Matrix3f IMUData::GetOrientationMatrix() {
13 | Eigen::Quaterniond q(orientation.w, orientation.x, orientation.y, orientation.z);
14 | Eigen::Matrix3f matrix = q.matrix().cast();
15 |
16 | return matrix;
17 | }
18 |
19 | bool IMUData::SyncData(std::deque& UnsyncedData, std::deque& SyncedData, double sync_time) {
20 | // 传感器数据按时间序列排列,在传感器数据中为同步的时间点找到合适的时间位置
21 | // 即找到与同步时间相邻的左右两个数据
22 | // 需要注意的是,如果左右相邻数据有一个离同步时间差值比较大,则说明数据有丢失,时间离得太远不适合做差值
23 | while (UnsyncedData.size() >= 2) {
24 | // UnsyncedData.front().time should be <= sync_time:
25 | if (UnsyncedData.front().time > sync_time)
26 | return false;
27 | // sync_time should be <= UnsyncedData.at(1).time:
28 | if (UnsyncedData.at(1).time < sync_time) {
29 | UnsyncedData.pop_front();
30 | continue;
31 | }
32 |
33 | // sync_time - UnsyncedData.front().time should be <= 0.2:
34 | if (sync_time - UnsyncedData.front().time > 0.2) {
35 | UnsyncedData.pop_front();
36 | return false;
37 | }
38 | // UnsyncedData.at(1).time - sync_time should be <= 0.2
39 | if (UnsyncedData.at(1).time - sync_time > 0.2) {
40 | return false;
41 | }
42 | break;
43 | }
44 | if (UnsyncedData.size() < 2)
45 | return false;
46 |
47 | IMUData front_data = UnsyncedData.at(0);
48 | IMUData back_data = UnsyncedData.at(1);
49 | IMUData synced_data;
50 |
51 | double front_scale = (back_data.time - sync_time) / (back_data.time - front_data.time);
52 | double back_scale = (sync_time - front_data.time) / (back_data.time - front_data.time);
53 | synced_data.time = sync_time;
54 | synced_data.linear_acceleration.x = front_data.linear_acceleration.x * front_scale + back_data.linear_acceleration.x * back_scale;
55 | synced_data.linear_acceleration.y = front_data.linear_acceleration.y * front_scale + back_data.linear_acceleration.y * back_scale;
56 | synced_data.linear_acceleration.z = front_data.linear_acceleration.z * front_scale + back_data.linear_acceleration.z * back_scale;
57 | synced_data.angular_velocity.x = front_data.angular_velocity.x * front_scale + back_data.angular_velocity.x * back_scale;
58 | synced_data.angular_velocity.y = front_data.angular_velocity.y * front_scale + back_data.angular_velocity.y * back_scale;
59 | synced_data.angular_velocity.z = front_data.angular_velocity.z * front_scale + back_data.angular_velocity.z * back_scale;
60 | // 四元数插值有线性插值和球面插值,球面插值更准确,但是两个四元数差别不大是,二者精度相当
61 | // 由于是对相邻两时刻姿态插值,姿态差比较小,所以可以用线性插值
62 | synced_data.orientation.x = front_data.orientation.x * front_scale + back_data.orientation.x * back_scale;
63 | synced_data.orientation.y = front_data.orientation.y * front_scale + back_data.orientation.y * back_scale;
64 | synced_data.orientation.z = front_data.orientation.z * front_scale + back_data.orientation.z * back_scale;
65 | synced_data.orientation.w = front_data.orientation.w * front_scale + back_data.orientation.w * back_scale;
66 | // 线性插值之后要归一化
67 | synced_data.orientation.Normlize();
68 |
69 | SyncedData.push_back(synced_data);
70 |
71 | return true;
72 | }
73 | }
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/src/subscriber/cloud_subscriber.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: 订阅激光点云信息,并解析数据
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-05 02:27:30
5 | */
6 |
7 | #include "lidar_localization/subscriber/cloud_subscriber.hpp"
8 |
9 | #include "glog/logging.h"
10 |
11 | namespace lidar_localization {
12 | CloudSubscriber::CloudSubscriber(ros::NodeHandle& nh, std::string topic_name, size_t buff_size)
13 | :nh_(nh) {
14 | subscriber_ = nh_.subscribe(topic_name, buff_size, &CloudSubscriber::msg_callback, this);
15 | }
16 |
17 | void CloudSubscriber::msg_callback(const sensor_msgs::PointCloud2::ConstPtr& cloud_msg_ptr) {
18 | CloudData cloud_data;
19 | cloud_data.time = cloud_msg_ptr->header.stamp.toSec();
20 | pcl::fromROSMsg(*cloud_msg_ptr, *(cloud_data.cloud_ptr));
21 |
22 | new_cloud_data_.push_back(cloud_data);
23 | }
24 |
25 | void CloudSubscriber::ParseData(std::deque& cloud_data_buff) {
26 | if (new_cloud_data_.size() > 0) {
27 | cloud_data_buff.insert(cloud_data_buff.end(), new_cloud_data_.begin(), new_cloud_data_.end());
28 | new_cloud_data_.clear();
29 | }
30 | }
31 | } // namespace data_input
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/src/subscriber/gnss_subscriber.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description:
3 | * @Author: Ren Qian
4 | * @Date: 2019-03-31 13:10:51
5 | */
6 | #include "lidar_localization/subscriber/gnss_subscriber.hpp"
7 |
8 | #include "glog/logging.h"
9 |
10 | namespace lidar_localization {
11 | GNSSSubscriber::GNSSSubscriber(ros::NodeHandle& nh, std::string topic_name, size_t buff_size)
12 | :nh_(nh) {
13 | subscriber_ = nh_.subscribe(topic_name, buff_size, &GNSSSubscriber::msg_callback, this);
14 | }
15 |
16 | void GNSSSubscriber::msg_callback(const sensor_msgs::NavSatFixConstPtr& nav_sat_fix_ptr) {
17 | GNSSData gnss_data;
18 | gnss_data.time = nav_sat_fix_ptr->header.stamp.toSec();
19 | gnss_data.latitude = nav_sat_fix_ptr->latitude;
20 | gnss_data.longitude = nav_sat_fix_ptr->longitude;
21 | gnss_data.altitude = nav_sat_fix_ptr->altitude;
22 | gnss_data.status = nav_sat_fix_ptr->status.status;
23 | gnss_data.service = nav_sat_fix_ptr->status.service;
24 |
25 | new_gnss_data_.push_back(gnss_data);
26 | }
27 |
28 | void GNSSSubscriber::ParseData(std::deque& gnss_data_buff) {
29 | if (new_gnss_data_.size() > 0) {
30 | gnss_data_buff.insert(gnss_data_buff.end(), new_gnss_data_.begin(), new_gnss_data_.end());
31 | new_gnss_data_.clear();
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/src/subscriber/imu_subscriber.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: 订阅imu数据
3 | * @Author: Ren Qian
4 | * @Date: 2019-06-14 16:44:18
5 | */
6 | #include "lidar_localization/subscriber/imu_subscriber.hpp"
7 |
8 | #include "glog/logging.h"
9 |
10 | namespace lidar_localization{
11 | IMUSubscriber::IMUSubscriber(ros::NodeHandle& nh, std::string topic_name, size_t buff_size)
12 | :nh_(nh) {
13 | subscriber_ = nh_.subscribe(topic_name, buff_size, &IMUSubscriber::msg_callback, this);
14 | }
15 |
16 | void IMUSubscriber::msg_callback(const sensor_msgs::ImuConstPtr& imu_msg_ptr) {
17 | IMUData imu_data;
18 | imu_data.time = imu_msg_ptr->header.stamp.toSec();
19 |
20 | imu_data.linear_acceleration.x = imu_msg_ptr->linear_acceleration.x;
21 | imu_data.linear_acceleration.y = imu_msg_ptr->linear_acceleration.y;
22 | imu_data.linear_acceleration.z = imu_msg_ptr->linear_acceleration.z;
23 |
24 | imu_data.angular_velocity.x = imu_msg_ptr->angular_velocity.x;
25 | imu_data.angular_velocity.y = imu_msg_ptr->angular_velocity.y;
26 | imu_data.angular_velocity.z = imu_msg_ptr->angular_velocity.z;
27 |
28 | imu_data.orientation.x = imu_msg_ptr->orientation.x;
29 | imu_data.orientation.y = imu_msg_ptr->orientation.y;
30 | imu_data.orientation.z = imu_msg_ptr->orientation.z;
31 | imu_data.orientation.w = imu_msg_ptr->orientation.w;
32 |
33 | new_imu_data_.push_back(imu_data);
34 | }
35 |
36 | void IMUSubscriber::ParseData(std::deque& imu_data_buff) {
37 | if (new_imu_data_.size() > 0) {
38 | imu_data_buff.insert(imu_data_buff.end(), new_imu_data_.begin(), new_imu_data_.end());
39 | new_imu_data_.clear();
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/workspace/assignments/01-introduction/src/lidar_localization/src/subscriber/tf_lisener.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: TF listener
3 | * @Author: Ren Qian
4 | * @Date: 2020-02-06 16:10:31
5 | */
6 |
7 | #include "lidar_localization/subscriber/tf_listener.hpp"
8 |
9 | #include
10 |
11 | namespace lidar_localization {
12 | TFListener::TFListener(ros::NodeHandle& nh, std::string base_frame_id, std::string child_frame_id)
13 | :nh_(nh), base_frame_id_(base_frame_id), child_frame_id_(child_frame_id) {
14 | }
15 |
16 | bool TFListener::LookupData(Eigen::Matrix4f& transform_matrix) {
17 | try {
18 | tf::StampedTransform transform;
19 | listener_.lookupTransform(base_frame_id_, child_frame_id_, ros::Time(0), transform);
20 | TransformToMatrix(transform, transform_matrix);
21 | return true;
22 | } catch (tf::TransformException &ex) {
23 | return false;
24 | }
25 | }
26 |
27 | bool TFListener::TransformToMatrix(const tf::StampedTransform& transform, Eigen::Matrix4f& transform_matrix) {
28 | Eigen::Translation3f tl_btol(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ());
29 |
30 | double roll, pitch, yaw;
31 | tf::Matrix3x3(transform.getRotation()).getEulerYPR(yaw, pitch, roll);
32 | Eigen::AngleAxisf rot_x_btol(roll, Eigen::Vector3f::UnitX());
33 | Eigen::AngleAxisf rot_y_btol(pitch, Eigen::Vector3f::UnitY());
34 | Eigen::AngleAxisf rot_z_btol(yaw, Eigen::Vector3f::UnitZ());
35 |
36 | // 此矩阵为 child_frame_id 到 base_frame_id 的转换矩阵
37 | transform_matrix = (tl_btol * rot_z_btol * rot_y_btol * rot_x_btol).matrix();
38 |
39 | return true;
40 | }
41 | }
--------------------------------------------------------------------------------
/workspace/assignments/README.md:
--------------------------------------------------------------------------------
1 | # 编程作业
2 |
3 | 章节作业开发环境
4 |
5 | ---
--------------------------------------------------------------------------------
/workspace/data/kitti/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 | !README.md
--------------------------------------------------------------------------------
/workspace/data/kitti/README.md:
--------------------------------------------------------------------------------
1 | # KITTI Dataset
2 |
3 | KITTI ROS Bags存放路径
4 |
5 | ---
6 |
7 | ## 获取数据
8 |
9 | 初次使用时, 请点击下述链接, 将课程配套数据下载至**当前路径**, 即:
10 |
11 | * 相对于Repo根目录的workspace/data/kitti
12 |
13 | 这样, 数据便可在Docker环境的/workspace/data下直接访问.
14 |
15 | 可供选择的网盘链接如下:
16 |
17 | * [腾讯云下载地址](https://share.weiyun.com/GxqcTaE2)
18 |
19 | * 百度云下载地址
20 |
21 | * **下载链接** https://pan.baidu.com/s/1gpO2Ssa12GoQTbYAseSFNA
22 | * **提取码** cau9
23 |
--------------------------------------------------------------------------------