作者:

DIY 自平衡自行车

在本文将会介绍平衡自行车的具体制作过程,包括机械、电路和代码。
平衡自行车完整的代码托管在 https://github.com/nicekwell/balance_bike

balance_bile.jpg

一、材料

机械

名称 数量 备注
铜柱、铁丝、胶枪等基础材料和工具
自行车架 1 自己做车架是很麻烦的,我是直接买的车架,淘宝上搜”自行车 拼装 DIY”能搜到很多
舵机 1 转向用的,对于我用的1:6车架,普通舵机有点大,我用的是9g舵机
N20电机 1 选扭力大一点,这样转速会比较稳定
皮带轮和皮带 如上面的图片,我是用皮带来传输动力的

电路

名称 数量 备注
电池、电池盒
洞洞板
lm1117-3.3 降压芯片给控制系统供电
stm32f103c8t6核心板 1
gy521模块 1 加速度传感器 + 陀螺仪
升压模块 1 升到12v给电机供电,根据电机特性选择是否使用升压模块
8050三极管 2 驱动电机,由于自行车不需要反转,所以不需要使用电机驱动芯片,用三极管就能方便地实现。我用了两个三极管并联提高功率。
自锁开关 1 整个系统开关
led指示灯 1 配合1k限流电阻
蓝牙模块 1 可选,如果想要遥控的话就使用蓝牙

二、动力部分

传动方式

如图,我用的是皮带传送的方式,因为比较好实现。

1.jpg

电机选择

这个DIY是不考虑变速情况的,平衡的参数都是按照一个固定速度调的。
所以动力部分的作用就是提供一个恒定的速度,并且这个速度尽可能稳定,尽可能不受外部影响。
电机应选择扭力大一些、转速稳定的减速电机。

电机供电

电机是直接供电还是使用升压模块供电要根据电机特性,有些电机用升压模块可以提高功率,有些大电流电机用升压模块反而可能限制了电流。

我这里用升压模块升到12v给N20电机供电的。

2.jpg

另外,电机通过三极管受stm32控制,通过控制占空比也可以限制电机输出的功率。

三、转向部分

转向部分用一个舵机带动把手转动即可。

3.jpg

四、电路

在github工程里有详细的引脚连接表 https://github.com/nicekwell/balance_bike

供电

用3.3v稳压芯片给整个控制系统供电,包括单片机、GY521模块、蓝牙模块。
用5v稳压芯片给舵机供电。
用12v升压模块给电机供电。

下载

我是用串口给stm32下载程序的。

引脚 功能 备注
PA9 下载TXD
PA10 下载RXD

GY521

这个模块通过i2c通信,只需要连接4根线。

引脚 功能 备注
3.3v
GND
PB0 GY521 I2C SCL
PB1 GY521 I2C SDA 用的是IO模拟i2c

电机

点击用12v升压模块供电,由于不需要反转,用三极管即可直接驱动,电路图如下:

4.jpg

加三极管的目的是为了可以通过调节PWM占空比来限制输出功率,但我的实际情况是100%输出时动力才勉强足够。所以如果你不需要限制电机输出功率,或者通过其他方式限制输出功率,也可以不要三极管,不通过单片机控制。

舵机

舵机是用5v供电的,而单片机是3.3v电平,对于pwm控制脚可以通过2个三极管实现同相的电平转换:

5.jpg

蓝牙模块

下图是我使用的蓝牙串口模块,可以实现串口透传,只需要4根线连接:vcc、gnd、txd、rxd。

6.jpg

蓝牙模块是用来调试和遥控的,没有它也能跑。建议还是加上这个模块,在调试PID擦数时会非常方便。
关于调试方面的内容可以参考我写的另一片文章:谈一谈单片机开发的几种调试方案

五、代码结构

代码提交在github https://github.com/nicekwell/balance_bike

主要分为3个部分:1、基础的驱动程序,实现电机、舵机、gy521数据读取;2、平衡控制系统,核心是一个20ms定时器,每20ms进行一次数据采集、计算和响应;3、遥控和调试系统,实现log输出、接收遥控信息。

驱动

名称 文件 功能
i2c i2c/i2c.c, include/i2c.h IO 模拟i2c驱动,提供i2c基础操作
gy521 gy521/gy521.c, include/gy521.h gy521模块驱动,基于i2c驱动,提供加速度和角速度的读取接口
motor motor/motor.c, include/motor.h 电机驱动,提供占空比控制接口
angle angle/angle.c, include/angle.h 舵机驱动,提供角度控制接口

平衡控制

main函数会初始化一个定时器20ms中断一次,调用 main/balance.c 里的 balance_tick 函数,平衡算法在 main/balance.c 实现。

每20ms到来会执行一次:

  1. 读取传感器加速度和角速度信息。
  2. 互补平衡滤波计算当前姿态。
  3. 用PID算法计算出前轮转角。

遥控和调试

两部分:状态输出和指令接收。

状态输出
在main函数的while循环里,利用串口中断构建一个简单的界面显示状态。

指令接收
串口接收到的数据会传给main/control.c,该文件分析串口数据,解释成相应的操作。主要是PID参数调节。

 

这是平衡自行车三篇教程中的第二篇,这一篇对平衡自行车的算法进行理论分析,包括模型分析、姿态检测方法、PID算法,控制算法。

一、模型分析

1、倒立摆

很显然我们知道自行车在左右方向上不稳定,这是一个很常见的物理模型——倒立摆。

1.jpg

顾名思义,倒立摆的意思就是倒着的摆,比如一个倒着的杆,

2.jpg

倒立摆的特性:不稳定,只要偏离平衡位置,就会有一个力(重力的分力)使系统更加偏离平衡位置,这样偏差就会越来越大。

一般倒立的杆在前后左右方向都有可能倒下,在二维的平面上不稳定;而自行车仅在左右方向上可能倒下,是一维的倒立摆,这要简单一些。

以下是几个生活中常见的倒立摆例子:

3.jpg

4.jpg

5.jpg

2、自行车的平衡控制

自行车属于倒立摆模型,倒立摆是不稳定的,那么倒立摆应该如何控制才能平衡呢?

我们把问题拆分一下:

  1. 怎样的状态才叫平衡?
  2. 我们能控制的是什么?
  3. 如何控制才能稳定平衡?

2.1 怎样的状态才叫平衡

我们要对”平衡”进行数学描述,所谓的平衡其实就是倒立摆的倾角稳定在一个我们想要的值。

2.jpg

通常我们想要平衡在θ = 0处。

2.2 我们能控制的是什么

对于倒立摆模型,通常我们能控制的是底端的 力 或 速度 或 位置,不同的控制量对应的控制方法不同。

对于自行车来说,它的控制方式不像通常的倒立摆那样直接控制底部,而是间接地通过转向来控制,当自行车以一个固定的速度前进时,自行车把手以一定角度进行转向(设为α),自行车会做相应半径的圆周运动,产生相应大小的”离心力”。

在自行车这个费惯性系里看来,只要对把手进行一定角度的转向(α),就会产生一个相应大小的横向力:

6.jpg

这就是我们进行平衡控制时的实际控制量——把手转角α,只要控制它就能控制回复力。

2.3 如何控制才能平衡

上面我们已经能够通过转向产生回复力,这个回复力可以把倒立摆”掰回”平衡位置,有往回掰的回复力就能稳定平衡了吗?
并不是这样,我们再来回顾一下中学物理:
过阻尼状态的摆会以较慢的速度回到平衡位置;
欠阻尼状态的摆会很快回到平衡位置,但会在平衡位置来回摆动;
临界阻尼状态的摆会以最快的速度稳定在平衡位置。

结合到实际的自行车平衡中就是:
如果回复力不够大,就无法矫正,或者矫正速度很慢,这会导致系统不稳定;
如果回复力过大,就会导致矫正过度,这也会导致系统不稳定; 我们最希望的状态就是回复力刚刚好,刚好使倒立摆快速回到平衡位置,又不至于矫正过度。

这是一个复杂的数学计算过程,回复力大小会在系统运行时不断地计算(本平衡自行车是20ms计算一次),用到的是PID算法,会在后面详细介绍。

3、自行车平衡需要解决的基本问题

  1. 获取左右方向倾角θ
  2. 以合适的算法控制转角α使系统稳定平衡

这将会在下面详细讨论。

二、姿态检测

1、检测的是什么

检测的是自行车左右倾斜的角度。

2、怎么检测

用一个叫gy521的模块,里面用的是mpu6050芯片,带有陀螺仪和加速度传感器。 gy521的具体使用会在第三篇-实践篇介绍,这里我们知道通过这个模块我们可以得到自行车各个方向的加速度和角速度。 注意哦,我们不能直接得到倾斜角度,我们的到的是各个方向的加速度和角速度,需要进行一些复杂的计算才能得到正确的倾斜角度。

常用的算法有互补平衡滤波、卡尔曼滤波,由于篇幅和精力问题这部分暂不介绍,网上有大量资源,也可以查看本工程源码,以后有时间再写详细教程。

三、PID算法

前面已经分析了,我们通过控制把手转角来控制回复力,我们需要实时计算一个合适的回复力使系统稳定平衡。

这部分内容也不做详细介绍了,网上有大量资源,也可以查看本工程源码。

在这里引用动力老男孩举的一个例子,帮大家简单理解一下需要解决的问题,以及PID算法是如何解决的。

7.jpg

有一个小球在光滑球面上,小球的位置是x,光滑球面顶端在L处,我们可以控制小球水平方向力F,现在要求让小球稳定平衡在x0处。

先看简单情况 x0=L,此时偏差为 L-x,

我们给出一个比例项(P) F = kp*(L-x),这样就会有一个回复力,当偏差存在时就会有一个力把小球拉回L处。
这存在的问题是,小球接近L时是会有一定速度的,小球越来越接近L,此时的力仍然是在把小球往L处拉,这会导致小球到达L时(我们想要的位置)速度很大,小球无法立刻停下来,而是会冲过去。
这样小球就会在L附近来回摆动,这是不稳定的状态,属于欠阻尼状态。

为了解决上述问题需要加一个微分项(D) F = kd*dx/dt = kd*v,所谓”微分”指的是位置x对时间的微分,说白了就是速度。
意思就是当速度越大,就产生一个反向的力使速度减小,这样就可以防止出现上面小球冲过去的。
可以认为这一项具有”预测”功能,预测小球下一时刻的状态从而提前做出反应(预测小球将要到达L处,提前减速),
也可以认为这一项具有阻尼作用,相当于系统中有一个和速度成比例的阻尼力。
这个”阻尼力”调得过小会导致欠阻尼状态,调得过大会导致过阻尼状态。

积分项此时可以不用,积分项是当平衡位置x0不等于L时使用的,
当平衡位置不是L处,那么当小球静止在平衡位置x0时,由于在坡道上会有一个恒定的横向偏移力,此时比例调节作用为0(Δx=0),微分调节作用也是0(v=0),所以小球在该处无法平衡,会在更远离平衡位置处达到平衡,那么就会有一个长时间存在的偏差。
积分作用就是检测偏差进行累积,对于上面这个长时间存在的偏差进行积分(累积叠加),使系统在长时间范围可以稳定在要求的平衡位置。

发表评论

评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据