1. 程式人生 > >ROS知識(20)----使用Master_API查詢Master管理的節點話題服務內容

ROS知識(20)----使用Master_API查詢Master管理的節點話題服務內容

知識 pytho system can div strong amp string ger

在一些應用中會需要獲取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 \t 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() << "\t" << 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\t 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() << "\t" << 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

ROS知識(20)----使用Master_API查詢Master管理的節點話題服務內容