Как опубликовать / подписать питонский "список списка" как тему в ROS

Я новичок в ROS и Росси, и я не знаком с непростым типом данных в качестве темы.

Я хочу построить узел 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 в Subscriber and Publisher это не данные сообщения, но я не могу понять, как это исправить, поскольку это не целое число или список целых чисел.

3 ответа

Решение

Вы можете усложнить себя, определив новый тип ros в msg ИЛИ используя стандартный и простой в реализации тип std_msgs, возможно, будет полезно использовать модуль json, поэтому вы сериализуете данные перед публикацией и десериализуете их на другой стороне после получение...

остальные Pub/Sub, тема и обработчики остаются прежними:)

Этот пост на форумах 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, поскольку у вас гораздо больше шансов получить ответ на свой вопрос.

Я согласен с решением, я думал о том, чтобы организовать его немного больше

  1. Создать файлFloatArray.msgв вашейcatkin_wsв папке src, где у вас есть все остальные файлы сообщений.

  2. Создайте свою среду, используяcatkin_makeилиcatkin build.

  3. В вашем скрипте (например, скрипт Python) импортируйте тип сообщения и используйте его в подписчике, например

    joint_state_publisher_Unity = rospy.Publisher("/joint_state_unity", FloatArray , queue_size = 10)

конкретный случай (бонус :)): если вы используете Unity и ROS#, создайте сообщение в Unity

Другие вопросы по тегам