久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 7516|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

搞平衡車熱身之PID試驗(yàn)程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:80436 發(fā)表于 2015-5-21 22:41 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
先上代碼
#include <string.h>   
#include <stdio.h>
#include "RobotLib.h"
int flag=0;
/*====================================================================================================   
    PID Function   

    The PID  function is used in mainly   
    control applications. PIDCalc performs one iteration of the PID   
    algorithm.  

    While the PID function works, main is just a dummy program showing   
    a typical usage.   
=====================================================================================================*/  

typedef struct PID {  

        int  SetPoint;           //  ???? Desired Value  

        int  Proportion;         //  ???? Proportional Const   
        int  Integral;           //  ???? Integral Const   
        int  Derivative;         //  ???? Derivative Const  

        int  LastError;          //  Error[-1]   
        int  PrevError;          //  Error[-2]   
        int  SumError;           //  Sums of Errors  

} PID;  

/*====================================================================================================   
   位置式PID

=====================================================================================================*/  

int PIDCalc( PID *pp, int NextPoint )   
{   
    int  dError,   
         Error;  

        Error = pp->SetPoint -  NextPoint;          // ??   
        pp->SumError += Error;                      // ??   
        dError = pp->LastError - pp->PrevError;     // ????   
        pp->PrevError = pp->LastError;   
        pp->LastError = Error;   
        return (pp->Proportion * Error              // ???   
            +   pp->Integral * pp->SumError         // ???   
            +   pp->Derivative * dError             // ???   
        );   
}  


/*====================================================================================================
   增量式PID
=====================================================================================================*/
double PIDCalc_delt( PID *pp, double NextPoint )
{
        double dError, Error;
        Error = pp->SetPoint - NextPoint;       // ?????  ???????????
        dError= pp->Proportion * Error  +  pp->Integral * pp->LastError  +  pp->Derivative * pp->PrevError;
        pp->PrevError = pp->LastError;          // ?????  ????????????
        pp->LastError = Error;
        return (dError);
}
/*====================================================================================================   
   Initialize PID Structure   
=====================================================================================================*/  

void PIDInit (PID *pp)   
{   
    memset ( pp,0,sizeof(PID));   
}  

/*====================================================================================================   
    Main Program   
=====================================================================================================*/  


/*#define N 12
int sensor (void)                    //  Dummy Sensor Function   
{   
  char count,i,j;
  int ad_data[N];
  int sum=0;
  int advalue=0;
  int temp=0;
  for (count = 0; count<=N; count++)
  {
  ad_data[count]=AI(1);
  }
  for (j=0;j<N-1;j++)
  {
  for (i=0;i<N-1;i++)
  {
  if (ad_data[i]>ad_data[i+1])
  {
    temp=ad_data[i];
    ad_data[i]=ad_data[i+1];
    ad_data[i+1]=temp;
  }
  }
  }
  for (count=0;count<N;count++)
  {
  sum=ad_data[count];
  }
  advalue=sum/(N-2);
  return advalue;

}  */
void Run(int left_speed,int right_speed)
{
SetMoto(0,-left_speed);
SetMoto(1,-right_speed);
}

int speed=0;
void actuator(int rDelta)            //  Dummy Actuator Function   
{
     speed=rDelta;
     if(flag==1)
     {
if (speed>100)
{
speed=100;
}
else if(speed<-100)
{
speed=-100;
}
}
else if(flag==2)
{
   speed=rDelta/3;
if (speed>50)
{
speed=50;
}
else if(speed<-50)
{
speed=-50;
}
    else if (speed<10 && speed>0)//電機(jī)死區(qū)
    {
      speed=8;
    }
    else if (speed>-10 && speed<0) //電機(jī)死區(qū)
    {
      speed=-8;
    }
}
Run(speed,speed);

}  
#define N 12
int sensor1(void)//均值濾波。最簡(jiǎn)單的一種
{
  int buffer[N];
  int count=0;
  int sum=0;
  int ad=0;
  for (count=0;count<N;count++)
  {
  buffer[count]=AI(1);
  wait(0.001);
  }
  for (count=0;count<N;count++)
  {
  sum+=buffer[count];
  }
  ad=sum/N;
  return ad;
}

void main(void)   
{   
    PID      setPID;                   //  PID Control Structure   
    int      OutPut;                   //  PID Response (Output)   
    int      InPut;                    //  PID Feedback (Input)  

    PIDInit ( &setPID );                  //  Initialize Structure   
    setPID.Proportion = 20;              //  Set PID Coefficients   
    setPID.Integral   = 0.5;   
    setPID.Derivative = 0.5;   
    setPID.SetPoint   = 150;            //  Set PID Setpoint  
    while(0)
    {
      printf("%d\n", sensor1());
    //  wait(0.2);
    }
    while(1)
     {                          //  Mock Up of PID Processing  
        InPut = sensor1();                //  Read Input
         if(InPut-setPID.SetPoint>80 ||InPut-setPID.SetPoint<-80)//分段式PID.距離遠(yuǎn),比例系數(shù)大點(diǎn)
         {
            flag=1;
     PIDInit ( &setPID );                  //  Initialize Structure   
    setPID.Proportion = 20;              //  Set PID Coefficients   
    setPID.Integral   = 0.5;   
    setPID.Derivative = 0.5;   
   setPID.SetPoint   = 150;            //  Set PID Setpoint  

         }
         else if (InPut-setPID.SetPoint<20 ||InPut-setPID.SetPoint<-20)//距離近,PID參數(shù)相應(yīng)小一點(diǎn)
         {
         flag=2;
         PIDInit ( &setPID );                  //  Initialize Structure   
       setPID.Proportion = 2;              //  Set PID Coefficients   
       setPID.Integral   = 0.3;   
       setPID.Derivative = 0;   
       setPID.SetPoint   = 150;            //  Set PID Setpoint  
         }

      //  wait(0.05);  
        OutPut = PIDCalc ( &setPID,InPut );   //  Perform PID Interation   
        actuator ( OutPut );              //  Effect Needed Changes   
        printf("InPut=%d\n,Output=%d\n",InPut,OutPut );
       // wait(0.1);
      }   
}



效果還不錯(cuò)(手機(jī)錄像不行,改天補(bǔ)上視頻)。(控制器性能強(qiáng)大。主頻144M RAM 1M ROM 2M)基本沒(méi)有超調(diào),兩個(gè)震蕩周期就穩(wěn)定了。設(shè)定的目標(biāo)是150(測(cè)距傳感器返回值).小車在距離150很遠(yuǎn)時(shí)是100%的速度跑的。快接近150時(shí),速度馬上降得很快。第一次到150時(shí),會(huì)超前1cm左右,然后往回跑,逼近150時(shí),剛好停下,趨于穩(wěn)定。傳感器在149 150 151左右跳動(dòng)。小車也在不斷微調(diào)。反應(yīng)非常靈敏。最后基本上小車在+-1mm左右晃或者不動(dòng)的狀態(tài)。

我后面試過(guò)不用PID來(lái)做位置控制。也是可以,效果不好就是。震蕩比較劇烈。需要調(diào)整6 7表周期才會(huì)停到目標(biāo)點(diǎn)。沒(méi)有PID那么迅速 靈敏。
簡(jiǎn)單許多,代碼如下,非常簡(jiǎn)單。
distance=sensor1();
   NeedSpeed=distance-SetPoint;

   printf("distance=%d\n,NeedSpeed=%d\n",distance,NeedSpeed );
  Run(NeedSpeed,NeedSpeed);



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:113448 發(fā)表于 2016-4-15 23:41 | 只看該作者
回復(fù)

使用道具 舉報(bào)

板凳
ID:113448 發(fā)表于 2016-7-23 08:55 | 只看該作者
厲害
回復(fù)

使用道具 舉報(bào)

地板
ID:98249 發(fā)表于 2019-4-19 09:30 | 只看該作者
樓主思路清晰,功能完善學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 人人爽人人草 | 欧美日本在线观看 | 欧美中文一区 | 亚洲高清视频一区二区 | 日韩一二区在线 | 伊人网站| 久久久久久亚洲精品 | 日韩成人一区 | 日韩中文一区 | 国产精品久久久久久久免费大片 | 九九久久久 | 国产高清一区二区三区 | 欧美影院久久 | 色婷婷综合久久久中字幕精品久久 | 欧美一区二区三区久久精品 | 亚洲vs天堂 | 97国产精品视频 | 国产精品久久久久久久久久久久久 | 欧美激情久久久 | 久久com| 欧美黄页| 一级大黄色片 | 天天看逼 | 国产精品一区二区免费看 | 日韩精品一区二区三区视频播放 | 欧美日韩在线成人 | 在线中文字幕亚洲 | 在线观看成人 | 看片91| 欧美日韩在线免费 | 中文字幕国产视频 | 日日夜夜狠狠操 | 久久精品久久综合 | 高清黄色 | 亚洲精品视频一区 | 国产三级日本三级 | 国产精品久久久久久久久久久久冷 | 国产一区三区在线 | 自拍偷拍在线视频 | 日韩毛片网 | 中文字幕一区二区三区不卡在线 |