Output single Timetable from Simulink when some logged signals are not doubles

13 visualizzazioni (ultimi 30 giorni)
I would like, for conveneince, to have one timetable output from Simulink. Some of my signals are logical and I don't want to make them doubles because that incorrectly captures what they are supposed to be. However, when I try to log these signals to a single timetable using extractTimetable(simout.logsout)
Error using matlab.internal.tabular.extractTimetable (line 300)
Unable to synchronize the specified data. To output data as a cell array, set 'OutputFormat' to 'cell-by-signal'.
Error in Simulink.SimulationData.Dataset/extractTimetable
(...)
Caused by:
Error using timetable/synchronize (line 343)
All variables in input timetables must support missing values (e.g. floating point, categorical, datetime, duration, or text) when synchronizing using 'fillwithmissing'.
As far as I can tell, it is because extractTimetable synchronizes everything with a specific option, fillWithNaN. Is there a way to change this behavior to allow logical values to be used? fillwithconstant would be my preference - but it is moot because my simulations do not have missing values!

Risposta accettata

Ruchika Parag
Ruchika Parag il 19 Lug 2024
Hi Yevgeniy, the error arises because logical values do not support missing values, which 'extractTimetable' tries to handle using the 'fillwithmissing' option.
To address this, you can try the following steps:
  1. Convert Logical Signals to a Compatible Format: Before logging, you can convert logical signals to a format that supports missing values, such as double or categorical. This way, 'extractTimetable' can handle them properly. After extraction, you can convert them back to logical if needed.
  2. Custom Extraction Function: Create a custom function to manually extract and synchronize the signals without using the default 'extractTimetable' method. This function can handle logical signals appropriately.
An example of how you might implement the first approach is as follows:
% Convert logical signals to double before logging
% Assuming 'simout' is your simulation output
for i = 1:numel(simout.logsout)
if islogical(simout.logsout{i}.Values.Data)
simout.logsout{i}.Values.Data = double(simout.logsout{i}.Values.Data);
end
end
% Now use extractTimetable
timetableData = extractTimetable(simout.logsout);
% Convert the signals back to logical if necessary
for i = 1:width(timetableData)
if all(ismember(timetableData{:, i}, [0, 1]))
timetableData{:, i} = logical(timetableData{:, i});
end
end
For the second approach, you can manually extract the signals and synchronize them without using 'extractTimetable':
% Manually extract and synchronize signals
signals = simout.logsout;
time = signals{1}.Values.Time;
data = arrayfun(@(s) s.Values.Data, signals, 'UniformOutput', false);
names = arrayfun(@(s) s.Name, signals, 'UniformOutput', false);
% Create a timetable
timetableData = timetable(time, data{:}, 'VariableNames', names);
% Synchronize manually if needed
% Assuming no missing values, just concatenate
% timetableData = synchronize(timetableData, 'union', 'fillwithconstant', NaN);
% Convert back to logical if necessary
for i = 1:width(timetableData)
if all(ismember(timetableData{:, i}, [0, 1]))
timetableData{:, i} = logical(timetableData{:, i});
end
end
By using one of these approaches, you should be able to log your logical signals into a single timetable without encountering the synchronization issue. Hope this helps!
  2 Commenti
Fangjun Jiang
Fangjun Jiang il 22 Lug 2024
The OP mentioned " but it is moot because my simulations do not have missing values!".
I suspect the error was due to something else. I would suggest the OP try a most simple example, logging a double and a boolean signal to see what happens.
Yevgeniy
Yevgeniy il 22 Lug 2024
I have also reproduced the issue with logging plain Constants. I ended up doing something similar to this.

Accedi per commentare.

Più risposte (1)

Fangjun Jiang
Fangjun Jiang il 19 Lug 2024
I did an example in R2022b. It didn't have problem logging and extracting different data types in a single table. Your problem must be something else.
>> d=matlab.internal.tabular.extractTimetable(out.logsout)
d =
1405×4 timetable
Time q w sw bq
_____________ ___________ ___________ ___________ _____
0 sec 0 0 0 false
0.0011246 sec -5.1379e-07 -2.9886e-06 -2.9886e-06 true
>> class(d.w)
ans =
'double'
>> class(d.sw)
ans =
'single'
>> class(d.bq)
ans =
'logical'
  4 Commenti
Yevgeniy
Yevgeniy il 22 Lug 2024
Exactly the same same error message as I wrote above, but it seems like you have a 0-length simulation, and I simulated for default times and time-step. It's possible that extractTimetable internally does not attempt to synchronize if there is only one time, can you try running for 10 seconds?
Fangjun Jiang
Fangjun Jiang il 22 Lug 2024
That "0-length" is due to the fact that the source of the signal is Constant blocks. The simulation did run for 10 seconds.
I tried a Step signal and also converted it to boolean. Below is the result.
What is your MATLAB R2021b patch number? Mine is "Update 6". It looks like "Update 7" is also available.
>> s=matlab.internal.tabular.extractTimetable(out.logsout)
s =
53×2 timetable
Time b d
_______ _____ _
0 sec false 0
0.2 sec false 0
0.4 sec false 0
0.6 sec false 0
0.8 sec false 0
1 sec false 0
1 sec true 1
1 sec true 1
1.2 sec true 1

Accedi per commentare.

Prodotti


Release

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by