Если rostopic info
показывает, что издатель подключен, то это так. Я думаю, что ваша проблема в том, что издатель публикует не более одного раза по этой теме.
Я изменил ваш код, чтобы он выглядел как тот, который доступен в учебниках по ROS .
Я объясню это, так как это коротко:
#!/usr/bin/env python
import sys
import rospy
from geometry_msgs.msg import Twist
Вы наверняка знаете, что все Python ROS-узлы начинаются с python shebang . Затем в вашем коде импортируются системные модули, rospy и сообщение Twist.
def commander(speed, time):
movement_publisher = rospy.Publisher('cmd_vel', Twist , queue_size=10)
rospy.init_node("bebop_commander", anonymous=True)
rate = rospy.Rate(10) # 10hz
movement_cmd = Twist()
Затем я изменил ваш код в функцию, commander
. Он создает издателя и инициализирует узел. Затем создается объект Rate
; с его помощью вы можете выполнить цикл с частотой 10 Гц и опубликовать сообщение с частотой 10 Гц, аналогичное аргументу -r 10
вашей команды rostopic pub
. После этого создается сообщение Twist, которое будет использоваться несколько раз.
while not rospy.is_shutdown():
movement_cmd.linear.x = 0
movement_cmd.linear.y = 0
movement_cmd.linear.z = 0
movement_cmd.angular.x = 0
movement_cmd.angular.y = 0
movement_cmd.angular.z = 0
rospy.logdebug("Publishing")
movement_publisher.publish(movement_cmd)
rate.sleep()
Цикл проверяет флаг rospy.is_shutdown()
, чтобы проверить, должен ли он остановиться, потому что узлу было сказано (например, с помощью ctrl+c
). Затем он заполняет сообщение Twist, регистрирует строку отладки и публикует командное сообщение. rate.sleep()
реализует задержку, поэтому узел может публиковать сообщения с желаемой скоростью, вместо того, чтобы делать это на полной скорости (которая зависит от вашего ПК).
if __name__ == '__main__':
speed = float(sys.argv[1])
time = float(sys.argv[2])
Условие заключается в том, чтобы скрипт выполнял тело if
при вызове узла, но не тогда, когда скрипт импортируется как модуль (это стандартная идиома python). Затем он преобразует аргументы, как вы.
if speed > 0:
rospy.logdebug("Velocidad = %s m/s", speed)
else:
raise ValueError("Falta parametro de velocidad o el valor es incorrecto")
Проверяет значение скорости, регистрирует отладочное сообщение, если все в порядке, и вызывает исключение, если нет. Это убьет узел. То же самое сделано для time
.
try:
commander(speed, time)
except rospy.ROSInterruptException:
pass
Наконец, commander()
вызывается до тех пор, пока не будет обнаружено исключение. Если исключение составляет rospy.ROSInterruptException
, то есть пользователь нажал CTRL+C
, оно отключает его, и узел завершается.
Полный код:
#!/usr/bin/env python
import sys
import rospy
from geometry_msgs.msg import Twist
def commander(speed, time):
movement_publisher = rospy.Publisher('cmd_vel', Twist , queue_size=10)
rospy.init_node("bebop_commander", anonymous=True)
rate = rospy.Rate(10) # 10hz
movement_cmd = Twist()
while not rospy.is_shutdown():
movement_cmd.linear.x = 0
movement_cmd.linear.y = 0
movement_cmd.linear.z = 0
movement_cmd.angular.x = 0
movement_cmd.angular.y = 0
movement_cmd.angular.z = 0
rospy.logdebug("Publishing")
movement_publisher.publish(movement_cmd)
rate.sleep()
if __name__ == '__main__':
speed = float(sys.argv[1])
time = float(sys.argv[2])
rospy.logdebug("Adelante") # Use rospy.logdebug() for debug messages.
if speed > 0:
rospy.logdebug("Velocidad = %s m/s", speed)
else:
raise ValueError("Falta parametro de velocidad o el valor es incorrecto")
if time > 0 :
rospy.logdebug("Tiempo = %s s", time)
else:
raise ValueError("Falta parametro de tiempo o el valor es incorrecto")
try:
commander(speed, time)
except rospy.ROSInterruptException:
pass