Simulating capacitive actuation noise


LPF noise source simulations

In this section we want to investigate how the DIST_* models behave, by simulating them. Let's begin with the DIST_CAPACT model, that provides the force/torque noise associated with the electrostatic actuation in the LPF TMs. We build the standard version of the system:

  % Build the default version of the GRS CAPactive ACTuation noise model
  GRScapactNoise = ssm(plist('built-in', 'DIST_CAPACT'));
We just recall that is it possible to obtain more informations about the system by:
  %% Get help on the GRS CAPactive ACTuation noise model
  help ssm_model_DIST_CAPACT
and:
  %% Obtain more details about this model
  GRScapactNoise.viewDetails
Now, as we can see from the call to ssm/viewDetails, the system has two input blocks, namely 'DIST_CAPACT_NOISE' and 'DIST_CAPACT_DC', representing respectively the DC forces/torques acting on the TMs and the fluctuating part (the noise). Each of the input block has 12 ports, one for each degree of freedom of the two test-masses.
We also see that the system has one output block, namely 'DIST_CAPACT' representing the total forces/torques acting on the TMs. The output block has 12 ports, one for each degree of freedom of the two test-masses.
Now we want to calculate the system transfer function of the input to the outputs, in order to estimate the effect of the sources. In order to do that, we can call the ssm/bode method, specifying the input port, the output port, and the frequency range. Here is an example, where we look at the response of the force noise along x acting on TM2 to the noise in input for the same quantity. Practically speaking, we charaterize the transfer function of the noise shaping filter.
      %% Calculate the bode response of the noise coloring filter for the continuous system, tm2_x port
      tm2_xNoisePlist = plist(...
                          'inputs', 'DIST_CAPACT_NOISE.tm2_x', ...
                          'outputs', 'DIST_CAPACT.tm2_x', ...
                          'f', logspace(-4, log10(0.5), 1000) ... % from 0.1mHz to 0.5Hz
                          );
      
      bode_out                       = bode(GRScapactNoise, tm2_xNoisePlist);
      GRScapactNoise_tm2_x_cont_resp = bode_out.unpack();
  
Remember: the output of bode is a matrix object. The single response we want (1 input to 1 output) is represented by the single ao inside the output matrix. So we unpack that single object from the matrix.



Discretizing the system

In order to simulate the ssm models, we need to discretize them, by setting the time-step to a non-zero value.

  %% Discretize the system to be simulated at 1 Hz
  timestep = 1;
  GRScapactNoise_discrete = GRScapactNoise.modifyTimeStep(timestep);
The discretization of a continuous system is a delicate step, because it involves a change from s-domain to z-domain representation. In this case, we want to evalue the impact of discretizing our capacitive actuation noise model at 1 Hz. To do so, we go ahead and calculate the transfer function of the discretized system, for both inputs, and compare them with the continuous ones.
  %% Calculate the bode response of the noise coloring filter for the discrete system, tm2_x port
  bode_out                       = bode(GRScapactNoise_discrete, tm2_xNoisePlist);
  GRScapactNoise_tm2_x_disc_resp = bode_out.unpack();

  %% Compare the transfer functions for the discrete and continuous case
  iplot(GRScapactNoise_tm2_x_cont_resp, GRScapactNoise_tm2_x_disc_resp);
We expect to see a plot similar to the following one, showing that the effect of discretizing at this rate is very tiny, and as expected it impacts only at very high frequencies:



Simulating the system

Let's assume we only want to simulate the effect of the force noise acting on TM2 along x, so we simulate a single noise source. We can do that by specifying a single input name and a value for the CPSD of that noise source:

  %% Simulate the system behavior: only tm2_x force noise
  % Simulation configuration plist
  simPlist_noise = plist(...
    'CPSD Variable Names', 'DIST_CAPACT_NOISE.tm2_x', ...
    'CPSD', 1, ...
    'Return outputs', {'DIST_CAPACT.tm2_x'}, ...
    'Nsamples', 1e6 ...
    );

  % Launch the simulation
  sim_output = GRScapactNoise_discrete.simulate(simPlist_noise);
  
  % Extract the AO with the force data
  out_tm2_x = sim_output.unpack();
  
  % Plot the results
  iplot(out_tm2_x)

The output of ssm/simulate is always encapsulated inside a a matrix object, so we can handle multiple output variables (blocks and ports) together. If we want to extract the individual ao object with the individual noise realizations for each port, we use the matrix/unpack method. We expect to see a plot similar to the following one:



You can verify that by changing the CPSD quantity, the noise level changes accordingly.

Estimating the PSD

Eventually, we want to estimate the PSD of the force. We also want to compare the estimated PSD with the expected output of the coloring filter; in order to do that, we have to change the units, so to account for the fact that the input CPSD is expressed in Hz^-1.

  %% Estimate the PSD
  % PSD estimation configuration plist
  psdPlist = plist(...
    'scale', 'PSD', ...
    'order', 1, ...
    'win', 'BH92', ...
    'navs', 25 ...
    );

  % Estimate the PSD
  S_out_tm2_x = out_tm2_x.psd(psdPlist);

  % Plot the PSD and compare with the expected noise shape
  % We have to account for the unit of the input to the coloring filter
  GRScapactNoise_tm2_x_disc_resp.setYunits(sqrt(S_out_tm2_x.yunits));
  iplot(sqrt(S_out_tm2_x), abs(GRScapactNoise_tm2_x_disc_resp));  

We expect to see a plot similar to the following one:



Again, you can verify that by changing the CPSD quantity, the noise levels change accordingly.



©LTP Team