(三)工作空间与功能包、Publisher、Subscriber

本文介绍了ROS工作空间的创建与功能包的建立,包括C++和Python版本的Publisher和Subscriber节点的编程实现。详细讲解了创建工作空间、功能包的步骤,以及编译和设置环境变量的方法。同时,通过Turtlesim模拟器展示了发布者和订阅者的功能,提供了C++和Python两种语言的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、创建工作空间与功能包

1、工作空间

2、创建功能包

3、编译新的功能包

4、 环境变量

5、功能包中的两个重要文件

二、发布者Publisher的编程实现

(一)C++版本

(二)Python版本

三、订阅者Subscriber的编程实现

(一)C++版本

(二)Python版本


一、创建工作空间与功能包

1、工作空间

工作空间(workspace)是一个存放工程开发相关文件的文件夹。

• src:代码空间(Source Space)
• build:编译空间(Build Space)
• devel:开发空间(Development Space)
• install:安装空间(Install Space)

创建工作空间:

$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ catkin_init_workspace

 编译工作空间:要编译工作空间,先要回到工作空间的根目录。

cd ~/catkin_ws
catkin_make

 编译过程可能会出现的报错:

   "对于ROS Melodic和早期版本的Python 3用户:注意,如果你从源代码构建ROS来实现Python 3的兼容性,并适当地设置您的系统(即:安装所有必需的ROS Python包的Python 3版本,例如catkin)

解决办法:在首次建立工作区后,在这个干净的catkin工作区中的第一次catkin_make命令

catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3

  然后再次进行编译即可。

 可以看到build和devel两个新文件夹,devel存放了编译完成的内容。目前没有生成install文件夹,要生成install文件夹,输入catkin_make install

 install中生成了可执行文件。这样一个空的工作空间创建好了,并且空的代码空间(功能包)编译完成。

2、创建功能包

 功能包是放置ROS源码的最小单元。同一个工作空间下,不允许存在同名功能包;不同工作空间下,允许存在同名功能包。

指令格式:catkin_create_pkg <package_name> [depend1] [depend2] [depend3]
 <package_name>为包名,[depend]为依赖,即指明编译的时候需要ROS中的其他功能包,如需要调用python、C++库,就要指明rospy、roscpp。

cd ~/catkin_ws/src
catkin_create_pkg test_pkg std_msgs rospy roscpp

3、编译新的功能包

 回到工作空间根目录,再编译一下。

cd ~/catkin_ws
catkin_make

4、 环境变量

设置环境变量,检查环境变量

source ~/catkin_ws/devel/setup.bash
echo $ROS_PACKAGE_PATH

5、功能包中的两个重要文件

 package.xml,使用xml语言描述功能包相关的信息。

 CMakeLists.txt,描述功能包里的编译规则,使用CMake语法。

二、发布者Publisher的编程实现

 ROS通信模式之一的Topic模式,其使用“发布订阅”的方式来通信。

使用ROS Master管理节点。有两个主要节点:Publisher,名为Turtle Velocity(即海龟的速度)、
Subscriber,即海龟仿真器节点 /turtlesim。

Publisher(Turtle Velocity),发布Message(即海龟的速度信息,以geometry_msgs::Twist的数据结构,包括线速度和角速度),通过Topic(/turtle1/cmd_vel)总线管道,将数据传输给Subscriber。Subscriber订阅得到的速度信息,来控制海龟发生运动。

“/turtle1/cmd_vel”这个topic是海归仿真器节点/turtlesim下自带的topic,可直接拿来用。

(一)C++版本

1、创建功能包

上面我们已经创建了工作空间,所以现在只需要在src文件夹创建一个新的功能包learning topic。

cd ~/catkin_ws/src
catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim

2、创建Publisher代码(C++版本)

 如何实现一个发布者:

  • 初始化ROS节点;
  • 向ROS Master注册节点信息,包括发布的话题名和话题中的消息类型;
  • 创建消息数据;
  • 按照一定频率循环发布消息。

 需要在src里创建C++的代码文件以输入代码:

/**
 * 该例程将发布turtle1/cmd_vel话题,消息类型geometry_msgs::Twist
 */

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>

int main(int argc, char **argv)
{
        // ROS节点初始化
        ros::init(argc, argv, "velocity_publisher");

        // 创建节点句柄
        ros::NodeHandle n;

        // 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
        ros::Publisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);

        // 设置循环的频率
        ros::Rate loop_rate(10);

        int count = 0;
        while (ros::ok())
        {
            // 初始化geometry_msgs::Twist类型的消息
                geometry_msgs::Twist vel_msg;
                vel_msg.linear.x = 0.5;
                vel_msg.angular.z = 0.2;

            // 发布消息
                turtle_vel_pub.publish(vel_msg);
                ROS_INFO("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]",
                                vel_msg.linear.x, vel_msg.angular.z);

            // 按照循环频率延时
            loop_rate.sleep();
        }

        return 0;
}
~          

3、编译代码(C++版本)

 配置Publisher代码编译规则。首先需要配置CMakeLists.txt中的编译规则:

 将下列代码拷贝至CMakeLists.txt中:

add_executable(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})

 执行编译回到工作空间目录,执行编译:

cd ~/catkin_ws
catkin_make

 由于之后每次运行这个程序都需要source一下devel/setup.bash,建议将source devel/setup.bash放入环境变量.bashrc中。可以打开主目录 按下Crtl+h 显示隐藏文件,双击打开bashrc文件:

4、运行

 分别打开终端运行:

roscore
rosrun turtlesim turtlesim_node
rosrun learning_topic velocity_publisher

 海龟就按照我们之前代码中设定的线速度和角速度画圆啦!编译完成的程序velocity_publisher是放在devel/lib/topic目录下的:

(二)Python版本

 Python的步骤中,在“配置编译规则”和“编译并执行”与C++版本有所不同。

 终端使用python3命令可调用python:

1、创建功能包

 在C++版本中已经创建了,无需重复操作。

2、创建Publisher代码(Python版本)

 python代码文件是放在功能包文件夹下的scripts目录下的,我们需要新建一个scripts文件夹。

 编写代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将发布turtle1/cmd_vel话题,消息类型geometry_msgs::Twist

import rospy
from geometry_msgs.msg import Twist

def velocity_publisher():
	# ROS节点初始化
    rospy.init_node('velocity_publisher', anonymous=True)

	# 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
    turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)

	#设置循环的频率
    rate = rospy.Rate(10) 

    while not rospy.is_shutdown():
		# 初始化geometry_msgs::Twist类型的消息
        vel_msg = Twist()
        vel_msg.linear.x = 0.5
        vel_msg.angular.z = 0.2

		# 发布消息
        turtle_vel_pub.publish(vel_msg)
    	rospy.loginfo("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]", 
				vel_msg.linear.x, vel_msg.angular.z)

		# 按照循环频率延时
        rate.sleep()

if __name__ == '__main__':
    try:
        velocity_publisher()
    except rospy.ROSInterruptException:
        pass

注意:右击文件→属性,打开执行权限

3、编译代码(Python版本)

 配置一下CMakeLists.txt(目录:/home/yang/catkin_ws/src/learning_topic)中的编译规则:将文件中的install这段取消注释,并将默认的my_python_script改成velocity_publisher.py

  回到工作空间目录,执行编译:

cd ~/catkin_ws
catkin_make

 source 一下 setup.bash。(在C++版本中有相关描述)

4、运行

分别打开终端,依次运行:

roscore
rosrun turtlesim turtlesim_node
rosrun learning_topic velocity_publisher.py

如果出现以下报错:

则说明 ,这一步没有处理。

三、订阅者Subscriber的编程实现

 ROS Master管理两个主要节点:Publisher,海龟仿真器/turtlesim、Subscriber,名为Pose Listener。

 海龟仿真器turtlesim为Publisher,发布Message(传输的是动作信息,以数据结构 turtlesim::Pose发布),通过Topic(/turtle1/pose)的管道,将数据传输给Subscriber。Subscriber订阅得到的数据,获得Pose信息。

 “/turtle1/pose”这个topic是海归仿真器节点/turtlesim下自带的topic,直接拿来用。

 如何实现一个订阅者:

  • 初始化ROS节点;
  • 订阅需要的话题;
  • 循环等待话题消息,接收到消息后进入回调函数;
  • 在回调函数中完成消息处理。

创建功能包:上述操作中,已经创建工作空间和功能包learning topic,无需重复操作,后续操作就直接跳过这一步啦~

(一)C++版本

1、创建Subscriber代码(C++版本)

/**
 * 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose
 */

#include <ros/ros.h>
#include "turtlesim/Pose.h"

// 接收到订阅的消息后,会进入消息回调函数
void poseCallback(const turtlesim::Pose::ConstPtr& msg)
{
    // 将接收到的消息打印出来
    ROS_INFO("Turtle pose: x:%0.6f, y:%0.6f", msg->x, msg->y);
}

int main(int argc, char **argv)
{
    // 初始化ROS节点
    ros::init(argc, argv, "pose_subscriber");

    // 创建节点句柄
    ros::NodeHandle n;

    // 创建一个Subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
    ros::Subscriber pose_sub = n.subscribe("/turtle1/pose", 10, poseCallback);

    // 循环等待回调函数
    ros::spin();

    return 0;
}

2、编译(C++版本)

 配置代码编译规则,配置CMakeLists.txt中的编译规则:

  • 设置需要编译的代码和生成的可执行文件
  • 设置链接库

将下列代码拷贝至CMakeLists.txt中,直接加到之前Publisher那两行下面即可。

add_executable(person_subscriber src/person_subscriber.cpp)
target_link_libraries(person_subscriber ${catkin_LIBRARIES})
add_dependencies(person_subscriber ${PROJECT_NAME}_generate_messages_cpp)

  回到工作空间目录,执行编译:

cd ~/catkin_ws
catkin_make

source devel/setup.bash

3、运行

分别打开终端运行:

roscore
rosrun turtlesim turtlesim_node
rosrun learning_topic pose_subscriber

 此刻海龟的位置就会一直被pose_subscriber监听,由于海龟没有行动,所以x、y坐标值是不会有所改变。若要让海龟动起来,再建立一个之前用过的键盘控制节点:

rosrun turtlesim turtle_teleop_key

(二)Python版本

1、创建Subscriber代码(Python版本)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose

import rospy
from turtlesim.msg import Pose

def poseCallback(msg):
    rospy.loginfo("Turtle pose: x:%0.6f, y:%0.6f", msg.x, msg.y)

def pose_subscriber():
	# ROS节点初始化
    rospy.init_node('pose_subscriber', anonymous=True)

	# 创建一个Subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
    rospy.Subscriber("/turtle1/pose", Pose, poseCallback)

	# 循环等待回调函数
    rospy.spin()

if __name__ == '__main__':
    pose_subscriber()

右击文件→属性,打开执行权限。

2、编译(Python版本)

 配置一下CMakeLists.txt中的编译规则:
之前已将文件中的install这段取消注释,并将默认的my_python_script改成了velocity_publisher.py。所以只需要再加上一个关于pose_subscriber.py的install方法:

 回到工作空间目录,执行编译:

cd ~/catkin_ws
catkin_make

 source 一下 setup.bash。

source devel/setup.bash

 3、运行

分别打开终端运行:

roscore
rosrun turtlesim turtlesim_node
rosrun learning_topic pose_subscriber.py

rosrun turtlesim turtle_teleop_key

我们可以查看系统当前计算图:

rqt_graph

  调到所有活动active节点/话题视图,可看到3个节点:键盘控制器节点/teleop_turtle 通过 /turtle/cmd_vel 传速度msg给海归仿真器节点/turtlesim,/turtlesim 通过 /turtle/pose 传位置msg给subscriber节点。

 /turtle/cmd_vel 和 /turtle/pose 两个topic都在turtle1海龟下面,因为海龟自身会发布速度和位置的msg给这两个topic。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值