Add analysis on the generation of time domain signal to match a PSD
BIN
figs/probability_density_function_adc.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
figs/psd_comparison.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
figs/psd_ground_motion.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
figs/psd_original.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
figs/signal_time_domain.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
figs/simulink_psd_generate.png
Normal file
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 47 KiB |
628
index.html
@ -3,7 +3,7 @@
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<!-- 2019-08-15 jeu. 12:31 -->
|
||||
<!-- 2019-12-02 lun. 11:22 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Compute Spectral Densities of signals with Matlab</title>
|
||||
@ -270,29 +270,77 @@ for the JavaScript code in this tag.
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="org-div-home-and-up">
|
||||
<a accesskey="h" href="./index.html"> UP </a>
|
||||
|
|
||||
<a accesskey="H" href="./index.html"> HOME </a>
|
||||
</div><div id="content">
|
||||
<div id="content">
|
||||
<h1 class="title">Compute Spectral Densities of signals with Matlab</h1>
|
||||
<div id="table-of-contents">
|
||||
<h2>Table of Contents</h2>
|
||||
<div id="text-table-of-contents">
|
||||
<ul>
|
||||
<li><a href="#org7cc41f2">1. Sensitivity of the instrumentation</a></li>
|
||||
<li><a href="#orgac6792b">2. Convert the time domain from volts to velocity</a></li>
|
||||
<li><a href="#org01a363c">3. Power Spectral Density and Amplitude Spectral Density</a></li>
|
||||
<li><a href="#org90edcdd">4. Modification of a signal's Power Spectral Density when going through an LTI system</a></li>
|
||||
<li><a href="#orgfb2734c">5. From PSD of the velocity to the PSD of the displacement</a></li>
|
||||
<li><a href="#org9310776">1. Spectral Analysis - Basics</a>
|
||||
<ul>
|
||||
<li><a href="#org2041123">1.1. PSD of ADC quantization noise</a></li>
|
||||
<li><a href="#orgb854582">1.2. Sensitivity of the instrumentation</a></li>
|
||||
<li><a href="#org78ed1de">1.3. Convert the time domain from volts to velocity</a></li>
|
||||
<li><a href="#org8775e6e">1.4. Power Spectral Density and Amplitude Spectral Density</a></li>
|
||||
<li><a href="#orgcba62e6">1.5. Modification of a signal's Power Spectral Density when going through an LTI system</a></li>
|
||||
<li><a href="#org3adf2bb">1.6. From PSD of the velocity to the PSD of the displacement</a></li>
|
||||
<li><a href="#org83b26dc">1.7. Cumulative Power/Amplitude Spectrum</a></li>
|
||||
<li><a href="#org5ace856">1.8. <span class="todo TODO">TODO</span> Add best practices from the Article and simple snippet that works</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#orga6e1da0">2. Technique 1 : Approximation with a transfer function</a>
|
||||
<ul>
|
||||
<li><a href="#orge44fa26">2.1. Signal's PSD</a></li>
|
||||
<li><a href="#org35e87c7">2.2. Transfer Function that approximate the ASD</a></li>
|
||||
<li><a href="#org5b0597b">2.3. Generated Time domain signal</a></li>
|
||||
<li><a href="#org2bb9116">2.4. Comparison of the Power Spectral Densities</a></li>
|
||||
<li><a href="#org6d66594">2.5. Simulink</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#orgd4fbbd9">3. Technique 2 : IFFT</a>
|
||||
<ul>
|
||||
<li><a href="#org98e4f2a">3.1. Signal's PSD</a></li>
|
||||
<li><a href="#orgcb607b3">3.2. Algorithm</a></li>
|
||||
<li><a href="#org4ff718c">3.3. Obtained Time Domain Signal</a></li>
|
||||
<li><a href="#orgc9527e8">3.4. PSD Comparison</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#org7fe2f42">4. <span class="todo TODO">TODO</span> Compute the Noise level and Signal level from PSD</a>
|
||||
<ul>
|
||||
<li><a href="#org640e940">4.1. Computation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This document presents the mathematics as well as the matlab scripts to do the spectral analysis of a measured signal.
|
||||
This document presents the mathematics as well as the matlab scripts to do various spectral analysis on a measured signal.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Some matlab documentation about Spectral Analysis can be found <a href="https://fr.mathworks.com/help/signal/ug/spectral-analysis.html">here</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
First, in section <a href="#orgd149260">1</a>, some basics of spectral analysis are presented.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In some cases, we want to generate a time domain signal with defined Power Spectral Density.
|
||||
Two methods are presented in sections <a href="#org2ea1c7b">2</a> and <a href="#org84b5cd1">3</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Finally, some notes are done on how to compute the noise level and signal level from a given Power Spectral Density in section <a href="#org7bce553">4</a>.
|
||||
</p>
|
||||
|
||||
<div id="outline-container-org9310776" class="outline-2">
|
||||
<h2 id="org9310776"><span class="section-number-2">1</span> Spectral Analysis - Basics</h2>
|
||||
<div class="outline-text-2" id="text-1">
|
||||
<p>
|
||||
<a id="orgd149260"></a>
|
||||
</p>
|
||||
<p>
|
||||
Typically this signal is coming from an inertial sensor, a force sensor or any other sensor.
|
||||
</p>
|
||||
@ -300,10 +348,85 @@ Typically this signal is coming from an inertial sensor, a force sensor or any o
|
||||
<p>
|
||||
We here take the example of a signal coming from a Geophone measurement the vertical velocity of the floor at the ESRF.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org7cc41f2" class="outline-2">
|
||||
<h2 id="org7cc41f2"><span class="section-number-2">1</span> Sensitivity of the instrumentation</h2>
|
||||
<div class="outline-text-2" id="text-1">
|
||||
<div id="outline-container-org2041123" class="outline-3">
|
||||
<h3 id="org2041123"><span class="section-number-3">1.1</span> PSD of ADC quantization noise</h3>
|
||||
<div class="outline-text-3" id="text-1-1">
|
||||
<p>
|
||||
This is taken from <a href="https://www.allaboutcircuits.com/technical-articles/quantization-nois-amplitude-quantization-error-analog-to-digital-converters/">here</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Let's note:
|
||||
</p>
|
||||
<ul class="org-ul">
|
||||
<li>\(q\) is the corresponding value in [V] of the least significant bit (LSB)</li>
|
||||
<li>\(\Delta V\) is the full range of the ADC in [V]</li>
|
||||
<li>\(n\) is the number of ADC's bits</li>
|
||||
<li>\(f_s\) is the sample frequency in [Hz]</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Let's suppose that the ADC is ideal.
|
||||
The only noise comes from the quantization error.
|
||||
Interestingly, the noise amplitude is uniformly distributed.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The quantization noise can take a value between \(\pm q/2\), and the probability density function is constant in this range (i.e., it’s a uniform distribution).
|
||||
Since the integral of the probability density function is equal to one, its value will be \(1/q\) for \(-q/2 < e < q/2\) (Fig. <a href="#orgee629ae">1</a>).
|
||||
</p>
|
||||
|
||||
|
||||
<div id="orgee629ae" class="figure">
|
||||
<p><img src="figs/probability_density_function_adc.png" alt="probability_density_function_adc.png" />
|
||||
</p>
|
||||
<p><span class="figure-number">Figure 1: </span>Probability density function \(p(e)\) of the ADC error \(e\)</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Now, we can calculate the time average power of the quantization noise as
|
||||
</p>
|
||||
\begin{equation}
|
||||
P_q = \int_{-q/2}^{q/2} e^2 p(e) de = \frac{q^2}{12}
|
||||
\end{equation}
|
||||
|
||||
|
||||
<p>
|
||||
The other important parameter of a noise source is the power spectral density (PSD), which indicates how the noise power spreads in different frequency bands.
|
||||
To find the power spectral density, we need to calculate the Fourier transform of the autocorrelation function of the noise.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Assuming that the noise samples are not correlated with one another, we can approximate the autocorrelation function with a delta function in the time domain.
|
||||
Since the Fourier transform of a delta function is equal to one, the <b>power spectral density will be frequency independent</b>.
|
||||
Therefore, the quantization noise is white noise with total power equal to \(P_q = \frac{q^2}{12}\).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Thus, the two-sided PSD (from \(\frac{-f_s}{2}\) to \(\frac{f_s}{2}\)), we should divide the noise power \(P_q\) by \(f_s\):
|
||||
</p>
|
||||
|
||||
\begin{equation}
|
||||
\int_{-f_s/2}^{f_s/2} \Gamma(f) d f = f_s \Gamma = \frac{q^2}{12}
|
||||
\end{equation}
|
||||
|
||||
<p>
|
||||
Finally:
|
||||
</p>
|
||||
\begin{equation}
|
||||
\begin{align}
|
||||
\Gamma &= \frac{q^2}{12 f_s} \\
|
||||
&= \frac{\left(\frac{\Delta V}{2^n}\right)^2}{12 f_s} \text{ in } \left[ \frac{V^2}{Hz} \right]
|
||||
\end{align}
|
||||
\end{equation}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-orgb854582" class="outline-3">
|
||||
<h3 id="orgb854582"><span class="section-number-3">1.2</span> Sensitivity of the instrumentation</h3>
|
||||
<div class="outline-text-3" id="text-1-2">
|
||||
<p>
|
||||
The measured signal \(x\) by the ADC is in Volts.
|
||||
The corresponding real velocity \(v\) in m/s.
|
||||
@ -314,17 +437,17 @@ To obtain the real quantity as measured by the sensor, one have to know the sens
|
||||
</p>
|
||||
|
||||
|
||||
<div id="org0a5ff56" class="figure">
|
||||
<div id="orgad69fc7" class="figure">
|
||||
<p><img src="figs/velocity_to_voltage.png" alt="velocity_to_voltage.png" />
|
||||
</p>
|
||||
<p><span class="figure-number">Figure 1: </span>Schematic of the instrumentation used for the measurement</p>
|
||||
<p><span class="figure-number">Figure 2: </span>Schematic of the instrumentation used for the measurement</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-orgac6792b" class="outline-2">
|
||||
<h2 id="orgac6792b"><span class="section-number-2">2</span> Convert the time domain from volts to velocity</h2>
|
||||
<div class="outline-text-2" id="text-2">
|
||||
<div id="outline-container-org78ed1de" class="outline-3">
|
||||
<h3 id="org78ed1de"><span class="section-number-3">1.3</span> Convert the time domain from volts to velocity</h3>
|
||||
<div class="outline-text-3" id="text-1-3">
|
||||
<p>
|
||||
Let's say, we know that the sensitivity of the geophone used is
|
||||
\[ G_g(s) = G_0 \frac{\frac{s}{2\pi f_0}}{1 + \frac{s}{2\pi f_0}} \quad \left[\frac{V}{m/s}\right] \]
|
||||
@ -348,11 +471,11 @@ And the gain of the amplifier is 1000: \(G_m(s) = 1000\).
|
||||
</div>
|
||||
|
||||
<p>
|
||||
If \({G_m(s)}^{-1} {G_g(s)}^{-1}\) is proper, we can simulate this dynamical system to go from the voltage to the velocity units (figure <a href="#orgd3dfdc8">2</a>).
|
||||
If \({G_m(s)}^{-1} {G_g(s)}^{-1}\) is proper, we can simulate this dynamical system to go from the voltage to the velocity units (figure <a href="#orgf9120d4">3</a>).
|
||||
</p>
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">data = load<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'mat/data_028.mat', 'data'</span><span class="org-rainbow-delimiters-depth-1">)</span>; data = data.data;
|
||||
<pre class="src src-matlab">data = load<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'mat/data_028.mat'</span>, <span class="org-string">'data'</span><span class="org-rainbow-delimiters-depth-1">)</span>; data = data.data;
|
||||
|
||||
t = data<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-type">:</span>, <span class="org-highlight-numbers-number">3</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% [s]</span>
|
||||
x = data<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-type">:</span>, <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">-</span>mean<span class="org-rainbow-delimiters-depth-1">(</span>data<span class="org-rainbow-delimiters-depth-2">(</span><span class="org-type">:</span>, <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% The offset if removed (coming from the voltage amplifier) [v]</span>
|
||||
@ -362,17 +485,17 @@ dt = t<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-high
|
||||
</div>
|
||||
|
||||
|
||||
<div id="orgd3dfdc8" class="figure">
|
||||
<div id="orgf9120d4" class="figure">
|
||||
<p><img src="figs/voltage_to_velocity.png" alt="voltage_to_velocity.png" />
|
||||
</p>
|
||||
<p><span class="figure-number">Figure 2: </span>Schematic of the instrumentation used for the measurement</p>
|
||||
<p><span class="figure-number">Figure 3: </span>Schematic of the instrumentation used for the measurement</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
We simulate this system with matlab:
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">v = lsim<span class="org-rainbow-delimiters-depth-1">(</span>inv<span class="org-rainbow-delimiters-depth-2">(</span>Gg<span class="org-type">*</span>Gm<span class="org-rainbow-delimiters-depth-2">)</span>, v, t<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
<pre class="src src-matlab">v = lsim<span class="org-rainbow-delimiters-depth-1">(</span>inv<span class="org-rainbow-delimiters-depth-2">(</span>Gg<span class="org-type">*</span>Gm<span class="org-rainbow-delimiters-depth-2">)</span>, x, t<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@ -382,22 +505,22 @@ And we plot the obtained velocity
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab"><span class="org-type">figure</span>;
|
||||
plot<span class="org-rainbow-delimiters-depth-1">(</span>t, v<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">"Time [s]"</span><span class="org-string"><span class="org-rainbow-delimiters-depth-1">)</span></span><span class="org-string">; ylabel</span><span class="org-string"><span class="org-rainbow-delimiters-depth-1">(</span></span><span class="org-string">"Velocity [m/s]"</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">"Time </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">s</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">"</span><span class="org-rainbow-delimiters-depth-1">)</span>; ylabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">"Velocity </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">m/s</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">"</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="org4dd86c0" class="figure">
|
||||
<div id="org8b13b82" class="figure">
|
||||
<p><img src="figs/velocity_time.png" alt="velocity_time.png" />
|
||||
</p>
|
||||
<p><span class="figure-number">Figure 3: </span>Measured Velocity</p>
|
||||
<p><span class="figure-number">Figure 4: </span>Measured Velocity</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org01a363c" class="outline-2">
|
||||
<h2 id="org01a363c"><span class="section-number-2">3</span> Power Spectral Density and Amplitude Spectral Density</h2>
|
||||
<div class="outline-text-2" id="text-3">
|
||||
<div id="outline-container-org8775e6e" class="outline-3">
|
||||
<h3 id="org8775e6e"><span class="section-number-3">1.4</span> Power Spectral Density and Amplitude Spectral Density</h3>
|
||||
<div class="outline-text-3" id="text-1-4">
|
||||
<p>
|
||||
We now have the velocity in the time domain:
|
||||
\[ v(t)\ [m/s] \]
|
||||
@ -437,27 +560,27 @@ ylabel<span class="org-rainbow-delimiters-depth-1">(</span>'Power Spectral Densi
|
||||
The Amplitude Spectral Density (ASD) is the square root of the Power Spectral Density:
|
||||
</p>
|
||||
\begin{equation}
|
||||
\Gamma_{vv}(f) = \sqrt{S_{vv}(f)} \quad \left[ \frac{m/s}{\sqrt{Hz}} \right]
|
||||
\Gamma_{vv}(f) = \sqrt{S_{vv}(f)} \quad \left[ \frac{m/s}{\sqrt{Hz}} \right]
|
||||
\end{equation}
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab"><span class="org-type">figure</span>;
|
||||
loglog<span class="org-rainbow-delimiters-depth-1">(</span>f, sqrt<span class="org-rainbow-delimiters-depth-2">(</span>Sv<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Frequency </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">Hz</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
ylabel<span class="org-rainbow-delimiters-depth-1">(</span>'Amplitude Spectral Density $<span class="org-type">\</span>left<span class="org-rainbow-delimiters-depth-2">[</span><span class="org-type">\</span>frac<span class="org-rainbow-delimiters-depth-3">{</span>m<span class="org-type">/</span>s<span class="org-rainbow-delimiters-depth-3">}{</span><span class="org-type">\</span>sqrt<span class="org-rainbow-delimiters-depth-4">{</span>Hz<span class="org-rainbow-delimiters-depth-4">}</span><span class="org-rainbow-delimiters-depth-3">}</span><span class="org-type">\</span>right<span class="org-rainbow-delimiters-depth-2">]</span>$'<span class="org-rainbow-delimiters-depth-1">)</span>
|
||||
ylabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Amplitude Spectral Density $\left</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">\frac</span><span class="org-string"><span class="org-rainbow-delimiters-depth-3">{</span></span><span class="org-string">m/s</span><span class="org-string"><span class="org-rainbow-delimiters-depth-3">}{</span></span><span class="org-string">\sqrt</span><span class="org-string"><span class="org-rainbow-delimiters-depth-4">{</span></span><span class="org-string">Hz</span><span class="org-string"><span class="org-rainbow-delimiters-depth-4">}</span></span><span class="org-string"><span class="org-rainbow-delimiters-depth-3">}</span></span><span class="org-string">\right</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">$'</span><span class="org-rainbow-delimiters-depth-1">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org90edcdd" class="outline-2">
|
||||
<h2 id="org90edcdd"><span class="section-number-2">4</span> Modification of a signal's Power Spectral Density when going through an LTI system</h2>
|
||||
<div class="outline-text-2" id="text-4">
|
||||
<div id="outline-container-orgcba62e6" class="outline-3">
|
||||
<h3 id="orgcba62e6"><span class="section-number-3">1.5</span> Modification of a signal's Power Spectral Density when going through an LTI system</h3>
|
||||
<div class="outline-text-3" id="text-1-5">
|
||||
|
||||
<div id="org9eca4b8" class="figure">
|
||||
<div id="org5a3eaea" class="figure">
|
||||
<p><img src="figs/velocity_to_voltage_psd.png" alt="velocity_to_voltage_psd.png" />
|
||||
</p>
|
||||
<p><span class="figure-number">Figure 4: </span>Schematic of the instrumentation used for the measurement</p>
|
||||
<p><span class="figure-number">Figure 5: </span>Schematic of the instrumentation used for the measurement</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
@ -476,14 +599,14 @@ And we also have:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-orgfb2734c" class="outline-2">
|
||||
<h2 id="orgfb2734c"><span class="section-number-2">5</span> From PSD of the velocity to the PSD of the displacement</h2>
|
||||
<div class="outline-text-2" id="text-5">
|
||||
<div id="outline-container-org3adf2bb" class="outline-3">
|
||||
<h3 id="org3adf2bb"><span class="section-number-3">1.6</span> From PSD of the velocity to the PSD of the displacement</h3>
|
||||
<div class="outline-text-3" id="text-1-6">
|
||||
|
||||
<div id="orga1a0bc5" class="figure">
|
||||
<div id="org14e4432" class="figure">
|
||||
<p><img src="figs/velocity_to_displacement_psd.png" alt="velocity_to_displacement_psd.png" />
|
||||
</p>
|
||||
<p><span class="figure-number">Figure 5: </span>Schematic of the instrumentation used for the measurement</p>
|
||||
<p><span class="figure-number">Figure 6: </span>Schematic of the instrumentation used for the measurement</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
@ -545,7 +668,12 @@ And we have
|
||||
Note here that we always have
|
||||
\[ PSD_x \left(f = \frac{1}{2\pi}\right) = PSD_v \left(f = \frac{1}{2\pi}\right) = PSD_a \left(f = \frac{1}{2\pi}\right), \quad \frac{1}{2\pi} \approx 0.16 [Hz] \]
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org83b26dc" class="outline-3">
|
||||
<h3 id="org83b26dc"><span class="section-number-3">1.7</span> Cumulative Power/Amplitude Spectrum</h3>
|
||||
<div class="outline-text-3" id="text-1-7">
|
||||
<p>
|
||||
If we want to compute the Cumulative Power Spectrum:
|
||||
\[ CPS_v(f) = \int_0^f PSD_v(\nu) d\nu \quad [(m/s)^2] \]
|
||||
@ -567,15 +695,425 @@ Then, we can obtain the Root Mean Square value of the velocity:
|
||||
</p>
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">
|
||||
<pre class="src src-matlab"><span class="org-type">figure</span>;
|
||||
hold on;
|
||||
plot<span class="org-rainbow-delimiters-depth-1">(</span>f, cumtrapz<span class="org-rainbow-delimiters-depth-2">(</span>f, Sv<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
hold off;
|
||||
<span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'xscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'yscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Frequency </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">Hz</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">'</span><span class="org-rainbow-delimiters-depth-1">)</span>; ylabel<span class="org-rainbow-delimiters-depth-1">(</span>'Cumulative Power Spectrum <span class="org-rainbow-delimiters-depth-2">[</span>$<span class="org-rainbow-delimiters-depth-3">(</span>m<span class="org-type">/</span>s<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2$</span><span class="org-rainbow-delimiters-depth-2">]</span><span class="org-type">'</span><span class="org-rainbow-delimiters-depth-1">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
In order to integrate from high frequency to low frequency:
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab"><span class="org-type">figure</span>;
|
||||
hold on;
|
||||
plot<span class="org-rainbow-delimiters-depth-1">(</span>f, flip<span class="org-rainbow-delimiters-depth-2">(</span><span class="org-type">-</span>cumtrapz<span class="org-rainbow-delimiters-depth-3">(</span>flip<span class="org-rainbow-delimiters-depth-4">(</span>f<span class="org-rainbow-delimiters-depth-4">)</span>, flip<span class="org-rainbow-delimiters-depth-4">(</span>Sv<span class="org-rainbow-delimiters-depth-4">)</span><span class="org-rainbow-delimiters-depth-3">)</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
hold off;
|
||||
<span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'xscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'yscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Frequency </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">Hz</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">'</span><span class="org-rainbow-delimiters-depth-1">)</span>; ylabel<span class="org-rainbow-delimiters-depth-1">(</span>'Cumulative Power Spectrum <span class="org-rainbow-delimiters-depth-2">[</span>$<span class="org-rainbow-delimiters-depth-3">(</span>m<span class="org-type">/</span>s<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2$</span><span class="org-rainbow-delimiters-depth-2">]</span><span class="org-type">'</span><span class="org-rainbow-delimiters-depth-1">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org5ace856" class="outline-3">
|
||||
<h3 id="org5ace856"><span class="section-number-3">1.8</span> <span class="todo TODO">TODO</span> Add best practices from the Article and simple snippet that works</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-orga6e1da0" class="outline-2">
|
||||
<h2 id="orga6e1da0"><span class="section-number-2">2</span> Technique 1 : Approximation with a transfer function</h2>
|
||||
<div class="outline-text-2" id="text-2">
|
||||
<p>
|
||||
<a id="org2ea1c7b"></a>
|
||||
</p>
|
||||
</div>
|
||||
<div id="outline-container-orge44fa26" class="outline-3">
|
||||
<h3 id="orge44fa26"><span class="section-number-3">2.1</span> Signal's PSD</h3>
|
||||
<div class="outline-text-3" id="text-2-1">
|
||||
<p>
|
||||
We load the PSD of the signal we wish to replicate.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">load<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'./mat/dist_psd.mat'</span>, <span class="org-string">'dist_f'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
We remove the first value with very high PSD.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">dist_f.f = dist_f.f<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">3</span><span class="org-type">:</span>end<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
dist_f.psd_gm = dist_f.psd_gm<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">3</span><span class="org-type">:</span>end<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The PSD of the signal is shown on figure <a href="#fig:psd_ground_motion">fig:psd_ground_motion</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<div id="org809f585" class="figure">
|
||||
<p><img src="figs/psd_ground_motion.png" alt="psd_ground_motion.png" />
|
||||
</p>
|
||||
<p><span class="figure-number">Figure 7: </span>PSD of the signal (<a href="./figs/psd_ground_motion.png">png</a>, <a href="./figs/psd_ground_motion.pdf">pdf</a>)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org35e87c7" class="outline-3">
|
||||
<h3 id="org35e87c7"><span class="section-number-3">2.2</span> Transfer Function that approximate the ASD</h3>
|
||||
<div class="outline-text-3" id="text-2-2">
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">G_gm = <span class="org-highlight-numbers-number">0</span>.<span class="org-highlight-numbers-number">002</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">^</span><span class="org-highlight-numbers-number">2</span> <span class="org-type">+</span> <span class="org-highlight-numbers-number">3</span>.<span class="org-highlight-numbers-number">169</span><span class="org-type">*</span>s <span class="org-type">+</span> <span class="org-highlight-numbers-number">27</span>.<span class="org-highlight-numbers-number">74</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">32</span>.<span class="org-highlight-numbers-number">73</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">8</span>.<span class="org-highlight-numbers-number">829</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">7</span>.<span class="org-highlight-numbers-number">983</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org5b0597b" class="outline-3">
|
||||
<h3 id="org5b0597b"><span class="section-number-3">2.3</span> Generated Time domain signal</h3>
|
||||
<div class="outline-text-3" id="text-2-3">
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">Fs = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span>dist_f.f<span class="org-rainbow-delimiters-depth-1">(</span>end<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
Ts = <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span>Fs;
|
||||
|
||||
t = <span class="org-highlight-numbers-number">0</span><span class="org-type">:</span>Ts<span class="org-type">:</span><span class="org-highlight-numbers-number">500</span>;
|
||||
u = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>Fs<span class="org-type">/</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">*</span>randn<span class="org-rainbow-delimiters-depth-1">(</span>length<span class="org-rainbow-delimiters-depth-2">(</span>t<span class="org-rainbow-delimiters-depth-2">)</span>, <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">u_o = lsim<span class="org-rainbow-delimiters-depth-1">(</span>G_gm, u, t<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab"><span class="org-type">figure</span>;
|
||||
plot<span class="org-rainbow-delimiters-depth-1">(</span>t, u_o<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org2bb9116" class="outline-3">
|
||||
<h3 id="org2bb9116"><span class="section-number-3">2.4</span> Comparison of the Power Spectral Densities</h3>
|
||||
<div class="outline-text-3" id="text-2-4">
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">nx = length<span class="org-rainbow-delimiters-depth-1">(</span>u_o<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
na = <span class="org-highlight-numbers-number">16</span>;
|
||||
win = hanning<span class="org-rainbow-delimiters-depth-1">(</span>floor<span class="org-rainbow-delimiters-depth-2">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
|
||||
<span class="org-rainbow-delimiters-depth-1">[</span>pxx, f<span class="org-rainbow-delimiters-depth-1">]</span> = pwelch<span class="org-rainbow-delimiters-depth-1">(</span>u_o, win, <span class="org-highlight-numbers-number">0</span>, <span class="org-rainbow-delimiters-depth-2">[]</span>, Fs<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Finally, we compare the PSD of the original signal and the obtained signal on figure <a href="#fig:psd_comparison">fig:psd_comparison</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org6d66594" class="outline-3">
|
||||
<h3 id="org6d66594"><span class="section-number-3">2.5</span> Simulink</h3>
|
||||
<div class="outline-text-3" id="text-2-5">
|
||||
|
||||
<div id="org3a810b6" class="figure">
|
||||
<p><img src="figs/simulink_psd_generate.png" alt="simulink_psd_generate.png" />
|
||||
</p>
|
||||
<p><span class="figure-number">Figure 8: </span>Simulink Schematic</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The parameters for the <code>Band-Limited White Noise</code> are:
|
||||
</p>
|
||||
<ul class="org-ul">
|
||||
<li>Noise Power: 1</li>
|
||||
</ul>
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">nx = length<span class="org-rainbow-delimiters-depth-1">(</span>out.u_gm.Data<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
na = <span class="org-highlight-numbers-number">8</span>;
|
||||
win = hanning<span class="org-rainbow-delimiters-depth-1">(</span>floor<span class="org-rainbow-delimiters-depth-2">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
|
||||
<span class="org-rainbow-delimiters-depth-1">[</span>pxx, f<span class="org-rainbow-delimiters-depth-1">]</span> = pwelch<span class="org-rainbow-delimiters-depth-1">(</span>out.u_gm.Data, win, <span class="org-highlight-numbers-number">0</span>, <span class="org-rainbow-delimiters-depth-2">[]</span>, <span class="org-highlight-numbers-number">1e3</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-orgd4fbbd9" class="outline-2">
|
||||
<h2 id="orgd4fbbd9"><span class="section-number-2">3</span> Technique 2 : IFFT</h2>
|
||||
<div class="outline-text-2" id="text-3">
|
||||
<p>
|
||||
<a id="org84b5cd1"></a>
|
||||
</p>
|
||||
<p>
|
||||
The technique comes from <a class='org-ref-reference' href="#preumont94_random_vibrat_spect_analy">preumont94_random_vibrat_spect_analy</a> (section 12.11).
|
||||
</p>
|
||||
</div>
|
||||
<div id="outline-container-org98e4f2a" class="outline-3">
|
||||
<h3 id="org98e4f2a"><span class="section-number-3">3.1</span> Signal's PSD</h3>
|
||||
<div class="outline-text-3" id="text-3-1">
|
||||
<p>
|
||||
We load the PSD of the signal we wish to replicate.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">load<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'./mat/dist_psd.mat'</span>, <span class="org-string">'dist_f'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
We remove the first value with very high PSD.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">dist_f.f = dist_f.f<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">3</span><span class="org-type">:</span>end<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
dist_f.psd_gm = dist_f.psd_gm<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">3</span><span class="org-type">:</span>end<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The PSD of the signal is shown on figure <a href="#fig:psd_original">fig:psd_original</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<div id="org7969683" class="figure">
|
||||
<p><img src="figs/psd_original.png" alt="psd_original.png" />
|
||||
</p>
|
||||
<p><span class="figure-number">Figure 9: </span>PSD of the original signal (<a href="./figs/psd_original.png">png</a>, <a href="./figs/psd_original.pdf">pdf</a>)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-orgcb607b3" class="outline-3">
|
||||
<h3 id="orgcb607b3"><span class="section-number-3">3.2</span> Algorithm</h3>
|
||||
<div class="outline-text-3" id="text-3-2">
|
||||
<p>
|
||||
We define some parameters.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">Fs = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span>dist_f.f<span class="org-rainbow-delimiters-depth-1">(</span>end<span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz]</span>
|
||||
N = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span>length<span class="org-rainbow-delimiters-depth-1">(</span>dist_f.f<span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% Number of Samples match the one of the wanted PSD</span>
|
||||
T0 = N<span class="org-type">/</span>Fs; <span class="org-comment">% Signal Duration [s]</span>
|
||||
df = <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span>T0; <span class="org-comment">% Frequency resolution of the DFT [Hz]</span>
|
||||
% Also equal to (dist_f.f(<span class="org-highlight-numbers-number">2</span>)<span class="org-type">-</span>dist_f.f(<span class="org-highlight-numbers-number">1</span>))
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
We then specify the wanted PSD.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">phi = dist_f.psd_gm;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Create amplitudes corresponding to wanted PSD.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">C = zeros<span class="org-rainbow-delimiters-depth-1">(</span>N<span class="org-type">/</span><span class="org-highlight-numbers-number">2</span>,<span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
<span class="org-keyword">for</span> <span class="org-variable-name"><span class="org-constant">i</span></span> = <span class="org-constant"><span class="org-highlight-numbers-number">1</span></span><span class="org-constant">:N/</span><span class="org-constant"><span class="org-highlight-numbers-number">2</span></span>
|
||||
C<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-constant">i</span><span class="org-rainbow-delimiters-depth-1">)</span> = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>phi<span class="org-rainbow-delimiters-depth-2">(</span><span class="org-constant">i</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span>df<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
<span class="org-keyword">end</span>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Add random phase to <code>C</code>.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">theta = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span>rand<span class="org-rainbow-delimiters-depth-1">(</span>N<span class="org-type">/</span><span class="org-highlight-numbers-number">2</span>,<span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% Generate random phase [rad]</span>
|
||||
|
||||
Cx = <span class="org-rainbow-delimiters-depth-1">[</span><span class="org-highlight-numbers-number">0</span> ; C<span class="org-type">.*</span>complex<span class="org-rainbow-delimiters-depth-2">(</span>cos<span class="org-rainbow-delimiters-depth-3">(</span>theta<span class="org-rainbow-delimiters-depth-3">)</span>,sin<span class="org-rainbow-delimiters-depth-3">(</span>theta<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">]</span>;
|
||||
Cx = <span class="org-rainbow-delimiters-depth-1">[</span>Cx; flipud<span class="org-rainbow-delimiters-depth-2">(</span>conj<span class="org-rainbow-delimiters-depth-3">(</span>Cx<span class="org-rainbow-delimiters-depth-4">(</span><span class="org-highlight-numbers-number">2</span><span class="org-type">:</span>end<span class="org-rainbow-delimiters-depth-4">)</span><span class="org-rainbow-delimiters-depth-3">)</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">]</span>;;
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org4ff718c" class="outline-3">
|
||||
<h3 id="org4ff718c"><span class="section-number-3">3.3</span> Obtained Time Domain Signal</h3>
|
||||
<div class="outline-text-3" id="text-3-3">
|
||||
<p>
|
||||
The time domain data is generated by an inverse FFT.
|
||||
We normalize the <code>ifft</code> Matlab command.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">u = <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>sqrt<span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span>df<span class="org-type">*</span><span class="org-highlight-numbers-number">1</span><span class="org-type">/</span>Fs<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">*</span>ifft<span class="org-rainbow-delimiters-depth-1">(</span>Cx<span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% Normalisation of the IFFT</span>
|
||||
t = linspace<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">0</span>, T0, N<span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% Time Vector [s]</span>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="org69c5e9c" class="figure">
|
||||
<p><img src="figs/signal_time_domain.png" alt="signal_time_domain.png" />
|
||||
</p>
|
||||
<p><span class="figure-number">Figure 10: </span>Obtained signal in the time domain (<a href="./figs/signal_time_domain.png">png</a>, <a href="./figs/signal_time_domain.pdf">pdf</a>)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-orgc9527e8" class="outline-3">
|
||||
<h3 id="orgc9527e8"><span class="section-number-3">3.4</span> PSD Comparison</h3>
|
||||
<div class="outline-text-3" id="text-3-4">
|
||||
<p>
|
||||
We duplicate the time domain signal to have a longer signal and thus a more precise PSD result.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">u_rep = repmat<span class="org-rainbow-delimiters-depth-1">(</span>u, <span class="org-highlight-numbers-number">10</span>, <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
We compute the PSD of the obtained signal with the following commands.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">nx = length<span class="org-rainbow-delimiters-depth-1">(</span>u_rep<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
na = <span class="org-highlight-numbers-number">16</span>;
|
||||
win = hanning<span class="org-rainbow-delimiters-depth-1">(</span>floor<span class="org-rainbow-delimiters-depth-2">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
|
||||
<span class="org-rainbow-delimiters-depth-1">[</span>pxx, f<span class="org-rainbow-delimiters-depth-1">]</span> = pwelch<span class="org-rainbow-delimiters-depth-1">(</span>u_rep, win, <span class="org-highlight-numbers-number">0</span>, <span class="org-rainbow-delimiters-depth-2">[]</span>, Fs<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Finally, we compare the PSD of the original signal and the obtained signal on figure <a href="#fig:psd_comparison">fig:psd_comparison</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<div id="orgce3ea03" class="figure">
|
||||
<p><img src="figs/psd_comparison.png" alt="psd_comparison.png" />
|
||||
</p>
|
||||
<p><span class="figure-number">Figure 11: </span>Comparison of the PSD of the original signal and the PSD of the obtained signal (<a href="./figs/psd_comparison.png">png</a>, <a href="./figs/psd_comparison.pdf">pdf</a>)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org7fe2f42" class="outline-2">
|
||||
<h2 id="org7fe2f42"><span class="section-number-2">4</span> <span class="todo TODO">TODO</span> Compute the Noise level and Signal level from PSD</h2>
|
||||
<div class="outline-text-2" id="text-4">
|
||||
<p>
|
||||
<a id="org7bce553"></a>
|
||||
</p>
|
||||
</div>
|
||||
<div id="outline-container-org640e940" class="outline-3">
|
||||
<h3 id="org640e940"><span class="section-number-3">4.1</span> Computation</h3>
|
||||
<div class="outline-text-3" id="text-4-1">
|
||||
<ul class="org-ul">
|
||||
<li class="off"><code>[ ]</code> Add table to compare the methods</li>
|
||||
<li class="off"><code>[ ]</code> Add some explanations</li>
|
||||
</ul>
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">N = <span class="org-highlight-numbers-number">10000</span>;
|
||||
dt = <span class="org-highlight-numbers-number">0</span>.<span class="org-highlight-numbers-number">001</span>;
|
||||
|
||||
t = dt<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">0</span><span class="org-type">:</span><span class="org-highlight-numbers-number">1</span><span class="org-type">:</span>N<span class="org-type">-</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">'</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Parameters of the signal
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">asig = <span class="org-highlight-numbers-number">0</span>.<span class="org-highlight-numbers-number">8</span>; <span class="org-comment">% Amplitude of the signal [V]</span>
|
||||
fsig = <span class="org-highlight-numbers-number">100</span>; <span class="org-comment">% Frequency of the signal [Hz]</span>
|
||||
|
||||
anoi = <span class="org-highlight-numbers-number">1e</span><span class="org-type">-</span><span class="org-highlight-numbers-number">3</span>; <span class="org-comment">% RMS value of the noise</span>
|
||||
|
||||
x = anoi<span class="org-type">*</span>randn<span class="org-rainbow-delimiters-depth-1">(</span>N, <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-type">+</span> asig<span class="org-type">*</span>sin<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span>fsig<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span>t<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab"><span class="org-type">figure</span>;
|
||||
plot<span class="org-rainbow-delimiters-depth-1">(</span>t, x<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Compute the PSD of the signal.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">nx = length<span class="org-rainbow-delimiters-depth-1">(</span>x<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
na = <span class="org-highlight-numbers-number">8</span>;
|
||||
win = blackmanharris<span class="org-rainbow-delimiters-depth-1">(</span>floor<span class="org-rainbow-delimiters-depth-2">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
|
||||
<span class="org-rainbow-delimiters-depth-1">[</span>pxx, f<span class="org-rainbow-delimiters-depth-1">]</span> = pwelch<span class="org-rainbow-delimiters-depth-1">(</span>x, win, <span class="org-highlight-numbers-number">0</span>, <span class="org-rainbow-delimiters-depth-2">[]</span>, <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span>dt<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Normalization of the PSD.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">CG = sum<span class="org-rainbow-delimiters-depth-1">(</span>win<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
NG = sum<span class="org-rainbow-delimiters-depth-1">(</span>win<span class="org-type">.^</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
fbin = f<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-type">-</span> f<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
|
||||
pxx_norm = pxx<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span>NG<span class="org-type">*</span>fbin<span class="org-type">/</span><span class="org-rainbow-delimiters-depth-2">(</span>CG<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">isig = round<span class="org-rainbow-delimiters-depth-1">(</span>fsig<span class="org-type">/</span>fbin<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">+</span><span class="org-highlight-numbers-number">1</span>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Estimate the Signal magnitude.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">srmt = asig<span class="org-type">/</span>sqrt<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% Theoretical value of signal magnitude</span>
|
||||
srms = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>sum<span class="org-rainbow-delimiters-depth-2">(</span>pxx<span class="org-rainbow-delimiters-depth-3">(</span>isig<span class="org-type">-</span><span class="org-highlight-numbers-number">5</span><span class="org-type">:</span>isig<span class="org-type">+</span><span class="org-highlight-numbers-number">5</span><span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">*</span>fbin<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% Signal spectrum integrated</span>
|
||||
srmsp = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>pxx<span class="org-rainbow-delimiters-depth-2">(</span>isig<span class="org-rainbow-delimiters-depth-2">)</span> <span class="org-type">*</span> NG<span class="org-type">*</span>fbin<span class="org-type">/</span>CG<span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% Maximum read off spectrum</span>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Estimate the noise floor.
|
||||
</p>
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab">nth = anoi<span class="org-type">/</span>sqrt<span class="org-rainbow-delimiters-depth-1">(</span>max<span class="org-rainbow-delimiters-depth-2">(</span>f<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% Theoretical value [V/sqrt(Hz)]</span>
|
||||
|
||||
inmax = isig<span class="org-type">-</span><span class="org-highlight-numbers-number">20</span>;
|
||||
nsum = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>sum<span class="org-rainbow-delimiters-depth-2">(</span>pxx<span class="org-rainbow-delimiters-depth-3">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">:</span>inmax<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">*</span>fbin<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-type">/</span> sqrt<span class="org-rainbow-delimiters-depth-1">(</span>f<span class="org-rainbow-delimiters-depth-2">(</span>inmax<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% Signal spectrum integrated</span>
|
||||
|
||||
navg = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>mean<span class="org-rainbow-delimiters-depth-2">(</span>pxx<span class="org-rainbow-delimiters-depth-3">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">:</span>inmax<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% pwelch output averaged</span>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre class="src src-matlab"><span class="org-type">figure</span>;
|
||||
hold on;
|
||||
plot<span class="org-rainbow-delimiters-depth-1">(</span>f, pxx<span class="org-rainbow-delimiters-depth-1">)</span>
|
||||
plot<span class="org-rainbow-delimiters-depth-1">(</span>f, pxx_norm<span class="org-rainbow-delimiters-depth-1">)</span>
|
||||
hold off;
|
||||
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Frequency </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">Hz</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
ylabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Power Spectral Density'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
<span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'xscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
<span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'yscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
||||
<h1 class='org-ref-bib-h1'>Bibliography</h1>
|
||||
<ul class='org-ref-bib'><li><a id="preumont94_random_vibrat_spect_analy">[preumont94_random_vibrat_spect_analy]</a> <a name="preumont94_random_vibrat_spect_analy"></a>Andr\'e Preumont, Random Vibration and Spectral Analysis, Springer Netherlands (1994).</li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
<div id="postamble" class="status">
|
||||
<p class="author">Author: Dehaeze Thomas</p>
|
||||
<p class="date">Created: 2019-08-15 jeu. 12:31</p>
|
||||
<p class="date">Created: 2019-12-02 lun. 11:22</p>
|
||||
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
|
||||
</div>
|
||||
</body>
|
||||
|
477
index.org
@ -12,7 +12,7 @@
|
||||
#+HTML_HEAD: <script type="text/javascript" src="./js/jquery.stickytableheaders.min.js"></script>
|
||||
#+HTML_HEAD: <script type="text/javascript" src="./js/readtheorg.js"></script>
|
||||
|
||||
#+PROPERTY: header-args:latex :headers '("\\usepackage{tikz}" "\\usepackage{import}" "\\import{$HOME/MEGA/These/LaTeX/}{config.tex}")
|
||||
#+PROPERTY: header-args:latex :headers '("\\usepackage{tikz}" "\\usepackage{import}" "\\import{$HOME/Cloud/thesis/latex/}{config.tex}")
|
||||
#+PROPERTY: header-args:latex+ :imagemagick t :fit yes
|
||||
#+PROPERTY: header-args:latex+ :iminoptions -scale 100% -density 150
|
||||
#+PROPERTY: header-args:latex+ :imoutoptions -quality 100
|
||||
@ -34,13 +34,27 @@
|
||||
#+PROPERTY: header-args:matlab+ :output-dir figs
|
||||
:END:
|
||||
|
||||
This document presents the mathematics as well as the matlab scripts to do the spectral analysis of a measured signal.
|
||||
* Introduction :ignore:
|
||||
This document presents the mathematics as well as the matlab scripts to do various spectral analysis on a measured signal.
|
||||
|
||||
Some matlab documentation about Spectral Analysis can be found [[https://fr.mathworks.com/help/signal/ug/spectral-analysis.html][here]].
|
||||
|
||||
First, in section [[sec:spectral_analysis_basics]], some basics of spectral analysis are presented.
|
||||
|
||||
In some cases, we want to generate a time domain signal with defined Power Spectral Density.
|
||||
Two methods are presented in sections [[sec:approximate_tf]] and [[sec:approximate_ifft]].
|
||||
|
||||
Finally, some notes are done on how to compute the noise level and signal level from a given Power Spectral Density in section [[sec:compute_psd_levels]].
|
||||
|
||||
* Spectral Analysis - Basics
|
||||
<<sec:spectral_analysis_basics>>
|
||||
|
||||
** Introduction :ignore:
|
||||
Typically this signal is coming from an inertial sensor, a force sensor or any other sensor.
|
||||
|
||||
We here take the example of a signal coming from a Geophone measurement the vertical velocity of the floor at the ESRF.
|
||||
|
||||
* Matlab Init :noexport:ignore:
|
||||
** Matlab Init :noexport:ignore:
|
||||
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
|
||||
<<matlab-dir>>
|
||||
#+end_src
|
||||
@ -49,7 +63,68 @@ We here take the example of a signal coming from a Geophone measurement the vert
|
||||
<<matlab-init>>
|
||||
#+end_src
|
||||
|
||||
* Sensitivity of the instrumentation
|
||||
** PSD of ADC quantization noise
|
||||
This is taken from [[https://www.allaboutcircuits.com/technical-articles/quantization-nois-amplitude-quantization-error-analog-to-digital-converters/][here]].
|
||||
|
||||
Let's note:
|
||||
- $q$ is the corresponding value in [V] of the least significant bit (LSB)
|
||||
- $\Delta V$ is the full range of the ADC in [V]
|
||||
- $n$ is the number of ADC's bits
|
||||
- $f_s$ is the sample frequency in [Hz]
|
||||
|
||||
Let's suppose that the ADC is ideal.
|
||||
The only noise comes from the quantization error.
|
||||
Interestingly, the noise amplitude is uniformly distributed.
|
||||
|
||||
The quantization noise can take a value between $\pm q/2$, and the probability density function is constant in this range (i.e., it’s a uniform distribution).
|
||||
Since the integral of the probability density function is equal to one, its value will be $1/q$ for $-q/2 < e < q/2$ (Fig. [[fig:probability_density_function_adc]]).
|
||||
|
||||
#+begin_src latex :file probability_density_function_adc.pdf :post pdf2svg(file=*this*, ext="png") :exports results
|
||||
\begin{tikzpicture}
|
||||
\path[fill=black!20!white] (-1, 0) |- (1, 1) |- (-1, 0);
|
||||
|
||||
\draw[->] (-2, 0) -- (2, 0) node[above left]{$e$};
|
||||
\draw[->] (0, -0.5) -- (0, 2) node[below right]{$p(e)$};
|
||||
|
||||
\node[below] at (1, 0){$\frac{q}{2}$};
|
||||
\node[below] at (-1, 0){$-\frac{q}{2}$};
|
||||
\node[right] at (1, 1){$\frac{1}{q}$};
|
||||
\end{tikzpicture}
|
||||
#+end_src
|
||||
|
||||
#+name: fig:probability_density_function_adc
|
||||
#+caption: Probability density function $p(e)$ of the ADC error $e$
|
||||
#+RESULTS:
|
||||
[[file:figs/probability_density_function_adc.png]]
|
||||
|
||||
Now, we can calculate the time average power of the quantization noise as
|
||||
\begin{equation}
|
||||
P_q = \int_{-q/2}^{q/2} e^2 p(e) de = \frac{q^2}{12}
|
||||
\end{equation}
|
||||
|
||||
|
||||
The other important parameter of a noise source is the power spectral density (PSD), which indicates how the noise power spreads in different frequency bands.
|
||||
To find the power spectral density, we need to calculate the Fourier transform of the autocorrelation function of the noise.
|
||||
|
||||
Assuming that the noise samples are not correlated with one another, we can approximate the autocorrelation function with a delta function in the time domain.
|
||||
Since the Fourier transform of a delta function is equal to one, the *power spectral density will be frequency independent*.
|
||||
Therefore, the quantization noise is white noise with total power equal to $P_q = \frac{q^2}{12}$.
|
||||
|
||||
Thus, the two-sided PSD (from $\frac{-f_s}{2}$ to $\frac{f_s}{2}$), we should divide the noise power $P_q$ by $f_s$:
|
||||
|
||||
\begin{equation}
|
||||
\int_{-f_s/2}^{f_s/2} \Gamma(f) d f = f_s \Gamma = \frac{q^2}{12}
|
||||
\end{equation}
|
||||
|
||||
Finally:
|
||||
\begin{equation}
|
||||
\begin{align}
|
||||
\Gamma &= \frac{q^2}{12 f_s} \\
|
||||
&= \frac{\left(\frac{\Delta V}{2^n}\right)^2}{12 f_s} \text{ in } \left[ \frac{V^2}{Hz} \right]
|
||||
\end{align}
|
||||
\end{equation}
|
||||
|
||||
** Sensitivity of the instrumentation
|
||||
The measured signal $x$ by the ADC is in Volts.
|
||||
The corresponding real velocity $v$ in m/s.
|
||||
|
||||
@ -75,7 +150,7 @@ To obtain the real quantity as measured by the sensor, one have to know the sens
|
||||
#+RESULTS: fig:velocity_to_voltage
|
||||
[[file:figs/velocity_to_voltage.png]]
|
||||
|
||||
* Convert the time domain from volts to velocity
|
||||
** Convert the time domain from volts to velocity
|
||||
Let's say, we know that the sensitivity of the geophone used is
|
||||
\[ G_g(s) = G_0 \frac{\frac{s}{2\pi f_0}}{1 + \frac{s}{2\pi f_0}} \quad \left[\frac{V}{m/s}\right] \]
|
||||
|
||||
@ -123,7 +198,7 @@ If ${G_m(s)}^{-1} {G_g(s)}^{-1}$ is proper, we can simulate this dynamical syste
|
||||
|
||||
We simulate this system with matlab:
|
||||
#+begin_src matlab
|
||||
v = lsim(inv(Gg*Gm), v, t);
|
||||
v = lsim(inv(Gg*Gm), x, t);
|
||||
#+end_src
|
||||
|
||||
And we plot the obtained velocity
|
||||
@ -144,7 +219,7 @@ And we plot the obtained velocity
|
||||
#+RESULTS: fig:velocity_time
|
||||
[[file:figs/velocity_time.png]]
|
||||
|
||||
* Power Spectral Density and Amplitude Spectral Density
|
||||
** Power Spectral Density and Amplitude Spectral Density
|
||||
We now have the velocity in the time domain:
|
||||
\[ v(t)\ [m/s] \]
|
||||
|
||||
@ -181,7 +256,7 @@ We first have to defined a window:
|
||||
|
||||
The Amplitude Spectral Density (ASD) is the square root of the Power Spectral Density:
|
||||
\begin{equation}
|
||||
\Gamma_{vv}(f) = \sqrt{S_{vv}(f)} \quad \left[ \frac{m/s}{\sqrt{Hz}} \right]
|
||||
\Gamma_{vv}(f) = \sqrt{S_{vv}(f)} \quad \left[ \frac{m/s}{\sqrt{Hz}} \right]
|
||||
\end{equation}
|
||||
|
||||
#+begin_src matlab
|
||||
@ -201,7 +276,7 @@ The Amplitude Spectral Density (ASD) is the square root of the Power Spectral De
|
||||
#+CAPTION: Power Spectral Density of the measured velocity
|
||||
#+RESULTS: fig:asd_velocity
|
||||
|
||||
* Modification of a signal's Power Spectral Density when going through an LTI system
|
||||
** Modification of a signal's Power Spectral Density when going through an LTI system
|
||||
|
||||
#+begin_src latex :file velocity_to_voltage_psd.pdf :post pdf2svg(file=*this*, ext="png") :exports results
|
||||
\begin{tikzpicture}
|
||||
@ -227,7 +302,7 @@ And we also have:
|
||||
\Gamma_{yy}(\omega) = \left|G(j\omega)\right| \Gamma_{xx}(\omega)
|
||||
\end{equation}
|
||||
|
||||
* From PSD of the velocity to the PSD of the displacement
|
||||
** From PSD of the velocity to the PSD of the displacement
|
||||
|
||||
#+begin_src latex :file velocity_to_displacement_psd.pdf :post pdf2svg(file=*this*, ext="png") :exports results
|
||||
\begin{tikzpicture}
|
||||
@ -284,6 +359,7 @@ And we have
|
||||
Note here that we always have
|
||||
\[ PSD_x \left(f = \frac{1}{2\pi}\right) = PSD_v \left(f = \frac{1}{2\pi}\right) = PSD_a \left(f = \frac{1}{2\pi}\right), \quad \frac{1}{2\pi} \approx 0.16 [Hz] \]
|
||||
|
||||
** Cumulative Power/Amplitude Spectrum
|
||||
If we want to compute the Cumulative Power Spectrum:
|
||||
\[ CPS_v(f) = \int_0^f PSD_v(\nu) d\nu \quad [(m/s)^2] \]
|
||||
|
||||
@ -296,8 +372,387 @@ The Cumulative Amplitude Spectrum is then the square root of the Cumulative Powe
|
||||
Then, we can obtain the Root Mean Square value of the velocity:
|
||||
\[ v_{\text{rms}} = CAS_v(0) \quad [m/s \ \text{rms}] \]
|
||||
|
||||
#+begin_src matlab
|
||||
#+begin_src matlab :results none
|
||||
figure;
|
||||
hold on;
|
||||
plot(f, cumtrapz(f, Sv));
|
||||
hold off;
|
||||
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
|
||||
xlabel('Frequency [Hz]'); ylabel('Cumulative Power Spectrum [$(m/s)^2$]')
|
||||
#+end_src
|
||||
|
||||
In order to integrate from high frequency to low frequency:
|
||||
#+begin_src matlab :results none
|
||||
figure;
|
||||
hold on;
|
||||
plot(f, flip(-cumtrapz(flip(f), flip(Sv))));
|
||||
hold off;
|
||||
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
|
||||
xlabel('Frequency [Hz]'); ylabel('Cumulative Power Spectrum [$(m/s)^2$]')
|
||||
#+end_src
|
||||
|
||||
** TODO Add best practices from the Article and simple snippet that works
|
||||
* Technique 1 : Approximation with a transfer function
|
||||
<<sec:approximate_tf>>
|
||||
** Introduction :ignore:
|
||||
|
||||
** Matlab Init :noexport:ignore:
|
||||
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
|
||||
<<matlab-dir>>
|
||||
#+end_src
|
||||
|
||||
#+begin_src matlab :exports none :results silent :noweb yes
|
||||
<<matlab-init>>
|
||||
#+end_src
|
||||
|
||||
** Signal's PSD
|
||||
We load the PSD of the signal we wish to replicate.
|
||||
#+begin_src matlab
|
||||
load('./mat/dist_psd.mat', 'dist_f');
|
||||
#+end_src
|
||||
|
||||
We remove the first value with very high PSD.
|
||||
#+begin_src matlab
|
||||
dist_f.f = dist_f.f(3:end);
|
||||
dist_f.psd_gm = dist_f.psd_gm(3:end);
|
||||
#+end_src
|
||||
|
||||
The PSD of the signal is shown on figure ref:fig:psd_ground_motion.
|
||||
|
||||
#+begin_src matlab :exports none
|
||||
figure;
|
||||
hold on;
|
||||
plot(dist_f.f, dist_f.psd_gm)
|
||||
hold off;
|
||||
xlabel('Frequency [Hz]');
|
||||
ylabel('Power Spectral Density');
|
||||
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
|
||||
#+end_src
|
||||
|
||||
#+HEADER: :tangle no :exports results :results none :noweb yes
|
||||
#+begin_src matlab :var filepath="figs/psd_ground_motion.pdf" :var figsize="wide-normal" :post pdf2svg(file=*this*, ext="png")
|
||||
<<plt-matlab>>
|
||||
#+end_src
|
||||
|
||||
#+NAME: fig:psd_ground_motion
|
||||
#+CAPTION: PSD of the signal ([[./figs/psd_ground_motion.png][png]], [[./figs/psd_ground_motion.pdf][pdf]])
|
||||
[[file:figs/psd_ground_motion.png]]
|
||||
|
||||
** Transfer Function that approximate the ASD
|
||||
#+begin_src matlab
|
||||
G_gm = 0.002*(s^2 + 3.169*s + 27.74)/(s*(s+32.73)*(s+8.829)*(s+7.983)^2);
|
||||
#+end_src
|
||||
|
||||
#+begin_src matlab :exports none
|
||||
figure;
|
||||
hold on;
|
||||
plot(dist_f.f, sqrt(dist_f.psd_gm))
|
||||
plot(dist_f.f, abs(squeeze(freqresp(G_gm, dist_f.f, 'Hz'))))
|
||||
hold off;
|
||||
xlabel('Frequency [Hz]');
|
||||
ylabel('Power Spectral Density');
|
||||
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
|
||||
#+end_src
|
||||
|
||||
** Generated Time domain signal
|
||||
#+begin_src matlab
|
||||
Fs = 2*dist_f.f(end);
|
||||
Ts = 1/Fs;
|
||||
|
||||
t = 0:Ts:500;
|
||||
u = sqrt(Fs/2)*randn(length(t), 1);
|
||||
#+end_src
|
||||
|
||||
#+begin_src matlab
|
||||
u_o = lsim(G_gm, u, t);
|
||||
#+end_src
|
||||
|
||||
#+begin_src matlab
|
||||
figure;
|
||||
plot(t, u_o);
|
||||
#+end_src
|
||||
|
||||
** Comparison of the Power Spectral Densities
|
||||
#+begin_src matlab
|
||||
nx = length(u_o);
|
||||
na = 16;
|
||||
win = hanning(floor(nx/na));
|
||||
|
||||
[pxx, f] = pwelch(u_o, win, 0, [], Fs);
|
||||
#+end_src
|
||||
|
||||
Finally, we compare the PSD of the original signal and the obtained signal on figure ref:fig:psd_comparison.
|
||||
|
||||
#+begin_src matlab :exports none
|
||||
figure;
|
||||
hold on;
|
||||
plot(dist_f.f, dist_f.psd_gm, 'DisplayName', 'Original PSD')
|
||||
plot(f, pxx, 'DisplayName', 'Computed')
|
||||
hold off;
|
||||
xlabel('Frequency [Hz]');
|
||||
ylabel('Power Spectral Density');
|
||||
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
|
||||
legend('location', 'northeast');
|
||||
#+end_src
|
||||
|
||||
** Simulink
|
||||
|
||||
#+name: fig:simulink_psd_generate
|
||||
#+caption: Simulink Schematic
|
||||
[[file:figs/simulink_psd_generate.png]]
|
||||
|
||||
The parameters for the =Band-Limited White Noise= are:
|
||||
- Noise Power: 1
|
||||
|
||||
#+begin_src matlab
|
||||
nx = length(out.u_gm.Data);
|
||||
na = 8;
|
||||
win = hanning(floor(nx/na));
|
||||
|
||||
[pxx, f] = pwelch(out.u_gm.Data, win, 0, [], 1e3);
|
||||
#+end_src
|
||||
|
||||
#+begin_src matlab :exports none
|
||||
figure;
|
||||
hold on;
|
||||
plot(dist_f.f, dist_f.psd_gm, 'DisplayName', 'Original PSD')
|
||||
plot(f, pxx, 'DisplayName', 'Computed')
|
||||
hold off;
|
||||
xlabel('Frequency [Hz]');
|
||||
ylabel('Power Spectral Density');
|
||||
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
|
||||
legend('location', 'northeast');
|
||||
#+end_src
|
||||
|
||||
* Technique 2 : IFFT
|
||||
<<sec:approximate_ifft>>
|
||||
** Introduction :ignore:
|
||||
The technique comes from cite:preumont94_random_vibrat_spect_analy (section 12.11).
|
||||
|
||||
** Matlab Init :noexport:ignore:
|
||||
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
|
||||
<<matlab-dir>>
|
||||
#+end_src
|
||||
|
||||
#+begin_src matlab :exports none :results silent :noweb yes
|
||||
<<matlab-init>>
|
||||
#+end_src
|
||||
|
||||
** Signal's PSD
|
||||
We load the PSD of the signal we wish to replicate.
|
||||
#+begin_src matlab
|
||||
load('./mat/dist_psd.mat', 'dist_f');
|
||||
#+end_src
|
||||
|
||||
We remove the first value with very high PSD.
|
||||
#+begin_src matlab
|
||||
dist_f.f = dist_f.f(3:end);
|
||||
dist_f.psd_gm = dist_f.psd_gm(3:end);
|
||||
#+end_src
|
||||
|
||||
The PSD of the signal is shown on figure ref:fig:psd_original.
|
||||
|
||||
#+begin_src matlab :exports none
|
||||
figure;
|
||||
hold on;
|
||||
plot(dist_f.f, dist_f.psd_gm)
|
||||
hold off;
|
||||
xlabel('Frequency [Hz]');
|
||||
ylabel('Power Spectral Density');
|
||||
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
|
||||
#+end_src
|
||||
|
||||
#+HEADER: :tangle no :exports results :results none :noweb yes
|
||||
#+begin_src matlab :var filepath="figs/psd_original.pdf" :var figsize="wide-normal" :post pdf2svg(file=*this*, ext="png")
|
||||
<<plt-matlab>>
|
||||
#+end_src
|
||||
|
||||
#+NAME: fig:psd_original
|
||||
#+CAPTION: PSD of the original signal ([[./figs/psd_original.png][png]], [[./figs/psd_original.pdf][pdf]])
|
||||
[[file:figs/psd_original.png]]
|
||||
|
||||
** Algorithm
|
||||
We define some parameters.
|
||||
#+begin_src matlab
|
||||
Fs = 2*dist_f.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz]
|
||||
N = 2*length(dist_f.f); % Number of Samples match the one of the wanted PSD
|
||||
T0 = N/Fs; % Signal Duration [s]
|
||||
df = 1/T0; % Frequency resolution of the DFT [Hz]
|
||||
% Also equal to (dist_f.f(2)-dist_f.f(1))
|
||||
#+end_src
|
||||
|
||||
We then specify the wanted PSD.
|
||||
#+begin_src matlab
|
||||
phi = dist_f.psd_gm;
|
||||
#+end_src
|
||||
|
||||
Create amplitudes corresponding to wanted PSD.
|
||||
#+begin_src matlab
|
||||
C = zeros(N/2,1);
|
||||
for i = 1:N/2
|
||||
C(i) = sqrt(phi(i)*df);
|
||||
end
|
||||
#+end_src
|
||||
|
||||
Add random phase to =C=.
|
||||
#+begin_src matlab
|
||||
theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
|
||||
|
||||
Cx = [0 ; C.*complex(cos(theta),sin(theta))];
|
||||
Cx = [Cx; flipud(conj(Cx(2:end)))];;
|
||||
#+end_src
|
||||
|
||||
** Obtained Time Domain Signal
|
||||
The time domain data is generated by an inverse FFT.
|
||||
We normalize the =ifft= Matlab command.
|
||||
#+begin_src matlab
|
||||
u = 1/(sqrt(2)*df*1/Fs)*ifft(Cx); % Normalisation of the IFFT
|
||||
t = linspace(0, T0, N+1); % Time Vector [s]
|
||||
#+end_src
|
||||
|
||||
#+begin_src matlab :exports none
|
||||
figure;
|
||||
plot(t, u)
|
||||
xlabel('Time [s]');
|
||||
ylabel('Amplitude');
|
||||
xlim([t(1), t(end)]);
|
||||
#+end_src
|
||||
|
||||
#+HEADER: :tangle no :exports results :results none :noweb yes
|
||||
#+begin_src matlab :var filepath="figs/signal_time_domain.pdf" :var figsize="normal-wide" :post pdf2svg(file=*this*, ext="png")
|
||||
<<plt-matlab>>
|
||||
#+end_src
|
||||
|
||||
#+NAME: fig:signal_time_domain
|
||||
#+CAPTION: Obtained signal in the time domain ([[./figs/signal_time_domain.png][png]], [[./figs/signal_time_domain.pdf][pdf]])
|
||||
[[file:figs/signal_time_domain.png]]
|
||||
|
||||
** PSD Comparison
|
||||
We duplicate the time domain signal to have a longer signal and thus a more precise PSD result.
|
||||
#+begin_src matlab
|
||||
u_rep = repmat(u, 10, 1);
|
||||
#+end_src
|
||||
|
||||
We compute the PSD of the obtained signal with the following commands.
|
||||
#+begin_src matlab
|
||||
nx = length(u_rep);
|
||||
na = 16;
|
||||
win = hanning(floor(nx/na));
|
||||
|
||||
[pxx, f] = pwelch(u_rep, win, 0, [], Fs);
|
||||
#+end_src
|
||||
|
||||
Finally, we compare the PSD of the original signal and the obtained signal on figure ref:fig:psd_comparison.
|
||||
|
||||
#+begin_src matlab :exports none
|
||||
figure;
|
||||
hold on;
|
||||
plot(dist_f.f, dist_f.psd_gm, 'DisplayName', 'Original PSD')
|
||||
plot(f, pxx, 'DisplayName', 'Computed')
|
||||
hold off;
|
||||
xlabel('Frequency [Hz]');
|
||||
ylabel('Power Spectral Density');
|
||||
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
|
||||
legend('location', 'northeast');
|
||||
#+end_src
|
||||
|
||||
#+HEADER: :tangle no :exports results :results none :noweb yes
|
||||
#+begin_src matlab :var filepath="figs/psd_comparison.pdf" :var figsize="wide-normal" :post pdf2svg(file=*this*, ext="png")
|
||||
<<plt-matlab>>
|
||||
#+end_src
|
||||
|
||||
#+NAME: fig:psd_comparison
|
||||
#+CAPTION: Comparison of the PSD of the original signal and the PSD of the obtained signal ([[./figs/psd_comparison.png][png]], [[./figs/psd_comparison.pdf][pdf]])
|
||||
[[file:figs/psd_comparison.png]]
|
||||
|
||||
* TODO Compute the Noise level and Signal level from PSD
|
||||
<<sec:compute_psd_levels>>
|
||||
** Introduction :ignore:
|
||||
|
||||
** Matlab Init :noexport:ignore:
|
||||
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
|
||||
<<matlab-dir>>
|
||||
#+end_src
|
||||
|
||||
#+begin_src matlab :exports none :results silent :noweb yes
|
||||
<<matlab-init>>
|
||||
#+end_src
|
||||
|
||||
** Computation
|
||||
- [ ] Add table to compare the methods
|
||||
- [ ] Add some explanations
|
||||
|
||||
#+begin_src matlab
|
||||
N = 10000;
|
||||
dt = 0.001;
|
||||
|
||||
t = dt*(0:1:N-1)';
|
||||
#+end_src
|
||||
|
||||
Parameters of the signal
|
||||
#+begin_src matlab
|
||||
asig = 0.8; % Amplitude of the signal [V]
|
||||
fsig = 100; % Frequency of the signal [Hz]
|
||||
|
||||
anoi = 1e-3; % RMS value of the noise
|
||||
|
||||
x = anoi*randn(N, 1) + asig*sin((2*pi*fsig)*t);
|
||||
#+end_src
|
||||
|
||||
#+begin_src matlab
|
||||
figure;
|
||||
plot(t, x);
|
||||
#+end_src
|
||||
|
||||
Compute the PSD of the signal.
|
||||
#+begin_src matlab
|
||||
nx = length(x);
|
||||
na = 8;
|
||||
win = blackmanharris(floor(nx/na));
|
||||
|
||||
[pxx, f] = pwelch(x, win, 0, [], 1/dt);
|
||||
#+end_src
|
||||
|
||||
Normalization of the PSD.
|
||||
#+begin_src matlab
|
||||
CG = sum(win)/(nx/na);
|
||||
NG = sum(win.^2)/(nx/na);
|
||||
fbin = f(2) - f(1);
|
||||
|
||||
pxx_norm = pxx*(NG*fbin/(CG)^2);
|
||||
#+end_src
|
||||
|
||||
#+begin_src matlab
|
||||
isig = round(fsig/fbin)+1;
|
||||
#+end_src
|
||||
|
||||
Estimate the Signal magnitude.
|
||||
#+begin_src matlab
|
||||
srmt = asig/sqrt(2) % Theoretical value of signal magnitude
|
||||
srms = sqrt(sum(pxx(isig-5:isig+5)*fbin)) % Signal spectrum integrated
|
||||
srmsp = sqrt(pxx(isig) * NG*fbin/CG^2) % Maximum read off spectrum
|
||||
#+end_src
|
||||
|
||||
Estimate the noise floor.
|
||||
#+begin_src matlab
|
||||
nth = anoi/sqrt(max(f)) % Theoretical value [V/sqrt(Hz)]
|
||||
|
||||
inmax = isig-20;
|
||||
nsum = sqrt(sum(pxx(1:inmax)*fbin)) / sqrt(f(inmax)) % Signal spectrum integrated
|
||||
|
||||
navg = sqrt(mean(pxx(1:inmax))) % pwelch output averaged
|
||||
#+end_src
|
||||
|
||||
#+begin_src matlab
|
||||
figure;
|
||||
hold on;
|
||||
plot(f, pxx)
|
||||
plot(f, pxx_norm)
|
||||
hold off;
|
||||
xlabel('Frequency [Hz]');
|
||||
ylabel('Power Spectral Density');
|
||||
set(gca, 'xscale', 'log');
|
||||
set(gca, 'yscale', 'log');
|
||||
#+end_src
|
||||
|
||||
* Bibliography :ignore:
|
||||
|
BIN
mat/dist_psd.mat
Normal file
BIN
matlab/generate_signal_psd.slx
Normal file
14
ref.bib
@ -1,8 +1,20 @@
|
||||
@article{schmid12_how_to_use_fft_matlab,
|
||||
author = {Schmid, Hanspeter},
|
||||
title = {How To Use the Fft and Matlab's Pwelch Function for Signal and
|
||||
title = {How To Use the FFT and Matlab's Pwelch Function for Signal and
|
||||
Noise Simulations and Measurements},
|
||||
journal = {Institute of Microelectronics},
|
||||
year = 2012,
|
||||
keywords = {},
|
||||
}
|
||||
|
||||
@book{preumont94_random_vibrat_spect_analy,
|
||||
author = {Andr{\'e} Preumont},
|
||||
title = {Random Vibration and Spectral Analysis},
|
||||
year = 1994,
|
||||
publisher = {Springer Netherlands},
|
||||
url = {https://doi.org/10.1007/978-94-017-2840-9},
|
||||
DATE_ADDED = {Mon Dec 2 08:52:51 2019},
|
||||
doi = {10.1007/978-94-017-2840-9},
|
||||
pages = {nil},
|
||||
series = {Solid Mechanics and Its Applications},
|
||||
}
|