搜索
bottom↓
回复: 4

AGV车PID控制(ii)

[复制链接]

出0入0汤圆

发表于 2010-5-19 08:41:29 | 显示全部楼层 |阅读模式

(原文件名:AGV running.jpg)


上图是前段时间和公司做的AGV车,功能都实现了,可以无线呼叫,到标志位停止,不过运行状况一般,有较大晃动,特别是载满货以后过弯道时经常出轨。
描述如下:
正常行驶时速度1~2M/S。这里我们只做到了1M/S。当速度再加快时,载上货物运行正常,但是空车运行时不太稳定,停止时易出轨。而在过弯道时,空车正常,载货时易出轨,所以这里我们采用了直道和弯道分开的策略,让弯道时减速。但由于载货对车体本身影响较大,过弯道有时还是不太稳定。

以下是系统中用到的PID循迹算法。虽然循迹功能实现了,但是当载货较重时,车身还是存在较大的晃动,感觉和机械机构也有关,因为通过挂钩拉货,挂钩摩擦力对车体由较大影响,当然这里和算法本身及其参数设计也有较大关系。

/********************
*    结构体定义区   *
********************/
typedef struct PID
{

int16_t pConst;         //  比例常数 Proportional Const   
int16_t iConst;         //  积分常数 Integral Const   
int16_t dConst;         //  微分常数 Derivative Const   

int16_t    position;  
int16_t    hisPosition;   
int16_t    lastPosition[10];


}PID;

/***********************************************************
*   函数名称:PID参数初始化                                      
*   功能描述:初始化PID参数,并实现P、I、D三个参数的整定                                       
*   参数列表:  
*   返回结果:无                                             
***********************************************************/
void  PIDInit(PID *iPID)
{
memset(iPID, 0, sizeof(iPID));  //将所有值清零

iPID->pConst = 2; //  比例常数 Proportional Const   
iPID->iConst = 0; //  积分常数 Integral     Const   
iPID->dConst = 8; //  微分常数 Derivative   Const

}


/***********************************************************
*   函数名称:PID控制程序                                      
*   功能描述:  
*   参数列表:  
*   返回结果:无                                             
***********************************************************/
void PIDCalc( PID *cPID)
{

int16_t  pGain; //P增益
int16_t  iGain; //I增益
int16_t  dGain; //D增益
int16_t  pidGain;            //控制量

cPID->position = Discretized(PIN_RED & 0X1F); //对采集的循迹信号进行离散化处理得到位置信息

cPID->hisPosition += cPID->position;                 //记录偏差之和

cPID->lastPosition[3] = cPID->lastPosition[2];
cPID->lastPosition[2] = cPID->lastPosition[1]; //
cPID->lastPosition[1] = cPID->lastPosition[0]; //
           cPID->lastPosition[0] = cPID->position;            //

pGain   = (cPID->pConst) * (cPID->position); //计算比例分量(P)=比例系数*本次位置差
iGain   = (cPID->iConst) * (cPID->hisPosition);                 //计算积分分量(I)=积分系数*偏差之和
dGain   = (cPID->dConst) * ((cPID->position) - (cPID->lastPosition[3])); //计算微分分量(D)=微分系数*(本次位置差-前3次的位置差)
                                                                                   //由于采样比较快,用本次位置-前3次位置才有足够大的控制 pidGain = pGain + iGain + dGain; //P分量和D分量相加,得到控制量。

if (pidGain > 320)  pidGain = 320; //模糊化处理,防止增量溢出
if (pidGain < -320) pidGain = -320;
pidGain = pidGain/10;

SetMotors(pidGain); //将控制量传入电机控制函数进行控制

}

/***********************************************************
*   函数名称:电机调速                                      
*   功能描述:通过得到的pidValue来改变占空比大小                                       
*   参数列表:                                             
*   返回结果:                                             
***********************************************************/
void SetMotors(int16_t pidValue)  
{
// PWM_CON =  _BV(ENA) | _BV(ENB) |  _BV(CTRL0) |!_BV(CTRL1) | _BV(CTRL2) |!_BV(CTRL3); //left
// PWM_CON =  _BV(ENA) | _BV(ENB) | !_BV(CTRL0) | _BV(CTRL1) |!_BV(CTRL2) | _BV(CTRL3); //right
// PWM_CON =  _BV(ENA) | _BV(ENB) |  _BV(CTRL0) |!_BV(CTRL1) |!_BV(CTRL2) | _BV(CTRL3); //back

PWM_CON =  _BV(ENA) | _BV(ENB) | !_BV(CTRL0) | _BV(CTRL1) | _BV(CTRL2) |!_BV(CTRL3); //forward

g_dutyL = 36 + pidValue;     //改变PWM值                        
g_dutyR = 36 - pidValue;  

}


/***********************************************************
*   函数名称:Discretized                                    
*   功能描述:对从循迹板采集的数据进行离散化处理                                       
*   参数列表:
*                                
*   返回结果:
*                                    
***********************************************************/
int16_t Discretized(uint8_t temp)
{

switch (temp)   //将位置信号进行离散化
{
case 0x1b: g_position = 0;
break;
case 0x1d: g_position = 10; //正,左加右减,向右转
break;
case 0x17: g_position = -10;           //负,左加右减,右转
break;
case 0x1e: g_position = 20; //正,左减右加,极左转
break;
case 0x0f: g_position = -20;            //负,左加右减,极右转
break;

case 0x1c: g_position = 40 ;             //正,左减右加,极左转
break;
case 0x07: g_position = -40 ;             //负,左加右减,极右转
break;

default:   g_position = 0;
break;
}


return g_position;

}

这上面的参数中10、20、40以及pConst、iConst、dConst都是先定了个大致范围,然后根据实际效果更改而得到的。希望大家对这这个算法和这个车多提些建议吧……

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

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2010-5-21 14:01:10 | 显示全部楼层
我不知道,AGV在停止的时候是不是减速停止,另外,从照片上看,货物是在车的前面,这样你要考虑整个AGV的重心点,这样能解决你行走的大部分问题,我们生产的AGV,一般都是把货物放在AGV驱动轮的上方,这样保证它的重心点,也就是说保证轮子与地面的磨擦力,只是从图片上看,说的不对,请拍砖

出0入0汤圆

发表于 2010-5-21 15:03:10 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-12-26 11:21:11 | 显示全部楼层
MARK

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-5-22 00:15

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

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