Как опубликовать / подписать питонский "список списка" как тему в 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, поскольку у вас гораздо больше шансов получить ответ на свой вопрос.
Я согласен с решением, я думал о том, чтобы организовать его немного больше
Создать файл
FloatArray.msg
в вашейcatkin_ws
в папке src, где у вас есть все остальные файлы сообщений.Создайте свою среду, используя
catkin_make
илиcatkin build
.В вашем скрипте (например, скрипт Python) импортируйте тип сообщения и используйте его в подписчике, например
joint_state_publisher_Unity = rospy.Publisher("/joint_state_unity", FloatArray , queue_size = 10)
конкретный случай (бонус :)): если вы используете Unity и ROS#, создайте сообщение в Unity