WSF
WsfSixDOF_PID.hpp
Go to the documentation of this file.
1// ****************************************************************************
2// CUI
3//
4// The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
5//
6// Copyright 2020 Infoscitex, a DCS Company. All rights reserved.
7//
8// The use, dissemination or disclosure of data in this file is subject to
9// limitation or restriction. See accompanying README and LICENSE for details.
10// ****************************************************************************
11
12#ifndef WSFSIXDOFPID_HPP
13#define WSFSIXDOFPID_HPP
14
15#include "wsf_six_dof_export.h"
16
17#include <stdio.h>
18#include <vector>
19
20class UtInputBlock;
21#include "UtOptional.hpp"
23
24// PID defines a Proportional, Integral, Derivative (PID) controller
25// class that is used by other autopilot classes. The PID includes the standard
26// Kp, Ki, and Kd parameters as well as five additional attributes:
27//
28// * MaxErrorAccum, limits accumulation to a max (absolute) value
29// * DerivativeLowpassAlpha, uses a low-pass filter on the derivative
30// * MaxErrorAntiWindup, halts accumulation if error is > value
31// * MinErrorAntiWindup, halts accumulation if error is < value
32// * Kt, which is an anti-windup to help address saturation
33//
34// It is also possible to use tabular gain data, if desired, based on a
35// controlling parameter (such as dynamic pressure).
36
37namespace wsf
38{
39namespace six_dof
40{
41class WSF_SIX_DOF_EXPORT PID
42{
43public:
44 PID() = default;
45 ~PID() = default;
46
47 PID& operator=(const PID& other) = delete;
48
49 PID* Clone() const;
50
51 PID(const PID& aSrc) = default;
52
53 // This function will provide an error warning if a mixture of tabular and scalar gain data is used.
54 void ProcessInput(UtInputBlock& aInputBlock);
55
56 // This is the main method is used to update the PID. It uses
57 // the set point and current value to determine the error.
58 double CalcOutputFromTarget(double aSetPoint, double aCurValue, double aSimTime_sec);
59
60 // This method includes output limits.
61 double CalcOutputFromTargetWithLimits(double aSetPoint,
62 double aCurValue,
63 double aSimTime_sec,
64 double aMinOutput,
65 double aMaxOutput);
66
67 // This method is used when the error needs to be calculated outside
68 // of the method, such as when dealing with circular values such
69 // as angles.
70 double CalcOutputFromError(double aError, double aCurValue, double aSimTime_sec);
71
72 // This method includes output limits.
73 double CalcOutputFromErrorWithLimits(double aError, double aCurValue, double aSimTime_sec, double aMinOutput, double aMaxOutput);
74
75 // This sets the current value of the plant
76 void SetCurrentValue(double aCurrentValue);
77
78 // This sets the target value (set point) for the plant
79 void SetTargetValue(double aTargetValue);
80
81 // This sets the controlling value (such as dynamic pressure). This only has
82 // an effect if the controlling value is enabled
83 void SetControllingValue(double aControllingValue);
84
85 // This zeroes out calculated state data, useful when resetting parent vehicle state
86 void ResetPidState();
87
88 // This zeroes out sim-time data, useful when returning from wash-in
89 void ResetPidTiming();
90
91 // This gets the current gains of the PID
92 std::vector<PidGainData>* GetPidGainTableData();
93
94 // This sets the gains of the PID
95 void SetPidGainTableData(const std::vector<PidGainData>& aDataTables);
96
97 // This gets the current values of the PID
98 void GetPidValueData(SinglePidValueData& aData) const;
99
100 // This sets a bias (also know as "feed forward") for the proportional channel.
101 // This bias will remain in effect until "cleared" by a value of zero.
102 void SetBias(double aBias);
103 void SetFeedForward(double aFeedForward);
104
105 // This returns true if feed forward is active, and returns the
106 // feed forward (bias) value by reference. Otherwise it returns
107 // false and the reference value is undefined.
108 bool GetFeedForward(double& aFeedForward);
109
110 // This should be used to setup items in the gain table before calling the
111 // various "set" functions such as SetKpTable, SetKtAntiWindupTable, etc. to
112 // avoid an error in the set function due to insufficient elements in the table.
113 void AddElementsToGainTable(size_t aTotalElementsInTable);
114
115 // This provides the sim time interval at which the PID operates
116 double GetUpdateInterval_sec();
117
118 // This attempts to set the update interval, but defers to a pre-existing value
119 // Returns true if the interval was successfully set by this function
120 bool TrySetUpdateInterval_sec(double aInterval_sec);
121
122private:
123 void ProcessPidGainTableBlock(UtInputBlock& aInputBlock,
124 PidGainData& aTableElement,
125 bool& aValidControllingValue,
126 bool& aValidKpGain,
127 bool& aValidKiGain,
128 bool& aValidKdGain,
129 bool& aValidMaxAccum,
130 bool& aValidMaxErrorZero,
131 bool& aValidMinErrorZero,
132 bool& aValidLowpassAlpha,
133 bool& aValidKtAntiWindup);
134
135 double GetOutputWithLimits(double aSimTime_sec, double aMinOutput, double aMaxOutput, bool aUseLimits);
136
137 void CalcPidGainsData(std::vector<PidGainData>& aTables,
138 double aControllingValue,
139 double& aKpGain,
140 double& aKiGain,
141 double& aKdGain,
142 double& aLowpassAlpha,
143 double& aMaxAccum,
144 double& aMaxErrorZero,
145 double& aMinErrorZero,
146 double& aKtAntiWindup);
147
148 float TruncatePidGain(float aGain);
149
150 static void CopyPidGainsData(std::vector<PidGainData>& aTargetTables, const std::vector<PidGainData>& aSourceTables);
151
152 double mLastSimTime_sec = 0.0;
153 ut::optional<double> mUpdateInterval_sec;
154
155 double mSetPoint = 0.0; // PID set point (target setting)
156 double mCurrentValue = 0.0; // Current value of PID
157 double mCurrentError = 0.0; // Current error of PID
158 double mCurrentDerivative = 0.0; // Current derivative of PID
159
160 double mLastValue = 0.0; // Previous value
161 double mLastError = 0.0; // Previous error
162 double mLastDerivative = 0.0; // Previous derivative
163
164 double mErrorAccum = 0.0; // Accumulated error
165 double mPrelimitedOutput = 0.0; // Output value before any limiting
166 double mOutput = 0.0; // Current output value
167
168 double mKpOutputContrib = 0.0; // Most recent contribution to output by Kp
169 double mKiOutputContrib = 0.0; // Most recent contribution to output by Ki
170 double mKdOutputContrib = 0.0; // Most recent contribution to output by Kd
171
172 // The flags are used by both single data (above) and tabular data (below)
173
174 // These tables provide PID gain data when mEnableControllingValue is true
175 std::vector<PidGainData> mGainTables;
176
177 bool mProportionalBiasActive = false;
178 double mProportionalBiasValue = 0.0; // This is a bias that is added to the proportional channel
179
180 // Controlling Value -- This allows tabular PID gain data, often using
181 // dynamic pressure as the "controlling value". For example, Kp can use
182 // a table of values and interpolate based on the current controlling
183 // value. This allows Kp to be a function of dynamic pressure, for instance.
184 double mControllingValue = 0.0;
185};
186} // namespace six_dof
187} // namespace wsf
188
189#endif // WSFSIXDOFPID_H
std::vector< PidGainData > * GetPidGainTableData()
Definition WsfSixDOF_PID.cpp:624
double CalcOutputFromTargetWithLimits(double aSetPoint, double aCurValue, double aSimTime_sec, double aMinOutput, double aMaxOutput)
Definition WsfSixDOF_PID.cpp:392
void SetControllingValue(double aControllingValue)
Definition WsfSixDOF_PID.cpp:675
bool GetFeedForward(double &aFeedForward)
Definition WsfSixDOF_PID.cpp:664
void SetFeedForward(double aFeedForward)
Definition WsfSixDOF_PID.cpp:658
void SetCurrentValue(double aCurrentValue)
Definition WsfSixDOF_PID.cpp:581
void ResetPidTiming()
Definition WsfSixDOF_PID.cpp:702
void GetPidValueData(SinglePidValueData &aData) const
Definition WsfSixDOF_PID.cpp:638
double CalcOutputFromTarget(double aSetPoint, double aCurValue, double aSimTime_sec)
Definition WsfSixDOF_PID.cpp:418
void SetTargetValue(double aTargetValue)
Definition WsfSixDOF_PID.cpp:586
void ResetPidState()
Definition WsfSixDOF_PID.cpp:680
bool TrySetUpdateInterval_sec(double aInterval_sec)
Definition WsfSixDOF_PID.cpp:596
double GetUpdateInterval_sec()
Definition WsfSixDOF_PID.cpp:591
PID(const PID &aSrc)=default
void AddElementsToGainTable(size_t aTotalElementsInTable)
Definition WsfSixDOF_PID.cpp:607
double CalcOutputFromErrorWithLimits(double aError, double aCurValue, double aSimTime_sec, double aMinOutput, double aMaxOutput)
Definition WsfSixDOF_PID.cpp:405
void SetBias(double aBias)
Definition WsfSixDOF_PID.cpp:652
double CalcOutputFromError(double aError, double aCurValue, double aSimTime_sec)
Definition WsfSixDOF_PID.cpp:427
void SetPidGainTableData(const std::vector< PidGainData > &aDataTables)
Definition WsfSixDOF_PID.cpp:629
PID * Clone() const
Definition WsfSixDOF_PID.cpp:20
void ProcessInput(UtInputBlock &aInputBlock)
Definition WsfSixDOF_PID.cpp:25
PID & operator=(const PID &other)=delete
Definition WsfSA_Processor.hpp:35
Function definitions for those who need run-time access to the version.
Definition WsfComm.cpp:32
Definition WsfSixDOF_VehicleData.hpp:80
Definition WsfSixDOF_VehicleData.hpp:96
Copyrights Multiple, All Rights Reserved