zoukankan      html  css  js  c++  java
  • ROS知识(20)----使用Master_API查询Master管理的节点话题服务内容

    在一些应用中会需要获取master的uri地址,发布的话题,订阅的话题,发布的服务,节点的信息等等。这些功能我们通常可一通过rosnode list, rosnode info, rostopic list, rostopic info, rosservice list和 rosservice info 等命令查询,而这些功能是怎么做到的呢? 这就需要用到Master_API进行查询,ROS官方使用了python来实现(在ros_comm包中),这里我们使用c++来实现这些查询的功能。

    1.实现

    参考[1]API,功能描述细节不累赘了,下面为实现的代码:

    #include "ros/ros.h"
    #include "std_msgs/String.h"
    #include <ros/master.h>
    #include <iostream>
    
    /*
     * Get the URI of the master.
     */
    bool getUri(std::string&uri) {
        XmlRpc::XmlRpcValue args, result, payload;
        args[0] = ros::this_node::getName();
    
        if (!ros::master::execute("getUri", args, result, payload, true)) {
            std::cout << "Failed!" << std::endl;
            return false;
        }
        std::cout << "----------Master URI----------" << std::endl;
        uri = std::string(payload);
        std::cout << std::string(payload) << std::endl;
    }
    
    /*
     * Get list of topics that can be subscribed to.
     * This does not return topics that have no publishers.
     * See getSystemState() to get more comprehensive list.
     * */
    bool getPublishedTopics(const std::string& subgraph,
            ros::master::V_TopicInfo& topics) {
        XmlRpc::XmlRpcValue args, result, payload;
        args[0] = ros::this_node::getName();
        args[1] = subgraph;
        if (!ros::master::execute("getPublishedTopics", args, result, payload,
                true)) {
            std::cout << "Failed!" << std::endl;
            return false;
        }
        topics.clear();
        std::cout << "----------PublishedTopics----------" << std::endl;
        std::cout << "published_topic_name 	 message_name" << std::endl;
        for (int i = 0; i < payload.size(); ++i) {
            topics.push_back(
                    ros::master::TopicInfo(std::string(payload[i][0]),
                            std::string(payload[i][1])));
            std::string v1 = std::string(payload[i][0]);
            std::string v2 = std::string(payload[i][1]);
            std::cout << v1.c_str() << "	" << v2.c_str() << std::endl;
        }
    
        return true;
    }
    
    /*
     * Retrieve list topic names and their types.
     * */
    bool getTopicTypes(ros::master::V_TopicInfo& topics) {
        XmlRpc::XmlRpcValue args, result, payload;
        args[0] = ros::this_node::getName();
    
        if (!ros::master::execute("getTopicTypes", args, result, payload, true)) {
            std::cout << "Failed!" << std::endl;
            return false;
        }
        topics.clear();
        std::cout << "----------TopicTypes----------" << std::endl;
        std::cout << "topic_name	 message_name" << std::endl;
        for (int i = 0; i < payload.size(); ++i) {
            topics.push_back(
                    ros::master::TopicInfo(std::string(payload[i][0]),
                            std::string(payload[i][1])));
            std::string v1 = std::string(payload[i][0]);
            std::string v2 = std::string(payload[i][1]);
            std::cout << v1.c_str() << "	" << v2.c_str() << std::endl;
        }
    
        return true;
    }
    
    /*
     * Get the XML-RPC URI of the node with the associated name/caller_id.
     * This API is for looking information about publishers and subscribers.
     * Use lookupService instead to lookup ROS-RPC URIs.
     */
    bool lookupNode(const std::string& node, std::string&uri) {
        XmlRpc::XmlRpcValue args, result, payload;
        args[0] = ros::this_node::getName();
        args[1] = node;
        if (!ros::master::execute("lookupNode", args, result, payload, true)) {
            std::cout << "Failed!" << std::endl;
            return false;
        }
        std::cout << "----------LookupedNode----------" << std::endl;
        uri = std::string(payload);
        std::cout << node << ":" << std::string(payload) << std::endl;
    }
    
    /*
     * Lookup all provider of a particular service.
     */
    bool lookupService(const std::string& service, std::string&uri) {
        XmlRpc::XmlRpcValue args, result, payload;
        args[0] = ros::this_node::getName();
        args[1] = service;
        if (!ros::master::execute("lookupService", args, result, payload, true)) {
            std::cout << "Failed!" << std::endl;
            return false;
        }
        std::cout << "----------LookupedService----------" << std::endl;
        uri = std::string(payload);
        std::cout << service << ":" << std::string(payload) << std::endl;
    }
    
    /*
     * Retrieve list representation of system state
     * (i.e. publishers, subscribers, and services).
     * */
    bool getSystemState() {
        XmlRpc::XmlRpcValue args, result, payload;
        args[0] = ros::this_node::getName();
        if (!ros::master::execute("getSystemState", args, result, payload, true)) {
            std::cout << "Failed!" << std::endl;
            return false;
        }
        std::cout << "----------SystemState----------" << std::endl;
    
        //publishers
        int t = 0;
        std::cout << "Published Topics:" << std::endl;
        for (int j = 0; j < payload[t].size(); ++j) {
            //topics
            std::cout << "    *" << std::string(payload[t][j][0]) << ":"
                    << std::endl;
            for (int k = 0; k < payload[t][j][1].size(); ++k) {
                //publisher
                std::cout << "        *" << std::string(payload[t][j][1][k])
                        << std::endl;
            }
        }
        t = 1;
        std::cout << "Subscribed Topics:" << std::endl;
        for (int j = 0; j < payload[t].size(); ++j) {
            //topics
            std::cout << "    *" << std::string(payload[t][j][0]) << ":"
                    << std::endl;
            for (int k = 0; k < payload[t][j][1].size(); ++k) {
                //publisher
                std::cout << "        *" << std::string(payload[t][j][1][k])
                        << std::endl;
            }
        }
    
        t = 2;
        std::cout << "Services:" << std::endl;
        for (int j = 0; j < payload[t].size(); ++j) {
            //topics
            std::cout << "    *" << std::string(payload[t][j][0]) << ":"
                    << std::endl;
            for (int k = 0; k < payload[t][j][1].size(); ++k) {
                //publisher
                std::cout << "        *" << std::string(payload[t][j][1][k])
                        << std::endl;
            }
        }
        return true;
    }
    
    int main(int argc, char **argv) {
        ros::init(argc, argv, "listener");
        ros::NodeHandle n;
    
        //get master uri
        std::string host_uri;
        getUri(host_uri);
    
        //get published topics
        std::string subgraph;
        ros::master::V_TopicInfo published_topics;
        getPublishedTopics(subgraph, published_topics);
    
        //get topic types
        ros::master::V_TopicInfo topics;
        getTopicTypes(topics);
    
        //get node uri
        std::string node, node_uri;
        node = "/talker";
        lookupNode(node, node_uri);
    
        //get service uri
        std::string service, service_uri;
        service = "/talker";
        lookupService(service, service_uri);
    
        //get all published topics,subscribed topics and services
        getSystemState();
    
        ros::spin();
        return 0;
    }

    查询的结果如下:

    ----------Master URI----------
    http://192.168.1.21:11311/
    ----------PublishedTopics----------
    published_topic_name      message_name
    /rosout    rosgraph_msgs/Log
    /rosout_agg    rosgraph_msgs/Log
    /talker/message    std_msgs/String
    ----------TopicTypes----------
    topic_name     message_name
    /rosout    rosgraph_msgs/Log
    /rosout_agg    rosgraph_msgs/Log
    /talker/message    std_msgs/String
    ----------LookupedNode----------
    /talker:http://192.168.1.21:44625/
    Failed!
    ----------SystemState----------
    Published Topics:
        */rosout:
            */talker
            */listener
        */rosout_agg:
            */rosout
        */talker/message:
            */talker
    Subscribed Topics:
        */rosout:
            */rosout
    Services:
        */talker/set_logger_level:
            */talker
        */listener/set_logger_level:
            */listener
        */rosout/get_loggers:
            */rosout
        */talker/get_loggers:
            */talker
        */rosout/set_logger_level:
            */rosout
        */listener/get_loggers:
            */listener

    2.参考资料

    [1]. Master_API

  • 相关阅读:
    Hashcode的作用
    java 强弱软虚 四种引用,以及用到的场景
    Object类有哪些公用方法?
    equals和==的区别
    switch能否用string做参数
    Java九种基本数据类型,以及他们的封装类
    Singleton(Java)
    快速排序和二分查找(Javascript)
    快速排序和二分查找(Go)
    ubuntn 安装 MySQL
  • 原文地址:https://www.cnblogs.com/cv-pr/p/7093861.html
Copyright © 2011-2022 走看看