学习ros推荐看官方教程,现在里面大部分都有翻译成中文的版本,多看看绝对没错
1. 数据的实时性
要保证从节点获取的数据是最新的,就必须设置Publisher的queue_size和Subscriber的queue_size都为1,如果数据过大还需要设置buff_size
具体参考博客ROS订阅最新的消息及queue_size和buff_size的理解
2. 名称
- 包内可执行程序名由包内CMakeLists.txt控制生成
add_executable( exe_name xxx.cpp)
- 在每个可执行程序的main里都会有定义节点的语句,这里的节点名字只是用于代码编译,和launch文件的节点名不是一回事
明确一下与节点相关术语的含义:
- Nodes:节点,一个节点即为一个可执行程序,它可以通过ROS与其他节点通信,另外,一个catkin程序包里可以有很多节点
- Messages:消息,消息是一种ROS数据类型,用于订阅或发布到一个话题,是一个载体。
- Topics:话题,节点可以向话题发布消息或可以向话题订阅消息,像通信中转站一样。
- Master:节点管理器,ROS名称服务。
- rosout:话题‘总管’,相当于std::cout
所有的节点发布都向话题/rosout 发布消息,该话题由同名的/rosout 节点订阅。这个话题的作用是用来生成各个节点的文本日志消息 - roscore:是在运行所有ROS程序前首先要运行的命令
我们往往将节点名和执行文件命名相同,但要注意节点名并不一定与对应可执行文件名称相同
3.中断程序
-
Ctrl-C 命令终止节点
使用这种方法时可能不会在节点管理器中注销该节点,因此会导致已终止的节点仍然在 rosnode 列表中。这虽然没有什么坏处,但可能会让用户对当前系统的行为感到困扰。此时可以使用下面的命令将节点从列表中删除:rosnode cleanup -
ctrl+c无法中断while循环
python利用rospy.is_shutdown()函数来判断当前是否关闭掉当前的进程
def main():
rospy.init_node('test', anonymous=True)
while not rospy.is_shutdown():
rospy.loginfo('gogogo')
if __name__ == '__main__':
main()
C++ 可以使用信号来监听
- ros::ok()接口:返回false,说明节点已经关闭。
- ros::isShuttingDown()接口:返回true,说明ros::shutdown()被调用,但是节点不一定结束
- 在ros::init()选项中,有一选项ros::init_options::NoSigintHandler,决定是否默认SIGINT处理函数,若不带此参数,则程序在收到SIGINT信号(ctrl+c)时,ros::ok()返回false,节点可以走关闭流程。若带此参数,需要自己设置SIGINT处理函数,以保证节点可以结束
#include "ros/ros.h"
#include <signal.h>
void MySigintHandler(int sig)
{
//这里主要进行退出前的数据保存、内存清理、告知其他节点等工作
ROS_INFO("shutting down!");
ros::shutdown();
}
int main(int argc, char** argv){
ros::init(argc, argv, "test");
signal(SIGINT, MySigintHandler);
ros::Rate loop_rate(1);
int sec = 0;
while(ros::ok() && sec++ < 5){
loop_rate.sleep();
ROS_INFO("ROS is ok!");
ros::spinOnce();
}
ROS_INFO("ROS bey!");
}
4.运行
运行ros节点一般有两种方法:
- 使用rosrun,在设置完环境变量后,可以使用包名来直接运行一个包内的节点。
$rosrun [package_name] [node_name]
注意:这种方法需要新打开一个终端 运行$roscore
- 使用roslaunch
$roslaunch [package] [fliename.launch]
launch是个文件,用launch文件来运行程序相对于rosrun的优点有两个:
- 可以向程序传参,常配合yaml配置参数
- 可以同时运行多个节点
使用参考launch和yaml使用
5.常用命令
- 获得话题列表 rostopic list,这个列表列举的话题和 rqt_graph 中展示的话题应该是一样的。
- 打印消息内容: rostopic echo [topic-name]
- 测量发布频率: rostopic hz [topic-name],带宽rostopic bw [topic-name]
- 查看话题: rostopic info [topic-name],可以获得消息类型等信息
- 查看消息类型: rosmsg show [message-type-name]
- 用命令发布消息: rostopic pub –r rate-in-hz [topic-name] [message-type] [message-content],
如:rostopic pub –r 1 /turtle1/cmd_vel geometry_msgs/Twist ’[2,0,0]’ ’[0,0,0]’ - 问题检查: roswtf
- 参数查看: rosparam get /run_id 查看 run_id通过runid来查看日志消息
- 清除日志: rosclean check ,rosclean purge
6.有用但被忽略的指令:
- rosrun rqt_tf_tree 查看tf 树
- roscd [pkg_name] 转到包路径
- rosdep install [pkg_name] 安装包所有依赖
- rosls [pkg_name] 列出包里面的文件
- rostopic info [topic_name] 查询话题详细内容
- rosnode info [topic_name] 查询节点详细内容
- rostopic type [topic_name] 列出消息类型 eg:/cmd_vel
- rosmsg show [msg_name] 列出消息包含的具体变量
7. 数据类型
注意不同语言间发布和获取的数据注意类型的转换:
比如C++发布的uint和int在python上对应的都是int,如果msg定义的是int,传递负数会被自动转换的