В этом примере показано, как исследовать степень батареи транспортного средства в режиме разряда в различных циклах привода. Данные для этого анализа содержатся в наборе файлов журнала транспортных средств в формате 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
для последующего анализа. The 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 Степени vs. Event Длительности.
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