//2014年4月17日

//2014年6月20日入“未完毕”(未完毕)

//2014年6月21日

一開始还以为是多难的算法。事实上就是个渣渣。

当然PID实践中应该会非常难。

另外在理解PID时有点走了弯路,记载例如以下:

1.为什么比例控制会有稳态误差

关键在于我们要考虑的是“加速度的系统”。比方一个不停在散热的东西,而你要保持它的温度。

最后稳定在一部分散热的热量等于你比例控制的值!所以会有偏差。

2.为什么积分控制会解决稳态误差?积分控制为什么在达到目标值时还会调整?

一開始调整到目标值时积分控制的确还在进行调整,由于此时其历史误差总和不为0。

但这不是问题,关键是它调整中,历史误差总和会不断正负抵消,终于达到稳态。此时历史误差总和不为0,却正好抵消了系统的散热。

/*====================================================================================================
这是从网上找来的一个比較典型的PID处理程序,在使用单片机作为控制cpu时。请稍作简化,详细的PID
參数必须由详细对象通过实验确定。因为单片机的处理速度和ram资源的限制。一般不採用浮点数运算,
而将所有參数所实用整数,运算到最后再除以一个2的N次方数据(相当于移位),作相似定点数运算,可
大大提高运算速度。依据控制精度的不同要求。当精度要求非常高时,注意保留移位引起的“余数”。做好余
数补偿。这个程序仅仅是一般经常使用pid算法的基本架构。没有包括输入输出处理部分。
=====================================================================================================*/
#include <string.h>
#include <stdio.h>
/*====================================================================================================
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 {
double SetPoint; // 设定目标 Desired Value
double Proportion; // 比例常数 Proportional Const
double Integral; // 积分常数 Integral Const
double Derivative; // 微分常数 Derivative Const
double LastError; // Error[-1]
double PrevError; // Error[-2]
double SumError; // Sums of Errors
} PID;
/*====================================================================================================
PID计算部分
=====================================================================================================*/
double PIDCalc( PID *pp, double NextPoint )
{
double 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 // 微分项
);
}
/*====================================================================================================
Initialize PID Structure
=====================================================================================================*/
void PIDInit (PID *pp)
{
memset ( pp,0,sizeof(PID));
}
/*====================================================================================================
Main Program
=====================================================================================================*/
double sensor (void) // Dummy Sensor Function
{
return 100.0;
}
void actuator(double rDelta) // Dummy Actuator Function
{}
void main(void)
{
PID sPID; // PID Control Structure
double rOut; // PID Response (Output)
double rIn; // PID Feedback (Input)
PIDInit ( &sPID ); // Initialize Structure
sPID.Proportion = 0.5; // Set PID Coefficients
sPID.Integral = 0.5;
sPID.Derivative = 0.0;
sPID.SetPoint = 100.0; // Set PID Setpoint
for (;;) { // Mock Up of PID Processing
rIn = sensor (); // Read Input
rOut = PIDCalc ( &sPID,rIn ); // Perform PID Interation
actuator ( rOut ); // Effect Needed Changes
}
}

某学长的单片机程序(巡线,pid输入是传感器。pid输出到定时器)

<pre name="code" class="cpp">void SysTickHandler(void)
{
test=(~GPIOF->IDR);
test= (test&0x27ff);
if (test==1) //1
{ roadinfo=11 ;}
if (test==3) //1
{ roadinfo=10 ;}
if (test==2) //1
{ roadinfo=9 ;}
if (test==6) //1
{ roadinfo=8 ;}
if (test==4) //1
{ roadinfo=7 ;}
if (test==0xc) //1
{ roadinfo=6 ;}
if (test==0x8) //1
{ roadinfo=5 ;}
if (test==0x18) //1
{ roadinfo=4 ;}
if (test==0x10) //1
{ roadinfo=3;}
if (test==0x30) //1
{ roadinfo=2 ;}
if (test==0x20) //1
{ roadinfo=1 ;}
if (test==0x60) //1
{ roadinfo=0;}
if (test==0x40) //1
{ roadinfo=-1 ;}
if (test==0xc0) //1
{ roadinfo=-2 ;}
if (test==0x80) //1
{ roadinfo=-3 ;}
if (test==0x180) //1
{ roadinfo=-4 ;}
if (test==0x100) //1
{ roadinfo=-5 ;}
if (test==0x300) //1
{ roadinfo=-6 ;}
if (test==0x200) //1
{ roadinfo=-7 ;}
if (test==0x600) //1
{ roadinfo=-8 ;}
if (test==0x400) //1
{ roadinfo=-9 ;}
if (test==0x2400) //1
{ roadinfo=-10 ;}
if (test==0x2000) //1
{ roadinfo=-11 ;}
speedo2=800-roadinfo*kp-(roadinfo-pre_inof)*ki;
speedo3=800+roadinfo*kp+(roadinfo-pre_inof)*ki;
if(speedo2>max) {speedo2=max;}
if(speedo2<min) {speedo2=min;}
if(speedo3>max) {speedo3=max;}
if(speedo3<min) {speedo3=min;}
pre_inof=roadinfo; if(speedo2>0) { TIM4->CCR1=0; TIM3->CCR2= speedo2; }
if(speedo2<=0) { TIM4->CCR1=-speedo2; TIM3->CCR2=0; }
if(speedo3>0) { TIM3->CCR3= speedo3; TIM4->CCR2=0; }
if(speedo3<=0) { TIM3->CCR3=0; TIM4->CCR2=-speedo3; }
}


电子设计省赛--PID的更多相关文章

  1. 电子设计省赛--SPWM(死区时间)

    //2014年4月17日 //2014年6月20日入"未完毕" //2014年6月21日 有两种方案:双定时器和单定时器 学长表示双定时器输出波形不好,还是单定时器好. 原理例如以 ...

  2. 电子设计省赛--DMA与ADC

    //2014年4月17日 //2014年6月20日入"未完毕" //2014年6月21日 DMA可实现无需cpu控制中断的传输数据保存. 特别是ADC转换多个通道时要用到. 关键是 ...

  3. 2014年TI杯大学生电子设计竞赛地区赛使用仪器及器件、设备

     2014年TI杯大学生电子设计竞赛地区赛使用仪器及器件.设备 a)        3A/30V双路稳压电源(可并联): b)        60MHz示波器: c)        三位半数字万用 ...

  4. Nios程序烧写到EPCS方法 - 第1页 - asus119's Blog - EDN China电子设计技术

    Nios程序烧写到EPCS方法 - 第1页 - asus119's Blog - EDN China电子设计技术 这里主要是针对EP3C系列FPGA的Nios程序固化到EPCS中的方法做简要说明.硬件 ...

  5. 2014年湖北省TI杯大学生电子设计竞赛论文格式

    2014年湖北省TI杯大学生电子设计竞赛 B题:金属物体探測定位器(本科) 2014年8月15日 文件夹 1 系统方案 1.1 XXX的论证与选择........................... ...

  6. 2020 年TI 杯大学生电子设计竞赛E题总结(放大器非线性失真研究装置)

    2020年TI杯大学生电子设计竞赛E题总结(放大器非线性失真研究装置) 摘要:E题的竞赛内容主要是参赛者自己搭建一个晶体管放大器,能够产生不失真.顶部失真.底部失真.双向失真和交越失真五种波形,并分别 ...

  7. 【Arduino】2017年电子设计大赛B题 滚球控制系统|板球系统

    今年电赛我们队伍选择的是B题,滚球控制系统.最后我们得到了省特和国一,也算是了结了我大一时的心愿吧.下面对这次比赛进行一下总结,以后回忆起来的时候也有个念想. 滚球控制系统是一个多变量.非线性控制对象 ...

  8. SLAM+语音机器人DIY系列:(四)差分底盘设计——5.底盘PID控制参数整定

    摘要 运动底盘是移动机器人的重要组成部分,不像激光雷达.IMU.麦克风.音响.摄像头这些通用部件可以直接买到,很难买到通用的底盘.一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的:另一方面是因为 ...

  9. 【工具】【电子设计】超屌的 fritzing 新建元件

    fritzing 有多好,用了才知道,但是通常会遇到一个问题,他的元件库不一定够用,这时候就得自己做元件了,但是搜了一下网上没有相关的教程啊. 算了,去官网看英文吧.. 首先在最新版本不支持直接新建元 ...

随机推荐

  1. 1. node.js环境搭建 第一行代码

    一.NodeJs简介 NodeJS官网上的介绍: Node.js is a platform built on  Chrome's JavaScript runtime  for easily bui ...

  2. 解决Can’t finish GitHub sharing process Successfully created project ‘GitHubDemo’ on GitHub

    Can't finish GitHub sharing process        Successfully created project 'KeyWordsFrameWork' on GitHu ...

  3. 大数据学习——ip改成固定ip

    vi /etc/sysconfig/network-scripts/ifcfg-eth0 修改BOOTPROTO为static 添加IPADDR=192.168.74.100 添加NETMASK=25 ...

  4. Java高级程序员面试题

    1.你认为项目中最重要的过程是那些? 分析.设计阶段  尽量找出进度的优先级 2.如果给你一个4-6人的team,怎么分配? 挑选一技术过硬的人作为我的替补.其它人平均分配任务,每周进行全面的任务分配 ...

  5. hust训练赛20160330--B - 又见LKity

    Problem 2122 又见LKity Time Limit: 1000 mSec Memory Limit : 32768 KB  Problem Description 嗨!大家好,在Templ ...

  6. LA 3890 半平面交

    二分查询答案,判断每一个新形成的向量合在一块能否形成半平面交 #include <iostream> #include <cstdio> #include <cstrin ...

  7. CodeForces - 586D Phillip and Trains

    这道题是一道搜索题 但是 如果没有读懂或者 或者拐过弯 就很麻烦 最多26个火车 那么每一个周期 (人走一次 车走一次) 就要更改地图 的状态 而且操作复杂 容易超时 出错 利用相对运动 计周期为 人 ...

  8. Flex设置PopUpManager创建modal(模态)窗口的背景样式

    有一个需求 , 使用PopUpManager弹出的窗口modal模式不可操作的地方颜色太浅, 这样弹出的窗口就不够突出, 搜了下没发现解决办法, 翻看了PopUpManagerImpl源码 , 找到了 ...

  9. Delphi字符串加密/解密

    unit uEncrypt_Decrypt;   interface   uses SysUtils;   const XorKey: array[0..7] of Byte = ($B2, $09, ...

  10. T1365 浴火银河星际跳跃 codevs

    http://codevs.cn/problem/1365/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 小 K 又在玩浴 ...