Сконфигурируйте flightLogSignalMapping объект для визуализации данных из пользовательского журнала полетов.
В этом примере предполагается, что полетные данные уже анализируются в MATLAB ® и сохраняются как MAT-файл. В этом примере рассматривается конфигурирование flightLogSignalMapping чтобы он мог правильно обрабатывать данные журнала, сохраненные в MAT-файле, и визуализировать их. Данные, customFlightData.matхранит структуру, содержащую 3 поля. Fs частота дискретизации сигналов, сохраненных в файле MAT. IMU и Trajectory - матрицы, содержащие фактическую информацию о полете. Данные траектории и данные IMU основаны на моделируемом полете, который следует по спроецированной прямоугольной траектории на плоскости XY.
customData = load("customFlightData.mat");
logData = customData.logDatalogData = struct with fields:
IMU: [2785×9 double]
Fs: 100
Trajectory: [2785×10 double]
IMU поле в logData - матрица n-by-9, где первые 3 столбца являются показаниями акселерометра в . Следующие 3 столбца - показания гироскопа в , а последние 3 столбца - показания магнитометра в .
logData.IMU(1:5, :)
ans = 5×9
0.8208 0.7968 10.7424 0.0862 0.0873 0.0862 327.6000 297.6000 283.8000
0.8016 0.8160 10.7904 0.0883 0.0873 0.0862 327.6000 297.6000 283.8000
0.7680 0.7680 10.7568 0.0862 0.0851 0.0851 327.6000 297.6000 283.8000
0.8208 0.7536 10.7520 0.0873 0.0883 0.0819 327.6000 297.6000 283.8000
0.7872 0.7728 10.7328 0.0873 0.0862 0.0830 327.6000 297.6000 283.8000
Trajectory поле в logData является матрицей n-by-9, с первыми 3 столбцами - координаты XYZ NED в м. Следующие 3 столбца - скорость в направлении XYZ NED в , а последние 4 столбца - кватернионы, описывающие поворот БПЛА от инерционного кадра NED к корпусу. Каждая строка является единственной точкой траектории со всеми указанными параметрами.
logData.Trajectory(1:5,:)
ans = 5×10
0.0200 0 -4.0000 2.0000 0 -0.0036 1.0000 0 0 -0.0000
0.0400 0 -4.0001 2.0000 0 -0.0072 1.0000 0 0 -0.0000
0.0600 0 -4.0002 2.0000 0 -0.0108 1.0000 0 0 -0.0000
0.0800 0 -4.0003 2.0000 0 -0.0143 1.0000 0 0 -0.0000
0.1000 0 -4.0004 2.0000 0 -0.0179 1.0000 0 0 -0.0001
Создать flightLogSignalMapping объект без входного аргумента, так как пользовательский формат журнала не соответствует стандарту "ulog" или "tlog" определение.
customPlotter = flightLogSignalMapping;
Объект имеет предопределенный набор сигналов, которые можно отобразить. Отображая эти предопределенные сигналы, вы получаете доступ к набору предопределенных графиков. Обратите внимание, что некоторые сигналы имеют суффикс символа «#». Для этих сигналов можно добавить целые числа в качестве суффиксов к названиям сигналов, чтобы плоттер журнала полета мог обрабатывать несколько сигналов такого типа, таких как вторичные сигналы IMU и показания барометра. Звонить info.
% Predefined signals info(customPlotter, "Signal")
ans=18×4 table
SignalName IsMapped SignalFields FieldUnits
_____________________ ________ __________________________________________________________________________________________________________________________________________________________________________________________________________ ___________________________________________________
"Accel#" false "AccelX, AccelY, AccelZ" "m/s^2, m/s^2, m/s^2"
"Airspeed#" false "PressDiff, IndicatedAirSpeed, Temperature" "Pa, m/s, degreeC"
"AttitudeEuler" false "Roll, Pitch, Yaw" "rad, rad, rad"
"AttitudeRate" false "BodyRotationRateX, BodyRotationRateY, BodyRotationRateZ" "rad/s, rad/s, rad/s"
"AttitudeTargetEuler" false "RollTarget, PitchTarget, YawTarget" "rad, rad, rad"
"Barometer#" false "PressAbs, PressAltitude, Temperature" "Pa, m, degreeC"
"Battery" false "Voltage_1, Voltage_2, Voltage_3, Voltage_4, Voltage_5, Voltage_6, Voltage_7, Voltage_8, Voltage_9, Voltage_10, Voltage_11, Voltage_12, Voltage_13, Voltage_14, Voltage_15, Voltage_16, RemainingCapacity" "v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, %"
"GPS#" false "Latitude, Longitude, Altitude, GroundSpeed, CourseAngle, SatellitesVisible" "degree, degree, m, m/s, degree, N/A"
"Gyro#" false "GyroX, GyroY, GyroZ" "rad/s, rad/s, rad/s"
"LocalENU" false "X, Y, Z" "m, m, m"
"LocalENUTarget" false "XTarget, YTarget, ZTarget" "m, m, m"
"LocalENUVel" false "VX, VY, VZ" "m/s, m/s, m/s"
"LocalENUVelTarget" false "VXTarget, VYTarget, VZTarget" "m/s, m/s, m/s"
"LocalNED" false "X, Y, Z" "m, m, m"
"LocalNEDTarget" false "XTarget, YTarget, ZTarget" "m, m, m"
"LocalNEDVel" false "VX, VY, VZ" "m/s, m/s, m/s"
⋮
% Predefined plots info(customPlotter,"Plot")
ans=10×4 table
PlotName ReadyToPlot MissingSignals RequiredSignals
_______________________ ___________ ____________________________________ ____________________________________
"Attitude" false "AttitudeEuler, AttitudeRate, Gyro#" "AttitudeEuler, AttitudeRate, Gyro#"
"AttitudeControl" false "AttitudeEuler, AttitudeTargetEuler" "AttitudeEuler, AttitudeTargetEuler"
"Battery" false "Battery" "Battery"
"Compass" false "AttitudeEuler, Mag#, GPS#" "AttitudeEuler, Mag#, GPS#"
"GPS2D" false "GPS#" "GPS#"
"Height" false "Barometer#, GPS#, LocalNED" "Barometer#, GPS#, LocalNED"
"Speed" false "GPS#, Airspeed#" "GPS#, Airspeed#"
"Trajectory" false "LocalNED, LocalNEDTarget" "LocalNED, LocalNEDTarget"
"TrajectoryTracking" false "LocalNED, LocalNEDTarget" "LocalNED, LocalNEDTarget"
"TrajectoryVelTracking" false "LocalNEDVel, LocalNEDVelTarget" "LocalNEDVel, LocalNEDVelTarget"
flightLogSignalMapping объект должен знать, как данные хранятся в журнале полета, прежде чем он сможет визуализировать данные. Чтобы связать имена сигналов с дескрипторами функций, которые обращаются к соответствующей информации в logData, необходимо отобразить сигналы с помощью mapSignal. Каждый сигнал определяется как вектор временной метки и матрица значений сигнала.
Например, чтобы сопоставить Gyro# сигнал, определите timeAccess функциональный дескриптор на основе частоты дискретизации данных датчика. Этот дескриптор функции генерирует вектор временной метки для значений сигнала с использованием глобального интервала временной метки для данных.
timeAccess = @(x)seconds(1/x.Fs*(1:size(x.IMU)));
Затем проверьте, какие поля должны быть определены для Gyro# сигнал с использованием info.
info(customPlotter,"Signal","Gyro#")
ans=1×4 table
SignalName IsMapped SignalFields FieldUnits
__________ ________ _____________________ _____________________
"Gyro#" false "GyroX, GyroY, GyroZ" "rad/s, rad/s, rad/s"
Gyro# сигнал требует трех столбцов, содержащих показания гироскопа для осей XYZ. Определите gyroAccess соответственно дескриптор функции и сопоставить его с timeAccess использование mapSignal.
gyroAccess = @(x)x.IMU(:,4:6);
mapSignal(customPlotter,"Gyro",timeAccess,gyroAccess);Аналогично, отображение других предварительно определенных сигналов для данных, которые присутствуют в журнале полета. Определите дескрипторы функций значений для данных. Отображение сигналов с использованием одного и того же timeAccess векторная функция временной метки.
% IMU data stores accelerometer and magnetometer data. accelAccess = @(x)x.IMU(:,1:3); magAccess = @(x)x.IMU(:,7:9)*1e-2; % Flight trajectory in local NED coordinates % XYZ coordinates nedAccess = @(x)x.Trajectory(:, 1:3); % XYZ celocities nedVelAccess = @(x)x.Trajectory(:, 4:6); % Roll Pitch Yaw rotations converted from a quaternion attitudeAccess = @(x)flip(quat2eul(x.Trajectory(:, 7:10)),2); % Configure flightLogSignalMapping for custom data mapSignal(customPlotter, "Accel", timeAccess, accelAccess); mapSignal(customPlotter, "Mag", timeAccess, magAccess); mapSignal(customPlotter, "LocalNED", timeAccess, nedAccess); mapSignal(customPlotter, "LocalNEDVel", timeAccess, nedVelAccess); mapSignal(customPlotter, "AttitudeEuler", timeAccess, attitudeAccess);
После отображения всех сигналов customPlotter готов генерировать графики на основе данных сигнала, хранящихся в журнале. Чтобы быстро проверить, правильно ли отображены сигналы, следует проверить, что вызов Signal и указать logData.
checkSignal(customPlotter,logData);
-------------------------------------------- SignalName: Gyro Pass -------------------------------------------- SignalName: Accel Pass -------------------------------------------- SignalName: Mag Pass -------------------------------------------- SignalName: LocalNED Pass -------------------------------------------- SignalName: LocalNEDVel Pass -------------------------------------------- SignalName: AttitudeEuler Pass
Чтобы получить предварительный просмотр отображенного сигнала, выберите опцию предварительного просмотра в check Signal.
checkSignal(customPlotter,logData,'Preview',"on",'Signal',"Accel");
-------------------------------------------- SignalName: Accel Pass Press a key to continue or 'q' to quit. Figure needs to be in focus.
Для визуализации данных полетного журнала звоните show и указать logData. Все графики, доступные на основе отображенных сигналов, показаны на рисунках.
predefinedPlots = show(customPlotter,logData);







Для анализа журнала подробностей мод определите больше сигналов и добавьте больше графиков, кроме предопределенных графиков, сохраненных в flightLogSignalMapping. Укажите дескриптор функции, фильтрующий ускорения больше 1.
accelThreshold = @(x)(vecnorm(accelAccess(x)')>11)'; mapSignal(customPlotter, "HighAccel", timeAccess,accelThreshold, "AccelGreaterThan11", "N/A");
Звонить updatePlot для добавления пользовательских графиков. Укажите объект плоттера журнала полетов и имя для графика в качестве первых двух аргументов. Чтобы указать временной ряд данных, используйте "Timeseries" в качестве третьего аргумента, а затем перечислить данные.
updatePlot(customPlotter, "AnalyzeAccel","Timeseries",["HighAccel.AccelGreaterThan11", "LocalNEDVel.VX", "LocalNEDVel.VY", "LocalNEDVel.VZ"]);
Определите пользовательский дескриптор функции для создания дескриптора фигуры (см. определение функции ниже). Эта функция генерирует периодограмму с использованием fft и другие функции в данных ускорения и строят их графики. Функция возвращает дескриптор функции.
updatePlot(customPlotter, "plotFFTAccel",@(acc)plotFFTAccel(acc),"Accel");
Проверьте, что customPlotter теперь содержит новый сигнал и два новых графика с использованием info.
info(customPlotter, "Signal")ans=19×4 table
SignalName IsMapped SignalFields FieldUnits
_____________________ ________ __________________________________________________________________________________________________________________________________________________________________________________________________________ ___________________________________________________
"Accel" true "AccelX, AccelY, AccelZ" "m/s^2, m/s^2, m/s^2"
"AttitudeEuler" true "Roll, Pitch, Yaw" "rad, rad, rad"
"Gyro" true "GyroX, GyroY, GyroZ" "rad/s, rad/s, rad/s"
"HighAccel" true "AccelGreaterThan11" "N/A"
"LocalNED" true "X, Y, Z" "m, m, m"
"LocalNEDVel" true "VX, VY, VZ" "m/s, m/s, m/s"
"Mag" true "MagX, MagY, MagZ" "Gs, Gs, Gs"
"Airspeed#" false "PressDiff, IndicatedAirSpeed, Temperature" "Pa, m/s, degreeC"
"AttitudeRate" false "BodyRotationRateX, BodyRotationRateY, BodyRotationRateZ" "rad/s, rad/s, rad/s"
"AttitudeTargetEuler" false "RollTarget, PitchTarget, YawTarget" "rad, rad, rad"
"Barometer#" false "PressAbs, PressAltitude, Temperature" "Pa, m, degreeC"
"Battery" false "Voltage_1, Voltage_2, Voltage_3, Voltage_4, Voltage_5, Voltage_6, Voltage_7, Voltage_8, Voltage_9, Voltage_10, Voltage_11, Voltage_12, Voltage_13, Voltage_14, Voltage_15, Voltage_16, RemainingCapacity" "v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, %"
"GPS#" false "Latitude, Longitude, Altitude, GroundSpeed, CourseAngle, SatellitesVisible" "degree, degree, m, m/s, degree, N/A"
"LocalENU" false "X, Y, Z" "m, m, m"
"LocalENUTarget" false "XTarget, YTarget, ZTarget" "m, m, m"
"LocalENUVel" false "VX, VY, VZ" "m/s, m/s, m/s"
⋮
info(customPlotter, "Plot")ans=12×4 table
PlotName ReadyToPlot MissingSignals RequiredSignals
_______________________ ___________ _____________________ ____________________________________
"AnalyzeAccel" true "" "HighAccel, LocalNEDVel"
"Attitude" true "AttitudeRate" "AttitudeEuler, AttitudeRate, Gyro#"
"AttitudeControl" true "AttitudeTargetEuler" "AttitudeEuler, AttitudeTargetEuler"
"Compass" true "GPS#" "AttitudeEuler, Mag#, GPS#"
"Height" true "Barometer#, GPS#" "Barometer#, GPS#, LocalNED"
"Trajectory" true "LocalNEDTarget" "LocalNED, LocalNEDTarget"
"TrajectoryTracking" true "LocalNEDTarget" "LocalNED, LocalNEDTarget"
"TrajectoryVelTracking" true "LocalNEDVelTarget" "LocalNEDVel, LocalNEDVelTarget"
"plotFFTAccel" true "" "Accel"
"Battery" false "Battery" "Battery"
"GPS2D" false "GPS#" "GPS#"
"Speed" false "GPS#, Airspeed#" "GPS#, Airspeed#"
Укажите имена печати. Звонить show использование "PlotsToShow" для визуализации анализа данных ускорения.
accelAnalysisProfile = ["AnalyzeAccel", "plotFFTAccel"]; accelAnalysisPlots = show(customPlotter, logData, "PlotsToShow", accelAnalysisProfile);


В этом примере показано, как использовать flightLogSignalMapping объект для просмотра предопределенных сигналов и графиков, а также настройки собственных графиков для анализа полетного журнала.
function h = plotFFTAccel(acc) h = figure("Name", "AccelFFT"); ax = newplot(h); v = acc.Values{1}; Fs = v.Properties.SampleRate; N = floor(length(v.AccelX)/2)*2; hold(ax, "on"); for idx = 1:3 x = v{1:N, idx}; xdft = fft(x); xdft = xdft(1:N/2+1); psdx = (1/(Fs*N)) * abs(xdft).^2; psdx(2:end-1) = 2*psdx(2:end-1); freq = 0:Fs/length(x):Fs/2; plot(ax, freq, 10*log10(psdx)); end hold(ax, "off"); title("Periodogram Using FFT"); xlabel("f (Hz)"); ylabel("Power/Frequency (dB/Hz)"); legend("AccelX", "AccelY", "AccelZ"); end