第四章 系统的软件设计
推荐给好友
打印
加入收藏
更新于2008-08-06 22:51:14

4.1程序结构规划


图4.1 主程序及中断子程序流程图


整个程序分为两大部分,分别是主程序与CCD中断程序,结构框图如图4.1所示。两大部分在程序结构上都使用了流水型结构,以避免代码的交叉调用,多层嵌套。在规划上以模块为目标,尽可能地减少代码的交叉。模块之间仅通过少量的全局变量作为数据交换通道,建立一个强内聚、松耦合的程序框架,达到便于维护、便于阅读、便于调试的目的。

主程序的结构相对比较简单,在完成系统初始化工作后启动1.5us定时中断,之后便进入一个while(1)循环。程序的所有调试相关代码都存放在while循环内,包括车模的红外遥控、PID参数调整、调试信息的输出等。

考虑到数据的采集与分析,包括PID算法本身对时间都有较高的要求,程序的所有数据采集主要集中在中断中完成。1.5us定时中断处理程序主要采集CCD信号,输入捕捉中断主要采集红外测速模块数据,PID算法运算模块、外部设备控制模块在主程序内完成。

4.2数据采集分析模块
数据采集分析模块负责外部传感器的信息采集及初步分析,此模块的输出数据将作为PID算法运算模块的输入,关系到整个运算的可靠性。因此,数据采集分析模块在数据的处理上尽可能的考虑了PID算法的需求。

4.2.1 轨道识别(CMOS)
轨道位置的确定主要依靠对CMOS传感器返回数据的分析计算。我们将8个红外传感器从左到右依次编号,左端起始为-4,右端终止为4。为了方便理解,编号0被舍弃。因为舵机角度控制部分的PID算法很大程度上依赖于探头返回数据的精度,PID算法需要输入数值具有较高的精度,所以需要对探头返回的数据进行处理。以符合PID算法的要求。
 
4.2.2 图像数据信息特点
摄像头的主要工作原理是:按一定的分辨率,以隔行扫描的方式采集图像上的点,当扫描到某点时,就通过图像传感芯片将该点处图像的灰度转换成与灰度成一一对应关系的电压值,然后将此电压值通过视频信号端输出。具体而言(参见图4.2),摄像头连续地扫描图像上的一行,则输出就是一段连续的电压视频信号,该电压信号的高低起伏正反映了该行图像的灰度变化情况。当扫描完一行,视频信号端就输出低于最低视频信号电压的电平(如 0.3V),并保持一段时间。这样相当于紧接着每行图像对应的电压信号之后会有一个电压“凹槽”,此“凹槽”叫做行同步脉冲,它是扫描换行的标志。然后,跳过一行后(因为摄像头是隔行扫描的方式),开始扫描新的一行,如此下去,直到扫描完该场的视频信号,接着就会出现一段场消隐区。此区中有若干个复合消隐脉冲(简称消隐脉冲),在这些消隐脉冲中,有个脉冲,它远宽于(即持续时间长于)其他的消隐脉冲,该消隐脉冲又称为场同步脉冲,它是扫描换场的标志。场同步脉冲标志着新的一场的到来,不过,场消隐区恰好跨在上一场的结尾部分和下一场的开始部分,得等到场消隐区过去,下一场的视频信号才真正到来。摄像头每秒扫描 25 幅图像,每幅又分奇、偶两场,先奇场后偶场,故每秒扫描 50 场图像。奇场时只扫描图像中的奇数行,偶场时则只扫描偶数行。图 4.2所示为摄像头视频信号。


图4.2 摄像头视频信号

由于 S12 芯片的处理能力不足以支持像 PC 那样的运算,因此我们采用了只有黑白制式、320×240 的 CMOS 单板摄像头(每秒 50 帧)。由于受 S12 片内 AD 的转换能力限制(参考技术报告《S12片内 AD 与 AD9054 的比较》),在总线周期为 32M 的情况下,每行最多能够采集 78 个点,其中前 12 个数据为行消影,第 12 到第 78 点为有效数据。

根据单行所能采集的数据点数,为了视觉上辨别前方一般路况信息,我们需要尽可能多的采集图像。 图 4.3所示为 40×80 的单幅图像。

但是对于比赛来说,赛道是在白色底板上铺设黑色引导线,因此它的干扰信息会少很多。所以对于比赛的黑线检测来说 40 行已经太多了:只要在单行上有足够多的信息点,较少的行数就可以实现对黑线的检测;在经过了实践比对之后,最终决定采用 10 行的信息来判断前方是直道还是弯道的方案。


图 4.3 40×80 灰度图


4.2.3 单行黑线提取算法
前面提到了摄像头图像信息的特点,接下来将结合比赛赛道的图像特点来讨论相应的黑线提取算法—边沿检测算法。由于比赛赛道是在白色底板上铺设黑色引导线,因此干扰比较小,黑线提取较为容易。
我们很自然的就想到了图像处理算法中较为简单的边界提取算法。由于黑色引导线和白色底板之间的色差较大,直接反映在图像数据中就是大于一个黑白色阀值。通过实验可以基本上确定该阀值的大小,由于现场光线变化的影响会有略微的变化,但是该阀值基本上介于 22-30 之间。可以通过判断相邻数据点的差是否大于该阀值,作为边沿提取算法的依据和主要参数。
 
该算法的主要过程为:首先从最左端的第一个有效数据点(12)开始依次向右进行阀值判断:由于实际中黑白赛道边沿可能会有模糊偏差,导致阀值并不是简单的介于相邻的两个点之间,很可能要相隔两个点。因此, 第 line 为原点,判断和 line+3 的差是否大于阀值,如果是则将 line+3 记为 i,从 i 开始判断从 i+3到该行最末一个点之间的差值是否大于阀值,如果大于则将 line+i/2+2 的坐标赋值给黑线中心位置。利用单行黑线提取算法所得到的黑线提取效果不仅可靠,而且实时性好,在失去黑线目标以后能够记住是从左侧还是右侧超出视野,从而控制舵机转向让赛车回到正常赛道。
 
根据CCD的数据采集,轨道相对于车体前端传感器组的位置由变量app_val表示,为方便理解,每两个相邻列的距离设定为18,因此轨道位置信息(app_val)的取值范围为0到700。也就是说,探头组返回的数据将是一个数组,经过计算后可以定量地表示轨道的位置,而不是局限于列的个数,如图4.4所示。由于系统本身存在的问题(如红外发射方向分布不均匀)等,图中轨道位置信息(app_val)的数值并不能确切地表达出轨道相对于车体的位置,下文会对此问题的处理方法作描述。


图4.4 轨道信息app_val数值设定


CCD传感器接收端返回的模拟信号经过MC9S12DG128内置的AD转换器处理之后,得到的数据数值在20~650范围内。如果下方为白色底板,返回的数值较大。如果下方为黑色轨迹,则返回的数值较小。其数值分布如图4.5所示,由于传感器组本身存在的误差以及外部光线的干扰,返回的数据会出现随机误差,但误差基本保持在20以内,不会影响系统的分析与计算。

取得探头返回的数据后,还需要一个算法将得到的数据转换成一个可以定性表示轨道位置的数值。通过几何的方法分析数据可以得到一个三角形算法,能够近似地计算得到轨道位置信息。计算方法如下:对于如图4.5所示的一组数据,首先对数据进行一次循环访问,找到数值最小的数据位置。然后将此数据及其左右侧的两个数提取出,保存至变量x、y、z(图4.6)中。


图4.5图象处理后返回数据


图4.6 变量保存图


之后计算黑线轨迹相对于y变量对应探头的偏移量(代码中变量名为app_offset)。黑线轨迹相对于探头的偏移量(app_offset)的计算公式推导依赖于几何方面的一些三角形定理,转换成C语言代码以后如下:

将计算得到的黑线轨迹偏移量(app_offset)的数值加上y对应探头的基值,即得到车体相对于轨道的位置(代码中变量名为app_val)。至此,已将一个CCD产生的不精确数据转换成确切的可以表现出轨道与探头距离的数值。然而,由于CCD的系统误差,当车体匀速偏移时,轨道相对于车体位置(app_val)在数值上并不是线性变化的。这是因为探头位置在100水平单位的整数倍位置,而CCD每列的数据是不均匀的,从而造成100水平单位整数倍附近的轨道位置(app_val)变化速率较慢,而100水平单位整数倍±50单位附近数值变化速率比较快。其变化速率如图4.7所示。


图4.7 app_val变化速率曲线图

鉴于MC9S12DG128有足够大的RAM,我们采用查表方式对轨道位置信息(app_val)进行修正。在测试阶段从左到右对轨道位置信息(app_val)进行多次采样,将原来的700个单位重新划分区域,转换成70个单位。虽然转换后的数据在数值范围上变小了,但是转换后的数据是近似线形变化的,有利于之后的PID控制。
 


图4.8 修正后的探头返回数据

通过查表方式对轨道位置信息(app_val)进行修正后如图4.8所示,对比图4.4可以发现app_val的值表现得更为确切。

4.3车速测定(红外对管)
车体的速度信息是整体控制不可缺少的一项。在速度的测定上,我们选用了红外对管。在软件上通过计数的方式计算当前的车体速度。对管对准编码盘的孔时,产生一个下降沿,引起计数器加1。然后程序定时检查定时器的值,同时判断是否需要更新当前速度(代码中变量名为vspeed)的值。
速度的计算代码如下: vspeed = 1000 / vcount,其中 vcount为所经历的1ms中断次数,即车轮转动1/24圈所消耗的毫秒数。


图4.9车速测定软件流程图

在PID速度控制中,计算得到的信息为速度增加减小的比例,所以在车速的测定过程中没有使用标准单位。上述代码中所使用的的1000只是一个参考值。

车速测定软件流程图如图4.9所示。速度计算函数每1ms中断都会被调用一次,首先检查计数器所对应的寄存器的值,然后计算vspeed或者vcount自增。其中将vcount保存的临时值进行1000/vcount计算,并与vspeed进行比较,这是为了防止在车模低速行进或者刹车时,车轮较长时间(相对ms级而言)以后才转过1/24圈,从而导致的因为vspeed刷新速度过慢而产生的不稳定现象。
 
4.4 PID算法运算模块
PID算法是整个软件控制的核心部分,因此PID算法运算模块的可靠性、维护性与可测试性等尤为重要。
 
4.4.1程序结构
PID算法作为整个软件控制的核心,需要不断试验、更改参数数值。因此在程序结构规划上将其分为PID路线控制与PID动力控制两部分,分别间接控制舵机与电机。前者主要负责对舵机角度的控制,输入轨道信息(app_val),运算结束时输出舵机控制信息(代码中变量名helm_ctrl)。当前应该达到的速度(代码中变量名keepspeed),是PID路线控制的另一个输出信息。其数值的确定依赖于舵机控制信息(helm_ctrl),依据的基本规则是舵机偏转角度越大,车体所应达到的车速越小。PID动力控制部分将对目标速度(keepspeed)和当前速度(vspeed)再次进行PID运算,得到电机控制信息(moto_ctrl)并交给外部设备控制模块处理,以达到控制速度的目的。两个部分通过外部全局变量交换信息,达到PID路线控制部分间接影响PID动力控制的目的。同时又将硬件控制模块与PID模块分离开来,两者之间也是通过外部全局变量交换信息。这种方法也利于后期的程序阅读和调试。PID算法程序结构示意图如图4.10所示。
 
4.4.2 PID控制算法的选择
在PID控制算法的选择上,都选用了增量式PID控制算法。因为在增量形式的控制算法中,控制作用的比例、积分和微分部分是相互独立的,便于检查参数变化对控制效果的影响,在后期调试过程中可以起到较好的效果。


图4.10 PID算法程序结构示意图

所需公式为:△u(k) = Kp[e(k) – e(k-1)] + Ki e(k) + Kd[e(k) – 2e(k-1) + e(k-2)],其中△u(k)表示增量,e (t)为系统的控制偏差,Kp为比例增益,Ki = Kp T / Ti 表示积分系数,Kd =KpTd / T 表示微分系数。

Kp 比例增益起比例调节作用,系统一旦出现了偏差,比例调节立即产生调节作用以减少偏差。将Kp设置成较大的数,比例作用大,可以加快调节,减少误差,但是对于过大的比例增益,会导致系统稳定性下降,甚至造成系统的不稳定。
 
Ki 积分调节使系统消除稳态误差,提高无差度。有误差时,积分调节就进行;无差时,积分调节停止。积分调节输出一常值,积分作用的强弱取决于积分时间常数Ti。Ti越小,积分作用就越强,反之则积分作用弱。积分调节的引入会使系统稳定性下降,动态响应变慢。

Kd 微分系数反映了系统偏差信号的变化速率,可以预见偏差的变化趋势,能提前对偏差进行控制。使用微分作用后可以在偏差还没有形成前将其消除,因此,可以改善系统的动态性能。选择合适的微分时间,可以减少调节时间。但是微分作用也同样存在缺陷,对噪声干扰有放大作用,因此过强的微分调节对系统的抗干扰能力会造成影响。

4.4.3 PID路线控制


图4.11 PID路线控制算法示意图

PID路线控制算法示意图如图4.11所示。Kp、Ki与Kd三个量的值需要反复试验,PID路线控制部分输出的控制信息比较多,包括了舵机与电机的两个控制信息,分别是当前舵机的偏转增量与车模需要达到的前进速度。这个两个数据又分别作为路线与动力控制模块及PID动力控制部分的输入数据。舵机控制信息(helm_ctrl)交给舵机控制部分以后直接查表转换成对应的PWM波产生器的寄存器值。当前应达到的速度(keepspeed)根据当前轨道黑线的位置以及偏差的累积程度来确定,其值大小与电机控制之间属间接关系,需要经过PID动力控制部分处理之后,转换成电机的控制信息,即动力的增强减弱量或刹车的强度。

4.4.4 PID动力控制
PID动力控制算法示意图如图4.12 所示。这里的Kp、Ki与Kd三个量的值同样需要反复试验。当前应达到的速度(keepspeed)在PID路线控制部分确定,计算原理基本上与路线控制算法相似。


图4.12 PID动力控制算法示意图



4.5 外部设备控制模块
外部设备控制模块将PID处理得到的数据转换成硬件控制信号并输出,作为PID处理信息的输出抽象层,使程序的PID信息处理部分脱离硬件控制信息而存在。

4.5.1舵机角度控制
舵机的偏转角度被分为11个等级,从-5至5分别表示从左到右的偏转程度,0等级表示竖直向前,负数表示左转,正数表示右转。舵机控制信息helm_ctrl就是以偏转角度等级作为控制单位。舵机控制表如表4.1所示。


表4.1舵机控制表

 舵机控制信息(helm_ctrl)表示的是舵机偏转的增量,但是舵机控制需要的是偏转的位置。在这里还需要预先保存当前的舵机位置信息(helm_base),执行helm_base += helm_ctrl。
将PID路线控制的输出信息加入到角度控制中,再对其进行一次查表,转换成所需要的PWM发生器的寄存器值,实现软件上对舵机的控制,如图4.13所示。


图4.13 舵机控制图

4.5.2电机动力控制
电机动力控制通过3种方式来实现:电机加速转动、减速转动、反转。这3种方式使车模得到最大的动力与阻力来完成加速与减速。电机动力控制程序流程图如图4.14所示。


图4.14电机动力控制程序流程图

 
加速的过程比较简单,直接将电机控制信息(moto_ctrl)的值查表转换成对应的PWM发生器寄存器值即可。根据所需要的速度增量调整PWM发生器寄存器值,提高电机的电压。减速过程则通过两种方法完成。把PID动力控制计算得出的电机控制信息(moto_ctrl)与一个事先测定好的临界值作比较,如果需要降低的速度量小于此临界值,说明速度需要稍微降低,使用类似于加速的方法根据速度增量调整PWM发生器寄存器值,降低电机电压。如果需要降低的速度量大于此临界值,说明当前车模需要一个刹车,程序将当前PWM发生器寄存器置零,然后设置另一个控制电机反转的寄存器值,给予电机一个反转的动力,给车模产生一个较大的阻力,使车体在短时间内迅速降低速度。电机控制图如图4.15所示。


图4.15 电机控制图

 

 

上一章: 系统的硬件设计                                                          下一章:调试




 
关于我们 | 诚邀加盟 | 客户服务 | 相关法律 | 网站地图 | 友情链接 | 服务信箱:service@eefocus.com
© 2006 与非门科技信息咨询(北京)有限公司 All Rights Reserved.