Сконфигурируйте flightLogSignalMapping
объект визуализировать данные из пользовательского журнала рейса.
В этом примере это принято, что полетные данные уже анализируются в MATLAB® и хранятся как матовый файл. Этот пример фокусируется на конфигурировании flightLogSignalMapping
возразите так, чтобы это могло правильно обработать данные логов, сохраненные в матовом файле, и визуализировать их. Данные, customFlightData.mat
, хранит struct, который содержит 3 поля. Fs
частота дискретизации сигналов, сохраненных в матовом файле. IMU
и Trajectory
матрицы, содержащие фактическую информацию о рейсе. Траектория и данные IMU основаны на симулированном рейсе, который следует за спроектированным прямоугольным контуром на XY-плоскости.
customData = load("customFlightData.mat");
logData = customData.logData
logData = struct with fields:
IMU: [2785x9 double]
Fs: 100
Trajectory: [2785x10 double]
IMU
поле в logData
n-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-9 матрицей, с первыми 3 столбцами координаты КСИЗА НЕДА в . Следующие 3 столбца являются скоростью в направлении КСИЗА НЕДА в , и последние 4 столбца являются кватернионами, описывающими вращение UAV от инерции система координат 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);
Точно так же сопоставьте другие предопределенные signalsfor данные, которые присутствуют в журнале рейса. Задайте указатели функции ценности для данных. Сопоставьте сигналы с помощью того же 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
готово сгенерировать графики на основе данных сигнала, сохраненных в журнале. Чтобы визуализировать данные логов рейса, вызовите 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