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 }