diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/Constants_for_Qt_compile.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/Constants_for_Qt_compile.h index 716a287fcc81430b331cea1d81c4b1f750f748a9..a6d8f5584ef4b07122c32857256b9a206e8b4b47 100644 --- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/Constants_for_Qt_compile.h +++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/Constants_for_Qt_compile.h @@ -107,7 +107,7 @@ #define CF_COMMAND_TYPE_ANGLE 8 // Types of controllers being used: -#define SAFE_CONTROLLER 1 +#define DEFAULT_CONTROLLER 1 #define DEMO_CONTROLLER 2 #define STUDENT_CONTROLLER 3 #define MPC_CONTROLLER 4 @@ -118,7 +118,7 @@ // The constants that "command" changes in the // operation state of this agent -#define CMD_USE_SAFE_CONTROLLER 1 +#define CMD_USE_DEFAULT_CONTROLLER 1 #define CMD_USE_DEMO_CONTROLLER 2 #define CMD_USE_STUDENT_CONTROLLER 3 #define CMD_USE_MPC_CONTROLLER 4 @@ -208,84 +208,4 @@ // ---------------------------------------------------------------------------------- // For standard buttons in the GUI -#define REQUEST_DEFAULT_SETPOINT_BUTTON_ID 100 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// OLD STUFF FOR LOADING YAML FILES -// For which controller parameters to load from file -#define LOAD_YAML_SAFE_CONTROLLER_AGENT 1 -#define LOAD_YAML_DEMO_CONTROLLER_AGENT 2 -#define LOAD_YAML_STUDENT_CONTROLLER_AGENT 3 -#define LOAD_YAML_MPC_CONTROLLER_AGENT 4 -#define LOAD_YAML_REMOTE_CONTROLLER_AGENT 5 -#define LOAD_YAML_TUNING_CONTROLLER_AGENT 6 -#define LOAD_YAML_PICKER_CONTROLLER_AGENT 7 -#define LOAD_YAML_TEMPLATE_CONTROLLER_AGENT 8 - -#define LOAD_YAML_SAFE_CONTROLLER_COORDINATOR 11 -#define LOAD_YAML_DEMO_CONTROLLER_COORDINATOR 12 -#define LOAD_YAML_STUDENT_CONTROLLER_COORDINATOR 13 -#define LOAD_YAML_MPC_CONTROLLER_COORDINATOR 14 -#define LOAD_YAML_REMOTE_CONTROLLER_COORDINATOR 15 -#define LOAD_YAML_TUNING_CONTROLLER_COORDINATOR 16 -#define LOAD_YAML_PICKER_CONTROLLER_COORDINATOR 17 -#define LOAD_YAML_TEMPLATE_CONTROLLER_COORDINATOR 18 - - -// For sending commands to the controller node informing -// which parameters to fetch -// > NOTE: these are identical to the #defines above, but -// used because they have the name distinguishes -// between: -// - "loading" a yaml file into ram -// - "fetching" the values that were loaded into ram -#define FETCH_YAML_SAFE_CONTROLLER_FROM_OWN_AGENT 1 -#define FETCH_YAML_DEMO_CONTROLLER_FROM_OWN_AGENT 2 -#define FETCH_YAML_STUDENT_CONTROLLER_FROM_OWN_AGENT 3 -#define FETCH_YAML_MPC_CONTROLLER_FROM_OWN_AGENT 4 -#define FETCH_YAML_REMOTE_CONTROLLER_FROM_OWN_AGENT 5 -#define FETCH_YAML_TUNING_CONTROLLER_FROM_OWN_AGENT 6 -#define FETCH_YAML_PICKER_CONTROLLER_FROM_OWN_AGENT 7 -#define FETCH_YAML_TEMPLATE_CONTROLLER_FROM_OWN_AGENT 8 - -#define FETCH_YAML_SAFE_CONTROLLER_FROM_COORDINATOR 11 -#define FETCH_YAML_DEMO_CONTROLLER_FROM_COORDINATOR 12 -#define FETCH_YAML_STUDENT_CONTROLLER_FROM_COORDINATOR 13 -#define FETCH_YAML_MPC_CONTROLLER_FROM_COORDINATOR 14 -#define FETCH_YAML_REMOTE_CONTROLLER_FROM_COORDINATOR 15 -#define FETCH_YAML_TUNING_CONTROLLER_FROM_COORDINATOR 16 -#define FETCH_YAML_TEMPLATE_CONTROLLER_FROM_COORDINATOR 18 +#define REQUEST_DEFAULT_SETPOINT_BUTTON_ID 100 \ No newline at end of file diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/enablecontrollerloadyamlbar.h b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/enablecontrollerloadyamlbar.h index 6699aa3bfc41e1e3f414912e1cc4f45bcf5649f3..3ffd3ff9f83268b23da78a423237137f1a81a7c9 100644 --- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/enablecontrollerloadyamlbar.h +++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/include/enablecontrollerloadyamlbar.h @@ -72,17 +72,7 @@ #endif -// COMMANDS FOR THE FLYING STATE/CONTROLLER USED -// The constants that "command" changes in the -// operation state of this agent. These "commands" -// are sent from this GUI node to the "FlyingAgentClient" -// node where the command is enacted -// #define CMD_USE_SAFE_CONTROLLER 1 -// #define CMD_USE_DEMO_CONTROLLER 2 -// #define CMD_USE_STUDENT_CONTROLLER 3 -// #define CMD_USE_MPC_CONTROLLER 4 -// #define CMD_USE_REMOTE_CONTROLLER 5 -// #define CMD_USE_TUNING_CONTROLLER 6 + namespace Ui { diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp index ec83ca37999e22adad5ad9a84e999e2828a3eed8..899ab6738242f922bbd27a9e3ff331f06be098c0 100644 --- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp +++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/controllertabs.cpp @@ -397,16 +397,11 @@ void ControllerTabs::setControllerEnabled(int new_controller) // the enable controller switch(new_controller) { - case SAFE_CONTROLLER: - { - setTextColourOfTabLabel( m_tab_text_colour_highlight , ui->default_tab ); - break; - } -// case DEFAULT_CONTROLLER: -// { -// setTextColourOfTabLabel( m_tab_text_colour_highlight , ui->default_tab ); -// break; -// } + case DEFAULT_CONTROLLER: + { + setTextColourOfTabLabel( m_tab_text_colour_highlight , ui->default_tab ); + break; + } case DEMO_CONTROLLER: { //ui->controller_enabled_label->setText("Demo"); 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 21585a85fee09fa4051f7c5d6698334997c13d14..b6d60f69027d02249278daa7a449ac0c111beb90 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 @@ -88,7 +88,7 @@ CoordinatorRow::CoordinatorRow(QWidget *parent, int agentID) : setFlyingState(STATE_UNAVAILABLE); // SET THE DEFAULT NAME FOR THE SELECTED CONTROLLER - setControllerEnabled(SAFE_CONTROLLER); + setControllerEnabled(DEFAULT_CONTROLLER); #ifdef CATKIN_MAKE @@ -708,9 +708,9 @@ void CoordinatorRow::setControllerEnabled(int new_controller) { switch(new_controller) { - case SAFE_CONTROLLER: + case DEFAULT_CONTROLLER: { - ui->controller_enabled_label->setText("Safe"); + ui->controller_enabled_label->setText("Default"); break; } case DEMO_CONTROLLER: diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp index 3046875521ef6ae5351891b910063a2c27086acd..d5389a8bf817fb1bbaf74c9c4404151a614650b2 100644 --- a/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp +++ b/dfall_ws/src/dfall_pkg/GUI_Qt/flyingAgentGUI/src/enablecontrollerloadyamlbar.cpp @@ -125,9 +125,9 @@ void EnableControllerLoadYamlBar::on_enable_default_button_clicked() #ifdef CATKIN_MAKE dfall_pkg::IntWithHeader msg; fillIntMessageHeader(msg); - msg.data = CMD_USE_SAFE_CONTROLLER; + msg.data = CMD_USE_DEFAULT_CONTROLLER; this->commandPublisher.publish(msg); - ROS_INFO("[ENABLE CONTROLLER LOAD YAML GUI BAR] Enable Safe Controller"); + ROS_INFO("[ENABLE CONTROLLER LOAD YAML GUI BAR] Enable Default Controller"); #endif } diff --git a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/constants_for_qt_compile.h b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/constants_for_qt_compile.h index b361da05638f8715502151fdce96166c4ea49128..891b10ef3511568f97a7026dd6800461925dc4c8 100644 --- a/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/constants_for_qt_compile.h +++ b/dfall_ws/src/dfall_pkg/GUI_Qt/systemConfigGUI/include/constants_for_qt_compile.h @@ -107,7 +107,7 @@ #define CF_COMMAND_TYPE_ANGLE 8 // Types of controllers being used: -#define SAFE_CONTROLLER 1 +#define DEFAULT_CONTROLLER 1 #define DEMO_CONTROLLER 2 #define STUDENT_CONTROLLER 3 #define MPC_CONTROLLER 4 @@ -117,7 +117,7 @@ // The constants that "command" changes in the // operation state of this agent -#define CMD_USE_SAFE_CONTROLLER 1 +#define CMD_USE_DEFAULT_CONTROLLER 1 #define CMD_USE_DEMO_CONTROLLER 2 #define CMD_USE_STUDENT_CONTROLLER 3 #define CMD_USE_MPC_CONTROLLER 4 @@ -206,81 +206,4 @@ // ---------------------------------------------------------------------------------- // For standard buttons in the GUI -#define REQUEST_DEFAULT_SETPOINT_BUTTON_ID 100 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// OLD STUFF FOR LOADING YAML FILES -// For which controller parameters to load from file -#define LOAD_YAML_SAFE_CONTROLLER_AGENT 1 -#define LOAD_YAML_DEMO_CONTROLLER_AGENT 2 -#define LOAD_YAML_STUDENT_CONTROLLER_AGENT 3 -#define LOAD_YAML_MPC_CONTROLLER_AGENT 4 -#define LOAD_YAML_REMOTE_CONTROLLER_AGENT 5 -#define LOAD_YAML_TUNING_CONTROLLER_AGENT 6 -#define LOAD_YAML_PICKER_CONTROLLER_AGENT 7 - -#define LOAD_YAML_SAFE_CONTROLLER_COORDINATOR 11 -#define LOAD_YAML_DEMO_CONTROLLER_COORDINATOR 12 -#define LOAD_YAML_STUDENT_CONTROLLER_COORDINATOR 13 -#define LOAD_YAML_MPC_CONTROLLER_COORDINATOR 14 -#define LOAD_YAML_REMOTE_CONTROLLER_COORDINATOR 15 -#define LOAD_YAML_TUNING_CONTROLLER_COORDINATOR 16 -#define LOAD_YAML_PICKER_CONTROLLER_COORDINATOR 17 - - -// For sending commands to the controller node informing -// which parameters to fetch -// > NOTE: these are identical to the #defines above, but -// used because they have the name distinguishes -// between: -// - "loading" a yaml file into ram -// - "fetching" the values that were loaded into ram -#define FETCH_YAML_SAFE_CONTROLLER_FROM_OWN_AGENT 1 -#define FETCH_YAML_DEMO_CONTROLLER_FROM_OWN_AGENT 2 -#define FETCH_YAML_STUDENT_CONTROLLER_FROM_OWN_AGENT 3 -#define FETCH_YAML_MPC_CONTROLLER_FROM_OWN_AGENT 4 -#define FETCH_YAML_REMOTE_CONTROLLER_FROM_OWN_AGENT 5 -#define FETCH_YAML_TUNING_CONTROLLER_FROM_OWN_AGENT 6 -#define FETCH_YAML_PICKER_CONTROLLER_FROM_OWN_AGENT 7 - -#define FETCH_YAML_SAFE_CONTROLLER_FROM_COORDINATOR 11 -#define FETCH_YAML_DEMO_CONTROLLER_FROM_COORDINATOR 12 -#define FETCH_YAML_STUDENT_CONTROLLER_FROM_COORDINATOR 13 -#define FETCH_YAML_MPC_CONTROLLER_FROM_COORDINATOR 14 -#define FETCH_YAML_REMOTE_CONTROLLER_FROM_COORDINATOR 15 -#define FETCH_YAML_TUNING_CONTROLLER_FROM_COORDINATOR 16 -#define FETCH_YAML_PICKER_CONTROLLER_FROM_COORDINATOR 17 \ No newline at end of file +#define REQUEST_DEFAULT_SETPOINT_BUTTON_ID 100 \ No newline at end of file diff --git a/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py b/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py index 3cfb0e2aafa272f009b676b57cbb349deb1c6cd9..f955bd2c0388996340f9729b490474e10be1aa58 100755 --- a/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py +++ b/dfall_ws/src/dfall_pkg/crazyradio/TestCF.py @@ -54,12 +54,6 @@ DISCONNECTED = 2 CMD_RECONNECT = 0 CMD_DISCONNECT = 1 -# Commands for FlyingAgentClient -CMD_USE_SAFE_CONTROLLER = 1 -CMD_USE_CUSTOM_CONTROLLER = 2 -CMD_CRAZYFLY_TAKE_OFF = 3 -CMD_CRAZYFLY_LAND = 4 -CMD_CRAZYFLY_MOTORS_OFF = 5 # rp = RosPack() # record_file = rp.get_path('dfall_pkg') + '/LoggingOnboard.bag' @@ -239,8 +233,6 @@ if __name__ == '__main__': # rospy.loginfo("Turning off crazyflie") - # change state to motors OFF - # cf_client.FlyingAgentClient_command_pub.publish(CMD_CRAZYFLY_MOTORS_OFF) #wait for client to send its commands # time.sleep(1.0) diff --git a/dfall_ws/src/dfall_pkg/include/nodes/Constants.h b/dfall_ws/src/dfall_pkg/include/nodes/Constants.h index 71507435e23d2c1117e1cd90460ea14815821c42..0843e1a25220581d77dc5ad49472c6ff2b8b257a 100644 --- a/dfall_ws/src/dfall_pkg/include/nodes/Constants.h +++ b/dfall_ws/src/dfall_pkg/include/nodes/Constants.h @@ -120,7 +120,7 @@ // ---------------------------------------------------------------------------------- // Types of controllers being used: -#define SAFE_CONTROLLER 1 +#define DEFAULT_CONTROLLER 1 #define DEMO_CONTROLLER 2 #define STUDENT_CONTROLLER 3 #define MPC_CONTROLLER 4 @@ -131,7 +131,7 @@ // The constants that "command" changes in the // operation state of this agent -#define CMD_USE_SAFE_CONTROLLER 1 +#define CMD_USE_DEFAULT_CONTROLLER 1 #define CMD_USE_DEMO_CONTROLLER 2 #define CMD_USE_STUDENT_CONTROLLER 3 #define CMD_USE_MPC_CONTROLLER 4 @@ -222,85 +222,4 @@ // ---------------------------------------------------------------------------------- // For standard buttons in the GUI -#define REQUEST_DEFAULT_SETPOINT_BUTTON_ID 100 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// OLD STUFF FOR LOADING YAML FILES -// For which controller parameters to load from file -#define LOAD_YAML_SAFE_CONTROLLER_AGENT 1 -#define LOAD_YAML_DEMO_CONTROLLER_AGENT 2 -#define LOAD_YAML_STUDENT_CONTROLLER_AGENT 3 -#define LOAD_YAML_MPC_CONTROLLER_AGENT 4 -#define LOAD_YAML_REMOTE_CONTROLLER_AGENT 5 -#define LOAD_YAML_TUNING_CONTROLLER_AGENT 6 -#define LOAD_YAML_PICKER_CONTROLLER_AGENT 7 -#define LOAD_YAML_TEMPLATE_CONTROLLER_AGENT 7 - -#define LOAD_YAML_SAFE_CONTROLLER_COORDINATOR 11 -#define LOAD_YAML_DEMO_CONTROLLER_COORDINATOR 12 -#define LOAD_YAML_STUDENT_CONTROLLER_COORDINATOR 13 -#define LOAD_YAML_MPC_CONTROLLER_COORDINATOR 14 -#define LOAD_YAML_REMOTE_CONTROLLER_COORDINATOR 15 -#define LOAD_YAML_TUNING_CONTROLLER_COORDINATOR 16 -#define LOAD_YAML_PICKER_CONTROLLER_COORDINATOR 17 -#define LOAD_YAML_TEMPLATE_CONTROLLER_COORDINATOR 18 - - -// For sending commands to the controller node informing -// which parameters to fetch -// > NOTE: these are identical to the #defines above, but -// used because they have the name distinguishes -// between: -// - "loading" a yaml file into ram -// - "fetching" the values that were loaded into ram -#define FETCH_YAML_SAFE_CONTROLLER_FROM_OWN_AGENT 1 -#define FETCH_YAML_DEMO_CONTROLLER_FROM_OWN_AGENT 2 -#define FETCH_YAML_STUDENT_CONTROLLER_FROM_OWN_AGENT 3 -#define FETCH_YAML_MPC_CONTROLLER_FROM_OWN_AGENT 4 -#define FETCH_YAML_REMOTE_CONTROLLER_FROM_OWN_AGENT 5 -#define FETCH_YAML_TUNING_CONTROLLER_FROM_OWN_AGENT 6 -#define FETCH_YAML_PICKER_CONTROLLER_FROM_OWN_AGENT 7 -#define FETCH_YAML_TEMPLATE_CONTROLLER_FROM_OWN_AGENT 8 - -#define FETCH_YAML_SAFE_CONTROLLER_FROM_COORDINATOR 11 -#define FETCH_YAML_DEMO_CONTROLLER_FROM_COORDINATOR 12 -#define FETCH_YAML_STUDENT_CONTROLLER_FROM_COORDINATOR 13 -#define FETCH_YAML_MPC_CONTROLLER_FROM_COORDINATOR 14 -#define FETCH_YAML_REMOTE_CONTROLLER_FROM_COORDINATOR 15 -#define FETCH_YAML_TUNING_CONTROLLER_FROM_COORDINATOR 16 -#define FETCH_YAML_PICKER_CONTROLLER_FROM_COORDINATOR 17 -#define FETCH_YAML_TEMPLATE_CONTROLLER_FROM_COORDINATOR 18 \ No newline at end of file +#define REQUEST_DEFAULT_SETPOINT_BUTTON_ID 100 \ No newline at end of file diff --git a/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h b/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h index 9e1d64e2b48340ca5096a1949c2d33730fb98bf2..2d97b7c2f6c4896ca102acaf81ec7d76560f0983 100644 --- a/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h +++ b/dfall_ws/src/dfall_pkg/include/nodes/FlyingAgentClient.h @@ -121,8 +121,38 @@ std::string m_namespace_to_own_agent_parameter_service; std::string m_namespace_to_coordinator_parameter_service; +// variables for the states: +int m_flying_state; +bool m_changed_flying_state_flag; + +// variable for crazyradio status +int crazyradio_status; + +//describes the area of the crazyflie and other parameters +CrazyflieContext m_context; + +// The index for which element in the "motion captate data" +// array is expected to match the name in "m_context" +// > Negative numbers indicate unknown +int m_poseDataIndex = -1; + +// wheter to use safe of demo controller +// variable for the instant controller, e.g., we use +// safe controller for taking off and landing even +// if demo controller is enabled. This variable WILL change automatically +int m_instant_controller; +ros::ServiceClient* m_instant_controller_service_client; +bool m_controllers_avialble = false; +ros::Timer timer_for_loadAllControllers; + +// controller used: +int m_controller_nominally_selected; + + // The safe controller specified in the ClientConfig.yaml ros::ServiceClient safeController; +// The default controller specified in the ClientConfig.yaml +ros::ServiceClient defaultController; // The Demo controller specified in the ClientConfig.yaml ros::ServiceClient demoController; // The Student controller specified in the ClientConfig.yaml @@ -139,92 +169,62 @@ ros::ServiceClient pickerController; ros::ServiceClient templateController; -//values for safteyCheck -bool yaml_strictSafety; +// The values for the safety check on tilt angle +bool yaml_isEnabled_strictSafety = true; float yaml_angleMargin; +float yaml_maxTiltAngle_for_strictSafety_degrees = 70; +float m_maxTiltAngle_for_strictSafety_redians = 70 * DEG2RAD; -// battery threshold -//float m_battery_threshold_while_flying; -//float m_battery_threshold_while_motors_off; - - -// battery values +//Setpoint controller_setpoint; -//int m_battery_state; -//float m_battery_voltage; - - - - - -Setpoint controller_setpoint; - -std::vector<float> yaml_default_setpoint = {0.0f, 0.0f, 0.0f, 0.0f}; +//std::vector<float> yaml_default_setpoint = {0.0f, 0.0f, 0.0f, 0.0f}; // variables for linear trayectory -Setpoint current_safe_setpoint; -double distance; -double unit_vector[3]; -bool was_in_threshold = false; -double yaml_distance_threshold; //to be loaded from yaml +//Setpoint current_safe_setpoint; +//double distance; +//double unit_vector[3]; +//bool was_in_threshold = false; +//double yaml_distance_threshold; //to be loaded from yaml +// Service Client from which the "CrazyflieContext" is loaded ros::ServiceClient centralManager; -ros::Publisher controlCommandPublisher; + +// Publisher for the control actions to be sent on +// to the Crazyflie (the CrazyRadio node listen to this +// publisher and actually send the commands) +// {onboardControllerType,roll,pitch,yaw,motorCmd1,motorCmd2,motorCmd3,motorCmd4} +ros::Publisher commandForSendingToCrazyfliePublisher; // communicate with safeControllerService, setpoint, etc... -ros::Publisher safeControllerServiceSetpointPublisher; +//ros::Publisher safeControllerServiceSetpointPublisher; -// publisher for flying state +// Publisher for the current flying state of this Flying Agent Client ros::Publisher flyingStatePublisher; -// publisher for battery state -ros::Publisher batteryStatePublisher; - -// publisher to send commands to itself. -ros::Publisher commandPublisher; +// Publisher for the commands of: +// {take-off,land,motors-off, and which controller to use} +//ros::Publisher commandPublisher; -// communication with crazyRadio node. Connect and disconnect +// Publisher Communication with crazyRadio node. Connect and disconnect ros::Publisher crazyRadioCommandPublisher; -// Variable for the namespaces for the paramter services -// > For the paramter service of this agent -std::string namespace_to_own_agent_parameter_service; -// > For the parameter service of the coordinator -std::string namespace_to_coordinator_parameter_service; - - -// variables for the states: -int flying_state; -bool changed_state_flag; - -// variable for crazyradio status -int crazyradio_status; - -//describes the area of the crazyflie and other parameters -CrazyflieContext context; - -//wheter to use safe of demo controller -int instant_controller; //variable for the instant controller, e.g., we use safe controller for taking off and landing even if demo controller is enabled. This variable WILL change automatically - -// controller used: -int controller_used; - +// Publisher for which controller is currently being used ros::Publisher controllerUsedPublisher; -float yaml_take_off_distance; -float yaml_landing_distance; -float yaml_duration_take_off; -float yaml_duration_landing; +// float yaml_take_off_distance; +// float yaml_landing_distance; +// float yaml_duration_take_off; +// float yaml_duration_landing; -bool finished_take_off = false; -bool finished_land = false; +// bool finished_take_off = false; +// bool finished_land = false; ros::Timer timer_takeoff; ros::Timer timer_land; @@ -250,17 +250,7 @@ ros::Timer timer_land; // ---------------------------------------------------------------------------------- -// > For the LOAD PARAMETERS -//void yamlReadyForFetchCallback(const std_msgs::Int32& msg); -//void fetchYamlParametersForSafeController(ros::NodeHandle& nodeHandle); -//void fetchClientConfigParameters(ros::NodeHandle& nodeHandle); -// > For the LOADING of YAML PARAMETERS -void isReadySafeControllerYamlCallback(const IntWithHeader & msg); -void fetchSafeControllerYamlParameters(ros::NodeHandle& nodeHandle); - -void isReadyClientConfigYamlCallback(const IntWithHeader & msg); -void fetchClientConfigYamlParameters(ros::NodeHandle& nodeHandle); @@ -268,10 +258,16 @@ void fetchClientConfigYamlParameters(ros::NodeHandle& nodeHandle); void viconCallback(const ViconData& viconData); +int getPoseDataForObjectNameWithExpectedIndex(const ViconData& viconData, std::string name , int expected_index , CrazyflieData& pose); +void coordinatesToLocal(CrazyflieData& cf); + +// > For the SAFETY CHECK on area and the angle +bool safetyCheck(CrazyflieData data, ControlCommand controlCommand); +void changeFlyingStateTo(int new_state); void crazyflieContextDatabaseChangedCallback(const std_msgs::Int32& msg); @@ -279,34 +275,51 @@ void crazyflieContextDatabaseChangedCallback(const std_msgs::Int32& msg); -void commandCallback(const IntWithHeader & commandMsg); +void flyingStateRequestCallback(const IntWithHeader & commandMsg); + +// void loadSafeController(); +// void loadDemoController(); +// void loadStudentController(); +// void loadMpcController(); +// void loadRemoteController(); +// void loadTuningController(); +// void loadPickerController(); +// void loadTemplateController(); -void loadSafeController(); -void loadDemoController(); -void loadStudentController(); -void loadMpcController(); -void loadRemoteController(); -void loadTuningController(); -void loadPickerController(); -void loadTemplateController(); +void loadController( std::string paramter_name , ros::ServiceClient& serviceClient ); void sendMessageUsingController(int controller); void setInstantController(int controller); int getInstantController(); -void setControllerUsed(int controller); -int getControllerUsed(); +void setControllerNominallySelected(int controller); +int getControllerNominallySelected(); + + + +// THE CALLBACK THAT THE CRAZY RADIO STATUS CHANGED +void crazyRadioStatusCallback(const std_msgs::Int32& msg); +// THE CALLBACK THAT AN EMERGENCY STOP MESSAGE WAS RECEIVED +void emergencyStopReceivedCallback(const IntWithHeader & msg); -// > For the BATTERY -//int getBatteryState(); -//void setBatteryStateTo(int new_battery_state); -//float movingAverageBatteryFilter(float new_input); -//void CFBatteryCallback(const std_msgs::Float32& msg); +// THE SERVICE CALLBACK REQUESTING THE CURRENT FLYING STATE +bool getCurrentFlyingStateServiceCallback(IntIntService::Request &request, IntIntService::Response &response); + +// FOR THE BATTERY STATE CALLBACK void batteryMonitorStateChangedCallback(std_msgs::Int32 msg); +// FOR THE SAFETY CHECKS ON POSITION AND TILT ANGLE +bool safetyCheck(CrazyflieData data); + +// THE CALLBACK THAT THE CONTEXT DATABASE CHANGED +void crazyflieContextDatabaseChangedCallback(const std_msgs::Int32& msg); -// > For the FLYING STATE -bool getCurrentFlyingStateServiceCallback(IntIntService::Request &request, IntIntService::Response &response); \ No newline at end of file +// FOR LOADING THE CONTEXT OF THIS AGENT +void loadCrazyflieContext(); + +// FOR LOADING THE YAML PARAMETERS +void isReadyClientConfigYamlCallback(const IntWithHeader & msg); +void fetchClientConfigYamlParameters(ros::NodeHandle& nodeHandle); \ No newline at end of file diff --git a/dfall_ws/src/dfall_pkg/param/ClientConfig.yaml b/dfall_ws/src/dfall_pkg/param/ClientConfig.yaml index 779d2461270c5f2c9baed4ea7c135a537b75fc13..1d3c48063d12ab14fbaac949ecd3586d3d10561c 100755 --- a/dfall_ws/src/dfall_pkg/param/ClientConfig.yaml +++ b/dfall_ws/src/dfall_pkg/param/ClientConfig.yaml @@ -1,4 +1,5 @@ safeController: "SafeControllerService/RateController" +defaultController: "DefaultControllerService/DefaultController" demoController: "DemoControllerService/DemoController" studentController: "StudentControllerService/StudentController" mpcController: "MpcControllerService/MpcController" @@ -7,9 +8,9 @@ tuningController: "TuningControllerService/TuningController" pickerController: "PickerControllerService/PickerController" templateController: "TemplateControllerService/TemplateController" -# Flag for whether to use angle for switching to the Safe Controller -strictSafety: false -angleMargin: 0.8 +# Flag for whether to use angle for switching to the Default Controller +isEnabled_strictSafety: true +maxTiltAngle_for_strictSafety_degrees: 70 battery_threshold_while_flying: 2.60 # in V battery_threshold_while_motors_off: 3.30 # in V diff --git a/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp b/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp index e4fab28c9f4dd1b93c01591bb369f2012ef97dd5..2b51ea5bc8c6f8e4359cc2b01e8b3174fbb9033b 100755 --- a/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp +++ b/dfall_ws/src/dfall_pkg/src/nodes/FlyingAgentClient.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017, ETH Zurich, D-ITET, Paul Beuchat, Angel Romero, Cyrill Burgener, Marco Mueller, Philipp Friedli +// Copyright (C) 2019, ETH Zurich, D-ITET, Paul Beuchat, Angel Romero, Cyrill Burgener, Marco Mueller, Philipp Friedli // // This file is part of D-FaLL-System. // @@ -61,504 +61,443 @@ -//checks if crazyflie is within allowed area and if demo controller returns no data -bool safetyCheck(CrazyflieData data, ControlCommand controlCommand) { - //position check - if((data.x < context.localArea.xmin) or (data.x > context.localArea.xmax)) { - ROS_INFO_STREAM("[FLYING AGENT CLIENT] x safety failed"); - return false; - } - if((data.y < context.localArea.ymin) or (data.y > context.localArea.ymax)) { - ROS_INFO_STREAM("[FLYING AGENT CLIENT] y safety failed"); - return false; - } - if((data.z < context.localArea.zmin) or (data.z > context.localArea.zmax)) { - ROS_INFO_STREAM("[FLYING AGENT CLIENT] z safety failed"); - return false; - } - //attitude check - //if strictSafety is set to true in ClientConfig.yaml the SafeController takes also over if the roll and pitch angles get to large - //the angleMargin is a value in the range (0,1). The closer to 1, the closer to 90 deg are the roll and pitch angles allowed to become before the safeController takes over - if(yaml_strictSafety){ - if((data.roll > PI/2*yaml_angleMargin) or (data.roll < -PI/2*yaml_angleMargin)) { - ROS_INFO_STREAM("[FLYING AGENT CLIENT] roll too big."); - return false; - } - if((data.pitch > PI/2*yaml_angleMargin) or (data.pitch < -PI/2*yaml_angleMargin)) { - ROS_INFO_STREAM("[FLYING AGENT CLIENT] pitch too big."); - return false; - } - } - return true; -} -void coordinatesToLocal(CrazyflieData& cf) { - AreaBounds area = context.localArea; - float originX = (area.xmin + area.xmax) / 2.0; - float originY = (area.ymin + area.ymax) / 2.0; - // change Z origin to zero, i.e., to the table height, zero of global coordinates, instead of middle of the box - float originZ = 0.0; - // float originZ = (area.zmin + area.zmax) / 2.0; - - cf.x -= originX; - cf.y -= originY; - cf.z -= originZ; -} -void setCurrentSafeSetpoint(Setpoint setpoint) -{ - current_safe_setpoint = setpoint; -} -void calculateDistanceToCurrentSafeSetpoint(CrazyflieData& local) -{ - double dx = current_safe_setpoint.x - local.x; - double dy = current_safe_setpoint.y - local.y; - double dz = current_safe_setpoint.z - local.z; - distance = sqrt(pow(dx,2) + pow(dy,2) + pow(dz,2)); +// void takeOffCF(CrazyflieData& current_local_coordinates) //local because the setpoint is in local coordinates +// { +// // set the setpoint and call safe controller +// Setpoint setpoint_msg; +// setpoint_msg.x = current_local_coordinates.x; // previous one +// setpoint_msg.y = current_local_coordinates.y; //previous one +// setpoint_msg.z = current_local_coordinates.z + yaml_take_off_distance; //previous one plus some offset +// // setpoint_msg.yaw = current_local_coordinates.yaw; //previous one +// setpoint_msg.yaw = 0.0; +// safeControllerServiceSetpointPublisher.publish(setpoint_msg); +// ROS_INFO("[FLYING AGENT CLIENT] Take OFF:"); +// ROS_INFO("[FLYING AGENT CLIENT] ------Current coordinates:"); +// ROS_INFO("[FLYING AGENT CLIENT] X: %f, Y: %f, Z: %f", current_local_coordinates.x, current_local_coordinates.y, current_local_coordinates.z); +// ROS_INFO("[FLYING AGENT CLIENT] ------New coordinates:"); +// ROS_INFO("[FLYING AGENT CLIENT] X: %f, Y: %f, Z: %f", setpoint_msg.x, setpoint_msg.y, setpoint_msg.z); - unit_vector[0] = dx/distance; - unit_vector[1] = dy/distance; - unit_vector[2] = dz/distance; -} +// // now, use safe controller to go to that setpoint +// loadSafeController(); +// setInstantController(SAFE_CONTROLLER); +// // when do we finish? after some time with delay? +// // update variable that keeps track of current setpoint +// setCurrentSafeSetpoint(setpoint_msg); +// } -void takeOffCF(CrazyflieData& current_local_coordinates) //local because the setpoint is in local coordinates -{ - // set the setpoint and call safe controller - Setpoint setpoint_msg; - setpoint_msg.x = current_local_coordinates.x; // previous one - setpoint_msg.y = current_local_coordinates.y; //previous one - setpoint_msg.z = current_local_coordinates.z + yaml_take_off_distance; //previous one plus some offset - // setpoint_msg.yaw = current_local_coordinates.yaw; //previous one - setpoint_msg.yaw = 0.0; - safeControllerServiceSetpointPublisher.publish(setpoint_msg); - ROS_INFO("[FLYING AGENT CLIENT] Take OFF:"); - ROS_INFO("[FLYING AGENT CLIENT] ------Current coordinates:"); - ROS_INFO("[FLYING AGENT CLIENT] X: %f, Y: %f, Z: %f", current_local_coordinates.x, current_local_coordinates.y, current_local_coordinates.z); - ROS_INFO("[FLYING AGENT CLIENT] ------New coordinates:"); - ROS_INFO("[FLYING AGENT CLIENT] X: %f, Y: %f, Z: %f", setpoint_msg.x, setpoint_msg.y, setpoint_msg.z); - - // now, use safe controller to go to that setpoint - loadSafeController(); - setInstantController(SAFE_CONTROLLER); - // when do we finish? after some time with delay? - - // update variable that keeps track of current setpoint - setCurrentSafeSetpoint(setpoint_msg); -} - -void landCF(CrazyflieData& current_local_coordinates) -{ - // set the setpoint and call safe controller - Setpoint setpoint_msg; - setpoint_msg.x = current_local_coordinates.x; // previous one - setpoint_msg.y = current_local_coordinates.y; //previous one - setpoint_msg.z = yaml_landing_distance; //previous one plus some offset - setpoint_msg.yaw = current_local_coordinates.yaw; //previous one - safeControllerServiceSetpointPublisher.publish(setpoint_msg); - - // now, use safe controller to go to that setpoint - loadSafeController(); - setInstantController(SAFE_CONTROLLER); - setCurrentSafeSetpoint(setpoint_msg); -} - -void changeFlyingStateTo(int new_state) -{ - if(crazyradio_status == CRAZY_RADIO_STATE_CONNECTED) - { - ROS_INFO("[FLYING AGENT CLIENT] Change state to: %d", new_state); - flying_state = new_state; - } - else - { - ROS_INFO("[FLYING AGENT CLIENT] Disconnected and trying to change state. State goes to MOTORS OFF"); - flying_state = STATE_MOTORS_OFF; - } +// void landCF(CrazyflieData& current_local_coordinates) +// { +// // set the setpoint and call safe controller +// Setpoint setpoint_msg; +// setpoint_msg.x = current_local_coordinates.x; // previous one +// setpoint_msg.y = current_local_coordinates.y; //previous one +// setpoint_msg.z = yaml_landing_distance; //previous one plus some offset +// setpoint_msg.yaw = current_local_coordinates.yaw; //previous one +// safeControllerServiceSetpointPublisher.publish(setpoint_msg); - changed_state_flag = true; - std_msgs::Int32 flying_state_msg; - flying_state_msg.data = flying_state; - flyingStatePublisher.publish(flying_state_msg); -} +// // now, use safe controller to go to that setpoint +// loadSafeController(); +// setInstantController(SAFE_CONTROLLER); +// setCurrentSafeSetpoint(setpoint_msg); +// } -void takeOffTimerCallback(const ros::TimerEvent&) -{ - finished_take_off = true; -} -void landTimerCallback(const ros::TimerEvent&) -{ - finished_land = true; -} -void goToControllerSetpoint() -{ - safeControllerServiceSetpointPublisher.publish(controller_setpoint); - setCurrentSafeSetpoint(controller_setpoint); -} +// void goToControllerSetpoint() +// { +// safeControllerServiceSetpointPublisher.publish(controller_setpoint); +// setCurrentSafeSetpoint(controller_setpoint); +// } //is called when new data from Vicon arrives void viconCallback(const ViconData& viconData) { - for(std::vector<CrazyflieData>::const_iterator it = viconData.crazyflies.begin(); it != viconData.crazyflies.end(); ++it) { - CrazyflieData global = *it; + // NOTE: THIS FUNCTION IS CALL AT THE FREQUENCY OF THE MOTION + // CAPTURE SYSTEM. HENCE ANY OPTERATIONS PERFORMED IN + // THIS FUNCTION MUST BE NON-BLOCKING. + + // Initilise a variable for the pose data of this agent + CrazyflieData poseDataForThisAgent; + + // Extract the pose data from the full motion capture array + // NOTE: that if the return index is a negative then this + // indicates that the pose data was not found. + m_poseDataIndex = getPoseDataForObjectNameWithExpectedIndex( viconData, m_context.crazyflieName , m_poseDataIndex , poseDataForThisAgent ); + + + + // switch(m_flying_state) + // { + // case STATE_MOTORS_OFF: // here we will put the code of current disabled button + // if(m_changed_flying_state_flag) // stuff that will be run only once when changing state + // { + // m_changed_flying_state_flag = false; + // ROS_INFO("[FLYING AGENT CLIENT] STATE_MOTORS_OFF"); + // } + // break; + // case STATE_TAKE_OFF: //we need to move up from where we are now. + // if(m_changed_flying_state_flag) // stuff that will be run only once when changing state + // { + // m_changed_flying_state_flag = false; + // takeOffCF(local); + // finished_take_off = false; + // ROS_INFO("[FLYING AGENT CLIENT] STATE_TAKE_OFF"); + // timer_takeoff = nodeHandle.createTimer(ros::Duration(yaml_duration_take_off), takeOffTimerCallback, true); + // } + // if(finished_take_off) + // { + // finished_take_off = false; + // setInstantController(getControllerNominallySelected()); + // changeFlyingStateTo(STATE_FLYING); + // } + // break; + // case STATE_FLYING: + // if(m_changed_flying_state_flag) // stuff that will be run only once when changing state + // { + // m_changed_flying_state_flag = false; + // // need to change setpoint to the controller one + // goToControllerSetpoint(); + // ROS_INFO("[FLYING AGENT CLIENT] STATE_FLYING"); + // } + // break; + // case STATE_LAND: + // if(m_changed_flying_state_flag) // stuff that will be run only once when changing state + // { + // m_changed_flying_state_flag = false; + // landCF(local); + // finished_land = false; + // ROS_INFO("[FLYING AGENT CLIENT] STATE_LAND"); + // timer_takeoff = nodeHandle.createTimer(ros::Duration(yaml_duration_landing), landTimerCallback, true); + // } + // if(finished_land) + // { + // finished_land = false; + // setInstantController(getControllerNominallySelected()); + // changeFlyingStateTo(STATE_MOTORS_OFF); + // } + // break; + // default: + // break; + // } + + // Only continue if: + // (1) the pose for this agent was found, and + // (2) the flying state is something other than MOTORS-OFF + if ( + (m_poseDataIndex >= 0) + and + (m_flying_state != STATE_MOTORS_OFF) + and + (m_controllers_avialble) + ) + { + // Initliase the "Contrller" service call variable + Controller controllerCall; - if(global.crazyflieName == context.crazyflieName) - { - Controller controllerCall; - CrazyflieData local = global; - coordinatesToLocal(local); - controllerCall.request.ownCrazyflie = local; + // Fill in the pose data for this agent + controllerCall.request.ownCrazyflie = poseDataForThisAgent; - ros::NodeHandle nodeHandle("~"); + // Initialise a node handle, needed for starting timers + ros::NodeHandle nodeHandle("~"); - switch(flying_state) //things here repeat every X ms, non-blocking stuff + // If the object is NOT occluded, + // then proceed to make the "Controller Service Call" that + // compute the controller output. + if(!poseDataForThisAgent.occluded) + { + // PERFORM THE SAFTY CHECK (IF NOT THE DEFAULT CONTROLLER) + if ( getInstantController() != DEFAULT_CONTROLLER ) { - case STATE_MOTORS_OFF: // here we will put the code of current disabled button - if(changed_state_flag) // stuff that will be run only once when changing state - { - changed_state_flag = false; - ROS_INFO("[FLYING AGENT CLIENT] STATE_MOTORS_OFF"); - } - break; - case STATE_TAKE_OFF: //we need to move up from where we are now. - if(changed_state_flag) // stuff that will be run only once when changing state - { - changed_state_flag = false; - takeOffCF(local); - finished_take_off = false; - ROS_INFO("[FLYING AGENT CLIENT] STATE_TAKE_OFF"); - timer_takeoff = nodeHandle.createTimer(ros::Duration(yaml_duration_take_off), takeOffTimerCallback, true); - } - if(finished_take_off) - { - finished_take_off = false; - setInstantController(getControllerUsed()); - changeFlyingStateTo(STATE_FLYING); - } - break; - case STATE_FLYING: - if(changed_state_flag) // stuff that will be run only once when changing state - { - changed_state_flag = false; - // need to change setpoint to the controller one - goToControllerSetpoint(); - ROS_INFO("[FLYING AGENT CLIENT] STATE_FLYING"); - } - break; - case STATE_LAND: - if(changed_state_flag) // stuff that will be run only once when changing state - { - changed_state_flag = false; - landCF(local); - finished_land = false; - ROS_INFO("[FLYING AGENT CLIENT] STATE_LAND"); - timer_takeoff = nodeHandle.createTimer(ros::Duration(yaml_duration_landing), landTimerCallback, true); - } - if(finished_land) - { - finished_land = false; - setInstantController(getControllerUsed()); - changeFlyingStateTo(STATE_MOTORS_OFF); - } - break; - default: - break; + if ( !safetyCheck(poseDataForThisAgent) ) + { + setInstantController(DEFAULT_CONTROLLER); + ROS_INFO_STREAM("[FLYING AGENT CLIENT] safety check failed, switching to DEFAULT CONTROLLER"); + } } - // control part that should always be running, calls to controller, computation of control output - if(flying_state != STATE_MOTORS_OFF) + // Initialise a local boolean success variable + bool isSuccessful_controllerCall = false; + + // switch( getInstantController() ) + // { + // case DEFAULT_CONTROLLER + // isSuccessful_controllerCall = defaultController.call(controllerCall); + // break; + // case DEMO_CONTROLLER: + // isSuccessful_controllerCall = demoController.call(controllerCall); + // break; + // case STUDENT_CONTROLLER: + // isSuccessful_controllerCall = studentController.call(controllerCall); + // break; + // case MPC_CONTROLLER: + // isSuccessful_controllerCall = mpcController.call(controllerCall); + // break; + // case REMOTE_CONTROLLER: + // isSuccessful_controllerCall = remoteController.call(controllerCall); + // break; + // case TUNING_CONTROLLER: + // isSuccessful_controllerCall = tuningController.call(controllerCall); + // break; + // case PICKER_CONTROLLER: + // isSuccessful_controllerCall = pickerController.call(controllerCall); + // break; + // case TEMPLATE_CONTROLLER: + // isSuccessful_controllerCall = templateController.call(controllerCall); + // break; + // default: + // ROS_ERROR("[FLYING AGENT CLIENT] the current controller was not recognised"); + // break; + // } + + + isSuccessful_controllerCall = m_instant_controller_service_client->call(controllerCall); + + // Ensure success and enforce safety + if(!isSuccessful_controllerCall) { - if(!global.occluded) //if it is not occluded, then proceed to compute the controller output. + //ROS_ERROR("[FLYING AGENT CLIENT] Failed to call a 'non-safe' controller, switching to safe controller"); + //ROS_ERROR_STREAM("[FLYING AGENT CLIENT] 'non-safe' controller status: valid: " << demoController.isValid() << ", exists: " << demoController.exists()); + //ROS_ERROR_STREAM("[FLYING AGENT CLIENT] 'non-safe' controller name: " << demoController.getService()); + + // Let the user know that the controller call failed + ROS_ERROR_STREAM("[FLYING AGENT CLIENT] Failed to call controller, valid: " << m_instant_controller_service_client->isValid() << ", exists: " << m_instant_controller_service_client->exists()); + + // Switch to the default controller, + // if it was not already the active controller + if ( getInstantController() != DEFAULT_CONTROLLER ) { - // Only call an "non-safe" controller if: - // 1) we are not currently using safe controller, AND - // 2) the flying state is FLYING - if( (getInstantController() != SAFE_CONTROLLER) && (flying_state == STATE_FLYING) ) + // Set the DEFAULT controller to be active + setInstantController(DEFAULT_CONTROLLER); + // Try the controller call + isSuccessful_controllerCall = m_instant_controller_service_client->call(controllerCall); + // Inform the user is not successful + if ( !isSuccessful_controllerCall ) { - // Initialise a local boolean success variable - bool success = false; - - switch(getInstantController()) - { - case DEMO_CONTROLLER: - success = demoController.call(controllerCall); - break; - case STUDENT_CONTROLLER: - success = studentController.call(controllerCall); - break; - case MPC_CONTROLLER: - success = mpcController.call(controllerCall); - break; - case REMOTE_CONTROLLER: - success = remoteController.call(controllerCall); - break; - case TUNING_CONTROLLER: - success = tuningController.call(controllerCall); - break; - case PICKER_CONTROLLER: - success = pickerController.call(controllerCall); - break; - case TEMPLATE_CONTROLLER: - success = templateController.call(controllerCall); - break; - default: - ROS_ERROR("[FLYING AGENT CLIENT] the current controller was not recognised"); - break; - } - - // Ensure success and enforce safety - if(!success) - { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to call a 'non-safe' controller, switching to safe controller"); - //ROS_ERROR_STREAM("[FLYING AGENT CLIENT] 'non-safe' controller status: valid: " << demoController.isValid() << ", exists: " << demoController.exists()); - //ROS_ERROR_STREAM("[FLYING AGENT CLIENT] 'non-safe' controller name: " << demoController.getService()); - setInstantController(SAFE_CONTROLLER); - } - else if(!safetyCheck(global, controllerCall.response.controlOutput)) - { - setInstantController(SAFE_CONTROLLER); - ROS_INFO_STREAM("[FLYING AGENT CLIENT] safety check failed, switching to safe controller"); - } - - + ROS_ERROR_STREAM("[FLYING AGENT CLIENT] Also failed to call the DEFAULT controller, valid: " << m_instant_controller_service_client->isValid() << ", exists: " << m_instant_controller_service_client->exists()); } - // SAFE_CONTROLLER and state is different from flying - else - { - calculateDistanceToCurrentSafeSetpoint(local); // update distance, it also updates the unit vector - // ROS_INFO_STREAM("distance: " << distance); - // here, detect if euclidean distance between setpoint and current position is higher than a threshold - if(distance > yaml_distance_threshold) - { - // DEBUGGING: display a message that the crazyflie is inside the thresholds - //ROS_INFO("inside threshold"); - // Declare a local variable for the "setpoint message" to be published - Setpoint setpoint_msg; - // here, where we are now, or where we were in the beginning? - setpoint_msg.x = local.x + yaml_distance_threshold * unit_vector[0]; - setpoint_msg.y = local.y + yaml_distance_threshold * unit_vector[1]; - setpoint_msg.z = local.z + yaml_distance_threshold * unit_vector[2]; - - // yaw is better divided by the number of steps? - setpoint_msg.yaw = current_safe_setpoint.yaw; - safeControllerServiceSetpointPublisher.publish(setpoint_msg); - was_in_threshold = true; - } - else - { - if(was_in_threshold) - { - was_in_threshold = false; - safeControllerServiceSetpointPublisher.publish(current_safe_setpoint); - // goToControllerSetpoint(); //maybe this is a bit repetitive? - } - } - - bool success = safeController.call(controllerCall); - if(!success) { - ROS_ERROR_STREAM("[FLYING AGENT CLIENT] Failed to call safe controller, valid: " << safeController.isValid() << ", exists: " << safeController.exists()); - } - } - - - controlCommandPublisher.publish(controllerCall.response.controlOutput); - - // Putting data into the ROS "bag" for post-analysis - //bag.write("ViconData", ros::Time::now(), local); - //bag.write("ControlOutput", ros::Time::now(), controllerCall.response.controlOutput); } } + + // Send the command to the CrazyRadio + // > IF SUCCESSFUL + if (isSuccessful_controllerCall) + { + commandForSendingToCrazyfliePublisher.publish(controllerCall.response.controlOutput); + } + // > ELSE SEND ZERO OUTPUT COMMAND else { + // Send the command to turn the motors off ControlCommand zeroOutput = ControlCommand(); //everything set to zero zeroOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS; //set to motor_mode - controlCommandPublisher.publish(zeroOutput); - - // Putting data into the ROS "bag" for post-analysis - //bag.write("ViconData", ros::Time::now(), local); - //bag.write("ControlOutput", ros::Time::now(), zeroOutput); + commandForSendingToCrazyfliePublisher.publish(zeroOutput); + // And change the state to motor-off + changeFlyingStateTo(STATE_MOTORS_OFF); } - } - } -} - -void loadCrazyflieContext() { - CMQuery contextCall; - contextCall.request.studentID = m_agentID; - ROS_INFO_STREAM("[FLYING AGENT CLIENT] AgentID:" << m_agentID); + // else if(!safetyCheck(global, controllerCall.response.controlOutput)) + // { + // setInstantController(SAFE_CONTROLLER); + // ROS_INFO_STREAM("[FLYING AGENT CLIENT] safety check failed, switching to safe controller"); + // } + + + + // // Ensure success and enforce safety + // if(!success) + // { + // ROS_ERROR("[FLYING AGENT CLIENT] Failed to call a 'non-safe' controller, switching to safe controller"); + // //ROS_ERROR_STREAM("[FLYING AGENT CLIENT] 'non-safe' controller status: valid: " << demoController.isValid() << ", exists: " << demoController.exists()); + // //ROS_ERROR_STREAM("[FLYING AGENT CLIENT] 'non-safe' controller name: " << demoController.getService()); + // setInstantController(SAFE_CONTROLLER); + // } + // else if(!safetyCheck(global, controllerCall.response.controlOutput)) + // { + // setInstantController(SAFE_CONTROLLER); + // ROS_INFO_STREAM("[FLYING AGENT CLIENT] safety check failed, switching to safe controller"); + // } + + + // } + // // SAFE_CONTROLLER and state is different from flying + // else + // { + // calculateDistanceToCurrentSafeSetpoint(local); // update distance, it also updates the unit vector + // // ROS_INFO_STREAM("distance: " << distance); + // // here, detect if euclidean distance between setpoint and current position is higher than a threshold + // if(distance > yaml_distance_threshold) + // { + // // DEBUGGING: display a message that the crazyflie is inside the thresholds + // //ROS_INFO("inside threshold"); + // // Declare a local variable for the "setpoint message" to be published + // Setpoint setpoint_msg; + // // here, where we are now, or where we were in the beginning? + // setpoint_msg.x = local.x + yaml_distance_threshold * unit_vector[0]; + // setpoint_msg.y = local.y + yaml_distance_threshold * unit_vector[1]; + // setpoint_msg.z = local.z + yaml_distance_threshold * unit_vector[2]; + + // // yaw is better divided by the number of steps? + // setpoint_msg.yaw = current_safe_setpoint.yaw; + // safeControllerServiceSetpointPublisher.publish(setpoint_msg); + // was_in_threshold = true; + // } + // else + // { + // if(was_in_threshold) + // { + // was_in_threshold = false; + // safeControllerServiceSetpointPublisher.publish(current_safe_setpoint); + // // goToControllerSetpoint(); //maybe this is a bit repetitive? + // } + // } + + // bool success = safeController.call(controllerCall); + // if(!success) { + // ROS_ERROR_STREAM("[FLYING AGENT CLIENT] Failed to call safe controller, valid: " << safeController.isValid() << ", exists: " << safeController.exists()); + // } + // } + + // Send the command to the CrazyRadio + //commandForSendingToCrazyfliePublisher.publish(controllerCall.response.controlOutput); + + } // END OF: "if(!global.occluded)" - CrazyflieContext new_context; + } + else + { + // Send the command to turn the motors off + ControlCommand zeroOutput = ControlCommand(); //everything set to zero + zeroOutput.onboardControllerType = CF_COMMAND_TYPE_MOTORS; //set to motor_mode + commandForSendingToCrazyfliePublisher.publish(zeroOutput); - centralManager.waitForExistence(ros::Duration(-1)); + } // END OF: "if ( (m_poseDataIndex >= 0) and (m_flying_state != STATE_MOTORS_OFF) )" - if(centralManager.call(contextCall)) { - new_context = contextCall.response.crazyflieContext; - ROS_INFO_STREAM("[FLYING AGENT CLIENT] CrazyflieContext:\n" << new_context); +} - if((context.crazyflieName != "") && (new_context.crazyflieName != context.crazyflieName)) //linked crazyflie name changed and it was not empty before - { - // Motors off is done in python script now everytime we disconnect - // send motors OFF and disconnect before setting context = new_context - // std_msgs::Int32 msg; - // msg.data = CMD_CRAZYFLY_MOTORS_OFF; - // commandPublisher.publish(msg); - ROS_INFO("[FLYING AGENT CLIENT] CF is now different for this student. Disconnect and turn it off"); - IntWithHeader msg; - msg.shouldCheckForAgentID = false; - msg.data = CMD_DISCONNECT; - crazyRadioCommandPublisher.publish(msg); +int getPoseDataForObjectNameWithExpectedIndex(const ViconData& viconData, std::string name , int expected_index , CrazyflieData& pose_to_fill_in) +{ + // Initialise an integer for the index where the object + // "name" is found + // > Initialise an negative to indicate not found + int object_index = -1; + + // Get the length of the "pose data array" + int length_poseData = viconData.crazyflies.size(); + + // If the "expected index" is non-negative and less than + // the length of the data array, then attempt to check + // for a name match + if ( + (0 <= expected_index) + and + (expected_index < length_poseData) + ) + { + // Check if the names match + if (viconData.crazyflies[expected_index].crazyflieName == m_context.crazyflieName) + { + object_index = expected_index; } + } - context = new_context; + // If not found, then iterate the data array looking + // for a name match + if (object_index < 0) + { + for( int i=0 ; i<length_poseData ; i++ ) + { + // Check if the names match + if(viconData.crazyflies[i].crazyflieName == m_context.crazyflieName) + { + object_index = i; + } + } + } - ros::NodeHandle nh("CrazyRadio"); - nh.setParam("crazyFlieAddress", context.crazyflieAddress); - } + // If not found, then retrun, else fill in the pose data + if (object_index < 0) + { + return object_index; + } else { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to load context. Waiting for next Save in DB by teacher"); - } + pose_to_fill_in = viconData.crazyflies[object_index]; + coordinatesToLocal(pose_to_fill_in); + return object_index; + } } +void coordinatesToLocal(CrazyflieData& cf) +{ + AreaBounds area = m_context.localArea; + float originX = (area.xmin + area.xmax) / 2.0; + float originY = (area.ymin + area.ymax) / 2.0; + // change Z origin to zero, i.e., to the table height, zero of global coordinates, instead of middle of the box + float originZ = 0.0; + // float originZ = (area.zmin + area.zmax) / 2.0; -void commandCallback(const IntWithHeader & msg) { + cf.x -= originX; + cf.y -= originY; + cf.z -= originZ; +} - // Check whether the message is relevant - bool isRevelant = checkMessageHeader( m_agentID , msg.shouldCheckForAgentID , msg.agentIDs ); - // Continue if the message is relevant - if (isRevelant) - { - // Extract the data - int cmd = msg.data; - switch(cmd) { - case CMD_USE_SAFE_CONTROLLER: - ROS_INFO("[FLYING AGENT CLIENT] USE_SAFE_CONTROLLER Command received"); - setControllerUsed(SAFE_CONTROLLER); - break; - case CMD_USE_DEMO_CONTROLLER: - ROS_INFO("[FLYING AGENT CLIENT] USE_DEMO_CONTROLLER Command received"); - setControllerUsed(DEMO_CONTROLLER); - break; - case CMD_USE_STUDENT_CONTROLLER: - ROS_INFO("[FLYING AGENT CLIENT] USE_STUDENT_CONTROLLER Command received"); - setControllerUsed(STUDENT_CONTROLLER); - break; - case CMD_USE_MPC_CONTROLLER: - ROS_INFO("[FLYING AGENT CLIENT] USE_MPC_CONTROLLER Command received"); - setControllerUsed(MPC_CONTROLLER); - break; - case CMD_USE_REMOTE_CONTROLLER: - ROS_INFO("[FLYING AGENT CLIENT] USE_REMOTE_CONTROLLER Command received"); - setControllerUsed(REMOTE_CONTROLLER); - break; - case CMD_USE_TUNING_CONTROLLER: - ROS_INFO("[FLYING AGENT CLIENT] USE_TUNING_CONTROLLER Command received"); - setControllerUsed(TUNING_CONTROLLER); - break; - case CMD_USE_PICKER_CONTROLLER: - ROS_INFO("[FLYING AGENT CLIENT] USE_PICKER_CONTROLLER Command received"); - setControllerUsed(PICKER_CONTROLLER); - break; - - case CMD_USE_TEMPLATE_CONTROLLER: - ROS_INFO("[FLYING AGENT CLIENT] USE_TEMPLATE_CONTROLLER Command received"); - setControllerUsed(TEMPLATE_CONTROLLER); - break; - - case CMD_CRAZYFLY_TAKE_OFF: - ROS_INFO("[FLYING AGENT CLIENT] TAKE_OFF Command received"); - if(flying_state == STATE_MOTORS_OFF) - { - changeFlyingStateTo(STATE_TAKE_OFF); - } - break; - - case CMD_CRAZYFLY_LAND: - ROS_INFO("[FLYING AGENT CLIENT] LAND Command received"); - if(flying_state != STATE_MOTORS_OFF) - { - changeFlyingStateTo(STATE_LAND); - } - break; - case CMD_CRAZYFLY_MOTORS_OFF: - ROS_INFO("[FLYING AGENT CLIENT] MOTORS_OFF Command received"); - changeFlyingStateTo(STATE_MOTORS_OFF); - break; - - default: - ROS_ERROR_STREAM("[FLYING AGENT CLIENT] unexpected command number: " << cmd); - break; - } +void changeFlyingStateTo(int new_state) +{ + if(crazyradio_status == CRAZY_RADIO_STATE_CONNECTED) + { + ROS_INFO("[FLYING AGENT CLIENT] Change state to: %d", new_state); + m_flying_state = new_state; + } + else + { + ROS_INFO("[FLYING AGENT CLIENT] Disconnected and trying to change state. State goes to MOTORS OFF"); + m_flying_state = STATE_MOTORS_OFF; } -} -void crazyflieContextDatabaseChangedCallback(const std_msgs::Int32& msg) -{ - ROS_INFO("[FLYING AGENT CLIENT] Received message that the Context Database Changed"); - loadCrazyflieContext(); -} + // Set the class variable flag that the + // flying state was changed + m_changed_flying_state_flag = true; -void emergencyStopCallback(const IntWithHeader & msg) -{ - ROS_INFO("[FLYING AGENT CLIENT] Received message to EMERGENCY STOP"); - commandCallback(msg); + // Publish a message with the new flying state + std_msgs::Int32 flying_state_msg; + flying_state_msg.data = m_flying_state; + flyingStatePublisher.publish(flying_state_msg); } -//void commandAllAgentsCallback(const std_msgs::Int32& msg) -//{ -// commandCallback(msg); -//} -void crazyRadioStatusCallback(const std_msgs::Int32& msg) -{ - ROS_INFO_STREAM("[FLYING AGENT CLIENT] Received message with Crazy Radio Status = " << msg.data ); - crazyradio_status = msg.data; - // RESET THE BATTERY STATE IF DISCONNECTED - //if (crazyradio_status == CRAZY_RADIO_STATE_DISCONNECTED) - //{ - // setBatteryStateTo(BATTERY_STATE_NORMAL); - //} -} - -void controllerSetPointCallback(const Setpoint& newSetpoint) +void takeOffTimerCallback(const ros::TimerEvent&) { - // load in variable the setpoint - controller_setpoint = newSetpoint; - - // if we are in flying, set it up NOW - if(flying_state == STATE_FLYING) - { - goToControllerSetpoint(); - } + //finished_take_off = true; } -void safeSetPointCallback(const Setpoint& newSetpoint) +void landTimerCallback(const ros::TimerEvent&) { + //finished_land = true; } @@ -583,7 +522,6 @@ void safeSetPointCallback(const Setpoint& newSetpoint) - // ---------------------------------------------------------------------------------- @@ -598,204 +536,411 @@ void safeSetPointCallback(const Setpoint& newSetpoint) -void loadSafeController() { - //ros::NodeHandle nodeHandle("~"); +// void loadSafeController() { +// //ros::NodeHandle nodeHandle("~"); +// ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); +// ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); + +// std::string safeControllerName; +// if(!nodeHandle.getParam("safeController", safeControllerName)) { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get safe controller name"); +// return; +// } + +// ros::service::waitForService(safeControllerName); +// safeController = ros::service::createClient<Controller>(safeControllerName, true); +// ROS_INFO_STREAM("[FLYING AGENT CLIENT] loaded safe controller: " << safeController.getService()); +// } + +// void loadDemoController() +// { +// //ros::NodeHandle nodeHandle("~"); +// ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); +// ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); + +// std::string demoControllerName; +// if(!nodeHandle.getParam("demoController", demoControllerName)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get demo controller name"); +// return; +// } + +// demoController = ros::service::createClient<Controller>(demoControllerName, true); +// ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded demo controller " << demoController.getService()); +// } + +// void loadStudentController() +// { +// //ros::NodeHandle nodeHandle("~"); +// ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); +// ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); + +// std::string studentControllerName; +// if(!nodeHandle.getParam("studentController", studentControllerName)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get student controller name"); +// return; +// } + +// studentController = ros::service::createClient<Controller>(studentControllerName, true); +// ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded student controller " << studentController.getService()); +// } + +// void loadMpcController() +// { +// //ros::NodeHandle nodeHandle("~"); +// ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); +// ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); + +// std::string mpcControllerName; +// if(!nodeHandle.getParam("mpcController", mpcControllerName)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get mpc controller name"); +// return; +// } + +// mpcController = ros::service::createClient<Controller>(mpcControllerName, true); +// ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded mpc controller " << mpcController.getService()); +// } + +// void loadRemoteController() +// { +// //ros::NodeHandle nodeHandle("~"); +// ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); +// ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); + +// std::string remoteControllerName; +// if(!nodeHandle.getParam("remoteController", remoteControllerName)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get remote controller name"); +// return; +// } + +// remoteController = ros::service::createClient<Controller>(remoteControllerName, true); +// ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded remote controller " << remoteController.getService()); +// } + +// void loadTuningController() +// { +// //ros::NodeHandle nodeHandle("~"); +// ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); +// ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); + +// std::string tuningControllerName; +// if(!nodeHandle.getParam("tuningController", tuningControllerName)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get tuning controller name"); +// return; +// } + +// tuningController = ros::service::createClient<Controller>(tuningControllerName, true); +// ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded tuning controller " << tuningController.getService()); +// } + +// void loadPickerController() +// { +// //ros::NodeHandle nodeHandle("~"); +// ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); +// ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); + +// std::string pickerControllerName; +// if(!nodeHandle.getParam("pickerController", pickerControllerName)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get picker controller name"); +// return; +// } + +// pickerController = ros::service::createClient<Controller>(pickerControllerName, true); +// ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded picker controller " << pickerController.getService()); +// } + +// void loadTemplateController() +// { +// //ros::NodeHandle nodeHandle("~"); +// ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); +// ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); + +// std::string templateControllerName; +// if(!nodeHandle.getParam("templateController", templateControllerName)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get template controller name"); +// return; +// } + +// templateController = ros::service::createClient<Controller>(templateControllerName, true); +// ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded template controller " << templateController.getService()); +// } + + + + + +// CREATE A SERVICE CLIENT +// NOTE: the second argument is a boolean that specifies whether the +// service is persistent or not. In the ROS documentation a +// persistent connection is described as: +// "Persistent connections should be used carefully. They greatly +// improve performance for repeated requests, but they also make +// your client more fragile to service failures. Clients using +// persistent connections should implement their own reconnection +// logic in the event that the persistent connection fails." +void loadController( std::string paramter_name , ros::ServiceClient& serviceClient ) +{ ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); - std::string safeControllerName; - if(!nodeHandle.getParam("safeController", safeControllerName)) { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get safe controller name"); + std::string controllerName; + if(!nodeHandle.getParam(paramter_name, controllerName)) + { + ROS_ERROR_STREAM("[FLYING AGENT CLIENT] Failed to get \"" << paramter_name << "\" paramter"); return; } - ros::service::waitForService(safeControllerName); - safeController = ros::service::createClient<Controller>(safeControllerName, true); - ROS_INFO_STREAM("[FLYING AGENT CLIENT] loaded safe controller: " << safeController.getService()); + serviceClient = ros::service::createClient<Controller>(controllerName, true); + ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded service: " << serviceClient.getService() << ", valid: " << serviceClient.isValid() << ", exists: " << serviceClient.exists() ); } -void loadDemoController() -{ - //ros::NodeHandle nodeHandle("~"); - ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); - ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); - std::string demoControllerName; - if(!nodeHandle.getParam("demoController", demoControllerName)) - { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get demo controller name"); - return; - } - demoController = ros::service::createClient<Controller>(demoControllerName, true); - ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded demo controller " << demoController.getService()); + + +void sendMessageUsingController(int controller) +{ + // Send a message on the topic for informing the Flying + // Agent GUI about this update + std_msgs::Int32 controller_used_msg; + controller_used_msg.data = controller; + controllerUsedPublisher.publish(controller_used_msg); } -void loadStudentController() +void setInstantController(int controller) //for right now, temporal use { - //ros::NodeHandle nodeHandle("~"); - ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); - ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); + // Update the class variable + m_instant_controller = controller; + + - std::string studentControllerName; - if(!nodeHandle.getParam("studentController", studentControllerName)) + switch(controller) { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get student controller name"); - return; + case DEFAULT_CONTROLLER: + m_instant_controller_service_client = &defaultController; + break; + case STUDENT_CONTROLLER: + m_instant_controller_service_client = &studentController; + break; + case TUNING_CONTROLLER: + m_instant_controller_service_client = &tuningController; + break; + case PICKER_CONTROLLER: + m_instant_controller_service_client = &pickerController; + break; + case TEMPLATE_CONTROLLER: + m_instant_controller_service_client = &templateController; + break; + default: + break; } - studentController = ros::service::createClient<Controller>(studentControllerName, true); - ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded student controller " << studentController.getService()); + sendMessageUsingController(controller); + // switch(controller) + // { + // case SAFE_CONTROLLER: + // loadSafeController(); + // break; + // case DEMO_CONTROLLER: + // loadDemoController(); + // break; + // case STUDENT_CONTROLLER: + // loadStudentController(); + // break; + // case MPC_CONTROLLER: + // loadMpcController(); + // break; + // case REMOTE_CONTROLLER: + // loadRemoteController(); + // break; + // case TUNING_CONTROLLER: + // loadTuningController(); + // break; + // case PICKER_CONTROLLER: + // loadPickerController(); + // break; + // case TEMPLATE_CONTROLLER: + // loadTemplateController(); + // break; + // default: + // break; + // } } -void loadMpcController() +int getInstantController() { - //ros::NodeHandle nodeHandle("~"); - ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); - ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); + return m_instant_controller; +} + +void setControllerNominallySelected(int controller) +{ + // Update the class variable + m_controller_nominally_selected = controller; - std::string mpcControllerName; - if(!nodeHandle.getParam("mpcController", mpcControllerName)) + // If in state "MOTORS-OFF" or "FLYING", + // then the change is instant. + if(m_flying_state == STATE_MOTORS_OFF || m_flying_state == STATE_FLYING) { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get mpc controller name"); - return; - } - mpcController = ros::service::createClient<Controller>(mpcControllerName, true); - ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded mpc controller " << mpcController.getService()); + setInstantController(controller); + } } -void loadRemoteController() +int getControllerNominallySelected() { - //ros::NodeHandle nodeHandle("~"); - ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); - ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); + return m_controller_nominally_selected; +} + + + - std::string remoteControllerName; - if(!nodeHandle.getParam("remoteController", remoteControllerName)) + + + + + + +void flyingStateRequestCallback(const IntWithHeader & msg) { + + // Check whether the message is relevant + bool isRevelant = checkMessageHeader( m_agentID , msg.shouldCheckForAgentID , msg.agentIDs ); + + // Continue if the message is relevant + if (isRevelant) { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get remote controller name"); - return; + // Extract the data + int cmd = msg.data; + + switch(cmd) { + case CMD_USE_DEFAULT_CONTROLLER: + ROS_INFO("[FLYING AGENT CLIENT] USE_DEFAULT_CONTROLLER Command received"); + setControllerNominallySelected(DEFAULT_CONTROLLER); + break; + + case CMD_USE_DEMO_CONTROLLER: + ROS_INFO("[FLYING AGENT CLIENT] USE_DEMO_CONTROLLER Command received"); + setControllerNominallySelected(DEMO_CONTROLLER); + break; + + case CMD_USE_STUDENT_CONTROLLER: + ROS_INFO("[FLYING AGENT CLIENT] USE_STUDENT_CONTROLLER Command received"); + setControllerNominallySelected(STUDENT_CONTROLLER); + break; + + case CMD_USE_MPC_CONTROLLER: + ROS_INFO("[FLYING AGENT CLIENT] USE_MPC_CONTROLLER Command received"); + setControllerNominallySelected(MPC_CONTROLLER); + break; + + case CMD_USE_REMOTE_CONTROLLER: + ROS_INFO("[FLYING AGENT CLIENT] USE_REMOTE_CONTROLLER Command received"); + setControllerNominallySelected(REMOTE_CONTROLLER); + break; + + case CMD_USE_TUNING_CONTROLLER: + ROS_INFO("[FLYING AGENT CLIENT] USE_TUNING_CONTROLLER Command received"); + setControllerNominallySelected(TUNING_CONTROLLER); + break; + + case CMD_USE_PICKER_CONTROLLER: + ROS_INFO("[FLYING AGENT CLIENT] USE_PICKER_CONTROLLER Command received"); + setControllerNominallySelected(PICKER_CONTROLLER); + break; + + case CMD_USE_TEMPLATE_CONTROLLER: + ROS_INFO("[FLYING AGENT CLIENT] USE_TEMPLATE_CONTROLLER Command received"); + setControllerNominallySelected(TEMPLATE_CONTROLLER); + break; + + case CMD_CRAZYFLY_TAKE_OFF: + ROS_INFO("[FLYING AGENT CLIENT] TAKE_OFF Command received"); + if(m_flying_state == STATE_MOTORS_OFF) + { + changeFlyingStateTo(STATE_TAKE_OFF); + } + break; + + case CMD_CRAZYFLY_LAND: + ROS_INFO("[FLYING AGENT CLIENT] LAND Command received"); + if(m_flying_state != STATE_MOTORS_OFF) + { + changeFlyingStateTo(STATE_LAND); + } + break; + case CMD_CRAZYFLY_MOTORS_OFF: + ROS_INFO("[FLYING AGENT CLIENT] MOTORS_OFF Command received"); + changeFlyingStateTo(STATE_MOTORS_OFF); + break; + + default: + ROS_ERROR_STREAM("[FLYING AGENT CLIENT] unexpected command number: " << cmd); + break; + } } +} + + - remoteController = ros::service::createClient<Controller>(remoteControllerName, true); - ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded remote controller " << remoteController.getService()); + + + + + +void crazyRadioStatusCallback(const std_msgs::Int32& msg) +{ + ROS_INFO_STREAM("[FLYING AGENT CLIENT] Received message with Crazy Radio Status = " << msg.data ); + crazyradio_status = msg.data; } -void loadTuningController() -{ - //ros::NodeHandle nodeHandle("~"); - ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); - ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); - std::string tuningControllerName; - if(!nodeHandle.getParam("tuningController", tuningControllerName)) - { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get tuning controller name"); - return; - } - tuningController = ros::service::createClient<Controller>(tuningControllerName, true); - ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded tuning controller " << tuningController.getService()); -} -void loadPickerController() -{ - //ros::NodeHandle nodeHandle("~"); - ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); - ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); - std::string pickerControllerName; - if(!nodeHandle.getParam("pickerController", pickerControllerName)) - { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get picker controller name"); - return; - } - pickerController = ros::service::createClient<Controller>(pickerControllerName, true); - ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded picker controller " << pickerController.getService()); +void emergencyStopReceivedCallback(const IntWithHeader & msg) +{ + ROS_INFO("[FLYING AGENT CLIENT] Received message to EMERGENCY STOP"); + flyingStateRequestCallback(msg); } -void loadTemplateController() -{ - //ros::NodeHandle nodeHandle("~"); - ros::NodeHandle nodeHandle_to_own_agent_parameter_service(m_namespace_to_own_agent_parameter_service); - ros::NodeHandle nodeHandle(nodeHandle_to_own_agent_parameter_service, "ClientConfig"); - std::string templateControllerName; - if(!nodeHandle.getParam("templateController", templateControllerName)) - { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get template controller name"); - return; - } - templateController = ros::service::createClient<Controller>(templateControllerName, true); - ROS_INFO_STREAM("[FLYING AGENT CLIENT] Loaded template controller " << templateController.getService()); -} -void sendMessageUsingController(int controller) -{ - // Send a message on the topic for informing the Flying - // Agent GUI about this update - std_msgs::Int32 controller_used_msg; - controller_used_msg.data = controller; - controllerUsedPublisher.publish(controller_used_msg); -} -void setInstantController(int controller) //for right now, temporal use -{ - instant_controller = controller; - sendMessageUsingController(controller); - switch(controller) - { - case SAFE_CONTROLLER: - loadSafeController(); - break; - case DEMO_CONTROLLER: - loadDemoController(); - break; - case STUDENT_CONTROLLER: - loadStudentController(); - break; - case MPC_CONTROLLER: - loadMpcController(); - break; - case REMOTE_CONTROLLER: - loadRemoteController(); - break; - case TUNING_CONTROLLER: - loadTuningController(); - break; - case PICKER_CONTROLLER: - loadPickerController(); - break; - case TEMPLATE_CONTROLLER: - loadTemplateController(); - break; - default: - break; - } -} -int getInstantController() +// ---------------------------------------------------------------------------------- +// GGGG EEEEE TTTTT SSSS TTTTT A TTTTT U U SSSS +// G E T S T A A T U U S +// G EEE T SSS T A A T U U SSS +// G G E T S T AAAAA T U U S +// GGGG EEEEE T SSSS T A A T UUU SSSS +// +// CCCC A L L BBBB A CCCC K K SSSS +// C A A L L B B A A C K K S +// C A A L L BBBB A A C KKK SSS +// C AAAAA L L B B AAAAA C K K S +// CCCC A A LLLLL LLLLL BBBB A A CCCC K K SSSS +// ---------------------------------------------------------------------------------- + +bool getCurrentFlyingStateServiceCallback(IntIntService::Request &request, IntIntService::Response &response) { - return instant_controller; + // Put the flying state into the response variable + response.data = m_flying_state; + // Return + return true; } -void setControllerUsed(int controller) //for permanent configs -{ - controller_used = controller; - if(flying_state == STATE_MOTORS_OFF || flying_state == STATE_FLYING) - { - setInstantController(controller); //if motors OFF or STATE FLYING, transparent, change is instant - } -} -int getControllerUsed() -{ - return controller_used; -} + + + @@ -810,8 +955,6 @@ int getControllerUsed() // BBBB A A T T EEEEE R R Y // ---------------------------------------------------------------------------------- - - void batteryMonitorStateChangedCallback(std_msgs::Int32 msg) { // Extract the data @@ -820,7 +963,7 @@ void batteryMonitorStateChangedCallback(std_msgs::Int32 msg) // Take action if changed to low battery state if (new_battery_state == BATTERY_STATE_LOW) { - if (flying_state != STATE_MOTORS_OFF) + if (m_flying_state != STATE_MOTORS_OFF) { ROS_INFO("[FLYING AGENT CLIENT] low level battery triggered, now landing."); changeFlyingStateTo(STATE_LAND); @@ -843,126 +986,149 @@ void batteryMonitorStateChangedCallback(std_msgs::Int32 msg) -/* -int getBatteryState() -{ - return m_battery_state; -} -void setBatteryStateTo(int new_battery_state) + + +// ---------------------------------------------------------------------------------- +// SSSS A FFFFF EEEEE TTTTT Y Y +// S A A F E T Y Y +// SSS A A FFF EEE T Y +// S AAAAA F E T Y +// SSSS A A F EEEEE T Y +// +// CCCC H H EEEEE CCCC K K SSSS +// C H H E C K K S +// C HHHHH EEE C KKK SSS +// C H H E C K K S +// CCCC H H EEEEE CCCC K K SSSS +// ---------------------------------------------------------------------------------- + +// Checks if crazyflie is within allowed area +bool safetyCheck(CrazyflieData data) { - switch(new_battery_state) + // Check on the X position + if((data.x < m_context.localArea.xmin) or (data.x > m_context.localArea.xmax)) { - case BATTERY_STATE_NORMAL: - m_battery_state = BATTERY_STATE_NORMAL; - ROS_INFO("[FLYING AGENT CLIENT] changed battery state to normal"); - break; - case BATTERY_STATE_LOW: - m_battery_state = BATTERY_STATE_LOW; - ROS_INFO("[FLYING AGENT CLIENT] changed battery state to low"); - if(flying_state != STATE_MOTORS_OFF) - changeFlyingStateTo(STATE_LAND); - break; - default: - ROS_INFO("[FLYING AGENT CLIENT] Unknown battery state command, set to normal"); - m_battery_state = BATTERY_STATE_NORMAL; - break; + ROS_INFO_STREAM("[FLYING AGENT CLIENT] x safety failed"); + return false; + } + // Check on the Y position + if((data.y < m_context.localArea.ymin) or (data.y > m_context.localArea.ymax)) + { + ROS_INFO_STREAM("[FLYING AGENT CLIENT] y safety failed"); + return false; + } + // Check on the Z position + if((data.z < m_context.localArea.zmin) or (data.z > m_context.localArea.zmax)) + { + ROS_INFO_STREAM("[FLYING AGENT CLIENT] z safety failed"); + return false; + } + + // Check the title angle (if required) + // > The tilt anlge between the body frame and inertial frame z-axis is + // give by: + // tilt angle = 1 / ( cos(roll)*cos(pitch) ) + // > But this would be too sensitve to a divide by zero error, so instead + // we just check if each angle separately exceeds the limit + if(yaml_isEnabled_strictSafety) + { + // Check on the ROLL angle + if( + (data.roll > m_maxTiltAngle_for_strictSafety_redians) + or + (data.roll < -m_maxTiltAngle_for_strictSafety_redians) + ) + { + ROS_INFO_STREAM("[FLYING AGENT CLIENT] roll too big."); + return false; + } + // Check on the PITCH angle + if( + (data.pitch > m_maxTiltAngle_for_strictSafety_redians) + or + (data.pitch < -m_maxTiltAngle_for_strictSafety_redians) + ) + { + ROS_INFO_STREAM("[FLYING AGENT CLIENT] pitch too big."); + return false; + } } - std_msgs::Int32 battery_state_msg; - battery_state_msg.data = getBatteryState(); - batteryStatePublisher.publish(battery_state_msg); + // If the code makes it to here then all the safety checks passed, + // Hence return "true" + return true; } -float movingAverageBatteryFilter(float new_input) -{ - const int N = 7; - static float previous_output = 4.2f; - static float inputs[N] = {4.2f,4.2f,4.2f,4.2f,4.2f,4.2f,4.2f}; - // imagine an array of an even number of samples, we will output the one - // in the middle averaged with information from all of them. - // For that, we only need to store some past of the signal - float output = previous_output + new_input/N - inputs[N-1]/N; - // update array of inputs - for(int i = N - 1; i > 0; i--) - { - inputs[i] = inputs[i-1]; - } - inputs[0] = new_input; + +// ---------------------------------------------------------------------------------- +// L OOO A DDDD +// L O O A A D D +// L O O A A D D +// L O O AAAAA D D +// LLLLL OOO A A DDDD +// +// CCCC OOO N N TTTTT EEEEE X X TTTTT +// C O O NN N T E X X T +// C O O N N N T EEE X T +// C O O N NN T E X X T +// CCCC OOO N N T EEEEE X X T +// ---------------------------------------------------------------------------------- - // update previous output - previous_output = output; - return output; +void crazyflieContextDatabaseChangedCallback(const std_msgs::Int32& msg) +{ + ROS_INFO("[FLYING AGENT CLIENT] Received message that the Context Database Changed"); + loadCrazyflieContext(); } -void CFBatteryCallback(const std_msgs::Float32& msg) + +void loadCrazyflieContext() { - m_battery_voltage = msg.data; - // filter and check if inside limits, and if, change status - // need to do the filtering first - float filtered_battery_voltage = movingAverageBatteryFilter(m_battery_voltage); //need to perform filtering here - - // ROS_INFO_STREAM("filtered data: " << filtered_battery_voltage); - if( - (flying_state != STATE_MOTORS_OFF && (filtered_battery_voltage < m_battery_threshold_while_flying)) - || - (flying_state == STATE_MOTORS_OFF && (filtered_battery_voltage < m_battery_threshold_while_motors_off)) - ) - { - if(getBatteryState() != BATTERY_STATE_LOW) - { - setBatteryStateTo(BATTERY_STATE_LOW); - ROS_INFO("[FLYING AGENT CLIENT] low level battery triggered"); - } - - } - else - { - // TO AVOID BEING ABLE TO IMMEDIATELY TAKE-OFF AFTER A - // "BATTERY LOW" EVENT IS TRIGGERED, WE DO NOT SET THE - // BATTERY STATE BACK TO NORMAL - // if(getBatteryState() != BATTERY_STATE_NORMAL) - // { - // setBatteryStateTo(BATTERY_STATE_NORMAL); - // } - } -} -*/ + CMQuery contextCall; + contextCall.request.studentID = m_agentID; + ROS_INFO_STREAM("[FLYING AGENT CLIENT] AgentID:" << m_agentID); + CrazyflieContext new_context; + centralManager.waitForExistence(ros::Duration(-1)); + if(centralManager.call(contextCall)) { + new_context = contextCall.response.crazyflieContext; + ROS_INFO_STREAM("[FLYING AGENT CLIENT] CrazyflieContext:\n" << new_context); + if((m_context.crazyflieName != "") && (new_context.crazyflieName != m_context.crazyflieName)) //linked crazyflie name changed and it was not empty before + { + // Motors off is done in python script now everytime we disconnect + // send motors OFF and disconnect before setting m_context = new_context + // std_msgs::Int32 msg; + // msg.data = CMD_CRAZYFLY_MOTORS_OFF; + // commandPublisher.publish(msg); + ROS_INFO("[FLYING AGENT CLIENT] CF is now different for this student. Disconnect and turn it off"); + IntWithHeader msg; + msg.shouldCheckForAgentID = false; + msg.data = CMD_DISCONNECT; + crazyRadioCommandPublisher.publish(msg); + } -// ---------------------------------------------------------------------------------- -// GGGG EEEEE TTTTT SSSS TTTTT A TTTTT U U SSSS -// G E T S T A A T U U S -// G EEE T SSS T A A T U U SSS -// G G E T S T AAAAA T U U S -// GGGG EEEEE T SSSS T A A T UUU SSSS -// -// CCCC A L L BBBB A CCCC K K SSSS -// C A A L L B B A A C K K S -// C A A L L BBBB A A C KKK SSS -// C AAAAA L L B B AAAAA C K K S -// CCCC A A LLLLL LLLLL BBBB A A CCCC K K SSSS -// ---------------------------------------------------------------------------------- + m_context = new_context; -bool getCurrentFlyingStateServiceCallback(IntIntService::Request &request, IntIntService::Response &response) -{ - // Put the flying state into the response variable - response.data = flying_state; - // Return - return true; + ros::NodeHandle nh("CrazyRadio"); + nh.setParam("crazyFlieAddress", m_context.crazyflieAddress); + } + else + { + ROS_ERROR("[FLYING AGENT CLIENT] Failed to load context. Waiting for next Save in DB by teacher"); + } } @@ -971,7 +1137,6 @@ bool getCurrentFlyingStateServiceCallback(IntIntService::Request &request, IntIn - // ---------------------------------------------------------------------------------- // L OOO A DDDD // L O O A A D D @@ -988,105 +1153,105 @@ bool getCurrentFlyingStateServiceCallback(IntIntService::Request &request, IntIn -void isReadySafeControllerYamlCallback(const IntWithHeader & msg) -{ - // Check whether the message is relevant - bool isRevelant = checkMessageHeader( m_agentID , msg.shouldCheckForAgentID , msg.agentIDs ); - - // Continue if the message is relevant - if (isRevelant) - { - // Extract the data - int parameter_service_to_load_from = msg.data; - // Initialise a local variable for the namespace - std::string namespace_to_use; - // Load from the respective parameter service - switch(parameter_service_to_load_from) - { - // > FOR FETCHING FROM THE AGENT'S OWN PARAMETER SERVICE - case LOAD_YAML_FROM_AGENT: - { - ROS_INFO("[FLYING AGENT CLIENT] Now fetching the SafeController YAML parameter values from this agent."); - namespace_to_use = m_namespace_to_own_agent_parameter_service; - break; - } - // > FOR FETCHING FROM THE COORDINATOR'S PARAMETER SERVICE - case LOAD_YAML_FROM_COORDINATOR: - { - ROS_INFO("[FLYING AGENT CLIENT] Now fetching the SafeController YAML parameter values from this agent's coordinator."); - namespace_to_use = m_namespace_to_coordinator_parameter_service; - break; - } - - default: - { - ROS_ERROR("[FLYING AGENT CLIENT] Paramter service to load from was NOT recognised."); - namespace_to_use = m_namespace_to_own_agent_parameter_service; - break; - } - } - // Create a node handle to the selected parameter service - ros::NodeHandle nodeHandle_to_use(namespace_to_use); - // Call the function that fetches the parameters - fetchSafeControllerYamlParameters(nodeHandle_to_use); - } -} - - - -void fetchSafeControllerYamlParameters(ros::NodeHandle& nodeHandle) -{ - // Here we load the parameters that are specified in the file: - // SafeController.yaml - - // Add the "SafeController" namespace to the "nodeHandle" - ros::NodeHandle nodeHandle_for_paramaters(nodeHandle, "SafeController"); - - // take off and landing parameters (in meters and seconds) - yaml_take_off_distance = getParameterFloat(nodeHandle_for_paramaters,"takeOffDistance"); - yaml_landing_distance = getParameterFloat(nodeHandle_for_paramaters,"landingDistance"); - yaml_duration_take_off = getParameterFloat(nodeHandle_for_paramaters,"durationTakeOff"); - yaml_duration_landing = getParameterFloat(nodeHandle_for_paramaters,"durationLanding"); - yaml_distance_threshold = getParameterFloat(nodeHandle_for_paramaters,"distanceThreshold"); - - // setpoint in meters (x, y, z, yaw) - getParameterFloatVector(nodeHandle_for_paramaters,"defaultSetpoint",yaml_default_setpoint,4); - - // DEBUGGING: Print out one of the parameters that was loaded - ROS_INFO_STREAM("[FLYING AGENT CLIENT] DEBUGGING: the fetched SafeController/durationTakeOff = " << yaml_duration_take_off); - - /* - // Here we load the parameters that are specified in the SafeController.yaml file - - // Add the "SafeController" namespace to the "nodeHandle" - ros::NodeHandle nodeHandle_for_safeController(nodeHandle, "SafeController"); - - if(!nodeHandle_for_safeController.getParam("takeOffDistance", take_off_distance)) - { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get takeOffDistance"); - } - - if(!nodeHandle_for_safeController.getParam("landingDistance", landing_distance)) - { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get landing_distance"); - } - - if(!nodeHandle_for_safeController.getParam("durationTakeOff", duration_take_off)) - { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get duration_take_off"); - } - - if(!nodeHandle_for_safeController.getParam("durationLanding", duration_landing)) - { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get duration_landing"); - } - - if(!nodeHandle_for_safeController.getParam("distanceThreshold", distance_threshold)) - { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get distance_threshold"); - } - */ -} +// void isReadySafeControllerYamlCallback(const IntWithHeader & msg) +// { +// // Check whether the message is relevant +// bool isRevelant = checkMessageHeader( m_agentID , msg.shouldCheckForAgentID , msg.agentIDs ); + +// // Continue if the message is relevant +// if (isRevelant) +// { +// // Extract the data +// int parameter_service_to_load_from = msg.data; +// // Initialise a local variable for the namespace +// std::string namespace_to_use; +// // Load from the respective parameter service +// switch(parameter_service_to_load_from) +// { +// // > FOR FETCHING FROM THE AGENT'S OWN PARAMETER SERVICE +// case LOAD_YAML_FROM_AGENT: +// { +// ROS_INFO("[FLYING AGENT CLIENT] Now fetching the SafeController YAML parameter values from this agent."); +// namespace_to_use = m_namespace_to_own_agent_parameter_service; +// break; +// } +// // > FOR FETCHING FROM THE COORDINATOR'S PARAMETER SERVICE +// case LOAD_YAML_FROM_COORDINATOR: +// { +// ROS_INFO("[FLYING AGENT CLIENT] Now fetching the SafeController YAML parameter values from this agent's coordinator."); +// namespace_to_use = m_namespace_to_coordinator_parameter_service; +// break; +// } + +// default: +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Paramter service to load from was NOT recognised."); +// namespace_to_use = m_namespace_to_own_agent_parameter_service; +// break; +// } +// } +// // Create a node handle to the selected parameter service +// ros::NodeHandle nodeHandle_to_use(namespace_to_use); +// // Call the function that fetches the parameters +// fetchSafeControllerYamlParameters(nodeHandle_to_use); +// } +// } + + + +// void fetchSafeControllerYamlParameters(ros::NodeHandle& nodeHandle) +// { +// // Here we load the parameters that are specified in the file: +// // SafeController.yaml + +// // Add the "SafeController" namespace to the "nodeHandle" +// ros::NodeHandle nodeHandle_for_paramaters(nodeHandle, "SafeController"); + +// // take off and landing parameters (in meters and seconds) +// yaml_take_off_distance = getParameterFloat(nodeHandle_for_paramaters,"takeOffDistance"); +// yaml_landing_distance = getParameterFloat(nodeHandle_for_paramaters,"landingDistance"); +// yaml_duration_take_off = getParameterFloat(nodeHandle_for_paramaters,"durationTakeOff"); +// yaml_duration_landing = getParameterFloat(nodeHandle_for_paramaters,"durationLanding"); +// yaml_distance_threshold = getParameterFloat(nodeHandle_for_paramaters,"distanceThreshold"); + +// // setpoint in meters (x, y, z, yaw) +// getParameterFloatVector(nodeHandle_for_paramaters,"defaultSetpoint",yaml_default_setpoint,4); + +// // DEBUGGING: Print out one of the parameters that was loaded +// ROS_INFO_STREAM("[FLYING AGENT CLIENT] DEBUGGING: the fetched SafeController/durationTakeOff = " << yaml_duration_take_off); + +// /* +// // Here we load the parameters that are specified in the SafeController.yaml file + +// // Add the "SafeController" namespace to the "nodeHandle" +// ros::NodeHandle nodeHandle_for_safeController(nodeHandle, "SafeController"); + +// if(!nodeHandle_for_safeController.getParam("takeOffDistance", take_off_distance)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get takeOffDistance"); +// } + +// if(!nodeHandle_for_safeController.getParam("landingDistance", landing_distance)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get landing_distance"); +// } + +// if(!nodeHandle_for_safeController.getParam("durationTakeOff", duration_take_off)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get duration_take_off"); +// } + +// if(!nodeHandle_for_safeController.getParam("durationLanding", duration_landing)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get duration_landing"); +// } + +// if(!nodeHandle_for_safeController.getParam("distanceThreshold", distance_threshold)) +// { +// ROS_ERROR("[FLYING AGENT CLIENT] Failed to get distance_threshold"); +// } +// */ +// } @@ -1147,40 +1312,44 @@ void fetchClientConfigYamlParameters(ros::NodeHandle& nodeHandle) ros::NodeHandle nodeHandle_for_paramaters(nodeHandle, "ClientConfig"); // Flag for whether to use angle for switching to the Safe Controller - yaml_strictSafety = getParameterBool(nodeHandle_for_paramaters,"strictSafety"); - yaml_angleMargin = getParameterFloat(nodeHandle_for_paramaters,"angleMargin"); + yaml_isEnabled_strictSafety = getParameterBool(nodeHandle_for_paramaters,"isEnabled_strictSafety"); + yaml_maxTiltAngle_for_strictSafety_degrees = getParameterFloat(nodeHandle_for_paramaters,"maxTiltAngle_for_strictSafety_degrees"); - - // DEBUGGING: Print out one of the parameters that was loaded - ROS_INFO_STREAM("[FLYING AGENT CLIENT] DEBUGGING: the fetched ClientConfig/strictSafety = " << yaml_strictSafety); + ROS_INFO_STREAM("[FLYING AGENT CLIENT] DEBUGGING: the fetched ClientConfig/isEnabled_strictSafety = " << yaml_isEnabled_strictSafety); - /* - if(!nodeHandle.getParam("strictSafety", strictSafety)) { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get strictSafety param"); - return; - } - if(!nodeHandle.getParam("angleMargin", angleMargin)) { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get angleMargin param"); - return; - } + // PROCESS THE PARAMTERS + // Convert from degrees to radians + m_maxTiltAngle_for_strictSafety_redians = DEG2RAD * yaml_maxTiltAngle_for_strictSafety_degrees; - if(!nodeHandle.getParam("battery_threshold_while_flying", m_battery_threshold_while_flying)) { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get battery_threshold_while_flying param"); - return; - } - if(!nodeHandle.getParam("battery_threshold_while_motors_off", m_battery_threshold_while_motors_off)) { - ROS_ERROR("[FLYING AGENT CLIENT] Failed to get battery_threshold_while_motors_off param"); - return; - } - */ + // DEBUGGING: Print out one of the processed values + ROS_INFO_STREAM("[PICKER CONTROLLER] DEBUGGING: after processing m_maxTiltAngle_for_strictSafety_redians = " << m_maxTiltAngle_for_strictSafety_redians); } +void timerCallback_for_loadAllControllers(const ros::TimerEvent&) +{ + // INITIALISE ALL THE CONTROLLER SERVICE CLIENTS + loadController( "defaultController" , defaultController ); + loadController( "studentController" , studentController ); + loadController( "tuningController" , tuningController ); + loadController( "pickerController" , pickerController ); + loadController( "templateController" , templateController ); + + if (defaultController) + { + m_controllers_avialble = true; + } + else + { + m_controllers_avialble = false; + } +} + // ---------------------------------------------------------------------------------- // M M A III N N @@ -1250,8 +1419,8 @@ int main(int argc, char* argv[]) ros::Subscriber clientConfig_yamlReady_fromAgent = nodeHandle_to_own_agent_parameter_service.subscribe( "ClientConfig", 1, isReadyClientConfigYamlCallback); ros::Subscriber clientConfig_yamlReady_fromCoord = nodeHandle_to_coordinator_parameter_service.subscribe("ClientConfig", 1, isReadyClientConfigYamlCallback); - ros::Subscriber safeController_yamlReady_fromAgent = nodeHandle_to_own_agent_parameter_service.subscribe( "SafeController", 1, isReadySafeControllerYamlCallback); - ros::Subscriber safeController_yamlReady_fromCoord = nodeHandle_to_coordinator_parameter_service.subscribe("SafeController", 1, isReadySafeControllerYamlCallback); + //ros::Subscriber safeController_yamlReady_fromAgent = nodeHandle_to_own_agent_parameter_service.subscribe( "SafeController", 1, isReadySafeControllerYamlCallback); + //ros::Subscriber safeController_yamlReady_fromCoord = nodeHandle_to_coordinator_parameter_service.subscribe("SafeController", 1, isReadySafeControllerYamlCallback); @@ -1266,53 +1435,19 @@ int main(int argc, char* argv[]) // Call the class function that loads the parameters for this class. fetchClientConfigYamlParameters(nodeHandle_to_own_agent_parameter_service); - fetchSafeControllerYamlParameters(nodeHandle_to_own_agent_parameter_service); - - - // THIS IS THE "NEW" WAY TO DO IT - // BUT NEED TO CHECK ALL VARIABLES HAVE INITIAL VALUE - // // FETCH ANY PARAMETERS REQUIRED FROM THE "PARAMETER SERVICES" - - // // The yaml files for the controllers are not added to - // // "Parameter Service" as part of launching. - // // The process for loading the yaml parameters is to send a - // // service call containing the filename of the *.yaml file, - // // and then a message will be received on the above subscribers - // // when the paramters are ready. - // // > NOTE IMPORTANTLY that by using a serice client - // // we stall the availability of this node until the - // // paramter service is ready - - // // Create the service client as a local variable - // ros::ServiceClient requestLoadYamlFilenameServiceClient = nodeHandle_to_own_agent_parameter_service.serviceClient<LoadYamlFromFilename>("requestLoadYamlFilename", false); - // // Create the service call as a local variable - // LoadYamlFromFilename loadYamlFromFilenameCall; - // // Specify the Yaml filename as a string - // loadYamlFromFilenameCall.request.stringWithHeader.data = "DefaultController"; - // // Set for whom this applies to - // loadYamlFromFilenameCall.request.stringWithHeader.shouldCheckForAgentID = false; - // // Wait until the serivce exists - // requestLoadYamlFilenameServiceClient.waitForExistence(ros::Duration(-1)); - // // Make the service call - // if(requestLoadYamlFilenameServiceClient.call(loadYamlFromFilenameCall)) - // { - // // Nothing to do in this case. - // // The "isReadyDefaultControllerYamlCallback" function - // // will be called once the YAML file is loaded - // } - // else - // { - // // Inform the user - // ROS_ERROR("[DEFAULT CONTROLLER] The request load yaml file service call failed."); - // } - - - - // Copy the default setpoint into the class variable - controller_setpoint.x = yaml_default_setpoint[0]; - controller_setpoint.y = yaml_default_setpoint[1]; - controller_setpoint.z = yaml_default_setpoint[2]; - controller_setpoint.yaw = yaml_default_setpoint[3]; + //fetchSafeControllerYamlParameters(nodeHandle_to_own_agent_parameter_service); + + + // INITIALISE ALL THE CONTROLLER SERVICE CLIENTS + // loadController( "defaultController" , defaultController ); + // loadController( "studentController" , studentController ); + // loadController( "tuningController" , tuningController ); + // loadController( "pickerController" , pickerController ); + // loadController( "templateController" , templateController ); + m_controllers_avialble = false; + timer_for_loadAllControllers = nodeHandle.createTimer(ros::Duration(3), timerCallback_for_loadAllControllers, true); + + @@ -1343,7 +1478,7 @@ int main(int argc, char* argv[]) ros::Subscriber databaseChangedSubscriber = nodeHandle_dfall_root.subscribe("CentralManagerService/DBChanged", 1, crazyflieContextDatabaseChangedCallback); // EMERGENCY STOP OF THE WHOLE "D-FaLL-System" - ros::Subscriber emergencyStopSubscriber = nodeHandle_dfall_root.subscribe("emergencyStop", 1, emergencyStopCallback); + ros::Subscriber emergencyStopSubscriber = nodeHandle_dfall_root.subscribe("emergencyStop", 1, emergencyStopReceivedCallback); // LOCALISATION DATA FROM MOTION CAPTURE SYSTEM //keeps 100 messages because otherwise ViconDataPublisher would override the data immediately @@ -1354,7 +1489,7 @@ int main(int argc, char* argv[]) // PUBLISHER FOR COMMANDING THE CRAZYFLIE // i.e., motorCmd{1,2,3,4}, roll, pitch, yaw, and onboardControllerType //ros::Publishers to advertise the control output - controlCommandPublisher = nodeHandle.advertise <ControlCommand>("ControlCommand", 1); + commandForSendingToCrazyfliePublisher = nodeHandle.advertise <ControlCommand>("ControlCommand", 1); //this topic lets the FlyingAgentClient listen to the terminal commands //commandPublisher = nodeHandle.advertise<std_msgs::Int32>("Command", 1); @@ -1364,9 +1499,9 @@ int main(int argc, char* argv[]) // SUBSCRIBER FOR THE CHANGE STATE COMMANDS // i.e., {TAKE-OFF,LAND,MOTORS-OFF,CONTROLLER SELECTION} // > for the agent GUI - ros::Subscriber commandSubscriber_to_agent = nodeHandle.subscribe("Command", 1, commandCallback); + ros::Subscriber commandSubscriber_to_agent = nodeHandle.subscribe("Command", 1, flyingStateRequestCallback); // > for the coord GUI - ros::Subscriber commandSubscriber_to_coord = nodeHandle_to_coordinator.subscribe("FlyingAgentClient/Command", 1, commandCallback); + ros::Subscriber commandSubscriber_to_coord = nodeHandle_to_coordinator.subscribe("FlyingAgentClient/Command", 1, flyingStateRequestCallback); @@ -1397,14 +1532,14 @@ int main(int argc, char* argv[]) // publish first flying state data std_msgs::Int32 flying_state_msg; - flying_state_msg.data = flying_state; + flying_state_msg.data = m_flying_state; flyingStatePublisher.publish(flying_state_msg); // SafeControllerServicePublisher: ros::NodeHandle namespaceNodeHandle = ros::NodeHandle(); - safeControllerServiceSetpointPublisher = namespaceNodeHandle.advertise<dfall_pkg::Setpoint>("SafeControllerService/Setpoint", 1); - ros::Subscriber controllerSetpointSubscriber = namespaceNodeHandle.subscribe("student_GUI/ControllerSetpoint", 1, controllerSetPointCallback); - ros::Subscriber safeSetpointSubscriber = namespaceNodeHandle.subscribe("SafeControllerService/Setpoint", 1, safeSetPointCallback); + //safeControllerServiceSetpointPublisher = namespaceNodeHandle.advertise<dfall_pkg::Setpoint>("SafeControllerService/Setpoint", 1); + //ros::Subscriber controllerSetpointSubscriber = namespaceNodeHandle.subscribe("student_GUI/ControllerSetpoint", 1, controllerSetPointCallback); + //ros::Subscriber safeSetpointSubscriber = namespaceNodeHandle.subscribe("SafeControllerService/Setpoint", 1, safeSetPointCallback); @@ -1435,9 +1570,9 @@ int main(int argc, char* argv[]) //start with safe controller - flying_state = STATE_MOTORS_OFF; - setControllerUsed(SAFE_CONTROLLER); - setInstantController(SAFE_CONTROLLER); //initialize this also, so we notify GUI + m_flying_state = STATE_MOTORS_OFF; + setControllerNominallySelected(DEFAULT_CONTROLLER); + setInstantController(DEFAULT_CONTROLLER); //initialize this also, so we notify GUI // Advertise the service for the current flying state diff --git a/dfall_ws/src/dfall_pkg/src/nodes/MpcControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/MpcControllerService.cpp index 216676d5d175d3b3ebd3556a516504c99d127c82..9a0545e31edbb227f31deb314f7443a02fe59a6e 100644 --- a/dfall_ws/src/dfall_pkg/src/nodes/MpcControllerService.cpp +++ b/dfall_ws/src/dfall_pkg/src/nodes/MpcControllerService.cpp @@ -653,46 +653,46 @@ void setpointCallback(const Setpoint& newSetpoint) // This function DOES NOT NEED TO BE edited for successful completion of the classroom exercise void yamlReadyForFetchCallback(const std_msgs::Int32& msg) { - // Extract from the "msg" for which controller the and from where to fetch the YAML - // parameters - int controller_to_fetch_yaml = msg.data; - - // Switch between fetching for the different controllers and from different locations - switch(controller_to_fetch_yaml) - { - - // > FOR FETCHING FROM THE AGENT'S OWN PARAMETER SERVICE - case FETCH_YAML_MPC_CONTROLLER_FROM_OWN_AGENT: - { - // Let the user know that this message was received - ROS_INFO("[MPC CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from this agent."); - // Create a node handle to the parameter service running on this agent's machine - ros::NodeHandle nodeHandle_to_own_agent_parameter_service(namespace_to_own_agent_parameter_service); - // Call the function that fetches the parameters - fetchYamlParameters(nodeHandle_to_own_agent_parameter_service); - break; - } - - // > FOR FETCHING FROM THE COORDINATOR'S PARAMETER SERVICE - case FETCH_YAML_MPC_CONTROLLER_FROM_COORDINATOR: - { - // Let the user know that this message was received - ROS_INFO("[MPC CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from the coordinator."); - // Create a node handle to the parameter service running on the coordinator machine - ros::NodeHandle nodeHandle_to_coordinator_parameter_service(namespace_to_coordinator_parameter_service); - // Call the function that fetches the parameters - fetchYamlParameters(nodeHandle_to_coordinator_parameter_service); - break; - } - - default: - { - // Let the user know that the command was not relevant - //ROS_INFO("The CustomControllerService received the message that YAML parameters were (re-)loaded"); - //ROS_INFO("> However the parameters do not relate to this controller, hence nothing will be fetched."); - break; - } - } + // // Extract from the "msg" for which controller the and from where to fetch the YAML + // // parameters + // int controller_to_fetch_yaml = msg.data; + + // // Switch between fetching for the different controllers and from different locations + // switch(controller_to_fetch_yaml) + // { + + // // > FOR FETCHING FROM THE AGENT'S OWN PARAMETER SERVICE + // case FETCH_YAML_MPC_CONTROLLER_FROM_OWN_AGENT: + // { + // // Let the user know that this message was received + // ROS_INFO("[MPC CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from this agent."); + // // Create a node handle to the parameter service running on this agent's machine + // ros::NodeHandle nodeHandle_to_own_agent_parameter_service(namespace_to_own_agent_parameter_service); + // // Call the function that fetches the parameters + // fetchYamlParameters(nodeHandle_to_own_agent_parameter_service); + // break; + // } + + // // > FOR FETCHING FROM THE COORDINATOR'S PARAMETER SERVICE + // case FETCH_YAML_MPC_CONTROLLER_FROM_COORDINATOR: + // { + // // Let the user know that this message was received + // ROS_INFO("[MPC CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from the coordinator."); + // // Create a node handle to the parameter service running on the coordinator machine + // ros::NodeHandle nodeHandle_to_coordinator_parameter_service(namespace_to_coordinator_parameter_service); + // // Call the function that fetches the parameters + // fetchYamlParameters(nodeHandle_to_coordinator_parameter_service); + // break; + // } + + // default: + // { + // // Let the user know that the command was not relevant + // //ROS_INFO("The CustomControllerService received the message that YAML parameters were (re-)loaded"); + // //ROS_INFO("> However the parameters do not relate to this controller, hence nothing will be fetched."); + // break; + // } + // } } diff --git a/dfall_ws/src/dfall_pkg/src/nodes/RemoteControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/RemoteControllerService.cpp index 2b980cbf413b41926de375402e7cffcd9b3e6565..de85865dde6359d0ca47fa5c66a4292a42983054 100644 --- a/dfall_ws/src/dfall_pkg/src/nodes/RemoteControllerService.cpp +++ b/dfall_ws/src/dfall_pkg/src/nodes/RemoteControllerService.cpp @@ -1214,46 +1214,46 @@ void setpointCallback(const Setpoint& newSetpoint) // This function DOES NOT NEED TO BE edited for successful completion of the classroom exercise void yamlReadyForFetchCallback(const std_msgs::Int32& msg) { - // Extract from the "msg" for which controller the and from where to fetch the YAML - // parameters - int controller_to_fetch_yaml = msg.data; - - // Switch between fetching for the different controllers and from different locations - switch(controller_to_fetch_yaml) - { - - // > FOR FETCHING FROM THE AGENT'S OWN PARAMETER SERVICE - case FETCH_YAML_REMOTE_CONTROLLER_FROM_OWN_AGENT: - { - // Let the user know that this message was received - ROS_INFO("[REMOTE CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from this agent."); - // Create a node handle to the parameter service running on this agent's machine - ros::NodeHandle nodeHandle_to_own_agent_parameter_service(namespace_to_own_agent_parameter_service); - // Call the function that fetches the parameters - fetchYamlParameters(nodeHandle_to_own_agent_parameter_service); - break; - } - - // > FOR FETCHING FROM THE COORDINATOR'S PARAMETER SERVICE - case FETCH_YAML_REMOTE_CONTROLLER_FROM_COORDINATOR: - { - // Let the user know that this message was received - ROS_INFO("[REMOTE CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from the coordinator."); - // Create a node handle to the parameter service running on the coordinator machine - ros::NodeHandle nodeHandle_to_coordinator_parameter_service(namespace_to_coordinator_parameter_service); - // Call the function that fetches the parameters - fetchYamlParameters(nodeHandle_to_coordinator_parameter_service); - break; - } - - default: - { - // Let the user know that the command was not relevant - //ROS_INFO("The CustomControllerService received the message that YAML parameters were (re-)loaded"); - //ROS_INFO("> However the parameters do not relate to this controller, hence nothing will be fetched."); - break; - } - } + // // Extract from the "msg" for which controller the and from where to fetch the YAML + // // parameters + // int controller_to_fetch_yaml = msg.data; + + // // Switch between fetching for the different controllers and from different locations + // switch(controller_to_fetch_yaml) + // { + + // // > FOR FETCHING FROM THE AGENT'S OWN PARAMETER SERVICE + // case FETCH_YAML_REMOTE_CONTROLLER_FROM_OWN_AGENT: + // { + // // Let the user know that this message was received + // ROS_INFO("[REMOTE CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from this agent."); + // // Create a node handle to the parameter service running on this agent's machine + // ros::NodeHandle nodeHandle_to_own_agent_parameter_service(namespace_to_own_agent_parameter_service); + // // Call the function that fetches the parameters + // fetchYamlParameters(nodeHandle_to_own_agent_parameter_service); + // break; + // } + + // // > FOR FETCHING FROM THE COORDINATOR'S PARAMETER SERVICE + // case FETCH_YAML_REMOTE_CONTROLLER_FROM_COORDINATOR: + // { + // // Let the user know that this message was received + // ROS_INFO("[REMOTE CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from the coordinator."); + // // Create a node handle to the parameter service running on the coordinator machine + // ros::NodeHandle nodeHandle_to_coordinator_parameter_service(namespace_to_coordinator_parameter_service); + // // Call the function that fetches the parameters + // fetchYamlParameters(nodeHandle_to_coordinator_parameter_service); + // break; + // } + + // default: + // { + // // Let the user know that the command was not relevant + // //ROS_INFO("The CustomControllerService received the message that YAML parameters were (re-)loaded"); + // //ROS_INFO("> However the parameters do not relate to this controller, hence nothing will be fetched."); + // break; + // } + // } } diff --git a/dfall_ws/src/dfall_pkg/src/nodes/SafeControllerService.cpp b/dfall_ws/src/dfall_pkg/src/nodes/SafeControllerService.cpp index d1934a0fbb2f9bab6fb7852539447c1cf5c7c0b3..e9f1c08cfd6265c2585b4c14244354f0069a6178 100755 --- a/dfall_ws/src/dfall_pkg/src/nodes/SafeControllerService.cpp +++ b/dfall_ws/src/dfall_pkg/src/nodes/SafeControllerService.cpp @@ -235,45 +235,45 @@ void estimateState(Controller::Request &request, float (&est)[9]) // This function DOES NOT NEED TO BE edited for successful completion of the classroom exercise void yamlReadyForFetchCallback(const std_msgs::Int32& msg) { - // Extract from the "msg" for which controller the and from where to fetch the YAML - // parameters - int controller_to_fetch_yaml = msg.data; - - // Switch between fetching for the different controllers and from different locations - switch(controller_to_fetch_yaml) - { - - // > FOR FETCHING FROM THE AGENT'S OWN PARAMETER SERVICE - case FETCH_YAML_SAFE_CONTROLLER_FROM_OWN_AGENT: - { - // Let the user know that this message was received - ROS_INFO("[SAFE CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from this machine."); - // Create a node handle to the parameter service running on this agent's machine - ros::NodeHandle nodeHandle_to_own_agent_parameter_service(namespace_to_own_agent_parameter_service); - // Call the function that fetches the parameters - fetchYamlParameters(nodeHandle_to_own_agent_parameter_service); - break; - } - - // > FOR FETCHING FROM THE COORDINATOR'S PARAMETER SERVICE - case FETCH_YAML_SAFE_CONTROLLER_FROM_COORDINATOR: - { - // Let the user know that this message was received - ROS_INFO("[SAFE CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from the coordinator."); - // Create a node handle to the parameter service running on the coordinator machine - ros::NodeHandle nodeHandle_to_coordinator_parameter_service(namespace_to_coordinator_parameter_service); - // Call the function that fetches the parameters - fetchYamlParameters(nodeHandle_to_coordinator_parameter_service); - break; - } - - default: - { - // Let the user know that the command was not relevant - //ROS_INFO("The SafeControllerService received the message that YAML parameters were (re-)loaded.\r> However the parameters do not relate to this controller, hence nothing will be fetched."); - break; - } - } + // // Extract from the "msg" for which controller the and from where to fetch the YAML + // // parameters + // int controller_to_fetch_yaml = msg.data; + + // // Switch between fetching for the different controllers and from different locations + // switch(controller_to_fetch_yaml) + // { + + // // > FOR FETCHING FROM THE AGENT'S OWN PARAMETER SERVICE + // case FETCH_YAML_SAFE_CONTROLLER_FROM_OWN_AGENT: + // { + // // Let the user know that this message was received + // ROS_INFO("[SAFE CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from this machine."); + // // Create a node handle to the parameter service running on this agent's machine + // ros::NodeHandle nodeHandle_to_own_agent_parameter_service(namespace_to_own_agent_parameter_service); + // // Call the function that fetches the parameters + // fetchYamlParameters(nodeHandle_to_own_agent_parameter_service); + // break; + // } + + // // > FOR FETCHING FROM THE COORDINATOR'S PARAMETER SERVICE + // case FETCH_YAML_SAFE_CONTROLLER_FROM_COORDINATOR: + // { + // // Let the user know that this message was received + // ROS_INFO("[SAFE CONTROLLER] Received the message that YAML parameters were (re-)loaded. > Now fetching the parameter values from the coordinator."); + // // Create a node handle to the parameter service running on the coordinator machine + // ros::NodeHandle nodeHandle_to_coordinator_parameter_service(namespace_to_coordinator_parameter_service); + // // Call the function that fetches the parameters + // fetchYamlParameters(nodeHandle_to_coordinator_parameter_service); + // break; + // } + + // default: + // { + // // Let the user know that the command was not relevant + // //ROS_INFO("The SafeControllerService received the message that YAML parameters were (re-)loaded.\r> However the parameters do not relate to this controller, hence nothing will be fetched."); + // break; + // } + // } } void fetchYamlParameters(ros::NodeHandle& nodeHandle)