USC-ACTLab / crazyswarm

A Large Quadcopter Swarm
MIT License
328 stars 323 forks source link

rospy.spin() not working in real nor sim #266

Closed ThomasCarstens closed 3 years ago

ThomasCarstens commented 4 years ago

I wish to create a ROS subscriber node for cf2 position callbacks. This is integrated in my code below, where I attempt to hover cf3 above cf2.

  1. When doing real drone tests: I cannot init_node (unable to register with CrazyflieAPI) nor use rospy.spin() (needs a node). A previous issue #54 says to remove both - but then only one callback occurs... Unless there is some method I am not aware of. I do however want the subscriber to continue running. How do I do so?

  2. When testing with the simulator: The matplotlib sim currently bugs when I register a node, stops updating right after takeoff. Currently it bugs at 2.4s. I have been able to trace a multithread problem between rospy.spin() and matplotlib's running thread. How do I use ROS in simulation? Is there some other method I am not aware of?

#!/usr/bin/env python

import numpy as np
import rospy
import tf
from geometry_msgs.msg import TransformStamped
import tf2_msgs.msg
from pycrazyswarm import *
import uav_trajectory
import matplotlib.pyplot as plt

def callback(tf_of_interest):

    cft = tf_of_interest.transforms[0]
    print(cft)

    x = cft.transform.translation.x
    y = cft.transform.translation.y
    z = cft.transform.translation.z

    pos = np.array([x, y, z+0.3])
    print("calculated pos: ", pos)
    print ("real pos: ", allcfs.crazyflies[0].position())
    allcfs.crazyflies[1].cmdPosition(pos, 0)

def listener():
    rospy.init_node('follow_me_now', anonymous=True)  #This and .spin() do not work...
    rospy.Subscriber('/tf', tf2_msgs.msg.TFMessage, callback)
    rospy.spin()

if __name__ == "__main__":
    swarm = Crazyswarm()
    timeHelper = swarm.timeHelper
    allcfs = swarm.allcfs

    Z = 0.3
    allcfs.crazyflies[1].takeoff(targetHeight=Z, duration=1.4+Z)
    timeHelper.sleep(1.5+Z)
    while (1):
        listener() # Not a great way to keep subscribing either...

    allcfs.crazyflies[1].land(targetHeight=0.06, duration=1.0+Z)
    timeHelper.sleep(1.0)
ThomasCarstens commented 4 years ago

The current 3D simulator is not ROS time-related. A ROS compatible simulator would be quite useful for myself and many others in the future. Perhaps I could get some precisions on how to change crazyflieSim.py to work on ROS data?

whoenig commented 4 years ago
  1. The Crazyflie server already initializes a node, see https://github.com/USC-ACTLab/crazyswarm/blob/master/ros_ws/src/crazyswarm/scripts/pycrazyswarm/crazyflie.py#L527. Spin is not required in ROS-Python (unlike in the C++ version). Thus, you should be able to first create the swarm object and then call rospy.Subscriber to add additional callbacks.

  2. The simulator does not rely on ROS, to reduce dependencies and allow faster simulation times. If you need ROS in this case, you'll need to call rospy.init_node in your script yourself (to be only active when using simulation though.) What is your use-case here? If you need more fully fledged simulation support, an integration with RotorS/CrazyS could be interesting.