4_Publieher的编程实现

4_Publisher的编程实现

我们前面讲解了如何创建工作空间和功能包,但是我们都仅仅只创建了一个空的工作空间和功能包,什么都没有实现

我们想要进一步为功能包添加功能,就不可避免的需要添加Publisher和Subscriber.

下面我们就将讲解Publisher和Subscriber的编程实现,我们同样,还是以小海龟仿真器为例,只不过这次我们将通过编程来实现让小海龟动起来,而非通过命令行工具


0.明确任务

我们前面所讲的Publisher和Subscriber本质上都是节点,因此我们下面要实现一个能够发布message的节点,即Publisher

我们之前讲到的话题模型具体在小海龟仿真器中具体的表现如下

Publisher就是我们之前启动的teleop_key节点,而Subscriber就是turtlesim节点

Topic就是/tirtle1/cmd_vel,其中的message我们前面见过,具体包含了线速度和角速度

在这里插入图片描述

我们想要编写自己的Publisher,那么首先Publisher需要向ROS Master注册,然后还要向/turtle1/cmd_vel发布指定格式的Message

1.创建功能包

因为节点是以功能包形式存在的,因此我们下面创建自己的功能包,随后我们在其中加入

首先必须要的三个依赖是roscpp, rospy, std_msgs

这里我们由于需要和turtlesim进行数据传输,因此我们还需要依赖turtlesim的接口

此外我们还需要发布指定格式的message,即geometry_msgs,所以我们还需要依赖这个接口

jack@ubuntu:~/myFirstRosProject/src$ catkin_create_pkg myturtle_velocity_publishernode_cpp roscpp rospy std_msgs geometry_msgs turtlesim

在这里插入图片描述

2.C++实现

在动手开始写之前,我们要明白我们用C++实现一个Publisher需要干的事.

上面说到Publisher本质上还是一个节点,而节点都是以功能包的形式出现的,因此我们实际上就是编写一个功能包,而这个功能包只有一个Publisher,因此我们编写完之后需要去编译,而编译则要求我们修改CMakeLists中的内容

因此我们使用C++实现一个Publisher分两三,第一步编写代码,第二步修改CmakeLists中的内容,第三步进行编译,最后验证下我们自己写的Node能不能用

1.编写代码

  1. 打开当前目录的工作空间
    这里用Vscode进行编写,具体如何使用VScode搭建ROS开发环境未来我会写一篇笔记记录

    jack@ubuntu:~/myFirstRosProject/src$ code 				  myturtle_velocity_publishernode_cpp/
    

    左边打开的文件夹就是我们正在编写的Node的工作空间,接下来我们在src新建一个c++文件
    在这里插入图片描述

  2. 在当前Node的src目录下新建cpp代码文件,进行编写
    在这里插入图片描述

  3. 快乐的进行编写

    注释里解释了每一句的意思

    我们编写一个ROS节点的流程如下:

    1. 初始化ros节点 & 在ROS Master中注册节点信息
      对应这一句ros::init(argc,argv,"my_velocity_publisher_cpp")
      其中argc和argv是系统变量,表示用户运行时传入的参数个数,argv是所有传入参数的列表,"my_velocity_publisher_cpp"是我们自定义的节点名,
      需要注意的是,ros中节点的命名规则是小写字母/下划线/数字的组合,不建议带大写字母
      这个接口既初始化节点,又进行了注册

    2. 创建发布者

      对应这句话ros::Publisher turtleVelocityPublihser_cpp=n.advertise<geometry_msgs::Twist> ("/turtle1/cmd_vel",10)
      其中我们要指出发布的消息类型,发布的话题名和消息的队列长度

    3. 发布数据
      对应这句话turtleVelocityPublihser_cpp.publish(velocity_msg)

    4. 向命令行输出信息
      对应这句话
      ROS_INFO("Publish the velocity [%0.2f m/s, %0.2f rad/s]\n\t\t Info from Jack",velocity_msg.linear.x,velocity_msg.angular.z);

    /*
    *   This is a node created by Jack Wang to practice ROS publisher
    */
    
    // Include head files
    #include <ros/ros.h>
    #include <geometry_msgs/Twist.h>
    
    // Receive system variable
    // argc is the number of system variable, ** argv is the list of all the system variables
    int main(int argc, char ** argv){
    
        // Initialize ROS node
        // argc,argv,name of the node
        ros::init(argc,argv,"my_velocity_publisher_cpp");
    
        // Create node handle
        ros::NodeHandle n;
    
        // Create a ros publisher which publishes topic named /turtle1/cmd_vel
        // and the type of message it sends is geometry_msgs::Twist
        // max length of the message quene is 10
        ros::Publisher turtleVelocityPublihser_cpp=n.advertise<geometry_msgs::Twist>
            ("/turtle1/cmd_vel",10);
        
        // Set loop frequency to 10
        ros::Rate loop_rate(10);
    
        // Things to do in while loop
        while (ros::ok())
        {
            // Initialize geometry_msgs::Twist message
            geometry_msgs::Twist velocity_msg;
    
            // Set the message
            velocity_msg.angular.z=0.2;   // Set the angular velocity to 0.2 rad/s
            velocity_msg.linear.x=0.5;    // Set the linear velocity to 0.5 m/s
    
            // Publish the message
            turtleVelocityPublihser_cpp.publish(velocity_msg);
    
            // Print info on the terminal
            ROS_INFO("Publish the velocity [%0.2f m/s, %0.2f rad/s]\n\t\t Info from Jack",
                velocity_msg.linear.x,velocity_msg.angular.z
            );
    
            // Delay as setting frequency
            loop_rate.sleep();
        }
        return 0;
    }
    

2.修改Cmakelists中的内容

前面讲过CmakeLists使用了简单的语言描述了该如何对一个项目进行编译

我们这里主要是设置catkin编译这个包的时候会编译我们刚刚添加的文件

所以主要有两点,第一指定编译我们刚才新增的文件,第二指定该文件的依赖库

  1. 打开该node的CmakeLists

    在这里插入图片描述

  2. 在指定位置添加如下两行

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

    第一句表明需要编译的文件和编译后的可执行文件名
    第二句表明需要添加的库文件

    在这里插入图片描述

3.编译

接下来我们回到工作空间的根目录,使用catkin_make进行编译

jack@ubuntu:~/myFirstRosProject$ catkin_make

在这里插入图片描述

4.运行编写的node

上面我们自己创建了一个功能包,这个功能包中只有一个node

接下来我们将运行所编写的node

具体分为两步,第一步添加环境变量,使得Tab键能够补全自己编写的包,第二步就是运行

  1. 添加环境变量
    注意这个环境变量仅在当前运行过下面命令的命令行生效

    jack@ubuntu:~/myFirstRosProject$ source ./devel/setup.bash 
    

    在这里插入图片描述

  2. 运行自己的包
    和运行小海龟仿真器一样,我们首先启动ros master,然后在使用rosrun命令运行自己的包即可

    在这里插入图片描述

通过上面的操作,我们最终得知一个node实际上就是一个可执行文件,我们运行这个node实际上就是运行这个可执行文件

而就像上面turtlesim_node和我们的my_velocity_publisher_cpp之间会有数据(即geometry_msgs::Twist)的传输,因此节点之间数据的传输可以类比于进程之间的通信

此外,我们运行的my_velocity_publisher_cpp最终的可执行文件的位置在./devel/lib/包名这个文件夹下

在这里插入图片描述

3.Python实现

Python由于是脚本语言,因此不需要像上面使用C++来编写node一样修改CmakeLists的内容然后编译

但是我们具体在代码中两者实际上是很像的,并且编写运行流程也很像,只是直接添加环境变量并运行即可

1.编写代码

代码的流程和上面C++版本的代码流程是一样的,同样我们需要创建包,一般来说,我们正常开发一个软件包的时候,可能会有很多节点

而有的节点是C++写得,有些节点是Python写得,这个时候我们会在创建的包下再新建一个script文件夹,所有用Python写得节点都放在里面

而所有的C++写得节点放在src中,写好之后修改当前包的CmakeLists文件即可

在这里插入图片描述

  1. 打开文件夹并创建Python文件

    jack@ubuntu:~/myFirstRosProject/src/myturtle_velocity_publishernode_cpp$ code scripts/myVelocityPublisherNode.py
    

    在这里插入图片描述

  2. 快乐的编写代码

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    # Importing libraries
    import rospy
    from geometry_msgs.msg import Twist
    
    
    # Encapsulate the function
    def myVelocityPublisher():
    
        # Initialize ros node
        rospy.init_node("my_velocity_publisher_py",anonymous=True)
    
        # Create a publisher
        turtle_vel_pub = rospy.Publisher("/turtle1/cmd_vel",Twist,queue_size=10)
    
        # Set loop rate
        rate = rospy.Rate(10)
    
        while not rospy.is_shutdown():
            velocity_msgs=Twist()
            velocity_msgs.angular.z=0.2
            velocity_msgs.linear.x=0.5
    
            turtle_vel_pub.publish(velocity_msgs)
            rospy.loginfo("Publish the velocity [%0.2f m/s, %0.2f rad/s]\n\t\t Info from Jack",\
                velocity_msgs.linear.x,velocity_msgs.angular.z)
    
            rate.sleep()
    
    
    # Main program
    if __name__=="__main__":
        try:
            myVelocityPublisher()
        except rospy.ROSInitException:
            print("my_velocity_publisher_py is terminated !")
    

    在这里插入图片描述

2.运行代码

我们完成编辑后调用Python解释器运行即可,或者赋予可执行权限后运行

  1. 赋予可执行权限

    使用如下命令添加可执行权限

    jack@ubuntu:~/myFirstRosProject/src/myturtle_velocity_publishernode_cpp/scripts$ chmod u+x myVelocityPublisherNode.py 
    

    在这里插入图片描述

  2. 添加环境变量
    和C++编译后的结果一样,我们先启动ros master,然后在rosrun节点即可,但是需要注意的是,我们直接写的脚本也需要添加环境变量,这样才能用Tab补全

    jack@ubuntu:~$ source myFirstRosProject/devel/setup.bash
    

    在这里插入图片描述

  3. rosrun运行即可

    jack@ubuntu:~$ rosrun myturtle_velocity_publishernode_cpp myVelocityPublisherNode.py 
    

    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值