重要说明:本文从网上资料整理而来,仅记录博主学习相关知识点的过程,侵删。
ROS相关技术介绍,可参考之前的文章:ROS相关技术(概念版)
Autolabor主站
ROS官网
ROS
ROS教程
ROS编程技术
ROS书籍整理:机器人操作系统 ROS 相关书籍整理合集 [古月居推荐]
Apollo可以看作是ROS的改进版,Apollo从通信功能优化、去中心化网络拓扑以及数据兼容性扩展三个方面做了定制化的改进。
单对多的传输场景下,ROS 在处理一对多的消息传输时,底层实现实际是多个点对点的连接,当把一份数据要发给三个节点时,相同的数据会传输三次,这会造成很大的资源浪费。而Apollo采用了共享内存的解决方案,减少传输过程中的数据拷贝,大幅度提升效率。
ROS系统非常依赖Master,一旦Master出现异常,将导致整个系统崩溃,且缺乏恢复自动机制。Apollo的整个网络拓扑不再以 master 为中心构建,当一个新的节点加入网络时,会通过 RTPS 协议向域内的所有其他节点发送广播信息,各个节点也会将自己的服务信息发送给新的节点,以代替 Master 的信息交换功能。
ROS 系统为了保证收发双方的消息格式一致,会对message定义做 MD5 校验,任何字段的增减或顺序调整都会使 MD5 变化。然而这种严格的限制也引起了兼容性的问题,OTA升级后可能出现兼容问题,在Apollo中,做了一整套对protobuf的支持, 在工程中可以不需要做格式转换,直接publish protobuf格式的消息,调试工具也能够非常正确的解析出来正确的protobuf消息。这样既能够很好解决兼容性问题,也不会产生额外的学习成本和使用成本。
ROS笔记(2)——ROS的基本命令
roscore
功能描述:用于启动ROS系统的核心功能。
启动roscore是ROS系统的先决条件,必须运行roscore才能使ROS节点进行通信。
启动roscore将:
ROS Master节点是ROS系统中的核心管理节点,负责管理所有节点之间的通信,包括节点的发现、消息的路由、参数服务器等。当执行 roscore
指令时,ROS Master节点将在计算机上启动,并将等待其他节点连接。只有在启动 roscore
之后,才能启动其他节点,并进行ROS操作。因此,通常在开始进行任何ROS项目之前,第一步是启动 roscore
。
rosrun
功能描述:启动ROS包中的节点。
# 启动小海龟节点用于演示机器人控制
rosrun turtlesim turtlesim_node
rosnode
rosnode
功能描述:用于获取节点信息。
# 测试节点的连接状态
rosnode ping
# 列出活动的节点
rosnode list
# 打印节点信息
rosnode info
# 列出指定设备上的节点
rosnode machine
# 杀死节点
rosnode kill
# 清除不可连接的节点
# ctrl+c并没有清除节点,需要用cleanup彻底清除
rosnode cleanup
roslaunch
功能描述:执行功能包的launch文件。
roslaunch <package_name> <launch文件名>
rostopic
功能描述:用于显示有关ROS 话题的调试信息,包括发布者,订阅者,发布频率和ROS消息。
# 显示话题使用的带框
rostopic bw
# 显示带有header的话题延迟
rostopic delay
# 打印话题的消息到屏幕
rostopic echo
# 根据消息类型查找话题
rostopic find
# 显示话题的发布频率
rostopic hz
# 显示话题的相关信息
rostopic info
# 显示所有活动状态下的话题
rostopic list -v
# 将数据发布到话题
rostopic pub </topic_name> <message_type> <message_content>
# 以10HZ的频率发送信息
rostopic pub -r 10 </topic_name> <message_type> <message_content>
# 打印话题的消息类型
rostopic type
rosmsg
rosmsg
功能描述:显示有关 ROS消息类型的信息。
# 显示消息描述
rosmsg show <message_type>
# 显示消息信息
rosmsg info
# 列出所有消息
rosmsg list
# 显示md5加密后的消息
rosmsg hd5
# 显示某个功能包下的所有消息
rosmsg package <package_name>
# 列出包含消息的所有包
rosmsg packages
rosservice
rosservice
功能描述:用于列出和查询ROS服务。
# 打印服务参数
rosservice args </service_name>
# 按照服务类型查找服务
rosservice find <servervice_name>
# 打印指定服务的信息
rosservice info
# 列出所有活动的服务
rosservice list
# 打印服务的类型
rosservice type
# 打印服务的ROSRPC uri
rosservice uri
# 调用指定服务
rosservice call </service_name>
rosparam
功能描述:用于管理ROS参数。
# 设置指定参数的值
rosparam set param_name value
rosbag详解
rosbag是ROS中的一种数据记录工具,它可以记录和回放ROS的消息数据。我们可以使用rosbag来记录ROS系统中的消息流,包括传感器数据、机器人状态等信息,然后在之后的时间点上回放这些消息数据,以便我们进行离线分析和调试。
rosbag可以将消息数据存储在文件中,并使用一种高效的压缩算法来减少文件大小。这样,我们可以在之后的时间点上使用rosbag回放工具来重新播放这些消息,以便我们在没有实际硬件的情况下进行测试和调试。rosbag还支持多个包(bag)之间的合并和分割,以便我们更好地管理消息数据。
rosbag常用指令
record
:用指定的话题录制一个 bag 包;info
:显示一个 bag 包的基本信息,比如包含哪些话题;play
:回放一个或者多个 bag 包;reindex
:重新索引一个或多个损坏 bag 包。rosbag record 是一个用于记录 ROS 消息到 ROS Bag 文件中的命令行工具。它可以记录指定主题的消息,将消息保存到一个ROS Bag文件中。例如,以下命令将记录名为/scan
的激光雷达数据并将其保存到名为scan.bag
的文件中:
rosbag record /scan -O scan.bag
以下是 rosbag record 命令的常用参数:
-a, --all
:记录所有主题。-O, --output-name
:指定输出的 ROS Bag 文件名。-b, --buffer-size
:设置ROS Bag文件的缓冲区大小。-d, --duration
:设置记录时间长度,以秒为单位。-l, --limit
:设置记录的消息数量限制。-j, --bz2
:使用bzip2压缩来压缩ROS Bag文件。-z, --lz4
:使用LZ4压缩来压缩ROS Bag文件。-p, --split
:设置ROS Bag文件的分段大小。-t, --topics
:指定要记录的主题列表。-x, --exclude
:指定要排除的主题列表。# 录制所有话题数据
rosbag record -a
# 录制指定话题数据
rosbag record <topic_name1> <topic_name2> <topic_name3> ...
# 指定数据包名称
rosbag record -O <bagname> <topic_name1> <topic_name2> <topic_name3> ...
rosbag info指令可以数据包中包含的话题名称,话题数量,话题消息类型等信息。
rosbag info <bagname>
使用 rosbag play
指令可以从指定的ROS包文件中回放消息数据。
# 回放指定bag
rosbag play <bagname>
# 回放当前目录下所有bag
rosbag play *
# 从指定时间(n = 指定时间s)开始回放bag
rosbag play -s n <bagname>
# 延时指定时间(n = 延时时间s)开始回放bag
rosbag play -d n <bagname>
# 播放指定时间(n = 指定秒数)的bag
rosbag play -u n <bagname>
# 从指定时间(n = 开始时间s)开始播放指定时间(m = 指定播放时间s)的bag
rosbag play -s n -u m <bagname>
# 按指定倍率(n = 倍率)回放bag
rosbag play -r n <bagname>
回放不成功,提示 reindex ,修复bag。
rosbag reindex
rqt_graph
ROS计算图
ROS 分布式系统中不同进程需要进行数据交互,计算图可以以点对点的网络形式表现数据交互过程。rqt_graph能够创建一个显示当前系统运行情况的动态图形。
# 安装rqt_graph
# 是ROS的版本,例如:kinetic、melodic、Noetic等
sudo apt install ros-<distro>-rqt
sudo apt install ros-<distro>-rqt-common-plugins
# 启动rqt_graph
rosrun rqt_graph rqt_graph
ROS学习笔记16:机器人系统建模与仿真
机器人系统仿真是通过计算机对实体机器人系统进行模拟的技术。在ROS中,仿真实现涉及的内容主要有三:对机器人建模(URDF)、创建仿真环境(Gazebo)以及感知环境(Rviz)等系统性实现。
URDF (Unified Robot Description Format,统一(标准化)机器人描述格式),以XML的方式描述机器人的部分结构,比如地盘、摄像头、激光雷达、机械臂以及不同关节的自由度,该文件可以被C++内置的解释器转换成可视化的机器人模型,是ROS中实现机器人仿真的重要组件。
rviz(ROS Visualization Tool,ROS的三维可视化工具),它的主要目的是以三维方式显示ROS信息,可以将数据进行可视化表达。例如,可以显示机器人模型,可以无需编程就能表达激光测距仪(LRF)传感器中的传感器到障碍物的距离,Kinect或Xtion等三维距离传感器的点云数据(PCD,Point Cloud Data),从相机获取的图象值等。
Gazebo是一款3D动态模拟器,用于显示机器人模型并创建仿真环境,能够在复杂的室内和室外环境中准确有效地模拟机器人。与游戏引擎提供高保真度的视觉模拟类似,Gazebo提供高保真度的物理模拟,其提供一整套传感器模型,以及用户和程序非常友好的交互方式。
ROS笔记(5)——Bag包概述与解析
ROS Bag是一种文件格式,用于存储ROS系统中的消息。ROS Bag可以将ROS节点发布的消息记录下来,然后在需要的时候将这些消息再次播放回ROS系统中。
ROS Bag文件以 .bag
拓展名结尾,可以通过以下两种方式保存:
rosbag
方式。在终端中使用rosbag record
命令来记录指定主题的消息,将消息保存到ROS Bag文件中。rosbag
方式rosbag
方式,参见rosbag指令。
以下代码段将记录名为/scan
的激光雷达数据并将其保存到名为scan.bag
的文件中。
C++代码示例
#include
#include
#include
void scanCallback(const sensor_msgs::LaserScan::ConstPtr& msg)
{
static rosbag::Bag bag;
if (!bag.isOpen()) {
bag.open("scan.bag", rosbag::bagmode::Write);
}
bag.write("/scan", ros::Time::now(), *msg);
/*
当程序退出时,ROS Bag 的析构函数会自动关闭文件。
如果您想手动关闭文件,可以在程序退出前显式地删除ROS Bag对象或调用rosbag::Bag::close()方法来关闭
文件。
*/
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "scan_logger");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe("/scan", 1, scanCallback);
ros::spin();
return 0;
}
python代码示例
#!/usr/bin/env python
import rospy
import rosbag
from sensor_msgs.msg import LaserScan
def scanCallback(msg):
global bag
if bag is None:
bag = rosbag.Bag('scan.bag', 'w')
bag.write('/scan', msg)
if __name__ == '__main__':
rospy.init_node('scan_logger')
bag = None
sub = rospy.Subscriber('/scan', LaserScan, scanCallback)
rospy.spin()
bag.close()
rosbag::View
是ROS Bag文件中的一组消息的视图,它提供了一些方便的方法来遍历和访问这些消息。
rosbag::View
实际上是一个包含 rosbag::Connection
对象的集合,每个对象代表一个主题。rosbag::Connection
对象包含一组时间戳和消息,表示该主题的所有消息。您可以使用以下方法来访问这些消息:
begin()
:返回指向第一条消息的迭代器。end()
:返回指向最后一条消息后面的位置的迭代器。rbegin()
:返回指向最后一条消息的迭代器。rend()
:返回指向第一条消息前面的位置的迭代器。size()
:返回视图中消息的数量。在使用 rosbag::View
遍历Bag文件中的所有消息时,每个迭代器会返回一个 rosbag::MessageInstance
对象。这个对象包含了消息的时间戳、消息类型和消息数据等信息。可以使用以下方法来访问这些信息:
getTime()
:返回消息的时间戳。getTopic()
:返回消息所属的主题名称。getDataType()
:返回消息的数据类型。instantiate()
:将消息实例化为指定的数据类型。如果无法实`例化,则返回空指针。#include
#include
#include
int main(int argc, char** argv) {
// 初始化ROS节点
ros::init(argc, argv, "rosbag_parser");
ros::NodeHandle n;
// 打开bag文件
rosbag::Bag bag;
bag.open("/path/to/bagfile.bag", rosbag::bagmode::Read);
// 遍历bag文件中的所有消息
rosbag::View view(bag);
for (rosbag::MessageInstance const m : view) {
std_msgs::String::ConstPtr msg = m.instantiate();
if (msg != nullptr && m.getTopic() == "/my_topic") {
// 打印消息内容
ROS_INFO("Message: %s", msg->data.c_str());
}
}
// 关闭bag文件
bag.close();
return 0;
}
import rosbag
import rospy
from std_msgs.msg import String
# 初始化ROS节点
rospy.init_node('rosbag_parser')
# 打开bag文件
bag = rosbag.Bag('/path/to/bagfile.bag')
# 遍历bag文件中的所有消息
for topic, msg, t in bag.read_messages():
# 检查消息类型和主题名称
if topic == '/my_topic' and isinstance(msg, String):
# 打印消息内容
rospy.loginfo("Message: %s", msg.data)
# 关闭bag文件
bag.close()
在这个示例中,我们使用了ROS提供的rospy.loginfo
函数来输出消息,它类似于Python的print
函数,但是它会将消息输出到ROS的日志系统,这有助于调试和记录机器人的运行情况。
python执行
rosrun <package_name> <filename.py>
C++与Python 解析ROS Bag文件两种方式的对比。
rosbag.Bag
读取 Bag 文件,C++ 中使用 rosbag::Bag
。bag.read_messages()
方法遍历 Bag 文件中的消息,C++ 中使用 rosbag::View
类和 C++11 的范围 for 循环来遍历消息。rosbag::MessageInstance::getTime()
方法来获取消息的时间戳。rosbag::MessageInstance::instantiate()
方法将消息实例化为指定的数据类型,如果无法实例化,则返回空指针。rosbag::MessageInstance::getTopic()
方法来获取消息所属的主题名称。rospy.loginfo()
函数来输出消息,C++ 中可以使用 ROS 的日志系统来输出消息,例如使用 ROS_INFO 宏来输出消息。使用 C++ 代码来解析 ROS Bag 文件,大致流程如下:
rosbag::Bag()
对象。rosbag::View()
对象并遍历 Bag 文件中的消息。rosbag::MessageInstance::instantiate()
方法将消息实例化为指定的数据类型,并使用 rosbag::MessageInstance::getTopic()
方法获取消息所属的主题名称和 rosbag::MessageInstance::getTime()
方法获取消息的时间戳。待补充。
D435i相机标定(不同标定方法总结)
深度相机D435i
Realsense d435i内参、外参标定
Realsense d435i驱动安装、配置及校准
古月居ROS入门21讲学习笔记
雷达相机标定(ROS)