2.2.4 雷达融合应用

本节我们将通过两个案例来演示ira_laser_tools功能包的基本使用。

1.准备工作

首先请创建一个功能包,指令如下:

ros2 pkg create mycar_laser_merger --dependencies ira_laser_tools

在功能包下新建launch与params目录,并修改功能包下的CMakeLists.txt文件,添加如下代码:

install(DIRECTORY params launch DESTINATION share/${PROJECT_NAME})

准备工作完毕,接下来就可以进入案例部分了。

2.雷达融合

(1)需求

机器人在纵向上安装有上下两个激光雷达,两个激光雷达分别安装在底盘中心(base_link)正上方0.05m和0.35m处,请融合激光雷达数据,并在rviz2中查看结果。

上雷达采集的数据

下雷达采集的数据

融合后数据

(2)实现

①.准备工作:请先按照1.3.2 USB端口绑定的相关内容为两个雷达端口映射别名,比如可以分别为laser_up和laser_down。

②.进入launch目录,新建两个launch文件,分别名为mycar_two_laser.launch.py和mycar_two_laser_merger.launch.py。

在mycar_two_laser.launch.py文件中输入如下内容:

import os
from launch_ros.actions import Node
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from ament_index_python.packages import get_package_share_directory



def generate_launch_description():



    laser_down_baselink_tf = Node(
        package="tf2_ros",
        executable="static_transform_publisher",
        arguments=["--z", "0.05", "--frame-id","base_link","--child-frame-id","laser_down"]
    )
    laser_up_baselink_tf = Node(
        package="tf2_ros",
        executable="static_transform_publisher",
        arguments=["--z", "0.35", "--frame-id","base_link","--child-frame-id","laser_up"]
    )
    # 启动两个激光雷达
    laser_up = Node(
        package='sllidar_ros2',
        executable='sllidar_node',
        name='sllidar_node_up',
        parameters=[{'serial_port': "/dev/laser_up", 
                        'serial_baudrate': 115200, 
                        'frame_id': "laser_up",
                        'angle_compensate': True,
                        'inverted': False,
                        }],
        remappings=[("/scan","/scan_up")],
        output='screen')
    laser_down = Node(
        package='sllidar_ros2',
        executable='sllidar_node',
        name='sllidar_node_down',
        parameters=[{'serial_port': "/dev/laser_down", 
                        'serial_baudrate': 115200, 
                        'frame_id': "laser_down",
                        'angle_compensate': True,
                        'inverted': False,
                        }],
        remappings=[("/scan","/scan_down")],
        output='screen')
    # 进行雷达融合
    merger_launch = IncludeLaunchDescription(
        launch_description_source= PythonLaunchDescriptionSource(
            launch_file_path=os.path.join(
                get_package_share_directory("mycar_laser_merger"),
                "launch",
                "mycar_two_laser_merger.launch.py"
            )
        )
    )

    return LaunchDescription([laser_down_baselink_tf,laser_up_baselink_tf,laser_up,laser_down,merger_launch])

在上述文件中,主要做了如下操作:

  • 发布了两个雷达相对于base_link的静态坐标变换;
  • 启动了两个雷达(此处可根据自己实际使用的雷达自行修改);
  • 包含了雷达融合的launch文件。

在mycar_two_laser_merger.launch.py文件中输入如下内容:

from launch_ros.actions import Node
from launch import LaunchDescription
from ament_index_python.packages import get_package_share_directory
import launch_ros.actions
import os

# 融合两个激光雷达
def generate_launch_description():

    return LaunchDescription([

        Node(
            package='ira_laser_tools',
            executable='laserscan_multi_merger',
            name='laserscan_multi_merger',
            parameters=[os.path.join(get_package_share_directory("mycar_laser_merger"), "params", "laserscan_multi_merger.yaml")],
            output='screen'),
    ])

上述文件主要用于实现雷达数据融合,它启动了ira_laser_tools功能包下的laserscan_multi_merger节点,并且加载了一个yaml文件用于配置参数。

在功能包的params目录下,新建名为laserscan_multi_merger.yaml的文件(也即mycar_two_laser_merger.launch.py中加载的yaml文件),并输入如下内容:

/laserscan_multi_merger:
  ros__parameters:
    angle_increment: 0.0058
    angle_max: 3.14
    angle_min: -3.14
    cloud_destination_topic: /merged_cloud
    destination_frame: base_link
    laserscan_topics: /scan_up /scan_down
    range_max: 25.0
    range_min: 0.0
    scan_destination_topic: /scan_multi
    scan_time: 0.0
    use_sim_time: false

上述文件主要配置了雷达融合所需要的一些参数。

③.构建功能包,执行launch文件mycar_two_laser.launch.py并启动rviz2。

rviz2启动之后,将Fixed Frame设置为base_link,并添加三个LaserScan插件,三个插件订阅的话题分别设置为/scan_up/scan_downscan_multi即可分别显示上雷达采集的数据、下雷达采集的数据和上下雷达融合后的数据,不过,需要注意的是为了保证订阅scan_multi的插件数据可以正常显示,需要将该插件的topic下的Reliability Policy设置为System DefaultBest Effort

3.融合后再过滤

(1)需求

继雷达融合之后,可以对雷达数据继续优化,过滤掉采集到的车身以及附属物数据。

过滤后的数据

(2)实现

①.在launch目录下新建实现雷达过滤的文件:mycar_two_laser_filter.launch.py,并在mycar_two_laser.launch.py中包含新建的launch文件。

修改mycar_two_laser.launch.py,修改后的内容如下:

import os
from launch_ros.actions import Node
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from ament_index_python.packages import get_package_share_directory



def generate_launch_description():



    laser_down_baselink_tf = Node(
        package="tf2_ros",
        executable="static_transform_publisher",
        arguments=["--z", "0.05", "--frame-id","base_link","--child-frame-id","laser_down"]
    )
    laser_up_baselink_tf = Node(
        package="tf2_ros",
        executable="static_transform_publisher",
        arguments=["--z", "0.35", "--frame-id","base_link","--child-frame-id","laser_up"]
    )
    # 启动两个激光雷达
    laser_up = Node(
        package='sllidar_ros2',
        executable='sllidar_node',
        name='sllidar_node_up',
        parameters=[{'serial_port': "/dev/laser_up", 
                        'serial_baudrate': 115200, 
                        'frame_id': "laser_up",
                        'angle_compensate': True,
                        'inverted': False,
                        }],
        remappings=[("/scan","/scan_up")],
        output='screen')
    laser_down = Node(
        package='sllidar_ros2',
        executable='sllidar_node',
        name='sllidar_node_down',
        parameters=[{'serial_port': "/dev/laser_down", 
                        'serial_baudrate': 115200, 
                        'frame_id': "laser_down",
                        'angle_compensate': True,
                        'inverted': False,
                        }],
        remappings=[("/scan","/scan_down")],
        output='screen')
    # 进行雷达融合
    merger_launch = IncludeLaunchDescription(
        launch_description_source= PythonLaunchDescriptionSource(
            launch_file_path=os.path.join(
                get_package_share_directory("mycar_laser_merger"),
                "launch",
                "mycar_two_laser_merger.launch.py"
            )
        )
    )
    # 过滤
    filter_launch = IncludeLaunchDescription(
        launch_description_source= PythonLaunchDescriptionSource(
            launch_file_path=os.path.join(
                get_package_share_directory("mycar_laser_merger"),
                "launch",
                "mycar_two_laser_filter.launch.py"
            )
        )
    )
    return LaunchDescription([laser_down_baselink_tf,laser_up_baselink_tf,laser_up,laser_down,merger_launch,filter_launch])

在mycar_two_laser_filter.launch.py文件中输入如下内容:

from launch import LaunchDescription
from launch.substitutions import PathJoinSubstitution
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory

# 过滤融合后的数据。
def generate_launch_description():
    # 去除一个立方体内扫描到的数据。
    return LaunchDescription([
        Node(
            package="laser_filters",
            executable="scan_to_scan_filter_chain",
            parameters=[
                PathJoinSubstitution([
                    get_package_share_directory("mycar_laser_merger"),
                    "params", "box_filter.yaml",
                ])],
            remappings=[("/scan","/scan_multi"),("/scan_filtered","/scan")],
        )
    ])

上述过滤器实现与2.2.2 雷达过滤器应用中的案例实现类似,唯一的区别是重映射了雷达的输入话题和输出话题。

在功能包的params目录下,新建名为box_filter.yaml的文件(也即mycar_two_laser_filter.launch.py中加载的yaml文件),并输入如下内容:

scan_to_scan_filter_chain:
  ros__parameters:
    filter1:
      name: box_filter
      type: laser_filters/LaserScanBoxFilter
      params:
        box_frame: base_link #参考坐标系
        max_x: 0.20
        max_y: 0.15
        max_z: 0.5
        min_x: -0.20
        min_y: -0.15
        min_z: -0.1

        invert: false # 是否反转,如果设置为 true,那么会只保留立方体内的数据。

②.构建功能包,执行launch文件mycar_two_laser.launch.py并启动rviz2。

rviz2启动之后,将Fixed Frame设置为base_link,并添加LaserScan插件,设置订阅的话题为/scan,即可显示过滤后的数据。

results matching ""

    No results matching ""