ROS 快速入门教程04

news2025/7/10 8:15:03

12.激光雷达工作原理

激光雷达的作用是探照周围障碍物的距离,按照测量维度可以分为单线雷达和多线雷达。 按照测量原理可以分为三角测距雷达和TOF雷达。按照工作方式可以分为固态雷达和机械旋转雷达。
本次讲解以TOF雷达为例,雷达发射器发射激光遇到障碍物再将雷达返回回来,被雷达的接收器捕获。通过计时器测量激光发射和接收的时间间隔测算雷达与障碍物之间的距离。

12.1使用RViz观测传感器数据

分别打开两个终端运行以下两条命令:

 roslaunch wpr_simulation  wpb_simple.launch 
rviz

在rviz页面进行如下设置:
在这里插入图片描述
Add添加RobotModelLaserScan并配置。
在这里插入图片描述
rviz是接收传感器的图形化界面,既可以接收拟真环境的也可以接收现实传感器的数据并且不参与运算。

12.2 激光雷达消息包格式

在这里插入图片描述

12.3 获取激光雷达数据的节点

先看样例,在两个终端里分别输入

roslaunch wpr_simulation  wpb_simple.launch 
rosrun wpr_simulation demo_lidar_data

在这里插入图片描述
在这里插入图片描述
在工作目录里创建新软件包:

cd catkin_ws/src
catkin_create_pkg  lidar_pkg roscpp rospy sensor_msgs

打开vscode,创建lidar_node.cpp
在这里插入图片描述

#include<ros/ros.h>
#include<sensor_msgs/LaserScan.h>
void LidarCallback(const sensor_msgs::LaserScan msg)
{

    float fMidDist = msg.ranges[180];//获取前方180度的测距值
    ROS_INFO("前方测距 ranges[180]: %f 米", fMidDist);//打印前方测距值
int main(int argc, char** argv)
{
    setlocale(LC_ALL, "");//设置中文显示
    ros::init(argc, argv, "lidar_node");//初始化节点
    ros::NodeHandle nh;//创建节点句柄
    ros::Subscriber lidar_sub = nh.subscribe("/scan", 10, &LidarCallback);//订阅激光雷达数据
    ros::spin();//循环等待回调函数
    return 0;
}

cmake编译。

add_executable(lidar_node src/lidar_node.cpp)
target_link_libraries(lidar_node 
  ${catkin_LIBRARIES}
)

启动ros仿真环境测试

roslaunch wpr_simulation  wpb_simple.launch
rosrun  lidar_pkg  lidar_node

在这里插入图片描述

13. 在ROS中实现激光雷达避障

在这里插入图片描述
对src下的lidar_node.cpp进行编写:

#include<ros/ros.h>
#include<sensor_msgs/LaserScan.h>
#include<geometry_msgs/Twist.h>
ros::Publisher vel_pub;//定义速度指令发布器
int nCount = 0;//定义计数器
void LidarCallback(const sensor_msgs::LaserScan msg)
{

    float fMidDist = msg.ranges[180];//获取前方180度的测距值
    ROS_INFO("前方测距 ranges[180]: %f 米", fMidDist);//打印前方测距值
   
    if (nCount > 0)//如果计数器大于0
    {
        nCount--;//计数器减1
       return;//返回
    }
    

    geometry_msgs::Twist vel_cmd;//定义速度指令
    if(fMidDist < 1.5)//如果前方距离小于0.5米
    {
        vel_cmd.linear.x = 0.0;//停止前进
        vel_cmd.angular.z = 0.3;//向右转
        ROS_INFO("前方障碍物,停止前进,向右转");//打印信息
        nCount=50;
    }
    else 
    {
        vel_cmd.linear.x = 0.5;//前进
        vel_cmd.angular.z = 0.0;//不转向
        ROS_INFO("前方无障碍物,继续前进");//打印信息
    }
    vel_pub.publish(vel_cmd);//发布速度指令
}


int main(int argc, char** argv)
{
    setlocale(LC_ALL, "");//设置中文显示
    ros::init(argc, argv, "lidar_node");//初始化节点
    ros::NodeHandle nh;//创建节点句柄
    ros::Subscriber lidar_sub = nh.subscribe("/scan", 10, &LidarCallback);//订阅激光雷达数据
    vel_pub = nh.advertise<geometry_msgs::Twist>("/cmd_vel", 10);//发布速度指令
    ros::spin();//循环等待回调函数
    return 0;
}

加入计数器的原因:函数只检测正前方的一条射线,转弯时虽然这条射线前方没有障碍物,但小车有体积不可忽略,因此解决思路是当前方射线检测到障碍物,计数器开始工作,等待转弯5秒后再继续前行。

14. ROS 中的 IMU 惯性测量单元消息包

惯性测量单元(Inertial Measurement Unit,简称 IMU)是一种集成了多个惯性传感器的设备,用于测量物体的加速度、角速度(及有时的磁场方向),从而推算其姿态(航向、俯仰、横滚)和运动轨迹。
在这里插入图片描述

14.1获取IMU数据的节点

一个IMU设备可能有这三个话题:

  • 加速度计输出的矢量加速度 和 陀螺仪输出的旋转角速度。
  • /imu/data raw的数据 再加上 融合后的四元数姿态描述。
  • 磁强计输出磁强数据。
    在这里插入图片描述
    在src工作目录下创建:
catkin_create_pkg imu_pkg roscpp rospy sensor_msgs

vscode在imu_pkg文件夹的src目录下创建imu_node.cpp

#include<ros/ros.h>
#include<sensor_msgs/Imu.h>
#include<tf/tf.h>

void IMUCallback(sensor_msgs::Imu msg)
{
  if(msg.orientation_covariance[0]<0)
  {
    ROS_INFO("IMU数据不可用");
    return;
  }
  tf::Quaternion quaternion(
    msg.orientation.x, 
    msg.orientation.y,
    msg.orientation.z,
    msg.orientation.w
    );
    double roll, pitch, yaw;
    tf::Matrix3x3(quaternion).getRPY(roll, pitch, yaw);
    roll = roll * 180 / M_PI;
    pitch = pitch * 180 / M_PI;
    yaw = yaw * 180 / M_PI;
    ROS_INFO("滚转角: %f, 俯仰角: %f, 偏航角: %f", roll, pitch, yaw);

}

int main(int argc, char** argv)
{
    setlocale(LC_ALL, "");//设置中文显示
    ros::init(argc, argv, "imu_node");//初始化节点
    ros::NodeHandle nh;//创建节点句柄
    ros::Subscriber imu_sub = nh.subscribe("/imu/data", 10, IMUCallback);//订阅IMU数据 {
        // 打印IMU数据
    ros::spin();//循环等待回调函数
    return 0;
}

Cmake里添加并编译。

add_executable(imu_node src/imu_node.cpp)
add_dependencies(imu_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(imu_node 
  ${catkin_LIBRARIES}
)

打开两个终端分别输入:

catkin_create_pkg imu_pkg roscpp rospy sensor_msgs
rosrun imu_pkg imu_node

调节模拟器中的小车角度就能看到节点中接收到的角度变化
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2343492.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2025 年导游证报考条件新政策解读与应对策略

2025 年导游证报考政策有了不少新变化&#xff0c;这些变化会对报考者产生哪些影响&#xff1f;我们又该如何应对&#xff1f;下面就为大家详细解读新政策&#xff0c;并提供实用的应对策略。 最引人注目的变化当属中职旅游类专业学生的报考政策。以往&#xff0c;中专学历报考…

vscode切换Python环境

跑深度学习项目通常需要切换python环境&#xff0c;下面介绍如何在vscode切换python环境&#xff1a; 1.点击vscode界面左上角 2.在弹出框选择对应kernel

Spark-Streaming(三)

一. kafka和flume的整合 任务需求一:利用flume监控某目录中新生成的文件&#xff0c;将监控到的变更数据发送给kafka&#xff0c;kafka将收到的数据打印到控制台 1. 在flume/conf/目录下添加flume-kafka.conf文件 配置文件如下 2. 启动flume和kafka消费者 3. 传入数据 查看fl…

SQLite 是什么?

&#x1f4cc; 一、SQLite 是什么&#xff1f; SQLite 是一个轻量级、嵌入式数据库&#xff0c;意思是它直接集成在你的 App 内部&#xff0c;不需要单独安装数据库服务端。 ✅ 特点&#xff1a; 特点说明本地使用所有数据保存在手机内部存储文件形式数据以 .db 文件形式存储…

海之淀攻略

家长要做的功课 家长可根据孩子情况&#xff0c;需要做好以下功课&#xff1a; 未读小学的家长&#xff1a;了解小学小升初派位初中校额到校在读小学的家长&#xff1a;了解小升初派位初中校额到校在读初中的家长&#xff1a;了解初中校额到校 越是高年级的家长&#xff0c;…

PCIe具体解释分析

参考文章 PCIe总线详解_STATEABC-GitCode 开源社区 https://zhuanlan.zhihu.com/p/652808759 PCI总线学习(一)&#xff1a;PCI总线结构-CSDN博客 PCI——第1章——PCI总线的基本知识-CSDN博客 计算机中register、cache、memory的区别 - Lines Blog 什么是内存管理单元&#xff…

Golang | 迭代器模式

迭代器模式&#xff08;Iterator Pattern&#xff09;是一种行为型设计模式&#xff0c;它提供了一种顺序访问聚合对象&#xff08;如列表、树等集合结构&#xff09;中元素的方法&#xff0c;而无需暴露其底层实现细节。通过将遍历逻辑与集合本身解耦&#xff0c;迭代器模式使…

使用命令行加密混淆C#程序

C#作为托管语言编译生成的IL中间代码极易被反编译工具还原源码。据统计&#xff0c;超过83%的商业软件曾遭遇过代码逆向风险&#xff0c;导致核心算法泄露、授权被跳过. 因此对于C#语言开发的程序来说, 在发布前进行混淆和加密非常有必要. 本文主要介绍如何使用恒盾C#混淆加密…

当智驾成标配,车企暗战升级|2025上海车展

文&#xff5c;刘俊宏 编&#xff5c;王一粟 智能化无处不在的2025年上海车展&#xff0c;回归了卖车的初衷。 光锥智能在展会暴走两天&#xff0c;最大的感触是今年的车展少了争奇斗艳&#xff0c;多了些许务实。 回顾智能汽车时代的三场重要车展。2023年的上海车展充满了…

在网上找的资料怎样打印出来?

在数字化时代&#xff0c;我们经常需要从互联网上获取各种资料&#xff0c;无论是学术论文、工作文档还是学习资料。然而&#xff0c;如何高效地将这些网上的资料打印出来&#xff0c;却是一个值得探讨的问题。本文将为您提供一个全面的解决方案&#xff0c;帮助您轻松完成网上…

算法训练营 Day1

努力追上那个曾经被寄予厚望的自己 —— 25.4.25 一、LeetCode_26 删除有序数组中的重复项 给你⼀个 升序排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现⼀次 &#xff0c;返回删除后数组的 新⻓度。元素的 相对顺序 应该保持 ⼀致 …

【linux】Chrony服务器

简介 1.1 时间的重要性 由于 IT 系统中&#xff0c;准确的计时非常重要&#xff0c;有很多种原因需要准确计时&#xff1a; 在网络传输中&#xff0c;数据包括和日志需要准确的时间戳 各种应用程序中&#xff0c;如订单信息&#xff0c;交易信息等 都需要准确的时间戳 1.2 时区…

技术视界 | 数据的金字塔:从仿真到现实,机器人学习的破局之道

在人工智能的世界里&#xff0c;有一个共识正逐渐达成——谁掌握了数据&#xff0c;谁就掌握了未来。 尤其是在机器人技术迅速演进的今天&#xff0c;“如何让机器人理解世界、学习操作”这一问题的根源&#xff0c;越来越回归到数据本身。正如一座金字塔般&#xff0c;不同层…

wsl联通外网

在C:\Users<你的用户名>下&#xff0c;新建.wslconfig文件添加如下配置&#xff08;具体配置参考官方文档&#xff09;&#xff1a; # Settings apply across all Linux distros running on WSL 2 [wsl2]# Limits VM memory to use no more than 4 GB, this can be set …

shadcn/radix-ui的tooltip高度定制arrow位置

尝试了半天&#xff0c;后来发现&#xff0c;不支持。。。。。就是不支持 那箭头只能居中 改side和align都没用&#xff0c;下面有在线实例 https://codesandbox.io/p/sandbox/radix-ui-slider-forked-zgn7hj?file%2Fsrc%2FApp.tsx%3A69%2C21 但是呢&#xff0c; 第一如果…

【专题刷题】二分查找(二)

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…

C++_数据结构_详解红黑树

✨✨ 欢迎大家来到小伞的大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 小伞的主页&#xff1a;xiaosan_blog 制作不易&#xff01;点个赞吧&#xff01;&#xff01;谢谢喵&#xff01;&…

数据结构手撕--【二叉树】

目录 定义结构体&#xff1a; 初始化&#xff1a; 手动创建一个二叉树&#xff1a; 前序遍历&#xff1a; 中序遍历&#xff1a; 后序遍历 二叉树节点个数&#xff1a; 叶子节点个数&#xff1a; 二叉树第k层节点个数&#xff1a; 二叉树的高度&#xff1a; 查找值为x…

.NET MAUI 发展历程:从 Xamarin 到现代跨平台应用开发框架

文章目录 引言Xamarin 起源&#xff1a;MAUI 的前身Xamarin 的创立&#xff08;2011年&#xff09;Xamarin Studio 与 Visual Studio 集成&#xff08;2013年&#xff09;Xamarin.Forms 的诞生&#xff08;2014年&#xff09;微软收购Xamarin&#xff08;2016年&#xff09; .N…

多模态大语言模型arxiv论文略读(四十)

The Wolf Within: Covert Injection of Malice into MLLM Societies via an MLLM Operative ➡️ 论文标题&#xff1a;The Wolf Within: Covert Injection of Malice into MLLM Societies via an MLLM Operative ➡️ 论文作者&#xff1a;Zhen Tan, Chengshuai Zhao, Raha M…