搜索
bottom↓
回复: 131

飞控算法应用之两轮自平衡小车

[复制链接]

出0入0汤圆

发表于 2010-4-6 15:41:00 | 显示全部楼层 |阅读模式
09-10年寒假,与几个同学合伙做四轴,时间原因,最终不了了之,甚痛~
这学期做毕业论文,于是选了“基于FPGA的两轮自平衡机器人”这个题目,基本做完了。
传感器用的是ENC-03MB和ADXL330(大材小用啊~),算法仿德国四轴,在NIOS中重写的。
效果不错,现上传视频及图片。
另,感谢OURAVR,伴我走过大学时光,受益良多!
感谢曾经和我并肩作战的同学们,以及支持我们的老师和所有人~

http://player.youku.com/player.php/sid/XMTYzMTQ0MDAw/v.swf


小车

小车 (原文件名:P1010018.JPG)

底盘

底盘 (原文件名:P1010020.JPG)

马达驱动

马达驱动板 (原文件名:P1010014.JPG)


马达驱动板(pcb) (原文件名:mtf1.JPG)

传感器

传感器 (原文件名:P1010033.JPG)


传感器(pcb) (原文件名:P1010011.JPG)

调试界面

gui (原文件名:P10005.JPG)

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2010-4-6 15:50:45 | 显示全部楼层
sf, mark

出0入0汤圆

发表于 2010-4-6 16:23:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-6 16:29:58 | 显示全部楼层
没看到fpga

出0入0汤圆

发表于 2010-4-6 16:47:54 | 显示全部楼层
关注中

出0入0汤圆

发表于 2010-4-6 18:05:23 | 显示全部楼层
我也想做一个,不过想做个大的,搜集资料中,楼主能不能把主要思路和大概的流程说说?

出0入0汤圆

发表于 2010-4-6 18:32:42 | 显示全部楼层
不错,看视频还不是太稳定!

出0入0汤圆

发表于 2010-4-6 18:38:14 | 显示全部楼层
PID 啊   不过,从视频看,有时振荡厉害,是因有电缆的缘故吗?

出0入0汤圆

发表于 2010-4-6 18:40:25 | 显示全部楼层
楼主,能不能 改用MEGA系列如MEGA8或16等,简单实现一下呢? FPGA又上台阶了。

出0入0汤圆

 楼主| 发表于 2010-4-6 18:58:24 | 显示全部楼层
回复【7楼】highnose
-----------------------------------------------------------------------
PID 啊   不过,从视频看,有时振荡厉害,是因有电缆的缘故吗?


应该不是~
小车用的是减速马达,最后一级齿轮,齿距较大,马达轴可以在5度左右范围内自由转动
刚开始做时,就意识到这个问题了,做完以后,效果还算可以(要求不高),就没换马达~

出0入0汤圆

发表于 2010-4-6 19:04:08 | 显示全部楼层
那加速度传感器是怎么焊上去的?真的是热风枪吹上去的么?

出0入0汤圆

 楼主| 发表于 2010-4-6 19:18:27 | 显示全部楼层
回复【5楼】zq186
-----------------------------------------------------------------------
我也想做一个,不过想做个大的,搜集资料中,楼主能不能把主要思路和大概的流程说说?


实质是对角度进行PID控制.

首先手动让小车站立,当松手后小车不倒(有点难哦)。此时,小车所在的竖直面为参考面。然后实时计算小车与参考面的夹角,最后PID即可。

至于如何PID,有如下思路可供参考。
先调P(只有P),当小车差不多可以前后等幅震荡时,P就算调好了;
接下来,把P值减半,加入D。D取到合适值时,小车基本可以稳定站立;
最后加入I,以提高小车反应的快速性。

难点是获得这个夹角。也就是陀螺仪和加速度计的融合,这方面可参考
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3348262&bbs_page_no=1&bbs_id=1025

希望回答对你有帮助~GOODLUCK!

出0入0汤圆

 楼主| 发表于 2010-4-6 19:24:45 | 显示全部楼层
回复【10楼】verysmart
-----------------------------------------------------------------------

那加速度传感器是怎么焊上去的?真的是热风枪吹上去的么?


嘿嘿~这个问题好~
是09年暑假焊的~
实不相瞒,当时没有热风枪,而且烙铁是个大粗头,就这些,我整整焊了俩小时,~
还好,加速度计没被我搞坏~
并且,焊好后,赶快用502给全沾上了~

哈哈,痛苦的回忆~不过主要是没经验~~~~

出0入0汤圆

发表于 2010-4-6 21:26:06 | 显示全部楼层
呵呵,中国的segway

出0入0汤圆

 楼主| 发表于 2010-4-7 12:04:36 | 显示全部楼层
回复【13楼】jjj206
-----------------------------------------------------------------------

呵呵,中国的segway


segway 的重心好像在轮轴下方~

日本人做得好~

(原文件名:U3-X.jpg)



(原文件名:xinsrc_3021002080844883026116.jpg)


(原文件名:U68P2T1D1263877F13DT20061130081111.jpg)

出0入0汤圆

发表于 2010-4-7 12:25:25 | 显示全部楼层
人才!作为本科生做到这个,应可以让很多研究生都汗颜的。

个人理解,不知道对否,请楼主指正,呵呵
我是学控制的,一看到类似的东西,我首先想到倒立摆,如果算倒立摆的话,那应该是一级的。
第二,我似乎没有看到您的FPGA的位置,不知道躲在哪里的,呵呵
第三,您这个控制的采集的只有角度吗?输出电机控制信号?SISO控制?以前本科毕设的时候,有同学搞一级的倒立摆,看着很复杂,都是用的状态空间,不知道您是否只是单变量控制?

出0入0汤圆

发表于 2010-4-7 12:38:45 | 显示全部楼层
不错,这个是我的作品(http://v.youku.com/v_show/id_XOTQwNjg0MjQ=.html),也是在论坛里面混的。重心位置很高,减速器间隙有点大。

出0入0汤圆

 楼主| 发表于 2010-4-7 13:43:14 | 显示全部楼层
回复【15楼】leoyang
-----------------------------------------------------------------------

人才!作为本科生做到这个,应可以让很多研究生都汗颜的。

个人理解,不知道对否,请楼主指正,呵呵
我是学控制的,一看到类似的东西,我首先想到倒立摆,如果算倒立摆的话,那应该是一级的。
第二,我似乎没有看到您的FPGA的位置,不知道躲在哪里的,呵呵
第三,您这个控制的采集的只有角度吗?输出电机控制信号?SISO控制?以前本科毕设的时候,有同学搞一级的倒立摆,看着很复杂,都是用的状态空间,不知道您是否只是单变量控制?


先生过奖~ 我学的电子,只不过是有兴趣有行动而已

一、对倒立摆不甚了解,凭感觉,应该算是一级,呵呵
二、FPGA确实没在图片上,用的是DE1开发板,通过排线与小车连接(视频中可看到排线)
三、采集的是陀螺仪和加速度计的值(FPGA控制两路AD。Verilog语言编写控制时序,最后封装成IP核,由NIOS II 软核读取),
    输出为两路PWM,精度 正反转都是1/5_000。这应该不是SISO吧?
    控制程序确实是单变量,也就是角度,而且只用了PID。
四、个人认为,控制的难点,在于获取准确的角度。用状态空间固然不错,而且便于计算系统的可控性、能观性,再结合模糊控制,
    或许效果很好~  这些东西很深奥,虽然去年自学过,但还是只懂得一些基本原理~
    相反,我喜欢把复杂的事情简单化,就像德国人对角度的获取。
    其实,德国人的算法也有自动控制原理在里面,如下图(来自一篇有关  汽车制动问题研究  的文章~~):

(原文件名:ourdev_528973.jpg)

    原文点击此处下载 ourdev_544261.pdf(文件大小:112K) (原文件名:measure_dynamic_motion_combine_gyro_with_acc.pdf)

出0入0汤圆

 楼主| 发表于 2010-4-7 13:51:38 | 显示全部楼层
回复【16楼】yangyh75
-----------------------------------------------------------------------

不错,这个是我的作品(http://v.youku.com/v_show/id_XOTQwNjg0MjQ=.html),也是在论坛里面混的。重心位置很高,减速器间隙有点大。


不错,早拜读(see)过。
能否说说你的控制思路,希望多交流,彼此进步

出0入0汤圆

发表于 2010-4-8 12:56:23 | 显示全部楼层
【17楼】 DDAI
.....
---------------------
谢谢你的提供的文章,下来看看,呵呵

出0入0汤圆

发表于 2010-4-8 22:28:26 | 显示全部楼层
具体的算法核心就是一个数字低通(RC)滤波器.

出0入0汤圆

发表于 2010-4-8 22:33:17 | 显示全部楼层
该滤波器在以上的使用也称作组合滤波器(Complementary Filter).
angle = 高通系数*(angle1+gyro*dt)+ 低通系数*(x_acc);
angle为本次的估计值;
angle1为上一次的估计值;
x_acc为从加速度计算出的角度;

出0入0汤圆

发表于 2010-4-8 22:43:08 | 显示全部楼层
大家看一下的录像:
http://www.youtube.com/watch?v=HzkSJKIBofs
Complementary Filters vs Kalman Filter vs Extended Kalman Filter (组合滤波器,卡尔曼滤波器,扩展卡尔曼滤波器的对比)

出0入0汤圆

发表于 2010-4-8 23:05:02 | 显示全部楼层
点击此处下载 ourdev_544597.pdf(文件大小:99K) (原文件名:7409_PCB.pdf)

(原文件名:DSC00788.jpg)


(原文件名:DSC00783.jpg)


(原文件名:DSC00784.jpg)


借楼主的地盘秀秀我的扩大版双轮车,选用无刷电机,为此专门设计了pcb,上图有自己做的双通道无刷驱动器,目前已经完成模拟测试,情况勉强可以。下地实际测试时反映跟不上,调整KP,KI,KD无改善。可能由于选用的无刷电机性能不好,油门加速滞后所致,设法调整无刷驱动通道软件,无改善。目前准备重新选用一款性能优良的无刷电机。
整个top结构为:主程序使用了kalman滤波+PID控制,主控制器和两个无刷通道之间使用I2C传递油门信号和转速信号。

出0入0汤圆

发表于 2010-4-14 15:32:00 | 显示全部楼层
回复【楼主位】DDAI
---------------------------------------------------------------------
看看我的。

(原文件名:IMG_1741-1.jpg)

出0入0汤圆

 楼主| 发表于 2010-4-18 20:29:51 | 显示全部楼层
回复【24楼】denglu
-----------------------------------------------------------------------

中国的SEGWAY~  
good!

出0入0汤圆

发表于 2010-4-18 22:55:48 | 显示全部楼层
我以前做的 用C8051和ENC-03角速度 没有用加速度芯片
http://v.youku.com/v_show/id_XMTAyOTMyNzM2.html
http://v.youku.com/v_show/id_XMTAwOTA1NTU2.html

出0入0汤圆

发表于 2010-4-18 23:47:17 | 显示全部楼层
回复【11楼】DDAI
回复【5楼】zq186  
-----------------------------------------------------------------------
我也想做一个,不过想做个大的,搜集资料中,楼主能不能把主要思路和大概的流程说说?  
实质是对角度进行PID控制.
首先手动让小车站立,当松手后小车不倒(有点难哦)。此时,小车所在的竖直面为参考面。然后实时计算小车与参考面的夹角,最后PID即可。
至于如何PID,有如下思路可供参考。
先调P(只有P),当小车差不多可以前后等幅震荡时,P就算调好了;
接下来,把P值减半,加入D。D取到合适值时,小车基本可以稳定站立;
最后加入I,以提高小车反应的快速性。
难点是获得这个夹角。也就是陀螺仪和加速度计的融合,这方面可参考
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_......
-----------------------------------------------------------------------

今天才看到楼主回复过了,不好意思哈~~
我计划用水平传感器,已经买了adis16201,再配合一个陀螺仪,初步定enc03
难点在于我不是学这行的,现在在搭无刷电机的驱动板,搭了两个月还没成型,郁闷。。。
心里很多想法没办法付诸实现。。。
今天终于把双面板做好了,调出了15V的电路,算是个小成功吧~

出0入0汤圆

发表于 2010-4-18 23:51:35 | 显示全部楼层
回复【23楼】yangyh75
-----------------------------------------------------------------------

我也买了这种电动车电机,无刷无齿,不知道你试的时候电流有多大?电池用的多少V?
还有一种无刷有齿的电机,我想扭力应该很大,我有个朋友装在电动车上,配合48V磷酸铁锂电池,带个人上陡坡都没问题,可惜那电机不能反转,里面有个自动离合器。
如果无齿的电机不行的话,我到时候看看能不能把这种带减速的改成能反转的。

还有个想法,把打印机里那种编码器想办法装到电机里,把电机改成伺服,那样会好控制些吧?

出0入0汤圆

发表于 2010-4-19 09:45:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-19 09:45:25 | 显示全部楼层
看来这方面研究的还不少,无刷有齿的电机启动特性要好点,但需要自己改装,打开后将超越离合器给失效了。我是打算这样做的,前几天买了两个无刷有齿电机,可惜到多货时被物流给摔坏了,现在在退货途中,郁闷。无刷有齿电机很难找,大家给推荐推荐。

出0入0汤圆

发表于 2010-4-19 10:35:33 | 显示全部楼层
这个强。

出0入0汤圆

发表于 2010-4-19 21:46:36 | 显示全部楼层
无刷有齿电机还是很多的,

那种俗称爬山王的就是,不过价格较贵而已,
不过和一般电动车盘式电机不同,那个定子是外壳,因此恐怕你的机架结构也要做相应的修改了

另外一种盘式的是采用行星齿轮的,估计你买的就是那种,带离合器的


我觉得你的轮子迟滞的原因可能是驱动力矩不够大,估计你是不是限流限的比较小

出0入0汤圆

发表于 2010-4-19 21:51:45 | 显示全部楼层
回复【30楼】yangyh75
看来这方面研究的还不少,无刷有齿的电机启动特性要好点,但需要自己改装,打开后将超越离合器给失效了。我是打算这样做的,前几天买了两个无刷有齿电机,可惜到多货时被物流给摔坏了,现在在退货途中,郁闷。无刷有齿电机很难找,大家给推荐推荐。
-----------------------------------------------------------------------

推荐去八方电机买,不过他们是电话联系,厂家直接发货,要转账过去,没淘宝那么方便。电机做工很好,不知道有没有一体轮毂的品种,我朋友买的都是要自己编圈的。20寸的圈还能编一下,16寸的估计自己是没办法编了。

出0入0汤圆

 楼主| 发表于 2010-4-19 22:33:47 | 显示全部楼层
回复【27楼】zq186 难得好天气
-----------------------------------------------------------------------

恭喜、恭喜~

我有个无刷驱动的资料,感觉写的很不错,希望能对你有没有帮助~
点击此处下载 ourdev_547526.pdf(文件大小:3.33M) (原文件名:无刷马达驱动设计与实现.pdf)

出0入0汤圆

 楼主| 发表于 2010-4-19 22:37:52 | 显示全部楼层
回复【26楼】xiazhengwu
我以前做的 用C8051和ENC-03角速度 没有用加速度芯片
http://v.youku.com/v_show/id_XMTAyOTMyNzM2.html
http://v.youku.com/v_show/id_XMTAwOTA1NTU2.html
-----------------------------------------------------------------------

很不错~
说实话,我以前只用ENC-03做过,但效果就差多了~

出0入0汤圆

发表于 2010-4-19 22:42:12 | 显示全部楼层
回复【34楼】DDAI
回复【27楼】zq186 难得好天气
-----------------------------------------------------------------------
恭喜、恭喜~
我有个无刷驱动的资料,感觉写的很不错,希望能对你有没有帮助~
点击此处下载  (原文件名:无刷马达驱动设计与实现.pdf)
-----------------------------------------------------------------------

谢过谢过,下来看看。。。不过服务器好像有问题呢。。。

出0入0汤圆

发表于 2010-4-19 23:09:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-20 15:49:37 | 显示全部楼层
mark  都太牛x了

出0入0汤圆

发表于 2010-4-24 21:06:46 | 显示全部楼层
COOL!希望楼主把程序分享一下来供大家学习 谢谢

出0入0汤圆

发表于 2010-4-24 23:24:10 | 显示全部楼层
mark@!

出0入0汤圆

 楼主| 发表于 2010-4-26 22:52:29 | 显示全部楼层
回复【39楼】06023116
-----------------------------------------------------------------------

COOL!希望楼主把程序分享一下来供大家学习 谢谢


可以~
现在在外地打工,每天工作十多个小时~
等有时间整理下贴上~一到两个星期吧~

望耐心等下~

出0入0汤圆

发表于 2010-4-26 23:26:03 | 显示全部楼层
再次感谢大方的楼主 THANKS
另外注意劳逸结合 呵呵 身体才是最重要的

出0入0汤圆

 楼主| 发表于 2010-5-2 19:33:08 | 显示全部楼层
一、传感器融合


(原文件名:传感器融合.jpg)

1、图中实线部分为实时计算获取倾角值,虚线部分是计算陀螺仪偏差。s1、s2每0.5s闭合一次
2、‘放大’‘缩小’其目的是化成同一个数量级。每获取一度倾角,陀螺仪积分值约为1000,加速度计变化10/9左右。
   二者相差约900倍。
3、另有温漂消除部分。思路是计算陀螺仪原始值及输出倾角在0.5s内的平均值,做差,据此来修正陀螺仪中值

二、主程序流程
1、等待2ms定时结束(自平衡控制周期为2ms)
2、获取最新传感器数据
3、传感器融合
4、PID
5、更新马达值

源程序:

/*
  * Self-balancing Ctrl
  *
  * By DDAI
  * 2010.03.21
  */  

    #include "system.h"                               //FPGA NIOS II 软核头文件
    #include "sys/alt_irq.h"
    #include "sys/alt_dev.h"
    #include "alt_types.h"
    #include "altera_avalon_pio_regs.h"
    #include "altera_avalon_timer_regs.h"
    #include "altera_avalon_timer.h"
    #include "stdio.h"

    alt_u8 data_acc;   //read from ad
    alt_u8 data_gyr;

    alt_u8 middle_gyr;

    /*Roll*/   
    alt_8     Reading_GyrRoll;
    alt_8     Reading_AccRoll;
    alt_16     Mean_AccRoll=512*12;

    alt_32     Reading_IntegralGyrRoll;            //Get degree
    alt_32     Reading_IntegralGyrRoll_2;

    alt_32     IntegralGyrRoll;
    alt_32     IntegralGyrRoll_2;

    alt_32     IntegralAccRoll;
    alt_32     Mean_IntegralGyrRoll;
  
    alt_32     IntegralDegreeRoll;
    alt_32     IntegralErrorRoll;
   
    alt_16     AuttitudecorrectionRoll = 0;   
    alt_32     Correction_Roll;

    static int balance_number;
    int timer_periodh,timer_periodl;
    int balance_ctrl = 1;
    int run = 0;

    float Amplify = 12;
    float Programset_GyrAcc = 32;

     #define MIDDLE_ACC 129
     #define P 1500
     #define I 10
     #define D 500

     void init(){                                        //初始化  获取陀螺仪初值
        int cnt=0;
        alt_u16 init_gyr=0;
        
        while(cnt<100){
            data_gyr=IORD_16DIRECT(TLC549_IC_BASE+2*1,0);
            init_gyr+=data_gyr;
            cnt++;
        }
        middle_gyr = init_gyr/100;   
     }
     
     void gui(){                                             //在nios2-terminal中输出倾角值
            static int gui_cnt=0;                            //便于JAVA GUI 调用显示
                        
            gui_cnt++;
            if(gui_cnt>500){
                printf("%d\n",IntegralGyrRoll/255);
                gui_cnt=0;
            }
        }
        
     static void Interrupt_timer(void *context,alt_u32 id){    //定时器中断     
        balance_ctrl = 1;
        IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE,0);
     }

     void Init_timer(){                                        //定时器初始化   
    alt_irq_register(TIMER_IRQ,NULL,Interrupt_timer);   
    IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_BASE,timer_periodh);
    IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_BASE,timer_periodl);
    IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE,0x07);
    }

     int main(void){   
        alt_u8 data_acc_old;            //low-pass fliter
        alt_u8 data_gyr_old;            //滤波器没有用到
        int integral;
        int degree,v;
        int err2,err_old;        
        
        init();
        timer_periodh = 1;                //2ms 定时
        timer_periodl = 0x86A0;
        Init_timer();
        
        for(;;){                          //主循环
        while(balance_ctrl){
            balance_ctrl = 0;
            data_acc=IORD_16DIRECT(TLC549_IC_BASE,0);         //由IP核读取传感器值
            data_gyr=IORD_16DIRECT(TLC549_IC_BASE+2*1,0);     
            
            /*LOW PASS FLITER*/
            /*
            data_acc = data_acc*71/100 + data_acc_old*29/100;
            data_gyr = data_gyr*71/100 + data_gyr_old*29/100;
            data_acc_old = data_acc;
            data_gyr_old = data_gyr;
            */
            
            /*Get sensors' value which has substricted by Middle value*/
            Reading_AccRoll = data_acc-MIDDLE_ACC;
            Reading_GyrRoll = data_gyr-middle_gyr;
            
            gui();            
            
            /*                  Renew data                            */
                                             
            Mean_AccRoll = (Mean_AccRoll + Amplify*Reading_AccRoll)/2;
            IntegralAccRoll += Reading_AccRoll*Amplify;    //Be used for long-time control
               
            Reading_IntegralGyrRoll += (Reading_GyrRoll-AuttitudecorrectionRoll); //Real-time control              
            Reading_IntegralGyrRoll_2 += Reading_GyrRoll;  //Original data integral
               
            IntegralGyrRoll = Reading_IntegralGyrRoll;     //Output tilt-Roll
            IntegralGyrRoll_2 = Reading_IntegralGyrRoll_2;
                  
            Mean_IntegralGyrRoll += IntegralGyrRoll;       //Long-time control
            
            
            
            /*********************************************************************/
            /*                      Real-time control                            */
            /*********************************************************************/
                    
            Correction_Roll = ((IntegralGyrRoll/Programset_GyrAcc) - Mean_AccRoll); //Error signal
                    
            Correction_Roll /= 2;         
                     
            #define MaxCorrection 64
            if(Correction_Roll >= MaxCorrection)    Correction_Roll = MaxCorrection;
            else if(Correction_Roll <= -MaxCorrection)    Correction_Roll = -MaxCorrection;
            
            Reading_IntegralGyrRoll -= Correction_Roll;
                    
            /*********************************************************************/
            /*                      Long-time control                           */
            /*********************************************************************/
                    
            #define BAL_NUM 250
        
            balance_number++;
                    
            if(balance_number >= BAL_NUM)            //0.5s
            {
                alt_16 long_correct;
               
                Mean_IntegralGyrRoll /= BAL_NUM;                    
                IntegralAccRoll /= BAL_NUM;
               
                long_correct = (Mean_IntegralGyrRoll - IntegralAccRoll);                    
                AuttitudecorrectionRoll = (long_correct/BAL_NUM);
               
                IntegralAccRoll = 0;                        
                //printf("AuttitudecorrectionRoll %d  ",AuttitudecorrectionRoll);        //调试时使用
                //printf("AuttitudecorrectionNick %d  \n",AuttitudecorrectionNick);
                        
                /*********************************************************************/
                /*                   修正陀螺仪温漂                                  */
                /*********************************************************************/
                                       
                IntegralErrorRoll = IntegralGyrRoll_2 - IntegralGyrRoll;
                        
                Reading_IntegralGyrRoll_2 -= IntegralErrorRoll;
                                             
                if(IntegralErrorRoll >= 4*balance_number) middle_gyr += 1;
                if(IntegralErrorRoll <= -4*balance_number) middle_gyr -= 1;
                       
                balance_number = 0;                                   
            }                  
            
            /*----------------------------------------------
             *             PID            
             * -------------------------------------------*/
           
            degree = IntegralGyrRoll/255;                              //缩小倾角值,与马达匹配

            err2=degree-err_old;
            err_old=degree;
            integral+=degree;
            if(integral<-4999) integral=-4999;                         //溢出处理
            if(integral>4999) integral=4999;
            
            v=P*degree+D*err2+I*integral;                  
            
            if(v>0){
                if(v>4999) v=4999;
            }
            else{
                v=5000-v;
                if(v>9999) v=9999;
            }
                                    
            IOWR_16DIRECT(MOTOR_CTRL_0_BASE,0,v);                  //更新马达值
            IOWR_16DIRECT(MOTOR_CTRL_1_BASE,0,v);                  //v取0~4999 马达正转  5000~9999 马达反转
            
                        
        }
        }      
           
     }

/*end*/

出0入0汤圆

发表于 2010-5-2 19:59:08 | 显示全部楼层
哇塞都是高人啊

小弟也有再搞

~~~~

很简单的那种

只图能站住

才疏学浅

LPC2148+MMA7260,测量倾角的工作已经搞定

硬件也做完了

奈何是摄像机里调焦距的电机

力足而速不行也~~~~

未果~~~,寻车轮与电机中~~~

出0入0汤圆

发表于 2010-5-3 21:27:14 | 显示全部楼层
没想到楼主这么快就发上来了 还以为要好几天 呵呵

好好学习下

出0入0汤圆

 楼主| 发表于 2010-5-3 22:19:24 | 显示全部楼层
回复【45楼】06023116
-----------------------------------------------------------------------

没想到楼主这么快就发上来了 还以为要好几天 呵呵

好好学习下


程序写的很简单
不过,确实管用~呵呵

出0入0汤圆

发表于 2010-5-4 13:48:41 | 显示全部楼层
回复【46楼】DDAI  
-----------------------------------------------------------------------
程序写的很简单
不过,确实管用~呵呵
-----------------------------------------------------------------------

看了一上午 没看太懂 好些变量没有弄清楚

果然是简约而不简单 更加佩服楼主了

下午抽时间继续看

出0入0汤圆

发表于 2010-5-4 13:54:54 | 显示全部楼层
非常感谢楼主提供的程序,我最近也在做自衡车,昨晚学习了楼主的程序。
想尝试楼主的程序,结果只能维持片刻。

我想知道楼主如何确定陀螺仪和加速度传感器的数值是如何选定耦合参数的。

发现楼主程序中Correction_Roll /= 2; 而德国程序中的衰减更大。

我不知道如何确定衰减的数值。

又比如AuttitudecorrectionRoll = (long_correct/BAL_NUM);

现在,我的车子只能短暂时间的摆动,就倒下了不知道是怎么回事,PID参数已经试过很多了。

我不知道是不是的滤波器的事~

出0入0汤圆

发表于 2010-5-4 14:14:25 | 显示全部楼层
这个要mark

出0入0汤圆

发表于 2010-5-4 14:19:47 | 显示全部楼层
mark,可惜一直没有时间去做。

出0入0汤圆

 楼主| 发表于 2010-5-4 21:54:26 | 显示全部楼层
回复【48楼】tensuns
-----------------------------------------------------------------------
我想知道楼主如何确定陀螺仪和加速度传感器的数值是如何选定耦合参数的。
-----------------------------------------------------------------------

思路是这样的:
陀螺仪和加速度计都在实时计算着小车的倾角,
且在处理器内倾角是用一个与它成一定比例的数值表示的。
算出同一个倾角时,陀螺仪与加速度计得到的数值各是多少,
它们的关系自然就知道了~

假设某时刻小车倾斜1度,由陀螺仪得到的角度值可以这样算:

1、enc-03  scale factor 0.67mv/deg/sec
   (以每秒一度的角速度转动,陀螺仪输出电压变化是0.67mv)

2、假设对陀螺仪信号放大100倍
   AD是8位精度,参考电压3v,那么分辨率 = 3000/256
                                     = 11.7mv
3、假设小车以 1deg/sec 的速度转动,1秒后,倾角为1度
   控制周期为2ms,即1s对角速度积分500次。

   有        角度值 = 0.67*100/11.7 * 500
               = 2863

同样,加速度计倾斜1度时,可参考其datasheet 得输出电压变化值,
AD转换后,得角度值。


上述仅为理论计算,使用时,数值上必然会有些波动。
如43楼源程序
    float Amplify = 12;
    float Programset_GyrAcc = 32;

上两个参数的乘积12*32=384 即为陀螺仪比加速度计的倍数
另外,不用陀螺仪/384或着加速度计*384 来比较二者的偏差,有两个好处:
     减小陀螺仪误差,同时提高倾斜角的分辨率。

增加Amplify可提升加速度计对平衡控制的影响,反之陀螺仪作用提升


其它问题,可参考
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3348262&bbs_page_no=1&bbs_id=1025

出0入0汤圆

发表于 2010-5-4 22:49:43 | 显示全部楼层
在 Long-time control 中用 IntegralGyrRoll 的累加(Mean_IntegralGyrRoll )

减去 Reading_AccRoll*Amplify 的累加(IntegralAccRoll),

而在 Real-time control 中却用 IntegralGyrRoll/Programset_GyrAcc

减去 Mean_AccRoll 去修正陀螺仪积分,

为什么又引入了一个 Mean_AccRoll ,而不直接用 Reading_AccRoll*Amplify ,Mean_AccRoll 是什么意思?

另外degree = IntegralGyrRoll/255作为PID的输入,而IntegralGyrRoll貌似是当前未修正的陀螺仪积分(修正后的是放在了

Reading_IntegralGyrRoll里面),这个怎么理解?

出0入0汤圆

发表于 2010-5-5 16:23:48 | 显示全部楼层
回复【51楼】DDAI
-----------------------------------------------------------------------

非常感谢楼主,热心的指导。

二轮自衡车终于晃晃悠悠地调出来了~\(≧▽≦)/~~

但我发现一个问题就是:
           PWM方波的占空比与直流的电机的转速是非线性关系的:

在低占空比下,电机不会转动。当占空比高时,占空比的一点调整就会使电机的转速变化很大。

不知道lz是否遇到这个问题?

出0入0汤圆

发表于 2010-5-5 20:55:20 | 显示全部楼层
做得真好,如今只有膜拜。

用现在流行的stm32能够处理得过来吗?

出0入0汤圆

 楼主| 发表于 2010-5-9 09:00:14 | 显示全部楼层
回复【52楼】06023116
-----------------------------------------------------------------------

1、

/*                  Renew data                         */  
                                               
Mean_AccRoll = (Mean_AccRoll + Amplify*Reading_AccRoll)/2;

Mean_AccRoll是周期为2的移动均值

2、使用IntegralGyrRoll,而不用Reading_IntegralGyrRoll,这个问题我也说不清楚~~~~~

出0入0汤圆

 楼主| 发表于 2010-5-9 09:03:07 | 显示全部楼层
回复【53楼】tensuns
-----------------------------------------------------------------------

有这个问题~

我的马达,PWM占空比到50%时,才会转~

可能与pwm的频率有关,频率越高,功率越小~~~

出0入0汤圆

发表于 2010-5-11 18:26:20 | 显示全部楼层
呵呵 感谢楼主热心的指导

不过还有些问题没弄清楚 应该是靠自己亲自动手才能体会的到

出0入0汤圆

发表于 2010-5-11 20:17:21 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-24 17:49:55 | 显示全部楼层
厉害!!PF

出0入0汤圆

发表于 2010-7-3 18:53:02 | 显示全部楼层
回复【18楼】DDAI
-----------------------------------------------------------------------

厉害!把你的资料和友友分享一下下哈!!1

出0入0汤圆

发表于 2010-7-3 18:56:41 | 显示全部楼层
回复【26楼】xiazhengwu
-----------------------------------------------------------------------
高手,请指教375870540

出0入0汤圆

发表于 2010-7-3 19:01:06 | 显示全部楼层
回复【25楼】DDAI
-----------------------------------------------------------------------回复【34楼】DDAI
-----------------------------------------------------------------------

请问下,用了哪一些传感器,先谢啦

出0入0汤圆

发表于 2010-7-4 21:58:19 | 显示全部楼层
支持,自己也在努力,还未站稳,电机更换了,再试验中,支持楼主。。。

出0入0汤圆

发表于 2010-7-15 22:57:32 | 显示全部楼层
回复【25楼】DDAI
-----------------------------------------------------------------------
我想问下是怎么做到 的,好想很复杂!

出0入0汤圆

发表于 2010-7-15 23:03:20 | 显示全部楼层
回复【43楼】DDAI
-----------------------------------------------------------------------

我现在每天都来光顾下有什么最新发展,我都研究了一年了,还是没有搞懂,嗨,太难了

出0入0汤圆

发表于 2010-7-15 23:04:24 | 显示全部楼层
回复【43楼】DDAI
-----------------------------------------------------------------------

希望能相互交流一下 QQ 375870540

出0入0汤圆

发表于 2010-7-15 23:08:46 | 显示全部楼层
回复【63楼】lin1936
-----------------------------------------------------------------------

想大家学习中

出0入0汤圆

发表于 2010-8-24 14:25:47 | 显示全部楼层
楼主请教一个问题,你的软件中有如下代码:
data_acc=IORD_16DIRECT(TLC549_IC_BASE,0);         //由IP核读取传感器值
data_gyr=IORD_16DIRECT(TLC549_IC_BASE+2*1,0);  

请问data_acc和data_gyr是计算出来通过ADXL330、ENC-03计算出来的角度值吗?(弧度)?还是带有系数的一个采样值?


谢谢!!谢谢!!

出0入0汤圆

发表于 2010-8-25 19:08:52 | 显示全部楼层
MS那个小尾巴要去掉就好了

出0入0汤圆

 楼主| 发表于 2010-8-26 16:03:08 | 显示全部楼层
回复【69楼】redwolf010
-----------------------------------------------------------------------

只是从AD转换器中读到的采样值,无任何处理。

陀螺仪  供电电压3.3v,放大后,中值1.6v.AD 12位
加速度计  输出直接接AD输入端,同样是12位

出0入0汤圆

 楼主| 发表于 2010-8-26 16:29:35 | 显示全部楼层
回复【62楼】lin1936
-----------------------------------------------------------------------

回复【65楼】lin1936
-----------------------------------------------------------------------

回复【66楼】lin1936
-----------------------------------------------------------------------
回复【67楼】lin1936
-----------------------------------------------------------------------

1、有什么疑问,请在各楼层转转,相信能找到答案~

2、这辆小车是为毕业答辩做的,做的过程十分辛苦,自不必说。然答辩时,不尽人意(非小车性能不好)。
   现在工作啦,做航模+玩具,用各种单片机,非FPGA。以前的事,不想再提。

3、26楼,提到只用陀螺仪也可以达到不错的效果。刚开始,并不是十分相信,现在做了两个月的航模,相信26楼。

4、还在努力为小车奋斗的朋友们,希望能多做些尝试,然后,留些时间认真思考。功夫到了,自然成功。

出0入0汤圆

发表于 2010-8-27 13:37:15 | 显示全部楼层
楼主的PID参数调节是手动在程序中改的吗?

出0入0汤圆

 楼主| 发表于 2010-8-27 16:49:01 | 显示全部楼层

出0入0汤圆

发表于 2010-8-27 18:03:23 | 显示全部楼层
MARK!!

出0入0汤圆

发表于 2010-9-23 19:11:54 | 显示全部楼层
回复【24楼】denglu
-----------------------------------------------------------------------
是否有主板出售?请复237907109@qq.com

出0入0汤圆

发表于 2010-9-27 22:49:16 | 显示全部楼层
不错。。。23楼的这电动车轮哪有卖的呀

出0入0汤圆

发表于 2010-9-28 08:34:31 | 显示全部楼层
今天看到新闻,segway的老板开自己的segway摔死了……杯具啊!

出0入0汤圆

发表于 2010-10-14 11:41:28 | 显示全部楼层
回复【23楼】yangyh75
-----------------------------------------------------------------------

回复【23楼】yangyh75
点击此处下载  (原文件名:7409_pcb.pdf)  


(原文件名:dsc00788.jpg)
引用图片


(原文件名:dsc00783.jpg)
<center><a class=tt16 onclick="fnquickimagequote(this,'files_28/ourdev_54......
-----------------------------------------------------------------------
请问一下车轮的这种悬臂梁安装结构强度够吗?

出0入0汤圆

发表于 2010-10-17 00:42:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-18 17:35:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-18 19:39:05 | 显示全部楼层
这是我做的,过段时间推出散件套件。供大家试验联系15057919777
http://u.youku.com/user_show/id_UNDU5OTk3NjA=.html
http://v.youku.com/v_show/id_XMjA0NjUxODk2.html

出0入0汤圆

发表于 2010-10-19 12:00:07 | 显示全部楼层
这东西 做成遥控的 可以 前进后退 左转弯 右转弯  这样就 好玩了

出0入0汤圆

发表于 2010-10-25 13:15:35 | 显示全部楼层
lz的点击还有轮子我看了很面熟,应该是淘宝上买的吧。
我只做过四轮的车子,两轮的还没弄过,不过很很有兴趣。
在此我有个问题,能不能换一个思路来控制车的平衡从而解放两个轮子,使小车能自由行动。
至于怎么控制小车的平衡,可以采用pid来控制小车的重心。具体的方法目前还没想到。

出0入0汤圆

发表于 2010-10-28 10:41:27 | 显示全部楼层
引用图片【43楼】DDAI  
-----------------------------------------------------------------------

(原文件名:传感器融合.jpg)

出0入0汤圆

发表于 2010-10-31 13:29:59 | 显示全部楼层
楼主你好,我是初学者,也想做一辆这种小车玩玩,元器件打算上网买来,回家后自己再慢慢琢磨、研究,目前我还不清楚需要哪些元器件。楼主能否列一份详尽的清单给我,我去淘宝上买回来?!
谢谢~~~!

出0入0汤圆

发表于 2010-11-11 22:50:46 | 显示全部楼层
回复【26楼】xiazhengwu
-----------------------------------------------------------------------

我也想用51单片机做,我想请问你是用的什么算法

出0入0汤圆

发表于 2010-11-12 16:22:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-18 12:52:02 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-12-20 11:46:20 | 显示全部楼层
记号!

出0入0汤圆

发表于 2010-12-20 16:39:52 | 显示全部楼层
牛   另人汗
头像被屏蔽

出0入0汤圆

发表于 2011-4-5 03:25:11 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2011-4-5 09:39:20 | 显示全部楼层
先赞一个,本科生能有这样的动手能力真的不错。不过还是建议:
1.先对器件进行足够的标定:
2.不要动不动就KALMAN,虽然是线性组合,但是会对方差估计不足;
3.可以采用加速度传感器的对称布置,这样可以去除杆臂效应;
4,如果真想做专业级的,一个MODEL1221,SCC1300是必须的。

对于控制,我不懂,就不敢乱说了。

出0入0汤圆

发表于 2011-4-13 09:49:09 | 显示全部楼层
很简洁

出0入0汤圆

发表于 2011-4-13 10:10:40 | 显示全部楼层
记号!!!

出0入0汤圆

发表于 2011-5-6 18:26:00 | 显示全部楼层
谁可以把代码中的变量用中文注释一下?不然那些变量的用意真让人很难搞清楚呀!头疼!!要是我看会了,我一定上传!

出0入0汤圆

发表于 2011-5-6 20:19:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-6 21:10:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-7 21:25:30 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-5-16 21:03:41 | 显示全部楼层
请问,当车子平衡时总向一个方向平移是怎么回事?还有车子的鲁棒性不够,轻轻一碰就保持不了平衡,应该怎么解决?希望朋友们不吝相告!万分感谢!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-7-23 17:30

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

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