LoongLee's blog

ROS2的使用

ROS2的特点

尽管有这个名字,但 ROS 实际上并不是一个作系统。相反,它是一个 SDK(软件开发工具包),提供构建机器人应用程序所需的构建块。无论您的应用程序是课堂项目、科学实验、研究原型还是最终产品,ROS 都将帮助您更快地实现目标。 而且这一切都是开源的。

  1. 管道 ROS 的核心是一个消息传递系统,通常称为“中间件”或“管道”。通信是实现新的机器人应用程序或任何将与硬件交互的软件系统时首先需要出现的需求之一。ROS 的内置且经过充分测试的消息系统通过匿名发布/订阅模式管理分布式节点之间的通信细节,从而节省您的时间。这种方法鼓励在软件开发中实施良好实践,包括故障隔离、关注点分离和清晰的接口。使用 ROS 可以使系统更易于维护、贡献和重用。 在此过程中,您可以利用丰富的社区经验,这些经验导致了标准的 ROS 消息格式;这些标准用于与从 LIDAR 和摄像头到定位算法和用户界面的所有内容进行交互。
  2. 工具 构建机器人应用程序具有挑战性。您有任何软件开发工作的所有困难,还需要通过传感器和执行器与物理世界异步交互。要高效地构建应用程序,您需要良好的开发人员工具。ROS 具有它们,包括:启动、内省、调试、可视化、绘图、日志记录和回放。这些工具可以加快开发团队的进度,并且可以在产品交付时包含在产品中。
  3. 能力 ROS 生态系统是机器人软件的聚宝盆。无论您是需要 GPS 的设备驱动程序、四足动物的行走和平衡控制器,还是移动机器人的地图系统,ROS 都能满足您的需求。从驱动程序到算法,再到用户界面,ROS 提供了构建块,让您能够专注于您的应用程序。 ROS 项目的目标是不断提高人们认为理所当然的标准,从而降低构建机器人应用程序的准入门槛。任何对有用 (或有趣 或 有趣) 机器人有好主意的人都应该能够将这个想法变为现实,而无需了解有关底层硬件和软件的所有信息。
  4. 社区 ROS 社区庞大、多样化且全球化。从学生和业余爱好者到跨国公司和政府机构,各行各业的人和组织都在推动 ROS 项目继续进行。 该项目的社区中心和中立管家是 Open Robotics,它托管共享的在线服务(例如本网站),创建和管理分发版本(包括您安装的二进制包),以及开发和维护 ROS 中的大部分核心软件。Open Robotics 还提供与 ROS 相关的工程服务。

  5. OpenRobotics

Turtlesim是一个轻量级的用于学习ROS 2的模拟器。它以最基本的方式展示了ROS 2的功能,让您对以后在真实机器人或机器人模拟中要做什么有个基本的了解。

ros2工具是用户管理、检视和与ROS系统交互的方式。它支持多个命令,针对系统及其操作的不同方面。用户可以使用它来启动一个节点、设置参数、监听话题等等。ros2工具是ROS 2核心安装的一部分。

rqt 是一个用于ROS 2的图形用户界面(GUI)工具。rqt 中的所有操作都可以通过命令行完成,但是rqt 提供了一种更加用户友好的方式来操作ROS 2元素。

ROS2使用

关于信息类型

地图消息

在ROS(机器人操作系统)中,地图消息通常使用 nav_msgs::msg::OccupancyGrid 类型来表示。下面详细解释该消息的定义以及在软件中的功能作用。

地图消息定义(nav_msgs::msg::OccupancyGrid) nav_msgs::msg::OccupancyGrid 是ROS中用于表示二维占用栅格地图的消息类型。它定义在 nav_msgs/msg/OccupancyGrid.msg 文件中,具体结构如下:

# This represents a 2-D grid map, in which each cell represents the probability of occupancy.

Header header
MapMetaData info
int8[] data
  • Header header:消息头,包含消息的时间戳、坐标系等信息。
  • MapMetaData info:地图的元数据,包含地图的尺寸、分辨率、原点等信息。其定义如下:
# This hold basic information about the characterists of the OccupancyGrid

time map_load_time
float32 resolution
uint32 width
uint32 height
geometry_msgs/Pose origin
  • map_load_time:地图加载的时间戳。
  • resolution:地图的分辨率,即每个栅格代表的实际物理尺寸(单位:米)。
  • widthheight:地图的宽度和高度,以栅格数量表示。
  • origin:地图的原点,即地图左下角栅格的位置和朝向。

int8[] data:一个一维数组,存储地图中每个栅格的占用信息。每个元素的值表示该栅格的占用概率,取值范围为:

  • 1:未知状态。
  • 0:空闲状态。
  • 100:占用状态。

地图消息(nav_msgs::msg::OccupancyGrid)主要用于以下几个方面:

地图显示:将接收到的地图消息可视化,让用户直观地了解机器人所处的环境。例如,在图形用户界面(GUI)中显示地图,帮助用户规划机器人的路径。

路径规划:路径规划算法需要根据地图信息来寻找机器人从当前位置到目标位置的最优路径。占用栅格地图可以提供环境的障碍物信息,算法可以避开占用状态的栅格,规划出可行的路径。

导航:在机器人导航过程中,地图消息可以帮助机器人进行定位和避障。机器人可以根据地图信息判断自身位置,避开障碍物,确保安全地到达目标位置。

建图:在同时定位与地图构建(SLAM)过程中,机器人通过传感器数据不断更新地图信息。地图消息可以用于存储和传递这些更新后的地图数据,以便后续的处理和使用。

map_callback、localCostMapCallback 和 globalCostMapCallback 函数分别用于处理全局地图、局部代价地图和全局代价地图的消息,这些地图信息对于机器人的导航和决策非常重要。回调函数会在接收到相应的地图消息时被调用,对地图数据进行处理和更新。

里程计消息

用于表示机器人的运动状态信息 作用: 机器人定位 * 运动控制 状态监控 * 融合其他传感器数据

全局代价地图消息

  • 全局路径规划 为机器人全局路径规划提供了基础数据。路径规划算法(如 A* 算法、Dijkstra 算法等)会根据全局代价地图中的代价值来搜索从起始点到目标点的最优路径。算法会尽量避开代价值高的区域(如障碍物所在区域),选择代价值较低的路径,从而规划出一条安全、高效的全局路径。
  • 任务规划与调度 在复杂的机器人应用场景中,需要对多个任务进行规划和调度。全局代价地图可以帮助系统评估不同任务的可行性和成本。例如,根据地图中的障碍物分布和代价值,判断机器人是否能够到达任务地点,以及完成任务所需的时间和能量成本等。这有助于合理安排任务的执行顺序,提高整个系统的效率。
  • 环境建模与分析 全局代价地图是对机器人工作环境的一种建模表示。通过分析全局代价地图,可以了解环境的整体布局、障碍物的分布情况等信息。这对于机器人的任务规划、环境探索以及系统的设计和优化都具有重要意义。例如,根据地图中的障碍物分布,可以确定机器人的安全工作区域,或者对环境进行分区管理,以便更好地组织机器人的活动。
  • 多机器人协同 在多机器人系统中,全局代价地图可以为多个机器人提供统一的环境信息。不同的机器人可以根据全局代价地图进行路径规划,避免相互碰撞和冲突。同时,全局代价地图还可以用于协调多个机器人的任务分配和协作,提高整个系统的协同工作能力。

局部代价地图消息

  • 局部代价地图是机器人在局部范围内实时感知环境的重要工具。它会随着机器人的移动和传感器数据的更新而动态变化。在机器人导航过程中,路径规划算法会参考局部代价地图,避开那些代价值高(即存在障碍物)的区域,从而实现实时避障。例如,当机器人前方突然出现一个障碍物时,局部代价地图会迅速更新该区域的代价值,路径规划算法会重新规划路径,让机器人绕过障碍物。
  • 路径规划算法通常分为全局路径规划和局部路径规划。全局路径规划会根据全局地图规划出一条从起点到目标点的大致路径,但在实际执行过程中,机器人可能会遇到全局地图中未包含的障碍物或者局部环境发生变化。这时,局部代价地图就用于局部路径规划,在全局路径的基础上,结合当前局部环境信息,生成更精确、安全的局部路径,确保机器人能够顺利到达目标点。 作用:
  • 实时避障
  • 局部路径规划
  • 运动决策
  • 与传感器数据融合

激光扫描消息

激光扫描消息使用 sensor_msgs::msg::LaserScan 类型来表示。其消息结构定义如下:

Header heade
float32 angle_min
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities

Header header:消息头,包含消息的时间戳(stamp)和坐标系信息(frame_id)。时间戳用于标记激光扫描数据的采集时间,坐标系信息则表明这些数据是在哪个坐标系下采集的。 float32 angle_min:扫描的起始角度(弧度),通常是激光扫描的最左侧角度。 float32 angle_max:扫描的结束角度(弧度),通常是激光扫描的最右侧角度。 float32 angle_increment:相邻两次扫描之间的角度增量(弧度),即每个扫描点之间的角度间隔。 float32 time_increment:相邻两次扫描之间的时间增量(秒),如果激光雷达是连续扫描的,该值表示每次扫描的时间间隔。 float32 scan_time:完成一次完整扫描所需的时间(秒)。 float32 range_min:激光雷达能够测量的最小距离(米)。 float32 range_max:激光雷达能够测量的最大距离(米)。 float32[] ranges:一个一维数组,存储每个扫描点测量到的距离值(米)。数组的长度取决于扫描的角度范围和角度增量。 float32[] intensities:一个一维数组,存储每个扫描点的反射强度值。反射强度可以反映目标物体的表面特性,如材质、颜色等。

作用:

  • 障碍物检测 激光扫描消息提供了机器人周围环境的距离信息,通过分析 ranges 数组中的距离值,可以检测出机器人周围的障碍物。当某个扫描点的距离值小于一定阈值时,就可以判断该方向上存在障碍物。这对于机器人的避障和安全导航非常重要。
  • 地图构建 在同时定位与地图构建(SLAM)过程中,激光扫描数据是构建地图的重要输入。通过将多个激光扫描帧的数据进行融合和处理,可以生成机器人工作环境的地图,如二维占用栅格地图或三维点云地图。
  • 定位 激光扫描数据可以与地图进行匹配,从而实现机器人的定位。通过比较当前激光扫描数据与地图中的特征信息,可以计算出机器人在地图中的位置和姿态。这对于机器人的自主导航和路径规划至关重要。
  • 目标追踪 通过分析激光扫描数据的变化,可以跟踪移动目标的位置和运动轨迹。例如,在机器人的工作环境中检测到其他移动的物体,通过持续监测其位置变化,可以实现对目标的跟踪。

路径消息

路径消息通常使用 nav_msgs::msg::Path 类型来表示,其消息结构定义如下: Header header geometry_msgs/PoseStamped[] poses Header header:消息头,包含消息的时间戳(stamp)和坐标系信息(frame_id)。时间戳标记了路径消息生成的时间,坐标系信息明确了路径中各个位姿数据所在的参考坐标系,方便与其他传感器数据或机器人的位姿信息进行统一的坐标转换。 geometry_msgs/PoseStamped[] poses:这是一个由 geometry_msgs/PoseStamped 类型元素组成的数组。PoseStamped 消息包含了一个带有时间戳和坐标系信息的位姿(位置和姿态),其结构如下:

Header header
geometry_msgs/Pose pose

其中,geometry_msgs/Pose 又包含了位置(Point 类型,有 x、y、z 三个坐标值)和姿态(Quaternion 类型,用四元数表示机器人的朝向)。也就是说,poses 数组中的每个元素代表路径上的一个点,包含该点的位置和姿态信息以及对应的时间戳和坐标系信息。

作用:

  • 路径规划结果传递
  • 运动控制参考
  • 可视化显示
  • 多机器人协作

电池状态消息

消息结构定义:

Header header
float32 voltage
float32 temperature
float32 current
float32 charge
float32 capacity
float32 design_capacity
float32 percentage
uint8 power_supply_status
uint8 power_supply_health
uint8 power_supply_technology
bool present
float32[] cell_voltage
string location
string serial_number

Header header:消息头,包含消息的时间戳(stamp)和坐标系信息(frame_id),用于标记消息的生成时间和指定数据所属的坐标系。 float32 voltage:电池的当前电压值,单位通常为伏特(V),反映了电池的电势差,可用于判断电池的大致状态。 float32 temperature:电池的当前温度,单位通常为摄氏度(°C),过高或过低的温度都可能影响电池的性能和寿命。 float32 current:电池的当前电流值,单位通常为安培(A),正值表示电池正在放电,负值表示电池正在充电。 float32 charge:电池当前的电荷量,单位通常为安培小时(Ah),表示电池当前存储的电量。 float32 capacity:电池的实际容量,单位为安培小时(Ah),指电池在当前使用条件下能够存储的最大电量。 float32 design_capacity:电池的设计容量,单位为安培小时(Ah),是电池在理想条件下的最大容量。 float32 percentage:电池当前电量的百分比,取值范围为 0 到 100,表示电池剩余电量相对于实际容量的比例。 uint8 power_supply_status:电池的供电状态,使用枚举值表示,常见的状态包括充电、放电、满电、空闲等。 uint8 power_supply_health:电池的健康状态,使用枚举值表示,如良好、过热、老化、故障等。 uint8 power_supply_technology:电池的技术类型,如锂离子电池、铅酸电池等,使用枚举值表示。 bool present:表示电池是否存在,如果为 true 则表示电池已安装且可正常检测,为 false 则表示电池未安装或无法检测。 float32[] cell_voltage:一个数组,包含电池中每个电池单元的电压值,单位为伏特(V),用于监测每个电池单元的状态。 string location:电池的安装位置,以字符串形式表示,方便在系统中定位电池。 string serial_number:电池的序列号,以字符串形式表示,用于唯一标识电池。

作用:

  1. 电量管理 通过监测电池的当前电量百分比(percentage)和电荷量(charge),软件可以实时了解电池的剩余电量。当电量低于一定阈值时,可以触发相应的措施,如提醒用户充电、自动返回充电基站等,以避免机器人因电量耗尽而停止工作。

  2. 电池健康监测 电池的温度(temperature)、电压(voltage)和健康状态(power_supply_health)等信息可以用于监测电池的健康状况。异常的温度或电压值可能表示电池存在故障或老化问题,软件可以及时发出警报,提醒用户进行检查或更换电池,以保证机器人的正常运行和电池的使用寿命。

  3. 性能优化 根据电池的供电状态(power_supply_status)和电流(current),软件可以调整机器人的工作模式和任务分配,以优化电池的使用效率。例如,在电池电量较低时,减少机器人的不必要操作或降低其运行速度,以延长电池的使用时间。

  4. 系统日志和维护 电池状态消息可以记录到系统日志中,方便后续的数据分析和维护。通过分析电池的历史数据,可以了解电池的使用情况和性能变化趋势,为电池的更换和维护提供依据。