ROS开发专栏---基于激光雷达的自动避障---适配Ubuntu 22.04

🎬 渡水无言个人主页渡水无言

专栏传送门 : 《linux专栏》《嵌入式linux驱动开发》《linux系统移植专栏》

专栏传送门 : 《freertos专栏》 《STM32 HAL库专栏》《linux裸机开发专栏

专栏传送门《产品测评专栏》 《Ai智能体专栏) 《ROS开发专栏

⭐️流水不争先,争的是滔滔不绝

📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生

| 省级优秀毕业生获得者 | csdn新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生

在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连

目录

前言

一、避障原理

二、避障程序流程框图

三、创建避障节点的代码实现

3.1、编写避障节点代码

3.2、编写CMakeLists.txt

[3.3、package.xml 依赖](#3.3、package.xml 依赖)

四、编译与运行

总结


前言

上一期博客我们实现了激光雷达数据读取的实验,本期博客我们本章我们将雷达数据 + 运动控制结合,实现机器人自动避障。为后续 SLAM 建图、自主导航打下基础。


一、避障原理

程序订阅雷达数据的"/scan"话题,从中接收激光雷达节点发来的sensor_msgs::LaserScan类型消息包,并解析出雷达测距值。根据雷达测距值让机器人做出反应:前方没有障碍物就前进,前方遇到障碍物就转向。如下图所示:

二、避障程序流程框图

订阅雷达数据:获取 /scan 话题的激光雷达数据,解析正前方障碍物距离

判断障碍物:

若前方距离 > 安全阈值(1.5m)→ 机器人保持前进

若前方距离 < 安全阈值 → 机器人原地左转,避开障碍物

发布速度指令:通过 /cmd_vel 话题控制机器人运动,实现 "遇障就转、无障就走"

三、创建避障节点的代码实现

我们直接在上一期的博客创建 lidar_pkg功能包中新增避障节点,无需新建包。

3.1、编写避障节点代码

lidar_pkg/src/ 目录下新建 lidar_avoid.cpp 文件,编写代码如下所示:

cpp 复制代码
#include <rclcpp/rclcpp.hpp>
#include <sensor_msgs/msg/laser_scan.hpp>
#include <geometry_msgs/msg/twist.hpp>

// 全局节点指针
std::shared_ptr<rclcpp::Node> node;
// 速度发布器
rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr vel_pub;
// 延时计数器,防止频繁抖动
int nCount = 0;

// 雷达数据回调函数
void LidarCallback(const sensor_msgs::msg::LaserScan::SharedPtr msg)
{
    // 获取雷达数据总数
    int nNum = msg->ranges.size();
    // 正前方索引
    int nMid = nNum / 2;
    // 正前方距离
    float fMidDist = msg->ranges[nMid];

    // 打印信息
    RCLCPP_INFO(node->get_logger(), "ranges[%d] = %f m", nMid, fMidDist);

    // 延时处理
    if (nCount > 0)
    {
        nCount--;
        return;
    }

    // 定义速度消息
    geometry_msgs::msg::Twist vel_msg;

    // 避障判断
    if (fMidDist < 1.5f)
    {
        // 左转避障
        vel_msg.angular.z = 0.3;
        nCount = 100;
    }
    else
    {
        // 直行
        vel_msg.linear.x = 0.1;
    }

    // 发布速度
    vel_pub->publish(vel_msg);
}

int main(int argc, char** argv)
{
    // 初始化ROS2
    rclcpp::init(argc, argv);

    // 创建节点
    node = std::make_shared<rclcpp::Node>("lidar_behavior_node");

    // 创建速度发布者
    vel_pub = node->create_publisher<geometry_msgs::msg::Twist>("/cmd_vel", 10);

    // 创建雷达订阅者
    auto lidar_sub = node->create_subscription<sensor_msgs::msg::LaserScan>(
        "/scan", 10, LidarCallback);

    // 循环等待回调
    rclcpp::spin(node);

    // 关闭ROS2
    rclcpp::shutdown();

    return 0;
}

3.2、编写CMakeLists.txt

编写代码如下:

cpp 复制代码
cmake_minimum_required(VERSION 3.8)
project(lidar_pkg)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)

# 编译雷达数据获取节点
add_executable(lidar_data src/lidar_data.cpp)
ament_target_dependencies(lidar_data
  rclcpp
  sensor_msgs
)

# 编译避障节点
add_executable(lidar_behavior src/lidar_behavior.cpp)
ament_target_dependencies(lidar_behavior
  rclcpp
  sensor_msgs
  geometry_msgs
)

# 安装节点
install(TARGETS
  lidar_data
  lidar_behavior
  DESTINATION lib/${PROJECT_NAME}
)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  set(ament_cmake_copyright_FOUND TRUE)
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

3.3、package.xml 依赖

添加一行<depend>geometry_msgs</depend>,全部代码如下所示:

cpp 复制代码
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>lidar_pkg</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="duan@todo.todo">duan</maintainer>
  <license>TODO: License declaration</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <depend>rclcpp</depend>
  <depend>sensor_msgs</depend>
  <depend>geometry_msgs</depend>


  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

四、编译与运行

编译功能包并运行仿真程序

cpp 复制代码
cd ~/ros2_ws
colcon build
source install/setup.bash
ros2 launch wpr_simulation2 wpb_simple.launch.py

打开第二个终端

运行避障节点

cpp 复制代码
ros2 run lidar_pkg lidar_behavior

节点运行起来之后,切换到刚才的仿真窗口。如图所示,可以看到机器人先以0.1米/秒的速度向前移动。当机器人距离书柜1.5米时,机器人停止前进,开始向左逆时针旋转。旋转一段时间后,机器人恢复直行,顺利的避开前方的书柜。


总结

本期博客完成了 ROS2 激光雷达自动避障 的完整实现,通过订阅 /scan 雷达数据、解析障碍物距离、结合 /cmd_vel 速度控制,实现了一套简单可靠的自主避障系统。

相关推荐
济61715 小时前
ROS开发专栏---基于 SLAM Toolbox 实现仿真环境 SLAM 建图--适配Ubuntu 22.04
嵌入式·ros2·机器人开发·机器人方向
时光の尘1 天前
【STM32实战】ESP8266 通过 MQTT 协议对接 OneNET 云平台实现数据上传与下发(源码可直接移植)
stm32·mqtt·嵌入式·iot·esp8266
十年编程老舅1 天前
读懂 MCU 启动:从上电到程序运行全链路
单片机·嵌入式硬件·mcu·嵌入式·cpu·嵌入式开发·ram
Qt程序员1 天前
从上电到系统就绪:ARM+U-Boot 嵌入式 Linux 启动流程
linux·运维·c++·内核·设备树·嵌入式·ram
华清远见IT开放实验室1 天前
华清远见亮相第64届高博会:聚焦具身智能,打造嵌入式/物联网/人工智能/机器人产教融合实践教学新生态
人工智能·物联网·机器人·嵌入式·实验室·具身智能·高校
爱学习的大牛1232 天前
软考系统架构设计师嵌入式方向总结
系统架构·嵌入式
BestOrNothing_20152 天前
ROS2 xacro 保姆级使用教程!零基础从入门到精通
机器人·ros2·macro·xacro·prefix·引用变量·调用宏
kyle~4 天前
ROS2 --- RMW(ROS Middleware Interface)
linux·c++·机器人·ros2
济6174 天前
ROS开发专栏---IMU 数据读取实验实现---适配Ubuntu 22.04
ubuntu·ros2·机器人开发