一个节点如何同时实现订阅者和客户端的功能

系列文章目录

留空



前言

自用


一、遇到错误

假设有一个"王五"节点,他既是某本小说话题的订阅者又是卖书的服务端,该如何同时实现两个功能

起初想把这两个功能分成两个类ReadersSellServer

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

class Readers : public rclcpp::Node
{
    public:
        Readers(std::string name) : Node(name)
        {
            RCLCPP_INFO(this->get_logger(),"读者节点%s已启动",name.c_str());

};

class SellServer : public rclcpp::Node
{
    public:
        SellServer(std::string name) : Node(name)
        {
            RCLCPP_INFO(this->get_logger(),"卖书客户端%s已启动",name.c_str());

        }

};

int main(int argc,char** argv)
{
    rclcpp::init(argc,argv);
    auto Readernode = std::make_shared<Readers>("wang5");
    auto Servernode = std::make_shared<SellServer>("wang5");
    rclcpp::spin(Readernode);
    rclcpp::spin(Servernode);
    rclcpp::shutdown();
    return 0;
}

运行节点,出现警告
在这里插入图片描述
警告信息提示了“Publisher already registered for provided node name”这个问题,意味着在节点名上已经注册了一个发布者。这通常是因为有多个节点使用相同的名称导致的。这是ROS2认为我们创建了两个节点,一个是Readers节点,另一个是SellServer节点,它们都使用了相同的名称“wang5”。

二、解决方法1

为了解决这个问题,我们可以将两个功能合并到同一个类中。

#include "rclcpp/rclcpp.hpp"
//(1)导入订阅的话题接口类型
#include "std_msgs/msg/string.hpp"

class ReadersAndSellServer : public rclcpp::Node
{
    public:
        ReadersAndSellServer(std::string name) : Node(name)
        {
            RCLCPP_INFO(this->get_logger(),"读者节点%s已启动",name.c_str());
            RCLCPP_INFO(this->get_logger(),"卖书客户端%s已启动",name.c_str());
        }         
};

int main(int argc,char** argv)
{
    rclcpp::init(argc,argv);
    auto node = std::make_shared<ReadersAndSellServer>("wang5");
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

重新编译运行,警告消除。
在这里插入图片描述

三、解决方法2

如果想分成两个类来编写,那只能将它分为两个节点,分别运行

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

class Readers : public rclcpp::Node
{
public:
    Readers(std::string name) : Node(name)
    {
        RCLCPP_INFO(this->get_logger(), "读者节点%s已启动", name.c_str());
    }

};

class SellServer : public rclcpp::Node
{
public:
    SellServer(std::string name) : Node(name)
    {
        RCLCPP_INFO(this->get_logger(), "卖书服务端节点%s已启动", name.c_str());
    }
};

int main(int argc, char **argv)
{
    rclcpp::init(argc, argv);
    auto Readernode = std::make_shared<Readers>("Readernode_wang5");
    auto SellServer = std::make_shared<SellServer>("SellServer_wang5");

    rclcpp::spin(Readernode_wang5);
    rclcpp::spin(SellServer_wang5);

    rclcpp::shutdown();
    return 0;
}

比较麻烦,这里就不试了。


总结

自用

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 Python 和 ROS Kinetic 实现节点代码,前提是已经安装好 ROS Kinetic 和 turtlesim 包: ```python #!/usr/bin/env python import rospy from geometry_msgs.msg import Twist from turtlesim.msg import Pose from turtlesim.srv import Spawn def spawn_turtle(): rospy.wait_for_service('spawn') try: spawn = rospy.ServiceProxy('spawn', Spawn) spawn(5, 5, 0, 'turtle2') except rospy.ServiceException as e: print("Service call failed: %s"%e) def pose_callback(data): rospy.loginfo("Turtle2 pose - x: %s, y: %s, theta: %s", data.x, data.y, data.theta) def main(): rospy.init_node('turtle_controller') spawn_turtle() pub = rospy.Publisher('turtle2/cmd_vel', Twist, queue_size=10) sub = rospy.Subscriber('turtle2/pose', Pose, pose_callback) rate = rospy.Rate(10) # 10Hz while not rospy.is_shutdown(): twist = Twist() twist.linear.x = 1.0 # 设置线速度为1m/s twist.angular.z = 1.0 # 设置角速度为1rad/s pub.publish(twist) rate.sleep() if __name__ == '__main__': try: main() except rospy.ROSInterruptException: pass ``` 代码解析: 1. 导入需要使用的 ROS 包和消息类型 2. 定义一个函数 `spawn_turtle()` 来生成一只名为 "turtle2" 的海龟,并将其放置在 (5,5) 的位置上 3. 定义一个回调函数 `pose_callback()` 来接收并处理海龟的位姿信息 4. 在 `main()` 函数中,初始化 ROS 节点并调用 `spawn_turtle()` 函数来生成海龟 5. 创建一个发布者 `pub`,用于发布海龟速度指令到 `turtle2/cmd_vel` 主题上 6. 创建一个订阅者 `sub`,用于订阅海龟的位姿信息从 `turtle2/pose` 主题上 7. 设置循环频率为 10Hz,使用 `Twist` 消息类型来控制海龟进行圆周运动 8. 在循环内部,发布海龟速度指令并周期打印海龟的实时位姿信息 运行节点: 1. 打开一个终端,启动 ROS Master: ``` roscore ``` 2. 打开一个新的终端,运行 turtlesim: ``` rosrun turtlesim turtlesim_node ``` 3. 打开一个新的终端,运行节点: ``` rosrun my_turtle turtle_controller.py ``` 4. 观察海龟在 `turtlesim` 窗口中进行圆周运动,并在终端中周期打印出海龟的实时位姿信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值