|
| 1 | +# Input Signal Generation |
| 2 | + |
| 3 | +This page describes the input signal generation capabilities of ControlSystemIdentification.jl. The `InputSignals` submodule provides functions for generating various types of excitation signals commonly used in system identification. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Proper excitation signal design is crucial for successful system identification. The quality of the input signal directly affects the quality of the identified model. This package provides several standard signal types: |
| 8 | + |
| 9 | +- **PRBS (Pseudo-Random Binary Sequence)**: Binary signals with white noise-like properties |
| 10 | +- **Chirp signals**: Frequency sweeps for analyzing system response across frequency ranges |
| 11 | +- **Multi-sine signals**: Controlled spectral content at specific frequencies |
| 12 | +- **Step signals**: Fundamental for transient response analysis |
| 13 | + |
| 14 | +## PRBS (Pseudo-Random Binary Sequence) |
| 15 | + |
| 16 | +```@docs |
| 17 | +prbs |
| 18 | +``` |
| 19 | + |
| 20 | +### Example |
| 21 | + |
| 22 | +```@example input_signals |
| 23 | +using ControlSystemIdentification, Plots |
| 24 | +
|
| 25 | +# Generate a standard PRBS signal |
| 26 | +N = 200 |
| 27 | +u_prbs = prbs(N; seed=42) |
| 28 | +
|
| 29 | +# Generate a PRBS with custom amplitude levels |
| 30 | +u_custom = prbs(N; low=0, high=5, seed=42) |
| 31 | +
|
| 32 | +# Generate a slower PRBS with period=10 (holds values for 10 samples) |
| 33 | +u_slow = prbs(N; period=10, seed=42) |
| 34 | +
|
| 35 | +# Plot the signals |
| 36 | +p1 = plot(u_prbs, title="Standard PRBS", xlabel="Sample", ylabel="Amplitude", |
| 37 | + label="u(t)", linewidth=2) |
| 38 | +p2 = plot(u_custom, title="Custom PRBS (0 to 5)", xlabel="Sample", ylabel="Amplitude", |
| 39 | + label="u(t)", linewidth=2) |
| 40 | +p3 = plot(u_slow, title="Slow PRBS (period=10)", xlabel="Sample", ylabel="Amplitude", |
| 41 | + label="u(t)", linewidth=2) |
| 42 | +
|
| 43 | +plot(p1, p2, p3, layout=(3,1), size=(600, 600)) |
| 44 | +``` |
| 45 | + |
| 46 | +## Chirp Signals |
| 47 | + |
| 48 | +```@docs |
| 49 | +chirp |
| 50 | +``` |
| 51 | + |
| 52 | +### Example |
| 53 | + |
| 54 | +```@example input_signals |
| 55 | +# Generate chirp signals |
| 56 | +N = 1000 |
| 57 | +Ts = 0.01 |
| 58 | +f0 = 1.0 # Start frequency (Hz) |
| 59 | +f1 = 10.0 # End frequency (Hz) |
| 60 | +
|
| 61 | +u_log = chirp(N; Ts, f0, f1, logspace=true) |
| 62 | +u_lin = chirp(N; Ts, f0, f1, logspace=false) |
| 63 | +
|
| 64 | +# Time vector for plotting |
| 65 | +t = (0:N-1) * Ts |
| 66 | +
|
| 67 | +# Plot time domain signals |
| 68 | +p1 = plot(t, u_log, title="Logarithmic Chirp", xlabel="Time (s)", ylabel="Amplitude", |
| 69 | + label="u(t)", linewidth=1) |
| 70 | +p2 = plot(t, u_lin, title="Linear Chirp", xlabel="Time (s)", ylabel="Amplitude", |
| 71 | + label="u(t)", linewidth=1) |
| 72 | +
|
| 73 | +plot(p1, p2, layout=(2,1), size=(600, 400)) |
| 74 | +``` |
| 75 | + |
| 76 | +### Frequency Content Analysis |
| 77 | + |
| 78 | +```@example input_signals |
| 79 | +using ControlSystemIdentification.FFTW |
| 80 | +
|
| 81 | +# Analyze frequency content of the chirp signals |
| 82 | +U_log = abs.(fft(u_log)) |
| 83 | +U_lin = abs.(fft(u_lin)) |
| 84 | +
|
| 85 | +# Frequency axis (only plot positive frequencies) |
| 86 | +freqs = (0:N-1) / (N*Ts) |
| 87 | +half_N = N÷2 |
| 88 | +
|
| 89 | +# Plot frequency domain (first half only, up to Nyquist frequency) |
| 90 | +p1 = plot(freqs[2:half_N], U_log[2:half_N], title="Logarithmic Chirp Spectrum", |
| 91 | + xlabel="Frequency (Hz)", ylabel="Magnitude", label="Log chirp", |
| 92 | + xscale=:log10, yscale=:log10, linewidth=2) |
| 93 | +p2 = plot(freqs[2:half_N], U_lin[2:half_N], title="Linear Chirp Spectrum", |
| 94 | + xlabel="Frequency (Hz)", ylabel="Magnitude", label="Linear chirp", |
| 95 | + xscale=:log10, yscale=:log10, linewidth=2) |
| 96 | +vline!(p1, [f0, f1], label="", linestyle=:dash, color=:red, alpha=0.7) |
| 97 | +vline!(p2, [f0, f1], label="", linestyle=:dash, color=:red, alpha=0.7) |
| 98 | +
|
| 99 | +plot(p1, p2, layout=(2,1), size=(600, 400)) |
| 100 | +``` |
| 101 | + |
| 102 | +Chirp signals are excellent for: |
| 103 | +- Frequency response estimation |
| 104 | +- Analyzing system behavior across frequency ranges |
| 105 | +- Identifying resonances and anti-resonances |
| 106 | +- Logarithmic chirps provide equal energy per frequency decade |
| 107 | + |
| 108 | +## Multi-sine Signals |
| 109 | + |
| 110 | +```@docs |
| 111 | +multisine |
| 112 | +``` |
| 113 | + |
| 114 | +### Example |
| 115 | + |
| 116 | +```@example input_signals |
| 117 | +# Generate multi-sine signal |
| 118 | +N = 1000 |
| 119 | +Ts = 0.01 |
| 120 | +frequencies = [0.5, 2.0, 5.0, 10.0] # Hz |
| 121 | +
|
| 122 | +u_multi = multisine(N; frequencies=frequencies, Ts) |
| 123 | +
|
| 124 | +# Time vector |
| 125 | +t = (0:N-1) * Ts |
| 126 | +
|
| 127 | +# Plot time domain signal |
| 128 | +p1 = plot(t, u_multi, title="Multi-sine Signal", xlabel="Time (s)", ylabel="Amplitude", |
| 129 | + label="u(t)", linewidth=1) |
| 130 | +
|
| 131 | +# Analyze frequency content |
| 132 | +U_multi = abs.(fft(u_multi)) |
| 133 | +freqs = (0:N-1) / (N*Ts) |
| 134 | +half_N = N÷2 |
| 135 | +
|
| 136 | +# Plot frequency domain |
| 137 | +p2 = plot(freqs[1:half_N], U_multi[1:half_N], title="Multi-sine Spectrum", |
| 138 | + xlabel="Frequency (Hz)", ylabel="Magnitude", label="Spectrum", |
| 139 | + linewidth=2) |
| 140 | +
|
| 141 | +# Mark the target frequencies with vertical lines |
| 142 | +for f in frequencies |
| 143 | + if f <= freqs[half_N] |
| 144 | + plot!(p2, [f, f], [0, maximum(U_multi[1:half_N])], |
| 145 | + label="", linestyle=:dash, color=:red, alpha=0.7) |
| 146 | + end |
| 147 | +end |
| 148 | +
|
| 149 | +plot(p1, p2, layout=(2,1), size=(600, 400)) |
| 150 | +``` |
| 151 | + |
| 152 | +Multi-sine signals are ideal for: |
| 153 | +- Avoiding problematic frequencies (resonances) |
| 154 | +- Controlled spectral content |
| 155 | +- Nonlinear system identification |
| 156 | +- Minimizing peak factor (crest factor) |
| 157 | + |
| 158 | +## Step Signals |
| 159 | + |
| 160 | +```@docs |
| 161 | +step_signal |
| 162 | +``` |
| 163 | + |
| 164 | +### Example |
| 165 | + |
| 166 | +```@example input_signals |
| 167 | +# Generate step signals |
| 168 | +N = 200 |
| 169 | +Ts = 0.1 |
| 170 | +u_step1 = step_signal(N; step_time=5.0, Ts) # Step at 5.0 seconds |
| 171 | +u_step2 = step_signal(N; step_time=10.0, Ts) # Step at 10.0 seconds |
| 172 | +
|
| 173 | +# Plot the signals |
| 174 | +p1 = plot(u_step1, title="Step at 5.0 seconds", xlabel="Sample", ylabel="Amplitude", |
| 175 | + label="u(t)", linewidth=2) |
| 176 | +p2 = plot(u_step2, title="Step at 10.0 seconds", xlabel="Sample", ylabel="Amplitude", |
| 177 | + label="u(t)", linewidth=2) |
| 178 | +
|
| 179 | +plot(p1, p2, layout=(2,1), size=(600, 400)) |
| 180 | +``` |
| 181 | + |
| 182 | +## Design Guidelines Video |
| 183 | + |
| 184 | +```@raw html |
| 185 | +<iframe style="height: 315px; width: 560px" src="https://www.youtube.com/embed/QMO8cDpjw5U?si=MZuC1BwKoLtgGJ_y" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
| 186 | +``` |
0 commit comments