描述
<p><strong>一、作品简介</strong>
<strong>1.1研究目的</strong>
倒立摆控制系统是一个复杂的、不稳定的、<a href="http://baike.baidu.com/item/%E9%9D%9E%E7%BA%BF%E6%80%A7%E7%B3%BB%E7%BB%9F" target="_blank">非线性系统</a>,是进行控制理论教学及开展各种控制实验的理想实验平台。对倒立摆系统的研究能有效的反映控制中的许多典型问题:如非线性问题、<a href="http://baike.baidu.com/item/%E9%B2%81%E6%A3%92%E6%80%A7" target="_blank">鲁棒性</a>问题、镇定问题、随动问题以及跟踪问题等。通过对倒立摆的控制,用来检验新的控制方法是否有较强的处理非线性和不稳定性问题的能力。同时,其控制方法在军工、航天、机器人和一般工业过程领域中都有着广泛的用途,如机器人行走过程中的平衡控制、火箭发射中的垂直度控制和卫星飞行中的姿态控制等。我们此次使用STM32F103C8T6进行项目开发,使用PID算法对倒立摆进行控制,并能对倒立摆的参数、状态等进行调节与显示,一方面可以用过理论研究之用,另一方面能够用于新手对于PID参数的整定方法进行练习,掌握大概的概念和思路。综上所述,我们的研究目的主要是设计一款简单易用,稳定可靠,同时具有研究意义和教学意义的圆周倒立摆PID调节系统。
<strong>1.2研究思路</strong>
为了完成圆周倒立摆调节系统,有三个问题是需要解决的:第一,应该用何种手段来检测倒立摆的角度;第二,当获取到角度反馈时,机械结构该如何搭建,电机该如何控制;第三,应该用什么方式来进行人机交互和参数调节。制作的思路应该以这三个问题为中心,来逐步完善。首先,检测问题,我们通过六轴传感器来检测加速度和陀螺仪,并进行解算或直接使用高精度电位器来获取角度值,一方面要保证检测装置安全可靠,另一方面对于获取的数据要求处理得当。然后,机械和控制问题,机械结构上力求简单稳定,在材料和加工上力求完美;当获取到反馈后,我们通过PID算法对电机进行控制,达到预期的设定角度。最后,显示和调试问题,我们可以使用上位机和键盘、OLED液晶屏相结合的方式或是使用时一体式的触摸屏进行人机交互,参数调节使用按键或是触摸屏,参数可以保存在EEPROM或是外置存储中。以上,就是本作品的研究思路。
<strong>1.3主要功能</strong></p>
<h3>1.3.1 自动起摆</h3>
<p>摆杆能够在自然下垂状态,通过左右摇晃使其迅速达到倒立平衡状态。</p>
<h3>1.3.2 倒立平衡</h3>
<p>在外力帮助下,让摆杆倒立,撤去外力,摆杆依然能够保持平衡状态,并在外力干扰下依旧能够保持长时间平衡。</p>
<h3>1.3.3 倒立圆周旋转</h3>
<p>在倒立平衡状态下,能够快速地完成任意方向和任意角度的旋转(通过触摸屏设置参数并控制)。</p>
<h3>1.3.4 人机交互</h3>
<p>通过触摸屏进行参数读取,参数调节,波形显示,模式控制等功能,同时参数将会存储在单片机的EEPROM中,便于掉电保护和实时存储。</p>
<h2>1.4技术指标</h2>
<p>① 摆杆平衡状态是指在-165°-165°之间,处于平衡状态必须保持30S以上。
② 倒立圆周运动不能在运动过程中中断,且需要保持匀速旋转,并实时显示目标位置。
③ 当摆杆处于平衡状态时,外力干扰在30°范围内依旧能够保持平衡。
④ 人机交互界面优化,参数调节步进值可调节,参数可记忆。
<strong>1.5实物照片</strong>
*<em> <img src="//" alt="">
***\</em> <img src="//" alt=""></p>
<hr>
<hr>
<p>**** <img src="//" alt="">
**** <img src="//" alt="">**</p>
<p><strong>二、系统构架图</strong>
2.1系统方案设计
本产品结合不锈钢型材和工件搭建的机械结构、大功率直流电机、高精度电位器、STM32单片机和TB6612FNG驱动、OLED液晶屏等进行设计,以STM32单片机作为控制中枢,电位器和编码器作为信息反馈,以PID算法对电机进行控制,以触摸式电容屏作为辅助控制与调试工具,最终实现倒立摆的平衡控制和参数调节与显示。整个控制系统要求控制中枢与各个模块协调工作,不仅具备极高的观赏性和操作性,还具有一定的研究意义和教学价值。作品框架大致可分为中央处理、信息采集、动作执行三个大类,细分则由五个主要部分构成,每个模块都有自己的功能和职责,相互协调工作,构成了完整的嵌入式系统。作品整体框架图如下图所示。
<img src="//" alt=""></p>
<h2>2.2 方案分析与选择</h2>
<h3>2.2.1 通讯模块选取</h3>
<p>方案一:使用Wi-Fi模块进行警报信息传递。基于ESP8266的Wi-Fi模块,属于物联网传输层,无线网络通信标准的嵌入式模块,内置无线网络协议协议栈以及<a href="http://baike.so.com/doc/2883582-3043043.html" target="_blank">TCP/IP</a>协议栈。传统的硬件设备嵌入Wi-Fi模块可以直接利用Wi-Fi联入互联网,是实现无线智能家居、M2M等物联网应用的重要组成部分。
方案二:使用BLE低功耗蓝牙模块进行警报信息传递。即蓝牙低能耗技术,利用许多智能手段最大限度地降低功耗。被称为超低功耗无线技术)。BLE是蓝牙4.0的核心Profile,主打功能是快速搜索,快速连接,超低功耗保持连接和传输数据,弱点是数据传输速率低,由于BLE的低功耗特点,因此普遍用于穿戴设备。
方案三:使用ZigBee模块进行警报信息传递。基于IEEE802.15.4标准的低功耗局域网协议。按照维基百科的说法,其命名参照蜜蜂的群体通信网络:蜜蜂(bee)靠飞翔和“嗡嗡”(zig)地抖动翅膀的“舞蹈”来与同伴传递花粉所在方位信息。简单来说,ZigBee技术是一种短距离、低功耗的、便宜的无线组网通讯技术。
方案四:使用GMS模块进行警报信息传递。GSM模块,是将GSM射频<a href="http://baike.so.com/doc/2573081-2717209.html" target="_blank">芯片</a>、基带处理芯片、<a href="http://baike.so.com/doc/4224899-4426539.html" target="_blank">存储器</a>、功放器件等集成在一块线路板上,具有独立的操作系统、GSM射频处理、基带处理并提供标准接口的功能模块。GSM模块具有发送SMS短信,语音通话,GPRS数据传输等基于GSM网络进行通信的所有基本功能。
方案五:使用NRF24L01+进行无线射频通信,是一款工作在2.4~2.5GHz 世界通用ISM 频段的单片无线收发器芯片。无线收发器包括:频率发生器、增强型ShockBurst模式控制器、<a href="http://baike.baidu.com/subview/70018/70018.htm" target="_blank">功率放大器</a>、<a href="http://baike.baidu.com/subview/480656/480656.htm" target="_blank">晶体振荡器</a><a href="http://baike.baidu.com/subview/1654807/1654807.htm" target="_blank">调制器</a>、<a href="http://baike.baidu.com/subview/3871271/3871271.htm" target="_blank">解调器</a>。<a href="http://baike.baidu.com/subview/192874/192874.htm" target="_blank">输出功率</a>频道选择和协议的设置可以通过<a href="http://baike.baidu.com/subview/140064/140064.htm" target="_blank">SPI接口</a>进行设置,传输较为稳定,性价比超高。
结论:WiFi模块的功耗比较大,适合传输大量的数据,耗电严重;BLE功耗相对比较低,但能同时连接的设备有限;而Zigbee功耗低,可拓展的节点多;Zigbee模块和GSM短信模块质量相对较大,无法满足我们作品的负载能力。NRF24L01+功耗较大,距离有限,配置繁琐。所以我们选择蓝牙模块来作为我们的调试通信模块,用于无线查看数据和实时调试项目。</p>
<h3>2.2.2 角度反馈方案选取</h3>
<p>方案一:选用高精度电位器WDD35D4,采用硬质铝合金材料制成外壳,采用导电塑料作为电阻材料,导电塑料由树脂和导电物质两者混合,用塑料的加工方式进行加工的功能型高分子材料,该系列电位器的导电塑料经过模压和激光修刻微调,以确保相应的高精度。贵金属激流装置,不锈钢的高速轴承等部件,保证了产品的高品质与高性能,具有机械寿命长,分辨率高,转动顺滑,动态噪声小的优良性能。机械寿命长达5000W转,经久耐用。
方案二:使用MPU6050/MPU9250传感器,MPU6050仅支持IIC通信,最大通信速率400KHz,其精确度高,价格低,目前市面上使用最为广泛;MPU9250是一个QFN封装的复合芯片(MCM),它由2部分组成。一组是3轴加速度还有3轴陀螺仪,另一组则是AKM公司的AK8963 3轴磁力计。所以,MPU9250是一款9轴运动跟踪装置,他在小小的封装中融合了3轴加速度,3轴陀螺仪以及数字运动处理器(DMP)并且兼容MPU6515。其完美的I2C方案,可直接输出9轴的全部数据。一体化的设计,运动性的融合,时钟校准功能,让开发者避开了繁琐复杂的芯片选择和外设成本,保证最佳的性能。本芯片也为兼容其它传感器开放了辅助I2C接口,比如连接压力传感器。
方案三:使用恩智浦公司的MMA7660加速度计,将-1.5g ~ 1.5g范围的XYZ三轴收到的加速度大小,由数字IIC输出,是非常低功耗、小形容性MEMS传感器,具有低通滤波器,用于0g和增益误差的补偿以及用户可配置的转化成6位数值。模拟电压为2.4-3.6V,数字工作电压1.71-3.6V,可进行三轴取向/运动的检测,广泛应用与手机、PDA、便携PC的防盗、游戏的运动检测等。
结论:考虑到项目要求更加稳定的器件,从硬件上来说,电位器的角度反馈最为简单直接,采集周期取决与ADC读取的最快速度,而数字式加速度计和陀螺仪安装较为麻烦,且数据可信度不高,采集周期受到限制,需要复杂的算法和校正,且长时间工作后会产生温漂,对控制系统会产生或多或少的影响。综合稳定性和使用难易程度,我们最终选取的WDD35D4高精度电位器作为我们的角度传感器,用于检测倒立摆的角度,作为控制系统的反馈。</p>
<h2>2.3 PID算法分析</h2>
<p>工程实际中,应用最为广泛调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。PID控制器问世至今已有近70年历史,它以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制主要技术之一。当被控对象结构和参数不能完全掌握,或不到精确数学模型时,控制理论其它技术难以采用时,系统控制器结构和参数必须依靠经验和现场调试来确定,这时应用PID控制技术最为方便。即当我们不完全了解系统和被控对象﹐或是不能有效测量手段来获系统参数时,最适合用PID控制技术。PID控制,实际中也有PI和PD控制。PID控制器就是系统误差,利用比例、积分、微分计算出控制量进行控制。我们的倒立摆平衡调节系统中使用到PID参数的整定。
<strong>三、硬件部分的描述</strong>
<strong>3.1电源模块原理图和PCB</strong>
(下载次数:678) <a href="http://club.szlcsc.com/article/downFile_FFAFF28788A3F418.html" target="_blank">电赛PCB准备之降压模块V1.1.zip</a> (下载次数:678)
<strong>3.2STM32最小系统板原理图和PCB</strong>
<a href="http://club.szlcsc.com/article/downFile_FE76E69A43471405.html" target="_blank">电赛PCB准备之STM32核心板.zip</a> (下载次数:708)
<strong>3.3 实现原理和工作过程</strong>
为实现稳定的圆周倒立摆控制系统,我们搭建了简单稳定的机械结构,整体机械结构如下图所示,在图中A位置我们选用了带编码器的大功率直流电机,同轴性较好,无需考虑齿轮传动存在的误差,闭环控制简单,支架B我们采用铝合金型材进行搭建,三角支撑,非常稳定,转轴F为电机A的轴,转轴D为高精度电位器的轴,减少中间传动环节,让控制更加稳定,E摆杆和C 旋转臂选用金属材料进行激光切割,稳定性好,不易变形。整体结构简单稳定,为之后的软件控制打下来坚实的硬件基础。通过电动机A传动C旋转臂,带动E摆杆运动,D转轴是活动的转轴,通过在D转轴上使用高精度电位器进行角度的检测,控制达到目标角度,使其最终平衡在倒立状态。
<img src="//" alt="">
<strong>四、材料清单(BOM列表)</strong>
名称 封装 编号
STM32F103C8T6 LQFP-48 <a href="http://www.szlcsc.com/product/details_9243.html" target="_blank">C8734 </a>
TB6612FNG SSOP-24 <a href="http://www.szlcsc.com/product/details_89402.html" target="_blank">C88224</a>
QG-2864KLBEG01 0.96寸 <a href="http://www.szlcsc.com/product/details_92944.html" target="_blank">C91755</a>
LM1117 3.3V SOT223 <a href="http://www.szlcsc.com/product/details_24724.html" target="_blank">C23984</a></p>
<p><strong>五、软件部分的描述(选填)</strong></p>
<h2>5.1软件工作流程图</h2>
<p>作品的程序主体大概由五个部分组成,分别是:各模块初始化、读取传感器数据、电容屏检测触摸操作、电容屏刷新显示、电机PID控制。软件总体流程图如下图所示。
<img src="//" alt=""></p>
<h2>5.2 位置式PID算法</h2>
<p>PID控制是一个二阶线性控制器,通过调整比例、积分和微分三项参数,使得大多数的工业控制系统获得良好的闭环控制性能。具有技术成熟、易被人们熟悉和掌握、不需要建立数学模型、控制效果好、鲁棒性等优点,通常依据控制器输出与执行机构的对应关系,将基本数字PID算法分为位置式PID和增量式PID两种。我们在整定PID控制器参数时,根据控制器的参数与系统动态性能和稳态性能之间的定性关系,用实验的方法来调节控制器的参数。有经验的调试人员一般可以较快地得到较为满意的调试结果。在调试中最重要的问题是在系统性能不能令人满意时,知道应该调节哪一个参数,该参数应该增大还是减小。为了减少需要整定的参数,首先可以采用PI控制器。为了保证系统的安全,在调试开始时应设置比较保守的参数,例如比例系数不要太大,积分时间不要太小,以避免出现系统不稳定或超调量过大的异常情况。给出一个阶跃给定信号,根据被控量的输出波形可以获得系统性能的信息,例如超调量和调节时间。应根据PID参数与系统性能的关系,反复调节PID的参数。如果阶跃响应的超调量太大,经过多次振荡才能稳定或者根本不稳定,应减小比例系数、增大积分时间。如果阶跃响应没有超调量,但是被控量上升过于缓慢,过渡过程时间太长,应按相反的方向调整参数。 如果消除误差的速度较慢,可以适当减小积分时间,增强积分作用。反复调节比例系数和积分时间,如果超调量仍然较大,可以加入微分控制,微分时间从0逐渐增大,反复调节控制器的比例、积分和微分部分的参数。 总之,PID参数的调试是一个综合的、各参数互相影响的过程,实际调试过程中的多次尝试是非常重要的,也是必须的。我们系统采用的经典的位置式PID算法,主要进行电机速度和位置的闭环控制,相关代码见附录,经过我们不断的调试,最终确定了一组较为合适的参数,如表 1 所示。
表 1 一组较为合适的PID参数</p>
<table>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
<tr>
<td>PID参数</td>
<td>Balance_KP</td>
<td>Balance_KD</td>
<td>Position_KP</td>
<td>Position_KD</td>
</tr>
<tr>
<td>合适数值</td>
<td>50</td>
<td>240</td>
<td>25</td>
<td>600</td>
</tr>
</table>
<p><strong>5.3 关键性代码</strong>
<a href="http://club.szlcsc.com/article/downFile_9EB4AF5FF07EE44D.html" target="_blank">代码.rar</a> (下载次数:716)
if(ParaADJ==0)
{
if(delay_flag==1)
{
if(++delay_50==10) delay_50=0\,delay_flag=0; //===给主函数提供50ms的精准延时
}
Angle_Balance=Get_Adc_Average(7\,15); //===更新姿态
D_Angle_Balance= Angle_Balance-Last_Angle_Balance ; //===获取微分值
if(State==0) Run(Way_Turn);//起摆 由入口参数控制 1:自动起摆 2:手动起摆</p>
<p>if(State==1) //起摆成功之后,进行倒立控制
{
Balance_Pwm =balance(Angle_Balance); //开启平衡控制
if(Flag_qb2==0) //位置控制延时启动
{
if(Angle_Balance(ZHONGZHI-200))Count_Position++; //
if(Count_Position>60)Flag_qb2=1\, Count_Position=0\,TIM2->CNT=10000; //在平衡位置倒立超过300ms 开启位置控制
}
if(Flag_qb2==1) //开启位置控制
{
Encoder=Read_Encoder(2); //===更新编码器位置信息
if(++Count_P2>4) Position_Pwm=Position(Encoder)\,Count_P2=0; //===位置PD控制 25ms进行一次位置控制
}
Moto=Balance_Pwm-Position_Pwm; //===计算电机最终PWM
Xianfu_Pwm(); //===PWM限幅
if(Turn_Off(Voltage)==0) //===低压和倾角过大保护
Set_Pwm(Moto); //===赋值给PWM寄存器
}
//==========以下是一些时序要求不严格的,在中断的最后执行===============//
Led_Flash(100); //===LED闪烁指示系统正常运行
Voltage_Temp=Get_battery_volt(); //=====读取电池电压
Voltage_Count++; //=====平均值计数器
Voltage_All+=Voltage_Temp; //=====多次采样累积
if(Voltage_Count==100) Voltage=Voltage_All/100\,Voltage_All=0\,Voltage_Count=0;//=====求平均值
Key(); //===扫描按键变化
Last_Angle_Balance=Angle_Balance; //===保存上一次的倾角值</p>
<p>int balance(float Angle)
{
float Bias; //倾角偏差
static float Last_Bias\,D_Bias\,I_Bias; //PID相关变量
int balance; //PWM返回值
Bias=Angle-ZHONGZHI; //求出平衡的角度中值 和机械相关
I_Bias+=Bias;
D_Bias=Bias-Last_Bias; //求出偏差的微分 进行微分控制
balance=-Balance_KP*Bias- D_Bias*Balance_KD+ I_Bias*Balance_Ratio; //===计算倾角控制的电机PWM PD控制
Last_Bias=Bias; //保持上一次的偏差
return balance;
}
int Position(int Encoder)
{
static float Position_PWM\,Last_Position\,Position_Bias\,Position_Differential;
static float Position_Least;
Position_Least =Encoder-Position_Zero; //===获取偏差
Position_Bias *=0.8;
Position_Bias += Position_Least*0.2; //===一阶低通滤波器
Position_Differential=Position_Bias-Last_Position; //===获取偏差变化率
Last_Position=Position_Bias; //保存上一次的偏差
Position_PWM=Position_Bias*Position_KP+Position_Differential*Position_KD; //===速度控制
return Position_PWM;
}
void Xianfu_Pwm(void)
{
int Amplitude=6900;
if(MotoAmplitude) Moto=Amplitude;
}
int Incremental_PI (int Encoder,float Target)
{
static float Bias,Pwm,Last_bias;
Bias=Encoder-Target; //计算偏差
Pwm+=9*(Bias-Last_bias)+9*Bias; //增量式PI控制器
Last_bias=Bias; //保存上一次偏差
return Pwm; //增量输出
}
int Position_PID (int Encoder,int Target)
{
static float Bias\,Pwm\,Integral_bias\,Last_Bias;
Bias=Encoder-Target; //计算偏差
Integral_bias+=Bias; //求出偏差的积分
Pwm=70*Bias*Ratio+0.00*Integral_bias*Ratio+200*(Bias-Last_Bias)*Ratio; //位置式PID控制器
// Pwm=80*Bias*Ratio+0.00*Integral_bias*Ratio+250*(Bias-Last_Bias)*Ratio; //位置式PID控制器
Last_Bias=Bias; //保存上一次偏差
return Pwm; //增量输出
}
/**************************************************************************
函数功能:自动起摆程序
入口参数:int
返回 值:
**************************************************************************/
void Run(u8 Way)
{
static float Count_FZ\,Count_Next\,Target_Position=10380;
static u8 Flag_Back;
static float Count_Big_Angle=0.046542;
static int Angle_Max\,Position_Max;
if(Way==1) //进入自动起摆程序 按键触发
{
if(Flag_qb==0) //第1步,采样
{
if(Target_Position12000)Flag_Back=1;
if(Flag_Back==1)
{
Ratio=0.1; //使用较小的PID参数
Target_Position=Position_Max;//回到之前读取的角位移传感器数据最大的地方
if(Count_Next++>600) //3s之后 进入下一步
{
Flag_qb++;
TIM2->CNT=10000;
Flag_Back=0;
}
}
Encoder=Read_Encoder(2); //===更新编码器位置信息
Moto_qb=Position_PID(Encoder\,Target_Position); //位置闭环控制
if(Moto_qb>1200)Moto_qb=1200; //控制位置闭环控制过程的速度
if(Moto_qb10260&&EncoderAngle_Max) Angle_Max=Angle_Balance\,Position_Max=Encoder;
}
Data_Show2=Position_Max;//赋值到全局变量显示
Data_Show=Angle_Max;
}
if(Flag_qb==1) //第2步,摆杆自由摆动,振幅越来越大
{
Ratio=1; //正常的PID参数
Count_qb+=Count_Big_Angle; //自变量
Count_Big_Angle-=0.00000205; //振幅越大,摆动周期略微减小
Count_FZ+=0.03; //振幅越来越大
Target_Position=0.8*Count_FZ*sin(Count_qb)+10000; //运动公式
Encoder=Read_Encoder(2); //===更新编码器位置信息
Moto_qb=Position_PID(Encoder\,Target_Position); //位置闭环控制
if(Moto_qb>7200)Moto_qb=7200;//控制位置闭环控制过程的速度
if(Moto_qb(Angle_Max+710)&&Angle_Balance7200) Moto_qb=7200;
if(Moto_qb</p>
<h5>更多项目详情见作品链接:<a href="http://club.szlcsc.com/article/details_7500_1.html" target="_blank">http://club.szlcsc.com/article/details_7500_1.html</a></h5>
<h5>本项目归立创社区Itchy所有</h5>
评论(0)