From 9cfd6dedfc9b10ef2a5c10358239ce85523f115c Mon Sep 17 00:00:00 2001 From: Paul Beuchat <beuchatp@control.ee.ethz.ch> Date: Mon, 13 Apr 2020 17:01:04 +0200 Subject: [PATCH] Extended the FlyingVehicleState message definition to inlude a type, and velocities (both translational and angular). Update the Vicon and Qualisys publishers to fill in the type. Updated the CrazyRadio node to fill in this expanded FlyingVehicleState correctly, including adding a crazyflie name property to the CrazyRadioClient class. Removed all empty lines as end of message definitions. --- .../flyingAgentGUI/src/coordinatorrow.cpp | 2 +- .../GUI_Qt/flyingAgentGUI/src/topbanner.cpp | 2 +- .../src/dfall_pkg/crazyradio/CrazyRadio.py | 65 +++++++++++++++---- dfall_ws/src/dfall_pkg/crazyradio/TestCF.py | 2 +- .../src/dfall_pkg/include/nodes/Constants.h | 19 +++++- .../include/nodes/DefaultControllerService.h | 2 +- dfall_ws/src/dfall_pkg/msg/AreaBounds.msg | 3 +- dfall_ws/src/dfall_pkg/msg/CrazyflieDB.msg | 3 +- dfall_ws/src/dfall_pkg/msg/CrazyflieEntry.msg | 3 +- .../src/dfall_pkg/msg/FlyingVehicleState.msg | 7 ++ dfall_ws/src/dfall_pkg/msg/Setpoint.msg | 2 +- .../src/dfall_pkg/msg/UnlabeledMarker.msg | 2 +- .../dfall_pkg/src/nodes/FlyingAgentClient.cpp | 3 +- .../src/dfall_pkg/src/nodes/MocapEmulator.cpp | 2 + .../src/nodes/ViconDataPublisher.cpp | 51 ++++++++++----- .../src/qualisys/QualisysDataPublisher.py | 8 +++ 16 files changed, 133 insertions(+), 43 deletions(-) diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/coordinatorrow.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/coordinatorrow.cpp index eb55555b..a93a3d8f 100644 --- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/coordinatorrow.cpp +++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/coordinatorrow.cpp @@ -625,7 +625,7 @@ void CoordinatorRow::loadCrazyflieContext() } // This updating of the radio only needs to be done by the actual agent's node //ros::NodeHandle nh("CrazyRadio"); - //nh.setParam("crazyFlieAddress", m_context.crazyflieAddress); + //nh.setParam("crazyflieAddress", m_context.crazyflieAddress); #else // Set the Crazyflie Name String to be a question mark qstr_crazyflie_name.append("?"); diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/topbanner.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/topbanner.cpp index baa47e7b..b2d401b7 100644 --- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/topbanner.cpp +++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/topbanner.cpp @@ -231,7 +231,7 @@ void TopBanner::loadCrazyflieContext(int ID_to_request_from_database , int emit_ } // This updating of the radio only needs to be done by the actual agent's node //ros::NodeHandle nh("CrazyRadio"); - //nh.setParam("crazyFlieAddress", m_context.crazyflieAddress); + //nh.setParam("crazyflieAddress", m_context.crazyflieAddress); #else // Set the Crazyflie Name String to be a question mark qstr_crazyflie_name.append("?"); diff --git a/dfall_ws/src/dfall_pkg/crazyradio/CrazyRadio.py b/dfall_ws/src/dfall_pkg/crazyradio/CrazyRadio.py index 6828e3df..2a9ae6dc 100755 --- a/dfall_ws/src/dfall_pkg/crazyradio/CrazyRadio.py +++ b/dfall_ws/src/dfall_pkg/crazyradio/CrazyRadio.py @@ -44,7 +44,7 @@ from std_msgs.msg import Int32 # Import dfall_pkg messages from dfall_pkg.msg import ControlCommand from dfall_pkg.msg import IntWithHeader -from dfall_pkg.msg import CrazyflieStateEstimate +from dfall_pkg.msg import FlyingVehicleState from dfall_pkg.msg import GyroMeasurements # Import dfall_pkg services from dfall_pkg.srv import IntIntService @@ -124,6 +124,14 @@ CMD_CRAZYFLY_TAKE_OFF = 11 CMD_CRAZYFLY_LAND = 12 CMD_CRAZYFLY_MOTORS_OFF = 13 +# Types of flying vehicle states: +#FLYING_VEHICLE_STATE_TYPE_NONE = 0 +#FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT = 1 +FLYING_VEHICLE_STATE_TYPE_CRAZYFLIE_STATE_ESTIMATE = 2 +#FLYING_VEHICLE_STATE_TYPE_12_STATE_ESTIMATE = 3 + + + # Open the ROS bag for logging rp = RosPack() record_file = rp.get_path('dfall_pkg') + '/LoggingOnboard.bag' @@ -139,12 +147,24 @@ class CrazyRadioClient: """ def __init__(self): - # Setpoints to be sent to the CrazyFlie - self._status = DISCONNECTED - self.link_uri = "" - + # INITIALISE THE PROPERTIES OF THE OBJECT + # > For the status of the radio link + self._status = DISCONNECTED + # > For the addess of the radio link + self.link_uri = "" + # > For the name of the connected crazyflie + self.crazyflie_name = "" + + # > INIIALISE PUBLISHERS + # > For informing the network of the status of + # the radio link self.radio_status_publisher = rospy.Publisher(node_name + '/CrazyRadioStatus', Int32, queue_size=1) + # > For publishing commands on behalf of the + # FlyingAgentClient, only used for publishing + # "motor off" commands self.flyingAgentClient_command_publisher = rospy.Publisher('FlyingAgentClient/Command', IntWithHeader, queue_size=1) + + # PAUSE SHORTLY FOR THE PUBLISHERS TO BE REGISTERED IN ROS time.sleep(1.0) # Initialize the CrazyFlie and add callbacks @@ -173,7 +193,10 @@ class CrazyRadioClient: return self._status def update_link_uri(self): - self.link_uri = "radio://" + rospy.get_param("~crazyFlieAddress") + self.link_uri = "radio://" + rospy.get_param("~crazyflieAddress") + + def update_crazyflie_name(self): + self.crazyflie_name = rospy.get_param("~crazyflieName") def connect(self): # update link from ros params @@ -217,8 +240,8 @@ class CrazyRadioClient: def _data_received_stateEstimate_callback(self, timestamp, data, logconf): - # Initialise the variable for the state estimate data - cfStateEstimate = CrazyflieStateEstimate() + # Initialise the variable for the flying vehicle state + cfStateEstimate = FlyingVehicleState() # Retrieve the values from the data packet received # > (x,y,z) positions @@ -245,10 +268,22 @@ class CrazyRadioClient: # Print out one value for DEBUGGING #print "[CRAZY RADIO] received (z,vz) = ( %6.3f , %6.3f )" %( cfStateEstimate.z , cfStateEstimate.vz ) #print "[CRAZY RADIO] received (r,p,y) = ( %6.3f , %6.3f , %6.3f )" %( cfStateEstimate.roll*RAD_TO_DEG , cfStateEstimate.pitch*RAD_TO_DEG , cfStateEstimate.yaw*RAD_TO_DEG ) - + + # Fill in the remaining details: + # > For the type + cfStateEstimate.type = FLYING_VEHICLE_STATE_TYPE_CRAZYFLIE_STATE_ESTIMATE + # > For the name + cfStateEstimate.vehicleName = self.crazyflie_name + # > For the validity flag + cfStateEstimate.isValid = True + # > For the acquiring time + cfStateEstimate.acquiringTime = 0.0 + # Publish the state estimate cfstateEstimate_pub.publish(cfStateEstimate) + + # Initialise the variable for the gyroscope data gyroMeasurements = GyroMeasurements() @@ -258,6 +293,9 @@ class CrazyRadioClient: gyroMeasurements.pitchrate = -data["stateEstimateZ.ratePitch"] / 1000.0 gyroMeasurements.yawrate = data["stateEstimateZ.rateYaw"] / 1000.0 + # Fill in the name + gyroMeasurements.vehicleName = self.crazyflie_name + # Print out one value for DEBUGGING #print "[CRAZY RADIO] gyro (r,p,y) = ( %6.3f , %6.3f , %6.3f )" %( gyroMeasurements.rollrate*RAD_TO_DEG , gyroMeasurements.pitchrate*RAD_TO_DEG , gyroMeasurements.yawrate*RAD_TO_DEG ) @@ -630,7 +668,12 @@ if __name__ == '__main__': cflib.crtp.init_drivers(enable_debug_driver=False) # Wait until address parameter is set by FlyingAgentClient - while not rospy.has_param("~crazyFlieAddress"): + while not rospy.has_param("~crazyflieAddress"): + time.sleep(0.05) + + # Wait until name parameter is set by FlyingAgentClient + # > Should be set at the same timie as the address + while not rospy.has_param("~crazyflieName"): time.sleep(0.05) # Use the following lines of code to connect without data @@ -659,7 +702,7 @@ if __name__ == '__main__': # Initialise a publisher for the state estimate global cfstateEstimate_pub - cfstateEstimate_pub = rospy.Publisher(node_name + '/CFStateEstimate', CrazyflieStateEstimate, queue_size=10) + cfstateEstimate_pub = rospy.Publisher(node_name + '/CFStateEstimate', FlyingVehicleState, queue_size=10) diff --git a/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py b/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py index 9598f852..0f3431c9 100755 --- a/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py +++ b/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py @@ -210,7 +210,7 @@ if __name__ == '__main__': cflib.crtp.init_drivers(enable_debug_driver=False) #wait until address parameter is set by FlyingAgentClient - # while not rospy.has_param("~crazyFlieAddress"): + # while not rospy.has_param("~crazyflieAddress"): # time.sleep(0.05) #use this following two lines to connect without data from CentralManager diff --git a/dfall_ws/src/dfall_pkg/include/nodes/Constants.h b/dfall_ws/src/dfall_pkg/include/nodes/Constants.h index 94b022d7..4bd6a094 100644 --- a/dfall_ws/src/dfall_pkg/include/nodes/Constants.h +++ b/dfall_ws/src/dfall_pkg/include/nodes/Constants.h @@ -41,7 +41,6 @@ // UUU // ---------------------------------------------------------------------------------- - // Conversions between degrees and radians #define RAD2DEG 180.0/PI #define DEG2RAD PI/180.0 @@ -64,8 +63,6 @@ // // ---------------------------------------------------------------------------------- - - // The types, i.e., agent or coordinator #define TYPE_INVALID -1 #define TYPE_COORDINATOR 1 @@ -121,6 +118,21 @@ +// ---------------------------------------------------------------------------------- +// +// +// +// +// +// ---------------------------------------------------------------------------------- + +// Types of flying vehicle states: +#define FLYING_VEHICLE_STATE_TYPE_NONE 0 +#define FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT 1 +#define FLYING_VEHICLE_STATE_TYPE_CRAZYFLIE_STATE_ESTIMATE 2 +#define FLYING_VEHICLE_STATE_TYPE_12_STATE_ESTIMATE 3 + + @@ -185,6 +197,7 @@ + // ---------------------------------------------------------------------------------- // BBBB A TTTTT TTTTT EEEEE RRRR Y Y // B B A A T T E R R Y Y diff --git a/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h b/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h index a838f2f2..92077899 100644 --- a/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h +++ b/dfall_ws/src/dfall_pkg/include/nodes/DefaultControllerService.h @@ -44,7 +44,7 @@ // These various headers need to be included so that this controller service can be // connected with the D-FaLL system. -//some useful libraries +// Include useful libraries #include <math.h> #include <stdlib.h> #include "ros/ros.h" diff --git a/dfall_ws/src/dfall_pkg/msg/AreaBounds.msg b/dfall_ws/src/dfall_pkg/msg/AreaBounds.msg index b367b15d..5b82cabb 100755 --- a/dfall_ws/src/dfall_pkg/msg/AreaBounds.msg +++ b/dfall_ws/src/dfall_pkg/msg/AreaBounds.msg @@ -4,5 +4,4 @@ float32 xmax float32 ymin float32 ymax float32 zmin -float32 zmax - +float32 zmax \ No newline at end of file diff --git a/dfall_ws/src/dfall_pkg/msg/CrazyflieDB.msg b/dfall_ws/src/dfall_pkg/msg/CrazyflieDB.msg index a65dc00e..28ffc012 100644 --- a/dfall_ws/src/dfall_pkg/msg/CrazyflieDB.msg +++ b/dfall_ws/src/dfall_pkg/msg/CrazyflieDB.msg @@ -1,2 +1 @@ -CrazyflieEntry[] crazyflieEntries - +CrazyflieEntry[] crazyflieEntries \ No newline at end of file diff --git a/dfall_ws/src/dfall_pkg/msg/CrazyflieEntry.msg b/dfall_ws/src/dfall_pkg/msg/CrazyflieEntry.msg index 1bf527e2..b8d7fd54 100644 --- a/dfall_ws/src/dfall_pkg/msg/CrazyflieEntry.msg +++ b/dfall_ws/src/dfall_pkg/msg/CrazyflieEntry.msg @@ -1,3 +1,2 @@ CrazyflieContext crazyflieContext -uint32 studentID - +uint32 studentID \ No newline at end of file diff --git a/dfall_ws/src/dfall_pkg/msg/FlyingVehicleState.msg b/dfall_ws/src/dfall_pkg/msg/FlyingVehicleState.msg index e5c00c0a..1e0b1c4e 100644 --- a/dfall_ws/src/dfall_pkg/msg/FlyingVehicleState.msg +++ b/dfall_ws/src/dfall_pkg/msg/FlyingVehicleState.msg @@ -1,9 +1,16 @@ +uint32 type string vehicleName float64 x float64 y float64 z +float64 vx +float64 vy +float64 vz float64 roll float64 pitch float64 yaw +float64 rollRate +float64 pitchRate +float64 yawRate float64 acquiringTime #delta t bool isValid \ No newline at end of file diff --git a/dfall_ws/src/dfall_pkg/msg/Setpoint.msg b/dfall_ws/src/dfall_pkg/msg/Setpoint.msg index b3f94d9f..eb02bd5d 100644 --- a/dfall_ws/src/dfall_pkg/msg/Setpoint.msg +++ b/dfall_ws/src/dfall_pkg/msg/Setpoint.msg @@ -1,4 +1,4 @@ float64 x float64 y float64 z -float64 yaw +float64 yaw \ No newline at end of file diff --git a/dfall_ws/src/dfall_pkg/msg/UnlabeledMarker.msg b/dfall_ws/src/dfall_pkg/msg/UnlabeledMarker.msg index c05b0c57..a0b6cea0 100644 --- a/dfall_ws/src/dfall_pkg/msg/UnlabeledMarker.msg +++ b/dfall_ws/src/dfall_pkg/msg/UnlabeledMarker.msg @@ -1,4 +1,4 @@ uint32 index float64 x float64 y -float64 z +float64 z \ No newline at end of file diff --git a/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp b/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp index 553e6e56..9e249f43 100755 --- a/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp +++ b/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp @@ -1230,7 +1230,8 @@ void loadCrazyflieContext() m_context = new_context; ros::NodeHandle nh("CrazyRadio"); - nh.setParam("crazyFlieAddress", m_context.crazyflieAddress); + nh.setParam("crazyflieAddress", m_context.crazyflieAddress); + nh.setParam("crazyflieName", m_context.crazyflieName); } else { diff --git a/dfall_ws/src/dfall_pkg/src/nodes/MocapEmulator.cpp b/dfall_ws/src/dfall_pkg/src/nodes/MocapEmulator.cpp index ab75c383..ceca93a8 100644 --- a/dfall_ws/src/dfall_pkg/src/nodes/MocapEmulator.cpp +++ b/dfall_ws/src/dfall_pkg/src/nodes/MocapEmulator.cpp @@ -86,6 +86,8 @@ void timerCallback_mocap_publisher(const ros::TimerEvent&) FlyingVehicleState quadrotor_data; // Fill in the details + // > For the type + quadrotor_data.type = FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT; // > For the name quadrotor_data.vehicleName = it->get_id_string(); // > For the occulsion flag diff --git a/dfall_ws/src/dfall_pkg/src/nodes/ViconDataPublisher.cpp b/dfall_ws/src/dfall_pkg/src/nodes/ViconDataPublisher.cpp index 7a5fe429..9d2a762c 100755 --- a/dfall_ws/src/dfall_pkg/src/nodes/ViconDataPublisher.cpp +++ b/dfall_ws/src/dfall_pkg/src/nodes/ViconDataPublisher.cpp @@ -30,12 +30,21 @@ // ---------------------------------------------------------------------------------- +// Include useful libraries #include <string.h> -#include "DataStreamClient.h" #include "ros/ros.h" + +// Include the VICON Data Steam SDK header +#include "DataStreamClient.h" + +// Include the DFALL message types #include "dfall_pkg/ViconData.h" #include "dfall_pkg/UnlabeledMarker.h" +// Include the shared definitions +#include "nodes/Constants.h" + + // #define TESTING_FAKE_DATA // notice that unit here are in milimeters @@ -243,21 +252,29 @@ int main(int argc, char* argv[]) { } - //build message - FlyingVehicleState cfData; - cfData.vehicleName = subjectName; - - cfData.isValid = outputTranslation.Occluded; - - cfData.x = outputTranslation.Translation[0] / 1000.0f; - cfData.y = outputTranslation.Translation[1] / 1000.0f; - cfData.z = outputTranslation.Translation[2] / 1000.0f; - cfData.roll = roll; - cfData.pitch = pitch; - cfData.yaw = yaw; - cfData.acquiringTime = totalViconLatency; + // Local variable for the data of this objcet + FlyingVehicleState object_data; + // Fill in the details + // > For the type + object_data.type = FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT; + // > For the name + object_data.vehicleName = subjectName; + // > For the occulsion flag + object_data.isValid = !outputTranslation.Occluded; + // > For position + object_data.x = outputTranslation.Translation[0] / 1000.0f; + object_data.y = outputTranslation.Translation[1] / 1000.0f; + object_data.z = outputTranslation.Translation[2] / 1000.0f; + // > For euler angles + object_data.roll = roll; + object_data.pitch = pitch; + object_data.yaw = yaw; + // > For the acquiring time + object_data.acquiringTime = totalViconLatency; + + // Push back into the Vicon Data variable // if(!outputTranslation.Occluded) - viconData.crazyflies.push_back(cfData); + viconData.crazyflies.push_back(object_data); } viconDataPublisher.publish(viconData); } @@ -327,7 +344,9 @@ void testFakeData(ros::Publisher viconDataPublisher) // TODO: Fake CF data FlyingVehicleState crazyfly; - crazyfly.isValid = false; + crazyfly.type = FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT; + + crazyfly.isValid = true; crazyfly.vehicleName = "CF1"; crazyfly.x = 0; diff --git a/dfall_ws/src/dfall_pkg/src/qualisys/QualisysDataPublisher.py b/dfall_ws/src/dfall_pkg/src/qualisys/QualisysDataPublisher.py index cea66f2a..043d9461 100755 --- a/dfall_ws/src/dfall_pkg/src/qualisys/QualisysDataPublisher.py +++ b/dfall_ws/src/dfall_pkg/src/qualisys/QualisysDataPublisher.py @@ -112,6 +112,11 @@ DEG_TO_RAD = 0.01745329 #QTM_FILE = pkg_resources.resource_filename("qtm", "data/Demo.qtm") QTM_FILE = "none" +# Types of flying vehicle states: +#FLYING_VEHICLE_STATE_TYPE_NONE = 0 +FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT = 1 +#FLYING_VEHICLE_STATE_TYPE_CRAZYFLIE_STATE_ESTIMATE = 2 +#FLYING_VEHICLE_STATE_TYPE_12_STATE_ESTIMATE = 3 # OPEN THE ROS BAG FOR WRITING #rp = RosPack() @@ -281,6 +286,9 @@ class QualisysQtmClient: # > This is defined in the "FlyingVehicleState.msg" file this_crazyflie_data = FlyingVehicleState(); + # Add the type + this_crazyflie_data.type = FLYING_VEHICLE_STATE_TYPE_MOCAP_MEASUREMENT; + # Add the name of this object if current_body_index < len(self._list_of_body_names): this_crazyflie_data.vehicleName = self._list_of_body_names[current_body_index] -- GitLab