Skip to content
Snippets Groups Projects
Commit cf833ee1 authored by Alessandro Donadi's avatar Alessandro Donadi
Browse files

fixed bug in fault generation and removed SFD, in it's place it's using the...

fixed bug in fault generation and removed SFD, in it's place it's using the latest data from the first sensor
parent 4ebd2977
2 merge requests!19Update main with the Gemini simulator development,!17Fault simulation implementation in dev
classdef Sensor_no_offset < handle
% Author: Jan Hammelman
% Skyward Experimental Rocketry | ELC-SCS Dept | electronics@skywarder.eu
% email: jan.hammelmann@skywarder.eu,alessandro.delduca@skywarder.eu
% Release date: 01/03/2021
%SENSOR Super call for all sensor
% Inherit from handle to have state variables which can be changed
% inside a method
properties (Access='public')
minMeasurementRange; % Max limit of sensor
maxMeasurementRange; % Min limit of sensor
bit; % number of bits for the sensor ( if available)
resolution; % resolution of the sensor
noiseVariance; % Varianze for the gaussian white noise
offset; % Offset in all directions
dt; % Sampling time
end
methods (Access='public')
function obj = Sensor_no_offset()
%SENSOR Construct an instance of this class
% Sensor is the Superclass of all sensors
end
function outputArg = sens(obj,inputArg,temp)
%SENS Method to use the sensor.
% Gets the simulation data and extract the unideal sensor
% output
%
% Inputs:
% inputArg sensor data
% temp: temperature of the sensor
%
% Outputs:
% outputArg sensor data with nois,
% offsets, etc.
inputArg=obj.whiteNoise(inputArg);
inputArg=obj.addOffset(inputArg);
inputArg=obj.quantization(inputArg);
inputArg=obj.saturation(inputArg);
outputArg = inputArg;
end
end
methods (Access='protected')
function outputArg = saturation(obj,inputArg)
%SATURATION Includes saturation to the sensor model
% inputArg is limited to minMeasurementRange at the lower end and maxMeasurementRange at the upper end
%
% Necessary properties:
% minMeasurementRange: Max limit of sensor
% maxMeasurementRange: Min limit of sensor
%
% Inputs:
% inputArg: sensor data
%
% Outputs:
% outputArg: sensor data with saturation
% checks if sensor data is higher than max possible value
if (~isempty(obj.maxMeasurementRange))
inputArg(inputArg>obj.maxMeasurementRange)=obj.maxMeasurementRange;
end
% checks if sensor data is lower than min possible value
if (~isempty(obj.minMeasurementRange))
inputArg(inputArg<obj.minMeasurementRange)=obj.minMeasurementRange;
end
outputArg = inputArg;
end
function outputArg = quantization(obj,inputArg)
%QUATIZATION Quantize the sensor data
% Quantizes the signal with the resolution properie of the object
%
% Necessary properties:
% resolution: resolution of the sensor
%
% Inputs:
% inputArg: sensor data
%
% Outputs:
% outputArg: quantized sensor data
if (~isempty(obj.resolution))
inputArg = obj.resolution*round(inputArg/obj.resolution);
end
outputArg = inputArg;
end
function outputArg = whiteNoise(obj,inputArg)
%WHITE_NOISE Includes gaussian white noise to the sensor data
% Adds gaussian white noise with variance noiseVariance
%
% Necessary properties:
% noiseVariance: Varianze for the gaussian white noise
%
% Inputs:
% inputArg: sensor data
%
% Outputs:
% outputArg: sensor data with white noise
if (~isempty(obj.noiseVariance))
% inputArg=inputArg+ones(size(inputArg)).*sqrt(obj.noiseVariance).*randn(1,1);,
inputArg=inputArg+sqrt(obj.noiseVariance).*randn(size(inputArg));
end
outputArg = inputArg;
end
function outputArg = addOffset(obj,inputArg)
%ADD_OFFSET Adds an offset to the signal
% adds the propertie offset to the input signal
%
% Necessary properties:
% offset: Offset in all directions
%
% Inputs:
% inputArg: sensor data
%
% Outputs:
% outputArg: sensor data plus offset
if (~isempty(obj.offset))
inputArg=inputArg+ones(size(inputArg)).*obj.offset;
end
outputArg = inputArg;
end
end
end
function [classification] = linear_svm_predict(Mdl, x)
%{
HELP:
classification function for sensor fault detection
INPUT:
- Mdl = model of the support vector machine
- x = features
OUTPUT:
- classification = true or false, if true then it's faulty
%}
scale = Mdl.Scale;
beta = Mdl.Beta;
bias = Mdl.Bias;
%normalization of the feautures
mu = Mdl.Mu;
sigma = Mdl.Sigma;
%x = bsxfun(@minus,x,mu);
x = x - mu;
x = x./sigma;
%calculating the prediction score of the linear kernel
score = -(((x/scale))*beta + bias);
%labeling based on the sign of the score
if(score < 0 || isnan(score))
classification = true;
else
classification = false;
end
end
\ No newline at end of file
function [sensorData,faulty_sensors] = run_SensorFaultDetection_SVM(SVM_model,sensorData,faulty_sensors,flagAscent,t)
%{
HELP:
Run the sensor fault detection algorithm with the Support Vector Machine.
INPUT:
OUTPUT:
Authors: Alessandro Donadi, Marco Marchesi
Skyward Experimental Rocketry | AVN Dept | GNC
email: marco.marchesi@skywarder.eu, alessandro.donadi@skywarder.eu
REVISIONS
1 - Revision date: 24/07/2023
release
%}
current_detection = faulty_sensors; % da capire come gestire y
for i = 1:length(faulty_sensors)
if(faulty_sensors(i) == false)
[current_detection(i)] = fault_detection_reduced_fft(SVM_model, sensorData.chunk{i}, flagAscent); %this function takes a chunk of data which goes backwards in time of a window_size
end
end
faulty_sensors = current_detection;
if all(faulty_sensors) || t<SVM_model.takeoff_shadowmode
faulty_sensors = [false, false, false];
end
% which sensors to pick?
goodSensors = [1,2,3]; % this has to be moved in the settings,
goodSensors = goodSensors(not(faulty_sensors));
sensorData.barometer.time = sensorData.barometer_sens{1}.time';
sensorData.barometer.t0 = sensorData.barometer_sens{1}.t0;
h_baro = zeros(length(goodSensors),length(sensorData.barometer_sens{1}.z));
pn = zeros(length(goodSensors),length(sensorData.barometer_sens{1}.measures));
for i_baro = 1:length(goodSensors)
h_baro(i_baro,:) = sensorData.barometer_sens{goodSensors(i_baro)}.z;
pn(i_baro,:) = sensorData.barometer_sens{goodSensors(i_baro)}.measures;
end
sensorData.barometer.z = mean(h_baro,1);
sensorData.barometer.measures = mean(pn,1);
\ No newline at end of file
...@@ -5,19 +5,13 @@ ...@@ -5,19 +5,13 @@
% release 16/09/2023 % release 16/09/2023
% fault parameters % fault parameters
max_offset = 1300; %Pa max_offset = 2000; %Pa
min_offset = 200; %Pa min_offset = 1200; %Pa
max_degradation = 1300; %Pa max_degradation = 2000; %Pa
min_degradation = 200; %Pa min_degradation = 1800; %Pa
N_faulty_sensors = 2; % how many sensors to set which will have faults, faulty sensors will be selected at random N_faulty_sensors = 2; % how many sensors to set which will have faults, faulty sensors will be selected at random
offset_value_2 = round((max_offset-min_offset)*rand() + min_offset);
offset_value_3 = round((max_offset-min_offset)*rand() + min_offset);
degradation_value_2 = round((max_degradation-min_degradation)*rand() + min_degradation);
degradation_value_3 = round((max_degradation-min_degradation)*rand() + min_degradation);
selected_sensors = []; selected_sensors = [];
fault_type = ["no fault", "no fault", "no fault"]; fault_type = ["no fault", "no fault", "no fault"];
for i = 1:N_faulty_sensors for i = 1:N_faulty_sensors
...@@ -33,8 +27,9 @@ for i = 1:N_faulty_sensors ...@@ -33,8 +27,9 @@ for i = 1:N_faulty_sensors
iterations_for_selection = 1; iterations_for_selection = 1;
end end
for j = 1:iterations_for_selection for j = 1:iterations_for_selection
if isempty(selected_sensors) || isequal(rand_sensor, selected_sensors(j)) if isempty(selected_sensors) || ~isequal(rand_sensor, selected_sensors(j))
selected_sensors = [selected_sensors, rand_sensor]; selected_sensors = [selected_sensors, rand_sensor];
else
continue_generate = true; continue_generate = true;
end end
end end
...@@ -122,11 +117,11 @@ switch fault_type(3) ...@@ -122,11 +117,11 @@ switch fault_type(3)
case "offset", case "offset",
offset_value_3 = round((max_offset-min_offset)*rand() + min_offset); offset_value_3 = round((max_offset-min_offset)*rand() + min_offset);
sensorSettings.barometer3 = sensorSettings.barometer3.setOffset(offset_value_3); % i don't know the unit of measurment as of now sensorSettings.barometer3 = sensorSettings.barometer3.setOffset(offset_value_3); % i don't know the unit of measurment as of now
[sensorSettings.barometer3, fault_time_3] = sensorSettings.barometer1.setErrorTime(); % in seconds [sensorSettings.barometer3, fault_time_3] = sensorSettings.barometer3.setErrorTime(); % in seconds
case "degradation", case "degradation",
degradation_value_3 = round((max_offset-min_offset)*rand() + min_offset); degradation_value_3 = round((max_offset-min_offset)*rand() + min_offset);
sensorSettings.barometer3 = sensorSettings.barometer3.setDegradation(degradation_value_3); % i don't know the unit of measurment as of now sensorSettings.barometer3 = sensorSettings.barometer3.setDegradation(degradation_value_3); % i don't know the unit of measurment as of now
[sensorSettings.barometer3, fault_time_3] = sensorSettings.barometer1.setErrorTime(); % in seconds [sensorSettings.barometer3, fault_time_3] = sensorSettings.barometer3.setErrorTime(); % in seconds
case "freezing", case "freezing",
sensorSettings.barometer3.setFreezing; sensorSettings.barometer3.setFreezing;
[sensorSettings.barometer3, fault_time_3] = sensorSettings.barometer3.setErrorTime(); % in seconds [sensorSettings.barometer3, fault_time_3] = sensorSettings.barometer3.setErrorTime(); % in seconds
...@@ -201,7 +196,7 @@ sensorSettings.pitot_static.resolution = (sensorSettings.pitot_static.maxMeasure ...@@ -201,7 +196,7 @@ sensorSettings.pitot_static.resolution = (sensorSettings.pitot_static.maxMeasure
sensorSettings.pitot_static.noiseVariance = 0.043043; % from flight logs sensorSettings.pitot_static.noiseVariance = 0.043043; % from flight logs
% total pressure % total pressure
sensorSettings.pitot_total = Sensor_no_offset(); sensorSettings.pitot_total = Sensor();
sensorSettings.pitot_total.maxMeasurementRange = 2*1034.21; % mbar ( 30psi) sensorSettings.pitot_total.maxMeasurementRange = 2*1034.21; % mbar ( 30psi)
sensorSettings.pitot_total.minMeasurementRange = 0; sensorSettings.pitot_total.minMeasurementRange = 0;
sensorSettings.pitot_total.bit = 12; sensorSettings.pitot_total.bit = 12;
......
...@@ -12,22 +12,12 @@ This function runs all subsystems in a simulated environment ...@@ -12,22 +12,12 @@ This function runs all subsystems in a simulated environment
% simulation of the faults % simulation of the faults
% sensor fault detection algorithm
Nsensors = [1,2,3];
goodSensors = Nsensors(not(settings.faulty_sensors)); %PRENDO ULTIMO VALORE??
if settings.flagAscent sensorData.barometer.z = sensorData.barometer_sens{1}.z(1,end);
SVM_model= settings.SVM_1; sensorData.barometer.measures = sensorData.barometer_sens{1}.measures(1,end);
else sensorData.barometer.time = sensorData.barometer_sens{1}.time(1,end);
SVM_model = settings.SVM_2;
end
for i = goodSensors
sensorData.chunk{i}(1,1:end-length(sensorData.barometer_sens{i}.measures)) = sensorData.chunk{i}(1+length(sensorData.barometer_sens{i}.measures):end);
sensorData.chunk{i}(1,end-length(sensorData.barometer_sens{i}.measures)+1:end) = sensorData.barometer_sens{i}.measures;
if length(sensorData.chunk{i})>SVM_model.N_sample
warning('chunk length is greater than %d samples',SVM_model.N_sample)
end
end
[sensorData,settings.faulty_sensors] = run_SensorFaultDetection_SVM(SVM_model,sensorData,settings.faulty_sensors,settings.flagAscent,t1);
sensorTot.barometer.pressure_measures(sensorTot.barometer.n_old:sensorTot.barometer.n_old + size(sensorData.barometer.measures' ,1) - 1,:) = sensorData.barometer.measures'; sensorTot.barometer.pressure_measures(sensorTot.barometer.n_old:sensorTot.barometer.n_old + size(sensorData.barometer.measures' ,1) - 1,:) = sensorData.barometer.measures';
sensorTot.barometer.altitude(sensorTot.barometer.n_old:sensorTot.barometer.n_old + size(sensorData.barometer.measures',1) - 1,:) = sensorData.barometer.z'; sensorTot.barometer.altitude(sensorTot.barometer.n_old:sensorTot.barometer.n_old + size(sensorData.barometer.measures',1) - 1,:) = sensorData.barometer.z';
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment