Этот пример показывает вам, как исследовать питание от батареи транспортного средства во время режима выброса через различные циклы диска. Данные для этого анализа содержатся в наборе файлов журнала транспортного средства в формате MDF. В данном примере мы должны создать механизм, который может "обнаружить", когда батарея транспортного средства находится в данном режиме. То, что мы действительно делаем, создает детектор, чтобы определить, когда сигнал интереса (питание от батареи в этом случае) соответствует определенным критериям. Когда критериям будут соответствовать, мы вызовем это "событие". Каждое событие будет впоследствии "квалифицировано" внушительными границами времени. То есть событие "квалифицировано", если оно сохраняется в течение по крайней мере 5 секунд (такой шаг проверки может помочь ограничить шум и удалить переходные процессы). Пороги, показанные в этом примере, иллюстративны только.
Задайте местоположение набора файла, чтобы анализировать.
dataDir = '*.dat';
Заставьте имена всех MDF-файлов анализировать в массив отдельной ячейки.
fileList = dir(dataDir); fileName = {fileList(:).name}'; fileDir = {fileList(:).folder}'; fullFilePath = fullfile(fileDir, fileName)
fullFilePath = 10×1 cell array
{'\\central-mi\home\jpyle\documents\MATLAB\examples\vnt-ex86857001\ADAC.dat' }
{'\\central-mi\home\jpyle\documents\MATLAB\examples\vnt-ex86857001\ECE.dat' }
{'\\central-mi\home\jpyle\documents\MATLAB\examples\vnt-ex86857001\FTP75.dat'}
{'\\central-mi\home\jpyle\documents\MATLAB\examples\vnt-ex86857001\HUDDS.dat'}
{'\\central-mi\home\jpyle\documents\MATLAB\examples\vnt-ex86857001\HWFET.dat'}
{'\\central-mi\home\jpyle\documents\MATLAB\examples\vnt-ex86857001\JC08.dat' }
{'\\central-mi\home\jpyle\documents\MATLAB\examples\vnt-ex86857001\LA92.dat' }
{'\\central-mi\home\jpyle\documents\MATLAB\examples\vnt-ex86857001\NEDC.dat' }
{'\\central-mi\home\jpyle\documents\MATLAB\examples\vnt-ex86857001\SC03.dat' }
{'\\central-mi\home\jpyle\documents\MATLAB\examples\vnt-ex86857001\US06.dat' }
Используйте массив ячеек, чтобы получить набор мини-таблиц, которые представляют представляющие интерес данные о событиях для каждого отдельного MDF-файла.
numFiles = size(fullFilePath, 1); eventSet = cell(numFiles, 1)
eventSet = 10×1 cell array
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 double}
{0×0 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'
Теперь посмотрите на Среднюю Степень по сравнению с Продолжительностью события.
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 = 5
Создайте объект MDF считать данные из MDF-файла.
mdfObj = mdf(fullFilePath{fileMsk})
mdfObj = MDF with properties: File Details Name: 'HWFET.dat' Path: '\\central-mi\home\jpyle\documents\MATLAB\examples\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: [0×0 struct] File Contents Attachment: [0×0 struct] ChannelNames: {{5×1 cell}} ChannelGroup: [1×1 struct]
Идентифицируйте канал с channelList
и считанный все данные из этого файла.
chInfo = channelList(mdfObj, chName)
chInfo=1×9 table
ChannelName ChannelGroupNumber ChannelGroupNumSamples ChannelGroupAcquisitionName ChannelGroupComment ChannelDisplayName ChannelUnit ChannelComment ChannelDescription
___________ __________________ ______________________ ___________________________ ___________________ __________________ ___________ ______________ __________________
"Power" 1 79176 <undefined> cg comment "" cg comment cg comment ""
data = read(mdfObj, chInfo)
data = 1×1 cell array
{79176×1 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)