Implementing PID Control Algorithms


Table of Contents

Introduction 3

Purpose 3

Scope 3

References 3

PID Control Algorithms 3

PID Controller Interaction with an Algorithm Component 3

PID Controller Interaction with Algorithm Component Property Pages 3

The Algorithm Component Module 3

IPIDAlgorithm Interface 3

Methods 3

IDL Definition 3

IPIDAlgorithm::SetPIDParameters method 3

IPIDAlgorithm::CalculatePID method 3

IPIDAlgorithm::StartPIDAutomatic method 3

IPIDAlgorithm::LoadExtraPIDParamaters method 3

IPIDAlgorithm::SaveExtraPIDParamaters method 3

Implementing a PID Algorithm 3

Development Environment 3

Sample Algorithm 3

Create an ATL DLL Server 3

Add a Simple Object 3

Add Support for IPIDAlgorithm 3

Implement IPIDAlgorithm Interface 3

Add Non-Standard Properties 3

Add the Algorithm to CATID_PIDAlgorithm Component Category 3

Test the Algorithm 3

Add Property Page Support 3

Test the Algorithm Property Page 3

Conclusion 3

Introduction

The PID Controller application currently supports two PID Algorithms (Position and Velocity). These algorithms are documented in the User Manual. There is much contention in the industry about the effectiveness of different PID algorithms. Some algorithms are better suited to certain types of control environments.

Therefore it is desirable that the PID Controller system be designed so that different algorithms could be swapped in or out by the user without having to change or recompile any of the systems code.

Purpose

This document describes how the system was designed to support different PID algorithms and how to implement your own algorithm.

Scope

This document concentrates on implementing/coding a PID algorithm component. It does not discuss the merits of different algorithms. This document assumes that the reader is familiar with Microsoft’s Component Object Model (COM) and has some experience with implementing COM objects using Visual C++/ATL.

References

For more information on COM check the following references:

  1. Microsoft Developer Network Library.
  1. http://www.microsoft.com/cominfo/.
  1. Essential COM, Don Box, ISBN 0-201-63446-5, Addison-Wesley.
  1. Inside OLE - 2nd Edition, Kraig Brockschmidt, ISBN 1-55615-843-2, Microsoft Press.
  1. Beginning ATL COM Programming, Grimes, Stockton & Templeman, ISBN: 1-861000-11-1, Wrox Press.


PID Control Algorithms

This section describes how the algorithm mechanism works within the current system, and documents the required interfaces for such a mechanism to work.

PID Controller Interaction with an Algorithm Component

The Component Object Model (COM) is a software architecture that allows the components made by different software vendors to be combined into a variety of applications. COM defines a standard for component interoperability, is not dependent on any particular programming language, is available on multiple platforms, and is extensible. Using COM technology we were able to design a PID Controller system that allows users to replace or add new algorithms.

The PID Controller interfaces to all algorithms through a COM custom interface called IPIDAlgorithm (defined below). This interfaces provides the PID runtime with the ability to set standard PID parameters such as Setpoint, Kp, Ki and Kd. Every PID algorithm component must support this interface.

The PID System interacts with an algorithm component in the following ways:

  1. When the system is enabled the runtime reads in all configured loops from disk. For each loop it creates an instance of the configured algorithm component. The runtime then queries the algorithm component for its IPIDAlgorithm interface.
  1. Each algorithm component is then asked to load its extra parameters when the runtime calls IPIDAlgorithm::LoadExtraPIDParameters. At this stage the component can read in any non-standard properties.
  1. The runtime will then perform some calculations (e.g. calculate sample period) and then sets the standard parameters for each algorithm component by calling IPIDAlgorithm::SetPIDParameters.
  1. If the loop moves from manual to automatic mode, the runtime will call IPIDAlgorithm:: StartPIDAutomatic. It is used to prevent integral windup.
  1. As each automatic loop runs, the runtime calls IPIDAlgorithm::CalculatePID to calculate the current PID output value, based on the configured PID properties. The output channels are then driven.
  1. When a user saves parameters for a loop to disk, the PID Configuration and Monitoring application calls IPIDAlgorithm::SaveExtraPIDParameters to save the non-standard parameters to disk.

PID Controller Interaction with Algorithm Component Property Pages

Because of the extensible nature of COM, you can implement your own properties and methods on an algorithm component using other interfaces (which you define). Support is provided for editing these non-standard properties through the use of OLE/COM Property Pages and the Edit|Extra Algorithm Properties command in the PID Configuration and Monitoring application.

Property pages allow a COM object user to view and change COM object properties. Invoking an object’s properties dialog box accesses these properties. This dialog box contains one or more property pages that provide a customized, graphical interface for viewing and editing the object properties. The PID Configuration and Monitoring application acts as a container that can display its own modeless dialog box that shows the property pages of the selected algorithm object.

The Algorithm component can support non-standard properties and methods by implementing its own custom interface (E.g. IMyAlgorithm). Algorithm components support visual editing of properties using property pages by implementing the ISpecifyPropertyPages interface.

Each property page supported by the object must support the IPropertyPage and IPropertyPage2 interfaces. The COM interfaces, ISpecifyPropertyPages, IPropertyPage and IPropertyPage2 are documented by Microsoft.

1.  When a loop document is opened in the configuration and monitoring application, its configuration is read from disk. The application creates an instance of the configured algorithm component.

2.  When the user chooses the Edit|Extra Algorithm Properties command the algorithm component is queried for the ISpecifyPropertyPages interface.

3.  If the object does not support the ISpecifyPropertyPages interface the user is notified and the sequence ends.

4.  Otherwise the application calls ISpecifyPropertyPages::GetPages to retrieve the CLSID of each supported property page.

5.  The application then displays its own property sheet. It then creates and displays an instance of each supported property page for the object. The user can then change any non-standard properties and save them to disk using the File|Save command.

The Algorithm Component Module

The following diagram shows the interfaces that a PID algorithm component should implement:

The Algorithm component should be implemented as an in-proc server (DLL).

An algorithm module advertises that it supports a PID algorithm by registering support for the Component Category CATID_PIDAlgorithm (see COM documentation for discussion of component categories). The PIDAlgorithm category is defined as:

HKEY_CLASSES_ROOT\Component Categories\{5D8839D5-EFF2-11D1-8329-006097C787F8}

IPIDAlgorithm Interface

The IPIDAlgorithm is described below:

Methods

HRESULT SetPIDParameters

This method sets the standard paramaters for the PID calculation

HRESULT CalculatePID

This method calculates the current PID output value, based on the configured PID properties.

HRESULT StartPIDAutomatic

This method is called when the control loop moves from manual to automatic mode. It is used to prevent integral windup.

HRESULT LoadExtraPIDParameters

This method reads in any non-standard PID parameters from a persistent stream.

HRESULT SaveExtraPIDParameters

This method writes out any non-standard PID parameters to a persistent stream.

IDL Definition

typedef enum DeadZoneType

{

Positive,

Negative,

PositiveAndNegative

}

DEADZONETYPE;

[

object,

uuid(B3F2A2E4-E4F1-11d1-831B-006097C787F8),

pointer_default(unique)

]

interface IPIDAlgorithm : IUnknown

{

HRESULT SetPIDParameters(

[in] float SetPoint,

[in] float SteadyState,

[in] float Kp,

[in] float Ki,

[in] float Kd,

[in] float SampleRate,

[in] BOOL InputHiLimitsOn,

[in] BOOL InputLoLimitsOn,

[in] float InputLoLimit,

[in] float InputHighLimit,

[in] float Filter,

[in] float OutputLoLimit,

[in] float OutputHiLimit,

[in] float ROC,

[in] BOOL DeadZoneOn,

[in] float DeadZoneValue,

[in] DEADZONETYPE DeadZoneType,

[in] BOOL bPIDInvertedOutput);

HRESULT CalculatePID([in] float InputValue,

[out,retval] float *OutputValue);

HRESULT StartPIDAutomatic([in] float InputValue,

[in] float OutputValue);

HRESULT LoadExtraPIDParamaters([in] IStream *PIDStream);

HRESULT SaveExtraPIDParamaters([in] IStream *PIDStream);

};

IPIDAlgorithm::SetPIDParameters method

HRESULT SetPIDParameters(

[in] float SetPoint,

[in] float SteadyState,

[in] float Kp,

[in] float Ki,

[in] float Kd,

[in] float SampleRate,

[in] BOOL InputHiLimitsOn,

[in] BOOL InputLoLimitsOn,

[in] float InputLoLimit,

[in] float InputHighLimit,

[in] float Filter,

[in] float OutputLoLimit,

[in] float OutputHiLimit,

[in] float ROC,

[in] BOOL DeadZoneOn,

[in] float DeadZoneValue,

[in] DEADZONETYPE DeadZoneType,

[in] BOOL PIDInvertedOutput )

This method sets the standard parameters for the PID calculation

Return Value / Description
S_OK / Success
E_INVALIDARG / Invalid argument

Parameters

SetPoint

The PID setpoint value.

SteadyState

Steady state output value.

Kp

The PID porportional gain constant.

Ki

The PID integral time constant.

Kd

The PID derivative time constant.

SampleRate

The measured variable sample period in minutes per sample. For example, if the controller's output is calculated two times a second, the value of this parameter is 1 / (2 * 60) = 0.0084 minutes.

InputHiLimitsOn

Flag for high limiting inputs. Set to TRUE if youn want high output limiting on.

InputLoLimitsOn

Flag for low limiting inputs. Set to TRUE if youn want low output limiting on.

InputLoLimit

The value corresponding to the low range of the input variable.

InputHighLimit

The value corresponding to the high range of the input variable.

Filter

The PID filter constant can be used to reduce the amount of noise present in PID input measurements. A value in the range 0.0 to 1.0, affecting the filtering of the noisy measurement signal. A value of 0.0 means that no filtering will take place. The filtering effect is maximal when value is 1.0. The formula for filtering is:

Filtered value = (1.0 - value) * Measured value + value * (Previous filtered value)

OutputLoLimit

The value corresponding to the low range of the output variable.

OutputHiLimit

The value corresponding to the high range of the output variable.

ROC

Rate of change output limit value.

DeadZoneOn

Flag for Deadzone limiting. Set to TRUE if youn want low deadzone limiting on.

DeadZoneValue

The value around the setpoint at which no control takes place.

DeadZoneType

The sign of the dead zone value (+, -, +-).

PIDInvertedOutput

Inverts the PID output response to an increase in the measurement variable input. Specifies the direction of change of PID output relative to measurement. If TRUE, the direction of change is the same. Normally this parameter should be set to FALSE (opposite directions).

IPIDAlgorithm::CalculatePID method

HRESULT CalculatePID([in] float InputValue, [out, retval] float* OutputValue)

This method calculates the current PID output value, based on the current state of the PID properties.

Return Value / Description
S_OK / Success
S_FALSE / No control took place due to deadzone, maths error etc.
E_INVALIDARG / Invalid argument

Parameters

InputValue

Current value of the measurement (process channel).

OutputValue

Address of the PID output value.

IPIDAlgorithm::StartPIDAutomatic method

HRESULT StartPIDAutomatic([in] float InputValue, [in] float OutputValue)

This method is called when the control loop moves from manual to automatic mode. It is used to prevent integral windup.

Return Value / Description
S_OK / Success
E_INVALIDARG / Invalid argument

Parameters

InputValue

Current value of the measurement (process channel).

OutputValue

Current PID output value.

IPIDAlgorithm::LoadExtraPIDParamaters method

HRESULT LoadExtraPIDParamaters([in] IStream * PIDStream)

This method reads any non-standard PID parameters from a stream.

Return Value / Description
S_OK / Success
S_FALSE / The data could not be read from the stream object.
STG_E_ACCESSDENIED / The caller does not have sufficient permissions for writing to this stream object.
STG_E_INVALIDPOINTER / One of the pointer values is invalid. The PIDStream parameter must contain a valid pointer even if cb is zero.

Parameters

PIDStream

A pointer to the stream to read from.

IPIDAlgorithm::SaveExtraPIDParamaters method

HRESULT SaveExtraPIDParamaters([in] IStream * PIDStream)

This method writes any non-standard PID parameters to a stream.

Return Value / Description
S_OK / Success
STG_E_MEDIUMFULL / The write operation was not completed because there is no space left on the storage device
STG_E_ACCESSDENIED / The caller does not have sufficient permissions for writing to this stream object.
STG_E_CANTSAVE / Data cannot be written for reasons other than no access or space.
STG_E_INVALIDPOINTER / One of the pointer values is invalid. The PIDStream parameter must contain a valid pointer even if cb is zero.
STG_E_WRITEFAULT / The write operation was not completed due to a disk error

Parameters

PIDStream

A pointer to the stream to write to.

Implementing a PID Algorithm

This section describes how the implement your own algorithm.

Development Environment

The algorithms that are shipped with the PID Controller were built with the following tools and environment:

§  Microsoft Windows NT 4.0 (Service Pack 3).

§  Microsoft Visual C++ (Visual Studio Service Pack 3).

§  Microsoft Active Template Library (Version 2.2).

§  Microsoft Platfrm SDK (Jan 98 Release).

Sample Algorithm

In this section we will go through the steps required to implement a sample algorithm.

Create an ATL DLL Server

The first thing to do is to create a new ATL DLL Server. Start Visual C++ and select the File|New menu command. You will be presented with the following dialog box. Select to the Projects Tab click on ATL COM AppWizard. We will call our new project PIDSample. Type PIDSample in the project name edit box, choose a location for you project and click on OK.

The ATL COM AppWizard will present the following dialog. Select the Dynamic link Library (DLL) Radion button and click the Allow merging of proxy/stub code check box on.

Click on the Finish button and then click OK to complete the operation. This has created a skeleton DLL for you. This DLL will be the COM server for the algorithm component.

The next step is to create a COM component that will function as a PID algorithm. We will build a simple object that supports the IPIDAlgorithm interface. Property page support will be added later.

Click on the New ATL Object button from the ATL toolbar.

Add a Simple Object

You will be presented with the following dialog box. Select the Objects entry from the left-hand side and then select the Simple Object entry from the right hand side.