思岚激光雷达rplidar从ROS 1到ROS 2的移植

系列文章目录

ROS 2下navigation 2 stack的构建
订阅rviz2的导航目标位置消息“/goal_pose”
为Navigation 2创建自定义behavior tree plugin
打断behavior tree的异步动作节点,并执行其他节点动作


前言

由于需要将ROS 1下项目升级到ROS 2,用到了思岚的激光雷达,但目前似乎思岚官方还没有在ROS 2上的package,因此做了一个移植。移植过程参考了ROS 2官方的说明,尽最大可能按照ROS 2新架构的规范做移植,希望本文能对同样在ROS 2上做开发的同仁起到帮助


创建rplida_ros的package

在终端输入命令:
cd ~/dev_ws/src
进入workspace的src目录,继续在终端输入命令:
ros2 pkg create --build-type ament_cmake rplidar_ros2 --dependencies rclcpp sensor_msgs std_srvs
package创建后打开其“package.xml”,参照ROS中rplidar的package.xml文件修改必要的信息,比如版本号,能够帮助查看是否需要后续的更新,如下图:
在这里插入图片描述

1. 拷贝思岚rplidar的sdk以及rivz包

拷贝到新建package rplidar_ros2的根目录下,如下图:
在这里插入图片描述
进入sdk目录,复制“node.cpp”为“node_ros2.cpp”作为ROS 2下的源码文件,同时保留了ROS下的“node.cpp”作为备份,如下图:
在这里插入图片描述

2. 为CMakeLists添加rplidar sdk和node的目标编译文件,以及ROS 2 run命令在寻找node时的路径

打开package的“CMakeLists.txt”,在“find_package”前添加如下语句:

set(RPLIDAR_SDK_PATH "./sdk/")

FILE(GLOB RPLIDAR_SDK_SRC 
  "${RPLIDAR_SDK_PATH}/src/arch/linux/*.cpp"
  "${RPLIDAR_SDK_PATH}/src/hal/*.cpp"
  "${RPLIDAR_SDK_PATH}/src/*.cpp"
)

即指定rplidar sdk路径的变量“RPLIDAR_SDK_PATH”,同时将rplidar sdk所需要的文件glob到变量“RPLIDAR_SDK_SRC”,便于后续添加目标。关于cmake的glob的说明参考官网链接:
https://cmake.org/cmake/help/v3.0/command/file.html

在“find_package”后添加如下语句:

add_executable(rplidarNode src/node_ros2.cpp ${RPLIDAR_SDK_SRC})
ament_target_dependencies(rplidarNode rclcpp sensor_msgs std_srvs)

install(TARGETS
  rplidarNode
  DESTINATION lib/${PROJECT_NAME})

即为“rplidarNode”添加编译目标文件“node_ros2.cpp”、sdk文件、以及ROS 2 run命令查找node时的路径,如下图:
在这里插入图片描述

3. 检查依赖问题

在终端输入命令:
rosdep install -i --from-path src --rosdistro foxy -y
如果依赖都已正确设置或安装,则如下图提示:
在这里插入图片描述
否则,在终端运行命令:
rosdep update
更新并安装必要的依赖

4. 尝试编译,以解决CMakeLists问题

在终端输入命令:
colcon build --packages-select rplidar_ros2
编译首先提示找不到“ros/ros.h”,如下图:
在这里插入图片描述
因为在ROS 2架构下变为了“rclcpp/rclcpp.hpp“,同理,后面的两个#include,即“sensor_msgs/LaserScan.h”和“std_srvs/Empty.h”,也分别变为了“<sensor_msgs/msg/laser_scan.hpp>”和“<std_srvs/srv/empty.hpp>”,也都需要替换,如下图:
在这里插入图片描述
在这里插入图片描述
在终端再次输入编译命令:
colcon build --packages-select rplidar_ros2
此时编译提示找不到“rplidar.h”,如下图:
在这里插入图片描述
该文件属于rplidar的头文件,在sdk/include目录下,这个问题表明CMakeLists缺少了include directories的声明,需要添加。打开package的“CMakeLists.txt”,在“install”后添加如下语句:

target_include_directories(rplidarNode
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/sdk/include>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/sdk/src>
    $<INSTALL_INTERFACE:include>)

即加入rplidar sdk的include和src两个路径,如下图:
在这里插入图片描述
NOTE:关于ROS 2的ament_cmake说明可以参看官网链接:
https://index.ros.org/doc/ros2/Tutorials/Ament-CMake-Documentation/

TIP:编译使用的命令指定了目标package即–packages-select ,当package较多时,该方式可以节省很多时间。也可以直接使用命令colcon build编译workspace中的所有package

适应ROS 2架构的代码移植

ROS 2相比ROS在构建架构上做出了很大的变化,即引入了DDS(Data Distribution Service)来优化ROS中通信,关于DDS的引入的考虑可以参考官网链接:
https://design.ros2.org/articles/ros_on_dds.html

由于DDS的引入,代码由ROS到ROS 2最大的变化在于node的引用方式上,本文对rplidar代码的移植参考了ROS 2说明中的三个示例,Writing a simple publisher and subscriber (C++)、Writing a simple service and client (C++)、Using parameters in a class (C++),它们的官网链接分别为:
https://index.ros.org/doc/ros2/Tutorials/Writing-A-Simple-Cpp-Publisher-And-Subscriber/
https://index.ros.org/doc/ros2/Tutorials/Writing-A-Simple-Cpp-Service-And-Client/
https://index.ros.org/doc/ros2/Tutorials/Using-Parameters-In-A-Class-CPP/

移植需要从rclcpp::Node继承我们自己的node,本文中为“rplidarROS2”。这里重点介绍继承类rplidarROS2的构造函数,因为该函数的实现过程几乎涵盖了ROS到ROS 2整个代码移植的关键变化,以及由此带来node的main函数的变化

首先,看继承类rplidarROS2及其构造函数:

class rplidarROS2 : public rclcpp::Node
{
public:
	rplidarROS2()
		: Node("rplidar_ros2")
		, driver_(nullptr)
		, clock_(RCL_ROS_TIME)
		, angle_compensate_multiple_(1) // it stand of angle compensate at per 1 degree
		, frequency_(5.5)
		, channel_type_("serial")
		, tcp_ip_("192.168.0.7")
		, tcp_port_(20108)
		, serial_port_("/dev/ttyUSB0")
		, serial_baudrate_(115200/*256000*/) // ros run for A1 A2, change to 256000 if A3;
		, frame_id_("laser_frame")
		, inverted_(false)
		, angle_compensate_(false)
		, scan_mode_(std::string())
		, max_distance_(8.0)
		, screened_begin_(91)
		, screened_end_(179)
	{
		RCLCPP_INFO(get_logger(), "RPLIDAR running on ROS package rplidar_ros. SDK Version:"RPLIDAR_SDK_VERSION"");
		
		declare_parameters(); // !!!NOTE
		get_parameters();
		
		rclcpp::QoS qos(rclcpp::KeepLast(50));  // !!!NOTE
		scan_publisher_ = create_publisher<sensor_msgs::msg::LaserScan>("scan", qos);  // !!!NOTE
		start_motor_server_ = create_service<std_srvs::srv::Empty>("start_motor", std::bind(&rplidarROS2::start_motor, this, std::placeholders::_1, std::placeholders::_2));  // !!!NOTE
		stop_motor_server_ = create_service<std_srvs::srv::Empty>("stop_motor", std::bind(&rplidarROS2::stop_motor, this, std::placeholders::_1, std::placeholders::_2));
		
		timer_ = create_wall_timer(std::chrono::milliseconds(int(ceil(1000.0 / frequency_))), std::bind(&rplidarROS2::spin, this));  // !!!NOTE
		
		connect_driver();
		check_scan_mode();
	};
	
	// other codes but screened for space reason
}

该代码片段即为继承于rclcpp::Node的rplidarROS2类及其构造函数,其他部分未给出,将在后面的源代码中一并给出。本文出于尽最大可能保证所移植代码与rplidar在ROS下的代码一致或相似的目的,将rplidarROS2类作为inline的方式写入了同一个文件“node_ROS2.cpp”,其也可以写入独立的.h和.cpp文件

该代码片段中带有“ // !!!NOTE”注释的部分是需要着重关注的变化点:

1. declare_parameters()

该函数的源代码如下:

void declare_parameters()
{
	declare_parameter<double>("frequency", frequency_);
	declare_parameter<std::string>("channel_type", channel_type_);
	declare_parameter<std::string>("tcp_ip", tcp_ip_);
	declare_parameter<int>("tcp_port", tcp_port_);
	declare_parameter<std::string>("serial_port", serial_port_);
	declare_parameter<int>("serial_baudrate", serial_baudrate_);
	declare_parameter<std::string>("frame_id", frame_id_);
	declare_parameter<bool>("inverted", inverted_);
	declare_parameter<bool>("angle_compensate", angle_compensate_);
	declare_parameter<std::string>("scan_mode", scan_mode_);
	declare_parameter<double>("max_distance", max_distance_);
	declare_parameter<int>("screened_begin", screened_begin_);
	declare_parameter<int>("screened_end", screened_end_);
}

ROS 2从版本Dashing,就要求在客户端读取或者设置参数时首先需要声明参数,该变化的好处是客户端代码能够通过自身对参数的声明以此判断ParameterDescriptor中定义的参数是否合法。因为在ROS 2中已经没有global parameter的概念,所有变量都基于其node,因此有对node变量的ParameterDescriptor。同时,ROS 2也兼容了不声明参数的方式,通过在node构造函数中设置变量“allow_undeclared_parameters”以及“automatically_declare_parameters_from_overrides”为“true”来实现直接读取或设置参数的功能,可以参考下面的示例程序链接:
https://github.com/ros2/demos/blob/75cf923f9f3a33be456db1785f91e503c4bee16d/demo_nodes_cpp/src/parameters/parameter_blackboard.cpp#L29
关于声明参数的说明可以参考官网链接:
https://index.ros.org/doc/ros2/Releases/Release-Dashing-Diademata/#declaring-parameters

2. rclcpp::QoS qos(rclcpp::KeepLast(50))和scan_publisher_ = create_publisher…

该代码是因为引入DDS后的变化之一。ROS的通信基于TCP,引入了DDS后,ROS 2的通信就基于了UDP,由于UDP不像TCP是可靠连接,因此DDS通过QoS(Quality of Service)配置机制,依据不同的配置能够在UDP基础上实现与TCP类似的可靠连接

回想在ROS中发布消息的过程,以ROS rplidar为例:

ros::Publisher scan_pub = nh.advertise<sensor_msgs::LaserScan>("scan", 1000);

该代码两个参数topic和队列缓存数量1000,在ROS 2的QoS中可以通过组合配置“History”和“Depth”两个原则组合实现,即代码中的rclcpp::KeepLast(50)。详细的QoS配置及其说明,参考官网链接:
https://index.ros.org/doc/ros2/Concepts/About-Quality-of-Service-Settings/

NOTE:ROS rplidar发布消息队列缓存数量设置为了1000,不知道是出于什么原因,按经验来看,50就足够了

3. start_motor_server_ = create_service…和stop_motor_server_ = create_service…

由于使用了类及类成员函数的方式,start motor server和stop motor server两个node service的callback函数使用了bind以及用于表明callback形参数量的placeholders。也可以将callback函数定义为static静态类型,直接输入callback函数的地址。本文中由于callback需要访问类成员变量,static函数会引入额外的重构,因此采用了bind方式

4. timer_ = create_wall_timer…

函数create_wall_timer依据形参period的时间,周期性的调用给定的callback函数spin,本文考虑到rplidar激光扫描频率的可变性并能适配不同频率的rplidar产品,将period设置为参数变量,即可以通过launch方式设置

回想ROS rplidar中main函数while循环处理扫描的过程,其调用了rplidar驱动中的函数“grabScanDataHq”,该函数是一个同步函数,每一次扫描处理的时间决定于rplidar的扫描频率,比如5.5Hz即为182ms左右,因此wall timer调用spin函数的周期,设置为基于launch输入参数的频率计算得到的时间周期

本文在wall timer中调用了spin函数,该函数即是ROS rplidar中main函数的while循环部分。因为spin本文也设置为类成员函数,因此同样使用了bind方式的callback调用

其次,在引入了node继承类后,main函数会变得非常简洁,下面为main函数代码:

int main(int argc, char * argv[])
{
    rclcpp::init(argc, argv);  // !!!NOTE
   
	try
	{
		auto node = std::make_shared<rplidarROS2>();  // !!!NOTE
		rclcpp::spin(node);  // !!!NOTE
		rclcpp::shutdown();
	}
	catch (const std::runtime_error& error)
	{
		printf((std::string(error.what()) + "\n").c_str());
		return -1;
	}
	
    return 0;
}

main函数和ROS一致的地方就是进行初始化,区别在ROS 2中变为了rclcpp::init(argc, argv)。同时因为继承类rplidarROS2定义了所有关于激光雷达的操作,main函数只需要创建rplidarROS2的node,即auto node = std::make_shared(),并开启node的spin即可,即rclcpp::spin(node)。整个main函数变得非常简洁直观,这也是ROS 2架构带来的一大变化

再次,编译移植后代码
保存移植后代码即node_ROS2.cpp,在终端再次输入命令:
colcon build --packages-select rplidar_ros2
一切顺利的话,终端将输出编译完成的信息,如下图:
在这里插入图片描述
在终端继续输入命令:
. install/setup.sh
将package加入setup bash

NOTE:由于本文基于最大可能保持与ROS rplidar的一致性,便于后续如果思岚官方有更新时能够快速merge,因此没有处理编译warning

最后,运行移植代码,在终端继续输入命令:
ros2 run rplidar_ros2 rplidarNode
激光雷达node将运行,如下图:
在这里插入图片描述
NOTE:第一次运行时可能会出现提示“Error, cannot bind to the specified serial port /dev/ttyUSB0.”,可以通过下面命令:
sudo gpasswd --add ${USER} dialout
重启后解决

激光雷达运行后,可以通过topic echo命令查看/scan消息,检验移植的正确性。打开一个新终端输入命令:
ros2 topic echo /scan
将输入当前激光雷达发布的消息/scan,如下图:
在这里插入图片描述
TIP:通过命令ros2 topic list查看所有运行node发布的消息,如下图:
在这里插入图片描述

launch

代码移植后可以通过命令ros2 run命令运行,但通常在ROS下需要组合多个node运行,比如navigation,因此还需要launch方式实现。ROS 2引入了python代码的launch方式,详细内容以及设计思想参考官网链接:
https://index.ros.org/doc/ros2/Tutorials/Launch-system/
https://design.ros2.org/articles/roslaunch.html

但同时,ROS 2也兼容ROS下xml的launch文件,但做了部分修改,参考官网链接:
https://index.ros.org/doc/ros2/Tutorials/Launch-files-migration-guide/

本文将对xml和python两种方式都做介绍,先说明xml launch,再依据其做python launch的说明

移植到xml

1. 为package rplidar_ros2建立launch文件夹

进入rplidar_ros2的根目录,新建文件夹lauch,如下图:
在这里插入图片描述

2. 拷贝ROS rplidar的launch文件

在rplidar中特定产品的运行都有两个对应的launch文件,比如产品A1的launch文件为“rplidar.launch”和“view_rplidar.launch”,本文将以这两个文件做说明,其他产品的处理方式是一致的

拷贝ROS rplidar\launch目录下的文件“rplidar.launch”和“view_rplidar.launch”到ROS 2的rplidar_ros2\launch目录下,如下图:
在这里插入图片描述

3. rplidar.launch的ROS 2 launch适配修改

打开rplidar.launch修改为下面语句:

<launch>
  <node name="rplidarNode" pkg="rplidar_ros2" exec="rplidarNode" output="screen">
    <param name="frequency" value="5.5"/>
    <param name="serial_port" value="/dev/lidar"/>
    <param name="serial_baudrate" value="115200"/><!--A1/A2 -->
    <!--param name="serial_baudrate" value="256000"--><!--A3 -->
    <param name="frame_id" value="laser"/>
    <param name="inverted" value="false"/>
    <param name="angle_compensate" value="true"/>
    <param name="scan_mode" value="Standard"/>
    <param name="screened_begin" value="101"/>
    <param name="screened_end" value="259"/>
    <param name="max_distance" value="8.0"/>
  </node>
</launch>

ROS 2中node没有了type属性,变为了“exec”属性,param没有了type属性,变为依据用户填入数据自动判断,详细区别参考官网链接:
https://index.ros.org/doc/ros2/Tutorials/Launch-files-migration-guide/

保存修改后在终端输入命令:
ros2 launch src/rplidar_ros2/launch/rplidar.launch
激光雷达node将运行,如下图:
在这里插入图片描述
NOTE:仔细观察run命令和launch命令的两种方式会发现“Point number”的数量分别为4.0K和2.0K。这是由于launch运行使用了我们指定的参数而得到不同的激光雷达配置结果,具体区别是“angle_compensate”以及“scan_mode”,可以回想在构造函数中上述两个参数与rplidar.launch中默认值及设定值的区别

4. 添加package的xml launch文件

仔细回想ROS中launch的调用方式:roslaunch package_name target.launch,对比上述运行步骤中命令ros2 launch path/target.launch,会发现ROS 2中运行launch不再需要指定package,直接给出目标launch的路径即可,这是ROS 2 launch system带来的另一个变化。有时候也许launch文件的路径不容易记忆,通过package和TAB键能帮助联想出目标launch文件的方式依然具有优势,ROS 2兼容了该方式,可以通过CMakeLists文件中实现

打开rplidar_ROS2根目录下的“CMakeLists.txt”文件,在文件最后但“ament_package()”之前,增加如下语句:

# Install launch files.
install(DIRECTORY
launch
DESTINATION share/${PROJECT_NAME}/
)

在终端输入命令:
cd ~/dev_ws
colcon build --packages-select rplidar_ros2

重新编译rplidar_ros2,继续在终端输入命令:
. install/setup.sh
将package加入setup bash。此时通过终端输入package和其target.launch的命令:
ros2 launch rplidar_ros2 rplidar.launch
即可通过tab联想目标launch,如下图:
在这里插入图片描述
ROS 2中添加launch的install后会在workspace的“install//share/”目录下复制launch文件夹及其内部的所有launch文件,包括xml与python类型的launch文件。该机制能够支持后续其他package的launch引入该package launch,关于该引用在“移植到python launch”中说明

5. view_rplidar.launch以及rplidar.rviz的ROS 2 launch适配修改

打开view_rplidar.launch修改为下面语句:

<!--
Used for visualising rplidar in action.
It requires rplidar.launch.
-->
<launch>
  <group>
    <!--<push-ros-namespace namespace="rplidar_ros2"/> with user defined ns-->
    <include file="/home/whi/dev_ws/src/rplidar_ros2/launch/rplidar.launch"/>
  </group>

  <node name="rviz2" pkg="rviz2" exec="rviz2" args="-d /home/whi/dev_ws/src/rplidar_ros2/rviz/rplidar.rviz"/>
</launch>

ROS 2中include标签必须被group标签包含,同时动态的$(find rplidar_ros)被取消,因此这里输入了绝对路径

NOTE:在ROS 2 Design中关于动态配置有介绍built-in的$(find-pkg-prefix )但本文尝试未能成功

另外需要修改的是rviz目录下的rplidar.rviz,ROS 2中rviz也升级到了rviz 2,大部分configuration也发生了相应的变化,因此本文不在之前ROS下的rviz上做修改,而是通过手动过程在rviz中添加相应的frame和plugin,并另存rviz2下的configuration文件

在终端运行刚才修改的view_rplidar.launch,输入命令:
ros2 launch src/rplidar_ros2/launch/view_rplidar.launch
运行后可以看到终端输出激光雷达成功运行,并打开了rviz,但rviz为默认初始配置,不能显示激光雷达点云

首先将“Fixed Frame”由map改为laser;再添加“LaserScan”插件,并将“topic”设置为/scan,此时rviz的显示区域将能显示激光雷达的点云,如下图:
在这里插入图片描述
此时的点云不明显,把LaserScan插件的三个属性“Size”,“ColorTransform”,“Axis”分别设置为“0.03”,“AxisColor”,“Z”,此时点云将变得更明显,如下图:
在这里插入图片描述
点击菜单“File->Save Config As”,存储该配置到rviz目录,命名为rplidar.rviz,如下图:
在这里插入图片描述
关闭终端中运行的launch,再次运行view_rplidar.launch,在终端输入命令:
ros2 launch src/rplidar_ros2/launch/view_rplidar.launch
此时将看到激光雷达成功运行,以及我们需要的rviz显示,如下图:
在这里插入图片描述

移植到python launch

首先,在“launch”目录中建立rplidar.launch对应的python launch文件“rplidar.launch.py”,在文件中编辑rplidar的参数,与xml中对应

rplidar.launch.py

1. 参数声明

在该python文件的“def generate_launch_description():”后,以及“return LaunchDescription([”前,添加如下语句:

frequency = LaunchConfiguration('frequency', default='5.5')
serial_port = LaunchConfiguration('serial_port', default='/dev/lidar')
serial_baudrate = LaunchConfiguration('serial_baudrate', default='115200')
frame_id = LaunchConfiguration('frame_id', default='laser')
inverted = LaunchConfiguration('inverted', default='false')
angle_compensate = LaunchConfiguration('angle_compensate', default='true')
scan_mode = LaunchConfiguration('scan_mode', default='Standard')
screened_begin = LaunchConfiguration('screened_begin', default='101')
screened_end = LaunchConfiguration('screened_end', default='259')
max_distance = LaunchConfiguration('max_distance', default='8.0')

2. 编辑launch对应的声明变量,该声明可以为后续launch的内嵌调用提供参数的设置接口

在python文件的“return LaunchDescription([”后,以及“Node(…”前,添加如下语句:

DeclareLaunchArgument('frequency', default_value=frequency,
    escription='Specifying scan frequency of lidar'),
    
DeclareLaunchArgument('serial_port', default_value=serial_port,
    description='Specifying serial port to connected lidar'),
    
DeclareLaunchArgument('serial_baudrate', default_value=serial_baudrate,
    description='Specifying serial baudrate to connected lidar'),
    
DeclareLaunchArgument('frame_id', default_value=frame_id,
    description='Specifying frame_id of lidar. Default frame_id is \'laser\''),
    
DeclareLaunchArgument('inverted', default_value=inverted,
    description='Specifying inverted property of lidar'),
    
DeclareLaunchArgument('angle_compensate', default_value=angle_compensate,
    description='Specifying angle_compensate property of lidar'),
    
DeclareLaunchArgument('scan_mode', default_value=scan_mode,
    description='Specifying scan_mode property of lidar'),
    
DeclareLaunchArgument('screened_begin', default_value=screened_begin,
    description='Specifying screened_begin property of lidar'),
    
DeclareLaunchArgument('screened_end', default_value=screened_end,
    description='Specifying screened_end property of lidar'),
    
DeclareLaunchArgument('max_distance', default_value=max_distance,
description='Specifying max_distance property of lidar'),

3. 编辑Node,与xml下node的内容对应,即package名称、可执行node、参数

编辑为如下语句:

package='rplidar_ros2',
executable='rplidarNode',
name='rplidarNode',
parameters=[{'frequency': frequency,
            'serial_port': serial_port,
            'serial_baudrate': serial_baudrate,
            'frame_id': frame_id,
            'inverted': inverted,
            'angle_compensate': angle_compensate,
            'scan_mode': scan_mode,
            'screened_begin': screened_begin,
            'screened_end': screened_end,
            'max_distance': max_distance}],
output='screen'),

rplidar.launch.py文件即移植修改完成

veiw_rplidar.launch.py

然后,在“launch”目录中建立view_rplidar.launch对应的python launch文件“view_rplidar.launch.py”,在文件中编辑rplidar的参数,与xml中对应

1. 为rviz的configuration添加变量

在该python文件的“def generate_launch_description():”后,以及“return LaunchDescription([”前,添加如下语句:

rviz_config_dir = os.path.join(
get_package_share_directory('rplidar_ros2'),
    'rviz',
    'rplidar.rviz')

NOTE:get_package_share_directory()寻找package的路径为该package在workspace的“install//share/”目录,因此上述语句的子目录“rviz”也在该目录下。所以,需要为rplidar_ros2的CMakeLIsts添加install的另一个目录“rviz”,如下图
在这里插入图片描述
添加后重新编译package,将在share/rplidar_ros2下生成rviz目录,如下图:
在这里插入图片描述

2. 嵌套调用“rplidar.launch.py”

继续在该python文件的“return LaunchDescription([”后,以及“Node(”前,添加如下语句:

IncludeLaunchDescription(
    PythonLaunchDescriptionSource([ThisLaunchFileDir(), '/rplidar.launch.py'])
    ),

view_rplidar.launch.py文件即移植修改完成

总结

至此,思岚激光雷达从ROS到ROS 2的移植工作已经完成,为了支持思岚激光雷达的其他系列产品,可以依据上述步骤继续修改其他launch文件

本文的移植代码已经从源代码端考虑了不同产品频率的兼容性,即通过设置变量“frequency”实现不同产品频率的配置,在移植其他产品launch文件时需要关注并检查该参数变量是否符合产品特性设置

同时,本文的移植代码加入了扫描角度的屏蔽范围设置,即参数“screened_begin”和“screened_end”

source codes

本文源代码的github地址:
https://github.com/xinjuezou-whi/rplidar_ros2

  • 9
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值