├── .gitignore
├── README.md
├── image
├── s1.png
├── s2.png
├── s3.png
├── s4.png
├── s5.png
└── s6.png
├── install.sh
├── run.sh
├── src
├── CMakeLists.txt
└── rviz_cloud_annotation
│ ├── CMakeLists.txt
│ ├── icons
│ └── classes
│ │ └── ic_launcher.png
│ ├── launch
│ └── annotation.launch
│ ├── msg
│ ├── RectangleSelectionViewport.msg
│ └── UndoRedoState.msg
│ ├── package.xml
│ ├── pc_utils
│ ├── CMakeLists.txt
│ ├── include
│ │ └── pc_utils
│ │ │ ├── bound
│ │ │ ├── OBB.h
│ │ │ └── box_extract.h
│ │ │ ├── common
│ │ │ ├── common.h
│ │ │ ├── detail
│ │ │ │ ├── factory.h
│ │ │ │ └── type_util.h
│ │ │ ├── lidar_device.h
│ │ │ ├── parameter.h
│ │ │ ├── point_type.h
│ │ │ └── utils.h
│ │ │ ├── filter
│ │ │ └── cloud_filter.h
│ │ │ └── seg
│ │ │ ├── cluster.h
│ │ │ └── ground_estimator.h
│ └── lib
│ │ └── libpc_utils.so
│ ├── pcl_include
│ ├── colors.cpp
│ └── pcl
│ │ └── common
│ │ └── colors.h
│ ├── rviz
│ └── annotation.rviz
│ ├── rviz_plugin
│ └── cloud_annotation.xml
│ └── src
│ ├── point_cloud_plane_curves_extract.cpp
│ ├── point_cloud_plane_curves_extract.h
│ ├── point_cloud_plane_params.cpp
│ ├── point_cloud_plane_params.h
│ ├── point_neighborhood.cpp
│ ├── point_neighborhood.h
│ ├── point_neighborhood_search.cpp
│ ├── point_neighborhood_search.h
│ ├── rviz_cloud_annotation.cpp
│ ├── rviz_cloud_annotation.h
│ ├── rviz_cloud_annotation_class.cpp
│ ├── rviz_cloud_annotation_class.h
│ ├── rviz_cloud_annotation_params.h
│ ├── rviz_cloud_annotation_plugin.cpp
│ ├── rviz_cloud_annotation_plugin.h
│ ├── rviz_cloud_annotation_point_plane.cpp
│ ├── rviz_cloud_annotation_point_plane.h
│ ├── rviz_cloud_annotation_points.cpp
│ ├── rviz_cloud_annotation_points.h
│ ├── rviz_cloud_annotation_points_io.cpp
│ ├── rviz_cloud_annotation_undo.cpp
│ ├── rviz_cloud_annotation_undo.h
│ ├── rviz_select_tool.cpp
│ └── rviz_select_tool.h
├── tools
├── clear_annotation.sh
├── install_annotation.sh
├── launch_annotation.sh
├── pcd_play
├── raw2pcd
├── ros_debug.sh
└── uninstall_annotation.sh
├── uninstall.sh
└── 示例pcd文件
└── pcd
├── 16line.pcd
└── 64line.pcd
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode/
2 | .ros/
3 | .catkin*
4 | .idea/
5 | devel/
6 | build/
7 | **/cmake-build-debug
8 | cmake-build-debug/
9 |
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | PCAT点云标注工具-使用手册
2 | ---------------------
3 |
4 | - Demo项目,请自行魔改
5 |
6 | - This is the open source version:
7 |
8 | `Author: WenwenDu`
9 | `TEL: 18355180339`
10 | `E-mail: 1455112695@qq.com`
11 |
12 | - Video tutorial:
13 | 1. `https://v.youku.com/v_show/id_XNDYxNjY4MDExMg==.html?spm=a2h0k.11417342.soresults.dtitle`
14 |
15 | 2. `https://v.youku.com/v_show/id_XNDYxNjY4MDI5Mg==.html?spm=a2hzp.8244740.0.0`
16 |
17 | ## **I. 配置使用环境及安装**
18 |
19 | - `配置要求:ubuntu16.04 + ROS Kinetic full`
20 | - `注意:请务必保证系统使用原生python2.7,在使用Anaconda2的情况下,请在~/.bashrc环境变量中临时关闭Anaconda2,避免冲突。(如果你长期使用ROS,强烈建议在虚拟环境下使用anaconda,避免冲突。)`
21 |
22 | ### 1. 安装ROS-Kinetic
23 | 参考[ROS WiKi-安装说明](http://http://wiki.ros.org/kinetic/Installation/Ubuntu), 安装步骤如下:
24 | ```
25 | 添加ROS源:
26 | sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
27 | 添加ROS源秘钥:
28 | sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
29 | 更新源
30 | sudo apt-get update
31 | ```
32 | ```
33 | 安装ROS完整版:(由于使用Rviz,PCL等模块,请务必安装完整版)
34 | sudo apt-get install ros-kinetic-desktop-full
35 | sudo apt-cache search ros-kinetic
36 | 初始化ROS:
37 | sudo rosdep init
38 | rosdep update
39 | ```
40 |
41 | ```
42 | 添加环境变量
43 | echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
44 | source ~/.bashrc
45 | 更新ROS环境变量
46 | source /opt/ros/kinetic/setup.bash
47 | ```
48 |
49 | ```
50 | 测试ROS是否成功安装:
51 | 开启一个新的Teminnal,输入:
52 | roscore
53 | 测试Rviz
54 | 开启一个新的Teminnal,输入:
55 | rviz
56 | ```
57 | 成功显示rviz界面如下:
58 | 
59 |
60 | ### 2. 安装PCAT标注工具
61 | ```
62 | (1) 进入文件夹PCAT
63 | (2) 开启终端,运行安装命令: sh install.sh
64 | (3) 显示 install successful 后,home文件夹下出现lidar_annotation文件夹,安装成功
65 | ```
66 | -------------------------
67 | ## **II. 导入pcd文件**
68 | 1. **导入待标注点云pcd文件**
69 | ```
70 | Copy 待标注的点云.pcd格式文件到 lidar_annotation/pcd/ 文件夹下
71 |
72 | 注意:标注工具默认支持激光雷达pcd格式点云,Field为[x,y,z,intensity],如果使用XYZRGB等其他pcd format,请在src/rviz_cloud_annotation/launch/annotation.launch中更改pcd_type参数的value.
73 |
74 | 常见issue
75 |
76 | [1] 如何支持其他类型pcd或其他3Dpoints? 修改以下code...
77 | // src/rviz_cloud_annotation/src/rviz_cloud_annotation_class.cpp
78 | void RVizCloudAnnotation::LoadCloud(const std::string &filename,
79 | const std::string &normal_source,
80 | PointXYZRGBNormalCloud &cloud);
81 |
82 | ```
83 |
84 | 2. **开始标注**
85 | ```
86 | 打开 Teminnal, 运行: sh run.sh
87 | ```
88 | 显示标注界面如下:
89 | 
90 |
91 | -------------------------------
92 | ## **III. 标注手册正篇**
93 | `首次使用请务必仔细阅读`
94 | ### 1. 标注面板详解
95 | **下面就上图中 A, B, C, D, E 5个模块做详细说明:**
96 | - [ ] **A. 标注菜单栏**
97 |
98 | ```
99 | 标注菜单栏由 [文件], [编辑],[视图],[标记],[选择] 5部分组成
100 | 文件:(1)切换新文件,(2)清除当前帧标记,(3)保存
101 | 编辑:(1)取消,(2)恢复
102 | 视图:(1)增加点的尺寸,(2)减小点的尺寸,(3)重置点的尺寸
103 | 标记:(1)清除当前物体的标记,(2)切换颜色,(3)设置障碍物BBox遮挡系数,(4)调节障碍物BBox方位,(5)调节障碍物BBox尺寸
104 | 选择:(1)跳转至下一物体,(2)跳转至上一物体
105 | ```
106 | ```
107 | 特别说明:
108 | 1.切换新文件会自动保存当前文件的标注信息
109 | 2.取消/恢复开销较大,尽量避免使用
110 | 3.标记完成一个物体后,需要切换到下一个物体进行标注,否则会覆盖当前标记;选择新的颜色会自动切换到下一物体;物体ID显示在面板上
111 | 4.标记障碍物时,颜色 1~5,6~10,11~15,16~20 分别对应标签: 小车,大车,行人,骑行;
112 | 5.标记障碍物时,需要设置方位角和遮挡系数,请以实际为准标注,0--不遮挡,1--完全遮挡
113 | 尽量使用简洁的方式完成标注,熟练使用快捷键可以有效提高标注速度。
114 | ```
115 | 
116 | 特别说明
117 | 1.点云被重复标记为 障碍物,路沿,车道线,地面时,标签优先级为 (障碍物 > 路沿/车道线 > 地面)
118 |
119 | ### 2.标注步骤
120 | `在看标注说明之前请务必观看视频教程`
121 | - [ ] 标注请按照: 【障碍物--> 路沿-->车道线-->地面】 的顺序。
122 |
123 | ```
124 | (1) 障碍物
125 | 障碍物包括 小车(轿车),大车(卡车、有轨电车等),行人,骑行(电动车)4类。
126 | 在该数据集中主要包含 小车和行人,及少量的大车和骑行。请在标注`颜色面板`选择不同的按钮,对应不同的障碍物。
127 | 颜色面板分为4大块,颜色 1~5,6~10,11~15,16~20 分别对应: 小车,大车,行人,骑行,代表不同的障碍物。
128 | 对每一帧的点云,障碍物存在则标注,不存在则不标注;每标注完一个障碍物,需要==切换至下一个障碍物进行新的标注。
129 | (比如:标完第一辆小车,需要按`Shitf+N` 切换至下一小车,或者按`Shift+P`切换至上一障碍物进行修改)。
130 | 选择新的颜色会自动切换至新的下一障碍物。
131 | 每个障碍物,需要标注人员自己判断大致的朝向,并进行方位调节(R、F键)。
132 | 受到遮挡的障碍物请设置`遮挡系数`,默认为 0,即不遮挡,大多数障碍物不存在遮挡。
133 | ```
134 | 
135 |
136 | ```
137 | (2) 路沿
138 | 路沿指道路中地面的边界,如上图显示;标记路沿只能使用点选的方式标注(具体操作可以参考标注视频教程)
139 | 一般一帧点云中有多条路沿,每标记一条,需要切换至下一路沿进行标注,切换方式与障碍物切换相同。
140 | (3) 车道线
141 | 车道线指道路中颜色明显突出的线段,一般出现的频率比较低,没有出现或者看不清楚则不用标注;车道线的标注方式与路沿完全相同。
142 | (4) 地面
143 | 地面是一帧点云中比较关键的部分,一般选择使用多边形进行选择标注,边界为之前标注的路沿。
144 | 地面可以分多次标注,拼接生成;如果一次选点过多,地面生成时间会较长。
145 | *在2.4.0版本之后,标注工具增加了地面辅助标记功能:用户每次选择`地面(F2)`按钮时,系统会自动生成95%的地面,用户在此基础上进行细节修改,
146 | 得到最终的地面标注。
147 | ```
148 |
149 | ### 3.标注结果
150 | #### Result路径说明
151 | 
152 | #### 3D框label
153 | 
154 |
155 | ------------------------
156 |
157 | **IV、注意事项**
158 | -----------------------
159 | 1. 标注工具使用过程中如果遇见问题,或者代码部分有疑问,编辑需要,联系 @杜文文(18355180339 / 1455112695@qq.com)
160 | 2. 视频教程:
161 | A`https://v.youku.com/v_show/id_XNDYxNjY4MDExMg==.html?spm=a2h0k.11417342.soresults.dtitle`
162 | B`https://v.youku.com/v_show/id_XNDYxNjY4MDI5Mg==.html?spm=a2hzp.8244740.0.0`
163 |
164 | -----------------------
165 |
166 | **V、版权说明**
167 | -----------------------
168 | 1. **软件版权**
169 | 本标注工具的版权归WenwenDu所有
170 | 2. **其他版权**
171 | 本标注工具在 RIMLab 开源标注工具 rviz_cloud_annotation 上改进完成:
172 | `https://github.com/RMonica/rviz_cloud_annotation`
173 |
174 | ```
175 | 原始版权说明:
176 | Original Copyright:
177 | /*
178 | * Copyright (c) 2016-2017, Riccardo Monica
179 | * RIMLab, Department of Engineering and Architecture
180 | * University of Parma, Italy
181 | * http://www.rimlab.ce.unipr.it/
182 | *
183 | * Redistribution and use in source and binary forms, with or without
184 | * modification, are permitted provided that the following conditions are met:
185 | *
186 | * 1. Redistributions of source code must retain the above copyright notice,
187 | * this list of conditions and the following disclaimer.
188 | *
189 | * 2. Redistributions in binary form must reproduce the above copyright notice,
190 | * this list of conditions and the following disclaimer in the documentation
191 | * and/or other materials provided with the distribution.
192 | *
193 | * 3. Neither the name of the copyright holder nor the names of its
194 | * contributors may be used to endorse or promote products derived from this
195 | * software without specific prior written permission.
196 | *
197 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
198 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
199 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
200 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
201 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
202 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
203 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
204 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
205 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
206 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
207 | * POSSIBILITY OF SUCH DAMAGE.
208 | */
209 | ```
210 |
211 |
--------------------------------------------------------------------------------
/image/s1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halostorm/PCAT_open_source/fdc9272f0a14c59469435b9444906b51e849a2ab/image/s1.png
--------------------------------------------------------------------------------
/image/s2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halostorm/PCAT_open_source/fdc9272f0a14c59469435b9444906b51e849a2ab/image/s2.png
--------------------------------------------------------------------------------
/image/s3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halostorm/PCAT_open_source/fdc9272f0a14c59469435b9444906b51e849a2ab/image/s3.png
--------------------------------------------------------------------------------
/image/s4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halostorm/PCAT_open_source/fdc9272f0a14c59469435b9444906b51e849a2ab/image/s4.png
--------------------------------------------------------------------------------
/image/s5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halostorm/PCAT_open_source/fdc9272f0a14c59469435b9444906b51e849a2ab/image/s5.png
--------------------------------------------------------------------------------
/image/s6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halostorm/PCAT_open_source/fdc9272f0a14c59469435b9444906b51e849a2ab/image/s6.png
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | mkdir $HOME/lidar_annotation/
2 |
3 | cd tools/
4 |
5 | bash install_annotation.sh
6 |
7 | echo "install successful!"
8 |
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | cd tools/
2 |
3 | bash launch_annotation.sh
4 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | /opt/ros/melodic/share/catkin/cmake/toplevel.cmake
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.11)
2 | project(rviz_cloud_annotation)
3 |
4 | find_package(catkin REQUIRED COMPONENTS
5 | cv_bridge
6 | interactive_markers
7 | pcl_conversions
8 | roscpp
9 | tf
10 | visualization_msgs
11 | geometry_msgs
12 | eigen_conversions
13 | cmake_modules
14 | std_msgs
15 | rviz
16 | )
17 | find_package(OpenCV)
18 | find_package(Eigen3 REQUIRED)
19 | find_package(Boost REQUIRED)
20 | find_package(PCL )
21 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pc_utils)
22 | message(WARNING "PCL 1.8 found")
23 |
24 | set(MAYBE_PCL_COMMON_COLORS "")
25 | if (NOT ${PCL_FOUND})
26 | message(WARNING "PCL 1.8 not found, attempting 1.7...")
27 | find_package(PCL 1.7 REQUIRED)
28 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/pcl_include)
29 | set(MAYBE_PCL_COMMON_COLORS "${CMAKE_CURRENT_SOURCE_DIR}/pcl_include/colors.cpp")
30 | endif()
31 |
32 | find_package(Qt5Widgets REQUIRED)
33 | set(CMAKE_CXX_STANDARD 17) # C++11...
34 | set(CMAKE_AUTOMOC ON)
35 | add_definitions(-DQT_NO_KEYWORDS)
36 |
37 | add_definitions(${PCL_DEFINITIONS})
38 | link_directories(${PCL_LIBRARY_DIRS})
39 |
40 | ################################################
41 | ## Declare ROS messages, services and actions ##
42 | ################################################
43 |
44 | add_message_files(
45 | FILES
46 | UndoRedoState.msg
47 | RectangleSelectionViewport.msg
48 | )
49 |
50 | generate_messages(
51 | DEPENDENCIES
52 | std_msgs
53 | geometry_msgs
54 | )
55 |
56 | ###################################
57 | ## catkin specific configuration ##
58 | ###################################
59 |
60 | include_directories(
61 | ${catkin_INCLUDE_DIRS}
62 | ${PCL_INCLUDE_DIRS}
63 | ${Boost_INCLUDE_DIRS}
64 | ${Eigen3_INCLUDE_DIRS}
65 | ${OpenCV_INCLUDE_DIRS}
66 | ${PC_UTILS_INCLUDE_DIRS}
67 | )
68 | message(WARNING " ${PC_UTILS_INCLUDE_DIRS}")
69 | add_executable(rviz_cloud_annotation_node
70 | src/rviz_cloud_annotation.cpp
71 | ${MAYBE_PCL_COMMON_COLORS}
72 | )
73 |
74 | add_dependencies(rviz_cloud_annotation_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
75 |
76 | target_link_libraries(
77 | rviz_cloud_annotation_node
78 | rviz_cloud_annotation_com
79 | ${PCL_LIBRARIES}
80 | ${Boost_LIBRARIES}
81 | ${Eigen3_LIBRARIES}
82 | ${catkin_LIBRARIES}
83 | ${PC_UTILS_LIBRARIES}
84 | )
85 |
86 |
87 | set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
88 |
89 | add_library(rviz_cloud_annotation_plugin
90 | src/rviz_cloud_annotation_plugin.cpp
91 | src/rviz_select_tool.cpp
92 | ${MAYBE_PCL_COMMON_COLORS}
93 | )
94 |
95 | add_dependencies(rviz_cloud_annotation_plugin ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
96 |
97 | target_link_libraries(rviz_cloud_annotation_plugin
98 | ${PCL_LIBRARIES}
99 | ${Boost_LIBRARIES}
100 | ${Eigen3_LIBRARIES}
101 | ${catkin_LIBRARIES}
102 | ${OpenCV_LIBRARIES}
103 | Qt5::Widgets
104 | )
105 |
106 |
107 | add_library(rviz_cloud_annotation_com
108 | src/rviz_cloud_annotation_points.cpp
109 | src/rviz_cloud_annotation_points_io.cpp
110 | src/rviz_cloud_annotation_point_plane.cpp
111 | src/rviz_cloud_annotation_class.cpp
112 | src/rviz_cloud_annotation_undo.cpp
113 | src/point_neighborhood.cpp
114 | src/point_neighborhood_search.cpp
115 | src/point_cloud_plane_curves_extract.cpp
116 | src/point_cloud_plane_params.cpp
117 | ${MAYBE_PCL_COMMON_COLORS}
118 | )
119 |
120 |
121 | add_dependencies(rviz_cloud_annotation_com ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
122 |
123 | target_link_libraries(rviz_cloud_annotation_com
124 | ${PCL_LIBRARIES}
125 | ${Boost_LIBRARIES}
126 | ${Eigen3_LIBRARIES}
127 | ${catkin_LIBRARIES}
128 | ${OpenCV_LIBRARIES}
129 | Qt5::Widgets
130 | )
131 |
132 |
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/icons/classes/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halostorm/PCAT_open_source/fdc9272f0a14c59469435b9444906b51e849a2ab/src/rviz_cloud_annotation/icons/classes/ic_launcher.png
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/launch/annotation.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/msg/RectangleSelectionViewport.msg:
--------------------------------------------------------------------------------
1 | uint32 start_x
2 | uint32 start_y
3 | uint32 end_x
4 | uint32 end_y
5 |
6 | uint32 viewport_height
7 | uint32 viewport_width
8 |
9 | float32 focal_length
10 |
11 | float32[16] projection_matrix
12 | geometry_msgs/Pose camera_pose
13 |
14 | bool is_deep_selection
15 |
16 | int32[] polyline_x
17 | int32[] polyline_y
18 |
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/msg/UndoRedoState.msg:
--------------------------------------------------------------------------------
1 | bool redo_enabled
2 | string redo_description
3 |
4 | bool undo_enabled
5 | string undo_description
6 |
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | rviz_cloud_annotation
4 | 3.1.0
5 | The rviz_cloud_annotation package
6 |
7 | wenwendu
8 | wenwendu
9 |
10 | catkin
11 | interactive_markers
12 | rviz
13 | pcl_conversions
14 | roscpp
15 | tf
16 | visualization_msgs
17 | cmake_modules
18 | std_msgs
19 | geometry_msgs
20 | eigen_conversions
21 | opencv2
22 | opencv2
23 |
24 | interactive_markers
25 | pcl_conversions
26 | roscpp
27 | tf
28 | visualization_msgs
29 | rviz
30 | std_msgs
31 | geometry_msgs
32 | eigen_conversions
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/pc_utils/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(PC_UTILS_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE)
2 | set(PC_UTILS_LIBRARIES ${CMAKE_CURRENT_SOURCE_DIR}/lib/libpc_utils.so yaml-cpp PARENT_SCOPE)
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/pc_utils/include/pc_utils/bound/OBB.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by ou on 2021/12/7.
3 | //
4 |
5 | #ifndef PC_UTILS_BOUNDING_OBB_H
6 | #define PC_UTILS_BOUNDING_OBB_H
7 | #include
8 | namespace pc_utils{
9 |
10 | class BoundingBox {
11 | public:
12 | Eigen::Isometry3f pose{Eigen::Isometry3f::Identity()};
13 | Eigen::Vector3f dxyz{1, 1, 1};
14 |
15 | static void Corner3d(const BoundingBox &_box, Eigen::Vector3f (&_corner3d)[8]) {
16 | /**
17 | ** Box Corner 下/上
18 | ** 2/3 __________ 6/7
19 | ** | y |
20 | ** | | |
21 | ** | o - x |
22 | ** | |
23 | ** |__________|
24 | ** 0/1 4/5
25 | **********************************************/
26 | static Eigen::Array3f corner3d_unit[8] = {{-1, -1, -1},
27 | {-1, -1, 1},
28 | {-1, 1, -1},
29 | {-1, 1, 1},
30 | {1, -1, -1},
31 | {1, -1, 1},
32 | {1, 1, -1},
33 | {1, 1, 1}};
34 |
35 | for (int i = 0; i < 8; i++) {
36 | _corner3d[i] = _box.pose * (0.5f * corner3d_unit[i] * _box.dxyz.array());
37 | }
38 | }
39 |
40 |
41 | static void LineList(const BoundingBox &_box, Eigen::Vector3f (&_lines)[24]) {
42 | static int table[] = {0, 1, 1, 3, 3, 2, 2, 0, 4, 5, 5, 7, 7, 6, 6, 4, 0, 4, 1, 5, 2, 6, 3, 7};
43 | Eigen::Vector3f corners[8];
44 | Corner3d(_box, corners);
45 | for (int i = 0; i < 24; i++) {
46 | _lines[i][0] = corners[table[i]][0];
47 | _lines[i][1] = corners[table[i]][1];
48 | _lines[i][2] = corners[table[i]][2];
49 | }
50 | }
51 | };
52 | }
53 |
54 | #endif //PC_UTILS_BOUNDING_OBB_H
55 |
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/pc_utils/include/pc_utils/bound/box_extract.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by nrsl on 2021/10/11.
3 | //
4 |
5 | #ifndef PERCEPTION3D_BOX_EXTRACT_H
6 | #define PERCEPTION3D_BOX_EXTRACT_H
7 |
8 | #include "pc_utils/bound/OBB.h"
9 | #include "pc_utils/common/common.h"
10 |
11 |
12 | /**
13 | * @brief support type of box extractor
14 | * @typedef OrientedBBoxExtractor
15 | * @typedef OrientedBBox2p5DExtractor
16 | * @typedef AxiallyAlignedBBoxExtractor
17 | */
18 | #define PC_UTILS_BBOX_TYPE \
19 | define( AxiallyAlignedBBoxExtractor ) \
20 | define( OrientedBBox3DExtractor ) \
21 | define( OrientedBBox2p5DExtractor )
22 |
23 | namespace pc_utils {
24 |
25 | template
26 | class BoundingExtractor {
27 | public:
28 | virtual void extract(const typename PC::Ptr &input, BoundingBox &output) = 0;
29 | };
30 |
31 | } // namespace pc_utils
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | PC_UTILS_LINK_HELPER_HEADER(BoundingExtractor)
44 | #endif //PERCEPTION3D_BOX_EXTRACT_H
45 |
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/pc_utils/include/pc_utils/common/common.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by ou on 2021/11/17.
3 | //
4 |
5 | #ifndef SRC_COMMON_H
6 | #define SRC_COMMON_H
7 |
8 | #include "utils.h"
9 |
10 | namespace pc_utils {
11 | double inline to_rad(double degree) { return degree / 180 * M_PI; }
12 |
13 | Eigen::Isometry3f inline fromXYZRPY(const Eigen::Vector3f &xyz, const Eigen::Vector3f &rpy) {
14 | Eigen::Isometry3f ret = Eigen::Isometry3f::Identity();
15 | Eigen::AngleAxisf
16 | r(rpy.x(), Eigen::Vector3f::UnitX()),
17 | p(rpy.y(), Eigen::Vector3f::UnitY()),
18 | y(rpy.z(), Eigen::Vector3f::UnitZ());
19 | ret.translate(xyz);
20 | ret.rotate(Eigen::Quaternionf{y * p * r});
21 | return ret;
22 | }
23 |
24 | Eigen::Isometry3f inline fromXYZRPY(float x, float y, float z, float r, float p, float yaw) {
25 | return fromXYZRPY(Eigen::Vector3f(x, y, z), Eigen::Vector3f(r, p, yaw));
26 | }
27 | }
28 |
29 |
30 |
31 |
32 | PC_UTILS_LINK_HELPER_HEADER(common)
33 | #endif //SRC_COMMON_H
34 |
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/pc_utils/include/pc_utils/common/detail/factory.h:
--------------------------------------------------------------------------------
1 | #ifndef FACTORY_H
2 | #define FACTORY_H
3 |
4 | #include "type_util.h"
5 | #include
6 | #include
7 | //#define BASE_UTILS_VERBOSE
8 | /***
9 | * @brief Factory class definition
10 | * @example
11 | * struct Base{}
12 | * struct Der{ Der(int){}}
13 | * static bool register_1 = Factory::Register();
14 | */
15 | template
16 | struct Factory {
17 | private:
18 | template
19 | static auto *BuildImpl(const std::string &name, T &&...t) {
20 | if (GetTable().find(name) == GetTable().end()) {
21 | fprintf(stderr, "build fail: %s no exist in %s.\n", name.c_str(),
22 | Type>::c_str());
23 | return (Base *) nullptr;
24 | } else {
25 | return GetTable()[name](std::forward(t)...);
26 | }
27 | }
28 |
29 | static inline auto &GetTable() {
30 | static std::unordered_map table;
31 | return table;
32 | }
33 |
34 | template
35 | struct raw_ptr;
36 | public:
37 |
38 | template
39 | static bool Register() {
40 | constexpr bool validation = std::is_default_constructible_v || std::is_constructible_v;
41 | static_assert(validation, "no Der(Args...) constructor function exist\n");
42 | if constexpr (validation) {
43 | static_assert(std::is_base_of_v, "no derivative relationship between this two types.\n");
44 | std::string hash_code;
45 | if constexpr (has_member_name_v)
46 | hash_code = std::string(Der::name());
47 | else
48 | hash_code = std::string(Type::name);
49 |
50 | if (GetTable().find(hash_code) == GetTable().end()) {
51 | #ifdef BASE_UTILS_VERBOSE
52 | printf("register [√]: %s -> %s\n",
53 | Type::c_str(),
54 | Type>::c_str());
55 | #endif
56 | GetTable()[hash_code] = [](Args ...args) -> Base * { return new Der(args...); };
57 | } else {
58 | fprintf(stderr, "register [x]: %s -> %s\n",
59 | Type::c_str(),
60 | Type>::c_str());
61 | }
62 | return true;
63 | } else
64 | return false;
65 | }
66 |
67 | template class PtrType=raw_ptr, class ...T>
68 | static auto Build(const std::string &name, T &&...t) {
69 | if constexpr (std::is_same_v, raw_ptr>) return BuildImpl(name, std::forward(t)...);
70 | else return PtrType(BuildImpl(name, std::forward(t)...));
71 | }
72 |
73 | template class PtrType=std::shared_ptr, class ...T>
74 | static auto BuildT(const std::string &name, T &&...t) {
75 | return Build(TTypeTrait::with_template_arg(name), std::forward(t)...);
76 | }
77 | };
78 |
79 | /***
80 | * @brief auto register (support construction overload)
81 | * @example
82 | * struct Base{}
83 | * struct Der: AutoRegister::template OverLoad<>,
84 | * AutoRegister::template OverLoad{
85 | * Der(){}
86 | * Der(int){}
87 | * }
88 | */
89 | template
90 | struct AutoRegister {
91 | template
92 | struct OverLoad {
93 | OverLoad() { (void) registered; /*必不可少,显式调用才会生成代码*/}
94 |
95 | static bool registered;
96 | };
97 |
98 | struct Default {
99 | Default() {
100 | (void) registered;
101 | Factory::template Register(); /*必不可少,显式调用才会生成代码*/}
102 |
103 | static bool registered;
104 | };
105 | };
106 | template
107 | template
108 | bool AutoRegister::OverLoad::registered = Factory::template Register();
109 |
110 | template
111 | bool AutoRegister::Default::registered = Factory::template Register();
112 |
113 |
114 |
115 | /***
116 | * @brief for manually register
117 | * @example
118 | * struct Base{}
119 | * struct Der{
120 | * Der(){}
121 | * Der(int){}
122 | * }
123 | * REGISTER_TO_FACTORY(Base,Der)
124 | * REGISTER_TO_FACTORY(Base,Der, int)
125 | */
126 |
127 |
128 | #define REGISTER_TO_FACTORY(der, ...) \
129 | namespace{static bool REGISTER_TO_FACTORY_UNIQUE_ID(register_der) = Factory<__VA_ARGS__>::Register();}
130 |
131 | /***
132 | * @brief define namespace decoration
133 | */
134 | namespace pc_utils { REGISTER_DEF_NAMESPACE_DECORATE}
135 |
136 |
137 | #endif
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/pc_utils/include/pc_utils/common/detail/type_util.h:
--------------------------------------------------------------------------------
1 | #ifndef FACTORY_TYPE_UTILS_H
2 | #define FACTORY_TYPE_UTILS_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | /**
9 | * @brief get type name from template arg
10 | * @example
11 | * Type::name -> constexpr std::string_view("int")
12 | * Type::str() -> std::string("int")
13 | * Type::c_str() -> std::string("int").c_str()
14 | */
15 | template
16 | struct Type {
17 | private:
18 | static constexpr auto type_name_impl() noexcept {
19 | std::string_view name, prefix, suffix;
20 | #ifdef __clang__
21 | name = __PRETTY_FUNCTION__;
22 | prefix = "static auto Type::type_name_impl() [T = ";
23 | suffix = "]";
24 | #elif defined(__GNUC__)
25 | name = __PRETTY_FUNCTION__;
26 | prefix = "static constexpr auto Type::type_name_impl() [with T = ";
27 | suffix = "]";
28 | #elif defined(_MSC_VER)
29 | name = __FUNCSIG__;
30 | prefix = "static auto __cdecl Type::type_name_impl<";
31 | suffix = ">(void) noexcept";
32 | #endif
33 | name.remove_prefix(prefix.size());
34 | name.remove_suffix(suffix.size());
35 | return name;
36 | }
37 |
38 | public:
39 | static constexpr auto name = type_name_impl();
40 |
41 | static std::string &str() {
42 | static std::string n(name);
43 | return n;
44 | }
45 |
46 | static auto *c_str() { return str().c_str(); }
47 | };
48 |
49 | /**
50 | * @brief get type name from template args
51 | * @example
52 | * Types::name<1> -> constexpr std::string_view("double")
53 | * Types::names -> constexpr std::string_view("")
54 | * Types::raw_names -> constexpr std::string_view("int, double")
55 | */
56 | template
57 | struct Types {
58 | private:
59 | static constexpr auto type_names_impl() noexcept {
60 | std::string_view name = Type>::name, prefix = "Types";
61 | name.remove_prefix(prefix.size());
62 | return name;
63 | }
64 |
65 | static constexpr auto raw_type_names_impl() noexcept {
66 | std::string_view name = type_names_impl(), prefix = "<", suffix = ">";
67 | name.remove_prefix(prefix.size());
68 | name.remove_suffix(suffix.size());
69 | return name;
70 | }
71 |
72 | public:
73 |
74 | static constexpr size_t size = sizeof...(T);
75 | template
76 | static constexpr auto name = Type >::type>::name;
77 |
78 | static constexpr auto names = type_names_impl();
79 | static constexpr auto raw_names = raw_type_names_impl();
80 | };
81 |
82 | /**
83 | * @brief decorate template class name with template arg
84 | * @example
85 | * DECORATE(TemplateClass,int,double) -> std::string("TemplateClass")
86 | * decorate(TemplateClass) -> std::string("TemplateClass")
87 | */
88 | #define DECORATE(name, ...) decorate<__VA_ARGS__>(name)
89 |
90 | template
91 | inline std::string decorate(const std::string &name) { return name + std::string(Types::names); }
92 |
93 | template<>
94 | inline std::string decorate(const std::string &name) { return name; }
95 |
96 | /**
97 | * @brief template class type trait
98 | * @example
99 | * TTypeTrait>::size -> size_t(2)
100 | * TTypeTrait>::arg_type<1> -> double
101 | * TTypeTrait>::with_template_arg(NewClass) -> std::string("NewClass")
102 | */
103 |
104 | template
105 | struct TTypeTrait {
106 | constexpr static size_t size = 0;
107 |
108 | static std::string with_template_arg(const std::string &name) { return name; }
109 | };
110 |
111 | template class TType, class ...T>
112 | struct TTypeTrait> {
113 | private:
114 | template
115 | static std::string
116 | with_template_arg_helper(const std::string &name, std::index_sequence) {
117 | return decorate...>(name);
118 | }
119 |
120 | public:
121 | constexpr static size_t size = sizeof ...(T);
122 | template
123 | using arg_type = typename std::tuple_element>::type;
124 |
125 | static std::string with_template_arg(const std::string &name) {
126 | return with_template_arg_helper(name, std::make_index_sequence());
127 | }
128 | };
129 |
130 | /***
131 | * @brief SFINAE to detect if CLASS have static function called "name"
132 | * @example
133 | * struct A {
134 | * static void name() {}
135 | * };
136 | * struct B {}
137 | *
138 | * has_member_name_v -> constexpr bool(true)
139 | * has_member_name_v -> constexpr bool(false)
140 | */
141 | #define PC_UTILS_HAS_MEMBER(XXX) \
142 | template\
143 | struct has_member_##XXX \
144 | { \
145 | private: \
146 | template static auto Check(int) -> decltype(std::declval().XXX(std::declval()...), std::true_type()); \
147 | template static std::false_type Check(...); \
148 | public: \
149 | static constexpr auto value = decltype(Check(0))::value; \
150 | };\
151 | template inline constexpr bool has_member_##XXX##_v{has_member_##XXX::value};
152 |
153 | PC_UTILS_HAS_MEMBER(name)
154 |
155 | /***
156 | * @brief get unique symbol
157 | * @example
158 | * REGISTER_TO_FACTORY_UNIQUE_ID(ABC) ABC1
159 | * REGISTER_TO_FACTORY_UNIQUE_ID(ABC) ABC2
160 | */
161 | #define REGISTER_TO_FACTORY_UNIQUE_ID_MERGE_IMPL(a, b) a ## b //合并用的主体
162 | #define REGISTER_TO_FACTORY_UNIQUE_ID_MERGE(a, b) REGISTER_TO_FACTORY_UNIQUE_ID_MERGE_IMPL(a, b) //中间层
163 | #define REGISTER_TO_FACTORY_UNIQUE_ID(name) REGISTER_TO_FACTORY_UNIQUE_ID_MERGE(name, __COUNTER__)
164 |
165 | #define REGISTER_REMOVE_PARENTHESES_IMPL(X) X
166 | #define REGISTER_REMOVE_PARENTHESES(X) REGISTER_REMOVE_PARENTHESES_IMPL X
167 |
168 | /***
169 | * @brief define namespace addition
170 | */
171 |
172 | #define REGISTER_DEF_NAMESPACE_DECORATE inline std::string ns(const std::string &name) { \
173 | struct Ns { \
174 | static constexpr auto name_space() noexcept { \
175 | auto name = Type::name, \
176 | suffix = std::string_view("ns(const string&)::Ns"); \
177 | name.remove_suffix(suffix.size()); \
178 | return name; \
179 | } \
180 | }; \
181 | return std::string(Ns::name_space()) + name; \
182 | }
183 |
184 | #endif
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/pc_utils/include/pc_utils/common/lidar_device.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by nrsl on 2021/10/11.
3 | //
4 |
5 | #ifndef PERCEPTION3D_LIDAR_H
6 | #define PERCEPTION3D_LIDAR_H
7 |
8 | #include "pc_utils/common/common.h"
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | namespace pc_utils {
16 | struct LidarDevice {
17 | int index;
18 | std::string name;
19 | std::string type;
20 | std::string frame_id;
21 | std::string ros_topic;
22 | std::string relative_to;
23 | Eigen::Isometry3f pose;
24 | bool enable;
25 | bool fuse_relative;
26 | bool fuse_global;
27 |
28 | static void from_yaml(const YAML::Node &config, std::vector &devices) {
29 | /***
30 | * 读取雷达配置
31 | */
32 | for (int i = 0; i < config.size(); i++) {
33 | auto device = config[i];
34 | auto lidar = device["device"];
35 | auto init = lidar["calibration"]["init_pose"].as>();
36 |
37 | devices.push_back({
38 | .index=i,
39 | .name=lidar["name"].as(),
40 | .type=lidar["type"].as(),
41 | .frame_id=lidar["frame_id"].as(),
42 | .ros_topic=lidar["ros_topic"].as(),
43 | .relative_to=lidar["calibration"]["relative_to"].as(),
44 | .pose=fromXYZRPY(init[0], init[1], init[2], init[3], init[4], init[5]),
45 | .enable=lidar["calibration"]["enable"].as(),
46 | .fuse_relative=lidar["calibration"]["fuse_relative"].as(),
47 | .fuse_global=lidar["fuse_global"].as()
48 | });
49 | }
50 | }
51 |
52 | static void from_yaml(const std::string &config_file, std::vector &devices) {
53 | if (not boost::filesystem::exists(config_file)) {
54 | throw std::runtime_error(config_file + std::string("no exist"));
55 | } else {
56 | auto config = YAML::LoadFile(config_file)["lidar"];
57 | from_yaml(config, devices);
58 | }
59 | }
60 | };
61 |
62 | }
63 |
64 | #endif //PERCEPTION3D_LIDAR_H
65 |
--------------------------------------------------------------------------------
/src/rviz_cloud_annotation/pc_utils/include/pc_utils/common/parameter.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by ou on 2021/12/2.
3 | //
4 |
5 | #ifndef PC_UTILS_PARAMETER_H
6 | #define PC_UTILS_PARAMETER_H
7 |
8 | #include
9 | #include