ROS机械臂开发:从入门到实践---学习笔记(2)

第二章作业
第一题 练习ROS Tutorials教程
如图1.1所示,熟悉了tutorials中所使用的基本命令。
ROS机械臂开发:从入门到实践---学习笔记(2)_第1张图片
图1.1

1.1 使用catkin_make
在一个工作空间下:catkin_make
catkin_make install(可选,与devel功能类似)
编译完成后使用ls命令即可看到build、devel、src文件,如图1.2,工作空间结构如图1.3。
ROS机械臂开发:从入门到实践---学习笔记(2)_第2张图片
图1.2
ROS机械臂开发:从入门到实践---学习笔记(2)_第3张图片
图1.3

1.2 总结
ROS开发大致分为四个步骤:
1)创作工作空间:catkin_init_workspace
2)编译工作空间:cd~catkin_ws、catkin_make
3)设置环境变量:vim .bash.rc 在里面添加:
source home/ ( c o m p u t e r n a m e ) / c a t k i n w s / d e v e l / s e t u p . s h 4 ) 检 查 环 境 变 量 : (computer_name)/catkin_ws/devel/setup.sh 4)检查环境变量: (computername)/catkinws/devel/setup.sh4echo $ROS_PACKAGE_PATH
/home/amov/catkin_ws/src:/opt/ros/melodic/share
这就是我的设置工作空间的环境变量,也可以有效的进行二次开发(即将ROS自带的功能包部分功能替换成自己想要实现的功能),因为ROS在找的时候优先找排在前面的功能包。
ROS机械臂开发:从入门到实践---学习笔记(2)_第4张图片
图1.4 ROS开发流程图
创建功能包
catkin_creat_pkg [depend1]…[dependn]
注意:同一个工作空间下,不允许存在同名功能包;不同的工作空间下,允许存在同名的功能包。
第二题 建立工作空间,并编译本讲代码
如图2.1所示。
ROS机械臂开发:从入门到实践---学习笔记(2)_第5张图片

图2.1 编译完成

第三题 运行本讲代码中的话题、服务、动作、TF例程
3.1 话题
打开终端运行master,在运行rosrun learning_communication listener与rosrun learning_communication talker这两个节点。效果如图3.1所示。
ROS机械臂开发:从入门到实践---学习笔记(2)_第6张图片
图3.1 运行topic效果
3.2服务
打开终端运行master,在运行rosrun learning_communication client与rosrun learning_communication server这两个节点。效果如图3.2所示。
ROS机械臂开发:从入门到实践---学习笔记(2)_第7张图片
图3.2 运行service效果
3.3 动作
打开终端运行master,在运行rosrun learning_communication DoDishes_client与rosrun learning_communication DoDishes_server这两个节点。效果如图3.3所示。
ROS机械臂开发:从入门到实践---学习笔记(2)_第8张图片

图3.3 运行action效果
3.4 TF例程
打开终端运行master,在运行:
roslaunch learning_tf start_demo_with_listener.launch这个launch文件。效果如图3.4所示。
ROS机械臂开发:从入门到实践---学习笔记(2)_第9张图片

图3.4 运行TF例程效果
第四题 熟悉代码实现原理
4.1 Publisher节点的实现
ROS机械臂开发:从入门到实践---学习笔记(2)_第10张图片

图4.1 Publisher节点的实现
下面逐行剖析以上代码中Publisher几点的实现过程。
4.1.1 头文件部分
#include “ros/ros.h”
#include “std_msgs/String.h”
为了避免包含繁杂的ROS功能包头文件,ros/ros.h已经帮我们包含了大部分ROS中通用的头文件。节点会发布String类型的消息,所以需要先包含该消息类型的头文件String.h。该头文件根据String.msg的消息结构定义自动生成,我们也可以自定义消息结构,并生成所需要的头文件。
4.1.2 初始化部分
ros::init(argc, argv, “talker”);
初始化ROS节点。该初始化的init函数包含三个参数,前两个参数是命令行或launch文件的输入参数,可以用来完成命名重映射等功能;第三个参数定义了Publisher节点的名称,而且该名称在运行的ROS中必须是独一无二的,不允许同时存在相同名称的两个节点。
ros::NodeHandle n;
创建一个节点句柄,方便对节点资源的使用和管理。
ros::Publisher chatter_pub = n.advertise(“chatter”, 1000);
在ROS Master端注册一个Publisher,并告诉Publisher节点将会发布以chatter为话题名的String类型的消息。第二个参数表示消息发布队列的大小。
ros::Rate loop_rate(10);
设置循环频率,单位是Hz,这里设置的是10 Hz。当调用Rate::sleep()时,ROS节点会根据此处设置的频率休眠相应的时间,以保证循环维持一致的时间周期。
4.1.3 循环部分
int count = 0;
while (ros::ok())
进入节点的主循环,在节点未发生异常的情况将一直再循环中进行,一旦发生异常,ros::ok()就会返回false,跳出循环。
这里的异常情况主要包括:
(1)收到SIGING信号(Ctrl+C);
(2)被另外一个相同名称的节点提掉线;
(3)节点调用了关闭函数ros::shutdown();
(4)所有的ros::NodeHandles句柄被销毁。
std_msgs::String msg;
std::stringstream ss;
ss << “hello world " << count;
msg.data = ss.str();
初始化即将发布的消息。ROS中定义了很多通用的消息类型,这里我们使用了最为简单的String消息类型,该消息类型只有一个成员,即date,用来存储字符串数据。
chatter_pub.publish(msg);
发布封装完毕的消息msg。消息发布后,Master会查找订阅该话题的节点,并且帮助两个节点建立连接,完成消息的传输。
ROS_INFO(”%s", msg.data.c_str());
ROS_INFO类似于C/C++中的print/cout函数,用来打印日志信息。这里我们将发布的数据在本地打印,以确保发出的数据符合要求。
ros::spinOnce();
ros::spinOnce是用来处理节点订阅话题的所有回调函数。
注意:虽然目前的发布节点并没有订阅任何消息,spinOnce函数不是必须的,但是为了保证功能无误,建议所有的节点都默认加入该函数。
loop_rate.sleep();
现在Publisher一个周期的工作已经完成,可以让节点休息一段时间了,调用休眠函数,节点进入休眠状态。当然,节点不可能一直休眠下去,别忘了之前设置了10HZ的休眠时间,节点休眠100ms以后又会开始下一个周期的循环工作。
上面就是实现一个Publisher的所有流程,下面再来总结这个流程:
(1)初始化ROS节点
(2)向ROS Master注册节点信息,包括发布的话题名和话题中的消息类型
(3)定义消息内容
(4)按照一定频率循环发布消息
4.2 Subscriber节点的实现
ROS机械臂开发:从入门到实践---学习笔记(2)_第11张图片
图4.2 Subscriber节点的实现
下面剖析以上代码中Subscriber节点的实现过程。
4.2.1 回调函数部分
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
// 将接收到的消息打印出来
ROS_INFO(“I heard: [%s]”, msg->data.c_str());
}
回调函数是订阅节点接收消息的基础机制,当有消息到达时会自动以消息指针作为参数,再调用回调函数,完成对消息内容的处理。如上是一个简单的回调函数,用来接收Publisher发布的String消息,并将数据打印出来。
4.2.2 主函数部分
主函数中ROS节点初始化部分的代码与Publisher的相同,不再赘述。
ros::Subscriber sub = n.subscribe(“chatter”, 1000, chatterCallback);
订阅节点首先需要声明自己订阅的消息话题,该消息信息会在ROS Master中注册,以便帮助话题名称相同的发布者与订阅者两节点建立连接,完成数据传输。ros::NodeHandle.subscribe()用来创建一个Subscriber。第一个参数是消息话题;第二个参数是接收消息队列的大小;第三个参数是接收到话题消息后的回调函数。
ros::spin();
接着,节点将进入循环状态,当有消息到达时,会尽快调用函数完成的处理。ros::spin()在ros::ok()返回false时退出。
以上就是订阅节点的实现,下面总结实现Subscriber的简要流程。
(1)初始化ROS节点
(2)订阅所需要的话题
(3)循环等待话题消息,接收到消息后进入回调函数
(4)在回调函数中完成消息的处理

你可能感兴趣的:(ROS基本教程,linux,机器学习)