Publisher/Subscriber issues when using rostopic pu

2019-08-20 23:11发布

I am working with a simulated bebop 2 ,these are the commands I am using to run the simulation.

sphinx /opt/parrot-sphinx/usr/share/sphinx/drones/bebop2.drone

roslaunch bebop_driver bebop_node.launch ip:=10.202.0.1

When using the following command I am able to move the drone succesfuly

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}}'

What Im trying to do is to move the drone with the python script I am showing below.

#!/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()

In this case bebop_driver is subscribed to cmd_vel and bebop_commander publishes to cmd_vel topic.I checked this by using rostopic info cmd_vel and I got:

Type: geometry_msgs/Twist

Publishers: 
 * /bebop_commander (http://sebastian-Lenovo-ideapad-320-15IKB:40043/)

Subscribers: 
 * /bebop_driver (http://sebastian-Lenovo-ideapad-320-15IKB:46591/)

But still I am not getting any message when checking the topic using rostopic echo cmd_vel

I think my main issue is that my python script is not even publishing to cmd_vel topic.

Edit

Here is my bebop_node.launch file :

<?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>

1条回答
\"骚年 ilove
2楼-- · 2019-08-21 00:12

If rostopic info shows that the publisher is connected, then it is. I think that your issue is that the publisher publishes at most once to that topic.

I've modified your code to make it look like the one available at ROS tutorials.

I'll explain it, as it's short:

#!/usr/bin/env python
import sys
import rospy
from geometry_msgs.msg import Twist

You certainly know that all python ROS node starts with the python shebang. Then, in your code, the imports for system module, rospy and the Twist message.

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()

Then, I've changed you code into a function, commander. It creates the publisher and initializes the node. Then a Rate object is created; with it you can loop at 10 Hz, and publish the message at 10 Hz, the same a the -r 10 argument of your rostopic pub command. After that, the Twist message is created, for it will be used multiple times.

    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()

The loop checks the rospy.is_shutdown() flag to check if it should stop, because the node was told to (for example, by means of a ctrl+c). Then it fills the Twist message, logs a debug string, and publishes the command message. rate.sleep() implements a delay, so the node can publish messages at the desired rate, instead of doing it at full speed (which depends on your PC).

if __name__ == '__main__':
    speed = float(sys.argv[1])
    time = float(sys.argv[2])

The conditional is there to make the script execute the body of the if when the node is called, but not when the script is imported as a module (it's a standard python idiom). Then it converts the arguments as you do.

    if speed > 0:
        rospy.logdebug("Velocidad = %s m/s", speed)
    else:
        raise ValueError("Falta parametro de velocidad o el valor es incorrecto")

Checks the speed value, logs a debug message if everything is ok, and raises an exception if not. That will kill the node. The same is done for time.

    try:
        commander(speed, time)
    except rospy.ROSInterruptException:
        pass

Finally, the commander() is called until an exception is caught. If the exception is rospy.ROSInterruptException, meaning the user pressed CTRL+C, it silences it and the node exits.

The complete code:

#!/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
查看更多
登录 后发表回答