PID源码讲解
来源:互联网 发布:vlookup查找相同数据 编辑:程序博客网 时间:2024/06/06 18:11
有人让我解释一下我程序里面PID计算的过程,这里就插一节吧,就是介绍下我的PID,当然,还很不完善,后期肯定还要经过很多改动才行,这里就先介绍下现在的"初级版"吧.
void PID_CAL(void) PID计算函数
{
static float thr=0,rool=0,pitch=0,yaw=0; 控制量
static float rool_i=0,pitch_i=0; 积分
int16_t Motor1,Motor2,Motor3,Motor4; 四个电机输出
IMU_TEST(); 计算姿态
GET_EXPRAD(); 获得控制量
////////////////////////////////////////////////////////////////////////////////
rool = PID_RP.P * DIF_ANGLE.X; roll方向的P计算
if(Q_ANGLE.Rool>-0.1 && Q_ANGLE.Rool<0.1) 判断I是否需要清零
{
rool_i = 0;
}
rool_i -= PID_RP.I * Q_ANGLE.Rool; I计算
PID_RP.IMAX = DIF_ANGLE.X * 10; 积分限幅
if(PID_RP.IMAX<0)
{
PID_RP.IMAX = (-PID_RP.IMAX) + 100;
}
else
{
PID_RP.IMAX += 100;
}
if(rool_i>PID_RP.IMAX) rool_i = PID_RP.IMAX;
if(rool_i<-PID_RP.IMAX) rool_i = -PID_RP.IMAX;
rool += rool_i; 积分
rool -= PID_RP.D * GYRO_F.X; D计算
///////////
pitch = PID_RP.P * DIF_ANGLE.Y; 同上
if(Q_ANGLE.Pitch>-0.1 && Q_ANGLE.Pitch<0.1)
{
pitch_i = 0;
}
pitch_i -= PID_RP.I * Q_ANGLE.Pitch;
if(PID_RP.IMAX<0)
{
PID_RP.IMAX = (-PID_RP.IMAX) + 100;
}
else
{
PID_RP.IMAX += 100;
}
if(PID_RP.IMAX<0) PID_RP.IMAX = -PID_RP.IMAX;
if(pitch_i>PID_RP.IMAX) pitch_i = PID_RP.IMAX;
if(pitch_i<-PID_RP.IMAX) pitch_i = -PID_RP.IMAX;
pitch += pitch_i;
pitch -= PID_RP.D * GYRO_F.Y;
/////////////
GYRO_I[0].Z += EXP_ANGLE.Z/3000; yaw方向就简单的用了陀螺的积分 PD
yaw = -10 * GYRO_I[0].Z;
yaw -= 3 * GYRO_F.Z;
//
thr = RC_DATA.THROTTLE+400;
////////////////////////////////////////////////////////////////////////////////将控制量输出给电机
Motor1=(int16_t)(thr + rool - pitch + yaw);
Motor2=(int16_t)(thr + rool + pitch - yaw);
Motor3=(int16_t)(thr - rool + pitch + yaw);
Motor4=(int16_t)(thr - rool - pitch - yaw);
if(FLY_ENABLE && (RC_DATA.THROTTLE>-400)) 和解锁有关,未解锁或油门太低电机禁止转动
MOTO_PWMRFLASH(Motor1,Motor2,Motor3,Motor4);
else
MOTO_PWMRFLASH(0,0,0,0);
}
void PID_CAL(void) PID计算函数
{
static float thr=0,rool=0,pitch=0,yaw=0; 控制量
static float rool_i=0,pitch_i=0; 积分
int16_t Motor1,Motor2,Motor3,Motor4; 四个电机输出
IMU_TEST(); 计算姿态
GET_EXPRAD(); 获得控制量
////////////////////////////////////////////////////////////////////////////////
rool = PID_RP.P * DIF_ANGLE.X; roll方向的P计算
if(Q_ANGLE.Rool>-0.1 && Q_ANGLE.Rool<0.1) 判断I是否需要清零
{
rool_i = 0;
}
rool_i -= PID_RP.I * Q_ANGLE.Rool; I计算
PID_RP.IMAX = DIF_ANGLE.X * 10; 积分限幅
if(PID_RP.IMAX<0)
{
PID_RP.IMAX = (-PID_RP.IMAX) + 100;
}
else
{
PID_RP.IMAX += 100;
}
if(rool_i>PID_RP.IMAX) rool_i = PID_RP.IMAX;
if(rool_i<-PID_RP.IMAX) rool_i = -PID_RP.IMAX;
rool += rool_i; 积分
rool -= PID_RP.D * GYRO_F.X; D计算
///////////
pitch = PID_RP.P * DIF_ANGLE.Y; 同上
if(Q_ANGLE.Pitch>-0.1 && Q_ANGLE.Pitch<0.1)
{
pitch_i = 0;
}
pitch_i -= PID_RP.I * Q_ANGLE.Pitch;
if(PID_RP.IMAX<0)
{
PID_RP.IMAX = (-PID_RP.IMAX) + 100;
}
else
{
PID_RP.IMAX += 100;
}
if(PID_RP.IMAX<0) PID_RP.IMAX = -PID_RP.IMAX;
if(pitch_i>PID_RP.IMAX) pitch_i = PID_RP.IMAX;
if(pitch_i<-PID_RP.IMAX) pitch_i = -PID_RP.IMAX;
pitch += pitch_i;
pitch -= PID_RP.D * GYRO_F.Y;
/////////////
GYRO_I[0].Z += EXP_ANGLE.Z/3000; yaw方向就简单的用了陀螺的积分 PD
yaw = -10 * GYRO_I[0].Z;
yaw -= 3 * GYRO_F.Z;
//
thr = RC_DATA.THROTTLE+400;
////////////////////////////////////////////////////////////////////////////////将控制量输出给电机
Motor1=(int16_t)(thr + rool - pitch + yaw);
Motor2=(int16_t)(thr + rool + pitch - yaw);
Motor3=(int16_t)(thr - rool + pitch + yaw);
Motor4=(int16_t)(thr - rool - pitch - yaw);
if(FLY_ENABLE && (RC_DATA.THROTTLE>-400)) 和解锁有关,未解锁或油门太低电机禁止转动
MOTO_PWMRFLASH(Motor1,Motor2,Motor3,Motor4);
else
MOTO_PWMRFLASH(0,0,0,0);
}
程序就这么简单,当然还需要很多改进,PID参数也需要慢慢调试才行
转载http://www.anotc.com/Articles/Browse/1
阅读全文
0 0
- PID源码讲解
- 转载PID讲解
- 四轴PID讲解
- 四轴PID讲解
- PID算法完全讲解
- 四轴PID讲解
- 四轴PID讲解
- PID算法完全讲解
- 四轴PID讲解
- 四轴PID讲解
- 四轴PID讲解
- 两种四轴PID讲解
- PID算法完全讲解
- 四轴PID讲解
- pid算法源码
- 匿名四轴PID参数调试讲解
- VB写的PID控制源码公布
- keepalived源码浅析——pid文件
- [vim] G
- RFID学习笔记
- 扁平化设计是否已经失宠?10个案例告诉你答案
- G711 编码 PCM (ALAW & ULAW)
- 库函数和底层系统调用
- PID源码讲解
- 胶水语言Python技术百问_从新手到进阶
- 【bzoj1503】 [NOI2004]郁闷的出纳员
- kotlin学习笔记(二)
- oracle数据库迁移
- android 如何保护我们的app(一)(干货)
- 【javascript】中国省市区号JSON格式数据--2017年为准,含省市名称和电话区号
- git命令
- linux下的gdb调试