Как обновить массив черепах на основе ввода из функции обратного вызова ROS

У меня есть узел ROS, который подписан на тему, в которой несколько агентов публикуют свои позиции и соответствующие идентификаторы. Я хочу иметь возможность рисовать таких агентов, как черепахи, и соответственно обновлять их позиции.

У меня есть следующее:

class Visualizer():

def __init__(self):
    self.turtles = list()
    #Of the form: [[id, pos], ...]
    #[[1, [2, 3]],[2, [6, 7]],[3, [1, 1]],[4, [9, 8]], ...]
    self.logistics = []
    self.colors = []

    rospy.init_node('visualizer', anonymous=True)
    rospy.Subscriber('/environment/agent_position', Protocol_Msg, self.draw_agents)

    turtle.Screen()

def is_it_new(self, data):

    ----> check if broadcast received by new agent

    if new:
        self.turtles.append(turtle.Turtle())
        self.colors.append([random.random(), random.random(), random.random()])
        print self.colors
        self.logistics.append([turtle_id, pos])

    else:
        #only update position
        for x in self.logistics:
            if x[0] == turtle_id:
                x[1] = pos
    print self.logistics

def draw_agents(self, data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.content)
    self.is_it_new(data)
    for x in self.logistics:
        if x[0] == int(data.sender):
            turtles[self.logistics.index(x)].setx(x[1][0])
            turtles[self.logistics.index(x)].sety(x[1][1])


if __name__=='__main__':
    try:
        visualize = Visualizer()
        rospy.spin()
    except rospy.ROSInterruptException:
    pass

Тем не менее, это не так, как я, и производит

RuntimeError: основной поток не находится в основном цикле

Я не уверен, как переписать код, чтобы обновление происходило в основном потоке. (Я не работал с такими графическими интерфейсами раньше).

1 ответ

Спасибо за попытку. Мне удалось решить это следующим образом. В функции обратного вызова я помещаю новые данные в очередь () следующим образом:

    def __init__(self):
        .....
        self.turtle_queue = Queue.Queue()

    def put2queue(self, data):
        self.turtle_queue.put(data)

Затем я вызываю функцию рисования из main следующим образом:

if __name__=='__main__':

try:
    visualize = Visualizer()
    while True:
        data = visualize.turtle_queue.get()
        visualize.draw_agents(data)
except rospy.ROSInterruptException:
    traceback.print_exc()
    raise

Таким образом, графический интерфейс обновляется не из потока обратного вызова, а из основного потока.:)

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