Uploaded by Samuel Yu Liu

Advanced Pulverizer Control - Design and Testbed Implementation

advertisement
Advanced Pulverizer Control
Design and Testbed Implementation
Technical Report
Advanced Pulverizer Control
Design and Testbed Implementation
1004423
Final Report, March 2004
EPRI Project Manager
R. Torok
EPRI • 3412 Hillview Avenue, Palo Alto, California 94304 • PO Box 10412, Palo Alto, California 94303 • USA
800.313.3774 • 650.855.2121 • askepri@epri.com • www.epri.com
DISCLAIMER OF WARRANTIES AND LIMITATION OF LIABILITIES
THIS DOCUMENT WAS PREPARED BY THE ORGANIZATION(S) NAMED BELOW AS AN
ACCOUNT OF WORK SPONSORED OR COSPONSORED BY THE ELECTRIC POWER RESEARCH
INSTITUTE, INC. (EPRI). NEITHER EPRI, ANY MEMBER OF EPRI, ANY COSPONSOR, THE
ORGANIZATION(S) BELOW, NOR ANY PERSON ACTING ON BEHALF OF ANY OF THEM:
(A) MAKES ANY WARRANTY OR REPRESENTATION WHATSOEVER, EXPRESS OR IMPLIED, (I)
WITH RESPECT TO THE USE OF ANY INFORMATION, APPARATUS, METHOD, PROCESS, OR
SIMILAR ITEM DISCLOSED IN THIS DOCUMENT, INCLUDING MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, OR (II) THAT SUCH USE DOES NOT INFRINGE ON OR
INTERFERE WITH PRIVATELY OWNED RIGHTS, INCLUDING ANY PARTY'S INTELLECTUAL
PROPERTY, OR (III) THAT THIS DOCUMENT IS SUITABLE TO ANY PARTICULAR USER'S
CIRCUMSTANCE; OR
(B) ASSUMES RESPONSIBILITY FOR ANY DAMAGES OR OTHER LIABILITY WHATSOEVER
(INCLUDING ANY CONSEQUENTIAL DAMAGES, EVEN IF EPRI OR ANY EPRI REPRESENTATIVE
HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES) RESULTING FROM YOUR
SELECTION OR USE OF THIS DOCUMENT OR ANY INFORMATION, APPARATUS, METHOD,
PROCESS, OR SIMILAR ITEM DISCLOSED IN THIS DOCUMENT.
ORGANIZATION(S) THAT PREPARED THIS DOCUMENT
EPRI Instrumentation and Control Center
Arizona State University
ORDERING INFORMATION
Requests for copies of this report should be directed to EPRI Orders and Conferences, 1355 Willow
Way, Suite 278, Concord, CA 94520, (800) 313-3774, press 2 or internally x5379, (925) 609-9169,
(925) 609-1310 (fax).
Electric Power Research Institute and EPRI are registered service marks of the Electric Power
Research Institute, Inc. EPRI. ELECTRIFY THE WORLD is a service mark of the Electric Power
Research Institute, Inc.
Copyright © 2004 Electric Power Research Institute, Inc. All rights reserved.
CITATIONS
This report was prepared by
EPRI Instrumentation and Control Center
714 Swan Pond Road
Harriman, TN 37922
Principal Investigators
C. Taft
P. Wolff
Arizona State University
Electrical Engineering
Box 875706
Tempe, Arizona 85287
Principal Investigator
K. Tsakalis
This report describes research sponsored by EPRI.
The report is a corporate document that should be cited in the literature in the following manner:
Advanced Pulverizer Control: Design and Testbed Implementation, EPRI, Palo Alto, CA: 2004.
1004423.
iii
PRODUCT DESCRIPTION
Coal pulverizers play an important role in all aspects of power plant performance including
availability, efficiency, and responsiveness. In relationship to dynamic response, pulverizer
control often limits a plant’s maximum load rate-of-change. EPRI has been investigating the use
of advanced multivariable control techniques on several plant subsystems and in this project is
developing an advanced pulverizer control system. The ultimate goal is to design, implement,
and test an advanced control system on an actual plant pulverizer. Before an advanced control
system can be implemented on an actual plant, its operation must be demonstrated in a
simulation environment. This report describes the development and checkout of a prototype
advanced pulverizer control system, including model enhancement and verification, robust
control design, and simulator implementation and testing.
Results & Findings
The advanced pulverizer control system, which was initially developed in the MATLAB
environment, was successfully converted to a C program and implemented on the EPRI I&C
Center testbed. The new control system demonstrated accurate tracking and bumpless transfer
with the existing conventional control system. This result means that the development of the
operational prototype is completed, and the system is ready for implementation and testing on an
actual plant.
Challenges & Objectives
Researchers and power producers interested in advanced control applications for power plants
will find this report useful and informative. In particular, the section on implementation on the
I&C Center testbed provides insight on real world issues involved with moving advanced control
technologies from the classroom to the plant. The remaining challenge for the prototype system
is the actual plant implementation and testing.
Applications, Values & Use
Improved pulverizer control has the potential to increase overall plant responsiveness at many
plants. Improved control is becoming more important as the power industry becomes more
deregulated and flexible operation capabilities, including load following and two-shift operation,
are at a premium to better meet the demands of competitive markets. Other EPRI studies have
shown there is considerable financial benefit for many units from improved response and the
resulting increased participation in the ancillary services markets.
v
EPRI Perspective
EPRI has been investigating the use of advanced control techniques for several years, effectively
acting as a bridge between academia and the power industry by developing and demonstrating
practical solutions based on new theoretical approaches. Advanced control techniques have
shown excellent performance in other industries on difficult control problems. Many aspects of
boiler system control are inherently multivariable, and so it is reasonable to expect the advanced
control methods to provide improved performance over conventional PID (Proportional, Integral,
Derivative) based control systems. The advanced pulverizer control project is one of several
studies currently underway that are attempting to compare advanced control system performance
against conventional control performance. The studies are also identifying and solving real world
implementation issues arising from the integration of advanced control systems into commercial
distributed control systems. These studies will encourage the use of advanced control systems on
power plants and provide guidance on where their use is most beneficial.
Approach
This report describes in some detail the modeling enhancements, controller design, and controller
implementation work on the advanced pulverizer control system. The project used an H-infinity
control approach with a process model based on actual plant data, and controller functional
testing performed in simulation environments. The discussion is not highly theoretical and
should be understandable by anyone familiar with pulverizer control.
Keywords
Pulverizer
Advanced control
Robust control
vi
ABSTRACT
Precise and responsive coal pulverizer control is important to power plant operators today more
than ever, due to tightening environmental constraints and increased competition. EPRI is
studying advanced multivariable pulverizer control to better understand the technology and its
performance benefits compared to conventional PID-based control strategies. In previous years,
a mathematical model of the pulverizer was developed and initial advanced control designs were
completed. This report describes modifications made to the model to incorporate the primary air
flow system into the model and the redesign of the advanced controller using the improved
model. Implementation of the advanced controller on the EPRI I&C Center testbed is also
described. A C program listing of the advanced controller is provided in the appendix.
vii
CONTENTS
1 INTRODUCTION....................................................................................................... 1-1
2 ADDING PRIMARY AIR FLOW SYSTEM TO MODEL ............................................ 2-1
Description of Primary Air Flow Model in Pulverizer Model...................................... 2-1
Model Validation ...................................................................................................... 2-5
3 CONTROL DESIGN FOR MODIFIED MODEL ......................................................... 3-1
Introduction .............................................................................................................. 3-1
Identification of a Linear Model ................................................................................ 3-1
Comments on the Linear Control Model .................................................................. 3-2
Controller Design Notes ........................................................................................... 3-3
Controller Implementation in Simulink...................................................................... 3-5
4 CONTROLLER IMPLEMENTATION ON EPRI I&C CENTER TESTBED ................ 4-1
EPRI I&C Center Testbed ........................................................................................ 4-1
Advanced Controller C Program .............................................................................. 4-3
Program Structure ............................................................................................... 4-4
Modifications to the Existing Foxboro Logic ............................................................. 4-5
Operator Interface Design........................................................................................ 4-7
Bumpless Transfer Testing ...................................................................................... 4-9
5 SUMMARY AND CONCLUSIONS............................................................................ 5-1
6 REFERENCES.......................................................................................................... 6-1
A CONTROLLER C PROGRAM LISTING ................................................................. A-1
ix
LIST OF FIGURES
Figure 1-1 Pulverizer Model Regions ...................................................................................... 1-2
Figure 2-1 Simulink Block Diagram of Primary Air Flow Model................................................ 2-4
Figure 2-2 Complete Pulverizer Simulink Block Diagram ........................................................ 2-5
Figure 2-3 Comparison of Plant and Model Data (50 klb/hr = 22,680 kg/hr and 180 degF
= 82 degC) ...................................................................................................................... 2-6
Figure 2-4 Exhauster Discharge Pressure Response Comparison (1 inch water = 249
pascals)........................................................................................................................... 2-7
Figure 2-5 Primary Air Flow Response Comparison (1 klb/hr = 454 kg/hr) .............................. 2-8
Figure 3-1 Comparison of Simulink Model Responses with Linear Model Responses............. 3-3
Figure 3-2 Controller Singular Values (magnitude (y-axis) vs. Frequency (x-axis)) ................. 3-4
Figure 3-3 Controller Sensitivities (left) and Step Responses (right)........................................ 3-5
Figure 3-4 Closed-loop Controller Implementation in Simulink ................................................ 3-5
Figure 4-1 EPRI I&C Center Advanced Control Testbed Diagram........................................... 4-3
Figure 4-2 Functional Diagram of Interface Between Conventional PID Controllers and
Advanced Controller ........................................................................................................ 4-7
Figure 4-3 Operator Display for Selecting Between PID Controller and Advanced Control
with PID Currently in Service ........................................................................................... 4-8
Figure 4-4 Operator Display for Selecting Between PID Control and Advanced Control
with Advanced Control in Service .................................................................................... 4-9
xi
1
INTRODUCTION
In 2001, EPRI published a Technical Brief entitled Advanced Coal Pulverizer Control: Proof of
Concept Study [1]. It provides background information on the project and described the
modeling and control design work that had been done up to that time. It also discusses several
future activities that should be done to complete the advanced control study on pulverizers.
Work on the those tasks was begun in 2002, but was delayed due to problems with the advanced
control testbed simulator at the EPRI I&C Center, on which the system was to be tested. This
report completes the description of the work done in 2002 and 2003, which included model
modifications to incorporate the primary air flow system, additional testing on the pulverizer to
verify the primary air flow model, another round of advanced control design utilizing the revised
pulverizer model and implementation and functional testing on the I&C Center testbed. The next
step would be to implement the advanced controller on an actual plant and compare its
performance against that of the conventional PID based control currently in use. Now that the
simulation testing is complete, the controller is ready for trial in the plant environment.
The advanced control method used in this study is the H infinity method. H infinity is a robust
control design method, which provides the designer with good flexibility to adjust robustness and
performance goals as required by the application [2].
The pulverizer studied in this project is an Alstom-CE RB-633 vertical spindle bowl mill.
Earlier in the project, a detailed lumped parameter model of the pulverizer was developed using
5 zones to represent the pulverizer as shown in Figure 1-1. The zones in the model are the air
mixing zone under bowl, the inner bowl region, the outer bowl region , the separator zone above
the bowl, and the classifier. One of the objectives of the original model was to study the effects
of coal fineness, so there is considerable complexity in the model to provide this capability. This
capability is no longer being used for this project, but it remains in the model to avoid the
additional work required to remove it.
1-1
Introduction
Classifier
Separator
Bowl
Under Bowl
Model Regions
Figure 1-1
Pulverizer Model Regions
1-2
2
ADDING PRIMARY AIR FLOW SYSTEM TO MODEL
The original pulverizer model [3] developed for this project treated the primary air flow through
the pulverizer as a variable boundary condition. In other words, the primary air flow rate was
computed directly from the damper position demands, but was not truly modeled. While this
simplified the model considerably, it also did not allow a realistic control design for the primary
air flow system. To improve the model fidelity, a true primary air flow system was added,
including the dampers and exhauster fan. This was not an easy task because the primary air flow
computations were coupled to the pulverizer coal flow model. Modeling a coupled system such
as this proved to be a challenge in the MATLAB Simulink environment.
Description of Primary Air Flow Model in Pulverizer Model
A parameter that has a significant effect on pulverizer performance is the primary air flow rate.
This in turn depends on several parameters that include the geometry of the flow path, the
various damper settings, the inlet and exit pressures, and the pressure increase produced by the
exhauster fan. The flow model computes the total primary air flow rate, the individual hot and
cold air flow rates, and the pressure drops in the system as functions of the aforementioned
parameters.
The flow computation loop consists of four basic elements that include; a flow element with a
fixed resistance; a flow element with a variable resistance; a mixing element; and a fan element.
Flow Element, Fixed Resistance – This element computes an exit air velocity and pressure
given the following primary air inlet conditions: pressure; velocity; mass flow rate; and
temperature. The Bernoulli Equation is used to compute the exit conditions:
P1
ρ
+
V12 P2
V2
= + (1 + K ) 2
2
ρ
2
(2-1)
where:
P = pressure
V = velocity
K = loss coefficient
= density
subscripts:
1 = inlet conditions
2 = exit conditions
2-1
Adding Primary Air Flow System to Model
In addition, the following assumptions are used: density is constant and is computed from the
inlet pressure; the process is isothermal; and elevation changes are ignored.
Flow Element, Variable Resistance – This element is identical to the previous flow element,
except it has a variable resistance to account for a damper. This element requires a damper
setting as an input, which is converted to a loss coefficient based on a curve fit for the type of
damper being modeled. The computation is then identical to Equation 2-1.
Mixing Element – The mixing element is required to compute the temperature of the combined
hot and cold air. This element computes the temperature of the mixture from an energy balance
given by:
mcTc c pc + mhTh c pc = mtTt c pt
(2-2)
where:
m = mass flow rate
T = temperature
cp = specific heat
subscripts:
h = hot air
c = cold air
t = mixed air
Fan Element – The fan element computes the pressure increase produced by the fan. This
element first converts mass flow rate to volumetric flow rate. The volumetric flow rate is then
used to compute pressure increase from a look up table.
Flow Loop Model – Figure 2-1 presents a schematic of the primary air flow model that was
created with Simulink, MATLAB Version 6.1. Each type of element in the model is listed
below:
Flow Element, Fixed Resistance:
Cold Air Inlet
Throat
ThroatExit – Exhauster
Fan-Furnace
Flow Element, Variable Resistance:
Hot Air Inlet
Exhauster Damper
Mixing Element:
Mixer
Fan Element:
Fan
2-2
Adding Primary Air Flow System to Model
There are two MATLAB algebraic loop elements in the model that enable it to compute
pressure-driven flow rates. The first loop is shown by the element labeled “Furnace Pressure
Loop.” This loop evaluates the difference between the specified furnace pressure and the
computed furnace pressure. It then adjusts the cold air mass flow rate and iterates until these
values agree.
The second algebraic loop is part of the mixing element. This loop evaluates the difference
between the cold air and hot air pressures entering the mixing element, which must be equal
since they are combined at this point. The algebraic loop adjusts the hot air mass flow rate and
iterates until these pressures agree.
The combined coal and primary air temperature is computed by the coal grinding model which
runs in parallel with the flow loop. This temperature is computed by sending the mixed primary
air temperature to the coal-grinding model, which performs an energy balance to compute the
combined coal/air temperature. This temperature is then fed back into the “ThroatExit –
Exhauster” element of the flow model.
There are several flow resistances that must be defined in the flow portion of the model. In order
to define these, pressure drop data from the actual pulverizer should be used. Unfortunately,
there were only two pressure measurement locations on the pulverizer, under the bowl and at the
exhauster discharge. To allow a better definition of all the flow resistances, three additional
pressure ports were added to the pulverizer at the following locations:
•
Above the bowl in the separator region.
•
At the outlet of the pulverizer before the exhauster damper.
•
At the inlet to the exhauster fan downstream of the exhauster damper.
A simple manometer was used to record the pressures at these locations under two different
pulverizer load conditions. This data was then used to define the flow resistances and fan curves
for the air flow system.
Although the Simulink modeling system was made to work on this application, the complete
model (Figure 2-2) is quite complex and executes rather slowly. The Simulink system does not
appear to be an ideal environment for simulating systems with coupled equations such as the
energy and pressure/flow equations in the pulverizer systems.
2-3
Adding Primary Air Flow System to Model
Figure 2-1
Simulink Block Diagram of Primary Air Flow Model
2-4
Adding Primary Air Flow System to Model
Figure 2-2
Complete Pulverizer Simulink Block Diagram
Model Validation
After the model was modified to include the primary flow system, it needed to be validated. The
focus for this validation was the pressure profile through the pulverizer and the exhauster system.
There are permanent pressure measurements installed at two locations on the system, one under
the bowl inside the pulverizer and the other at the discharge of the exhauster fan. In addition the
outlet temperature was also used in the validation, along with the primary air flow rate.
Considerable time was spent adjusting various model parameters to achieve the best overall
match between the plant data and the model predictions. It is not possible to know the coal flow
rate, the coal moisture content or the air inleakage rate very accurately so this caused some
uncertainty in the model. In the end a good compromise was achieved, and some of the
validation data is shown in Figures 2-3 through 2-5. One area where good agreement was not
reached is in the predicted primary air flow rate during a hot air damper step response test. The
damper was stepped down, and on the plant the mass flow rate decreased slightly. The primary
air mass flow rate predicted by the model makes a slight increase under the same test conditions
as shown in Figure 2-4. This results from the fact that the hot air flow decreases, but the denser
cold air flow increases and the exhauster can move more flow when it is denser. It is hard to say
which response is correct without additional instrumentation on the pulverizer.
2-5
Adding Primary Air Flow System to Model
Plant and Model Data Comparison
Hot Air Damper Step Response
45
l
e
d
o
M
)
%
(
r
e
p
m
a
D
ri
A
t
o
H
40
35
30
0
500
1000
1500
2000
2500
3000
0
500
1000
1500
2000
2500
3000
0
500
1000
1500
2000
2500
3000
0
500
1000
1500
2000
2500
3000
0
500
1000
1500
2000
2500
3000
0
500
1000
1500
Time (seconds)
2000
2500
3000
45
40
t
n
al
P
35
30
55
l
e
d
o
M
50
45
)
r
h/
bl
k(
w
ol
F
A
P
55
t
n
al
P
50
45
180
)
F
g
e
d(
p
m
e
T
t
el
t
u
O
r
e
zi
r
e
vl
u
P
l
e
d
o
M
170
160
180
t
n
al
P
170
160
Figure 2-3
Comparison of Plant and Model Data (50 klb/hr = 22,680 kg/hr and 180 degF = 82 degC)
2-6
Adding Primary Air Flow System to Model
Discharge Pressure Comparison for Exhauster Step Response
8
7.8
7.6
)
r
et
a
w
s
e
h
c
n(i
er
u
s
s
er
P
e
g
r
a
h
c
si
D
r
et
s
u
a
h
x
E
7.4
7.2
7
Model
Plant
6.8
6.6
6.4
6.2
6
0
300
600
900
1200
1500
Time (seconds)
Figure 2-4
Exhauster Discharge Pressure Response Comparison (1 inch water = 249 pascals)
2-7
Adding Primary Air Flow System to Model
PA Flow Comparison for HA Damper Step Response
55
54
Model
Plant
53
52
)
r
h/
bl
k(
w
ol
F
A
P
51
50
49
48
47
46
45
0
500
1000
1500
Time (seconds)
2000
Figure 2-5
Primary Air Flow Response Comparison (1 klb/hr = 454 kg/hr)
2-8
2500
3000
3
CONTROL DESIGN FOR MODIFIED MODEL
Introduction
This section describes the system identification process and control design of the revised
pulverizer model. This model describes the relationship between the three controlled variables
primary air flow (PAF), pulverizer outlet temperature and coal flow to the three manipulated
variables exhauster damper demand (EDD), hot air damper demand (HAD) and feeder speed
demand (FSD). The first-principles model is based on the earlier developed pulverizer model
with the addition of a flow-loop module performing air flow computations.
System identification is the process of developing a mathematical model of a system based on
input and output data resulting from tests on the system. In this phase of the pulverizer control
project, the system being identified and controlled is the first principles Simulink model of the
pulverizer.
The first-principles model has been implemented in MATLAB/Simulink R12 to serve as a
testing platform for the implementation of system identification and controller design techniques
that can be transported to the actual industrial process. The theory and implementation of this
identification-based controller design have been outlined in [4] and references therein. Public
domain, parsed versions of the relevant MATLAB codes can be found in
http://www.eas.asu.edu/~tsakalis/482.htm (links to Course Notes, EEE482 Project, MATLAB
functions).
Identification of a Linear Model
The generation of a low-order control-oriented model is the typical first step in any
identification-based controller design procedure. This model should be accompanied by an
uncertainty description that defines the frequency-domain limitations of the model for controller
design purposes and aids in the selection of the target closed-loop system.
MATLAB offers a quick approach to obtain such a model through the use of the linmod
function. The resulting model is the linearization of the plant at a given steady-state and can be
further reduced in order and used for uncertainty computations. The main drawback of this
method is that it cannot be extended to the actual process. However, it can be useful in analyzing
the changes of the linearized model over the operating domain.
3-1
Control Design for Modified Model
The identification-based model for the pulverizer has been obtained using the revised Simulink
model. Signal generators to produce random binary sequence (RBS) excitation signals and pulse
signals have been added to the model. An RBS excitation test was run for all three inputs
simultaneously and single-pulse excitation tests were run for each of the three model inputs. The
data collected from these four experiments were saved and then the relevant portions were
extracted using the function keep and appended with NaN (not-a-number) separators using the
function dat_app.
Comments on the Linear Control Model
1. An exceedingly long initial interval was used to ensure that the pulverizer had reached
steady-state. This is helpful in isolating the local dynamics from long-term drifts but it is not
strictly necessary for an actual implementation.
2. The operating point was selected as: primary air flow ~ 50000 lb/hr (22,680 kg/hr), outlet
temperature ~ 180 degF (82 degC), Coal flow ~ 6.7 lb/s (3.04 kg/hr).
3. The magnitudes of excitation and the RBS bandwidths have been selected based on a few
initial simulations and the prior expectations for the closed-loop response. The outputs have
also been scaled so that the variances of the three output signals are comparable. It is
convenient to define a scaling transformation to reflect the relative importance of output
signal variability (e.g., 100 lb/hr (45.4 kg/hr) - PAF ~ 1 degF (0.56 degC) -Temp ~ 0.01 lb/s
(0.0045 kg/s) - coal flow) in a manner so that the model conditioning is reasonable around
the intended closed-loop bandwidth. In general, such a transformation helps in the
uncertainty computations and assigns appropriate weights for the design of a controller.
(Although both the identification and controller design codes contain internal scaling
mechanisms to handle badly conditioned plants; it is still a good idea to take care of the
scaling issue explicitly.)
4. The RBS experiment is the most important one, because it contains the critical information
about the plant behavior around the intended crossover frequency. The pulse experiments
provide useful information about the DC component of the transfer function and help to
avoid excessive bias at low frequencies due to slow drifts. In a two-stage design (first design
and refinement), the data from the closed-loop evaluation of the first controller can be
substituted for the pulse experiments.
5. The initial flow-loop model has been modified to eliminate the obvious input nonlinearities
(rate-limiters and damper curves) from both the identification and controller design. The
rationale and practical justification for this change is as follows:
a) Both of these nonlinearities can be identified separately with reasonable accuracy.
b) Their inclusion in the identification process would create a large model mismatch and
would adversely affect the linear model approximation.
3-2
Control Design for Modified Model
c) They occur at the plant input where they can be handled a posteriori through
straightforward inversion and anti-windup mechanisms.
d) The corresponding flow loop modifications are: extraction of hot-air damper and
exhauster damper curves from the flow-loop block, and creation of a new output signal
containing the effective control signals. In practice, this would be equivalent to a postprocessing of the input signals with a nonlinear transformation. Any small
discrepancies between the assumed nonlinear models and the actual damper behavior
would then appear as modeling mismatches and would be lumped in the uncertainty
estimates.
The identification of a linear model between the effective inputs and the scaled plant outputs
produced a good match between the model and the actual response as shown in the left hand side
of Figure 3-1. The top plot shows both the Simulink model and identified linear model
predictions for all three output variables, outlet temperature, primary air flow and coal flow. The
bottom plot shows the differences between the two models for each of the three variables. After
a few trials, a suitable model order was determined so that both the uncertainty estimates and the
pole-zero structure of the model were reasonable. The minimum RHP zero bandwidth appears at
0.3 rad/s, which is lower than the model obtained from linmod, but allows for a closed loop
bandwidth around 0.1 rad/s.
Figure 3-1
Comparison of Simulink Model Responses with Linear Model Responses
Controller Design Notes
The weights for the H-infinity controller design were chosen as follows:
1. PAF: 3rd order complementary sensitivity with 0.3 rad/s bandwidth and 1st order sensitivity.
This channel is apparently uncertainty-limited. While higher bandwidths are feasible, they
tend to increase “spill-over” and adversely affect the closed-loop decoupling properties.
3-3
Control Design for Modified Model
2. Temperature: 3rd order complementary sensitivity with 0.2 rad/s bandwidth and 2nd order
sensitivity. This channel is apparently RHP-zero-limited. Faster loops tend to produce
unacceptable levels of inverse response.
3. Coal flow: 3rd order complementary sensitivity with 0.2 rad/s bandwidth and 2nd order
sensitivity. This channel is apparently uncertainty-limited but RHP-zero limitations also
appear in the same bandwidth.
Figure 3-2
Controller Singular Values (magnitude (y-axis) vs. Frequency (x-axis))
It should be emphasized that the selection of these weights required a few trials with the Hinfinity controller design function. The model exhibits considerable singular value spread, righthalf-plane (RHP) zeros appear near the closed-loop bandwidth and there are structural
differences among the channel dynamics (PAF is tuned below open-loop bandwidth while the
rest are tuned above open-loop bandwidth). All these factors require a careful selection of the
weights so that the closed-loop performance is close to the target (at the optimum, gamma ~ 0.50.7). Otherwise, the H-infinity optimization relaxes the constraints too much and the resulting
controller is essentially H-2 optimal with significantly larger sensitivity peaks.
The final controller has reasonable nominal sensitivities and step response as shown in Figure
3-3.
3-4
Control Design for Modified Model
Figure 3-3
Controller Sensitivities (left) and Step Responses (right)
Controller Implementation in Simulink
The controller was implemented in closed-loop with the Simulink pulverizer model as shown in
Figure 3-4. The simulation is initialized by defining the state space matrices, the controller
output scaling matrices used during identification, and the input non-linearities. These are used
in the block “saturations” to enforce the various control input constraints and generate the
appropriate anti-windup signal when the requested control input exceeds the actuator limitations.
The results from this first evaluation are reasonably close to the nominal model predictions.
0
Display
1t
u
O
f
er
T
Time
R
U
Y
T o Workspace3
To Workspace1
PAF/temp/c_flow
ref Out1
scaling3
inputs
scaling1
0
1t
u
O
f
er
Display1
scaling2
ref
out
Out1
Out1
scaling
pulse
Mux
Out1
pulse3
Out1
PAF Temp Fcoal
ref erence
output
control
EDD HAD FSD
enable
Mux1
pulse1
>=
errors
EDDo HADo FSDo
controller
Uo
T o Workspace2
Pulverizer 2
Relational
Operator
10
Constant1
Figure 3-4
Closed-loop Controller Implementation in Simulink
3-5
Control Design for Modified Model
During the controller evaluation phase, it was observed that the simulator would often “freeze”
and occasionally fail to converge. The reason for that was traced back to the algebraic loops and
discontinuities introduced by the new flow loop block. To circumvent these problems, sampleand-hold blocks were introduced in all I/O signals of this block. Their sampling rate is 0.1s so
that the pulverizer dynamics are not altered significantly. This modification forces the maximum
step size of the solver to be less than 0.1s at all times and increases the execution time. Even
though there are still a few convergence warnings, it appears that the simulation completes
successfully; the speed of execution is approximately real-time.
3-6
4
CONTROLLER IMPLEMENTATION ON EPRI I&C
CENTER TESTBED
The final step in the advanced control design process is to test the design on a simulation
platform which closely mimics the actual plant and its control system. In Section 3, the
controller was tested in the MATLAB Simulink environment but this is a much different
environment from the Foxboro digital control system where the advanced control system will
ultimately be applied. The EPRI I&C Center has an advanced control testbed system that
provides a realistic Foxboro control platform on which advanced controllers can be tested.
This section describes how the advanced controller was implemented and functionally tested on
the I&C Center testbed. The major steps are:
•
Converting the MATLAB controller program into a C program that will execute on the
Foxboro Application Workstation computer
•
Modifying the Foxboro control strategy to interface with the advanced controller outputs
•
Developing an operator graphic display to allow selection of which control system is in
service
•
Testing for bumpless transfer in both directions between the advanced control system and the
conventional PID-based control system
While the functional testing of the advanced controller using the simulator was successfully
completed, testing in the plant is still needed to fully verify the dynamic performance capabilities
of the new controller. This is because the controller identification process used actual plant data
to determine the controller design, so the controller has been optimized and highly customized
for the actual plant. Small differences between behavior characteristics of the simulator and the
plant will not degrade the basic functionality of the controller, but may significantly affect its
dynamic performance characteristics, including time response and stability. Thus the
performance of the new controller will not be fully demonstrated until proper interaction with the
actual plant has been accomplished. All other facets of the controller's design have been
verified.
EPRI I&C Center Testbed
The EPRI I&C Center Advanced Control Testbed is a dual purpose plant simulator used for both
operator training and for engineering studies such as this one. The system was developed by
ESSCOR Corporation (now SimSci-ESSCOR) and is referred to as a “virtual” stimulation type
4-1
Controller Implementation on EPRI I&C Center Testbed
of system. Modern power plant simulators can be divided into two major categories depending
on how the control system is represented in the system. If the plant control system is modeled
using the regular simulation tools, then the simulator is called an emulated system. If actual
control system hardware is provided for both the real-time controllers and the operator interface,
the simulator is called a stimulated system.
The I&C Center testbed, Figure 4-1, is a little different from either of the two systems described
above. The operator interface hardware is actual Foxboro workstations but the real-time
controllers are not actual Foxboro hardware. Instead the Foxboro controller software was
modified by ESSCOR to execute on a Sun SPARC workstation. This allows one Sun
workstation to replace many Foxboro control processors, but the “virtual” control processor
behaves almost identically to the real Foxboro processors.
There are three Foxboro workstations, each with two CRT’s that provide the operator interface
for the testbed. Two of these machines are Workstation Processor (WP) 51B models and one is
an Application Workstation (AW) 51B model. The AW-51B is a dual-purpose machine in that it
functions as both a WP and an Application Processor (AP). As an AP, it provides an
environment for developing C programs which can interface with the rest of the Foxboro control
system. It is this capability which is utilized for testing the advanced controller.
The models used in the testbed are generally based on first principles and are quite realistic. For
the pulverizer model, the representation of the primary air flow and the outlet temperature
responses is good, but the response of the coal flow through the pulverizer is too fast. It does not
adequately represent the delay due to the storage of coal in the pulverizer bowl. Delays due to
material storage are difficult to represent well in lumped-parameter models like those used in
power plant simulators. The Simulink model of the pulverizer has an explicit delay term to
represent this storage response.
4-2
Controller Implementation on EPRI I&C Center Testbed
Foxboro Workstation
Processor (WP) 51B
Foxboro Application
Workstation (AW) 51B
Foxboro Nodebus Network
Master Simulation
Computer and Virtual
Control Processor
Foxboro Workstation
Processor (WP) 51B
Operator Interface System
Instructor's Station
ESSCOR Network
Figure 4-1
EPRI I&C Center Advanced Control Testbed Diagram
Advanced Controller C Program
The advanced pulverizer controller was initially designed in the MATLAB Simulink
environment as described in Section 3. While the MATLAB environment is very good for
control design, it does not produce a controller program that will directly execute in the Foxboro
distributed control system used on the testbed and the real unit. The computations required for
the advanced controller are mostly matrix multiplications.
There are two possible ways of implementing the advanced controller on the Foxboro system.
The first is to use the Foxboro block language to program the controller. The block language is
used for all the conventional control functions such as PID controllers, summers, comparators,
multipliers, and function generators. It also provides a general purpose calculation block with
similar capabilities to a programmable calculator. The block language executes on the real-time
control processors and is specifically designed for critical control applications. The block
4-3
Controller Implementation on EPRI I&C Center Testbed
language could be used to program the advanced controller, but it would be very cumbersome,
especially if the order of the controller is more than about 4 or 5.
The other option for programming the controller is to write a C program and execute it on the
Application Workstation processor. In a C program, it is very easy to perform the matrix
multiplications required by the controller and it is also easy to generalize the program so it can
handle different controller complexities. In other words, the program to handle a third order
th
controller is the same as a program to handle a 30 order controller. Some of the other required
functions are not as easy. The C program must exchange data with the rest of the Foxboro
control system and this is not a trivial task, as it is with the block language. Foxboro provides an
application programming interface (API) to allow C programs to read values from and write
values to the block language portion of the control system, but it still requires some
programming effort. The application workstation environment is not as secure and reliable as
the control processor environment, so specific precautions must be used in the program to deal
with possible failure modes, such as the application processor shutting down unexpectedly.
Since the controllers produced by robust control design techniques tend to be quite high order (>
10), it is really only practical to implement the controller in a C program and execute it on the
application workstation.
Program Structure
The C program to implement the controller has four major tasks:
•
Controller Initialization
•
Data Read/Write Setup
•
Tracking
•
Controller Operation
A complete listing of the C program is provided in Appendix A. This listing is provided for
information only and is not intended to be used for actual controller implementation. This is not
a commercial grade program at this time, it is only a functional prototype.
When the program is first started the initialization routine is executed. The main function of the
initialization routine is to read the contents of data files that contain all the values that define the
controller properties. There are three data files, one for the main controller, one for the pre-filter,
and one for miscellaneous values. The main controller and the pre-filter are both defined by the
A, B, C and D matrices of the state-space representation of a system. The main controller file
and the pre-filter file both contain arrays of numbers that define the A, B, C, and D matrices,
along with a parameter for the number of states in the controller. The main controller file
contains two additional matrices, one for the anti-reset windup function and another for the
controller tracking function. The pre-filter file also contains a matrix for initialization.
4-4
Controller Implementation on EPRI I&C Center Testbed
After the controller definition files are read, the program sets up the lists of tags to be read from
and written to the Foxboro system. The Foxboro API requires that datasets (lists) be opened for
any tags to be read or written. When the datasets are created they are defined as read-only or
read-write capable. For this reason, two datasets are created. One is read-only and contain all
the data points needed by the controller. The other is read-write and only contains those tags that
will be written back to the Foxboro system. The read dataset contains 18 tags including the
controlled variables, loop setpoints, high and low limits on the manipulated variables, tracking
signals, and manual/auto status flags. The write dataset contains only the three tags for the
controller's manipulated variables.
Once the datasets are created for reading and writing tags, then another function actually reads in
a first set of data from the Foxboro control system. This data is used to initialize the controller
states so the controller's outputs properly track the outputs of the PID controllers in the Foxboro
system. The program then enters an endless loop in which it reads the controller inputs, checks
the status of the manual/auto flags and if auto is selected, executes the controller code. If manual
is selected, the program computes a new set of tracking inputs and waits for the next cycle.
If the controller is selected for automatic mode, the controller function computes new controller
outputs and states and then writes the output values to the Foxboro system. It then waits until the
next cycle and repeats the process. The cycle time for the controller on this project is 5 seconds.
Modifications to the Existing Foxboro Logic
It was decided to implement the advanced control system in parallel with the existing PID based
control system. This required modifications to the existing control logic to incorporate switches
downstream of the PID controllers. Since there are three manipulated variables in the control
system, three switches were needed. Figure 4-2 shows the arrangement of the switches and the
existing conventional control logic.
Each switch block has two inputs and one output. The input parameters are INP1 and INP2.
INP1 is connected to the existing PID controller output for the Hot Air Damper and the
Exhauster Damper, and to a BIAS block output for the Feeder Speed. INP2 is not connected to
another block, but instead receives a value from the advanced controller through the FoxAPI
routines.
The TOGGLE parameter of the SWCH block controls which input is connected to the output.
When the TOGGLE parameter is a 0, INP1 is selected. When TOGGLE is a 1, INP2 is selected.
The logic for the switch blocks is set up so that the operator controls the TOGGLE of the switch
block on the feeder demand. The TOGGLE parameter from the feeder switch block is connected
to the TOGGLE parameters on the other two switch blocks. This keeps all three switch blocks
aligned and allows the operator to only have to switch one block to transfer control from the PID
controllers to the advanced controller.
4-5
Controller Implementation on EPRI I&C Center Testbed
An important aspect of having the two controllers in parallel is to make sure that all transfers
back and forth between the controller are done without bumps. In this design, bumpless transfer
is done as follows. When the PID controllers are in control, the TOGGLE parameters are all set
to 0. The C program for the advanced controller reads these parameters and knows that if the
PID is in control, then the advanced controller must be in a tracking mode. When in tracking
mode, the advanced controller computes the controller states that will produce the same outputs
as the current PID outputs. It then outputs these tracking values to the INP2 parameters of the
switch blocks so the operator can see that the tracking is working properly. An assumption is
made in calculating the desired states that the system is at steady state. This means that when
testing the prototype in the plant, at least initially, to avoid unanticipated and potentially
undesired behaviors, it will be important for the operator to allow transfer from the PID control
to the advanced control only when the plant is in a very stable condition.
When the advanced controller is in control, the PID controllers must track the advanced control
outputs. Most DCS block languages have built-in capabilities to perform this function, and
Foxboro is no exception. Foxboro uses a parameter called BCALCI and BCALCO, back
calculation input and output, for this purpose. The system works by connecting a downstream
block’s BCALCO parameter to an upstream block’s BCALCI parameter. Whenever a
downstream block is no longer connected to the upstream block, the upstream block reads the
BCALCI parameter to determine what its output should be. In this case, when the switch block
is switched to INP2, the PID output is no longer connected to the switch block’s output. The
PID block recognizes this and sets its output equal to the back calculation output parameter of
the switch block. In this case the back calculation parameter is called BCALC1, since the PID
controller is connected to INP1 of the switch block. BCALC2 is not used because the controller
C program is connected to INP2 and it does not use the back calculation parameters.
This scheme worked fine for the two loops with PID controllers, but the feeder speed loop has a
BIAS block instead of a PID block. In this instance the normal tracking arrangement would not
work properly, so a slightly different scheme was used. The OUT parameter of the switch block
was connected to the BCALCI parameter of the BIAS block and the TOGGLE parameter of the
switch block was connected to the INITI parameter of the BIAS block. The INITI parameter
tells the BIAS block when it should be tracking and is normally not used, as this information is
included in the BCALCO parameter.
4-6
Controller Implementation on EPRI I&C Center Testbed
Primary Air Flow
Pulverizer Outlet
Temperature
FT
TE
Rht Furnace
Fdr Demand
KLB/HR
%
INITI
∆
f(x)
+/-
A
∆
A
BCALCI
PI
BCALCI
DegF
BCALCI
PI
BIAS
PID
PID
INP1
H Inf
INP2
BCALCI
T
TOGGLE H Inf
INP2
SWCH
TOGGLE
INP1
BCALC1
T
BCALCI
SWCH
H Inf
INP2
INP1
BCALC1
T
BCALCI
SWCH
OUT
BCALCO
f(x)
CHARC
f(x)
BCALCO
CHARC
f(x)
BCALCO
CHARC
AOUT
AOUT
AOUT
Feeder 'E' Speed
Demand
Exhauster Damper
Demand
Hot Air Damper
Demand
Figure 4-2
Functional Diagram of Interface Between Conventional PID Controllers and Advanced
Controller
Operator Interface Design
The operator interface for the advanced controller has two primary functions. First it provides
the operator a means of selecting which control system is actually in control. It also provides a
visual indication that the advanced control system is tracking the conventional control system
properly before initiating a transfer.
A single graphic display was developed using the Foxboro Display Manager graphic system as
shown in Figure 4-3. In the bottom half of the graphic are three faceplate-type objects showing
the status of each of the three switch blocks in the system. Each faceplate shows the values of
the block inputs and output and indicates which input is currently selected for control
(highlighted with a white background.) In the lower right hand corner are two control buttons
for selecting which control system is in control. The button labeled “Enable MIMO” places the
4-7
Controller Implementation on EPRI I&C Center Testbed
advanced controller in service while the “Disable MIMO” puts the PID controllers in service.
MIMO is an acronym for multiple input, multiple output and is how the advanced controller is
identified to the operators. Figure 4-4 shows the appearance of the graphic when the advanced
controller is in service. There is a message above the control buttons which changes to “In
Service” with a green background when the advanced control is active.
A trend is also provided on the graphic to show both inputs for two of the switches. One trend
display can only show four parameters, so only the feeder and exhauster damper switches are
shown. The trend allows the operator to see the movement of the output of the advanced
controller and also see how the two systems have tracked each other over time.
Figure 4-3
Operator Display for Selecting Between PID Controller and Advanced Control with PID
Currently in Service
4-8
Controller Implementation on EPRI I&C Center Testbed
Figure 4-4
Operator Display for Selecting Between PID Control and Advanced Control with Advanced
Control in Service
Bumpless Transfer Testing
One of the key functions to be tested on the testbed is the bumpless transfer functionality of the
advanced controller. The test itself is almost trivial, but it is still important to verify that it works
properly before testing the controller on the real plant.
In this case the testbed was reset to a stable full-load initial condition, and the advanced
controller C program was started. Initially the PID controllers were in service, so the advanced
controller stayed in a tracking mode. Figure 4-3 shows the status of the two controllers before
the transfer to the advanced controller. Notice that the advanced controller outputs are properly
tracking the PID controller outputs in each switch block faceplate. Figure 4-4 shows the
controllers ‘status shortly after the transfer. Notice that none of the control signals have moved,
and the PID controllers are now properly tracking the advanced controller outputs. The control
was then switched back to the PID controllers and again no bumps occurred.
This test was used to confirm that the bumpless transfer scheme employed in the advanced
controller and in the Foxboro system performed satisfactorily.
4-9
5
SUMMARY AND CONCLUSIONS
The development of a prototype advanced controller for a coal pulverizer has been completed to
the point where it is ready for trials in a power plant. In 2002, work focused on developing and
demonstrating an advanced multivariable control solution for a vertical spindle pulverizer. The
mathematical model of the pulverizer was modified to include a more detailed representation of
the primary air flow system. This revised model was then used to develop an advanced
controller using the H infinity control design method. The performance of the new controller
was tested on a non-linear Simulink model of the pulverizer and was satisfactory.
In 2003, the advanced controller design was implemented on the EPRI I&C Center Advanced
Control Testbed. The implementation consisted of four main steps:
1. Convert the MATLAB controller program to a C program that would execute on the Foxboro
control system in the testbed.
2. Modify the existing Foxboro control logic to incorporate the advanced control signals.
3. Develop an operator display graphic to allow selection between the two control systems.
4. Test the bumpless transfer capabilities of the advanced controller and the modified Foxboro
control logic.
All of these tasks have been accomplished successfully and the prototype advanced controller is
now ready for testing on the actual plant.
5-1
6
REFERENCES
1. Advanced Coal Pulverizer Control - Proof of Concept Study, Technical Brief, EPRI, Palo
Alto, CA, 2001. 1004546.
2. Essentials of Robust Control, Kemin Zhou, Prentice Hall, 1998
3. G. Zhou, J. Si, and C. W. Taft, ”Modeling and Simulation of C-E Deep Bowl Pulverizer,’’
IEEE Transactions on Energy Conversion, 15: 312-322, 2000.
4. Jennie Si, Kostas Tsakalis Jose-Job Flores-Godoy, Aris Papadopoulos, ”Pulverizer
simulation and control’’ Final Report, November 2000.
6-1
A
CONTROLLER C PROGRAM LISTING
This listing is provided for information only and is not intended to be used for actual controller
implementation. This is not a commercial grade program at this time, it is only a functional
prototype.
/*
cw.c
Program that implements the controller structure shown in the
simulink model PULV2con.MDL from Kostas Tsakalis in October 2002.
The controller parameters are read from 3 files generated by a small
m-file called c_cfg_cwt.m.
These files are the following:
CNTRL.CFG: Controller definitions
FFF.CFG:
Prefilter definitions (also referred to as the
feedback filter in places)
MISC.CFG: Miscellaneous constants such as scaling vectors
The following signals need to be tied to the "supervisor"
READING FROM THE SUPERVISOR
In1SP[0]: Primary Air Flow Setpoint [klb/hr], PA_SP
In1SP[1]: Coal Temperature Setpoint [degF], COALAIR_SP
In1SP[2]: Coal Flow Setpoint [%],
, FDRSPD_SP
ufo[0]: Primary Air Flow Measurement [klb/hr], PA_MSMT
ufo[1]: Coal Temperature Measurement [degF], COALAIR_MSMT
ufo[2]: Coal Flow Measurement [klb/hr], FDRSPD_MSMT
track[0]: Logic signal from Exhauster dmpr toggle, EXHDMPR_TOG
track[1]: Logic signal from Hot air damper toggle, HADMPR_TOG
track[2]: Logic signal from Feeder spd dem toggle, FDRSPD_TOG
When all three Track signals are 0, the advanced controller
is enabled. (1:Track, 0:Auto)
tieback[0]: Output of Exh Dmpr PID cntlr, EXHDMPR_OUT
tieback[1]: Output of Hot Air Dmpr PID cntlr, HADMPR_OUT
tieback[2]: Output of Feeder Spd PID cntlr FDRSPD_OUT
The tieback signals will be tracked by the advanced
controller when the advanced controller is not enabled.
minsat[0]:
Low limit on Exh dmpr demand signal, EXHDMPR_LO
A-1
Controller C Program Listing
minsat[1]:
minsat[2]:
maxsat[0]:
maxsat[1]:
maxsat[2]:
Low limit on Hot air dmpr demand signal, HADMPR_LO
Low limit on Feeder speed demand signal, FDRSPD_LO
High limit on Exh dmpr demand signal, EXHDMPR_HO
High limit on Hot air dmpr demand signal, HADMPR_HO
High limit on Feeder speed demand signal, FDRSPD_HO
WRITING TO THE SUPERVISOR
Y[0]: Exhauster Damper Demand [0 to 100 %], EXHDMPR_DEM
Y[1]: Hot Air Damper Demand [0 to 100 %], HADMPR_DEM
Y[2]: Feeder Speed Demand [0 to 100 %], FDRSPD_DEM
Point list for Pulv controller interface to Foxboro system
READ SET
Index
Name
0
9DS_CTRL:B5.PNT
1
9PULVE:B29.SPT
2
9PULVE:B2.PNT
3
9PULVE:B20.RSP
4
9PULVE:B20.HOLIM
5
9PULVE:B20.LOLIM
6
9PULVE:B36SWITCH.TOGGLE
7
9PULVE:B36SWITCH.OUT
8
9PULVE:B29.HOLIM
9
9PULVE:B29.LOLIM
10 9PULVE:B37SWITCH.TOGGLE
11 9PULVE:B37SWITCH.OUT
12 9PULVE:B1.PNT
13 9PULVE:B11.MEAS
14 9PULVE:B11.HOLIM
15 9PULVE:B11.LOLIM
16 9PULVE:B35SWITCH.TOGGLE
17 9PULVE:B35SWITCH.OUT
Desc
Coal Air Measurement
Coal Air Set Point
Primary Air Measurement
Primary Air Set Point
Exh Dmpr High Output Limit
Exh Dmpr Low Output Limit
Exh Dmpr Controller Engaged
Exh Dmpr Toggle Output
HA Dmpr High Output Limit
HA Dmpr Low Output Limit
HA Dmpr Controller Engaged
HA Dmpr Toggle Output
Fdr Spd Measurement
Fdr Spd Set Point
Fdr Spd High Output Limit
Fdr Spd Low Output Limit
Fdr Spd Controller Engaged
Fdr Spd Toggle Output
Pointer
COALAIR_MSMT
COALAIR_SP
PA_MSMT
PA_SP
EXHDMPR_HO
EXHDMPR_LO
EXHDMPR_TOG
EXHDMPR_OUT
HADMPR_HO
HADMPR_LO
HADMPR_TOG
HADMPR_OUT
FDRSPD_MSMT
FDRSPD_SP
FDRSPD_HO
FDRSPD_LO
FDRSPD_TOG
FDRSPD_OUT
WRITE SET
Index
0
1
2
Name
9PULVE:B35SWITCH.INP2
9PULVE:B36SWITCH.INP2
9PULVE:B37SWITCH.INP2
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define INPUTS 3
#define OUTPUTS 3
#define MAXSTATES 24
#define READPARAMS 18
A-2
Desc
Feeder speed demand
Exhauster damper demand
Hot air damper demand
Pointer
FDRSPD_DEM
EXHDMPR_DEM
HADMPR_DEM
Controller C Program Listing
#define WRITPARAMS 3
#undef echo_screen
/* Read Set Pointers */
#define COALAIR_MSMT 0
#define COALAIR_SP 1
#define PA_MSMT 2
#define PA_SP 3
#define EXHDMPR_HO 4
#define EXHDMPR_LO 5
#define EXHDMPR_TOG 6
#define EXHDMPR_OUT 7
#define HADMPR_HO 8
#define HADMPR_LO 9
#define HADMPR_TOG 10
#define HADMPR_OUT 11
#define FDRSPD_MSMT 12
#define FDRSPD_SP 13
#define FDRSPD_HO 14
#define FDRSPD_LO 15
#define FDRSPD_TOG 16
#define FDRSPD_OUT 17
/* Write Set Pointers
*/
#define EXHDMPR_DEM 0
#define HADMPR_DEM 1
#define FDRSPD_DEM 2
double scales[INPUTS],scales_inv[OUTPUTS]; /* Scales for input/output */
double In1SP[OUTPUTS],Y[OUTPUTS],U[OUTPUTS];
double Aci[MAXSTATES][MAXSTATES],Bci[MAXSTATES][INPUTS];
double Cci[OUTPUTS][MAXSTATES],Dci[OUTPUTS][INPUTS];
double Lci[MAXSTATES][INPUTS],ICCS[MAXSTATES][INPUTS+OUTPUTS];
double xci[MAXSTATES],yci[OUTPUTS],uci[INPUTS];
double yci_sat[OUTPUTS],AW[OUTPUTS],yci_scale[OUTPUTS];
int
states_ci;
double Afo[MAXSTATES][MAXSTATES],Bfo[MAXSTATES][INPUTS];
double Cfo[OUTPUTS][MAXSTATES],Dfo[OUTPUTS][INPUTS];
double xfo[MAXSTATES],yfo[OUTPUTS],ufo[INPUTS];
double IFCS[MAXSTATES][INPUTS+OUTPUTS];
int
states_fo;
char ReadNames[READPARAMS][32]; /* Names of read parameters */
char WriteNames[WRITPARAMS][32]; /* Names of write parameters */
double minsat[OUTPUTS];
double maxsat[OUTPUTS];
int
track[OUTPUTS];
double tieback[OUTPUTS],tieback_scale[OUTPUTS];
A-3
Controller C Program Listing
/*
********************************************************************** */
void main()
{
int i, j;
int readSet, writeSet;
int readIndex[READPARAMS],writeIndex[WRITPARAMS];
void modelInit();
void statesInit();
void controller();
void getreadindex(int *, int index[]);
void getwriteindex(int *, int index[]);
void getsets(int *, int index[]);
void readInputs(int readset, int index[]);
void outputs(int writeSet, int index[]);
void readoutputs(int writeSet, int index[]);
void SetReadWriteNames();
float scanrate;
printf("Start\n\n");
SetReadWriteNames();
printf("Finished SetReadWriteNames\n");
modelInit();
printf("Finished modelInit\n");
getreadindex(&readSet, readIndex);
printf("Finished getreadindex\n");
getwriteindex(&writeSet, writeIndex);
printf("Finished getwriteindex\n");
getsets(&readSet, readIndex);
printf("Finished getsets\n");
scanrate = 5.;
readInputs(readSet,readIndex);
statesInit();
for (;;)
{
readInputs(readSet,readIndex);
printf("Track signals %d,%d,%d\n", track[0],track[1],track[2]);
printf("Tieback signals %f,%f,%f\n", tieback[0],tieback[1],tieback[2]);
if (track[0]>0.5 && track[1]>0.5 && track[2]>0.5)
{
printf("Calling controller from loop, MIMO\n");
controller();
outputs(writeSet,writeIndex);
readoutputs(writeSet,writeIndex);
}
else
A-4
Controller C Program Listing
{
printf("Calling statesInit from loop, not MIMO\n");
statesInit();
outputs(writeSet,writeIndex);
}
sleep(scanrate);
}
}
void getreadindex(int *preadSet, int index[])
{
int i,j,k;
char Tagname[READPARAMS][32];
char SetName[32];
int ObjectID[READPARAMS], ValueType[READPARAMS], ReadScanRate,
WriteScanRate;
float ReadDelta[READPARAMS], WriteDelta[READPARAMS];
int CallType, quenr, nument, reterr;
for(i=1; i <= 20; i++)
{
get_set_name(i, SetName, &reterr);
if(reterr != 0)
printf("Error getting set name for set #%d\n",i);
printf("Set #=%d, Setname =%s\n",i,SetName);
if(strstr(SetName, "cpulv Read")==NULL) continue;
{
printf("name contains cpulv Read\n");
*preadSet=i;
gsinfo(i,&CallType,&quenr,&nument,ValueType,ObjectID,&reterr);
if(reterr !=0)
printf("Error getting set info for set #%d\n",1);
printf("gsinfo OK\n");
getnam(i,&nument, ReadDelta, Tagname, &reterr);
if(reterr !=0)
printf("Error getting tag names for set #%d\n",i);
for(j=0; j<nument; j++)
{
for(k=0; k<READPARAMS; k++)
{
if(strcmp(Tagname[j], ReadNames[k])!=0) continue;
{
index[k]=ObjectID[j];
printf("Tagname=%s, ReadNames=%s, ObjectID=%d,
index=%d\n",Tagname[j],ReadNames[k],ObjectID[j],index[k]);
}
}
}
}
}
}
/*
********************************************************************
*/
A-5
Controller C Program Listing
void getwriteindex(int *pwritSet, int index[])
{
int i,j,k,l;
char Tagname[WRITPARAMS][32];
char SetName[32];
int ObjectID[WRITPARAMS];
int ValueType[WRITPARAMS], ReadScanRate, WriteScanRate;
float ReadDelta[WRITPARAMS], WriteDelta[WRITPARAMS];
int CallType, quenr, nument, reterr;
l = 0;
i = 0;
while (l<=1)
{
i=i+1;
get_set_name(i, SetName, &reterr);
if(reterr != 0)
{
printf("Exiting while loop i = %d\n",i);
break;
}
else
{
printf("Set #=%d, Setname =%s\n",i,SetName);
if(strstr(SetName, "cpulv Write")==NULL) continue;
else
{
*pwritSet=i;
gsinfo(i,&CallType,&quenr,&nument,ValueType,
ObjectID,&reterr);
if(reterr !=0)
printf("Error getting set info for set %d\n",1);
else
{
printf("gsinfo OK\n");
getnam(i,&nument, ReadDelta, Tagname, &reterr);
printf("Num values =%d\n",nument);
if(reterr !=0)
printf("Error getting tag names for set #%d\n",i);
else
{
for(j=0; j<nument; j++)
{
for(k=0; k<WRITPARAMS; k++)
{
if(strcmp(Tagname[j], WriteNames[k])!=0) continue;
{
index[k]=ObjectID[j];
printf("Tagname=%s, WriteNames=%s, ObjectID=%d,
index=%d\n",Tagname[j],WriteNames[k],
ObjectID[j],index[k]);
}
}
}
}
}
}
A-6
Controller C Program Listing
}
}
}
void getsets(int *pwritSet, int index[])
{
int i,j,k;
char SetName[32];
int reterr;
/* Define name array */
for(i=1; i <= 30; i++)
{
get_set_name(i, SetName, &reterr);
if(reterr != 0)
{
/* printf("Exiting while loop i = %d\n",i);
break; */
}
else
{
printf("Set #=%d, Setname =%s\n",i,SetName);
}
}
}
void readInputs(int set, int index[])
{
typedef union
{
long lval;
float fval;
char bval;
} IAXVAL;
int i;
IAXVAL value[READPARAMS];
int status,type;
if(gsnent(set)!=READPARAMS)
{
printf("Read from the wrong set\n");
exit(1);
}
for(i=0;i<READPARAMS;i++)
{
value[i].lval=readval(index[i]);
status=readsta(index[i]);
type=status & 7;
/* printf("Index=%d, Value=%f,Type=%d\n",index[i],
value[i].fval,type); */
if(type!= 3)
{
/* printf("The type of %d th read parameter is not float,
but TYPE %d !\n",i,type); */
}
}
A-7
Controller C Program Listing
In1SP[0] = value[PA_SP].fval;
In1SP[1] = value[COALAIR_SP].fval;
In1SP[2] = value[FDRSPD_SP].fval;
ufo[0] = value[PA_MSMT].fval;
ufo[1] = value[COALAIR_MSMT].fval;
ufo[2] = value[FDRSPD_MSMT].fval;
/* temporary scaling for coal flow */
ufo[2] = ufo[2]*4.0;
track[0] = value[EXHDMPR_TOG].bval;
track[1] = value[HADMPR_TOG].bval;
track[2] = value[FDRSPD_TOG].bval;
tieback[0] = value[EXHDMPR_OUT].fval;
tieback[1] = value[HADMPR_OUT].fval;
tieback[2] = value[FDRSPD_OUT].fval;
minsat[0] = value[EXHDMPR_LO].fval;
minsat[1] = value[HADMPR_LO].fval;
minsat[2] = value[FDRSPD_LO].fval;
maxsat[0] = value[EXHDMPR_HO].fval;
maxsat[1] = value[HADMPR_HO].fval;
maxsat[2] = value[FDRSPD_HO].fval;
printf("Set point indices, PA = %d, CoalAir = %d, Feeder Speed = %d\n",
index[PA_SP], index[COALAIR_SP], index[FDRSPD_SP]);
printf("Set points, PA = %f, CoalAir = %f, Feeder Speed = %f\n\n",
value[PA_SP].fval, value[COALAIR_SP].fval,
value[FDRSPD_SP].fval);
printf("Measurement indices, PA = %d, CoalAir = %d, Feeder Speed =
%d\n", index[PA_MSMT], index[COALAIR_MSMT], index[FDRSPD_MSMT]);
printf("Measurements, PA = %f, CoalAir = %f, Feeder Speed = %f\n ",
value[PA_MSMT].fval, value[COALAIR_MSMT].fval, value[FDRSPD_MSMT].fval);
printf("Scaled Measurements, PA = %f, CoalAir = %f, Feeder Speed =
%f\n\n ", ufo[0], ufo[1], ufo[2]);
printf("Toggle indices, Exh Dmpr = %d, HA Dmpr = %d, Feeder Speed =
%d\n", index[EXHDMPR_TOG], index[HADMPR_TOG], index[FDRSPD_TOG]);
printf("Toggles, Exh Dmpr = %d, HA Dmpr = %d, Feeder Speed = %d\n",
value[EXHDMPR_TOG].bval, value[HADMPR_TOG].bval, value[FDRSPD_TOG].bval);
printf("Track, Exh Dmpr = %d, HA Dmpr = %d, Feeder Speed = %d\n\n",
track[0], track[1], track[2]);
printf("Tieback indices, Exh Dmpr = %d, HA Dmpr = %d, Feeder Speed =
%d\n", index[EXHDMPR_OUT], index[HADMPR_OUT], index[FDRSPD_OUT]);
printf("Tieback values, Exh Dmpr = %f, HA Dmpr = %f, Feeder Speed =
%f\n", value[EXHDMPR_OUT].fval, value[HADMPR_OUT].fval,
value[FDRSPD_OUT].fval);
printf("Tieback values, Exh Dmpr = %f, HA Dmpr = %f, Feeder Speed =
%f\n\n", tieback[0], tieback[1], tieback[2]);
printf("Lo Output Limit Indices, Exh Dmpr = %d, HA Dmpr = %d, Feeder
Speed = %d\n", index[EXHDMPR_LO], index[HADMPR_LO], index[FDRSPD_LO]);
A-8
Controller C Program Listing
printf("Lo Output Limits, Exh Dmpr = %f, HA Dmpr = %f, Feeder Speed =
%f\n\n", value[EXHDMPR_LO].fval, value[HADMPR_LO].fval,
value[FDRSPD_LO].fval);
printf("Hi Output Limit Indices, Exh Dmpr = %d, HA Dmpr = %d, Feeder
Speed = %d\n", index[EXHDMPR_HO], index[HADMPR_HO], index[FDRSPD_HO]);
printf("Hi Output Limits, Exh Dmpr = %f, HA Dmpr = %f, Feeder Speed =
%f\n\n", value[EXHDMPR_HO].fval, value[HADMPR_HO].fval,
value[FDRSPD_HO].fval);
}
void outputs(int set,int index[])
{
typedef union
{
long lval;
float fval;
} IAXVAL;
int i;
float xx;
IAXVAL value[WRITPARAMS],reads[WRITPARAMS]={0.0};
printf("Y[0]= %f, Y[1]= %f, Y[2]= %f\n",Y[0],Y[1],Y[2]);
value[EXHDMPR_DEM].fval=Y[EXHDMPR_DEM];
value[HADMPR_DEM].fval=Y[HADMPR_DEM];
value[FDRSPD_DEM].fval=Y[FDRSPD_DEM];
if(gsnent(set)!=WRITPARAMS)
{
printf("Write to the wrong set\n");
exit(1);
}
for(i=0;i<WRITPARAMS;i++)
{
printf("Write values: Index= %d, Value=
%f\n",index[i],value[i].fval);
wrtval(index[i],value[i].lval);
}
}
void readoutputs(int set,int index[])
{
typedef union
{
long lval;
float fval;
} IAXVAL;
int i;
char tempfile[32];
IAXVAL value[WRITPARAMS],reads[WRITPARAMS]={0.0};
A-9
Controller C Program Listing
/*
printf("Waste Some Time:\n");
scanf("%s",tempfile); */
if(gsnent(set)!=WRITPARAMS)
{
printf("Write to the wrong set\n");
exit(1);
}
for(i=0;i<WRITPARAMS;i++)
{
reads[i].lval=readval(index[i]);
printf("read it now: index= %d ; value= %f\n",index[i],reads[i].fval);
}
}
void SetReadWriteNames()
{
/* Define name arrays for inputs */
strcpy(ReadNames[0],"9DS_CTRL:B5.PNT");
strcpy(ReadNames[1],"9PULVE:B29.SPT");
strcpy(ReadNames[2],"9PULVE:B2.PNT");
strcpy(ReadNames[3],"9PULVE:B20.RSP");
strcpy(ReadNames[4],"9PULVE:B20.HOLIM");
strcpy(ReadNames[5],"9PULVE:B20.LOLIM");
strcpy(ReadNames[6],"9PULVE:B36SWITCH.TOGGLE");
strcpy(ReadNames[7],"9PULVE:B36SWITCH.OUT");
strcpy(ReadNames[8],"9PULVE:B29.HOLIM");
strcpy(ReadNames[9],"9PULVE:B29.LOLIM");
strcpy(ReadNames[10],"9PULVE:B37SWITCH.TOGGLE");
strcpy(ReadNames[11],"9PULVE:B37SWITCH.OUT");
strcpy(ReadNames[12],"9PULVE:B1.PNT");
strcpy(ReadNames[13],"9PULVE:B11.MEAS");
strcpy(ReadNames[14],"9PULVE:B11.HOLIM");
strcpy(ReadNames[15],"9PULVE:B11.LOLIM");
strcpy(ReadNames[16],"9PULVE:B35SWITCH.TOGGLE");
strcpy(ReadNames[17],"9PULVE:B35SWITCH.OUT");
strcpy(WriteNames[0],"9PULVE:B36SWITCH.INP2");
strcpy(WriteNames[1],"9PULVE:B37SWITCH.INP2");
strcpy(WriteNames[2],"9PULVE:B35SWITCH.INP2");
}
void modelInit()
{
int i,j;
void statesInit();
A-10
Controller C Program Listing
//double temp[MAXSTATES];
char tempfile[32];
FILE *fid,*fid11;
printf("Enter the check file name:\n");
scanf("%s",tempfile);
fid11=fopen(tempfile,"w");
/* Initialization for the controller. 3 files are needed, one for the
controller, one for the FFF and one with miscellaneous variables. */
/* Initialization for controller */
fid=fopen("Cntrl.cfg","r");
fprintf(fid11,"Cntrl.cfg starts \n");
if(fid==NULL)
{
printf("Cannot open the cntrl.cfg data file!\n");
exit(1);
}
if(fid11==NULL)
{
printf("Cannot open the check data file!\n");
exit(1);
}
fscanf(fid,"%d",&states_ci);
fprintf(fid11,"%d ",states_ci);
fprintf(fid11,"Aci starts \n");
for (i=0;i<states_ci;i++)
{
for (j=0;j<states_ci;j++)
{
fscanf(fid,"%le",&Aci[i][j]);
fprintf(fid11,"%f ",Aci[i][j]);
}
fprintf(fid11,"\n");
}
fprintf(fid11,"Aci ends \n");
printf("Aci Matrix done \n");
fprintf(fid11,"Bci starts\n");
for (i=0;i<states_ci;i++)
{
for (j=0;j<INPUTS;j++)
{
fscanf(fid,"%le",&Bci[i][j]);
fprintf(fid11,"%f ",Bci[i][j]);
}
fprintf(fid11,"\n");
}
fprintf(fid11,"Bci ends \n");
printf("Bci Matrix done \n");
fprintf(fid11,"Cci starts\n");
for (i=0;i<OUTPUTS;i++)
A-11
Controller C Program Listing
{
for (j=0;j<states_ci;j++)
{
fscanf(fid,"%le",&Cci[i][j]);
fprintf(fid11,"%f ",Cci[i][j]);
}
fprintf(fid11,"\n");
}
fprintf(fid11,"Cci ends \n");
printf("Cci Matrix done \n");
fprintf(fid11,"Dci starts\n");
for (i=0;i<OUTPUTS;i++)
{
for (j=0;j<INPUTS;j++)
{
fscanf(fid,"%le",&Dci[i][j]);
fprintf(fid11,"%f ",Dci[i][j]);
}
fprintf(fid11,"\n");
}
fprintf(fid11,"Dci ends \n");
printf("Dci Matrix done\n ");
/* Lci is the anti-windup feedback matrix */
fprintf(fid11,"Lci starts\n");
for (i=0;i<states_ci;i++)
{
for (j=0;j<OUTPUTS;j++)
{
fscanf(fid,"%le",&Lci[i][j]);
fprintf(fid11,"%f ",Lci[i][j]);
}
fprintf(fid11,"\n");
}
fprintf(fid11,"Lci ends \n");
printf("Lci Matrix done\n ");
/* ICCS is the controller tracking matrix
fprintf(fid11,"ICCS starts\n");
for (i=0;i<states_ci;i++)
{
for (j=0;j<INPUTS+OUTPUTS;j++)
{
fscanf(fid,"%le",&ICCS[i][j]);
fprintf(fid11,"%f ",ICCS[i][j]);
}
fprintf(fid11,"\n");
}
fprintf(fid11,"ICCS ends \n");
printf("ICCS Matrix done\n ");
fclose(fid);
fprintf(fid11,"Cntrl.cfg ends \n");
printf("Closed Cntrl.cfg file\n");
A-12
*/
Controller C Program Listing
/* Initialization FFF */
fid=fopen("FFF.cfg","r");
fprintf(fid11,"FFF.cfg starts \n");
if(fid==NULL)
{
printf("Cannot open the model data file!\n");
exit(1);
}
if(fid11==NULL)
{
printf("Cannot open the check data file!\n");
exit(1);
}
fscanf(fid,"%d",&states_fo);
fprintf(fid11,"%d ",states_fo);
fprintf(fid11,"Afo starts \n");
for (i=0;i<states_fo;i++)
{
for (j=0;j<states_fo;j++)
{
fscanf(fid,"%le",&Afo[i][j]);
fprintf(fid11,"%f ",Afo[i][j]);
}
fprintf(fid11,"\n");
}
fprintf(fid11,"Afo ends \n");
printf("Afo Matrix done \n");
fprintf(fid11,"Bfo starts\n");
for (i=0;i<states_fo;i++)
{
for (j=0;j<INPUTS;j++)
{
fscanf(fid,"%le",&Bfo[i][j]);
fprintf(fid11,"%f ",Bfo[i][j]);
}
fprintf(fid11,"\n");
}
fprintf(fid11,"Bfo ends \n");
printf("Bfo Matrix done \n");
fprintf(fid11,"Cfo starts\n");
for (i=0;i<OUTPUTS;i++)
{
for (j=0;j<states_fo;j++)
{
fscanf(fid,"%le",&Cfo[i][j]);
fprintf(fid11,"%f ",Cfo[i][j]);
}
fprintf(fid11,"\n");
}
fprintf(fid11,"Cfo ends \n");
printf("Cfo Matrix done ");
fprintf(fid11,"Dfo starts\n");
for (i=0;i<OUTPUTS;i++)
{
A-13
Controller C Program Listing
for (j=0;j<INPUTS;j++)
{
fscanf(fid,"%le",&Dfo[i][j]);
fprintf(fid11,"%f ",Dfo[i][j]);
}
fprintf(fid11,"\n");
}
fprintf(fid11,"Dfo ends \n");
printf("Dci Matrix done \n");
fprintf(fid11,"IFCS starts\n");
for (i=0;i<states_fo;i++)
{
for (j=0;j<INPUTS+OUTPUTS;j++)
{
fscanf(fid,"%le",&IFCS[i][j]);
fprintf(fid11,"%f ",IFCS[i][j]);
}
fprintf(fid11,"\n");
}
fprintf(fid11,"IFCS ends \n");
printf("IFCS Matrix done \n");
fclose(fid);
fprintf(fid11,"FFF.cfg ends \n");
printf("Closed FFF.cfg file\n");
/* Initialization Miscellaneous matrices */
fid=fopen("Misc.cfg","r");
fprintf(fid11,"Misc.cfg starts \n");
if(fid==NULL)
{
printf("Cannot open the model data file!\n");
exit(1);
}
if(fid11==NULL)
{
printf("Cannot open the check data file!\n");
exit(1);
}
fprintf(fid11,"scales starts \n");
for (i=0;i<INPUTS;i++)
{
fscanf(fid,"%le",&scales[i]);
fprintf(fid11,"%f ",scales[i]);
scales_inv[i]=1/scales[i];
}
fprintf(fid11,"\n scales ends \n");
printf("scales matrix done\n");
fclose(fid);
fprintf(fid11,"Misc.cfg ends \n");
printf("Closed Misc.cfg file\n");
A-14
Controller C Program Listing
/* statesInit(); */
}
void statesInit()
{
int i,j;
double utrack[INPUTS+OUTPUTS];
printf("Starting statesInit function\n");
/* Intialization for xfo Prefilter states */
for (i=0;i<states_fo;i++)
{
xfo[i]=0;
for (j=0;j<INPUTS;j++)
{
xfo[i]=xfo[i]+IFCS[i][j]*ufo[j];
}
for (j=INPUTS;j<INPUTS+OUTPUTS;j++)
{
xfo[i]=xfo[i]+IFCS[i][j]*ufo[j-INPUTS];
}
// printf("xfo[%d] = %f\n",i,xfo[i]);
}
/* Prefilter output
yfo=Cfo*xfo+Dfo*ufo */
for (i=0;i<INPUTS;i++)
{
printf("ufo[%d] = %f\n",i,ufo[i]);
yfo[i]=0;
for(j=0;j<states_fo;j++)
{
yfo[i]=yfo[i]+Cfo[i][j]*xfo[j];
}
for(j=0;j<INPUTS;j++)
{
yfo[i]=yfo[i]+Dfo[i][j]*ufo[j];
}
printf("yfo[%d] = %f\n",i,yfo[i]);
}
/* Begin controller initialization (tracking)
Scaled input for the controller after FFF
uci=diag([.01,1.0,100.0])*(reference-yfo);
reference is given by In1SP[] */
for (i=0;i<INPUTS;i++)
{
uci[i]=scales[i]*(In1SP[i]-yfo[i]);
printf("uci[%d] = %f\n",i,uci[i]);
}
/* Combine the measurement vector with the manipulated vector
in new vector called utrack */
/* Hardcoded scaling for the tieback signals to invert
the output function generators */
A-15
Controller C Program Listing
tieback_scale[0]=(tieback[0]-100.0)/(-16.25);
tieback_scale[1]=(tieback[1]-65.4)/(-0.817);
tieback_scale[2]=tieback[2]/8.33;
for (i=0;i<INPUTS;i++)
{
utrack[i]=uci[i];
printf("utrack[%d] = %f\n",i,utrack[i]);
}
for (i=INPUTS;i<INPUTS+OUTPUTS;i++)
{
utrack[i]=tieback_scale[i-INPUTS];
printf("utrack[%d] = %f\n",i,utrack[i]);
}
/* Initialization for xci Controller states
for (i=0;i<states_ci;i++)
{
xci[i]=0;
for (j=0;j<INPUTS+OUTPUTS;j++)
{
xci[i]=xci[i]+ICCS[i][j]*utrack[j];
}
}
*/
/* Initialize controller outputs */
for (i=0;i<OUTPUTS;i++)
{
yci[i]=0;
for (j=0;j<states_ci;j++)
{
yci[i]=yci[i]+Cci[i][j]*xci[j];
}
for (j=0;j<INPUTS;j++)
{
yci[i]=yci[i]+Dci[i][j]*uci[j];
//printf("yci[%d] = %f\n",i,yci[i]);
}
}
/* hardcoded scaling to convert controller outputs to match Foxboro inputs.
this is done before checking for saturation so saturation
limits can be simple. This should eventually be changed to a
lookup table with linear interpolation */
yci_scale[0]=(yci[0]*-16.25)+100.0; /* Exhauster Damper Demand */
yci_scale[1]=(yci[1]*-0.817)+65.4; /* Hot Air Damper Demand */
yci_scale[2]= 8.33*yci[2]; /* Feeder Speed Demand */
for (i=0;i<OUTPUTS;i++)
{
printf("yci_scale[%d] = %f\n",i,yci_scale[i]);
if (yci_scale[i]<minsat[i])
{
yci_sat[i]=minsat[i];
}
else
{
A-16
Controller C Program Listing
if (yci_scale[i]>maxsat[i])
{
yci_sat[i]=maxsat[i];
}
else
{
yci_sat[i]=yci_scale[i];
}
}
Y[i]=yci_sat[i];
}
}
void controller()
{
int i,j;
double temp[MAXSTATES];
double tmp_AW;
/* Prefilter output
yfo=Cfo*xfo+Dfo*ufo */
for (i=0;i<INPUTS;i++)
{
printf("Filter inputs: ufo[%d] = %f\n",i,ufo[i]);
}
for (i=0;i<INPUTS;i++)
{
yfo[i]=0;
for(j=0;j<states_fo;j++)
{
yfo[i]=yfo[i]+Cfo[i][j]*xfo[j];
}
for(j=0;j<INPUTS;j++)
{
yfo[i]=yfo[i]+Dfo[i][j]*ufo[j];
}
}
for (i=0;i<INPUTS;i++)
{
printf("Filter outputs: yfo[%d] = %f\n",i,yfo[i]);
}
/* Scaled input for the controller after FFF
uci=diag([.01,1.0,100.0])*(reference-yfo);
reference is given by In1SP[] */
for (i=0;i<INPUTS;i++)
{
uci[i]=scales[i]*(In1SP[i]-yfo[i]);
printf("uci[%d] = %f; Setpoint[%d] = %f;\n",i,uci[i],i,In1SP[i]);
}
/* Controller output */
/*
yci=Cci*xci+Dci*uci
Conversion for Output to the supervisor
Y[0]=(yci[0]*-16.25)+100.0
A-17
Controller C Program Listing
Y[1]=(yci[1]*-0.817)+65.4
Y[2]=8.33*yci[2]
*/
/* Controller saturated output
/* Y=sat(Y);
*/
*/
for (i=0;i<OUTPUTS;i++)
{
yci[i]=0;
for (j=0;j<states_ci;j++)
{
yci[i]=yci[i]+Cci[i][j]*xci[j];
}
for (j=0;j<INPUTS;j++)
{
yci[i]=yci[i]+Dci[i][j]*uci[j];
}
printf("Controller outputs: yci[%d] = %f\n",i,yci[i]);
}
/* hardcoded scaling to convert controller outputs to match Foxboro inputs.
this is done before checking for saturation so saturation
limits can be simple. This should eventually be changed to a
lookup table with linear interpolation */
yci_scale[0]=(yci[0]*-16.25)+100.0; /* Exhauster Damper Demand */
yci_scale[1]=(yci[1]*-0.817)+65.4; /* Hot Air Damper Demand */
yci_scale[2]= 8.33*yci[2]; /* Feeder Speed Demand */
for (i=0;i<OUTPUTS;i++)
{
if (yci_scale[i]<minsat[i])
{
yci_sat[i]=minsat[i];
}
else
{
if (yci_scale[i]>maxsat[i])
{
yci_sat[i]=maxsat[i];
}
else
{
yci_sat[i]=yci_scale[i];
}
}
Y[i]=yci_sat[i];
printf("Outputs: Y[%d] = %f\n",i,Y[i]);
}
/* Antiwindup signal
AW=(yci_scale-yci_sat)*sat((yci_scale-yci_sat)'*(yci_scale-yci_sat))
*/
tmp_AW=0;
for (i=0;i<OUTPUTS;i++)
{
tmp_AW=tmp_AW+(yci_scale[i]-yci_sat[i])*(yci_scale[i]-yci_sat[i]);
A-18
Controller C Program Listing
}
if (tmp_AW<0)
{
tmp_AW=0;
}
else
{
if (tmp_AW>1)
{
tmp_AW=1;
}
}
printf("AW signal = %f\n", tmp_AW);
for (i=0;i<OUTPUTS;i++)
{
AW[i]=(yci_scale[i]-yci_sat[i])*tmp_AW;
}
/* State update for FFF
xfo(k+1)=Afo*xfo(k)+Bfo*ufo(k);*/
for (i=0;i<states_fo;i++)
{
temp[i]=0;
for (j=0;j<states_fo;j++)
{
temp[i]=temp[i]+Afo[i][j]*xfo[j];
}
for (j=0;j<INPUTS;j++)
{
temp[i]=temp[i]+Bfo[i][j]*ufo[j];
}
}
printf("States FFF \n");
for (i=0;i<states_fo;i++)
{
xfo[i]=temp[i];
#ifdef echo_screen
printf("%f ",xfo[i]);
#endif
}
/* State update for Controller
xci(k+1)=Aci*xci(k)+Bci*uci(k)+Lci*AW;*/
for (i=0;i<states_ci;i++)
{
temp[i]=0;
for (j=0;j<states_ci;j++)
{
temp[i]=temp[i]+Aci[i][j]*xci[j];
}
for (j=0;j<INPUTS;j++)
{
temp[i]=temp[i]+Bci[i][j]*uci[j];
}
for (j=0;j<OUTPUTS;j++)
{
A-19
Controller C Program Listing
temp[i]=temp[i]-Lci[i][j]*AW[j];
}
}
printf("States Controller \n");
for (i=0;i<states_ci;i++)
{
xci[i]=temp[i];
#ifdef echo_screen
printf("%f ",xci[i]);
#endif
}
}
A-20
Program:
I&C and Automation for Improved Plant
Operations
About EPRI
EPRI creates science and technology solutions for
the global energy and energy services industry. U.S.
electric utilities established the Electric Power
Research Institute in 1973 as a nonprofit research
consortium for the benefit of utility members, their
customers, and society. Now known simply as EPRI,
the company provides a wide range of innovative
products and services to more than 1000 energyrelated organizations in 40 countries. EPRI’s
multidisciplinary team of scientists and engineers
draws on a worldwide network of technical and
business expertise to help solve today’s toughest
energy and environmental problems.
EPRI. Electrify the World
© 2004 Electric Power Research Institute (EPRI), Inc. All rights
reserved. Electric Power Research Institute and EPRI are registered
service marks of the Electric Power Research Institute, Inc.
EPRI. ELECTRIFY THE WORLD is a service mark of the Electric
Power Research Institute, Inc.
Printed on recycled paper in the United States of America
1004423
EPRI • 3412 Hillview Avenue, Palo Alto, California 94304 • PO Box 10412, Palo Alto, California 94303 • USA
800.313.3774 • 650.855.2121 • askepri@epri.com • www.epri.com
Download