Publisher/Subscriber 使用 rostopic pub 时的问题
Publisher/Subscriber issues when using rostopic pub
我正在使用模拟 bebop 2,这些是我用来 运行 模拟的命令。
sphinx /opt/parrot-sphinx/usr/share/sphinx/drones/bebop2.drone
roslaunch bebop_driver bebop_node.launch ip:=10.202.0.1
使用以下命令时,我可以成功移动无人机
rostopic pub -r 10 cmd_vel geometry_msgs/Twist '{linear: {x: 0.0, y: 0.0, z: 0.0}, angular: {x: 0.0,y: 0.0,z: 0.0}}'
我想做的是使用下面显示的 python 脚本移动无人机。
#!/usr/bin/env python
import rospy
from geometry_msgs.msg import Twist
import sys
rospy.init_node("bebop_commander")
movement_publisher= rospy.Publisher('cmd_vel', Twist , queue_size=10)
movement_cmd = Twist()
speed = float(sys.argv[1])
time = float(sys.argv[2])
print ("Adelante")
if speed != "" and speed > 0 :
print ("Velocidad =" , speed , "m/s")
else:
print ("Falta parametro de velocidad o el valor es incorrecto")
if time != "" and time > 0 :
print ("Tiempo = ",time, "s")
else:
print ("Falta parametro de tiempo o el valor es incorrecto")
if time != "" and time > 0 :
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
movement_publisher.publish(movement_cmd)
print ("Publishing")
rospy.spin()
在这种情况下bebop_driver订阅了cmd_vel 和 bebop_commander 发布到 cmd_vel topic.I checked这是通过使用 rostopic info cmd_vel
得到的:
Type: geometry_msgs/Twist
Publishers:
* /bebop_commander (http://sebastian-Lenovo-ideapad-320-15IKB:40043/)
Subscribers:
* /bebop_driver (http://sebastian-Lenovo-ideapad-320-15IKB:46591/)
但是在使用 rostopic echo cmd_vel
检查主题时我仍然没有收到任何消息
我认为我的主要问题是我的 python 脚本甚至没有发布到 cmd_vel 主题。
编辑
这是我的 bebop_node.launch 文件:
<?xml version="1.0"?>
<launch>
<arg name="namespace" default="bebop" />
<arg name="ip" default="10.202.0.1" />
<arg name="drone_type" default="bebop2" /> <!-- available drone types: bebop1, bebop2 -->
<arg name="config_file" default="$(find bebop_driver)/config/defaults.yaml" />
<arg name="camera_info_url" default="package://bebop_driver/data/$(arg drone_type)_camera_calib.yaml" />
<node pkg="bebop_driver" name="bebop_driver" type="bebop_driver_node" output="screen">
<param name="camera_info_url" value="$(arg camera_info_url)" />
<param name="bebop_ip" value="$(arg ip)" />
<rosparam command="load" file="$(arg config_file)" />
</node>
<include file="$(find bebop_description)/launch/description.launch" />
</launch>
如果 rostopic info
显示发布者已连接,则已连接。我认为您的问题是发布者最多发布一次该主题。
我已经修改了您的代码,使其看起来像 ROS tutorials 上可用的代码。
我来解释一下,因为它很短:
#!/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 Hz 的频率循环,并以 10 Hz 的频率发布消息,与 rostopic pub
命令的 -r 10
参数相同。之后,创建了 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()
实施延迟,因此节点可以以所需的速率发布消息,而不是全速发布(这取决于您的 PC)。
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
我正在使用模拟 bebop 2,这些是我用来 运行 模拟的命令。
sphinx /opt/parrot-sphinx/usr/share/sphinx/drones/bebop2.drone
roslaunch bebop_driver bebop_node.launch ip:=10.202.0.1
使用以下命令时,我可以成功移动无人机
rostopic pub -r 10 cmd_vel geometry_msgs/Twist '{linear: {x: 0.0, y: 0.0, z: 0.0}, angular: {x: 0.0,y: 0.0,z: 0.0}}'
我想做的是使用下面显示的 python 脚本移动无人机。
#!/usr/bin/env python
import rospy
from geometry_msgs.msg import Twist
import sys
rospy.init_node("bebop_commander")
movement_publisher= rospy.Publisher('cmd_vel', Twist , queue_size=10)
movement_cmd = Twist()
speed = float(sys.argv[1])
time = float(sys.argv[2])
print ("Adelante")
if speed != "" and speed > 0 :
print ("Velocidad =" , speed , "m/s")
else:
print ("Falta parametro de velocidad o el valor es incorrecto")
if time != "" and time > 0 :
print ("Tiempo = ",time, "s")
else:
print ("Falta parametro de tiempo o el valor es incorrecto")
if time != "" and time > 0 :
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
movement_publisher.publish(movement_cmd)
print ("Publishing")
rospy.spin()
在这种情况下bebop_driver订阅了cmd_vel 和 bebop_commander 发布到 cmd_vel topic.I checked这是通过使用 rostopic info cmd_vel
得到的:
Type: geometry_msgs/Twist
Publishers:
* /bebop_commander (http://sebastian-Lenovo-ideapad-320-15IKB:40043/)
Subscribers:
* /bebop_driver (http://sebastian-Lenovo-ideapad-320-15IKB:46591/)
但是在使用 rostopic echo cmd_vel
我认为我的主要问题是我的 python 脚本甚至没有发布到 cmd_vel 主题。
编辑
这是我的 bebop_node.launch 文件:
<?xml version="1.0"?>
<launch>
<arg name="namespace" default="bebop" />
<arg name="ip" default="10.202.0.1" />
<arg name="drone_type" default="bebop2" /> <!-- available drone types: bebop1, bebop2 -->
<arg name="config_file" default="$(find bebop_driver)/config/defaults.yaml" />
<arg name="camera_info_url" default="package://bebop_driver/data/$(arg drone_type)_camera_calib.yaml" />
<node pkg="bebop_driver" name="bebop_driver" type="bebop_driver_node" output="screen">
<param name="camera_info_url" value="$(arg camera_info_url)" />
<param name="bebop_ip" value="$(arg ip)" />
<rosparam command="load" file="$(arg config_file)" />
</node>
<include file="$(find bebop_description)/launch/description.launch" />
</launch>
如果 rostopic info
显示发布者已连接,则已连接。我认为您的问题是发布者最多发布一次该主题。
我已经修改了您的代码,使其看起来像 ROS tutorials 上可用的代码。
我来解释一下,因为它很短:
#!/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 Hz 的频率循环,并以 10 Hz 的频率发布消息,与 rostopic pub
命令的 -r 10
参数相同。之后,创建了 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()
实施延迟,因此节点可以以所需的速率发布消息,而不是全速发布(这取决于您的 PC)。
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