В этом примере показано, как визуализировать моделируемые и фактические траектории рейса с объектом анимации (Aero.Animation), показывая при этом некоторые функциональные возможности объекта анимации. В этом примере можно использовать объект Aero.Animation, чтобы создать и сконфигурировать объект анимации, а затем использовать этот объект для создания, визуализации и манипулирования телами для траекторий рейса.
Этот код создает образец Aero.Animation
объект.
h = Aero.Animation;
Этот код устанавливает количество систем координат в секунду. Это управляет частотой отображения систем координат в окне рисунка.
h.FramesPerSecond = 10;
Этот код устанавливает секунды данных анимации в секунду во время масштабирования. Это свойство и 'FramesPerSecond'
свойство определяет временной шаг симуляции. Настройки в этом примере приводят к временному шагу приблизительно 0,5. Уравнение является (1/FramesPerSecond) * TimeScaling вместе с некоторыми дополнительными терминами для обработки для субсекундной точности.
h.TimeScaling = 5;
Этот код загружает тела, используя createBody
для объекта анимации, h
. Этот пример будет использовать эти тела для работы и отображения моделируемых и фактических траекторий рейса. Первое тело оранжевого цвета и будет представлять моделируемые данные. Второй корпус синего цвета и будет представлять фактические данные о рейсе.
idx1 = h.createBody('pa24-250_orange.ac','Ac3d'); idx2 = h.createBody('pa24-250_blue.ac','Ac3d');
Используя тела из предыдущего кода, этот код обеспечивает моделируемые и фактические зарегистрированные данные для траекторий рейса в следующих файлах:
Файл simdata содержит записанные симулированные данные. simdata
настраивается как массив 6DoF, который является одним из стандартных форматов данных.
Файл fltdata содержит фактические рейсы тестовых данных. В этом примере fltdata
настраивается в пользовательском формате. Пример должен создать пользовательскую функцию чтения и задать 'TimeSeriesSourceType'
параметр в 'Custom'
.
Чтобы загрузить файлы simdata и fltdata:
load simdata load fltdata
Чтобы работать с пользовательским рейсом тестовых данных, этот код устанавливает второе тело 'TimeSeriesReadFcn'
. Пользовательская функция чтения находится здесь: matlabroot/toolbox/aero/astdemos/CustomReadBodyTSData.m
h.Bodies{2}.TimeseriesReadFcn = @CustomReadBodyTSData;
Установите данные timeseries тел.
h.Bodies{1}.TimeSeriesSource = simdata;
h.Bodies{2}.TimeSeriesSource = fltdata;
h.Bodies{2}.TimeSeriesSourceType = 'Custom';
Этот код иллюстрирует, как можно манипулировать камерой для двух тел.
The 'PositionFcn'
свойство объекта камеры управляет положением камеры относительно тел в анимации. Камера по умолчанию 'PositionFcn'
идёт по пути первого транспортного средства погони. Поэтому камере требуется несколько шагов, чтобы она правильно расположилась в положении плоскости погони. Значение по умолчанию 'PositionFcn'
находится здесь: matlabroot/toolbox/aero/aero/doFirstOrderChaseCameraDynamics.m
Задайте 'PositionFcn'
.
h.Camera.PositionFcn = @doFirstOrderChaseCameraDynamics;
Этот код использует show
метод для создания графического объекта рисунка для объекта анимации.
h.show();
Этот код использует play
метод для анимации тел на время данных timeseries. Использование этого метода проиллюстрирует небольшие различия между моделируемыми и летными данными.
h.play();
Код также может использовать пользовательский, упрощенный 'PositionFcn'
это статическое положение, основанное на положении тел (то есть без динамики). Упрощенное 'PositionFcn'
находится здесь: matlabroot/toolbox/aero/astdemos/staticCameraPosition.m
Установите новый 'PositionFcn'
.
h.Camera.PositionFcn = @staticCameraPosition;
Запуск анимации с новыми 'PositionFcn'
.
h.play();
Этот код иллюстрирует, как переместить тела в стартовое положение (на основе данных timeseries) и обновить положение камеры в соответствии с новым 'PositionFcn'
. Этот код использует updateBodies
и updateCamera
.
t = 0; h.updateBodies(t); h.updateCamera(t);
Этот код иллюстрирует, как изменить положение тел, сначала получив текущее положение тела, а затем разделив тела.
Получите текущие положения тела и повороты от объектов тела.
pos1 = h.Bodies{1}.Position; rot1 = h.Bodies{1}.Rotation; pos2 = h.Bodies{2}.Position; rot2 = h.Bodies{2}.Rotation;
Разделите тела, используя moveBody
. Этот код разделяет и изменяет положение двух тел.
h.moveBody(1,pos1 + [0 0 -3],rot1); h.moveBody(2,pos1 + [0 0 0],rot2);
Этот код иллюстрирует, как создать прозрачность в первом теле. Код делает это, изменяя свойства патча тела через 'PatchHandles'
. (Для получения дополнительной информации о закрашенных фигурах в MATLAB ® смотрите Introduction to Patch Objects
раздел в документации MATLAB.)
Примечание.На некоторых платформах, использующих программное обеспечение отрисовки OpenGL ®, прозрачность может привести к снижению скорости анимации.
Смотрите opengl
документация для получения дополнительной информации об OpenGL в MATLAB.
Чтобы создать прозрачность, код получает указатели закрашенной фигуры для первого тела.
patchHandles2 = h.Bodies{1}.PatchHandles;
Установите требуемые значения граней и ребер.
desiredFaceTransparency = .3; desiredEdgeTransparency = 1;
Этот код получает текущие данные грани и ребра альфа и изменяет все значения на желаемые значения альфа. На рисунке заметьте, что первое тело теперь имеет прозрачность.
for k = 1:size(patchHandles2,1) tempFaceAlpha = get(patchHandles2(k),'FaceVertexAlphaData'); tempEdgeAlpha = get(patchHandles2(k),'EdgeAlpha'); set(patchHandles2(k),... 'FaceVertexAlphaData',repmat(desiredFaceTransparency,size(tempFaceAlpha))); set(patchHandles2(k),... 'EdgeAlpha',repmat(desiredEdgeTransparency,size(tempEdgeAlpha))); end
Этот код иллюстрирует, как изменить цвет тела второго тела. Код делает это, изменяя свойства патча тела через 'PatchHandles'
.
patchHandles3 = h.Bodies{2}.PatchHandles;
Этот код устанавливает требуемый цвет закрашенной фигуры (красный).
desiredColor = [1 0 0];
Теперь код может получить текущие данные о цвете лица и изменить все значения на желаемые значения цвета. Обратите внимание на следующие точки кода:
The if
условие мешает окнам быть окрашенными.
Свойство name сохранено в данных геометрии тела (h.Bodies {2} .Geometry.FaceVertexColorData (k) .name).
Код изменяет только индексы в patchHandles3
с неоконными аналогами в данных геометрии тела.
Свойство имени не всегда может быть доступным для определения различных частей транспортного средства. В этих случаях вам нужно будет использовать альтернативный подход к выборочной раскраске.
for k = 1:size(patchHandles3,1) tempFaceColor = get(patchHandles3(k),'FaceVertexCData'); tempName = h.Bodies{2}.Geometry.FaceVertexColorData(k).name; if ~contains(tempName,'Windshield') &&... ~contains(tempName,'front-windows') &&... ~contains(tempName,'rear-windows') set(patchHandles3(k),... 'FaceVertexCData',repmat(desiredColor,[size(tempFaceColor,1),1])); end end
Следующий код отключает шасси для второго корпуса. Для этого он отключает видимость всех деталей транспортного средства, связанных с шасси. Обратите внимание на индексы в patchHandles3
вектор определялся из свойства name в геометрических данных. Другие источники данных могут не иметь этой информации. В этих случаях необходимо знать, какие индексы соответствуют конкретным частям геометрии.
for k = [1:8,11:14,52:57] set(patchHandles3(k),'Visible','off') end
Чтобы закрыть и удалить
h.delete();
%#ok<*REPMAT>