mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-16 05:00:35 +00:00
Add adaptive Cloop-4quadrant discriminator
This commit is contained in:
parent
f2fe8e9d0d
commit
59a991b884
@ -126,6 +126,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(
|
||||
// initialize internal vars
|
||||
d_dump = dump;
|
||||
d_veml = false;
|
||||
d_cloop = true;
|
||||
d_synchonizing = false;
|
||||
d_track_pilot = track_pilot;
|
||||
d_fs_in = fs_in;
|
||||
@ -535,6 +536,7 @@ void dll_pll_veml_tracking::start_tracking()
|
||||
// enable tracking pull-in
|
||||
d_state = 1;
|
||||
d_synchonizing = false;
|
||||
d_cloop = true;
|
||||
d_Prompt_buffer_deque.clear();
|
||||
d_last_prompt = gr_complex(0.0, 0.0);
|
||||
LOG(INFO) << "PULL-IN Doppler [Hz] = " << d_carrier_doppler_hz
|
||||
@ -703,11 +705,11 @@ void dll_pll_veml_tracking::do_correlation_step(const gr_complex *input_samples)
|
||||
}
|
||||
|
||||
|
||||
void dll_pll_veml_tracking::run_dll_pll(bool enable_costas_loop)
|
||||
void dll_pll_veml_tracking::run_dll_pll()
|
||||
{
|
||||
// ################## PLL ##########################################################
|
||||
// PLL discriminator
|
||||
if (enable_costas_loop)
|
||||
if (d_cloop)
|
||||
{
|
||||
// Costas loop discriminator, insensitive to 180 deg phase transitions
|
||||
d_carr_error_hz = pll_cloop_two_quadrant_atan(d_P_accu) / PI_2;
|
||||
@ -823,11 +825,18 @@ void dll_pll_veml_tracking::save_correlation_results()
|
||||
d_E_accu += *d_Early;
|
||||
d_P_accu += *d_Prompt;
|
||||
d_L_accu += *d_Late;
|
||||
d_current_symbol++;
|
||||
d_current_symbol %= d_symbols_per_bit;
|
||||
}
|
||||
// If tracking pilot, disable Costas loop
|
||||
if (d_track_pilot)
|
||||
d_cloop = false;
|
||||
else
|
||||
d_cloop = true;
|
||||
}
|
||||
|
||||
|
||||
void dll_pll_veml_tracking::log_data()
|
||||
void dll_pll_veml_tracking::log_data(bool integrating)
|
||||
{
|
||||
if (d_dump)
|
||||
{
|
||||
@ -876,6 +885,16 @@ void dll_pll_veml_tracking::log_data()
|
||||
tmp_E = std::abs<float>(d_E_accu);
|
||||
tmp_P = std::abs<float>(d_P_accu);
|
||||
tmp_L = std::abs<float>(d_L_accu);
|
||||
if (integrating)
|
||||
{
|
||||
// It compensates the amplitude difference while integrating
|
||||
float scale_factor = static_cast<float>(d_extend_correlation_symbols) / static_cast<float>(d_extend_correlation_symbols_count);
|
||||
tmp_VE *= scale_factor;
|
||||
tmp_E *= scale_factor;
|
||||
tmp_P *= scale_factor;
|
||||
tmp_L *= scale_factor;
|
||||
tmp_VL *= scale_factor;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@ -987,11 +1006,11 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
|
||||
{
|
||||
bool next_state = false;
|
||||
// Perform DLL/PLL tracking loop computations. Costas Loop enabled
|
||||
run_dll_pll(true);
|
||||
run_dll_pll();
|
||||
update_tracking_vars();
|
||||
|
||||
// enable write dump file this cycle (valid DLL/PLL cycle)
|
||||
log_data();
|
||||
log_data(false);
|
||||
if (d_secondary)
|
||||
{
|
||||
// ####### SECONDARY CODE LOCK #####
|
||||
@ -1139,6 +1158,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
|
||||
d_extend_correlation_symbols_count = 0;
|
||||
d_state = 4;
|
||||
}
|
||||
log_data(true);
|
||||
break;
|
||||
}
|
||||
case 4: // narrow tracking
|
||||
@ -1158,17 +1178,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
|
||||
}
|
||||
else
|
||||
{
|
||||
run_dll_pll(!d_secondary);
|
||||
//EQUIVALENT TO THE LINE ABOVE if (d_secondary)
|
||||
//{
|
||||
// //If secondary code is locked, disable Costas Loop
|
||||
// run_dll_pll(false);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// //The signal does not have secondary code, enable Costas Loop
|
||||
// run_dll_pll(true);
|
||||
//}
|
||||
run_dll_pll();
|
||||
update_tracking_vars();
|
||||
|
||||
// ########### Output the tracking results to Telemetry block ##########
|
||||
@ -1207,7 +1217,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
|
||||
current_synchro_data.Flag_valid_symbol_output = true;
|
||||
current_synchro_data.correlation_length_ms = d_correlation_length_ms;
|
||||
// enable write dump file this cycle (valid DLL/PLL cycle)
|
||||
log_data();
|
||||
log_data(false);
|
||||
// reset extended correlator
|
||||
d_VE_accu = gr_complex(0.0, 0.0);
|
||||
d_E_accu = gr_complex(0.0, 0.0);
|
||||
|
@ -112,16 +112,17 @@ private:
|
||||
bool cn0_and_tracking_lock_status();
|
||||
bool acquire_secondary();
|
||||
void do_correlation_step(const gr_complex *input_samples);
|
||||
void run_dll_pll(bool disable_costas_loop);
|
||||
void run_dll_pll();
|
||||
void update_tracking_vars();
|
||||
void clear_tracking_vars();
|
||||
void save_correlation_results();
|
||||
void log_data();
|
||||
void log_data(bool integrating);
|
||||
int save_matfile();
|
||||
|
||||
// tracking configuration vars
|
||||
bool d_dump;
|
||||
bool d_veml;
|
||||
bool d_cloop;
|
||||
unsigned int d_vector_length;
|
||||
unsigned int d_channel;
|
||||
double d_fs_in;
|
||||
|
84
src/utils/matlab/dll_pll_veml_plot_sample.m
Normal file
84
src/utils/matlab/dll_pll_veml_plot_sample.m
Normal file
@ -0,0 +1,84 @@
|
||||
% /*!
|
||||
% * \file dll_pll_vml_plot_sample.m
|
||||
% * \brief Read GNSS-SDR Tracking dump binary file using the provided
|
||||
% function and plot some internal variables
|
||||
% * \author Javier Arribas, 2011. jarribas(at)cttc.es
|
||||
% * \author Antonio Ramos, 2018. antonio.ramos(at)cttc.es
|
||||
% * -------------------------------------------------------------------------
|
||||
% *
|
||||
% * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
|
||||
% *
|
||||
% * GNSS-SDR is a software defined Global Navigation
|
||||
% * Satellite Systems receiver
|
||||
% *
|
||||
% * This file is part of GNSS-SDR.
|
||||
% *
|
||||
% * GNSS-SDR is free software: you can redistribute it and/or modify
|
||||
% * it under the terms of the GNU General Public License as published by
|
||||
% * the Free Software Foundation, either version 3 of the License, or
|
||||
% * at your option) any later version.
|
||||
% *
|
||||
% * GNSS-SDR is distributed in the hope that it will be useful,
|
||||
% * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
% * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
% * GNU General Public License for more details.
|
||||
% *
|
||||
% * You should have received a copy of the GNU General Public License
|
||||
% * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||
% *
|
||||
% * -------------------------------------------------------------------------
|
||||
% */
|
||||
close all;
|
||||
clear all;
|
||||
|
||||
if ~exist('dll_pll_veml_read_tracking_dump.m','file')
|
||||
addpath('./libs')
|
||||
end
|
||||
|
||||
samplingFreq = 5000000; %[Hz]
|
||||
coherent_integration_time_ms = 20; %[ms]
|
||||
channels = 5; % Number of channels
|
||||
first_channel = 0; % Number of the first channel
|
||||
|
||||
path = '/dump_dir/'; %% CHANGE THIS PATH
|
||||
|
||||
for N=1:1:channels
|
||||
tracking_log_path = [path 'track_ch_' num2str(N+first_channel-1) '.dat']; %% CHANGE track_ch BY YOUR dump_filename
|
||||
GNSS_tracking(N)= dll_pll_veml_read_tracking_dump(tracking_log_path);
|
||||
end
|
||||
|
||||
% GNSS-SDR format conversion to MATLAB GPS receiver
|
||||
|
||||
for N=1:1:channels
|
||||
trackResults(N).status = 'T'; %fake track
|
||||
trackResults(N).codeFreq = GNSS_tracking(N).code_freq_hz.';
|
||||
trackResults(N).carrFreq = GNSS_tracking(N).carrier_doppler_hz.';
|
||||
trackResults(N).dllDiscr = GNSS_tracking(N).code_error.';
|
||||
trackResults(N).dllDiscrFilt = GNSS_tracking(N).code_nco.';
|
||||
trackResults(N).pllDiscr = GNSS_tracking(N).carr_error.';
|
||||
trackResults(N).pllDiscrFilt = GNSS_tracking(N).carr_nco.';
|
||||
|
||||
trackResults(N).I_P = GNSS_tracking(N).P.';
|
||||
trackResults(N).Q_P = zeros(1,length(GNSS_tracking(N).P));
|
||||
|
||||
trackResults(N).I_VE = GNSS_tracking(N).VE.';
|
||||
trackResults(N).I_E = GNSS_tracking(N).E.';
|
||||
trackResults(N).I_L = GNSS_tracking(N).L.';
|
||||
trackResults(N).I_VL = GNSS_tracking(N).VL.';
|
||||
trackResults(N).Q_VE = zeros(1,length(GNSS_tracking(N).VE));
|
||||
trackResults(N).Q_E = zeros(1,length(GNSS_tracking(N).E));
|
||||
trackResults(N).Q_L = zeros(1,length(GNSS_tracking(N).L));
|
||||
trackResults(N).Q_VL = zeros(1,length(GNSS_tracking(N).VL));
|
||||
trackResults(N).data_I = GNSS_tracking(N).prompt_I.';
|
||||
trackResults(N).data_Q = GNSS_tracking(N).prompt_Q.';
|
||||
trackResults(N).PRN = GNSS_tracking(N).PRN.';
|
||||
trackResults(N).CNo = GNSS_tracking(N).CN0_SNV_dB_Hz.';
|
||||
|
||||
% Use original MATLAB tracking plot function
|
||||
settings.numberOfChannels = channels;
|
||||
settings.msToProcess = length(GNSS_tracking(N).E)*coherent_integration_time_ms;
|
||||
plotVEMLTracking(N,trackResults,settings)
|
||||
end
|
||||
|
||||
|
||||
|
153
src/utils/matlab/libs/dll_pll_veml_read_tracking_dump.m
Normal file
153
src/utils/matlab/libs/dll_pll_veml_read_tracking_dump.m
Normal file
@ -0,0 +1,153 @@
|
||||
% /*!
|
||||
% * \file dll_pll_veml_read_tracking_dump.m
|
||||
% * \brief Read GNSS-SDR Tracking dump binary file into MATLAB.
|
||||
% * \author Luis Esteve, 2012. luis(at)epsilon-formacion.com
|
||||
% * -------------------------------------------------------------------------
|
||||
% *
|
||||
% * Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
|
||||
% *
|
||||
% * GNSS-SDR is a software defined Global Navigation
|
||||
% * Satellite Systems receiver
|
||||
% *
|
||||
% * This file is part of GNSS-SDR.
|
||||
% *
|
||||
% * GNSS-SDR is free software: you can redistribute it and/or modify
|
||||
% * it under the terms of the GNU General Public License as published by
|
||||
% * the Free Software Foundation, either version 3 of the License, or
|
||||
% * at your option) any later version.
|
||||
% *
|
||||
% * GNSS-SDR is distributed in the hope that it will be useful,
|
||||
% * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
% * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
% * GNU General Public License for more details.
|
||||
% *
|
||||
% * You should have received a copy of the GNU General Public License
|
||||
% * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||
% *
|
||||
% * -------------------------------------------------------------------------
|
||||
% */
|
||||
|
||||
function [GNSS_tracking] = dll_pll_veml_read_tracking_dump (filename, count)
|
||||
%% usage: dll_pll_veml_read_tracking_dump (filename, [count])
|
||||
%%
|
||||
%% open GNSS-SDR tracking binary log file .dat and return the contents
|
||||
%%
|
||||
|
||||
m = nargchk (1,2,nargin);
|
||||
|
||||
num_float_vars = 17;
|
||||
num_unsigned_long_int_vars = 1;
|
||||
num_double_vars = 1;
|
||||
num_unsigned_int_vars = 1;
|
||||
|
||||
if(~isempty(strfind(computer('arch'), '64')))
|
||||
% 64-bit computer
|
||||
double_size_bytes = 8;
|
||||
unsigned_long_int_size_bytes = 8;
|
||||
float_size_bytes = 4;
|
||||
unsigned_int_size_bytes = 4;
|
||||
else
|
||||
double_size_bytes = 8;
|
||||
unsigned_long_int_size_bytes = 4;
|
||||
float_size_bytes = 4;
|
||||
unsigned_int_size_bytes = 4;
|
||||
end
|
||||
|
||||
skip_bytes_each_read = float_size_bytes * num_float_vars + unsigned_long_int_size_bytes * num_unsigned_long_int_vars + ...
|
||||
double_size_bytes * num_double_vars + num_unsigned_int_vars*unsigned_int_size_bytes;
|
||||
|
||||
bytes_shift = 0;
|
||||
|
||||
if (m)
|
||||
usage (m);
|
||||
end
|
||||
|
||||
if (nargin < 2)
|
||||
count = Inf;
|
||||
end
|
||||
%loops_counter = fread (f, count, 'uint32',4*12);
|
||||
f = fopen (filename, 'rb');
|
||||
if (f < 0)
|
||||
else
|
||||
v1 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v2 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v3 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v4 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v5 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v6 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v7 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next interleaved float
|
||||
v8 = fread (f, count, 'long', skip_bytes_each_read - unsigned_long_int_size_bytes);
|
||||
bytes_shift = bytes_shift + unsigned_long_int_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v9 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v10 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v11 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v12 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v13 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v14 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v15 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v16 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next interleaved float
|
||||
v17 = fread (f, count, 'float', skip_bytes_each_read - float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next float
|
||||
v18 = fread (f, count, 'float', skip_bytes_each_read-float_size_bytes);
|
||||
bytes_shift = bytes_shift + float_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next double
|
||||
v19 = fread (f, count, 'double', skip_bytes_each_read - double_size_bytes);
|
||||
bytes_shift = bytes_shift + double_size_bytes;
|
||||
fseek(f,bytes_shift,'bof'); % move to next unsigned int
|
||||
v20 = fread (f, count, 'uint', skip_bytes_each_read - unsigned_int_size_bytes);
|
||||
fclose (f);
|
||||
|
||||
GNSS_tracking.VE = v1;
|
||||
GNSS_tracking.E = v2;
|
||||
GNSS_tracking.P = v3;
|
||||
GNSS_tracking.L = v4;
|
||||
GNSS_tracking.VL = v5;
|
||||
GNSS_tracking.prompt_I = v6;
|
||||
GNSS_tracking.prompt_Q = v7;
|
||||
GNSS_tracking.PRN_start_sample = v8;
|
||||
GNSS_tracking.acc_carrier_phase_rad = v9;
|
||||
GNSS_tracking.carrier_doppler_hz = v10;
|
||||
GNSS_tracking.code_freq_hz = v11;
|
||||
GNSS_tracking.carr_error = v12;
|
||||
GNSS_tracking.carr_nco = v13;
|
||||
GNSS_tracking.code_error = v14;
|
||||
GNSS_tracking.code_nco = v15;
|
||||
GNSS_tracking.CN0_SNV_dB_Hz = v16;
|
||||
GNSS_tracking.carrier_lock_test = v17;
|
||||
GNSS_tracking.var1 = v18;
|
||||
GNSS_tracking.var2 = v19;
|
||||
GNSS_tracking.PRN = v20;
|
||||
end
|
||||
|
@ -69,8 +69,8 @@ for channelNr = channelList
|
||||
timeAxisInSeconds = (1:4:settings.msToProcess)/1000;
|
||||
|
||||
%----- Discrete-Time Scatter Plot ---------------------------------
|
||||
plot(handles(1, 1), trackResults(channelNr).I_P,...
|
||||
trackResults(channelNr).Q_P, ...
|
||||
plot(handles(1, 1), trackResults(channelNr).data_I,...
|
||||
trackResults(channelNr).data_Q, ...
|
||||
'.');
|
||||
|
||||
grid (handles(1, 1));
|
||||
@ -80,8 +80,9 @@ for channelNr = channelList
|
||||
ylabel(handles(1, 1), 'Q prompt');
|
||||
|
||||
%----- Nav bits ---------------------------------------------------
|
||||
plot (handles(1, 2), timeAxisInSeconds, ...
|
||||
trackResults(channelNr).I_P);
|
||||
t = (1:length(trackResults(channelNr).data_I));
|
||||
plot (handles(1, 2), t, ...
|
||||
trackResults(channelNr).data_I);
|
||||
|
||||
grid (handles(1, 2));
|
||||
title (handles(1, 2), 'Bits of the navigation message');
|
||||
@ -89,7 +90,8 @@ for channelNr = channelList
|
||||
axis (handles(1, 2), 'tight');
|
||||
|
||||
%----- PLL discriminator unfiltered--------------------------------
|
||||
plot (handles(2, 1), timeAxisInSeconds, ...
|
||||
t = (1:length(trackResults(channelNr).pllDiscr));
|
||||
plot (handles(2, 1), t, ...
|
||||
trackResults(channelNr).pllDiscr, 'r');
|
||||
|
||||
grid (handles(2, 1));
|
||||
@ -99,7 +101,8 @@ for channelNr = channelList
|
||||
title (handles(2, 1), 'Raw PLL discriminator');
|
||||
|
||||
%----- Correlation ------------------------------------------------
|
||||
plot(handles(2, 2), timeAxisInSeconds, ...
|
||||
t = (1:length(trackResults(channelNr).I_VE));
|
||||
plot(handles(2, 2), t, ...
|
||||
[sqrt(trackResults(channelNr).I_VE.^2 + ...
|
||||
trackResults(channelNr).Q_VE.^2)', ...
|
||||
sqrt(trackResults(channelNr).I_E.^2 + ...
|
||||
@ -127,7 +130,8 @@ for channelNr = channelList
|
||||
set(hLegend, 'Interpreter', 'Latex');
|
||||
|
||||
%----- PLL discriminator filtered----------------------------------
|
||||
plot (handles(3, 1), timeAxisInSeconds, ...
|
||||
t = (1:length(trackResults(channelNr).pllDiscrFilt));
|
||||
plot (handles(3, 1), t, ...
|
||||
trackResults(channelNr).pllDiscrFilt, 'b');
|
||||
|
||||
grid (handles(3, 1));
|
||||
@ -137,7 +141,8 @@ for channelNr = channelList
|
||||
title (handles(3, 1), 'Filtered PLL discriminator');
|
||||
|
||||
%----- DLL discriminator unfiltered--------------------------------
|
||||
plot (handles(3, 2), timeAxisInSeconds, ...
|
||||
t = (1:length(trackResults(channelNr).dllDiscr));
|
||||
plot (handles(3, 2), t, ...
|
||||
trackResults(channelNr).dllDiscr, 'r');
|
||||
|
||||
grid (handles(3, 2));
|
||||
@ -147,7 +152,8 @@ for channelNr = channelList
|
||||
title (handles(3, 2), 'Raw DLL discriminator');
|
||||
|
||||
%----- DLL discriminator filtered----------------------------------
|
||||
plot (handles(3, 3), timeAxisInSeconds, ...
|
||||
t = (1:length(trackResults(channelNr).dllDiscrFilt));
|
||||
plot (handles(3, 3), t, ...
|
||||
trackResults(channelNr).dllDiscrFilt, 'b');
|
||||
|
||||
grid (handles(3, 3));
|
||||
|
Loading…
Reference in New Issue
Block a user