Встроенное программное обеспечение видеоларингоскопа «СЕНСАР»
Версия ПО: 1.15 Дата: 23.02.2026
Встроенное программное обеспечение видеоларингоскопа «СЕНСАР» является управляющим программным обеспечением видеоларингоскопа, предназначенного для визуализации дыхательных путей и голосовых связок во время эндотрахеальной интубации, а также для осмотра и обследования верхних дыхательных путей, в том числе при проведении отдельных ЛОР-процедур. Программное обеспечение обеспечивает захват изображения с эндоскопической камеры в режиме реального времени, отображение видеопотока на встроенном дисплее, фотосъёмку и видеозапись, просмотр медиатеки, передачу видеопотока по сети, а также управление системными параметрами устройства.
Целевое аппаратное обеспечение: встраиваемая платформа на базе системы-на-кристалле Rockchip RV1126 с процессорным ядром ARM Cortex-A7 (4 ядра). Программное обеспечение разработано на языке C++11 с применением фреймворка Qt версии 5.9.4 и декларативного языка разметки интерфейса QML.
Версия программного обеспечения: 1.15.
Область применения: медицинские учреждения, скорая медицинская помощь, анестезиология и реаниматология.
Идентификационные наименования компонентов:
Программное обеспечение построено по модульной архитектуре. Ядро системы реализовано на языке C++11 и отвечает за бизнес-логику, взаимодействие с аппаратным обеспечением и управление ресурсами. Пользовательский интерфейс реализован на декларативном языке QML с применением фреймворка Qt Quick.
Основной паттерн организации: синглтон — каждый функциональный модуль представлен единственным экземпляром объекта, созданным в функции main() и зарегистрированным в контексте QML. Взаимодействие между модулями осуществляется через механизм сигналов и слотов Qt.
Все синглтоны создаются и связываются в src/main.cpp. В следующей таблице приведён полный перечень модулей, зарегистрированных в контексте QML:
| Имя в QML | Класс C++11 | Описание |
| splashScreen | SplashScreen | Управление экраном загрузки |
| navigationController | NavigationController | Стековая навигация между экранами |
| cameraManager | CameraManager | Управление жизненным циклом камеры |
| mediaStorage | MediaStorage | Управление хранилищем медиафайлов |
| photoCapture | PhotoCapture | Фотосъёмка |
| videoEncoder | VideoEncoder | Видеозапись |
| inputHandler | InputHandler | Обработка аппаратных кнопок |
| galleryModel | GalleryModel | Модель фотогалереи |
| videoGalleryModel | VideoGalleryModel | Модель видеогалереи |
| systemMetrics | SystemMetrics | Сбор метрик производительности |
| diskSpaceMonitor | DiskSpaceMonitor | Мониторинг дискового пространства |
| batteryWarningController | BatteryWarningController | Предупреждения о заряде батареи |
| autoCleanup | AutoCleanup | Автоматическая очистка хранилища |
| settingsManager | SettingsManager | Управление настройками |
| wifiManager | WiFiManager | Управление Wi-Fi подключением |
| mjpegServer | MjpegStreamingServer | HTTP MJPEG стриминг |
| tcpStream | TcpStreamClient | TCP мониторинг (ImagePDU) |
| nfcReader | NfcConfigReader | Считывание конфигурации с NFC меток |
| Translations | Translations | Локализация интерфейса |
| brightnessController | BrightnessController | Управление яркостью подсветки |
| inactivityMonitor | InactivityMonitor | Мониторинг бездействия и энергосбережение |
Следующие классы зарегистрированы как QML-типы в модуле Sensar 1.0:
Ключевые сигнальные связи между модулями:
Программное обеспечение разработано и оптимизировано для следующей аппаратной конфигурации:
| Компонент | Характеристика |
| Процессор | Rockchip RV1126, ARM Cortex-A7 x4 |
| ОЗУ | 1.75 ГБ DDR |
| Накопитель | eMMC (внутренняя flash-память) |
| Дисплей | ЖК, 4.5” сенсорный IPS, 854×480 пикселей |
| Камера | USB UVC-совместимая, форматы MJPEG/YUYV, разрешение до 1280×720 |
| Батарея | Li-ion, контроллер rk-bat (доступ через sysfs) |
| Wi-Fi | 802.11 b/g/n, интерфейс wlan0, управление через wpa_supplicant и nl80211 |
| NFC | FM17580 (Fudan Micro), UART /dev/ttyS4, скорость 115200 бод |
| Кнопки | 6 аппаратных кнопок, доступ через evdev (/dev/input/event0–4) |
| LED индикатор | work_led, управление через sysfs (триггеры: heartbeat / none) |
| USB | USB Type-C (зарядка, ADB, передача данных) |
| Подсветка дисплея | sysfs backlight, диапазон яркости 0–255 |
Графическая подсистема работает через драйвер linuxfb и DRM. Плагин eglfs недоступен в используемом BSP (Board Support Package). Аппаратное ускорение кодирования H.264 недоступно в текущей версии BSP, поэтому применяется программный MJPEG кодек.
Модуль управления камерой включает следующие классы:
При запуске приложения CameraManager автоматически выполняет сканирование устройств /dev/video0 — /dev/video9 для обнаружения подключённой камеры. После обнаружения производится инициализация устройства с выбором оптимального формата и разрешения.
CameraWatchdog запускается в отдельном потоке и осуществляет периодический опрос состояния подключения камеры с интервалом 1 секунда. При обнаружении отключения или повторного подключения генерируются соответствующие сигналы.
Приоритет выбора формата:
Поддерживаемые разрешения подключаемых устройств (в порядке убывания приоритета):
Для захвата видео применяется буферизация V4L2 через разделяемую память (mmap):
Декодирование JPEG кадров выполняется библиотекой libturbojpeg:
При разрешении камеры 720p (1280×720) для отображения на экране превью производится масштабирование вниз в 2 раза до разрешения 640×360, что снижает нагрузку на CPU при рендеринге.
После декодирования кадра генерируются два сигнала:
Класс: PhotoCapture
Модуль отвечает за захват неподвижного изображения с камеры и сохранение его в файловой системе устройства.
Характеристики:
После сохранения файла модуль генерирует сигнал обновления галереи для отражения нового снимка в GalleryModel.
Класс: VideoEncoder
Модуль обеспечивает запись видеопотока с камеры в файл.
Характеристики:
Запись начинается по сигналу от пользователя (нажатие кнопки SENSAR_TRIGGER или соответствующий элемент сенсорного интерфейса) и завершается повторным нажатием той же кнопки. В период активной видеозаписи таймер бездействия InactivityMonitor принудительно перезапускается при каждом записанном кадре для предотвращения перехода устройства в режим сна.
При открытии файла выполняется:
Для навигации по видео выполняется индексирование кадров:
Файл загружается в оперативную память через механизм mmap для обеспечения произвольного доступа к кадрам с минимальными задержками.
Декодирование каждого JPEG кадра выполняется библиотекой libturbojpeg:
Применяется цепочечная схема таймера (chain-based): следующий кадр декодируется только после завершения рендеринга предыдущего. Это исключает накопление очереди декодирования при высокой нагрузке CPU.
Адаптивное планирование (adaptive scheduling):
| Свойство / Метод | Тип | Описание |
| source | string | Путь к файлу AVI |
| playing | bool | Состояние воспроизведения |
| duration | int | Длительность в миллисекундах |
| position | int | Текущая позиция в миллисекундах |
| play() | метод | Начать / возобновить воспроизведение |
| pause() | метод | Приостановить воспроизведение |
| stop() | метод | Остановить и вернуться в начало |
| seek(pos) | метод | Перейти к указанной позиции (мс) |
| seekRelative(delta) | метод | Перейти относительно текущей позиции (мс) |
GalleryModel предоставляет данные для отображения сетки миниатюр фотографий. Фотографии считываются из каталога /userdata/media/photos/ и сортируются от новых к старым.
VideoGalleryModel предоставляет данные для отображения списка видеозаписей с указанием длительности каждой записи. Видеозаписи считываются из каталога /userdata/media/videos/ и сортируются от новых к старым.
Для ускорения загрузки галерей реализован ThumbnailProvider:
CameraPreviewItem подписывается на сигнал CameraManager::frameReady и выполняет прямой рендеринг кадра через QPainter::drawImage. Синхронизация между потоком камеры и потоком рендеринга Qt обеспечивается через QMutex.
При отсутствии кадра (камера не подключена или поток прерван) производится заливка области отображения чёрным цветом.
Класс: WiFiManager
После установки подключения автоматически отключается режим энергосбережения Wi-Fi адаптера командой:
iw dev wlan0 set power_save off
| Таймер | Интервал | Назначение |
| Статус подключения | 5 секунд | Проверка текущего состояния |
| Сигнал изменения статуса | 10 секунд | Уведомление QML интерфейса |
| Результаты сканирования | 3 секунды после команды scan | Считывание найденных сетей |
Уровень сигнала рассчитывается на основе значения RSSI:
| Диапазон RSSI (дБм) | Уровень (0–4) |
| ≥ −50 | 4 (отличный) |
| −60 … −51 | 3 (хороший) |
| −70 … −61 | 2 (средний) |
| −80 … −71 | 1 (слабый) |
| < −80 | 0 (нет сигнала) |
Результаты сканирования (scan_results) разбираются по формату с разделителем табуляция: bssid, freq, signal, flags, ssid.
Класс: MjpegStreamingServer
Модуль реализует HTTP сервер для трансляции видеопотока с камеры на внешние устройства в формате MJPEG.
Технические характеристики:
Стриминг запускается автоматически при запуске приложения и активен на протяжении всей работы устройства при наличии подключения к Wi-Fi сети.
Класс: TcpStreamClient
Модуль реализует передачу видеопотока во внешнюю систему мониторинга по протоколу TCP с использованием бинарного протокола ImagePDU.
Бинарный заголовок каждого пакета:
Перед отправкой каждый кадр перекомпрессируется для снижения трафика:
Для автоматического обнаружения сервера мониторинга применяется приоритетное сканирование подсети:
| Параметр | Значение |
| Задержка перед переподключением | 3 секунды |
| Максимальное число циклов сканирования | 5 |
| Пауза между циклами сканирования | 5 секунд |
| Максимальное число попыток подключения к хосту | 10 |
| Пауза между попытками подключения | 1 секунда |
Классы: NfcConfigReader, NfcUartWorker
Взаимодействие с чипом выполняется через бинарный командный протокол:
Данные записываются на метку в текстовом формате UTF-8:
SSID|PASSWORD
где | — разделитель между именем сети и паролем.
Минимальная длина валидных данных: 5 байт. Байт recv_buf[3] содержит длину полезных данных.
Поллинг выполняется в отдельном потоке pthread. Ожидание данных через select с таймаутом 10 секунд.
При успешном считывании метки генерируется сигнал tagRead, который преобразуется в сигнал wifiConfigReceived(ssid, password) и передаётся в WiFiManager для автоматического подключения к указанной сети.
Класс: SettingsManager
| Параметр | Тип | Допустимые значения | Описание |
| Wi-Fi | bool | true / false | Включение/отключение Wi-Fi |
| Дата/время | string | ISO 8601 | Системное время устройства |
| Формат времени | enum | 24h / 12h | Формат отображения времени |
| Яркость | int | 0–255 | Яркость подсветки дисплея |
| Язык | enum | RU / EN | Язык интерфейса |
Для предотвращения избыточных операций записи при частом изменении параметров реализован debounce таймер: фактическая запись в файл выполняется через 500 мс после последнего изменения настроек.
Класс: BrightnessController
Управление яркостью подсветки дисплея осуществляется через интерфейс sysfs:
Модуль используется совместно с InactivityMonitor для управления яркостью при переходе в режим сна и при пробуждении.
Класс: InactivityMonitor
Модуль управляет тремя состояниями:
| Таймер | Интервал | Действие |
| Таймер бездействия | 600 000 мс (10 минут) | Инициировать переход в режим сна |
| Обратный отсчёт | 10 секунд (TimerFd) | Уведомить пользователя и перейти в режим сна |
| Таймер автовыключения | 1 800 000 мс (30 минут в режиме сна) | Выполнить poweroff |
При входе в режим сна выполняются следующие действия последовательно:
При получении события пробуждения (нажатие любой кнопки):
Перезапуск через execv() обеспечивает корректную повторную инициализацию всех аппаратных компонентов без перезагрузки операционной системы.
При активной видеозаписи таймер бездействия принудительно перезапускается при каждом записанном кадре, что исключает переход в режим сна во время съёмки.
Сброс таймера выполняется при каждом нажатии аппаратной кнопки через метод InactivityMonitor::resetActivity(), вызываемый из InputHandler.
Класс: BatteryWarningController
Данные об уровне заряда считываются из интерфейса sysfs:
/sys/class/power_supply/rk-bat/capacity
Значение представляет собой целое число в диапазоне 0–100 (проценты).
| Уровень заряда | Действие |
| 35 % | Показать предупреждение (3 мигания) |
| 30 % | Показать предупреждение (3 мигания) |
| 25 % | Показать предупреждение (3 мигания) |
| 20 % | Показать предупреждение (3 мигания) |
| 15 % | Показать предупреждение (3 мигания) |
| 10 % | Показать предупреждение (3 мигания) |
| 5 % | Показать предупреждение (3 мигания) |
Предупреждение отображается однократно при достижении каждого порогового значения в сторону убывания.
| Диапазон заряда | Цвет индикатора |
| ≥ 60 % | Зелёный |
| 40–59 % | Жёлтый |
| 20–35 % | Оранжевый |
| < 20 % | Красный |
Классы: DiskSpaceMonitor, AutoCleanup
DiskSpaceMonitor выполняет периодический опрос состояния файловой системы с интервалом 30 секунд. Результаты опроса публикуются в QML контексте и отображаются в строке состояния.
| Заполненность | Цвет индикатора |
| < 70 % | Зелёный |
| 70–89 % | Жёлтый |
| ≥ 90 % | Красный |
AutoCleanup активируется при превышении порога заполненности диска 70%. При активации модуль последовательно удаляет наиболее старые медиафайлы (фотографии и видеозаписи) до тех пор, пока заполненность не снизится до 30 %.
Порядок удаления: файлы удаляются в порядке от более старых к более новым на основании метки времени создания.
Класс: InputHandler
Модуль осуществляет мониторинг событий от аппаратных кнопок через подсистему evdev Linux:
| Имя кнопки | Код Linux | Значение | Назначение |
| SENSAR_TRIGGER | 59 | KEY_F1 | ФОТО/ВИДЕО (курок) |
| SENSAR_OK | 30 | KEY_A | Подтверждение выбора |
| SENSAR_UP | 103 | KEY_UP | Навигация вверх |
| SENSAR_DOWN | 108 | KEY_DOWN | Навигация вниз |
| SENSAR_MENU | 48 | KEY_B | Открытие меню |
| SENSAR_POWER | 116 | KEY_POWER | Питание / сон |
Кнопка SENSAR_POWER поддерживает длительное нажатие:
При каждом нажатии любой кнопки вызывается метод InactivityMonitor::resetActivity() для сброса таймера бездействия.
Класс: Translations
Модуль обеспечивает поддержку многоязычного интерфейса.
Поддерживаемые языки:
Реализация: строки локализации хранятся непосредственно в исходном коде C++ без использования стандартного механизма Qt Linguist (файлы .ts / .qm). Все строки пользовательского интерфейса в QML файлах обращаются к свойствам объекта Translations.
Переключение языка выполняется мгновенно без перезагрузки приложения или пересоздания QML объектов — через обновление свойств синглтона.
Класс: Logger
Характеристики:
Журнал предназначен для диагностики неисправностей и отладки. В производственной среде рекомендуется использовать уровень INFO или выше.
Класс: SystemMetrics
Модуль осуществляет непрерывный сбор метрик производительности системы и их запись в файл CSV.
Характеристики:
Собираемые метрики:
| Метрика | Источник данных |
| FPS | Счётчик кадров CameraManager |
| Использование ОЗУ | /proc/meminfo |
| Загрузка CPU | /proc/stat |
| Температура процессора | /sys/class/thermal |
| Использование диска | statvfs() |
| Уровень заряда батареи | /sys/class/power_supply/rk-bat/capacity |
Приложение включает 10 экранов:
| Экран | QML файл | Описание |
| SplashScreen | — | Экран загрузки при старте приложения |
| MainMenu | — | Главное меню |
| CameraView | — | Просмотр видеопотока с камеры в реальном времени |
| PhotoGallery | — | Сетка миниатюр фотографий |
| PhotoViewer | — | Просмотр выбранной фотографии |
| VideoGallery | — | Список видеозаписей с миниатюрами |
| VideoPlayer | — | Воспроизведение видеозаписи |
| GuideScreen | src/qml/GuideScreen.qml | Учебные материалы / инструкция |
| SettingsScreen | src/qml/SettingsScreen.qml | Настройки устройства |
| WifiSettingsScreen | src/qml/WifiSettingsScreen.qml | Настройки Wi-Fi |
Поверх основных экранов отображаются 5 оверлеев:
| Оверлей | QML файл | Назначение |
| StatusBar | — | Время, уровень заряда, Wi-Fi, диск |
| BatteryWarning | — | Предупреждение о низком заряде батареи |
| SleepCountdown | — | Обратный отсчёт до перехода в режим сна |
| DiskWarning | — | Предупреждение о заполнении диска |
| NfcOverlay | src/qml/components/NfcOverlay.qml | Уведомление о считывании NFC метки |
Навигация между экранами осуществляется через синглтон NavigationController, реализующий стековую модель: каждый переход помещает новый экран на стек, кнопка «назад» убирает верхний экран. Предусмотрена защита от возврата на SplashScreen после завершения загрузки.
Экран GuideScreen отображает обучающие материалы по применению ларингоскопа. Контент представлен в виде последовательности страниц, включающих текстовые описания и иллюстрации. Тексты руководства локализованы и отображаются в соответствии с выбранным языком интерфейса.
Экран SettingsScreen обеспечивает управление следующими параметрами:
Экран WifiSettingsScreen обеспечивает:
| Тип данных | Формат | Расширение | Путь хранения | Описание |
| Фотографии | JPEG | .jpg | /userdata/media/photos/ | Полное разрешение камеры |
| Видеозаписи | MJPEG AVI | .avi | /userdata/media/videos/ | RIFF контейнер, 30 fps |
| Настройки | JSON | .json | /userdata/settings.json | Параметры приложения |
| Метрики | CSV | .csv | /userdata/logs/ | Данные производительности |
| Журнал | Plain text | .log | /tmp/sensar.log | Системный журнал |
| Библиотека | Версия | Назначение |
| Qt | 5.9.4 | UI фреймворк: Quick, QML, Concurrent, Network, Core |
| FFmpeg | — | libavformat, libavcodec, libavutil, libswscale (парсинг AVI) |
| libturbojpeg | — | JPEG декодирование / кодирование с SIMD NEON ускорением |
| POSIX | — | timerfd, pthread, mmap, evdev, sysfs интерфейсы |
| wpa_supplicant | — | Управление Wi-Fi подключением (вызов через wpa_cli) |
| udhcpc | — | DHCP клиент для получения IP-адреса |
Компиляция выполняется для архитектуры ARM Cortex-A7 (armhf) с кросс-компилятором arm-linux-gnueabihf-g++. Стандарт языка: C++11.
| Ресурс | Требование |
| Минимальный объём ОЗУ | ~100 МБ для приложения |
| Свободное место на eMMC | Минимум 500 МБ для операционных нужд |
| Частота процессора | ARM Cortex-A7, 4 ядра, ≥ 1 ГГц |
Видеокодек. Аппаратное кодирование H.264 недоступно в текущей версии BSP для Rockchip RV1126. Применяется программный MJPEG кодек на CPU. Данное ограничение влияет на размер записываемых видеофайлов по сравнению с форматами с эффективным сжатием.
LED камеры. Индикационный светодиод камеры запитан от линии 5V USB напрямую. Программное отключение LED при переходе в режим сна невозможно без отключения питания всей USB линии.
Графическая подсистема. Используемый BSP поддерживает работу только через драйверы linuxfb и DRM. Плагин Qt QPA eglfs (OpenGL ES через EGL) недоступен. Доступные Qt QPA плагины:
Версия документа: 1.15 Дата составления: 23.02.2026 Разработчик ПО: ООО «ШИФТАПП»
Обработка персональных данных на основании 152-ФЗ