pid_height.cpp
Go to the documentation of this file.
00001 #include "quad_height/pid_height.h"
00002 #include <math.h>
00003 #include "mav_msgs/Height.h"
00004 #include <Eigen/Eigen>
00005 #include <Eigen/LU>
00006 #include <std_msgs/Float64.h>
00007 
00008 //Nominal Hover Thrust Estimator Variables
00009 /* Model Constants -> TODO: Config file */
00010 #define _Ts 0.1
00011 #define _delta 6.74
00012 
00013 bool initialized = false;
00014 
00015 //PID Variables
00016 double p_term, d_term, i_term;
00017 double ThrustMax = 23.2472;
00018 double ThrustMin = 6.5241;
00019 double ThrustCoefA = 0.102613151321317;
00020 double ThrustCoefB = 3.352893193381934;
00021 double i_error = 0;
00022 double U = 0;
00023 
00025 
00026 //Kalman Only With Height
00027 
00028 //Kalman Variables
00029 typedef Eigen::Matrix<double, 4, 1> VecState;
00030 typedef Eigen::Matrix<double, 4, 4> MetState;
00031 
00032 VecState xhat, B;
00033 MetState P, A, Q;
00034 Eigen::Matrix<double, 4, 1> K;
00035 Eigen::Matrix<double, 1, 4> C;
00036 double R, Meas, resid;
00037 
00038 //Initializing Nominal Hover Estimator
00039 void ZKalman_Init(){
00040     xhat << 0, 0, 0, _delta;
00041     P << 0,0,0,0,
00042          0,0,0,0,
00043          0,0,0,0,
00044          0,0,0,0;
00045     A << 1, _Ts, pow(_Ts,2)/2, 0 ,
00046          0, 1  , _Ts         , 0 ,
00047          0, 0  , 0           , -1,
00048          0, 0  , 0           , 1 ;
00049     B << 0, 0, 1, 0;
00050     C << 1, 0, 0 , 0;
00051     Q << 0.1, 0  , 0  , 0  ,
00052          0  , 0.1, 0  , 0  ,
00053          0  , 0  , 0.1, 0  ,
00054          0  , 0  , 0  , 0.1;
00055     R = 0.1;
00056     initialized=true;
00057     U=0;
00058 }
00059 
00060 double ZKalman_newZMeasurement(double z, double zdd){
00061     if(initialized){
00062         // Predict
00063         // Propagate the state estimate and covariance matrix:
00064         xhat = A * xhat + B *U;
00065         P = A * P * A.transpose() + Q;
00066         //Update
00067         // Calculate the Kalman gain
00068         K = (P * C.transpose()) / (C * P * C.transpose() + R);
00069         // Calculate the measurement residual
00070         Meas = z;
00071         resid = Meas - C*xhat;
00072         // Update the state and error covariance estimate
00073         xhat = xhat + K*resid;
00074         P = (Eigen::MatrixXd::Identity(4, 4)-K*C)*P;
00075         return xhat(3);
00076     }
00077     return 0;
00078 }
00080 
00081 int ThrustConversion(double AccZ, double Mass){
00082                 int thrust = 0;
00083         if (AccZ<=ThrustMin){ thrust = 20;
00084         }else if (AccZ>=ThrustMax){ thrust = 210;
00085         }else{ thrust = round((AccZ*Mass-ThrustCoefB)/ThrustCoefA);     }
00086         
00087         if (thrust>210) thrust=210;
00088                 return thrust;
00089 }
00090 
00091 double PID_height(double desired_height, Height_str Height, double height_gain[5], double t, double Mass, double roll, double pitch, ros::Publisher AccZ_pub){
00092 
00093     double p, d, i, i_max, i_min;
00094         
00095     double error = desired_height - Height.current;
00096         
00097         p = height_gain[P_GAIN];
00098         d = height_gain[D_GAIN];
00099         i = height_gain[I_GAIN];
00100         i_max = height_gain[I_MAX];
00101         i_min = height_gain[I_MIN];
00102 
00103         // Calculate proportional contribution to command
00104         p_term = p * error;
00105 
00106         // Calculate the integral error
00107         i_error = i_error + t * error;
00108         
00109         //Calculate integral contribution to command
00110         i_term = i * i_error;
00111 
00112         // Limit i_term so that the limit is meaningful in the output
00113         if (i_term > i_max){
00114                 i_term = i_max;
00115                 i_error=i_term/i;
00116         }
00117         else if (i_term < -i_min){
00118                 i_term = -i_min;
00119                 i_error=i_term/i;
00120         }
00121 
00122         // Calculate the derivative error
00123     ros::Duration t_d = Height.time_current-Height.time_last;
00124     double d_error = (Height.current - Height.last) / t_d.toSec();
00125 
00126     if(abs(d_error)>3.0){
00127         d_error=(d_error/abs(d_error))*3.0;
00128     }
00129         // Calculate derivative contribution to command
00130         d_term = d * d_error;
00131         
00132     double Accz =((p_term + i_term - d_term)+xhat(3));
00133     //double Accz =(p_term + i_term - d_term +xhat(3))/(cos(pitch)*cos(roll));
00134     U=Accz;
00135     int cmd = ThrustConversion (Accz, Mass);
00136 
00137     std_msgs::Float64 az;
00138     az.data=Accz;
00139     AccZ_pub.publish(az);
00140 
00141         return cmd;
00142 }


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