PID控制器(比例-积分-微分控制器)- V
Linear Actuator - PID Control
Introduction
This application guide is designed to explain the basics of PID control and how to implement a basic control loop using Phidgets.
Once implemented, the control loop will allow the linear actuator to move to a precise position and remain there, even if an external force tries to move it.
PID Control Basics
Proportional Control
The goal of a control loop is to use data from the feedback device (in this case, the potentiometer) to iteratively adjust the output
until it has reached the target value.
For example, consider this simple control loop (This code would be used in the sensor change event handler):
DutyCycle = TargetPosition - ActualPosition;
if (DutyCycle > )
DutyCycle = ;
if (DutyCycle < -)
DutyCycle = -;
Whenever the potentiometer value (ActualPosition) changes, the event handler triggers and updates the Duty Cycle of the motor.
Eventually, this will result in the motor reaching its target. The following table further illustrates how this works:
This diagram illustrates the flow of the simple control loop being implemented.
The function PID() is called, which sets a new duty cycle, which causes the actuator to move.
Eight milliseconds later, the potentiometer that keeps track of how far the actuator has extended causes an analog input change event,
which in turn calls PID() again. The cycle continues until the target position is reached.
The type of control we've just implemented here is called Proportional control,
because the output is directly proportional to the error.
We can multiply (TargetPosition - ActualPosition) by a gain value if we want to control how the control loop behaves when it gets close to the target.
A lower value (i.e. less than 1) will result in a more gradual reduction in speed as the actuator reaches its target position,
while a larger value will result in a sharper, quicker response.
We'll call this value the proportional gain, or Kp for short.
If the proportional gain is set too high, the actuator will overshoot the target position and oscillate back and forth around the target.
While we've gained basic control of the actuator position, there are still some problems with purely proportional control.
You may find that the actuator never quite reaches the target position, especially with a low proportional gain.
Also, if the load on the actuator changes while it's moving, it won't be able to react to the difference.
To solve these problems, we need an integral term.
Integral Control
The purpose of the integral term in a control loop is to look back at all of the past error
and accumulate it into an offset that the control loop can use.
Combined with our proportional control loop, it will be able to react to changes in load and land closer
to the target position if we choose our gain values properly.
dt = 0.008;
error = TargetPosition - ActualPosition;
DutyCycle = (Kp * error) + (Ki * integral); if (DutyCycle > )
DutyCycle = ;
else if (DutyCycle < -)
DutyCycle = -;
else
integral += (error * dt);
Where dt is the change in time between iterations of the control loop.
For this example, dt is set to 0.008 seconds, which is the update rate of the analog input.
The integral is only accumulated when the duty cycle isn't saturated at 100% or -100%.
This prevents the control loop from needlessly accumulating the integral when it's already running at maximum velocity.
Now we have two control gains: Kp and Ki.
Kp still functions as it did in the proportional example, and Ki controls how influential the integral term is.
Increasing the integral gain will cause the control loop to reach the target faster,
and ensure that you hit the exact target rather than settling to a value close to the target.
Just like the proportional gain, increasing the integral gain too much can cause instability.
After tweaking the control gains, you may find that PI control is sufficient for your application.
If you're having trouble finding control gains that provide the results you're looking for, y
ou can implement full PID control by adding the derivative term.
Derivative Control
Derivative control looks at past errors in the system and calculates the slope of those errors to predict future error values.
Adding derivative control should add stability to the system and increase the control we have over it by adding another gain value.
dt = 0.008;
error = TargetPosition - ActualPosition;
DutyCycle = (Kp * error) + (Ki * integral) + (Kd * derivative); if (DutyCycle > )
DutyCycle = ;
else if (DutyCycle < -)
DutyCycle = -;
else
integral += (error * dt); derivative = (error - errorlast)/dt;
Where errorlast is the error value a set number of samples ago.
In an application such as this, an error value from around 64 samples ago (0.5 seconds) should suffice.
Just as before, we can now use Kd to modify the weight of this new derivative term.
Increasing Kd should smooth things out and increase stability,
but you'll find that it should be kept small in comparison to the other control gains
or it will cause the control to oscillate when it's near the target.
Sample Program
You can download the sample program written for this guide via the link below. This is a Visual C# project.
Controls and Settings
- These boxes contain the information of the attached motor controller. If these boxes are blank, it means the controller object didn't successfully attach.
- These boxes control which motor output and analog input are being used, and allow you to set each of the control gains. You can click on the "?" icon in the top right for more information on a particular setting. Changes will not take effect until the "Start" button is hit.
- These boxes display the target position set by the slider and the actual position according to the feedback potentiometer. The error is the difference between these two values, and the output velocity is the duty cycle of the controller as dictated by the control loop.
- The maximum velocity slider controls the maximum duty cycle that the controller will output. It is unrestricted (100%) by default.
- This slider selects the target position, from 1 to 1000 sensorvalue of the feedback potentiometer.
- Pressing the start button will initiate the control loop and the actuator will begin to move toward the target position. If the actuator does not move, check your power and connections.
- These settings are for actuators whose potentiometers don't span the full range of 0-5V (0 - 1000 sensorvalue). Experiment with your actuator to discover the potentiometer's limits.
- This graph will plot the motor's position and the target position over time.
Algorithm
The PID control algorithm in this sample program operates by setting up a change handler for the analog input connected
to the feedback potentiometer that calls an external function.
This function computes the PID control loop output as briefly described in the previous section.
By changing the output, the motor's duty cycle is set and the function will be called again the next time the sensor change handler triggers
(in 0.008 seconds, because the sampling period of an analog input is 8ms).
This loop will continue until the output of the control loop is zero, at which point the sensor change event will no longer trigger.
// This is the event handler for the attached feedback sensor
void actuator_SensorUpdate(object sender, SensorUpdateEventArgs e)
{
// If the selected sensor input is the one that triggered this handler,
if ((e.Index == && analogCmb.Text == "") || (e.Index == && analogCmb.Text == ""))
{
//Store sensor value in global variable
feedback = e.Value; //Run the PID loop
if (started)
{
PID();
} //Update the motor controller with the new duty cycle
actuator.motors[Convert.ToInt32(motorCmb.Text)].Velocity = Math.Round(output);
}
}
It's always a good idea to keep your event handlers as small and optimized as possible to avoid missing events.
In this sample program, all of the complexity of the PID algorithm is tucked away in the function "PID( )".
The PID() function:
- Updates error variables
- Checks to see if the actuator has reached its target (and if it has, stops the loop)
- Updates the the output (duty cycle) of the control loop
- Limits the duty cycle to the specified output limit
- Updates the derivative variable
In the downloadable example, this function also updates the graph and all of the text boxes that track the variables.
These lines were removed from the excerpt below for increased readability.
// This function does the control system calculations and sets output to the duty cycle that the motor needs to run at.
void PID()
{
// Calculate how far we are from the target
errorlast = error;
error = input - feedback; // If the error is within the specified deadband, and the motor is moving slowly enough,
// Or if the motor's target is a physical limit and that limit is hit (within deadband margins),
if ((Math.Abs(error) <= deadBand && Math.Abs(output) < )
|| (input < (deadBand + + (double)svMinTxt.Value) && feedback < (deadBand + + (double)svMinTxt.Value))
|| (input > ((double)svMaxTxt.Value - ( + deadBand)) && feedback > ((double)svMaxTxt.Value - ( + deadBand))))
{
// Stop the motor
output = ;
error = ;
}
else
{
// Else, update motor duty cycle with the newest output value
// This equation is a simple PID control loop
output = ((Kp * error) + (Ki * integral)) + (Kd * derivative);
errorTxt.Text = error.ToString();
} //Prevent output value from exceeding maximum output specified by user, otherwise accumulate the integral
if (output >= maxOutput)
output = maxOutput;
else if (output <= -maxOutput)
output = -maxOutput;
else
integral += (error * dt); derivative = (error - errorlast) / dt;
}
PID控制器(比例-积分-微分控制器)- V的更多相关文章
- PID控制器(比例-积分-微分控制器)- I
形象解释PID算法 小明接到这样一个任务: 有一个水缸点漏水(而且漏水的速度还不一定固定不变),要求水面高度维持在某个位置,一旦发现水面高度低于要求位置,就要往水缸里加水. 小明接到任务后就一直守在水 ...
- PID控制器(比例-积分-微分控制器)- IV
调节/测量放大电路电路图:PID控制电路图 如图是PlD控制电路,即比例(P).积分(I).微分(D)控制电路. A1构成的比例电路与环路增益有关,调节RP1,可使反相器的增益在0·5一∞范围内变化; ...
- PID控制器(比例-积分-微分控制器)- II
Table of Contents Practical Process Control Proven Methods and Best Practices for Automatic PID Cont ...
- PID控制器(比例-积分-微分控制器)- III
PID Controller Algorithms Controller manufacturers arrange the Proportional, Integral and Derivative ...
- [Fundamental of Power Electronics]-PART II-9. 控制器设计-9.5 控制器的设计
9.5 控制器设计 现在让我们来考虑如何设计控制器系统,来满足有关抑制扰动,瞬态响应以及稳定性的规范或者说设计目标.典型的直流控制器设计可以用以下规范定义: 1.负载电流变化对输出电压调节的影响.当负 ...
- .NET/ASP.NET MVC Controller 控制器(深入解析控制器运行原理)
阅读目录: 1.开篇介绍 2.ASP.NETMVC Controller 控制器的入口(Controller的执行流程) 3.ASP.NETMVC Controller 控制器的入口(Controll ...
- 创建控制器的方法、控制器加载view过程、控制器view的生命周期、多控制器组合
在介绍四大对象的那篇博客中,可以基本了解到程序启动的过程: main-->UIApplicationMain-->创建UIApplication的实例和app代理AppDelegate的实 ...
- 集合视图控制器(CollectionViewController) 、 标签控制器(TabBarController) 、 高级控件介绍
1 创建集合视图,设置相关属性以满足要求 1.1 问题 集合视图控制器UIConllectionViewController是一个展示大量数据的控制器,系统默认管理着一个集合视图UICollectio ...
- 【iOS开发-21】UINavigationController导航控制器初始化,导航控制器栈的push和pop跳转理解
(1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最以下,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...
随机推荐
- springMVC3学习--ModelAndView对象(转)
原文链接:springMVC3学习(二)--ModelAndView对象 当控制器处理完请求时,通常会将包含视图名称或视图对象以及一些模型属性的ModelAndView对象返回到DispatcherS ...
- ASP.NET Identity详解
Asp.Net Identiy是ASP.NET身份验证机制. 如何构建安全的Web应用? 我们先来思考一个问题:如何构建安全的WEB应用? 一直以来,这都是比较热门的话题.不幸的是,目前还没有一种 ...
- python全栈开发day44-js、DOM、BOM
JS的三大部分 一.ECMAJavaScript基础语法: 1.javascript的引入方式 1) 行内式 <script> alert(1) </script> 2) 引入 ...
- django 10.5 sqlite3迁移到mysql
参考: http://www.voidcn.com/article/p-hesvaooz-ru.html 原文: python ./manage.py syncdb --database slave ...
- Codeforces 924D Contact ATC (看题解)
Contact ATC 我跑去列方程, 然后就gg了... 我们计每个飞机最早到达时间为L[ i ], 最晚到达时间为R[ i ], 对于面对面飞行的一对飞机, 只要他们的时间有交集则必定满足条件. ...
- 6.Django与Ajax
Ajax 文件夹为Ajaxdemo 向服务器发送请求的途径: 1.浏览器地址栏,默认get请求: 2.form表单: get请求 post请求 3.a标签,超链接(get请求) 4.Ajax请求 特点 ...
- 洛谷 P1507 NASA的食物计划 【二维费用背包】 || 【DFS】
题目链接:https://www.luogu.org/problemnew/show/P1507 题目背景 NASA(美国航空航天局)因为航天飞机的隔热瓦等其他安全技术问题一直大伤脑筋,因此在各方压力 ...
- python 中的可变对象与不可变对象
近日辞职待工,没有实际的项目与大家分享.暂写写在实际运用python中遇到的关于可变对象和不可变对象的坑. 首先我们需要明确一个概念,在python中一且皆对象.我们一般定义一个变量a=0,其实质a是 ...
- JS高级-原型等概念深入理解
一 数据类型: 基本(值)数据类型: string number undefined null boolean 对象(引用)类型 [ 查找对象的属性时,会查找原型链 设置属性时,一般在构造函数里面设置 ...
- hql查询后释放内存
Session session=getSession(); //进行session查询,取得前16个数据 Query q=session.createQuery(hql).setFirstResult ...