系列文章目录

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

目录

  • 系列文章目录
  • 前言
  • 创建rplida_ros的package
    • 1. 拷贝思岚rplidar的sdk以及rivz包
    • 2. 为CMakeLists添加rplidar sdk和node的目标编译文件,以及ROS 2 run命令在寻找node时的路径
    • 3. 检查依赖问题
    • 4. 尝试编译,以解决CMakeLists问题
  • 适应ROS 2架构的代码移植
    • 1. declare_parameters()
    • 2. rclcpp::QoS qos(rclcpp::KeepLast(50))和scan_publisher_ = create_publisher…
    • 3. start_motor_server_ = create_service…和stop_motor_server_ = create_service…
    • 4. timer_ = create_wall_timer…
  • launch
    • 移植到xml
      • 1. 为package rplidar_ros2建立launch文件夹
      • 2. 拷贝ROS rplidar的launch文件
      • 3. rplidar.launch的ROS 2 launch适配修改
      • 4. 添加package的xml launch文件
      • 5. view_rplidar.launch以及rplidar.rviz的ROS 2 launch适配修改
    • 移植到python launch
      • rplidar.launch.py
      • 1. 参数声明
      • 2. 编辑launch对应的声明变量,该声明可以为后续launch的内嵌调用提供参数的设置接口
      • 3. 编辑Node,与xml下node的内容对应,即package名称、可执行node、参数
      • veiw_rplidar.launch.py
      • 1. 为rviz的configuration添加变量
      • 2. 嵌套调用“rplidar.launch.py”
  • 总结
  • source codes

前言

由于需要将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(TARGETSrplidarNodeDESTINATION 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(rplidarNodePUBLIC$<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(); // !!!NOTEget_parameters();rclcpp::QoS qos(rclcpp::KeepLast(50));  // !!!NOTEscan_publisher_ = create_publisher<sensor_msgs::msg::LaserScan>("scan", qos);  // !!!NOTEstart_motor_server_ = create_service<std_srvs::srv::Empty>("start_motor", std::bind(&rplidarROS2::start_motor, this, std::placeholders::_1, std::placeholders::_2));  // !!!NOTEstop_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));  // !!!NOTEconnect_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);  // !!!NOTEtry{auto node = std::make_shared<rplidarROS2>();  // !!!NOTErclcpp::spin(node);  // !!!NOTErclcpp::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

思岚激光雷达rplidar从ROS 1到ROS 2的移植相关推荐

  1. 激光雷达初体验 - Ubuntu 18.04 + 思岚科技 RPLIDAR A1M8 + ROS 上手使用

    思岚科技 RPLIDAR A1M8 + ROS 上手使用 一.开箱图 二.文档和SDK下载 `官网链接` 三.SDK 安装 四.SDK 使用 五.小结 一.开箱图 型号 RPLIDAR A1 配料 激 ...

  2. 思岚科技Rplidar A3实现指定角度扫描及扫描结果存储输出

    思岚科技Rplidar A3实现指定任意角度扫描及扫描结果.txt存储输出 前言 思岚科技Rplidar系列产品非常不错,拥有A1.A2.A3系列成熟的商业激光雷达产品.产品均可从官网获取相应的SDK ...

  3. 关于思岚激光雷达在ros包中如何把360度扫描数据切割成想要的扫描平面

    最近入手测试思岚的激光雷达,在测试过程中发现,思岚官网不提供ros应用方面的技术支持,扫描的角度为360度,如果想任意设定角度却没有配置参数的设定,对于应用灵活使用十分痛苦...于是开始十分痛苦的看思 ...

  4. ROS中使用思岚激光雷达进行跟随和Cmakelist.txt讲解

    之前一直在弄ROS小车的底盘和编写底盘的代码,现在把底盘已经弄好了,所以开始编写一些上层的代码和算法,这篇博客主要介绍使用思岚雷达来进行跟随和Cmakelist.txt的讲解,本人注重于手动DIY R ...

  5. Jeson nano + 思岚激光雷达rplidar_s1 + ubuntu18.04

    首先在思岚官网下载rplidar_s1的ROS功能包(官网的下载和支持里),新建工作空间catkin_ws/src 接下来安装配置思岚RPLIDAR S1,首先在github上下载它的ROS包. 在工 ...

  6. 思岚激光雷达A2M7-R4踩坑记录

    1.惨痛的踩坑记录,啊啊!!!!!!!!!!! 思岚A2M7的激光雷达和普通的A2系列雷达是不一样的,A2系列的波特率大多是115200的波特率,然而A2M7的波特率是256000.然而在ROS包中的 ...

  7. 当“思岚”激光雷达邂逅盲人拐杖

    目前,在全球范围内,超过2.5亿人视力受损.对于视力受损的群体来说,独立外出是一项巨大挑战.不仅需要识别障碍物,避开障碍物,还需要根据障碍物的位置信息做出自主寻路和导航判断. 当说到盲人导航的时候,大 ...

  8. Cartographer(三)思岚雷达rplidar ros驱动使用报错与解决

    0.参考 https://github.com/Slamtec/rplidar_ros/issues/5https://github.com/Slamtec/rplidar_ros/issues/5 ...

  9. 激光雷达初体验 == 思岚A1M8 + Ubuntu 18.04 + ROS melodic + hector_slam

    一.开箱图 型号 RPLIDAR A1 配料 激光雷达一台 + usb 转接板一块 + 转接线一条 二.文档和SDK下载 (官网链接) RPILIDAR A1M8 简介与规格书 Datasheet R ...

  10. 思岚发布新品TOF激光雷达——RPLIDAR S1 性能更强、更稳定

    去年2月, 思岚科技 对外发布了第三代激光扫描测距雷达RPLIDAR A3,基于思岚科技最新的RPVision 3.0测距引擎,可实现25米范围的实用化距离探测,每秒16,000的采样频率,刷新了三角 ...

最新文章

  1. spring怎么解耦_终于有人把Spring和SpringMvc讲透了!
  2. python和c++哪个好用-python和C++语言哪个好?老男孩教育
  3. PIC单片机入门_指令系统
  4. 【定时同步系列4】QPSK调制+OM定时(FFT实现及频域补偿)+信号分段处理+误码率曲线之MATLAB仿真(复信号模型)
  5. [译] 论 Rust 和 WebAssembly 对源码地址索引的极限优化
  6. 中北大学计算机学,中北大学计算机类专业好吗
  7. RabbitMQ学习之ConntectionFactory与Conntection的认知
  8. 技术支持和研发哪个好_考拉海购技术支持的前世今生,聊聊家常“黑历史”
  9. 利用Split函数进行多关键字检索
  10. 如何清除BIOS密码
  11. webpack, react项目中利用外部JS库提升效率
  12. php mysql update 不成功也不提示_php与MySQL(基本操作)
  13. fatal error: hb.h: 没有那个文件或目录
  14. JavaScript 优先队列
  15. linux svn e210003,svnadmin load 遇到E125005 的错误
  16. Java生成简单的验证码图片
  17. 恶意软件相似度检测过程
  18. Win10系统打不开html文件,电脑无法打开html文件
  19. malloc()动态分配内存
  20. 关于64位UBUNTU硬盘安装方式详解,和提示找不到vmlinuz的分析

热门文章

  1. 百度地图API 拾取坐标
  2. 《Python实用爬虫案例》练习8:获取搜狗搜索引擎微信文章
  3. cachecloud 安装
  4. mysql proxy maxscale_MaxScale: 一个用于解决MySQL扩展性的新工具(译)
  5. JS使用递归遍历json对象进行操作
  6. refreshToken的作用讨论及几点疑惑
  7. Insyde BIOS@G50-80 继续研究
  8. 偏微分方程中常用的不等式
  9. win10禁用uac_在Win 7、8或10上通过简便方法禁用用户帐户控制(UAC)
  10. 如何学习PLC编程,有没有什么好的方法?