From b5aa168ffebda96ced24ef95e235a5aeaaa19818 Mon Sep 17 00:00:00 2001 From: roangel <roangel@student.ethz.ch> Date: Mon, 4 Sep 2017 18:08:38 +0200 Subject: [PATCH] custom controller a bit more ready, still need to fill information in GUI fields and connect everything to GUI (set setpoint mainly). Landing and take off parameters now in YAML file --- .../GUI_Qt/studentGUI/src/MainWindow.cpp | 2 +- pps_ws/src/d_fall_pps/launch/Student.launch | 1 + pps_ws/src/d_fall_pps/param/ClientConfig.yaml | 2 +- .../src/d_fall_pps/param/SafeController.yaml | 6 +++ .../src/CustomControllerService.cpp | 40 ++++++++++++++--- pps_ws/src/d_fall_pps/src/PPSClient.cpp | 45 +++++++++++++++++-- .../d_fall_pps/src/SafeControllerService.cpp | 8 ---- 7 files changed, 84 insertions(+), 20 deletions(-) diff --git a/pps_ws/src/d_fall_pps/GUI_Qt/studentGUI/src/MainWindow.cpp b/pps_ws/src/d_fall_pps/GUI_Qt/studentGUI/src/MainWindow.cpp index 2792f85b..2e1678e7 100644 --- a/pps_ws/src/d_fall_pps/GUI_Qt/studentGUI/src/MainWindow.cpp +++ b/pps_ws/src/d_fall_pps/GUI_Qt/studentGUI/src/MainWindow.cpp @@ -43,7 +43,7 @@ MainWindow::MainWindow(int argc, char **argv, QWidget *parent) : DBChangedSubscriber = nodeHandle.subscribe("/my_GUI/DBChanged", 1, &MainWindow::DBChangedCallback, this); ros::NodeHandle my_nodeHandle("~"); - controllerSetpointPublisher = my_nodeHandle.advertise<Setpoint>("ControllerSetpoint", 1); + controllerSetpointPublisher = nodeHandle.advertise<Setpoint>("ControllerSetpoint", 1); customYAMLloadedPublisher = my_nodeHandle.advertise<std_msgs::Int32>("customYAMLloaded", 1); safeYAMLloadedPublisher = my_nodeHandle.advertise<std_msgs::Int32>("safeYAMLloaded", 1); diff --git a/pps_ws/src/d_fall_pps/launch/Student.launch b/pps_ws/src/d_fall_pps/launch/Student.launch index 475bf792..c2480b38 100755 --- a/pps_ws/src/d_fall_pps/launch/Student.launch +++ b/pps_ws/src/d_fall_pps/launch/Student.launch @@ -14,6 +14,7 @@ </node> <node pkg="d_fall_pps" name="CustomControllerService" output="screen" type="CustomControllerService"> + <rosparam command="load" file="$(find d_fall_pps)/param/CustomController.yaml" /> </node> <!-- When we have a GUI, this has to be adapted and included --> diff --git a/pps_ws/src/d_fall_pps/param/ClientConfig.yaml b/pps_ws/src/d_fall_pps/param/ClientConfig.yaml index 27a48ab3..4e69d2ac 100755 --- a/pps_ws/src/d_fall_pps/param/ClientConfig.yaml +++ b/pps_ws/src/d_fall_pps/param/ClientConfig.yaml @@ -1,5 +1,5 @@ safeController: "SafeControllerService/RateController" -customController: "CircleControllerService/CircleController" +customController: "CustomControllerService/CustomController" strictSafety: true angleMargin: 0.6 diff --git a/pps_ws/src/d_fall_pps/param/SafeController.yaml b/pps_ws/src/d_fall_pps/param/SafeController.yaml index 1997d4da..d660059e 100644 --- a/pps_ws/src/d_fall_pps/param/SafeController.yaml +++ b/pps_ws/src/d_fall_pps/param/SafeController.yaml @@ -16,3 +16,9 @@ estimatorMatrix: [-22.3384, 0.9106] #only for velocity calculation #setpoint in meters (x, y, z, yaw) defaultSetpoint: [0.0, 0.0, 0.3, 0.0] + +#take off and landing parameters (in meters and seconds) +takeOffDistance : 1 +landingDistance : 0.15 +durationTakeOff : 3 +durationLanding : 3 diff --git a/pps_ws/src/d_fall_pps/src/CustomControllerService.cpp b/pps_ws/src/d_fall_pps/src/CustomControllerService.cpp index d9fd6949..a3b8aa6e 100644 --- a/pps_ws/src/d_fall_pps/src/CustomControllerService.cpp +++ b/pps_ws/src/d_fall_pps/src/CustomControllerService.cpp @@ -1,5 +1,5 @@ // Place for students to implement their controller -// The ROS::service is set to work +// The ROS::service is set to work //some useful libraries @@ -13,6 +13,8 @@ #include "d_fall_pps/ControlCommand.h" #include "d_fall_pps/Controller.h" +#include <std_msgs/Int32.h> + //constants #define PI 3.1415926535 #define RATE_MODE 0 @@ -29,6 +31,22 @@ const float SATURATION_THRUST = MOTOR_REGRESSION_POLYNOMIAL[2] * 12000 * 12000 + using namespace d_fall_pps; +// load parameters from corresponding YAML file + +void loadParameterFloatVector(ros::NodeHandle& nodeHandle, std::string name, std::vector<float>& val, int length) { + if(!nodeHandle.getParam(name, val)){ + ROS_ERROR_STREAM("missing parameter '" << name << "'"); + } + if(val.size() != length) { + ROS_ERROR_STREAM("parameter '" << name << "' has wrong array length, " << length << " needed"); + } +} + +void loadCustomParameters(ros::NodeHandle& nodeHandle) +{ + // here we load the parameters that are in the CustomController.yaml +} + // ********* important function that has to be used!! ********* //-est- is an array with the estimated values : x,y,z,vx,vy,vz,roll,pitch,yaw @@ -56,7 +74,7 @@ void convertIntoBodyFrame(float est[9], float (&estBody)[9], int yaw_measured) { /* --- the data students can work with --- -request- contains data provided by Vicon. Check d_fall_pps/msg/ViconData.msg what it includes. - -response- is where you have to write your calculated data into. + -response- is where you have to write your calculated data into. */ bool calculateControlOutput(Controller::Request &request, Controller::Response &response) { //writing the data from -request- to command line @@ -71,7 +89,7 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response & - // ********* do your calculations here ********* + // ********* do your calculations here ********* //Tip: create functions that you call here to keep you code cleaner @@ -94,18 +112,28 @@ bool calculateControlOutput(Controller::Request &request, Controller::Response & it can either be Motor, Rate or Angle based */ response.controlOutput.onboardControllerType = MOTOR_MODE; //response.controlOutput.onboardControllerType = RATE_MODE; - //response.controlOutput.onboardControllerType = ANGLE_MODE; - + //response.controlOutput.onboardControllerType = ANGLE_MODE; + return true; } +void customYAMLloadedCallback(const std_msgs::Int32& msg) +{ + ros::NodeHandle nodeHandle("~"); + ROS_INFO("received msg custom loaded YAML"); + loadCustomParameters(nodeHandle); +} + int main(int argc, char* argv[]) { //starting the ROS-node ros::init(argc, argv, "CustomControllerService"); ros::NodeHandle nodeHandle("~"); - ros::ServiceServer service = nodeHandle.advertiseService("CustomController", calculateControlOutput); + + ros::NodeHandle namespace_nodeHandle(ros::this_node::getNamespace()); + ros::Subscriber customYAMLloadedSubscriber = namespace_nodeHandle.subscribe("student_GUI/customYAMLloaded", 1, customYAMLloadedCallback); + ROS_INFO("CustomControllerService ready"); ros::spin(); diff --git a/pps_ws/src/d_fall_pps/src/PPSClient.cpp b/pps_ws/src/d_fall_pps/src/PPSClient.cpp index e212fe83..b3d2ebbe 100755 --- a/pps_ws/src/d_fall_pps/src/PPSClient.cpp +++ b/pps_ws/src/d_fall_pps/src/PPSClient.cpp @@ -111,6 +111,11 @@ bool usingSafeController; std::string ros_namespace; +float take_off_distance; +float landing_distance; +float duration_take_off; +float duration_landing; + void loadSafeController() { ros::NodeHandle nodeHandle("~"); @@ -196,7 +201,7 @@ void takeOffCF(CrazyflieData& current_local_coordinates) //local because the set 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 + TAKE_OFF_OFFSET; //previous one plus some offset + setpoint_msg.z = current_local_coordinates.z + 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); @@ -218,7 +223,7 @@ void landCF(CrazyflieData& current_local_coordinates) Setpoint setpoint_msg; setpoint_msg.x = current_local_coordinates.x; // previous one setpoint_msg.y = current_local_coordinates.y; //previous one - setpoint_msg.z = LANDING_DISTANCE; //previous one plus some offset + setpoint_msg.z = landing_distance; //previous one plus some offset setpoint_msg.yaw = current_local_coordinates.yaw; //previous one safeControllerServiceSetpointPublisher.publish(setpoint_msg); @@ -312,7 +317,7 @@ void viconCallback(const ViconData& viconData) { takeOffCF(local); finished_take_off = false; ROS_INFO("STATE_TAKE_OFF"); - timer_takeoff = nodeHandle.createTimer(ros::Duration(DURATION_TAKE_OFF), takeOffTimerCallback, true); + timer_takeoff = nodeHandle.createTimer(ros::Duration(duration_take_off), takeOffTimerCallback, true); } if(finished_take_off) { @@ -336,7 +341,7 @@ void viconCallback(const ViconData& viconData) { landCF(local); finished_land = false; ROS_INFO("STATE_LAND"); - timer_takeoff = nodeHandle.createTimer(ros::Duration(DURATION_LANDING), landTimerCallback, true); + timer_takeoff = nodeHandle.createTimer(ros::Duration(duration_landing), landTimerCallback, true); } if(finished_land) { @@ -409,8 +414,30 @@ void loadParameters(ros::NodeHandle& nodeHandle) { ROS_ERROR("Failed to get angleMargin param"); return; } +} + +void loadSafeControllerParameters() +{ + ros::NodeHandle nh_safeControllerService(ros_namespace + "/SafeControllerService"); + if(!nh_safeControllerService.getParam("takeOffDistance", take_off_distance)) + { + ROS_ERROR("Failed to get takeOffDistance"); + } + if(!nh_safeControllerService.getParam("landingDistance", landing_distance)) + { + ROS_ERROR("Failed to get landing_distance"); + } + if(!nh_safeControllerService.getParam("durationTakeOff", duration_take_off)) + { + ROS_ERROR("Failed to get duration_take_off"); + } + + if(!nh_safeControllerService.getParam("durationLanding", duration_landing)) + { + ROS_ERROR("Failed to get duration_landing"); + } } void loadCrazyflieContext() { @@ -515,6 +542,13 @@ void controllerSetPointCallback(const Setpoint& newSetpoint) } } + +void safeYAMLloadedCallback(const std_msgs::Int32& msg) +{ + ROS_INFO("received msg safe loaded YAML"); + loadSafeControllerParameters(); +} + int main(int argc, char* argv[]) { ros::init(argc, argv, "PPSClient"); @@ -539,6 +573,7 @@ int main(int argc, char* argv[]) // load context parameters loadParameters(nodeHandle); + loadSafeControllerParameters(); //ros::service::waitForService("/CentralManagerService/CentralManager"); centralManager = nodeHandle.serviceClient<CMQuery>("/CentralManagerService/Query", false); @@ -580,6 +615,8 @@ int main(int argc, char* argv[]) // crazyradio status. Connected, connecting or disconnected ros::Subscriber crazyRadioStatusSubscriber = namespaceNodeHandle.subscribe("CrazyRadio/CrazyRadioStatus", 1, crazyRadioStatusCallback); + ros::Subscriber safeYAMloadedSubscriber = namespaceNodeHandle.subscribe("student_GUI/safeYAMLloaded", 1, safeYAMLloadedCallback); + //start with safe controller flying_state = STATE_MOTORS_OFF; usingSafeController = true; diff --git a/pps_ws/src/d_fall_pps/src/SafeControllerService.cpp b/pps_ws/src/d_fall_pps/src/SafeControllerService.cpp index f0f7e5b4..6f1000d9 100755 --- a/pps_ws/src/d_fall_pps/src/SafeControllerService.cpp +++ b/pps_ws/src/d_fall_pps/src/SafeControllerService.cpp @@ -267,13 +267,6 @@ void setpointCallback(const Setpoint& newSetpoint) { setpoint[3] = newSetpoint.yaw; } -void customYAMLloadedCallback(const std_msgs::Int32& msg) -{ - ros::NodeHandle nodeHandle("~"); - ROS_INFO("received msg custom loaded YAML"); - // loadSafeParameters(nodeHandle); -} - void safeYAMLloadedCallback(const std_msgs::Int32& msg) { ros::NodeHandle nodeHandle("~"); @@ -296,7 +289,6 @@ int main(int argc, char* argv[]) { ros::NodeHandle namespace_nodeHandle(ros::this_node::getNamespace()); - ros::Subscriber customYAMloadedSubscriber = namespace_nodeHandle.subscribe("student_GUI/customYAMLloaded", 1, customYAMLloadedCallback); ros::Subscriber safeYAMloadedSubscriber = namespace_nodeHandle.subscribe("student_GUI/safeYAMLloaded", 1, safeYAMLloadedCallback); ros::ServiceServer service = nodeHandle.advertiseService("RateController", calculateControlOutput); -- GitLab