代码
#include “Ano_AttCtrl.h”
#include “Ano_Imu.h”
#include “Drv_icm20602.h”
#include “Ano_MagProcess.h”
#include “Drv_spl06.h”
#include “Ano_MotionCal.h”
#include “Ano_FlightCtrl.h”
#include “Ano_LocCtrl.h”
#include “Ano_MotorCtrl.h”
#include “Ano_FlyCtrl.h”
#include “Ano_Sensor_Basic.h”
#include “Ano_ProgramCtrl_User.h”
//角度环控制参数
_PID_arg_st arg_2[VEC_RPY] ;
//角速度环控制参数
_PID_arg_st arg_1[VEC_RPY] ;
//角度环控制数据
_PID_val_st val_2[VEC_RPY];
//角速度环控制数据
_PID_val_st val_1[VEC_RPY];
/角度环PID参数初始化/
void Att_2level_PID_Init()
{
arg_2[ROL].kp = Ano_Parame.set.pid_att_2level[ROL][KP];
arg_2[ROL].ki = Ano_Parame.set.pid_att_2level[ROL][KI];
arg_2[ROL].kd_ex = Ano_Parame.set.pid_att_2level[ROL][KD];
arg_2[ROL].kd_fb = Ano_Parame.set.pid_att_2level[ROL][KD];
arg_2[ROL].k_ff = 0.0f;
arg_2[PIT].kp = Ano_Parame.set.pid_att_2level[PIT][KP];
arg_2[PIT].ki = Ano_Parame.set.pid_att_2level[PIT][KI];
arg_2[PIT].kd_ex = Ano_Parame.set.pid_att_2level[PIT][KD];
arg_2[PIT].kd_fb = Ano_Parame.set.pid_att_2level[PIT][KD];
arg_2[PIT].k_ff = 0.0f;
arg_2[YAW].kp = Ano_Parame.set.pid_att_2level[YAW][KP];
arg_2[YAW].ki = Ano_Parame.set.pid_att_2level[YAW][KI];
arg_2[YAW].kd_ex = Ano_Parame.set.pid_att_2level[YAW][KD];
arg_2[YAW].kd_fb = Ano_Parame.set.pid_att_2level[YAW][KD];
arg_2[YAW].k_ff = 0.0f;
}
#define CTRL_1_KI_START 0.f
/角速度环PID参数初始化/
void Att_1level_PID_Init()
{
arg_1[ROL].kp = Ano_Parame.set.pid_att_1level[ROL][KP];
arg_1[ROL].ki = Ano_Parame.set.pid_att_1level[ROL][KI];
arg_1[ROL].kd_ex = 0;//0.000f ;
arg_1[ROL].kd_fb = Ano_Parame.set.pid_att_1level[ROL][KD];
arg_1[ROL].k_ff = 0.0f;
arg_1[PIT].kp = Ano_Parame.set.pid_att_1level[PIT][KP];
arg_1[PIT].ki = Ano_Parame.set.pid_att_1level[PIT][KI];
arg_1[PIT].kd_ex = 0;//0.000f ;
arg_1[PIT].kd_fb = Ano_Parame.set.pid_att_1level[PIT][KD];
arg_1[PIT].k_ff = 0.0f;
arg_1[YAW].kp = Ano_Parame.set.pid_att_1level[YAW][KP];
arg_1[YAW].ki = Ano_Parame.set.pid_att_1level[YAW][KI];
arg_1[YAW].kd_ex = 0;//0.00f ;
arg_1[YAW].kd_fb = Ano_Parame.set.pid_att_1level[YAW][KD];
arg_1[YAW].k_ff = 0.00f;
#if (MOTOR_ESC_TYPE == 2) //电调带刹车
#define DIFF_GAIN 0.3f
arg_1[ROL].kd_fb = arg_1[ROL].kd_fb *DIFF_GAIN;
arg_1[PIT].kd_fb = arg_1[PIT].kd_fb *DIFF_GAIN;
#elif (MOTOR_ESC_TYPE == 1) //电调不带刹车
#define DIFF_GAIN 1.0f
arg_1[ROL].kd_fb = arg_1[ROL].kd_fb *DIFF_GAIN;
arg_1[PIT].kd_fb = arg_1[PIT].kd_fb *DIFF_GAIN;
#endif
}
//设置角速度环的Ki
void Set_Att_1level_Ki(u8 mode)
{
if(mode == 0)
{
arg_1[ROL].ki = arg_1[PIT].ki = 0;
}
else if(mode == 1)
{
arg_1[ROL].ki = Ano_Parame.set.pid_att_1level[ROL][KI];
arg_1[PIT].ki = Ano_Parame.set.pid_att_1level[PIT][KI];
}
else
{
arg_1[ROL].ki = arg_1[PIT].ki = CTRL_1_KI_START;
}
}
//设置角度环的Ki
void Set_Att_2level_Ki(u8 mode)
{
if(mode == 0)
{
arg_2[ROL].ki = arg_2[PIT].ki = 0;
}
else
{
arg_2[ROL].ki = Ano_Parame.set.pid_att_2level[ROL][KI];
arg_2[PIT].ki = Ano_Parame.set.pid_att_2level[PIT][KI];
}
}
_att_2l_ct_st att_2l_ct;
static s32 max_yaw_speed,set_yaw_av_tmp;
#define POS_V_DAMPING 0.02f
static float exp_rol_tmp,exp_pit_tmp;
/角度环控制/
void Att_2level_Ctrl(float dT_s,s16 *CH_N)
{
//将位置环的角度信息(期望角度的负数)储存到角度环的期望角度
exp_rol_tmp = - loc_ctrl_1.out[Y];
exp_pit_tmp = - loc_ctrl_1.out[X];
//如果飞行模式为自稳模式ATT_STAB
if(flag.flight_mode == ATT_STAB)
{
//若位置环算出的期望横滚角加上期望的横滚角的修正的绝对值小于5
if(ABS(exp_rol_tmp + att_2l_ct.exp_rol_adj) < 5)
{
/*积分微调*/
att_2l_ct.exp_rol_adj += 0.2f *exp_rol_tmp *dT_s;
att_2l_ct.exp_rol_adj = LIMIT(att_2l_ct.exp_rol_adj,-1,1);
}
//若位置环算出的俯仰角加上期望的俯仰角偏差的绝对值小于5
if(ABS(exp_pit_tmp + att_2l_ct.exp_pit_adj) < 5)
{
/*积分微调*/
att_2l_ct.exp_pit_adj += 0.2f *exp_pit_tmp *dT_s;
att_2l_ct.exp_pit_adj = LIMIT(att_2l_ct.exp_pit_adj,-1,1);
}
}
else//在非自稳模式下,不需要期望角的调整参数
{
att_2l_ct.exp_rol_adj =
att_2l_ct.exp_pit_adj = 0;
}
*/ **********************以上部分就是说:
在自稳模式下,如果期望的角度很小且与调整参数之间相差小于5,则增大调整参数;
期望角度 = 期望角度 + 角度调整参数
在非自稳模式下,期望角度 = 期望角度
*****************************/
/*正负参考ANO坐标参考方向*/
//对期望角度赋值
att_2l_ct.exp_rol = exp_rol_tmp + att_2l_ct.exp_rol_adj;// + POS_V_DAMPING *imu_data.h_acc[Y];
att_2l_ct.exp_pit = exp_pit_tmp + att_2l_ct.exp_pit_adj;// + POS_V_DAMPING *imu_data.h_acc[X];
/*期望角度限幅*/
att_2l_ct.exp_rol = LIMIT(att_2l_ct.exp_rol,-MAX_ANGLE,MAX_ANGLE);
att_2l_ct.exp_pit = LIMIT(att_2l_ct.exp_pit,-MAX_ANGLE,MAX_ANGLE);
//
//如果速度模式为3
if(flag.speed_mode == 3)
{
//设置飞控的最大航向角速度=250-----------给设置偏航角速度限幅用的
max_yaw_speed = MAX_SPEED_YAW;
}
//如果速度模式为2
else if(flag.speed_mode == 2 )
{
//设置飞控的最大航向角速度=220
max_yaw_speed = 220;
}
else
{
//设置飞控的最大航向角速度=200
max_yaw_speed = 200;
}
//
fc_stv.yaw_pal_limit = max_yaw_speed;
/*摇杆量转换为YAW期望角速度 + 程控期望角速度*/
set_yaw_av_tmp = (s32)(0.0023f *my_deadzone(CH_N[CH_YAW],0,65) *max_yaw_speed) + (-program_ctrl.yaw_pal_dps) + pc_user.pal_dps_set;
/*最大YAW角速度限幅*/
set_yaw_av_tmp = LIMIT(set_yaw_av_tmp ,-max_yaw_speed,max_yaw_speed);
/*没有起飞,复位*/
if(flag.taking_off==0||(flag.locking))
{
att_2l_ct.exp_rol = att_2l_ct.exp_pit = set_yaw_av_tmp = 0;
att_2l_ct.exp_yaw = att_2l_ct.fb_yaw;
}
/*限制误差增大*/
if(att_2l_ct.yaw_err>90)
{
//当偏航角度误差过大时,且此时偏航角速度有值,则直接令偏航角速度=0(不然偏差会越来越大)
if(set_yaw_av_tmp>0)
{
set_yaw_av_tmp = 0;
}
}
else if(att_2l_ct.yaw_err<-90)
{
//当偏航角度误差过大时,且此时偏航角速度有值,则直接令偏航角速度=0(不然偏差会越来越大)----------可以优化一下,调用绝对值函数就可以用一条语句解决
if(set_yaw_av_tmp<0)
{
set_yaw_av_tmp = 0;
}
}
//增量限幅
//将摇杆量转换的偏航角速度
att_1l_ct.set_yaw_speed += LIMIT((set_yaw_av_tmp - att_1l_ct.set_yaw_speed),-30,30);
/*设置期望YAW角度*/
att_2l_ct.exp_yaw += att_1l_ct.set_yaw_speed *dT_s;
/*限制为+-180度*/
if(att_2l_ct.exp_yaw<-180) att_2l_ct.exp_yaw += 360;
else if(att_2l_ct.exp_yaw>180) att_2l_ct.exp_yaw -= 360;
/*计算YAW角度误差*/
att_2l_ct.yaw_err = (att_2l_ct.exp_yaw - att_2l_ct.fb_yaw);
/*限制为+-180度*/
if(att_2l_ct.yaw_err<-180) att_2l_ct.yaw_err += 360;
else if(att_2l_ct.yaw_err>180) att_2l_ct.yaw_err -= 360;
/*赋值反馈角度值---------------------------imu测量值作为反馈*/
att_2l_ct.fb_yaw = imu_data.yaw ;
att_2l_ct.fb_rol = (imu_data.rol ) ;
att_2l_ct.fb_pit = (imu_data.pit ) ;
PID_calculate( dT_s, //周期(单位:秒)
0 , //前馈值
att_2l_ct.exp_rol , //期望值(设定值)
att_2l_ct.fb_rol , //反馈值()
&arg_2[ROL], //PID参数结构体
&val_2[ROL], //PID数据结构体-------------------------------代表副翼
5,//积分误差限幅
5 *flag.taking_off //integration limit,积分限幅
) ;
PID_calculate( dT_s, //周期(单位:秒)
0 , //前馈值
att_2l_ct.exp_pit , //期望值(设定值)
att_2l_ct.fb_pit , //反馈值()
&arg_2[PIT], //PID参数结构体
&val_2[PIT], //PID数据结构体-------------------------代表升降
5,//积分误差限幅
5 *flag.taking_off //integration limit,积分限幅
) ;
PID_calculate( dT_s, //周期(单位:秒)
0 , //前馈值
att_2l_ct.yaw_err , //期望值(设定值)
0 , //反馈值()
&arg_2[YAW], //PID参数结构体
&val_2[YAW], //PID数据结构体-------------------------------代表方向
5,//积分误差限幅
5 *flag.taking_off //integration limit,积分限幅
) ;
//经过PID调节后的结果(角度环的输出)保存在val_2[i].out中
}
_att_1l_ct_st att_1l_ct;
static float ct_val[4];
/角速度环控制/
void Att_1level_Ctrl(float dT_s)
{
改变控制参数任务(最小控制周期内)
ctrl_parameter_change_task();//改变控制参数,-------------应该是改变pid的参数
/*目标角速度赋值--------------------期望角速度赋值*/
for(u8 i = 0;i<3;i++)
{
att_1l_ct.exp_angular_velocity[i] = val_2[i].out;// val_2[i].out;//目标速度赋值就是遥控器传过去给到角度环的值,从角度环输出到角速度环就是目标的角速度,也就是你想要控制飞机怎么去飞的一个值
//val_2[i]就是二环 val_2[i].out就是姿态角度环的输出
/*
对于给定的状态,可以是静止也可以是前进。如果是静止,那么姿态角度为0,如果是前进,俯仰角保持一定的、
角度。总之,为了满足给定的状态必须保持一个一定的姿态,也就是我们期望达到的姿态,也就是期望的角度。
如果我们能测的当前的角度,就可以通过pid求出我们需要多大的角速度。
*/
}
/*目标角速度限幅(没有考虑到YAW角)*/
att_1l_ct.exp_angular_velocity[ROL] = LIMIT(att_1l_ct.exp_angular_velocity[ROL],-MAX_ROLLING_SPEED,MAX_ROLLING_SPEED);
att_1l_ct.exp_angular_velocity[PIT] = LIMIT(att_1l_ct.exp_angular_velocity[PIT],-MAX_ROLLING_SPEED,MAX_ROLLING_SPEED);
/*反馈角速度赋值-----------------------就是陀螺仪测得的当前角速度值*/
att_1l_ct.fb_angular_velocity[ROL] = ( sensor.Gyro_deg[X] );
att_1l_ct.fb_angular_velocity[PIT] = (-sensor.Gyro_deg[Y] );
att_1l_ct.fb_angular_velocity[YAW] = (-sensor.Gyro_deg[Z] );
/*PID计算*/
for(u8 i = 0;i<3;i++)//这个函数就是调用PID函数来进行各个角速度的计算得到输出值,也就是控制电机的转速的值
{
PID_calculate( dT_s, //周期(单位:秒)
0, //前馈值
att_1l_ct.exp_angular_velocity[i], //期望值(设定值)
att_1l_ct.fb_angular_velocity[i], //反馈值(测量值)
&arg_1[i], //PID参数结构体
&val_1[i], //PID数据结构体
200,//积分误差限幅
CTRL_1_INTE_LIM *flag.taking_off //integration limit,积分幅度限幅
) ;
ct_val[i] = (val_1[i].out);
}
/*赋值,最终比例调节*/
mc.ct_val_rol = FINAL_P *ct_val[ROL];//FINAL_P点击输出量比例:0.5
mc.ct_val_pit = X_PROPORTION_X_Y *FINAL_P *ct_val[PIT];//X_PROPORTION_X_Y:1.0f
mc.ct_val_yaw = FINAL_P *ct_val[YAW];
/*输出量限幅*/
mc.ct_val_rol = LIMIT(mc.ct_val_rol,-1000,1000);
mc.ct_val_pit = LIMIT(mc.ct_val_pit,-1000,1000);
mc.ct_val_yaw = LIMIT(mc.ct_val_yaw,-400,400);
}
_rolling_flag_st rolling_flag;
总结
该源文件主要写了两个函数:角速度环和角度环。构成了双环姿态控制器。
其中:角速度环是内环;角度环是外环。
角度环:利用PID求解期望角速度
- 期望的YAW角度
摇杆量转换的角速度 * 周期 + 当前角度(位置环的输出) - 期望的ROL/PIT角度
在自稳模式下:期望角度(位置环的输出) + 修正参数
非自稳模式下:期望角度 = 期望角度(位置环的输出) - 反馈角度值
就是陀螺仪的测量值 - PID求解出期望的角速度
角速度环:也是利用PID求解出电机控制量
就是角度环的输出
2. 反馈角速度值
就是陀螺仪测量的角速度
3. 利用PID求解出角速度环的输出,即电机控制量
所以,根据以上的分析我们可以知道,通过角度环与角速度环,最终得到的是对于电机的控制量。且对于角度环与角速度环的输入就是周期与飞行模式。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)