Изменение узла с издателя на подписчика по условному заявлению - PullRequest
0 голосов
/ 22 ноября 2018

Я хочу подписаться на опубликованное сообщение geomtery.Но внутри узла, который также является издателем при условии.

Мой узел публикует сообщение cmd_vel, когда объект находится рядом с роботом, чтобы сказать роботу остановиться.а если нет, то он движется с постоянной скоростью.

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

Я пытался написать это, но ничего не работает, поэтому я не думал, что будет полезно показать вам, что не работает.Потому что это не работает.Вместо этого, если бы вы могли мне помочь, как это сделать, особенно в части кода, я буду благодарен.

Я также хочу спросить, есть ли способ, чтобы он публиковался в теме только тогда, когдаусловие выполнено, и просто не публикуется, когда оно не выполняется.

#!/usr/bin/env python

import rospy
from sensor_msgs.msg import LaserScan
from geometry_msgs.msg import Twist

class Obstacle():
def __init__(self):
    self.LIDAR_ERR = 0.05
    self._cmd_pub = rospy.Publisher('cmd_vel', Twist, queue_size=1)
    self.obstacle()

def get_scan(self):
    msg = rospy.wait_for_message("scan", LaserScan)
    self.scan_filter = []
    for i in range(360):
        if i <= 15 or i > 335:
            if msg.ranges[i] >= self.LIDAR_ERR:
                self.scan_filter.append(msg.ranges[i])

def obstacle(self):
    self.twist = Twist()
    while not rospy.is_shutdown():
        self.get_scan()

        if min(self.scan_filter) < 0.2:
            self.twist.linear.x = 0.0
            self.twist.angular.z = 0.0
            self._cmd_pub.publish(self.twist)
            rospy.loginfo('Stop!')

        else:
            self.twist.linear.x = 0.5
            self.twist.angular.z = 0.0
            rospy.loginfo('distance of the obstacle : %f', min(self.scan_filter))

        self._cmd_pub.publish(self.twist)

def main():
rospy.init_node('turtlebot3_obstacle')
try:
    obstacle = Obstacle()
except rospy.ROSInterruptException:
    pass

if __name__ == '__main__':
main()

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

У вас есть два варианта, и они различаются в том, что вы пытаетесь архивировать:

  1. У вас есть разные задачи, которые робот должен выполнить.Взгляните на actionlib .

    Например, робот должен ехать в дом x и парковаться в гараже.Затем вы можете разделить это на несколько задач:

    • Поездка в гараж.
    • Парковка в гараже.

    Это разделение имеет смысл, потому что природа маневров очень различна, и вы, вероятно, не захотите писать другой узел (или несколько узлов) только для этого маневра.

  2. Из вашего вопроса I 'Я немного сбит с толку, потому что кажется, что вы пытаетесь реализовать функцию «безопасности», которая должна быть в состоянии взять под контроль во всех возможных случаях.

    К сожалению, ROS, насколько я знаю, нетхороший способ провести различие между издателями сообщений ROS.Сообщение ROS может иметь столько издателей и подписчиков, сколько вы хотите, и вы не можете выбрать «слушать здесь, но игнорировать эти сообщения».

    Лучший способ найти что-то подобное - создатьновый подписчик в каждом cmd_vel издателе, и если ваш «безопасный» узел отправляет «стоп» (или bool false / true в этом случае), издатель прекращает публикацию.

Последняя рекомендацияПопытайтесь связать свои инструменты навигации в одну ветку для каждой отдельной задачи только с одним конечным узлом, который публикует cmd_vel.И каждый механизм безопасности и управления, который вам нужен, упакован снизу, а не «параллельно», так сказать.

Это делает все намного проще, и вы можете использовать actionlib в полной мере.Вы даже можете делить узлы между ветвями, не мешая, потому что конечный издатель будет отключен, если не будет необходимости.

0 голосов
/ 24 ноября 2018

Подписка и отмена подписки, также как публикация и отмена публикации, не являются оптимальным способом, поскольку для их создания и деконструкции требуется время, и вы можете настроить как издателя, так и подписчика и контролировать, когда они будут обновляться и публиковаться:

  1. контролирует, когда вы публикуете, добавляя if до self._cmd_pub.publish(self.twist).
  2. , настройте обратный вызов и обновите переменные данными из обратного вызова, если ваше условие соответствует.
...