Vulcan
Aerospace Engineering Utilities Built on Janus
Loading...
Searching...
No Matches
DrydenTurbulence.hpp
Go to the documentation of this file.
1// Dryden Turbulence Model
2// Forming filters with rational transfer functions (MIL-F-8785C)
3#pragma once
4
5#include <cmath>
7
8namespace vulcan::dryden {
9
10// ============================================================================
11// Power Spectral Density Functions
12// ============================================================================
13
25template <typename Scalar>
26Scalar psd_longitudinal(const Scalar &omega, double sigma_u, double L_u) {
27 Scalar L_omega = L_u * omega;
28 return sigma_u * sigma_u * (2.0 * L_u / M_PI) /
29 (Scalar(1) + L_omega * L_omega);
30}
31
45template <typename Scalar>
46Scalar psd_lateral(const Scalar &omega, double sigma, double L) {
47 Scalar L_omega = L * omega;
48 Scalar L_omega_sq = L_omega * L_omega;
49 Scalar denom = Scalar(1) + L_omega_sq;
50 return sigma * sigma * (L / M_PI) * (Scalar(1) + Scalar(3) * L_omega_sq) /
51 (denom * denom);
52}
53
54// ============================================================================
55// Forming Filter State
56// ============================================================================
57
66template <typename Scalar> struct FilterState {
67 Scalar x_u;
68 Scalar x_v1;
69 Scalar x_v2;
70 Scalar x_w1;
71 Scalar x_w2;
72};
73
80template <typename Scalar> FilterState<Scalar> init_state() {
81 return FilterState<Scalar>{.x_u = Scalar(0),
82 .x_v1 = Scalar(0),
83 .x_v2 = Scalar(0),
84 .x_w1 = Scalar(0),
85 .x_w2 = Scalar(0)};
86}
87
88// ============================================================================
89// Filter Coefficients
90// ============================================================================
91
100 // Longitudinal (first-order filter)
101 double a_u;
102 double b_u;
103 double c_u;
104
105 // Lateral (second-order filter)
106 double a_v11, a_v12, a_v21, a_v22;
107 double b_v1, b_v2;
108 double c_v1, c_v2;
109
110 // Vertical (second-order filter, same structure as lateral)
112 double b_w1, b_w2;
113 double c_w1, c_w2;
114};
115
133inline FilterCoeffs
135 double airspeed, double dt) {
136 FilterCoeffs coeffs;
137
138 // Longitudinal filter (first-order)
139 // Time constant: τ_u = L_u / V
140 double tau_u = params.L_u / airspeed;
141 double alpha_u = dt / tau_u;
142 coeffs.a_u = std::exp(-alpha_u);
143 coeffs.b_u = std::sqrt(1.0 - coeffs.a_u * coeffs.a_u);
144 coeffs.c_u = params.sigma_u;
145
146 // Lateral filter (second-order)
147 // Time constant: τ_v = L_v / V
148 double tau_v = params.L_v / airspeed;
149 double alpha_v = dt / tau_v;
150 double exp_v = std::exp(-alpha_v);
151
152 // State-space representation for second-order system
153 // Using diagonal approximation for the 2x2 system
154 coeffs.a_v11 = exp_v;
155 coeffs.a_v12 = alpha_v * exp_v;
156 coeffs.a_v21 = 0.0;
157 coeffs.a_v22 = exp_v;
158
159 // Input and output scaling
160 double gain_v = params.sigma_v * std::sqrt(3.0 * params.L_v / airspeed);
161 coeffs.b_v1 = std::sqrt(1.0 - exp_v * exp_v);
162 coeffs.b_v2 = coeffs.b_v1 * std::sqrt(3.0) / 2.0;
163 coeffs.c_v1 = gain_v;
164 coeffs.c_v2 = gain_v * std::sqrt(3.0);
165
166 // Vertical filter (same structure as lateral)
167 double tau_w = params.L_w / airspeed;
168 double alpha_w = dt / tau_w;
169 double exp_w = std::exp(-alpha_w);
170
171 coeffs.a_w11 = exp_w;
172 coeffs.a_w12 = alpha_w * exp_w;
173 coeffs.a_w21 = 0.0;
174 coeffs.a_w22 = exp_w;
175
176 double gain_w = params.sigma_w * std::sqrt(3.0 * params.L_w / airspeed);
177 coeffs.b_w1 = std::sqrt(1.0 - exp_w * exp_w);
178 coeffs.b_w2 = coeffs.b_w1 * std::sqrt(3.0) / 2.0;
179 coeffs.c_w1 = gain_w;
180 coeffs.c_w2 = gain_w * std::sqrt(3.0);
181
182 return coeffs;
183}
184
185// ============================================================================
186// Filter Step Function
187// ============================================================================
188
203template <typename Scalar>
206 const Scalar &noise_u, const Scalar &noise_v, const Scalar &noise_w) {
207 // Longitudinal (1st order)
208 Scalar new_x_u = coeffs.a_u * state.x_u + coeffs.b_u * noise_u;
209 Scalar u_g = coeffs.c_u * new_x_u;
210 state.x_u = new_x_u;
211
212 // Lateral (2nd order)
213 Scalar new_x_v1 = coeffs.a_v11 * state.x_v1 + coeffs.a_v12 * state.x_v2 +
214 coeffs.b_v1 * noise_v;
215 Scalar new_x_v2 = coeffs.a_v21 * state.x_v1 + coeffs.a_v22 * state.x_v2 +
216 coeffs.b_v2 * noise_v;
217 Scalar v_g = coeffs.c_v1 * new_x_v1 + coeffs.c_v2 * new_x_v2;
218 state.x_v1 = new_x_v1;
219 state.x_v2 = new_x_v2;
220
221 // Vertical (2nd order)
222 Scalar new_x_w1 = coeffs.a_w11 * state.x_w1 + coeffs.a_w12 * state.x_w2 +
223 coeffs.b_w1 * noise_w;
224 Scalar new_x_w2 = coeffs.a_w21 * state.x_w1 + coeffs.a_w22 * state.x_w2 +
225 coeffs.b_w2 * noise_w;
226 Scalar w_g = coeffs.c_w1 * new_x_w1 + coeffs.c_w2 * new_x_w2;
227 state.x_w1 = new_x_w1;
228 state.x_w2 = new_x_w2;
229
230 return wind::GustVelocity<Scalar>{.u_g = u_g, .v_g = v_g, .w_g = w_g};
231}
232
233// ============================================================================
234// Convenience Functions
235// ============================================================================
236
248inline FilterCoeffs mil_spec_coeffs(double altitude,
250 double airspeed, double dt) {
251 wind::TurbulenceParams params = wind::mil_spec_params(altitude, severity);
252 return compute_filter_coeffs(params, airspeed, dt);
253}
254
255} // namespace vulcan::dryden
Definition DrydenTurbulence.hpp:8
FilterState< Scalar > init_state()
Initialize filter state to zero.
Definition DrydenTurbulence.hpp:80
wind::GustVelocity< Scalar > step(FilterState< Scalar > &state, const FilterCoeffs &coeffs, const Scalar &noise_u, const Scalar &noise_v, const Scalar &noise_w)
Step the Dryden forming filter.
Definition DrydenTurbulence.hpp:205
Scalar psd_lateral(const Scalar &omega, double sigma, double L)
Dryden lateral/vertical PSD.
Definition DrydenTurbulence.hpp:46
FilterCoeffs compute_filter_coeffs(const wind::TurbulenceParams< double > &params, double airspeed, double dt)
Compute forming filter coefficients.
Definition DrydenTurbulence.hpp:134
FilterCoeffs mil_spec_coeffs(double altitude, wind::TurbulenceSeverity severity, double airspeed, double dt)
Compute all filter coefficients for MIL-spec conditions.
Definition DrydenTurbulence.hpp:248
Scalar psd_longitudinal(const Scalar &omega, double sigma_u, double L_u)
Dryden longitudinal PSD.
Definition DrydenTurbulence.hpp:26
TurbulenceSeverity
Turbulence severity levels per MIL-HDBK-1797.
Definition WindTypes.hpp:85
TurbulenceParams< double > mil_spec_params(double altitude, TurbulenceSeverity severity)
Compute MIL-spec turbulence parameters for given conditions.
Definition WindTypes.hpp:125
Discretized Dryden forming filter coefficients.
Definition DrydenTurbulence.hpp:99
double a_u
State transition coefficient.
Definition DrydenTurbulence.hpp:101
double c_w2
Definition DrydenTurbulence.hpp:113
double a_v11
Definition DrydenTurbulence.hpp:106
double b_u
Input coefficient.
Definition DrydenTurbulence.hpp:102
double b_v1
Definition DrydenTurbulence.hpp:107
double a_v22
State transition matrix.
Definition DrydenTurbulence.hpp:106
double c_w1
Definition DrydenTurbulence.hpp:113
double b_v2
Input vector.
Definition DrydenTurbulence.hpp:107
double c_v2
Output vector.
Definition DrydenTurbulence.hpp:108
double a_v21
Definition DrydenTurbulence.hpp:106
double b_w1
Definition DrydenTurbulence.hpp:112
double a_w22
Definition DrydenTurbulence.hpp:111
double b_w2
Definition DrydenTurbulence.hpp:112
double a_w21
Definition DrydenTurbulence.hpp:111
double a_w11
Definition DrydenTurbulence.hpp:111
double c_v1
Definition DrydenTurbulence.hpp:108
double a_w12
Definition DrydenTurbulence.hpp:111
double a_v12
Definition DrydenTurbulence.hpp:106
double c_u
Output coefficient.
Definition DrydenTurbulence.hpp:103
Dryden forming filter state.
Definition DrydenTurbulence.hpp:66
Scalar x_v2
Lateral filter state 2.
Definition DrydenTurbulence.hpp:69
Scalar x_w2
Vertical filter state 2.
Definition DrydenTurbulence.hpp:71
Scalar x_v1
Lateral filter state 1.
Definition DrydenTurbulence.hpp:68
Scalar x_w1
Vertical filter state 1.
Definition DrydenTurbulence.hpp:70
Scalar x_u
Longitudinal filter state.
Definition DrydenTurbulence.hpp:67
Turbulent gust velocities in body frame.
Definition WindTypes.hpp:46
Turbulence intensity and scale parameters (MIL-F-8785C).
Definition WindTypes.hpp:73
Scalar sigma_u
Longitudinal RMS intensity [m/s].
Definition WindTypes.hpp:74
Scalar sigma_v
Lateral RMS intensity [m/s].
Definition WindTypes.hpp:75
Scalar L_w
Vertical scale length [m].
Definition WindTypes.hpp:79
Scalar L_u
Longitudinal scale length [m].
Definition WindTypes.hpp:77
Scalar L_v
Lateral scale length [m].
Definition WindTypes.hpp:78
Scalar sigma_w
Vertical RMS intensity [m/s].
Definition WindTypes.hpp:76