4

我是 ROS 和 rospy 的新手,我不熟悉非简单数据类型作为主题。

我想构建一个 ROS 节点作为订阅者和发布者:它接收一个主题(两个列表float64),并使用一个函数(比如my_function)返回一个列表列表float64,然后将此列表列表作为主题发布。

为此,我构建了一个节点,如下所示:

from pymongo import MongoClient
from myfile import my_function
import rospy
import numpy as np

pub = None
sub = None

def callback(req):
    client = MongoClient()
    db = client.block
    lon = np.float64(req.b)
    lat = np.float64(req.a)
    point_list = my_function(lon, lat, db)
    pub.publish(point_list)

def calculator():
    global sub, pub
    rospy.init_node('calculator', anonymous=True)
    pub = rospy.Publisher('output_data', list)
    # Listen
    sub = rospy.Subscriber('input_data', list, callback)
    print "Calculation finished. \n"
    ros.spin()

if __name__ == '__main__':
    try:
        calculator()
    except rospy.ROSInterruptException:
        pass

我清楚地知道list在订阅者和发布者中不是消息数据,但我无法弄清楚如何修复它,因为它不是整数也不是整数列表。

4

2 回答 2

3

ROS 论坛上的这篇文章为您提供了您需要的大部分内容。也很有用。您可以使用以下规范定义新的消息类型: FloatList.msg

float64[] elements

然后第二个消息类型FloatArray.msg定义为:

FloatList[] lists

然后你的函数可能看起来像:

def callback(req):
    client = MongoClient()
    db = client.block
    lon = np.float64(req.b)
    lat = np.float64(req.a)
    point_list = my_function(lon, lat, db)
    float_array = FloatArray()
    for i in range(len(point_list)):
        float_list = FloatList()
        float_list.elements = point_list[i]
        float_array.lists[i] = float_list
    pub.publish(float_array)

然后你可以用以下方法解压它:

def unpack_callback(float_array_msg):
    for lst in float_array_msg.lists:
        for e in lst.elements:
            print "Here is an element: %f" % e

一般来说,建议您将与 ROS 相关的问题放在ROS 论坛上,因为在那里您更有可能得到问题的答案。

于 2017-10-09T23:43:27.993 回答
0

您可以通过在msg中定义新的ros类型来使自己复杂化,或者使用默认且易于实现的std_msgs类型,使用 json 模块可能会很有用,因此您可以在发布之前序列化数据,然后在另一端反序列化它接收...

其余的 Pub/Sub 、主题和处理程序保持不变 :)

于 2017-04-03T11:54:54.013 回答