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

7 次查看(过去 30 天)
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!

采纳的回答

Ruchika Parag
Ruchika Parag 2024-7-19
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 个评论
Fangjun Jiang
Fangjun Jiang 2024-7-22
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 2024-7-22
I have also reproduced the issue with logging plain Constants. I ended up doing something similar to this.

请先登录,再进行评论。

更多回答(1 个)

Fangjun Jiang
Fangjun Jiang 2024-7-19
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 个评论
Yevgeniy
Yevgeniy 2024-7-22
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 2024-7-22
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

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Sources 的更多信息

产品


版本

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by