Lidar-Lidar calibration#
概述#
在本教程中,我们将通过 TIER IV 的 基于测绘的 LiDAR-LiDAR 校准工具 解释 LiDAR -LiDAR 校准 校准工具.
警告
请从 手动校准 部分获取初始校准结果. 这对于从此工具获得准确的结果至关重要. 我们将使用计算出的初始校准参数 在本教程的上一步中. 要在校准工具中应用这些初始值, 请在单个参数包中更新您的传感器校准文件.
我们需要一个用于 lidar-lidar 校准过程的 sample bag 文件 其中包括原始 LiDAR 主题. 此外,我们建议使用异常值筛选 用于映射的点云,因为此点云 包括裁剪的车辆点云.因此 地图中不包含车辆点.当您开始时 袋子记录, 在前 5 秒内,您不应移动车辆以获得更好的地图绘制性能. 下面显示了用于此校准的 bag 文件示例:
??? note 我们的 tutorial_vehicle 校准过程的 ROS 2 Bag 示例
```sh
Files: rosbag2_2023_09_05-11_23_50_0.db3
Bag size: 3.8 GiB
Storage id: sqlite3
Duration: 112.702s
Start: Sep 5 2023 11:23:51.105 (1693902231.105)
End: Sep 5 2023 11:25:43.808 (1693902343.808)
Messages: 2256
Topic information: Topic: /sensing/lidar/front/pointcloud_raw | Type: sensor_msgs/msg/PointCloud2 | Count: 1128 | Serialization Format: cdr
Topic: /sensing/lidar/top/pointcloud | Type: sensor_msgs/msg/PointCloud2 | Count: 1128 | Serialization Format: cdr
```
基于地图的激光雷达-激光雷达校准#
创建启动文件#
我们首先创建我们的车辆的启动文件 4,例如 Extrinsic Manual Calibration
过程:
cd <YOUR-OWN-AUTOWARE-DIRECTORY>/src/autoware/calibration_tools/sensor
cd extrinsic_calibration_manager/launch
cd <YOUR-OWN-SENSOR-KIT-NAME> # i.e. for our guide, it will ve cd tutorial_vehicle_sensor_kit which is created in manual calibration
touch mapping_based.launch.xml mapping_based_sensor_kit.launch.xml
我们将使用 TIER IV 的样品传感器套件aip_x1修改这些 mapping_based.launch.xml 和 mapping_based_sensor_kit.launch.xml .
所以
您应该将这两个文件的内容从 aip_x1 复制到您创建的文件中.
然后,我们将继续将 vehicle_id 和 sensor model 名称添加到 mapping_based.launch.xml:
(或者,值不重要.这些参数将被 launch 参数覆盖)
<arg name="vehicle_id" default="default"/>
<let name="sensor_model" value="aip_x1"/>
+ <?xml version="1.0" encoding="UTF-8"?>
+ <launch>
- <arg name="vehicle_id" default="default"/>
+ <arg name="vehicle_id" default="<YOUR_VEHICLE_ID>"/>
+
- <arg name="sensor_model" default="aip_x1"/>
+ <let name="sensor_model" value="<YOUR_SENSOR_KIT_NAME>"/>
tutorial_vehicle 的文件 (mapping_based.launch.xml) 的最终版本应如下所示:
??? 备注 教程战车的样本 mapping_based.launch.xml 文件
```xml
<?xml version="1.0" encoding="UTF-8"?>
<launch>
<arg name="vehicle_id" default="tutorial_vehicle"/>
<let name="sensor_model" value="tutorial_vehicle_sensor_kit"/>
<arg name="rviz" default="true"/>
<group>
<push-ros-namespace namespace="sensor_kit"/>
<include file="$(find-pkg-share extrinsic_calibration_manager)/launch/$(var sensor_model)/mapping_based_sensor_kit.launch.xml">
<arg name="vehicle_id" value="$(var vehicle_id)"/>
<arg name="rviz" value="$(var rviz)"/>
</include>
</group>
</launch>
```
完成 mapping_based.launch.xml 文件后,
我们将准备好为自己的传感器模型实现 mapping_based_sensor_kit.launch.xml.
可选,您可以在此 XML 代码段上将 sensor_kit 和 vehicle_id 修改为 mapping_based.launch.xml:
(您可以将 rviz 配置保存为 video 后更改 rviz_profile 路径包含在页面末尾)
我们将为每个激光雷达添加传感器套件框架(测绘激光雷达除外), 我们有一个 LiDAR 用于与 Tutorial Vehicle 的主 LiDAR 传感器配对,因此它应该是这样的:
注意:测绘激光雷达将用于测绘目的,但不会进行校准. 我们可以将这个激光雷达视为我们硬件架构的主要传感器. 因此,其他激光雷达将相对于测绘激光雷达(主传感器)进行校准.
+ <let name="lidar_calibration_sensor_kit_frames" value="[
+ sensor_kit_base_link,
+ sensor_kit_base_link,
+ sensor_kit_base_link
+ ...]"/>
如果你之前保存了 rviz 配置文件用于 lidar-lidar 校准过程:
- <let name="rviz_profile" value="$(find-pkg-share extrinsic_mapping_based_calibrator)/rviz/x1.rviz"/>
+ <let name="rviz_profile" value="$(find-pkg-share extrinsic_mapping_based_calibrator)/rviz/<YOUR-RVIZ-CONFIG>.rviz"/>
??? 注意 i.e., If you have one main lidar for mapping, three lidar for calibration
```xml
+ <let name="lidar_calibration_sensor_kit_frames" value="[
+ sensor_kit_base_link,
+ sensor_kit_base_link,
+ sensor_kit_base_link]"/>
```
??? 注意 即,对于 tutorial_vehicle(一个激光雷达主用于测绘,一个激光雷达用于校准)
```xml
+ <let name="lidar_calibration_sensor_kit_frames" value="[sensor_kit_base_link]"/>
```
我们将添加 lidar_calibration_service_names, 校准器的 calibration_lidar_base_frames 和 calibration_lidar_frames:
- <let
- name="lidar_calibration_service_names"
- value="[
- /sensor_kit/sensor_kit_base_link/livox_front_left_base_link,
- /sensor_kit/sensor_kit_base_link/livox_front_center_base_link,
- /sensor_kit/sensor_kit_base_link/livox_front_right_base_link]"
- />
- <let name="calibration_lidar_base_frames" value="[
- livox_front_left_base_link,
- livox_front_center_base_link,
- livox_front_right_base_link]"/>
- <let name="calibration_lidar_frames" value="[
- livox_front_left,
- livox_front_center,
- livox_front_right]"/>
+ <let
+ name="lidar_calibration_service_names"
+ value="[/sensor_kit/sensor_kit_base_link/<YOUR_SENSOR_BASE_LINK>,
+ /sensor_kit/sensor_kit_base_link/<YOUR_SENSOR_BASE_LINK
+ ...]"
+ />
+
+ <let name="calibration_lidar_base_frames" value="[YOUR_SENSOR_BASE_LINK,
+ YOUR_SENSOR_BASE_LINK
+ ...]"/>
+ <let name="calibration_lidar_frames" value="[YOUR_SENSOR_LINK,
+ YOUR_SENSOR_LINK
+ ...]"/>
??? 注意 即,在 tutorial_vehicle 它应该像这个片段一样
```xml
+ <let
+ name="lidar_calibration_service_names"
+ value="[/sensor_kit/sensor_kit_base_link/rs_bpearl_front_base_link]"
+ />
+ <let name="calibration_lidar_base_frames" value="[rs_bpearl_front_base_link]"/>
+ <let name="calibration_lidar_frames" value="[rs_bpearl_front]"/>
```
之后,我们将添加传感器主题和传感器帧,以便执行此作, 我们将继续用 mapping_based_sensor_kit.launch.xml 填充 (我们建议使用 /sensing/lidar/top/pointcloud 主题作为映射点云因为车辆云在此主题中被 PointCloud 预处理裁剪):
- <let name="mapping_lidar_frame" value="velodyne_top"/>
- <let name="mapping_pointcloud" value="/sensing/lidar/top/pointcloud"/>
+ <let name="mapping_lidar_frame" value="<MAPPING_LIDAR_SENSOR_LINK>"/>
+ <let name="mapping_pointcloud" value="<MAPPING_LIDAR_POINTCLOUD_TOPIC_NAME>"/>
- <let name="calibration_pointcloud_topics" value="[
- /sensing/lidar/front_left/livox/lidar,
- /sensing/lidar/front_center/livox/lidar,
- /sensing/lidar/front_right/livox/lidar]"/>
+ <let name="calibration_pointcloud_topics" value="[
+ <YOUR_LIDAR_TOPIC_FOR_CALIBRATION>,
+ <YOUR_LIDAR_TOPIC_FOR_CALIBRATION>,
+ ...]"/>
??? 注意 在 tutorial_vehicle 它应该像这个片段一样.
```xml
<let name="calibration_lidar_base_frames" value="[rs_bpearl_front_base_link]"/>
<let name="calibration_lidar_frames" value="[rs_bpearl_front]"/>
<let name="mapping_lidar_frame" value="rs_helios_top"/>
<let name="mapping_pointcloud" value="/sensing/lidar/top/pointcloud_raw"/>
<let name="detected_objects" value="/perception/object_recognition/detection/objects"/>
<let name="calibration_pointcloud_topics" value="[
/sensing/lidar/right/pointcloud_raw]"/>
```
tutorial_vehicle 的 mapping_based_sensor_kit.launch.xml 启动文件应为:
??? 注意 i.e. mapping_based_sensor_kit.launch.xml 表示 tutorial_vehicle
```xml
<?xml version="1.0" encoding="UTF-8"?>
<launch>
<arg name="vehicle_id" default="tutorial_vehicle"/>
<let name="sensor_model" value="tutorial_vehicle_sensor_kit"/>
<arg name="rviz"/>
<let name="rviz_profile" value="$(find-pkg-share extrinsic_mapping_based_calibrator)/rviz/x1.rviz"/>
<arg name="src_yaml" default="$(find-pkg-share individual_params)/config/$(var vehicle_id)/$(var sensor_model)/sensor_kit_calibration.yaml"/>
<arg name="dst_yaml" default="$(env HOME)/sensor_kit_calibration.yaml"/>
<let name="camera_calibration_service_names" value="[``]"/>
<let name="camera_calibration_sensor_kit_frames" value="[``]"/>
<let name="calibration_camera_frames" value="[``]"/>
<let name="calibration_camera_optical_link_frames" value="[``]"/>
<let name="calibration_camera_info_topics" value="[``]"/>
<let name="calibration_image_topics" value="[``]"/>
<let name="lidar_calibration_sensor_kit_frames" value="[sensor_kit_base_link]"/>
<let
name="lidar_calibration_service_names"
value="[/sensor_kit/sensor_kit_base_link/rs_bpearl_front_base_link]"
/>
<let name="calibration_lidar_base_frames" value="[rs_bpearl_front_base_link]"/>
<let name="calibration_lidar_frames" value="[rs_bpearl_front]"/>
<let name="mapping_lidar_frame" value="rs_helios_top"/>
<let name="mapping_pointcloud" value="/sensing/lidar/top/pointcloud_raw"/>
<let name="detected_objects" value="/perception/object_recognition/detection/objects"/>
<let name="calibration_pointcloud_topics" value="[
/sensing/lidar/right/pointcloud_raw]"/>
<group>
<!-- extrinsic_calibration_client -->
<node pkg="extrinsic_calibration_client" exec="extrinsic_calibration_client" name="extrinsic_calibration_client" output="screen">
<param name="src_path" value="$(var src_yaml)"/>
<param name="dst_path" value="$(var dst_yaml)"/>
</node>
<!-- extrinsic_calibration_manager -->
<node pkg="extrinsic_calibration_manager" exec="extrinsic_calibration_manager" name="extrinsic_calibration_manager" output="screen">
<param name="parent_frame" value="sensor_kit_base_link"/>
<param name="child_frames" value="[rs_bpearl_front_base_link]"/>
</node>
</group>
<!-- mapping based calibrator -->
<include file="$(find-pkg-share extrinsic_mapping_based_calibrator)/launch/calibrator.launch.xml">
<arg name="ns" value=""/>
<arg name="camera_calibration_service_names" value="$(var camera_calibration_service_names)"/>
<arg name="lidar_calibration_service_names" value="$(var lidar_calibration_service_names)"/>
<arg name="camera_calibration_sensor_kit_frames" value="$(var camera_calibration_sensor_kit_frames)"/>
<arg name="lidar_calibration_sensor_kit_frames" value="$(var lidar_calibration_sensor_kit_frames)"/>
<arg name="calibration_camera_frames" value="$(var calibration_camera_frames)"/>
<arg name="calibration_camera_optical_link_frames" value="$(var calibration_camera_optical_link_frames)"/>
<arg name="calibration_lidar_base_frames" value="$(var calibration_lidar_base_frames)"/>
<arg name="calibration_lidar_frames" value="$(var calibration_lidar_frames)"/>
<arg name="mapping_lidar_frame" value="$(var mapping_lidar_frame)"/>
<arg name="mapping_pointcloud" value="$(var mapping_pointcloud)"/>
<arg name="detected_objects" value="$(var detected_objects)"/>
<arg name="calibration_camera_info_topics" value="$(var calibration_camera_info_topics)"/>
<arg name="calibration_image_topics" value="$(var calibration_image_topics)"/>
<arg name="calibration_pointcloud_topics" value="$(var calibration_pointcloud_topics)"/>
<arg name="mapping_max_range" value="150.0"/>
<arg name="local_map_num_keyframes" value="30"/>
<arg name="dense_pointcloud_num_keyframes" value="20"/>
<arg name="ndt_resolution" value="0.5"/>
<arg name="ndt_max_iterations" value="100"/>
<arg name="ndt_epsilon" value="0.005"/>
<arg name="lost_frame_max_acceleration" value="15.0"/>
<arg name="lidar_calibration_max_frames" value="10"/>
<arg name="calibration_eval_max_corr_distance" value="0.2"/>
<arg name="solver_iterations" value="100"/>
<arg name="calibration_skip_keyframes" value="15"/>
</include>
<node pkg="rviz2" exec="rviz2" name="rviz2" output="screen" args="-d $(var rviz_profile)" if="$(var rviz)"/>
</launch>
```
使用基于交互式映射的校准器进行激光雷达-激光雷达校准过程#
完成 mapping_based.launch.xml 后, mapping_based_sensor_kit.launch.xml 自己的传感器套件的启动文件; 现在我们准备好校准我们的激光雷达了. 首先,我们需要构建 extrinsic_calibration_manager 包:
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release --packages-select extrinsic_calibration_manager
因此,我们已准备好启动和使用基于地图的激光雷达-激光雷达校准器:
ros2 launch extrinsic_calibration_manager calibration.launch.xml mode:=mapping_based sensor_model:=<OWN-SENSOR-KIT> vehicle_model:=<OWN-VEHICLE-MODEL> vehicle_id:=<VEHICLE-ID>
对于教程车辆:
ros2 launch extrinsic_calibration_manager calibration.launch.xml mode:=mapping_based sensor_model:=tutorial_vehicle_sensor_kit vehicle_model:=tutorial_vehicle vehicle_id:=tutorial_vehicle
您将显示具有多个配置的 rviz2 屏幕,
你需要要使用您的传感器信息主题(如视频)对其进行更新,
其中包括文件的结尾. 此外,您还可以将 rviz2 配置保存在 rviz 目录下.
因此,您可以稍后使用它来修改 mapping_based_sensor_kit.launch.xml .
extrinsic_ground_plane_calibrator/
└─ rviz/
+ └─ tutorial_vehicle_sensor_kit.rviz
然后播放 ROS 2 bag 文件:
ros2 bag play <rosbag_path> --clock -r 0.2 \
--remap /tf:=/null/tf /tf_static:=/null/tf_static # if tf is recorded
校准步骤包括两个阶段:映射和校准. 在袋子开始播放,然后开始映射以及下面的 rviz2 屏幕截图.

因此,红色箭头标记表示映射过程中的姿势, 绿色箭头标记是统一采取的特殊姿势, 白点表示构建的地图.
映射在达到预定义的数据阈值时停止 或者可以通过调用此服务来过早地结束:
ros2 service call /NAMESPACE/stop_mapping std_srvs/srv/Empty {}
校准的映射阶段完成后,校准过程将开始. 校准完成后,您应该如下图所示 rviz2 屏幕:

红点表示 上一节的绿点表示对齐点(校准结果).校准结果将自动保存在您的 dst_yaml ($HOME/sensor_kit_calibration.yaml) 在本教程中.
以下是在 tutorial_vehicle 上演示基于测绘的激光雷达-激光雷达校准过程的视频: