当前位置: 首页 > article >正文

ROS 快速入门教程04

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--;//计数器减1return;//返回}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

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

相关文章:

ROS 快速入门教程04

12.激光雷达工作原理 激光雷达的作用是探照周围障碍物的距离&#xff0c;按照测量维度可以分为单线雷达和多线雷达。 按照测量原理可以分为三角测距雷达和TOF雷达。按照工作方式可以分为固态雷达和机械旋转雷达。 本次讲解以TOF雷达为例&#xff0c;雷达发射器发射激光遇到障碍…...

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 文件形式存储…...

两段文本比对,高亮出差异部分

用法一:computed <div class"card" v-if"showFlag"><div class"info">*红色背景为已删除内容&#xff0c;绿色背景为新增内容</div><el-form-item label"与上季度比对&#xff1a;"><div class"comp…...

成熟的前端vue vite websocket,Django后端实现方案包含主动断开websocket连接的实现

可参考实现方式点击进入查看 具体实现方案如下所示&#xff1a; import { useWebsocketMsessageStore } from /stores/websocketMsessageStore.js import {ElMessage} from "element-plus"; import {useUserStore} from "/stores/userStore.js"; // impo…...

2.5 桥梁桥面系及附属结构施工

2.5.1 桥面系施工 1.排水设施 设置纵横坡及泄水孔&#xff0c;减少桥面积水、防排结合。汇水槽、泄水孔顶面高程低于桥面铺装10-15mm。泄水孔边缘设渗水盲沟泄水管下端至少应伸出构筑物底面100-150mm。泄水管通过竖向管道直接引至地面或雨水管线。竖向管道抱箍、卡环、定位卡…...

Markdown格式思维导图——用DeepSeek从PDF内容提取关键信息的有效方法

结构化PDF的思维导图提取方法 当PDF文档结构清晰&#xff0c;包含明确的章节和小节标题时&#xff0c;可以使用以下提示词&#xff1a; 读取上方的PDF&#xff0c;请帮我生成一个结构清晰的思维导图&#xff0c;包含以下内容&#xff1a; 1. 提取PDF中的主要标题作为思维导图…...

海之淀攻略

家长要做的功课 家长可根据孩子情况&#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…...

【阿里云大模型高级工程师ACP习题集】2.5 优化RAG应用提升问答准确度(⭐️⭐️⭐️ 重点章节!!!)

习题集 【单选题】在RAG应用的文档解析与切片阶段,若遇到文档类型不统一,部分格式的文档不支持解析的问题,以下哪种解决方式不可行?( ) A. 开发对应格式的解析器 B. 转换文档格式 C. 直接忽略该类型文档 D. 改进现有解析器以支持更多格式 【多选题】在选择向量数据库时,…...

Golang | 迭代器模式

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

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

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

MYSQL 常用数值函数 和 条件函数 详解

一、数值函数 1、ROUND(num, decimals) 四舍五入到指定小数位。 SELECT ROUND(3.1415, 2); -- 输出 3.142、ABS(num) 取绝对值 SELECT ABS(-10); -- 输出 103、CEIL(num) / FLOOR(num) 向上/向下取整 SELECT CEIL(3.2), FLOOR(3.7); -- 输出 4 和 34、MOD(num1, num2) 取…...

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

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

QuecPython+GNSS:实现快速定位

概述 QuecPython 结合 GNSS&#xff08;全球导航卫星系统&#xff09;模块为物联网设备提供开箱即用的定位能力解决方案。该方案支持 GPS/北斗/GLONASS/Galileo 多系统联合定位&#xff0c;为物联网开发者提供从硬件接入到云端服务的全栈式定位解决方案。 优势特点 多体系定…...

[java八股文][Java基础面试篇]设计模式

volatile和sychronized如何实现单例模式 public class SingleTon {// volatile 关键字修饰变量 防止指令重排序private static volatile SingleTon instance null;private SingleTon(){}public static SingleTon getInstance(){if(instance null){//同步代码块 只有在第一次…...

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

在数字化时代&#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…...

【刷题Day26】Linux命令、分段分页和中断(浅)

说下你常用的 Linux 命令&#xff1f; 文件与目录操作&#xff1a; ls&#xff1a;列出当前目录的文件和子目录&#xff0c;常用参数如-l&#xff08;详细信息&#xff09;、-a&#xff08;包括隐藏文件&#xff09;cd&#xff1a;切换目录&#xff0c;用于在文件系统中导航m…...

星火燎原:大数据时代的Spark技术革命在数字化浪潮席卷全球的今天,海量数据如同奔涌不息的洪流,传统的数据处理方式已难以满足实时、高效的需求。

星火燎原&#xff1a;大数据时代的Spark技术革命 在数字化浪潮席卷全球的今天&#xff0c;海量数据如同奔涌不息的洪流&#xff0c;传统的数据处理方式已难以满足实时、高效的需求。Apache Spark作为大数据领域的璀璨明星&#xff0c;凭借其卓越的性能和强大的功能&#xff0c…...

.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…...