我正在使用模拟的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 主题。我使用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>
答案 0 :(得分:1)
如果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的速度发布消息,与-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()
实现了延迟,因此节点可以以所需的速率发布消息,而不是全速运行(取决于您的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