搜索
bottom↓
回复: 28

KK_C源代码的重点分析讲解和疑惑,希望懂的朋友能看到...

[复制链接]

出0入0汤圆

发表于 2012-9-16 16:30:54 | 显示全部楼层 |阅读模式
接触四轴有半个月了。在网上看到了gale 大哥的KKC代码。里面有详细的注释。相对其它四轴程序比较简单容易理解。给了我们这些菜鸟级的四轴爱好者一个很好的入门教程与编程思路。感谢gale大哥的无私奉献和辛苦工作。看了几天代码,借助这个平台写一写我的简单理解和疑惑。望懂的朋友能对每个疑问点给些详细的回答。对现在或以后学习KK_C程序的朋友也算是解惑吧。
看到这个贴的朋友顶顶 别沉了。希望大家都能看到参与讨论共同 进步!。


void main(void)
{        
        Init();                                    //Board init 初始化系统
        PpmWaitSignal();        //Wait rx signal, led will flash 等待接收机的信号,等待时LED闪烁
        Setup();                        //Load & Adjust parameters 加载&调节参数
        
        //Main loop 主循环
        LED0_OFF();
        while(1)
        {               
                TimerRst();
                        CaclAttitude();        //Caculate plane attitude 计算飞行器姿态        
                TimerTo(1000);
                                
                //Do something between MotorControlBegin() and MotorControlEnd
                //See functions declaration, can not exceed 1000us
                //在MotorControlBegin()和MotorControlEnd()之间干点事儿,注意不要超过1000us
                MotorControlBegin();        //Output head of ppm signal 输出PPM信号的头部分
                        PpmReadSignal();        //Read rx 读取接收机信号 140us
                        if(RxThr<RxThrLow)        //If thr shutdown 如果油门关闭
                        {        
                                GyroGainRead();                //Read gain 读取感度电位器 670us               
                                ArmingRoutine();        //Arm/disarm 加锁解锁测试 5us
                        }
                        else
                        {
                                AxisMixer();                //Cacl motor signal 计算电机信号 305us
                        }               
                        
                        //If locked(arm) or no gyro base, shutdown all motor
                        //如果处于锁定态或者陀螺仪基准未建立,关闭所有马达
                        if(InLock || GyroBaseCnt || RxThr<5)
                        {
                                  Motor1=Motor2=Motor3=Motor4=0;
                        }               
                        //MOTOR6_L();                        //I use it for test execute period 我用来观察执行时间的               
                MotorControlEnd();                //Output whole ppm signal 输出完整的PPM信号
        }
}



从main函数开始看: Init();                                    //Board init 初始化系统 设置IO端口和定时器。
第二个函数调用:void PpmWaitSignal(void)
{
         uchar rxcnt;
                  
         //Wait for 5 times signal received
         //等待收到5次信号
         for(rxcnt=RxValid=0;rxcnt<20;)
         {
                   //Read ppm signals
                   PpmReadSignal();
               
                   //If got signal, inc rxcnt
                  if(RxValid==0x0f)
                 {
                          RxValid=0;
                        rxcnt++;
                }
                  LED0_TOG();
                Delay1ms(50);
        }
}


里面有个函数:void PpmReadSignal(void) 读取PPM信号并作处理和限副。
疑问1:RxValid为四个通道都有效读取的标志。Rxcnt<20一直运行。那么应该是等待收到20次信号 怎么是5次呢?

第三个函数:
Setup();  根据油门杆位置进行相应参数设置。
接着进入死循环:
TimerRst(); 类似于开始计时器。
接着调用:
void CaclAttitude(void)
{
        GyroRead();// 采样陀螺仪,进行相应滤波。
        
        //If no gyro base, calibrate gyro
        //如果还未建立,建立它
        if(GyroBaseCnt)    建立基准
        {                        
                 GyroBaseRol+=GyroRol;
                GyroBaseRol/=2;
               
                GyroBasePit+=GyroPit;
                GyroBasePit/=2;
               
                GyroBaseYaw+=GyroYaw;
                GyroBaseYaw/=2;
               
                GyroBaseCnt--;
                if(!(GyroBaseCnt&7)) LED0_TOG();        //Shine LED show gyro cali 闪烁LED表示在进行陀螺仪校准
               
                GyroRolI=GyroPitI=GyroYawI=0;//Reset I value 清空积分值
        }
        else
        {               
                if(InLock)
                {
                         //熄灭LED表示在锁定中
                        LED0_OFF();
                }
                else
                {
                          //Remove base part from gyro value
                        //减去基础值
                         GyroRol-=GyroBaseRol;
                         GyroPit-=GyroBasePit;
                         GyroYaw-=GyroBaseYaw;
        
                        //Reverse gyro signals if necessary
                        //根据设置反转各个陀螺仪信号
                        if(BITTST(DevRev,GYRO_ROL))          GyroRol=-GyroRol;
                        if(BITTST(DevRev,GYRO_PIT))          GyroPit=-GyroPit;
                        if(BITTST(DevRev,GYRO_YAW))          GyroYaw=-GyroYaw;
                        
                        //Gyro feature compensation
                        //陀螺仪特性补偿
                        GyroRol=GyroCompe(GyroRol,GyroRolPN);
                        GyroPit=GyroCompe(GyroPit,GyroPitPN);
                        GyroYaw=GyroCompe(GyroYaw,GyroYawPN);
                        
                        //Sum integral value with return
                        //带回归计算积分值               
                        GyroRolI=GyroIntegral(GyroRolI,GyroRol);
                        GyroPitI=GyroIntegral(GyroPitI,GyroPit);
                        GyroYawI=GyroIntegral(GyroYawI,GyroYaw);
               
                        //Light LED
                        //点亮LED表示在工作中
                         LED0_ON();
                }
        }
}

         
int GyroIntegral(int v,int delta)
{
        //Integral gain
        //内部积分增益
        delta/=4;//delta=-511~511 -> -127~127
        v+=delta;
        
        //Limit value
        //限幅
        if(v>I_MAX)         v=I_MAX;
        if(v<-I_MAX) v=-I_MAX;

        //Return value
        //回归
        v/=I_RETSTEP;   //I_RETSTEP== 2

        return v;
}
疑问2:里面用到的积分回归法。我个人理解 i是对角速度积分然后 调节I的值 随着误差值的减少而作相应衰减增加而相应增加。自身除于2就算回归算法了吗,但不知道这个这个算法具体怎么起作用的,在实际应用中有什么好处?在帖子中看gale大哥回答是积分回归是为了避免漂移的一种不得已做法,就是让积分作用自行慢慢消失,这样,即使出现较大漂移,也不会“发疯”,如果没有回归,又没有加速度校准,四轴飞起来会很稳,但是一旦摇摆几次后,就会发疯。这样的话随着陀螺仪与目标值的差值减少而趋近于0
接着往下:
TimerTo(1000); 等待到1000us 否则一直喂狗
MotorControlBegin();
PpmReadSignal();//读PPm  140us


GyroRol-=GyroBaseRol;
GyroPit-=GyroBasePit;
GyroYaw-=GyroBaseYaw;
ail+=GainAdj(GyroRol,GainRol)+GainAdj(GyroRolI,GainPit);
ele+=GainAdj(GyroPit,GainRol)+GainAdj(GyroPitI,GainPit);
rud=RxRud/4+GainAdj(GyroYaw,GainYaw);//+GainAdj(GyroYawI,GainPit);


int GyroIntegral(int v,int delta)
{
        //Integral gain
        //内部积分增益
        delta/=4;//delta=-511~511 -> -127~127
        v+=delta;
        
        //Limit value
        //限幅
        if(v>I_MAX)         v=I_MAX;
        if(v<-I_MAX) v=-I_MAX;

        //Return value
        //回归
        v/=I_RETSTEP;

        return v;
}

疑问3:I+= delta/4/2  相当于除于8 也就是i大概在-63~63内变化?但我看有的朋友分析说[[[对速度进行积分,将陀螺的输出值GyroYaw/4再加上积分值GyroYawI(初始是0)一次积分后增加6

6 ,如何把陀螺仪的输出变成电机控制信号 首先加上感度信息,算法是积分值GyroYawI×感度
(0-128)×0.0078 , 副翼ail输出量=当前角数度+角速度积分积分。
同理可以得到下面几个调整量
副翼 ail=3
升降 ele=3
方向 rud=3]]]

这些值他怎么算的?

调整量:
ail+=GainAdj(GyroRol,GainRol)+GainAdj(GyroRolI,GainPit);
ele+=GainAdj(GyroPit,GainRol)+GainAdj(GyroPitI,GainPit);
rud=RxRud/4+GainAdj(GyroYaw,GainYaw);//+GainAdj(GyroYawI,GainPit);

化成另外一种形式:ail+= GyroRol*GainRol/128+ GyroRolI*GainPit/128
                  ail+= (GyroRol*GainRol+ GyroRolI*GainPit)/128
疑问4:GainRol应该相当于微调了。这个式子应该是算增量了,难道前面的是P后面的是I吗?如果按这样理解的话 等化下:ail+= GyroRol*P+ I*(GainPit/128)  那么P值是根据感度值/128了 这样P值就在(0~1)之间了,I的话为什么乘与(GainPit/128)不是应该是GainRol吗?,天啊,为什么 十万个为什么!
(:P  哥不才,脑子此刻浆糊了)其它式子也一窍不通了   

// 假设 X模式下
                //     1   2
                //       X
                //     3   4
如果我现在要翻滚动作 (1,4转向同向 2,3同向, 12前方位置)
那应该设法增加1,3的转速 (相邻轴方向反抵消自转)     
                 Motor1=MotorLimitValue(thr + ail - ele + rud);
                 Motor2=MotorLimitValue(thr - ail - ele - rud);
                 Motor3=MotorLimitValue(thr + ail + ele - rud);
                 Motor4=MotorLimitValue(thr - ail + ele + rud);   
上述1,3式子中很明显有+ail的动作。而2,4是在减。同理可知其它动作的调整。
        

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2012-9-16 19:34:21 | 显示全部楼层
本帖最后由 小笨蛋 于 2012-9-16 19:36 编辑

沙发陪楼主等待高人。。我做四轴也急的要命啊。。你看看我这几天的帖子就知道了

另外第四个问题应该是P和I用独立的比例吧,也许需要两个不一样呢

出0入0汤圆

发表于 2012-9-16 19:51:35 | 显示全部楼层
kk-c写的很好啊。以前移植到stm32平台上试过。。。

出0入0汤圆

 楼主| 发表于 2012-9-16 21:03:02 | 显示全部楼层
zhaofeng2008 发表于 2012-9-16 19:51
kk-c写的很好啊。以前移植到stm32平台上试过。。。

呵呵  发你Q  一起聊下

出0入0汤圆

 楼主| 发表于 2012-9-16 22:24:30 | 显示全部楼层
疑问2 和四已经明白了 ,现在只有疑问3了  有知道的朋友可以讨论下

出0入0汤圆

发表于 2012-9-18 15:33:21 | 显示全部楼层
看的还不是很懂,再看,呵呵,KK_C里面有没有什么四元数之类的东西啊,感觉好像没看到啊

出0入0汤圆

发表于 2012-9-18 15:53:31 | 显示全部楼层
楼主太在乎这些数值了, 通过观察就可以知道这些值要根据自己的四轴去调整的,经过亲测移植到STM32是可以飞的

出0入0汤圆

发表于 2012-10-4 12:11:38 | 显示全部楼层
mark,可以参考下

出0入0汤圆

发表于 2012-10-11 22:59:25 | 显示全部楼层
最近看了一下程序,有一个想不通的地方,主程序进入死循环后会有“MotorControlBegin();”输出PPM信号的头部分,然后循环最后有“MotorControlEnd();                //Output whole ppm signal 输出完整的PPM信号”这些按我的理解都是控制PPM信号高电平时间的,PPM信号周期都是20MS的,那剩下的那些十几毫秒的低电平时间在哪里控制的啊,望大神求教啊,一直想不通。。。

出0入0汤圆

发表于 2012-10-31 20:18:40 | 显示全部楼层
yangjinghua1990 发表于 2012-10-30 11:28
我有个疑问,他对积分进行衰减,如果我把四轴静止斜放,那么不就没有矫正力了吗,因为输出角度是0 ...

你说的这个应该是P调节,还有一个I调节呢,I调节就是有倾斜角度就会有矫正力输出

出0入0汤圆

发表于 2012-11-4 13:26:05 | 显示全部楼层
Mark。。

出0入0汤圆

发表于 2012-11-5 18:30:38 | 显示全部楼层
MARK。。中

出0入0汤圆

发表于 2012-11-6 14:04:32 | 显示全部楼层
那里可以找到KK_C的源代码啊,楼主可以发一份给我吗,邮箱1779696316@qq.com

出0入0汤圆

发表于 2012-11-6 14:04:54 | 显示全部楼层
我也想研究研究

出0入0汤圆

发表于 2012-11-6 14:18:19 | 显示全部楼层
http://bbs.5imx.com/bbs/forum.ph ... p;extra=&page=1

出0入0汤圆

发表于 2013-5-7 23:37:19 | 显示全部楼层
你好啊,我也正kk_C的源代码,飞行效果不稳定啊,代码感觉消化得差不多了,但起飞时不是平稳上升的啊,会向一个方向漂,加个qq一起交流交流吧

出0入0汤圆

发表于 2013-5-9 23:21:29 | 显示全部楼层
先顶再看,后面会用到,先学习下

出0入0汤圆

发表于 2013-5-10 17:47:16 | 显示全部楼层
先顶再看,后面会用到,先学习下

出0入0汤圆

发表于 2013-5-12 00:06:14 | 显示全部楼层
能不能把q 给我,我加你深入讨论下

出0入0汤圆

发表于 2013-7-2 01:48:09 | 显示全部楼层
不错 顶

出0入0汤圆

发表于 2013-7-2 13:54:21 | 显示全部楼层
认真的孩子,我还真没仔细看过

出0入0汤圆

发表于 2013-7-7 13:50:07 | 显示全部楼层
为什么我烧入KK_c到黑版KK飞控怎么没反应啊,接收机是用天9的

出0入0汤圆

发表于 2013-8-21 16:29:10 | 显示全部楼层
楼主这个程序调试成功了吗?我移植到STM32上面,飞不稳,还飘。

出0入0汤圆

发表于 2013-8-21 16:30:03 | 显示全部楼层
雨霖铃 发表于 2013-5-7 23:37
你好啊,我也正kk_C的源代码,飞行效果不稳定啊,代码感觉消化得差不多了,但起飞时不是平稳上升的啊,会向 ...

,我也是飘得厉害,你调试成功了吗?

出0入0汤圆

发表于 2013-9-28 10:53:35 | 显示全部楼层
void IsrRxCh1(void)
{
        BITSET(RxValid,0);
        if(PIND&2) //Rising 上升沿
        {
                 RxChStart1=TCNT1;
        }
        else//Falling 下降沿
        {
                 RxChBusy=1;
                 RxCh1=TCNT1-RxChStart1;
                RxChBusy=0;
        }
}
RxCh1=TCNT1-RxChStart1;
TCNT1溢出怎么办

出0入0汤圆

发表于 2013-9-28 13:28:49 | 显示全部楼层
KK四轴 无人问津?

出0入0汤圆

发表于 2014-2-25 15:42:10 | 显示全部楼层
aishadow 发表于 2012-9-16 22:24
疑问2 和四已经明白了 ,现在只有疑问3了  有知道的朋友可以讨论下

你好,我现在也在做四轴,能请问几个问题么

出0入0汤圆

发表于 2014-2-25 20:04:56 | 显示全部楼层
没有加速器,玩玩还可以
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 14:33

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表