В этом примере показано, как исследовать мощность аккумулятора транспортного средства в режиме разрядки в различных циклах привода. Данные для этого анализа содержатся в наборе файлов регистрации транспортных средств в формате MDF. Для этого примера нам нужно создать механизм, который может «обнаруживать», когда батарея транспортного средства находится в заданном режиме. На самом деле мы строим детектор, чтобы определить, когда интересующий сигнал (в данном случае мощность батареи) соответствует определенным критериям. Когда критерии будут выполнены, мы назовем это «событием». Каждое событие будет впоследствии «квалифицировано» путем наложения временных ограничений. То есть событие является «квалифицированным», если оно сохраняется в течение по меньшей мере 5 секунд (такой шаг квалификации может помочь ограничить шум и удалить переходные процессы). Пороговые значения, показанные в этом примере, являются только иллюстративными.
Определите расположение анализируемого набора файлов.
dataDir = '*.dat';Получите имена всех MDF-файлов для анализа в одном массиве ячеек.
fileList = dir(dataDir);
fileName = {fileList(:).name}';
fileDir = {fileList(:).folder}';
fullFilePath = fullfile(fileDir, fileName)fullFilePath = 5x1 cell
{'/tmp/BR2021ad_1655202_62692/mlx_to_docbook1/tp4da62608/vnt-ex86857001/ADAC.dat' }
{'/tmp/BR2021ad_1655202_62692/mlx_to_docbook1/tp4da62608/vnt-ex86857001/ECE.dat' }
{'/tmp/BR2021ad_1655202_62692/mlx_to_docbook1/tp4da62608/vnt-ex86857001/HWFET.dat'}
{'/tmp/BR2021ad_1655202_62692/mlx_to_docbook1/tp4da62608/vnt-ex86857001/SC03.dat' }
{'/tmp/BR2021ad_1655202_62692/mlx_to_docbook1/tp4da62608/vnt-ex86857001/US06.dat' }
Используйте массив ячеек для захвата коллекции мини-таблиц, которые представляют интересующие данные событий для каждого отдельного MDF-файла.
numFiles = size(fullFilePath, 1); eventSet = cell(numFiles, 1)
eventSet=5×1 cell array
{0x0 double}
{0x0 double}
{0x0 double}
{0x0 double}
{0x0 double}
chName = 'Power'; % Name of the signal of interest in the MDF-files thdValue = [5, 55]; % Threshold in KW thdDuration = seconds(5); % Threshold for event qualification
eventSet - массив ячеек, содержащий сводную таблицу для каждого проанализированного файла. Этот массив ячеек таблиц можно рассматривать как набор мини-таблиц с одинаковым форматом, но содержимое каждой мини-таблицы соответствует отдельным MDF-файлам.
В этом примере детектор событий сообщает не только время начала и окончания события, но и некоторые описательные статистические данные о самом событии. Такой вид агрегирования и создания отчетов может быть полезен для операций обнаружения и устранения неполадок. Чтобы более подробно понять интерфейс файлов MDF и обработку данных, откройте и изучите processMDF из этого примера.
Следует отметить, что обработка данных записывается таким образом, что каждый MDF-файл анализируется атомарно и возвращается в свой собственный индекс результирующего массива ячеек. Это позволяет функции обработки использовать возможности параллельных вычислений с parfor. parfor и стандарт for являются взаимозаменяемыми с точки зрения результатов, но приводят к изменению времени обработки, необходимого для завершения анализа. Чтобы поэкспериментировать с параллельными вычислениями, просто измените for звоните ниже parfor и выполните этот пример.
for i = 1:numFiles eventSet{i} = processMDF(fullFilePath{i}, chName, thdValue, thdDuration); end eventSet{1}
ans=20×8 table
FileName EventNumber EventDuration EventStart EventStop MeanPower_KW MaxPower_KW MinPower_KW
________ ___________ _____________ __________ __________ ____________ ___________ ___________
ADAC.dat 2 00:01:22 19.345 sec 101.79 sec 28.456 53.5 5
ADAC.dat 3 00:00:08 107.82 sec 116.36 sec 21.295 53.5 5.09
ADAC.dat 5 00:00:55 123.8 sec 179.67 sec 28.642 37.2 5.01
ADAC.dat 6 00:00:10 189.83 sec 200.36 sec 11.192 54.4 5.1
ADAC.dat 8 00:00:40 212.4 sec 252.79 sec 28.539 37.4 5.01
ADAC.dat 9 00:00:08 258.76 sec 267.37 sec 21.289 53.7 5.02
ADAC.dat 11 00:00:44 274.81 sec 319.79 sec 28.554 37.2 5.08
ADAC.dat 12 00:00:08 325.75 sec 334.37 sec 21.279 53.7 5.05
ADAC.dat 14 00:00:44 341.81 sec 386.79 sec 28.554 37.2 5.08
ADAC.dat 15 00:00:08 392.75 sec 401.37 sec 21.278 53.7 5.04
ADAC.dat 17 00:00:44 408.81 sec 453.67 sec 28.579 37.2 5.08
ADAC.dat 18 00:00:07 463.77 sec 471.37 sec 11.895 54.676 5.04
ADAC.dat 20 00:00:40 483.44 sec 523.79 sec 28.544 37.363 5.0682
ADAC.dat 21 00:00:08 529.75 sec 538.37 sec 21.279 53.7 5.05
ADAC.dat 23 00:00:44 545.81 sec 590.79 sec 28.553 37.2 5.08
ADAC.dat 24 00:00:08 596.75 sec 605.37 sec 21.279 53.7 5.05
⋮
Объединение содержимого массива ячеек eventSet в одну таблицу. Теперь мы можем использовать таблицу eventSummary для последующего анализа. head используется для отображения первых 5 строк таблицы eventSummary.
eventSummary = vertcat(eventSet{:});
disp(head(eventSummary, 5)) FileName EventNumber EventDuration EventStart EventStop MeanPower_KW MaxPower_KW MinPower_KW
________ ___________ _____________ __________ __________ ____________ ___________ ___________
ADAC.dat 2 00:01:22 19.345 sec 101.79 sec 28.456 53.5 5
ADAC.dat 3 00:00:08 107.82 sec 116.36 sec 21.295 53.5 5.09
ADAC.dat 5 00:00:55 123.8 sec 179.67 sec 28.642 37.2 5.01
ADAC.dat 6 00:00:10 189.83 sec 200.36 sec 11.192 54.4 5.1
ADAC.dat 8 00:00:40 212.4 sec 252.79 sec 28.539 37.4 5.01
Ознакомьтесь с обзором продолжительности мероприятия.
histogram(eventSummary.EventDuration) grid on title 'Distribution of Event Duration' xlabel 'Event Duration (minutes)' ylabel 'Frequency'

Теперь посмотрите на Mean Power vs. Продолжительность события.
scatter(eventSummary.MeanPower_KW, minutes(eventSummary.EventDuration)) grid on xlabel 'MeanPower(KW)' ylabel 'Event Duration (minutes)' title 'Mean Power vs. Event Duration'

Проверьте событие, продолжавшееся более 4 минут. Сначала создайте маску для поиска интересующего случая. msk - логический индекс, показывающий, какие строки таблицы eventSummary соответствуют указанным критериям.
msk = eventSummary.EventDuration > minutes(4);
Вытащить строки таблицы eventSummary , которые соответствуют указанным критериям и отображают результаты.
eventOfInterest = eventSummary(msk, :); disp(eventOfInterest)
FileName EventNumber EventDuration EventStart EventStop MeanPower_KW MaxPower_KW MinPower_KW
_________ ___________ _____________ __________ __________ ____________ ___________ ___________
HWFET.dat 18 00:04:43 297.22 sec 580.37 sec 12.275 30.2 5.0024
Для считывания данных из MDF-файла необходимы полный путь к файлу и его имя. Стол eventOfInterest имеет имя файла, потому что мы отслеживали это. Он не имеет полного пути к этому файлу. Чтобы получить эту информацию, мы применим немного теории множеств к нашему первоначальному списку имен файлов и путей. Сначала найдите полный путь к файлу, представляющему интерес.
fileMsk = find(ismember(fileName, eventOfInterest.FileName))
fileMsk = 3
Создайте объект MDF для чтения данных из файла MDF.
mdfObj = mdf(fullFilePath{fileMsk})mdfObj =
MDF with properties:
File Details
Name: 'HWFET.dat'
Path: '/tmp/BR2021ad_1655202_62692/mlx_to_docbook1/tp4da62608/vnt-ex86857001/HWFET.dat'
Author: ''
Department: ''
Project: ''
Subject: ''
Comment: ''
Version: '3.00'
DataSize: 3167040
InitialTimestamp: 2017-08-09 12:20:03.000000000
Creator Details
ProgramIdentifier: 'MDA v7.1'
Creator: [1x1 struct]
File Contents
Attachment: [0x1 struct]
ChannelNames: {{5x1 cell}}
ChannelGroup: [1x1 struct]
Options
Conversion: Numeric
Идентификация канала с помощью channelList и прочтите все данные из этого файла.
chInfo = channelList(mdfObj, chName)
chInfo=1×9 table
ChannelName ChannelGroupNumber ChannelGroupNumSamples ChannelGroupAcquisitionName ChannelGroupComment ChannelDisplayName ChannelUnit ChannelComment ChannelDescription
___________ __________________ ______________________ ___________________________ ___________________ __________________ ___________ ______________ __________________
"Power" 1 79176 <undefined> cg comment "" <undefined> <undefined> ""
data = read(mdfObj, chInfo)
data = 1x1 cell array
{79176x1 timetable}
Обратите внимание, что чтение с выходом channelList возвращает массив результатов ячейки.
data{1}(1:10,:)ans=10×1 timetable
Time Power
_____________ _________
0.0048987 sec 0
0.0088729 sec 0
0.01 sec 0
0.013223 sec 0
0.016446 sec 0
0.019668 sec 0
0.02 sec 0
0.021658 sec -2.4e-28
0.023878 sec -3.42e-15
0.026098 sec -1.04e-14
Пользовательские функции печати полезны для инкапсуляции и повторного использования. Визуализация события в контексте всего цикла дисковода. Чтобы понять, как создавалась визуализация, откройте и изучите eventPlotter из этого примера.
eventPlotter(data{1}, eventOfInterest)
Закройте доступ к MDF-файлу, удалив его переменную из рабочей области.
clear mdfObj