Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include <tk_ctrlalgo/YawControl.hpp>
00009 
00010 #include <telekyb_base/Spaces/Angle.hpp>
00011 
00012 
00013 namespace TELEKYB_NAMESPACE {
00014 
00015 
00016 
00017 YawControlOptions::YawControlOptions()
00018         : OptionContainer("YawControl")
00019 {
00020         tPropGain = addOption<double>( "tPropGain",
00021                         "Yaw Proportional gain for control with onboard yaw rate measure", 5.0, false, true);
00022         tIntGain = addOption<double>( "tIntGain",
00023                         "Yaw integrational gain for control with onboard absolute yaw measure", 0.5, false, true);
00024         tIntGainInfluenceSaturation = addOption<double>( "tIntGainInfluenceSaturation",
00025                         "Yaw integrational components saturation for control with onboard absolute yaw measure", 2.0, false, true);
00026         tPropGainExt = addOption<double>( "tPropGainExt",
00027                         "Yaw Proportional gain for control with external yaw rate measurement", 5.0, false, true);
00028         tDerivGainExt = addOption<double>( "tDerivGainExt",
00029                         "Yaw Derivative gain for control with external yaw rate measurement", 15.0, false, true);
00030         tAbsolutAngleControl = addOption<bool>( "tAbsolutAngleControl",
00031                         "Send a direct angle instead of a yaw rate command", false, false, true);
00032 }
00033 
00034 YawControl::YawControl()
00035 {
00036         lastTime = ros::Time::now();
00037         integralYawError = 0;
00038 }
00039 
00040 YawControl::~YawControl()
00041 {
00042 
00043 }
00044 
00045 void YawControl::run(const TKTrajectory& input, const TKState& currentState, YawCtrlOutput& output)
00046 {
00047         currentTime = ros::Time::now();
00048         double currentYawRate = currentState.angVelocity(2);
00049         double currentYawAngle = currentState.getEulerRPY()(2);
00050         output.comYaw = 0.0;
00051 
00052         double yawAngleErr = Angle::normPi(input.yawAngle - currentYawAngle); 
00053         double yawRateErr = input.yawRate - currentYawRate; 
00054 
00055 
00056         if (input.yawCtrl == YawControlType::AngleOnBoard || input.yawCtrl == YawControlType::RateOnBoard) {
00057                 if(options.tAbsolutAngleControl->getValue()){
00058                         
00059                         integralYawError += (currentTime-lastTime).toSec()*yawAngleErr;
00060                         if(integralYawError > options.tIntGainInfluenceSaturation->getValue()){
00061                                 integralYawError = options.tIntGainInfluenceSaturation->getValue();
00062                         }
00063                         else if (integralYawError < -options.tIntGainInfluenceSaturation->getValue()){
00064                                 integralYawError = -options.tIntGainInfluenceSaturation->getValue();
00065                         }
00066 
00067                         double ki = options.tIntGain->getValue();
00068                         output.comYaw = input.yawAngle + ki*integralYawError; 
00069                 }
00070                 else{
00071                         double kp = options.tPropGain->getValue();
00072                         output.comYaw = input.yawRate  + kp*yawAngleErr; 
00073                 }
00074         } else if (input.yawCtrl == YawControlType::AngleOffBoard) {
00075                 double kp = options.tPropGainExt->getValue();
00076                 double kd = options.tDerivGainExt->getValue();
00077                 output.comYaw = input.yawAcceleration + kd*yawRateErr + kp*yawAngleErr; 
00078         } else if (input.yawCtrl == YawControlType::RateOffBoard) {
00079                 double kd = options.tDerivGainExt->getValue();
00080                 output.comYaw = input.yawAcceleration + kd*yawRateErr; 
00081         } else if (input.yawCtrl == YawControlType::AccelerationOnBoard) {
00082                 ROS_ERROR("YawControlType::AccelerationOnBoard not implemented!");
00083         } else if (input.yawCtrl == YawControlType::AccelerationOffBoard) {
00084                 ROS_ERROR("YawControlType::AccelerationOffBoard not implemented!");
00085         }
00086 
00087 
00088         lastTime = currentTime;
00089 }
00090 
00091 }