Класс Device

Класс Device

Как было описано в первой части документации, основным классом, через который происходит взаимодействие симулятора с моделью подвижной единицы является класс Vehicle, от которого наследуется класс конкретной модели ПЕ. Разрабатывая тепловоз ТЭП70 мы создадим соответствующий класс TEP70, унаследовав его от Vehicle.

Однако, любой подвижной состав, будь то локомотив или вагон, представляет собой совокупность разного рода оборудования: механического, электрического, пневматического. Работа этого оборудования может описываться достаточно сложными математическими соотношениями. Кроме того, различные блоки оборудования взаимодействуют между собой.

Одним из основных принципов RRS является предоставление разработчику полного контроля над разработкой программной части дополнения. А это, в том числе означает, что код, реализующий функции DLL подвижной единицы, можно писать произвольным образом, не придерживаясь каких либо правил. Например, можно реализовать локомотив ТЭП70 в методах класса TEP70, не прибегая к созданию других классов. Однако, такой подход приведет к разбуханию и запутыванию кода, усложнению его отладки и сопровождения.

Очевидно, что выгоднее реализовать каждых элемент оборудования локомотива в виде отдельного класса, реализовав внутри него функции устройства и обеспечить возможность получения состояния и задания параметров, для взаимодействия с другими устройствами. Для этой цели в динамическом движке симулятора предусмотрел класс Device.

Этот класс позволяет реализовать любой динамический объект, описываемый дифференциальными и алгебраическими уравнениями. Он представляет собой абстрактное устройство, состояние которого описывается вектором состояния y.

Интерфейс класса Device можно посмотреть в комплекте SDK, поставляемого с симулятором в файле device.h. Опишем основные методы и свойства этого класса

  • virtual void step(double t, double dt) — выполняет один шаг интегрирования дифференциальных уравнений и расчет алгебраических соотношений. По-умолчание решение дифференциальных уравнений выполняется методом Рунге-Кутты 4-го порядка. Метод может быть переопределен в наследнике, например для задания собственного алгоритма решения дифференциальных уравнений.
  • void setY(size_t i, double value) — задать значение переменной состояния. Несмотря на то, что внутри классов-наследников возможен прямой доступ к вектору y, рекомендуется пользоваться этим методом, так как он является «дуракозащищенным», исключая выход за границы массива.
  • double getY(size_t i) — возвращает значение переменной состояния. Аналогично, рекомендуется для использования, так как исключает выход за границы вектора y.
  • virtual void read_config(const QString &path) — выполняет чтение файла конфигурации в формате XML. При этом предполагается что файл находится в каталоге cfg/devices/
  • virtual void read_custom_config(const QString &path) — выполняет чтение конфигурационного файла, расположенного по произвольному пути.
  • void setControl(QMap<int, bool> keys, control_signals_t control_signals = control_signals_t()) — передает внутрь класса состояние клавиш и массив сигналов, принимаемых от внешних устройств, подключенных к симулятору.

Публичные методы используются для настройки устройства и организации его взаимодействия с другими устройствами. Реализация функционала устройства выполняется разработчиком внутри защищенных методов

  • virtual void ode_system(const state_vector_t &Y, state_vector_t &dYdt, double t) = 0 — абстрактный метод, реализующий систему дифференциальных уравнений, описывающих динамику устройства. Является методом обратного вызова, вызывается 4 раза при выполнении метода step(…)
  • virtual void preStep(state_vector_t &Y, double t) — вызывается перед выполнением шага интегрирования дифференциальных уравнений. В данном методе реализуются алгебраические соотношения, описывающие работу устройства.
  • virtual void postStep(state_vector_t &Y, double t) — вызывается после выполнения шага интегрирования дифференциальных уравнений. В данном методе реализуются алгебраические соотношения, описывающие работу устройства.
  • virtual void load_config(CfgReader &cfg) — реализует загрузку параметров из XML-конфига. Данный метод вызывается при вызове методов read_config(…) и read_custom_config(…). При этом выполняется автоматическое открытие файла, его разбор. Доступ к считанным параметрам выполняется через методы класса CfgReader, экземпляр которого передается в load_config(…) по ссылке.
  • virtual void stepKeysControl(double t, double dt) — рекомендуется для организации обработки клавиш. Вызывается на каждом шаге симуляции.
  • bool getKeyState(int key) const — возвращает состояние клавиши по её коду.
  • bool isShift() const — проверка нажатия клавиш Shift.
  • bool isControl() const — проверка нажатия клавиш Ctrl.
  • bool isAlt() const — проверка нажатия клавиш Alt.

По сути реализация устройства сводится к созданию класса, наследующего от Device и переопределении его защищенных методов. Естественно, для полной ясности необходимо привести конкретный пример реализации.

Будем считать, что мы создали проект DLL нашего тепловоза, как это описано в соответствующей главе. Реализуем для тепловоза первое устройство — контроллер машиниста.

Назад Вперед
Содержание