height_controller.cpp
Go to the documentation of this file.
00001 #include "ros/ros.h"
00002 #include "quad_can_driver/Thrust.h"
00003 #include "mav_msgs/Height.h"
00004 #include "quad_height/pid_height.h"
00005 #include <sensor_msgs/Imu.h>
00006 #include <tf/transform_datatypes.h>
00007 #include <std_msgs/Float64.h>
00008 #include <std_msgs/Float32.h>
00009 #include <math.h>
00010 #include <geometry_msgs/Vector3Stamped.h>
00011 #include "px_comm/OpticalFlow.h"
00012 
00013 // Variables for Reference Generator
00014 Reference Ref;
00015 
00016 Height_str Height;
00017 tfScalar yaw, pitch, roll;
00018 
00019 double RC;
00020 ros::Publisher zhat_pub, Accz_pub, thrust_pub, desired_pub;
00021 
00022 bool init_control = false, init_ref = false;
00023 
00024 void desired_heightCallback(std_msgs::Float32 const &msg){
00025     Ref.desired=msg.data;
00026     init_ref = true;
00027 }
00028 
00029 void imuCallback(sensor_msgs::Imu const &imu){
00030         tf::Quaternion orientation;
00031         tf::quaternionMsgToTF(imu.orientation, orientation);
00032         tf::Matrix3x3(orientation).getEulerYPR(yaw, pitch, roll);
00033 }
00034 
00035 void heightCallback(const mav_msgs::Height& msg){
00036     //Update last height
00037     Height.time_last=Height.time_current;
00038     Height.last=Height.current;
00039     //Update current height
00040     Height.time_current=msg.header.stamp;
00041     Height.current=msg.height;
00042     init_control=true;
00043     //New Measure -> Run the Estimator
00044     double delta = ZKalman_newZMeasurement(Height.current, 0);
00045     std_msgs::Float64 zhat;
00046     zhat.data=delta;
00047     zhat_pub.publish(zhat);
00048 }
00049 
00050 // Second Order Filter for Reference Generator
00051 void Ref_Generator(double t){
00052     double zd_ref_old=Ref.zd_ref;
00053     double z_ref_old=Ref.z_ref;
00054     Ref.zdd_ref=((Ref.desired-Ref.z_ref)*Ref.Ref_Rate)-Ref.zd_ref;
00055     Ref.zd_ref=zd_ref_old+Ref.zdd_ref*t;
00056     Ref.z_ref=z_ref_old+Ref.zd_ref*t;
00057 }
00058 
00059 /*
00060 * Returns the sign of a double
00061 * 1        if the value is positive
00062 * 0        if the value is 0
00063 * -1       if the value is negative
00064 */
00065 /*int sign(double v){
00066        return v>0?1:(v<0?-1:0);
00067 }*/
00068 /*double Ramp(double ref_u, double uref_old){
00069         
00070         if(fabs(ref_u-uref_old)> Ref_Rate)
00071                 ref_u = uref_old + sign(ref_u-uref_old)*Ref_Rate;
00072                 
00073         return ref_u;
00074 }*/
00075 
00076 int main(int argc, char **argv){
00077         
00078         ros::init(argc, argv, "quad_height");
00079     ros::NodeHandle n, nl("~");
00080 
00081     // Variables
00082     bool pub_reference;
00083     int cmd = 0;
00084     double height_gain[5];
00085     double Mass;
00086 
00087     //Set Reference Variables
00088     Ref.desired=0;
00089     Ref.zdd_ref=0;
00090     Ref.zd_ref=0;
00091     Ref.z_ref=0;
00092     Ref.Ref_Rate=0.3;
00093 
00094     // Height Structure
00095     Height.current=0;
00096     Height.last=0;
00097     Height.time_current=ros::Time::now();
00098     Height.time_last=Height.time_current;
00099 
00100     std_msgs::Float32 zref_pub;
00101     quad_can_driver::Thrust thrust_msg;
00102 
00103     //Read Parameters
00104     nl.param("height_p", height_gain[P_GAIN], 1.0);
00105     nl.param("height_i", height_gain[I_GAIN], 0.01);
00106     nl.param("height_d", height_gain[D_GAIN], 1.3);
00107     nl.param("height_imax", height_gain[I_MAX], 1.0);
00108     nl.param("height_imin", height_gain[I_MIN], 1.0);
00109     nl.param("mass",Mass,1.60);
00110     nl.param("pub_ref",pub_reference,true);
00111 
00112     //Subscribing
00113         ros::Subscriber sub1 = n.subscribe("/quad_height/height_to_base", 10, heightCallback);
00114         ros::Subscriber sub2 = n.subscribe("/imu/data", 10, &imuCallback);
00115     ros::Subscriber sub4 = n.subscribe("/desired_height", 10, &desired_heightCallback);
00116         
00117     //Publishing
00118         thrust_pub = n.advertise<quad_can_driver::Thrust>("ThrustCtrl", 10);
00119     if(pub_reference) desired_pub = n.advertise<std_msgs::Float32>("Z_Ref", 10);
00120     zhat_pub = n.advertise<std_msgs::Float64>("xhat", 10);
00121     Accz_pub = n.advertise<std_msgs::Float64>("Applied_AccZ", 10);
00122 
00123     ros::Rate loop_rate(10);
00124         ros::Time last_time, current_time;
00125         ros::Duration t;
00126 
00127         last_time = ros::Time::now();
00128         current_time = ros::Time::now();
00129     ZKalman_Init();
00130 
00131         while (ros::ok()){
00132                 
00133                 last_time = current_time;
00134                 current_time = ros::Time::now();
00135                 t = current_time - last_time;
00136 
00137         //Reference Generator
00138         Ref_Generator(t.toSec());
00139         ROS_WARN("Z_Ref: %f",Ref.z_ref);
00140 
00141         //Publish Reference
00142         if(pub_reference){
00143             zref_pub.data= Ref.z_ref;
00144             desired_pub.publish(zref_pub);
00145         }
00146 
00147         //PID Controller
00148         if(init_control && init_ref){
00149             cmd = PID_height(Ref.z_ref, Height, height_gain, t.toSec(), Mass, roll, pitch, Accz_pub);
00150         }
00151                         
00152         if(Ref.z_ref<=0.1 && Height.current<=0.1) cmd=0;
00153         ROS_INFO("Thrust Command: %d",cmd);
00154 
00155                 // Send message to quad_can_interface
00156                 thrust_msg.header.stamp = ros::Time::now();
00157                 thrust_msg.thrust = cmd;
00158                 thrust_pub.publish(thrust_msg);
00159 
00160         //rosspin and rate
00161                 ros::spinOnce();
00162                 loop_rate.sleep();
00163         }
00164         return 0;
00165 }


quad_height
Author(s): Henrique
autogenerated on Mon Jan 6 2014 11:48:06