ROS 详细讲解通过键盘控制小海龟运动来实现话题发布者Publisher与订阅者Sbuscriber

// linear线性的 angular角度的
//%0.2f打印geometry_msgs::Twist类型
// %s打印std_msgs::String类型

发布者Publisher与订阅者Sbuscriber

// linear线性的 angular角度的
%0.2f打印geometry_msgs::Twist类型

第一步启动小海龟及其键盘控制

启动小海龟及其键盘控制

$ roscore
$ rosrun turtlesim turtlesim_node 
$ rosrun turtlesim turtle_teleop_key 

第二步查看rosnode节点直接的关系

查看rosnode节点直接的关系

$ rqt_graph

rqt_graph
由于箭头是单向的,所以消息传播是单向的,由图像可知,/teleop_turtle为发布者Publisher,用于键盘发布指令,/turtlesim为订阅者Subscriber,用于定义指令,两节点的通信管道为/turtle/cmd_vel,只要实现一个发布者在通信管道/turtle/cmd_vel发送相应信息都会被订阅者订阅,下面将介绍如何查看发布消息的类型

第三步查看发布消息的列表

查看发布消息的列表

$ rosnode list 

查看发布消息的类型
我们可以看到发布者/teleop_turtle

然后输入下列指令

$ rosnode info /teleop_turtle 

然后输入下列指令我们可以看到

Publications: 
 * /rosout [rosgraph_msgs/Log]
 * /turtle1/cmd_vel [geometry_msgs/Twist]

其中 /turtle1/cmd_vel [geometry_msgs/Twist]是我们要的信息
以 /turtle1/cmd_vel消息管道,以geometry_msgs::Twist传递消息

Services: 
 * /teleop_turtle/get_loggers
 * /teleop_turtle/set_logger_level

这里面可以看到/teleop_turtle,该为发布者的节点名

第四步创建发布者Publishser

创建发布者Publishser

//以 /turtle1/cmd_vel消息管道,以geometry_msgs::Twist传递消息
// /teleop_turtle,该为发布者的节点名
// linear线性的  angular角度的
//%0.2f打印geometry_msgs::Twist类型
#include "ros/ros.h"
#include "geometry_msgs/Twist.h"

int main(int argc, char **argv){
    //初始化ros节点
    ros::init(argc, argv, "Publisher");//也可以将Publisher改为/teleop_turtle
    //创建节点句柄
    ros::NodeHandle node;

    //创建一个发布者Publisher,消息管道/turtle1/cmd_vel,消息类型geometry_msgs::Twist
    ros::Publisher pub = node.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",1000);

    //设置一个循环频率每秒5次
    ros::Rate loop_rate(5);

    //计数发布次数
    int count = 0;
    while (ros::ok()){
        //初始化消息类型geometry_msgs::Twist
        geometry_msgs::Twist msg;
        msg.linear.x = 5;
        msg.angular.z = 1;

        //发布消息
        pub.publish(msg);

        //发布成功在该节点终端显示
        //已成功发布第%d条消息,发布的内容为%0.2f打印geometry_msgs::Twist类型
        ROS_INFO("Successfully published message %d with:[msg.linear.x = %0.2f m/s , msg.angular.z = %.2f rad/s]"
                ,count , msg.linear.x, msg.angular.z);

        loop_rate.sleep();
        ++count;
    }
    return 0;
}

发布者运行结果:

创建Publishser

第五步创建订阅者Sbuscriber

创建订阅者Sbuscriber
创建订阅者由图像可知,消息管道为/turtle1/cmd_vel
消息类型为geometry_msgs::Twist

 * /turtlesim/get_loggers
 * /turtlesim/set_logger_level

节点名为/turtlesim

/*
 * 消息管道为/turtle1/cmd_vel 消息类型为geometry_msgs::Twist
 * 节点名为  /turtlesim
 */

#include "ros/ros.h"
#include "geometry_msgs/Twist.h"

void cmdCallBack(const geometry_msgs::Twist& msg){
    //将收到的消息打印出来
    ROS_INFO("The message I received was:[x=%0.2f m/s, z=%0.2f rad/s]"
            , msg.linear.x, msg.angular.z);
}

int main(int argc, char **argv){
    //初始化ros节点
    ros::init(argc, argv, "Subscriber");//节点名也可以写成/turtlesim
    //创建节点句柄
    ros::NodeHandle node;

    //创建一个Subscriber,消息管道为/turtle1/cmd_vel,注册回调函数为cmdCallBack
    ros::Subscriber sub = node.subscribe("/turtle1/cmd_vel", 1000, cmdCallBack);
    ros::spin();

    return 0;
}

订阅者运行结果:

运行结果

扩展:发布hello_n_word并订阅

通过上面的内容实现,不通过小海龟信息管道,自己定义一个,来实现发布者发布hello_n_word ,n为数字并打印在自己终端,订阅者接收并打印出该消息。

第一步:模拟发布者

//以 /talker消息管道,以std_msgs::String传递消息
// /Publisher,该为发布者的节点名
// %s打印std_msgs::String类型

#include "sstream"
#include "ros/ros.h"
#include "std_msgs/String.h"

int main(int argc, char **argv){
    //初始化ros节点
    ros::init(argc, argv, "Publisher");
    //创建节点句柄
    ros::NodeHandle node;

    //创建一个发布者Publisher,消息管道/turtle1/cmd_vel,消息类型std_msgs::String
    ros::Publisher pub = node.advertise<std_msgs::String>("/talker",1000);

    //设置一个循环频率每秒5次
    ros::Rate loop_rate(5);

    //计数发布次数
    int count = 0;
    while (ros::ok()){
        ++count;
        //初始化消息类型std_msgs::String
        std_msgs::String msg;
        std::stringstream ss;
        ss<< "hello_"<< ++count<<"_world";
        msg.data = ss.str();
        //发布消息
        pub.publish(msg);

        //发布成功在该节点终端显示
        //已成功发布第%d条消息,发布的内容为%s打印std_msgs::String类型
        ROS_INFO("Successfully published message with:[%s]",msg.data.c_str());

        loop_rate.sleep();

    }
    return 0;
}

第二步:模拟订阅者

/*
 * 消息管道为/talker 消息类型为std_msgs::String
 * 节点名为  /Subscriber
 */

#include "sstream"
#include "ros/ros.h"
#include "std_msgs/String.h"

void cmdCallBack(const std_msgs::String::ConstPtr& msg){
    //将收到的消息打印出来
    ROS_INFO("The message I received was:[%s]",msg->data.c_str());
}

int main(int argc, char **argv){
    //初始化ros节点
    ros::init(argc, argv, "Subscriber");
    //创建节点句柄
    ros::NodeHandle node;

    //创建一个Subscriber,消息管道为/turtle1/cmd_vel,注册回调函数为cmdCallBack
    ros::Subscriber sub = node.subscribe("/talker", 1000, cmdCallBack);
    ros::spin();

    return 0;
}

运行结果:

运行结果
运行结果

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
利用ROS(机器人操作系统)实现手势控制小海龟运动是通过结合ROS的三个核心概念:发布者Publisher)、订阅者(Subscriber)和服务(Service)来实现的。 首先,我们需要通过ROS发布者订阅者模式,将与手势识别相连的传感器发布到一个特定的主题上。在这个情况下,传感器将捕捉到手势的运动,并将其解释为特定的ROS消息。例如,当手势为“向前推进”时,发布者将将消息发布到主题“/cmd_vel”。 其次,我们将创建一个ROS订阅者节点,用于接收发布者节点发送的消息。该节点将通过订阅主题“/cmd_vel”来获取手势传感器发布的指令。一旦接收到指令,该节点将相应地解释并发送小海龟运动指令到主题“/turtle1/cmd_vel”,以使其向所需的方向移动。 最后,我们可以创建一个服务节点,它可以监听特定的服务求,并执行相应的任务。例如,我们可以通过创建一个名为“/turtle_control”的服务节点,来接收特定手势的求,例如“停止”、“左转”、“右转”等。当接收到这些求时,服务节点将向小海龟发送相应的运动指令。 通过结合这三个核心概念,我们可以实现利用ROS实现手势控制小海龟运动的功能。总体而言,这种方法可以使小海龟通过手势控制来移动,从而增加了机器人控制的交互性和灵活性。同时,通过ROS的发布订阅模式和服务,我们可以高效地管理和处理海龟运动的指令,从而更好地控制机器人的运动

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值