Телеметрии что это такое
Перейти к содержимому

Телеметрии что это такое

  • автор:

Телеметрия

Телеметрия, телеизмерение (от др.-греч. τῆλε «далеко» + μέτρεω  — «измеряю») — совокупность технологий, позволяющая производить удалённые измерения и сбор информации для предоставления оператору или пользователю, составная часть телемеханики. Термин образован от греческих корней «теле» — «удалённый» и «метрон» — «измерение». Хотя сам термин в большинстве случаев относится к механизмам с беспроводной передачей информации (например, используя радио или инфракрасные системы) он также заключает в себе данные, передаваемые с помощью других средств массовой коммуникации, таких как телефонные или компьютерные сети, оптическое волокно или другие проводные связи.

Для сбора данных обычно используют либо датчики телеметрии (с возможностью работы в телеметрических системах, то есть специальным встроенным модулем связи), либо устройства связи с объектом, к которым подключаются обычные датчики.
В телевидении и видеонаблюдении встречается другое понимание слова «телеметрия» [1]  — дистанционное управление.

В качестве среды передачи данных используются как беспроводные (радио, GSM/GPRS, ZigBee, WiFi, WiMax, LTE), так и проводные (телефонные, ISDN, xDSL, компьютерные) сети (электрические или оптические).

Содержание

История

Передача информации по проводам берёт своё начало в 19-м столетии. Одна из первых линий передачи была создана в 1845 между Зимним дворцом российского императора и штабами армий. В 1874 французские инженеры установили систему датчиков определения погоды и глубины снега на Монблане, передающей информацию в режиме реального времени в Париж. В 1901 американский изобретатель Михалик запатентовал сельсин, индукционную машину для попеременной передачи синхронизированной информации на расстоянии. В 1906 был построен ряд сейсмических станций, связанных телеметрической связью с Пулковской обсерваторией. В 1912 Эдисон разработал телеметрическую систему для мониторинга подключаемых нагрузок к электросети. При постройке Панамского канала (законченной в 1913—1914) массово использовались телеметрические системы для мониторинга шлюзов и уровней воды.. [2]
Беспроводная телеметрия начала применяться в радиозондах, разработанных независимо друг от друга Робертом Бюро во Франции и Павлом Молчановым в России. Система Молчанова измеряла температуру и давления и преобразовывала результаты в беспроводной код Морзе.
В немецкой ракете Второй мировой войны Фау-2 использовалась система передачи примитивных многократных радиосигналов под названием «Мессина» для получения информации о параметрах ракеты, но эта система была столь ненадёжной, что Вернер фон Браун однажды заявил, что было бы эффективнее следить за ракетой в бинокль. Как в СССР, так и в США на смену системе «Мессина» быстро пришли более совершенные системы, основанные на импульсно-позиционной модуляции. [3]
В ранних советских телеметрических системах (ракетных и космических), разработанных в конце 1940-х, использовалась как импульсно-позиционная модуляция (например в телеметрической системе Трал, разработанной в ОКБ МЭИ), так и полосно-импульсная модуляция (например в системе RTS-5 разработанной в НИИ-885). В ранних американских разработках также использовались подобные системы, но позднее они были заменены на системы с импульсно-кодовой модуляцией (например, в космическом аппарате для исследования Марса «Маринер-4»). В поздних советских межпланетных аппаратах использовались избыточные радиосистемы, осуществляющие телеметрическую передачу с импульсно-кодовой модуляцией в дециметровом диапазоне и с импульсно-позиционной модуляцией в сантиметровом диапазоне. [4]

Применение

Телеметрия нашла своё применение в следующих областях:

  • узлы магистральных линий связи;
  • сельское хозяйство.

Большинство видов деятельности, связанных с благополучным состоянием сельскохозяйственных культур и получения хороших урожаев, зависит от своевременного предоставления данных о состоянии погоды и почвы. Таким образом, беспроводные метеостанции играют важную роль в профилактике заболеваний и соразмерном орошении. Эти метеостанции передают на базовую станцию информацию о важных параметрах, необходимых для принятия решений: о температуре и относительной влажности воздуха, выпадении осадков и влажности листвы (для построения моделей профилактики заболеваний), солнечной радиации, скорости ветра (для расчёта испарения) и для увлажнённости почвы, посредством чего оценивается проникание воды в почву к корням растений, что необходимо для принятия решений об орошении.
Поскольку местные микроклиматы могут существенно различаться, такую информацию необходимо получать буквально прямо от сельскохозяйственных культур. Обычно станции мониторинга передают данные, используя наземное радио, хотя время от времени используются и спутниковые системы. Также используются солнечные батареи для обеспечения энергонезависимости станций от местной инфраструктуры.

  • водоснабжение и водоотведение

Телеметрия стала существенным подспорьем в водопользовании, она применяется при оценке качества воды и измерения показателей потока. Телеметрия в основном применяется в автоматических водосчётчиках, мониторинге подводных вод, определении утечек в распределительных трубопроводах. Данные получаются практически в реальном времени и позволяют незамедлительно реагировать на происшествия.

  • медицина

Телеметрия (биотелеметрия) также используется для наблюдения за пациентами, находящимися под угрозой возникновения патологической сердечной деятельности, в основном пребывающих в кардиологических диспансерах. К таким пациентам подключаются измерительные, записывающие и передающие устройства. Зарегистрированные данные могут быть использованы врачами в диагностике состояния пациента. Благодаря функциям сигнала тревоги медицинские сёстры могут быть оповещены при возникновении резких обострений или опасных состояний для пациента.
Также есть система доступная для применения операционными медсёстрами для наблюдения за состоянием, в котором состояния сердца могут быть исключены. Или для наблюдения за реакцией организма на медикаментозное лечение такими антиаритмическим препаратами как дигоксин.

  • оборона и космос

Телеметрия — доступная технология для больших сложных систем, таких как ракеты, реакторы (Reactor pressure vessel), космические аппараты, нефтяные платформы и химические заводы, поскольку она позволяет осуществлять автоматическое наблюдение, тревожную сигнализацию, запись и сохранение данных, необходимых для безопасных, эффективных действий. Такие космические агентства как НАСА, ЕКА и другие используют телеметрические/ телеуправляемые системы для сбора данных с действующих космических аппаратов и спутников.
Телеметрия жизненно важна в развитии ракет, спутников и авиации, поскольку данные системы могут быть уничтожены после или во время проведения теста. Инженерам нужна информация о критичных параметрах для анализа (и улучшения). Без применения телеметрии такого рода данные часто оказываются недоступными.

  • разведка

Телеметрия была жизненно важным источником о тестировании советских ракет для британской и американской разведок. Для этой цели США содержали пост прослушивания в Иране. В конечном итоге Советы раскрыли данную разведывательную деятельность американцев по сбору и расшифровке телеметрических сигналов о тестировании ракет. СССР с кораблей в Кардиганском заливе прослушивал сигналы при испытаниях британских ракет, проводимых там.

  • ракетная техника

В ракетной технике телеметрическое оборудование становится неотъемлемой частью оборудования ракет, использующихся при наблюдении за процессом ракетного запуска, для получения информации о параметрах внешней среды (температуры, ускорений, вибраций) о энергоснабжении, точном выравнивании антенны и (на длинных дистанциях, например при космическом полёте) о времени распространения сигнала.

  • авто- и мотоспорт

Телеметрия является ключевым фактором в современном автоспорте. Инженеры могут обрабатывать огромное количество данных, собираемых в ходе пробного заезда и использовать их для соответствующей модернизации автомобиля и достижении при этом оптимальных свойств. Системы, использующиеся в таких сериях гонок как Формула-1, настолько продвинулись, что позволяют высчитать возможное время прохождения круга и это то что ожидает пилот. Некоторые примеры необходимых измерений включают ускорения (силы тяготения) по трём осям, графики температур, скорость вращения колёс и смещение подвески. В Формуле 1 также записываются действия пилота, что позволяет команде оценить его производительность и при несчастном случае Международная автомобильная федерация может определить или исключить роль ошибки пилота как возможный случай.
В дополнение существуют некоторые серии, где реализуется идея «двухпутевой телеметрии». Идея предполагает, что инженеры имеют возможность обновлять калибровки в режиме реального времени, возможно, когда автомобиль проходит трассу. В Формуле 1 двухпутевая телеметрия появилась в начале 90-х годов (ТАГ электроникс) и реализовывалась через дисплей сообщений на приборном щитке, сообщения на котором команда могла обновлять. Его развитие продолжалось до мая 2001, когда впервые было получено разрешение устанавливать данную систему на автомобилях. С 2002 команды уже могли изменять режимы работы двигателя и отключать отдельные моторные датчики с пит-стопов, когда машина находилась на трассе. Начиная с сезона 2003 года двухпутевая телеметрия была запрещена на Формуле 1, однако данная технология всё ещё продолжает существовать и в конечно итоге находит своё применение в других видах гоночных или дорожных автомобилей.
В Формуле 1, двусторонний телеметрии всплыли в начале девяностых годов от TAG, электроника, и состояла из сообщения отображаются на приборной панели которого группа могла бы обновить.

  • бурение наклонных скважин
  • системы глобального позиционирования, в том числе Спутниковый мониторинг транспорта
  • энергетика

На фабриках, стройках и в домах проводится наблюдение во множестве местоположений за энергопотреблением таких систем как климат-контроль вместе со связанными параметрами (например температурой) при помощи беспроводной телеметрии на одну центральную точку. Информация собирается и обрабатывается, позволяя принимать наиболее разумные решения касающиеся наиболее эффективных путей использования энергии. Такие системы также позволяют осуществлять профилактическое техническое обслуживание.

  • системы безопасности (сигнализация, видеонаблюдение)
  • исследование дикой природы

Телеметрия используется для изучения дикой природы, в частности для наблюдения за видами, находящимися под угрозой на индивидуальном уровне. Подопытные животные могут быть оснащены инструментарием, начиная от простых бирок и заканчивая камерами, пакетами GPS и передатчиками для обеспечения информацией учёных и управляющих.
Телеметрия используется в гидроакустических оценках рыбы, которые традиционно используются при мобильных обследований с лодок для оценки биомассы рыб и пространственного распределения. И наоборот есть техническое оборудование, размещаемое в стационарных местах, оно использует стационарные преобразователи для контроля прохождения рыбы. Хотя первые серьёзные попытки количественно оценить биомассу рыб были проведены в 1960-х годов, основные достижения в области оборудования и технологий произошли на плотинах гидроэлектростанций в 1980-х. Оценки прохождения рыбы проводятся 24 часа в сутки в течение года, определяется скорость прохождения рыбы, её размер, пространственное и временное распределение.
В 1970 была изобретена двухлучевая техника, позволяющая прямую оценку размера рыбы на месте её нахождения посредством сопротивления цели. Первая переносная расщеплено-лучевая гидроакустическая система была разработана HTI в 1971 и обеспечивала более аккуратные и менее вариабельные оценки сопротивления цели в виде рыбы, чем двухлучевой метод. Система также позволяла отслеживать путь рыбы на 3D, можно было проследить путь движения каждой рыбы и общую направленность движения.
Эта функция оказалась важной для оценки захваченных рыба в воде, утечки, а также для изучения мигрирующих рыб в реках. Эта функция оказалась важной для оценок перемещений рыбы в завихрениях водяного течения, также как и для изучения миграций рыб в реках. В последние 35 лет по всему миру используются десятки тысяч мобильных или стационарных аппаратов гидроакустической оценки.

  • Розничная торговля

В 2005 на семинаре в Лас-Вегасе было отмечено, что введение телеметрического оборудования, позволяющего торговым автоматам передавать информацию о продажах и учёте маршрутным грузовикам или в штабы. Эта информация может быть использована для разнообразных целей, таких как сообщение водителю перед поездкой какие пункты должны быть пополнены, что отменяет необходимость первой проверочной поездки перед проведением внутренней инвентаризации.
Торговцы начинают использовать бирки RFID для проведения учёта и предотвращения краж товаров. Большинство из данных бирок пассивно читаются считывающими устройствами RFID (например у кассы), но активные RFID могут периодически передавать информацию посредством телеметрии на базовую станцию.

  • Правоохранительная деятельность

Телеметрическое оборудование полезно в правоохранительной деятельности для отслеживания людей и надзором за имуществом. Осужденные в период испытания после досрочного освобождения могут носить браслет на лодыжке, устройство которого может предупреждать власти о нарушении преступником условий своего освобождения, таких как отступление от установленных границ или посещение неразрешённых мест. Телеметрическое оборудование даёт возможность применить идею «машин-ловушек». Правоохранительные органы могут оснащать машины камерами и следящим оборудованием и оставлять машины в тех местах, где ожидается их угон. После угона телеметрическое оборудование передаёт информацию о местоположении транспортного средства и сотрудники правоохранительных органов могут заглушить мотор и запереть двери после остановки его выехавшими на вызов полицейскими.

Передача и обработка данных в системах телеметрии

Для сбора и передачи информации в системах телеметрии могут использоваться как последовательные протоколы RS-232, RS-485, CAN, так и различные сетевые протоколы TCP/IP, Ethernet. Последние обычно называются системы телеметрического IP-мониторинга объектов, но термин ещё не устоялся. В технике часто применяется термин IP-мониторинг для программного мониторинга компьютерных сетей, в то же время термин IP-мониторинг применяется для обозначения систем наблюдения, видеонаблюдения и управления, телеметрического контроля по IP за объектами. Возможно со временем, эти два близких понятия сведутся в один класс. В последнее время (около середины 2000 годов) для облегчения инсталляции, обеспечения многофункциональности, интеграции с другими системами в телеметрии применяются компьютеры, различные серверы и микропроцессорные системы, имеющие в основе переплетение различных протоколов, встроенные средства переработки и отображения информации, часто имеющие кольцевые базы данных, а также и возможности мультизонального сбора информации с многочисленных датчиков, разбросанных зачастую вне физических пределов самих систем, либо и вовсе на другой стороне земного шара, к примеру различные беспроводные датчики, IP датчики и тд.

Международные стандарты

Как и в других телекоммуникационных областях существуют международные стандарты, установленные такими организациями как CCSDS [

Телеметрия или кибершпионаж?

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

Для этого есть несколько путей. Первый путь − проведение опросов, когда вы задаете пользователю вопросы и он дает свои ответы. В этом случае пользователь предоставляет данные, только если он этого хочет, и только ту информацию, которой готов поделиться. Так делаем мы, собирая информацию о Panic Button. Можете познакомиться с нашей анкетой https://panicbutton.pw/ru/survey.

Но этот путь имеет очевидные минусы: во-первых, пользователи неохотно делятся информацией, во-вторых, пользователи зачастую не способны грамотно оценить даже информацию об используемом ими функционале, в-третьих, многие ошибки вообще не видны и не понятны пользователям, их можно обнаружить только при помощи функционала программного обеспечения.

Плюсы: никакого несанкционированного сбора данных о пользователе и возможность выяснить удовлетворенность пользователя, которую телеметрия может выяснить лишь по косвенным данным.

Второй путьавтоматизированный сбор телеметрических данных. Он имеет неоспоримые преимущества перед анкетированием: о пользователе поступает вся необходимая информация, включая версию его системы, параметры и версию программы, месторасположение, использование ресурсов, например загрузку процессора, и многое другое. Можно получить точный список всех используемых опций, время использования, технические данные обо всех ошибках и падениях приложения.

Дальше эта информация передается на сервер и там автоматически обрабатывается. Здесь возникает ключевой вопрос: где тонкая грань между сбором телеметрии и кибершпионажем, привязывать ли информацию к конкретному пользователю или просто обезличивать данные?

Например, если приложение собирает информацию обо всех запущенных вами сеансах и отправляет ее без привязки конкретно к вам − это телеметрия. Если данные каким-либо образом привязаны к вам − это кибершпионаж. Приложение может знать ваш email, но он абсолютно не нужен для сбора данных с целью улучшения приложения, зато он необходим для адресного сбора информации о вас.

По нашему мнению, телеметрия должна собираться без какой-либо идентификации пользователей, будь то email или IP-адрес. Можно использовать идентификатор, абсолютно не связанный с пользователем, который не должен быть статичным и будет обновляться через энное количество времени или с началом новой сессии. При поступлении и обработке данные должны обезличиваться… но вы же понимаете, что мы не можем все это проверить. В любом случае данные приходят не анонимно, к ним привязан IP-адрес устройства, с которого они отправляются. Дальше этот IP может удаляться, как обещает нам Mozilla, либо сохраняться, хотя никакой ценности для улучшения приложения он не несет. Так или иначе, вы не сможете проверить, удаляется ли ваш IP или нет.

Многие специалисты при разграничении кибершпионажа и сбора телеметрии предлагают ориентироваться на цель сбора данных. Если цель − улучшить работу приложения, понимание, как пользователи используют его, то это телеметрия, если цель − сами пользователи, их данные и активность, то это кибершпионаж. На мой взгляд, это спорное утверждение, хотя кое в чем не могу не согласиться.

Например, если браузер будет собирать информацию обо всех посещенных пользователем сайтах и отправлять разработчику, это сложно назвать телеметрией, так как подобная информация никак не способна повлиять на улучшение работы приложения, это просто сбор данных, вероятно, для дальнейшей их продажи.

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

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

Примеры сбора телеметрических данных

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

Начнем с программ и возьмем для примера браузер Mozilla Firefox. Боюсь, вы мне не поверите, потому я просто скопирую данные, которые браузер передает о вас по умолчанию, с официального сайта.

Данные о взаимодействии: Firefox отправляет нам данные о вашем взаимодействии с этим браузером (количество открытых вкладок и окон, количество посещенных страниц, число и тип установленных дополнений, продолжительность сеансов и т. д.) и об использовании функций Firefox, предлагаемых компанией Mozilla или нашими партнерами (таких, как поиск Firefox и поиск по партнерским ссылкам).

Технические данные: Firefox отправляет нам данные о версии и языке браузера, операционной системе устройства и конфигурации оборудования, объеме памяти, сбоях и ошибках, результатах автоматизированных процессов, таких как обновление, безопасный браузинг или активация. Когда Firefox отправляет нам данные, временно передается и ваш IP-адрес (как элемент журналов нашего сервера).

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

Рассмотрим сбор телеметрических данных со стороны операционных систем. Вы, вероятно, ждете информацию о Windows, но о ней мы будем достаточно говорить в рамках курса, а в данном случае я приведу в пример macOS Yosemite.

Вышедшая летом 2014 года macOS Yosemite передавала на сервера Apple все запросы в поиске Spotlight с местоположением пользователя. Например, если пользователь искал на своем компьютере Mac какой-то файл, Apple знала, когда его искали, где и как он назывался. Передача происходила в процессе ввода данных, поэтому пользователю достаточно было просто начать вводить информацию, и она отправлялась в Apple вместе с координатами.

Говоря о ноутбуках, хотелось бы отметить Lenovo, но то, что делает китайский производитель, относится, скорее, к главе о вредоносном программном обеспечении, здесь же речь пойдет о ноутбуках HP.

В 2017 году пользователи ноутбуков HP начали жаловаться на программу под названием HP Touchpoint Analytics Service. Она была установлена в принудительном порядке пользователям и начала сбор телеметрических данных. Так, между делом пользователи ноутбуков HP стали участниками масштабной программы сбора телеметрических данных. Каких? А вот это загадка, но есть сведения, что записываются даже нажатия клавиш. К счастью, данная проблема решалась удалением программы.

Как защищаться от сбора телеметрических данных

Есть несколько путей защиты: радикальный, условно радикальный и путь доверия.

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

Условно радикальный путь предполагает блокировку отправки данных приложением на сервера. В данном случае определяются и блокируются IP-адреса, на которые приложение шлет запросы, либо приложению целиком блокируется возможность отправлять какие-либо уведомления. Подобным способом мы будем ограничивать Windows 10 в непомерном желании знать о вас все.

В данном курсе мы научим вас проводить анализ запросов приложений и их блокировку при помощи firewall. Это эффективный метод, но он имеет один минус: не все приложения можно заблокировать, например, вам вряд ли понравится работа браузера без доступа к сети или отсутствие важных обновлений…

Путь доверия предполагает отключение сбора и отправки данных в настройках программы. Часто это дает прекрасный результат, этим способом мы будем ограничивать сбор данных браузером Mozilla Firefox.

Но не стоит его переоценивать. Например, в 2017 году стало известно, что Google собирает данные о местоположении смартфонов Android даже при активированных настройках приватности. Координаты определялись на основе координат ближайших сотовых вышек и отправлялись на сервера Google.

Кодекс летописца или Ода к телеметрии

Допустим, ко группе инженеров снизошла задача разработать систему управления чем-нибудь достаточно сложным. Теоретик заточил зубы и приступил к граниту — строит модели объекта и системы управления. Комплексники копают руду компоновки, вопросов климатики, вибрации и спецтребований, кто-то рисует платы/корпуса/кабели, кто-то пишет и тестирует уже определившиеся элементы ПО.

И здесь же, с самого старта, нужен человек, который займется телеметрией: ее формированием, передачей и сохранением. Ибо переоценить важность телеметрии для разработки практически нереально. Когда что-то пойдет не так — а оно пойдет — только телеметрия даст шанс понять, что это, черт возьми, было. Когда все будет так — она станет объективным доказательством успеха. Больше того: иногда, когда внешне все прошло так, она заставит при анализе запуска уронить челюсть и спросить себя и окружающих: «как, черт возьми, всё обошлось?»

А потому исходное положение кодекса, пункт зеро:

0. Телеметрия нужна

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

Конечно, в идеале система должна быть предварительно отработана на модели, все мелочи вычищены там же, а реализация на железе — заработать сразу и без проблем. Но подобные мечты высокие и светлые следует отбросить, упав вместо того в объятия реальности, где не так пойдет даже то, что по природе своей к этому неспособно.

А когда хотя бы какая-то телеметрия появляется, к ней тут же просыпается аппетит, и хочется видеть еще вот то, вот это, и пяток-другой значений отсюда. Из чего быстро возникает понимание:

1. Телеметрию необходимо сохранять для дальнейшего анализа

Человеку постороннему при слове «телеметрия» первым делом представляются живые графики во многих окнах. Да, следить за поведением системы в реальном времени — это чертовски увлекательно. Держать руку на пульсе, видеть, как система дышит, и прочее подобное. Но красивые кривые в реальном времени — вещь сильно второстепенная, и вот почему.

Во-первых, эти графики надо в чем-то рисовать. А если реалтайм-телеметрия не является значимой продуктовой фичей — под нее не будет отдельной строки в расходной ведомости. Но бог бы с ним, можно на коленке накидать приложуху с графиками («— думаете вы», (с) один анекдот), в крайнем случае просто отображать цифры в окошках. Да можно хоть в консоли смотреть!

И это, действительно, вариант. Случается даже, что от прошлых проектов доступна полноценная реалтайм-система наблюдения. Но есть еще два «но», куда более важных:

вне стенда, в условиях реального применения, может вообще не быть канала связи с устройством (а знать, что происходило, хочется);

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

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

А еще записанные данные суть ключ к одной редко вспоминаемой и не всем доступной (зависит от методики разработки), но также неоценимой возможности: их можно прогнать через исходную матмодель системы управления и посмотреть, как она вела бы себя в тех же внешних условиях при иных настройках параметров. Конечно, для этого первым делом потребно существование модели системы как таковой; плюс она должна уметь брать данные не только с модели объекта управления, но и из внешнего источника. И, конечно, у этого метода есть ограничения, накладываемые предметной областью. Но при всем при этом запись реального запуска есть уникальный материал для как моделирования поведения системы в «боевых» условиях, так и для уточнения матмодели объекта управления. Потому что нет такой модели, которую нельзя было бы немножечко допилить.

С необходимостью записи понятно. Встает масса практических вопросов, начиная с:

2. Выбор формата передачи и хранения (человеко-читаемая форма vs. бинарная)

У человеко-читаемого формата есть очевидные плюсы:

человеко-читаемость per se: возможность видеть цифры данных (и импортировать их для анализа во что-нибудь вроде Excel) без дополнительного ПО;

как следствие предыдущего пункта, простота первичной проверки организации телеметрии: передаваемые данные можно посмотреть в консоли, а записанные — в любом текстовом редакторе.

Но эти плюсы остаются плюсами только в случае, когда перечень и объем передаваемых данных крайне мал, и все потребные числа можно уместить буквально в одну строку, окидываемую взглядом. А это — вырожденный случай, потому что на практике в проектах, где телеметрия действительно нужна, условие краткости перечня не выполняется. О, нет! В таких случаях переменных много, их набор меняется от версии к версии, от режима к режиму, они нужны с разной частотой. В потоке могут присутствовать данные об однократных и случайно возникающих событиях. К телеметрии в целом, как к подсистеме, появляется определенный набор практических требований. В этом случае человеко-читаемость теряет оба преимущества: разобраться в мешанине цифр и идентификаторов в режиме реального времени становится невозможно вообще, а выбор руками нужных данных из записанного потока прекращается в квест. И все это — на фоне крайне низкой эффективности использования канала связи: из всех доступных значений байта задействованы только 10 цифр и несколько букв и символов.

В идеальном мире это не было бы проблемой: если уж данные все равно придется разбирать специальным ПО, то какая разница, человеко-читаемы они или нет, бы была формализованная структура. Но на практике всегда есть ограничения либо на пропускную способность канала связи, либо на объем хранилища, либо и на то, и на другое сразу. Поэтому бинарное кодирование — единственный практически разумный вариант. А реальная отправная точка при разработке структуры телеметрии — это

3. Конечность пропускной способности канала связи

Обычно заранее более или менее ясно, по какому каналу данные будут передаваться, и какова его предельная пропускная способность. В случае записи данных на встроенный или внешний накопитель, конструктивно объединенный с системой управления, известна также емкость этого накопителя (и, возможно, иные ограничения — например, со стороны файловой системы).

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

Но обычно такой лафы не случается. Тогда приходится уточнять у заинтересованных лиц, какие данные и с какой частотой они желают иметь, оценивать потребную пропускную способность на каждый набор однородных данных, сводить всё это в единую ведомость и с этой ведомостью ходить и выкручивать интересантам руки (или договариваться полюбовно, если прокачан скилл дипломатии), добиваясь компромиссного решения. В этом решении придется:

сохранить баланс интересов всех участвующих сторон;

учесть, что эффективность использования канала не будет равна 100%: иногда звезды станут сходиться так, что данные в аппаратном буфере передачи закончились, а поток, заполняющий этот буфер, на паузе из-за того, что именно сейчас выполняется более приоритетная задача;

не забыть оставить запас под рост аппетитов участников.

На практике распределение пропускной способности канала удобно планировать на основе пакетной организации данных, поскольку однородные данные рационально группировать в пакеты фиксированного размера, снабженные заголовком. Про пакеты тоже будет отдельный разговор впереди, а пока в качестве примера — случай, когда все пакеты имеют одинаковый размер. Положим, имеем канал 1 Мбит/сек, то есть 125 кбайт/с. Размер пакета — 200 байт. Следовательно, теоретически достижимая частота передачи пакетов — 125000/200=625 Гц. Потребители хотят иметь один пакет с частотой 200 Гц, два пакета с частотой 50 Гц, и два пакета с частотой 25 Гц. Итого канал занят на 200+2*50+2*25=350 Гц, запас еще 625-350=275 Гц, 42% от теоретической пропускной способности. Или, оценивая в герцах, доступными остаются еще 4 потока по 50 Гц и плюс 3 по 25 Гц.

4. Приоритизация данных

От телеметрии хочется получить по возможности подробную и целостную историю состояния системы. Частота передачи различных данных — это столп, на котором зиждется подробность. Другой столп, не менее важный — относительная ценность различных групп данных. Вот первичные данные с датчиков: они появляются часто, записывать их надо столь же часто, но при этом мы практически ничего не потеряем, если время от времени в поток не будет попадать отсчет-другой. В то же время срабатывание датчика безопасности будет случаться лишь изредка, но нам крайне важно, чтобы запись об этом сохранилась в телеметрии, и попала в нее как можно раньше после того, как датчик сработал[1]. А между тем канал может быть доступен не всегда, или в ходе развития системы его запасы пропускной способности окажутся выбраны даже больше, чем на 100%, и возникнет конкуренция между данными.

По такому случаю имеет смысл завести в системе две (а то и больше) очереди пакетов, ожидающих передачи: обычные и высокоприоритетные/разовые. При наличии пакетов в высокоприоритетной очереди отсылаются сначала они, а уж после того — обычные.

Возможно, придется подумать и об относительной приоритизации обычных пакетов в случае деградации канала. Как жертвовать данными, если послать всё желаемое не удается по не зависящим от нас причинам? Можно сохранять соотношение между частотами передачи, пропорционально снижая их все. Либо отказаться от пропорциональности, и стараться передавать по возможности одинаково часто каждый из пакетов. Решение за разработчиком.

Можно даже постараться обеспечить в рамках единого решения и выдерживание штатных частот передачи пакетов при нормально работающем канале, и возможность переключаться между двумя тактиками поведения при деградации канала. Пример такого решения в общих чертах:

запускается таймер с частотой срабатывания, равной наименьшему общему кратному частот передачи всех пакетов, и превышающей полосу канала: для примера выше (пакеты 200 Гц, 50 Гц, 25 Гц, полоса канала 625 Гц) это может быть 800 Гц;

создается пул объектов-наблюдателей, в котором каждый наблюдатель отвечает за расчет времени до следующей посылки «своего» телеметрического пакета, и а) осведомлен о необходимой частоте его передачи, и б) может получать уведомления о факте отправки подконтрольного пакета в канал. Период передачи подконтрольного пакета определяется наблюдателем в тактах задающего таймера: каждые N тактов пакет должен быть передан в телеметрию. Скажем, для 200-Гц пакета эта величина составляет N=800/200=4 такта;

скелет класса наблюдателя:

class PacketPeriodWatcher
<
public:
void onTimerTick()
<
if (_packetSent) <
_ticksLeft = sendingPeriodTicks;
_packetSent = false;
>
—_ticksLeft;
>

int getTimeLeft() const
<
switch(_degradationHandling)
<
case DegradationHandling::keepRelativeFrequencies:
// Оставшееся время до отсылки выдается в виде числа
// собственных периодов отсылки данного пакета, округленных
// до ближайшего большего целого. Таким образом, чем реже
// пакет шлется в нормальных условиях, тем медленнее будет
// возрастать и его «величина просрочки» при возникновении
// аковой, и тем реже он будет получать преимущество по
// величине просрочки перед пакетами, в норме отсылаемыми
// более часто
if (_ticksLeft > 0) <
return (_ticksLeft + sendingPeriodTicks — 1) / sendingPeriodTicks;
>
else <
return _ticksLeft / sendingPeriodTicks;
>

case DegradationHandling::equalizeFrequencies:
// Оставшееся время до отсылки выдается в форме количества
// оставшихся периодов задающего таймера. При
// возникновении просрочки ее величина будет расти у всех
// пакетов одинаково быстро, и чем дольше любой пакет
// задерживается, тем скорее он окажется первым в очереди
// на отправку
return _ticksLeft;

default:
// добавлен какой-то новый вариант стратегии, нужен обработчик
assert(false);
return 0;
>
>

void onPacketSent()
<
_packetSent = true;
>

private:
// варианты стратегии поведения при деградации канала
enum class DegradationHandling <
// пытаться сохранить соотношение частот передачи пакетов
keepRelativeFrequencies,
// слать все пакеты одинаково часто
equalizeFrequencies,
>;

enum : int <
// раз во сколько тиков таймера слать пакет
sendingPeriodTicks = 4,
>;

DegradationHandling _degradationHandling = DegradationHandling::keepRelativeFrequencies;
int _ticksLeft = sendingPeriodTicks;
bool _packetSent = false;
>;

по прерыванию таймера вызывается onTimerTick() для каждого из наблюдателей;

cуществует также таск-диспетчер канала передачи, который по завершении передачи очередного пакета и при отсутствии запросов в очереди высокоприоритетных пакетов вызывает getTimeLeft() для каждого наблюдателя из пула. Если находятся пакеты, чье время до отправки равно или меньше 0 (последнее возможно при деградации канала и означает, что пакет уже отстал от графика), выбирается тот из пакетов, чье оставшееся время минимально. Такой пакет передается в канал, а у его наблюдателя вызывается onPacketSent(). При отсутствии пакетов с оставшимся временем 0 и менее диспетчер канала инициирует переключение таска.

У этой схемы есть очевидные ограничения: требуются удобные кратности периодов передачи всех пакетов, будет достаточно часто вызываться прерывание таймера, на обработку которого тратится время процессора. Есть и подводные камни: многопоточный доступ на запись _packetSent. Однако в целом вариант вполне рабочий.

5. Буферизация

Используемый для передачи телеметрии канал может оказаться разделяемым, полудуплексным, или иметь периоды неработоспособности иной природы. Например, при записи на SD-карточку в FAT32 необходимо периодически вызывать функцию flush(), иначе есть риск при отключении питания потерять инфу за заметный промежуток времени (точнее, физически данные на флэшке будут, но в FAT-е этот факт не отразится[2]). И пока синхронизация выполняется, запись на флэшку невозможна — а данные-то продолжают поступать, и терять их не хочется. Примерно то же происходит, когда размер файла приближается к 4 ГБ, и нужно закрывать имеющийся и создавать новый файл.

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

6. Версионность, метаданные

Структура телеметрических данных изменяется со временем. Таков закон, обойти который смертным не дано. Если его не учесть с самого начала, то в недалеком будущем ждите великий плач и скрежет зубов при попытке глянуть архивные записи.

Через это совершенно необходимо иметь в потоке телеметрии номера версий всего, что может меняться: аппаратуры, прошивки основного и периферических модулей, самой телеметрии. Если есть возможность, хорошо бы сохранять и данные о дате и времени запуска. Без, как минимум, сведений о версии прошивки будет крайне трудно потом разобраться, в каких условиях были получены данные, а иногда — даже и понять, что они вообще собой представляют. Последнее случается при пакетной организации данных, когда идентификаторы переменных в пакете не передаются, а содержимое пакета определяется его структурой, каковая мутирует: вчера в пятом слове от начала пакета была только температура, а сегодня там еще два старших бита слова признаков. Посему следует заранее выделить и навсегда (в рамках текущего проекта) закрепить за версионными данными группу уникальных идентификаторов. Тогда, как бы ни менялось содержимое остальной телеметрии, версию ее всегда можно будет определить, а оттуда уж танцевать краковяк дальнейшего разбора.

Если ситуация позволяет, удобно формировать самоописывающиеся файлы, где в заголовке указана метаинформация: для переменных — идентификатор, имя, формат представления, цена младшего разряда, знаковость; для массивов — идентификаторы, имена, наборы переменных, составляющих пакет — и прочее, что окажется полезным по месту. Такой файл есть совершенно автономный источник информации, легко переносимый с одного рабочего места на другое.

Чаще возможность формировать и передавать метаданные недоступна. В этом варианте приходится для каждой версии телеметрии создавать внешние файлы описания, и раздавать их вместе с файлами данных. Соответствие версий файла описания и файла данных становится тогда критически важно.

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

7. Возможность подключения к каналу в произвольный момент времени

Если таки есть желание подключаться к каналу когда бог пошлёт, тут же встает вопрос обнаружения в потенциально непрерывном потоке данных начала ближайшей целостной единицы. Если канал по своей природе пакетный, то проблемы нет. Вот в протоколах CAN и МКИО (MIL-STD-1553) формирование и контроль пакетов осуществляется аппаратно, и обработка подключения-отключения абонентов встроена в них изначально. Получить половину пакета и смутиться не удастся, аппаратура такое поползновение пресечет на корню. А, скажем, RS-232 оперирует именно отдельными байтами, и в этом случае понять, включившись в канал, что мы видим и где концы, не так просто.

Логичным решением в этом случае будет периодически замешивать в поток данных какой-то уникальный идентификатор — токен. Значение его нужно взять таким, чтобы вероятность появления в данных его двоичного близнеца была достаточно мала. Размер — от 2 байт: любое значение однобайтного токена обречено на слишком частые коллизии и, как следствие, ложноположительные обнаружения. Брать токен длиннее 4 байт тоже не имеет особого смысла: труднее обрабатывать, и избыточность великовата. При пакетной организации потока токен можно помещать в начало или конец пакета, а при передаче потока отдельных переменных — слать после каждых N переменных, выбирая N так, чтобы расход трафика на токен оставался достаточно мал, но появление гарантировалось спустя недолгое время после подключения к каналу.

При пакетной организации потока дополнительным источником сведений для различения токена и данных будет известная длина пакета, будь то фиксированная или задаваемая в самом пакете. Если токен принят, а ближайший пакет оказывается несамосогласованным — значит, это был не токен, особенно если его значение снова обнаружилось в ходе приема пакета: тогда, возможно, настоящий токен — вот это второе обнаружение, а до того были данные. Для случая потока отдельных переменных — повторное обнаружение токена ранее, чем после приема N переменных может значить, что первое обнаружение ложное и нужно пробовать еще.

Поможет правильному обнаружению токена и

8. Контроль целостности данных

Вообще требования к контролю целостности могут быть заданы и безотносительно токенов сегментирования потока — скажем, заказчиком в ТЗ, или введены разработчиком ввиду ожидаемой плотности помех на канале связи.

Крутить же контроль целостности вручную нужно далеко не всегда. Во-первых, если канал изначально ожидается неустойчивым и подверженным помехам (как, например, радиоканал до движущегося объекта), то он на одном или более из уровней OSI уже обеспечен аппаратными средствами контроля целостности. Битые пакеты в лучшем случае будут исправлены, в худшем — не дойдут до адресата. А если контроля целостности нет, то и шанс искажения данных — низкий. Впрочем, практика может показать, что он все же высокий, и тогда лучше поправить это, пока (и если) есть возможность, на аппаратном уровне, изменив тип канала.

Во-вторых, зачастую многие параметры в системе имеют предсказуемый диапазон значений и характер изменения, и резкие выбросы в них однозначно будут идентифицированы аналитиком, как сбои. Тем более что сбои имеют тенденцию проявляться в куче переменных сразу, и из сопоставления нескольких графиков это будет видно еще лучше.

Если все-таки астрологи объявили неделю гарантий целостности и механизм придется реализовывать, то его контрольные значения удобно передавать совместно с токенами сегментирования потока (в конце пакета/после отсылки N переменных). Заодно это послужит дополнительным средством определения того, действительно ли принятое значение было признаком границы сегмента.

Собственно метод расчета контрольных значений можно выбрать любой на свой вкус, исходя из доступных вычислительных возможностей и предполагаемой степени зашумленности канала: от простого XOR-а со сдвигом до мощных хэш-функций. Тут на Хабре об этом полно информации. Можно даже развернуться и внедрить коды Рида-Соломона, гарантируя себе не только контроль целостности, но и возможность восстановления сбойных участков (как всегда, взамен на дополнительный расход трафика).

9. Идентификация и пакетирование переменных

Очевидно, нельзя слать в канал произвольный поток чисел, и надеяться потом что-то в нем понять. Поток должен быть структурирован, а переменные в нем — идентифицируемы.

В простейшем случае, когда набор параметров очень короткий, можно слать все переменные одну за одной по кругу. Известно их общее количество и размер каждой, содержимое переменной определяется местоположением в цикле отправки — сведений для парсинга потока достаточно. Но даже в этом, базовом случае нужен механизм отслеживания изменений структуры передачи: с помощью ли файлов описания, предварительной ли передачей (при старте работы системы) имен переменных в нужной последовательности, или путем жесткого прописывания последовательности передачи в зависимости от версии системы в спецПО интерпретации.

Потом переменных становится больше, возникает нужда передавать их с разной частотой. Слать вместе с каждой переменной ее имя? Адский расход трафика. Фактически оправданны два пути:

присвоить всем переменным числовые идентификаторы, и передавать идентификатор в паре с каждым посылаемым значением соответствующей переменной;

комбинировать однородные переменные в пакеты. Числовые (или текстовые) идентификаторы тогда будут у пакетов, а содержимое переменной будет определяться, как и в простейшем случае, ее позицией в пакете. Никто не мешает при этом передавать одну и ту же переменную в нескольких разных пакетах, повышая таким образом эффективную частоту ее появления в потоке.

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

Выбор размера идентификатора определяется количеством переменных, которые надо передавать. Удобно группировать однородные переменные, давая им близкие номера, и не забывая о запасе на развитие. Скажем, есть три подсистемы, в одной 15 параметров, в другой 40, в третьей 8. Итого меньше 70 уникальных переменных. Значит, хватит 8-битного идентификатора; под данные первой подсистемы можно выделить номера, начинающиеся с 10, 20 и 30 (итого место под 30 параметров, на будущее), второй — с 40 по 90 (60 позиций), и третьей — 100 и 110 (20 позиций). Не забыть, разумеется, данные о версии — это будут параметры с номерами [0..9]. Остальное про запас.

Но такая свобода есть только при условии, что вся телеметрия находится под вашим полным контролем. А если вы, предположим, делите канал со смежниками (разработчиками составных частей изделия), или даже канал весь ваш, но от смежников поступили просьбы сохранить в потоке их родные идентификаторы, то придется думать. Особенно если у разных смежников диапазоны идентификаторов пересекаются. Тут, во-первых, рациональнее группировать переменные уже по смежникам, и, во-вторых, воспользоваться двоичной природой идентификатора: объявить его логически разделенным на поля, порубить маской на поле группы и поле внутреннего идентификатора в группе, и пусть смежники выцепляют свои данные, пользуясь выделенным им значением по маске поля группы. Но идентификатор придется сделать пошире. Зато это дает возможность, удовлетворив пожелания смежников, сохранить в то же время деление своих данных по подгруппам — только уже внутри своей группы.

Наконец, о пакетах. Сборка переменных в пакеты и передача их в таком виде, без указания идентификаторов отдельных переменных, дает максимально возможную эффективность использования канала. Тогда, как уже говорилось, поиск нужной переменной в потоке базируется на номере пакета и известном местоположении переменной в нем (смещении относительно начала пакета). Для определения границ пакетов и для различения их друг от друга каждому пакету нужен, как минимум, заголовок, содержащий, как минимум, идентификатор пакета. Что еще будет в заголовке — определяется желанием: токен сегментации, время формирования, длина пакета, контрольная сумма, какие-то специальные признаки. Опционально добавляется уникальный либо единый признак конца пакета (который во втором случае становится по совместительству токеном сегментации). Можно слать даже вырожденные пакеты, состоящие из одного заголовка — в этом случае пакет выполняет роль переменной, сигнализирующей о чем-либо.

Зачастую канал изначально имеет пакетную природу — как те же CAN и МКИО, причем оба они разрешают, например, посылки переменной длины, и оба содержат средства контроля целостности. Тогда для задания пакетов можно пользоваться готовой аппаратной инфраструктурой, а это снимает многие головные боли с разработчика. Однако всякое аппаратное решение имеет ограничения: например, у CAN (в базовом формате пакета) это 11-битный идентификатор и максимум 8 байт данных в пакете, а у МКИО — запрос-ответная организация канала, и всего лишь 5 бит на поле подадреса оконечного устройства, т.е. на номер пакета (зато максимум 32 16-битных слова в пакете, что достаточно много в сравнении с CAN). К чему это всё: придется сначала оценить, достаточно ли аппаратных возможностей канала для задач телеметрической подсистемы, и если нет — возводить слой абстракции поверх используемого аппаратного протокола.

10. Формат времени

Если есть какой-то параметр, важность которого трудно переоценить — так это время. Без знания моментов формирования данных вся затея с телеметрией теряет смысл. В принципе, можно фиксировать время на приемной стороне, при получении переменных/пакетов, но тут есть риск исказить сведения о последовательности возникновения событий внутри системы — наружу-то пакеты выдаются с разной частотой, поэтому пакет с реакцией может быть выдан раньше пакета с причиной. Кроме того, не всегда на приемной стороне в принципе доступно достаточно точное знание момента выдачи пакета со стороны передающей, в силу программно-аппаратных ограничений платформы и/или канала (например, из-за приоритизации пакетов в той же шине CAN). Наконец, при этом подходе невозможно знать внутреннее время системы, а без него во многих случаях никакой содержательный анализ не провести.

Поэтому возникает нужда передавать время системы в потоке данных. Спрашивается: как это лучше делать?

Прежде всего, время следует передавать в форме целочисленной переменной, дальше будет сказано, почему. Выбрать тогда остается размер переменной и цену ее младшего разряда. Оба этих параметра определяются сочетанием пары же условий: насколько точно время нужно знать, и как велика максимальная длительность непрерывной работы (при условии, конечно, что время нужно знать от момента включения; если требуется только знание относительной удаленности событий друг от друга, переменной времени можно позволить циклически переполняться, это не станет помехой).

С ценой младшего разряда все довольно просто: во многих случаях в системе присутствует какой-то базовый высокочастотный цикл, чаще которого ничего не происходит — скажем, опрос первичных датчиков с частотой 1000 Гц. В этом случае за единицу времени рационально принять период этого цикла (1 мс в примере). Все значимые события в системе так или иначе будут подчинены периоду опроса датчиков, и моменты их возникновения будут кратны периоду опроса. Если же такого цикла нет, придется пытать аналитиков относительно того, какая точность знания времени их устроит.

Выбор размера переменной времени зависит от ожидаемой длительности непрерывной работы. Формально нижняя граница количества бит определятся как log2(максимум времени/цена младшего разряда), округленный до ближайшего большего целого. А прикинуть, хватит разрядности или нет, можно и на глаз, зная предельное целое число, умещающееся в выбранное слово. Например, 16-битная переменная переполнится в нашем примере через 65,536 секунды, а 32-битная — через без малого 4,3 миллиона секунд. Для большинства задач достаточно.

В принципе, если запись данных ведется непрерывно с самого начала работы, переменной тоже можно позволить свободно переполняться: истинное время будет восстановлено при обработке. Но если планируется подключение к каналу в произвольные моменты времени, придется выделить под время побольше места. В качестве альтернативного решения можно разделить переменную времени на старшую и младшую части, и передавать младшую часть настолько часто, насколько это необходимо (в каждом пакете/каждые N переменных), а старшую — лишь время от времени, но не реже периода переполнения младшей части. Лучше, конечно, еще чаще: возможны сбои, или отключение от канала до момента передачи старшего слова времени. Таким способом можно записывать совершенно гигантские времена с огромной точностью.

К слову, в системе могут фиксироваться и иные события — случайно возникающие внешние прерывания. Хотя моменты появления этих событий не могут быть точно представлены в выбранных единицах шкалы времени, это в большинстве случаев и неважно: все равно значимая реакция (какие-то действия, отличные от регистрации факта появления сигнала) происходит обычно не раньше начала очередного цикла опроса датчиков. Поэтому с практической точки зрения достаточно знать не момент, когда внешнее событие произошло, а момент, не позже которого оно было обработано. Если все-таки точное время регистрации события критично, то под него заводится отдельная телеметрическая переменная со своим именем, и в нее заносится момент первичной регистрации с точностью, заданной аналитиком с учетом возможностей системы.

Так в чем все-таки плюс целочисленного времени? Точность. Точность в таком представлении никогда не теряется, независимо от того, сколь долго продолжается запись. В этом его кардинальное отличие от формата с плавающей точкой: можно, конечно, передавать время как переменную типа float (32-битное одинарной точности по IEEE-754), и потом иметь при обработке сразу готовое бинарное значение, но у float-а точность — лишь 7 с хвостиком десятичных разрядов. В нашем примере это значит, что, начиная с примерно десяти тысяч секунд записи, позиции точек данных станут дерганными, и тогда о качестве и удобстве анализа можно будет забыть. При 100-мкс точности проблемы полезут уже где-то с тысячи секунд. Можно, конечно, подключить всю мощь double-а с его практически 16-ю десятичными разрядами, но, камон, это 64 бита данных. Передавая время в 64-битной целочисленной переменной с точностью в 1 наносекунду, можно обеспечить непрерывную запись на протяжении 18 с лишним миллиардов секунд, то есть 580 с гаком лет. Неплохо, не правда ли.

Минусы целочисленного времени: при подготовке данных к анализу придется кучу раз умножить целое число на 0,001.

11. Формат прочих переменных

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

Отдельно стоит сказать про данные первичных датчиков: они обычно приходят в виде целых чисел с того или иного варианта АЦП, поэтому при разрядности АЦП 16 бит и меньше такие данные — идеальный кандидат на передачу в канал «как есть». Да, вы вряд ли потеряете в точности при переводе их из 16-битных АЦПшных во float, где под мантиссу отведено 24 разряда, но расход трафика определенно возрастет. Относительно 18- и более битных АЦП уже нужно смотреть по месту, там экономия канала за счет целочисленности будет скромнее.

В итоге все равно всё определяется шириной канала, а float- и double-данные удобны своей готовностью к непосредственному отображению и использованию, так что выбор за вами.

12. Проблемы многопоточного доступа

В сколь-нибудь сложной системе данные всегда генерируются во многих точках. Но даже если все они в итоге доступны из одного места, то, как минимум, поток исполнения, формирующий набор данных к отправке, и поток, управляющий выдачей данных в канал — это разные потоки. И это еще минимальный случай, на практике потоков больше. А любой многопоточный доступ к данным — это всегда более или менее проблемы в реализации, и всегда — трехсторонний компромисс между быстродействием, консистентностью и количеством потребной памяти.

Если запасы оперативки и процессорного времени позволяют — лучше всего копировать готовые блоки данных (группы переменных, пакеты) в очередь отправки, оснащенную механизмом межпоточной синхронизации. Скопированные в очередь, данные к моменту передачи в канал точно останутся целостными и согласованными.

При нехватке ОЗУ придется создать по единственному экземпляру каждой отсылаемой структуры, и защищать доступ к этим экземплярам мьютексами, или чем там оптимально позволит операционка — это для пакетного варианта передачи. Для варианта с потоком переменных рациональней охранять доступ к группе переменных сразу, иначе затраты времени на синхронизацию на порядки превысят длительность собственно записи/чтения данных. Хотя и такое может быть приемлемо, если процессор избыточно крут для выполняемой задачи.

О необходимости защиты доступа

Чуть подробнее о том, зачем вообще нужна защита доступа. Ведь тут в одном месте идет запись, в другом — чтение, одновременное изменение данных из двух мест невозможно. Так и пиши здесь в ТМ-структуры в потоке с высоким приоритетом, там читай из них в канал в потоке с низким, чем плохо?

И так, правда, можно — но опять только в случае, когда запас процессорного времени поистине велик. Потому что в реальности практически неизбежны моменты 100%-ной занятости процессора. Вот приходят многие прерывания, накладываются одно на другое, вызываются их обработчики, и на это время потоки с высоким приоритетом подтормаживаются, не говоря уже о низкоприоритетных. А когда обработка прерываний закончилась, высокоприоритетные потоки снова кидаются исполнять свои обязанности, формируют новые значения в тех разделяемых хранилищах — а низкоприоритетный поток как раз находился в середине процедуры чтения одного из них, когда был остановлен. Все, консистентность блока данных разрушена: половина его окажется составлена из данных одного цикла, другая половина — из данных другого.

Кстати, о реакции контрольной суммы на такое безобразие: если сумма формируется в процессе записи данных в структуру — на стороне «писателя» — то потом при анализе данных определится ошибка, и сбой не пройдет незамеченным. Правда, его природа будет неочевидной. А если сумму вычислять прямо в процессе передачи данных в канал, и отсылать ее туда последней — тогда и она ничего не покажет, потому что со стороны потока передачи нельзя понять, менялся ли блок данных за время чтения. Это к вопросу о непродуманных оптимизациях логики.

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

В общем, не стоит отказываться от синхронизации, не убедившись в ходе предварительных тестов на реальном железе, что затраты времени на нее неприемлемы. Если частичный или полный отказ все же необходим — напишите, по крайней мере, нормальные функции сериализации (виртуальные функции С++/указатели на функции С в помощь). Не применяйте традиционный подход с кастом блока памяти структуры к void* или char*, и дальнейшим копированием его данных в выходной буфер канала. Во-первых, аппаратный регистр канала наверняка объявлен как volatile-указатель, поэтому данные все равно придется копировать в него вручную побайтно (пословно), выиграть в скорости за счет использования memcpу не удастся из-за этого самого volatile — вызов memcpу не скомпилируется, и это замечательно. А непосредственное ручное копирование даст совершенно ничтожный выигрыш во времени по сравнению вызовом функции сериализации. Во-вторых, в продуманной функции можно будет во многих случаях избежать еще более неприятной проблемы: при прямом копировании данные способны стать несогласованными даже в пределах одной переменной! Получается это по следующим причинам:

зачастую канал по своей природе оперирует отдельными байтами, и поэтому передача в него двух- и более байтной переменной может прерваться посредине, новой записью в нее в другом потоке. В функции сериализации по этому поводу можно предварительно копировать переменные размером в слово или менее во временную переменную, что будет сделано одной машинной операцией;

даже если канал оперирует машинными словами, а элементы копируемой структуры выровнены по границе слов, и для элементов, меньших или равных размеру машинного слова, запись и чтение ячейки памяти можно считать атомарными операциями — то для элементов, больших аппаратного слова, на это всё равно рассчитывать не приходится: скажем, величина типа double на 32-битном процессоре будет писаться и читаться минимум за две машинные операции;

самое же главное — то, что обычно для удобства блочного копирования структура объявляется примерно таким кодом:

то есть, чтобы не расходовать место впустую, объявление структуры обрамляется директивами #pragma pack(push, 1)/ #pragma pack(pop) (все помнят про стаффинг — выравнивание по умолчанию элементов структуры по границам машинного слова, с заполнением промежутков пустыми байтами?). А в плотном варианте упаковки выравнивание, в общем случае, исчезает, так что работа с вообще любой переменной, кроме однобайтных, может пойти по частям и при записи, и при чтении.

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

На сладкое: существуют платформы с размером char-а, отличным от 8 бит (например, опциональные 32, как в 1967ВН044), где вся эта красота прирастает новыми, веселыми фокусами сопряжения форматов данных платформ источника и приемника. Возрадуйтесь!

13. Циклические счетчики

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

Блоки управления по природе своей общаются в бесконечном цикле с различными периферическими устройствами и исполнительными механизмами. В этих устройствах зачастую стоит какая-то своя электроника, и для связи с ними пишутся подходящие несложные (или сложные) протоколы. При этом когда что-то идет не так, иногда трудно понять, с чьей стороны проблема и на каком уровне она возникает.

Поэтому для упрощения первичной диагностики полезно предусмотреть в протоколе с каждым из таких устройств буквально пару байт, передаваемых со стороны устройства: один из них будет содержать циклический счетчик количества принятых от нас управляющих пакетов, а другой — количества ответных пакетов, переданных, по мнению устройства, с его стороны. Счетчики увеличиваются на единицу с каждым принятым нашим/отправленным его пакетом, а при достижении величины 255 сбрасываются на 0 в следующем такте приема/передачи.

На графиках тогда будет видна характерная «пила», и наблюдение этой пилы многое скажет даже при беглом взгляде на картинку. Стабильная ровная пила — все отлично. Обе пилы, синхронно меняющие наклон — иногда наши команды не доходят до устройства, но оно успешно отвечает на каждую, нужно смотреть канал связи. Остановка пилы — потеря связи. Вырождение в прямую линию — мозги периферии зависли целиком или частично, а выходной пакет либо раз за разом передается из аппаратного буфера по запросу, либо цикл отправки жив и шлет ответы из памяти с общим доступом, но эта память не обновляется — цикл управления умер.

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

14. Именование переменных. Иерархические имена

Это в направлении заботы о народе: при выборе названий телеметрических параметров крайне желательно сохранять систему обозначений, привычную для людей, работающих с этими параметрами. Скажем, если традиционно перегрузка записывается как NY, не следует называть соответствующий параметр rel_total_accel_Y. Для программиста такое название, может, и будет более говорящим. Но специалист по управлению будет каждый раз, кривясь, вспоминать, как тут перегрузку-то обозвали? Аксель? Что-то там… Может быть, специалист будет кричать. Душераздирающее зрелище.

Еще не стоит без веских причин переводить на английский язык имена, которые аналитики привыкли видеть в форме русскоязычных сокращений, записанных латиницей. Если команда «Готовность 1», чье привычное всем имя — Kgot1, окажется вдруг поименована как CmdReady1, аплодисментов не будет и цветы вам не пришлют.

В целом, аналитикам должно быть комфортно работать с данными, и привычные имена параметров — значимая составляющая такого комфорта. Если, паче чаяния, вам придется лично заниматься незнакомой теоретической областью и формировать имена по собственному разумению, стоит потратить некоторое время, привыкая к принятой в этой области символике, и в телеметрии использовать ее же. Велик шанс того, что подходящий теоретик будет-таки подключен позже, и лучше вам сразу говорить с ним на общем языке, в том числе — глядя на записи пусков.

Иерархические имена. Подобно тому, как идентификаторы переменных стоит группировать по подсистемам, имена тоже стоит предварять префиксами подсистем, к которым они принадлежат. Когда в списке переменных многие десятки, а то и сотни имен, гораздо проще прокрутить его до плотненькой группы, где все имена начинаются с «nav_angles», и там кликнуть галочки «nav_angles_psi», «nav_angles_gamma» и «nav_angles_theta» одна поблизости от другой, чем искать во всем списке, где примерно расположены «гаммы» среди множества строк на g, а потом еще выбирать свою «gamma» среди визуально очень схожих «gamma0», «gamma_t1» и «gammaMax», повторяя потом это трюк с «psi» и «theta».

Второй плюс иерархичности — возможность найти переменную в списке, не помня ее точного имени. Некоторые параметры нужны редко, и из-за этого их названия забываются. Потом в какой-то момент в них возникает однократная нужда, и тогда вспомнить, глядя на неструктурированный перечень, как же, черт возьми, оно называлось, невероятно сложно. Зато при этом обычно хорошо знаешь, к какому модулю этот параметр относился, и вот тут иерархические имена снова очень удобны: проматываешь до блока имен нужной подсистемы, и среди тех полутора-двух десятков нужный параметр находится очень быстро.

Понятное дело, что рекомендация теряет смысл, если у вас развитая система обработки: в таковой, скорее всего, уже предусмотрена иерархическая организация имен своими средствами. Тогда имена сразу будут те, что наиболее удобны для аналитиков. Хотя в истинно развитой системе могут быть предусмотрены и псевдонимы на случай разного именования одной и той же переменной в разных массивах/разных версиях телеметрии… фантазия телеметристов, к сожалению, иногда не знает границ.

Приложение А. Случаи из практики

Поскольку ода вышла какая-то куцая — ни дифирамбов нормальных, ни панегириков, следует хотя бы потравить коротких баек по теме. Тут некоторые истории известны мне только в пересказе, поэтому могут быть неточности, но основная идея сохраняется.

1/1000 vs. 1/1024 секунды

В одном проекте часть расчетов в устройстве велась на основе данных, поступающих из внешнего источника. Экземпляров этого источника тоже было несколько, и они, с точки зрения устройства, не различались: протокол связи был единым. В том числе с такого внешнего источника поступало время, как раз целочисленное, цена младшего разряда которого, в соответствии с протоколом, составляла 1/1000 с.

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

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

В итоге, как понятно из заголовка, оказывается, что в данном экземпляре внешнего устройства цена младшего разряда была заменена, с 1/1000 секунды на 1/2 10 . Эта разница в 2.5%, накапливаясь в расчетах квадратично, давала заметную погрешность результата на периоде вычислений.

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

Проблемы ускорения, гласности и перестройки

В одной модифицируемой системе подвижный модуль счислял своё положение с большой ошибкой, хотя ничто к тому не предрасполагало. В частности, данные первичных датчиков лежали вполне в пределах допустимого, ни необычные шумы, ни сбои в них не наблюдались, все остальные составляющие для вычислений были корректными. И, тем не менее, результаты автономного расчета положения отличались от данных, получаемых из внешних источников. Конечно, коррекция по внешним данным позволяла исправить положение, но в реальности такие данные должны были быть доступны лишь изредка, при этом точность нужно было выдерживать всегда — а тут такая засада уже в самом начале работы.

Довольно скоро аналитик сообразил, что наблюдаемое поведение связано с новой конструкцией двигателя. Характер изменения ускорений, придаваемых им модулю (величина то ли первой, то ли второй производной ускорения) был такой, что счисление положения привычным методом давало недопустимую погрешность. Хорошо, что это обнаружилось на этапе запусков с коррекцией и дало возможность поменять алгоритм так, чтобы свести эту погрешность к приемлемой. Если бы не данные телеметрии, успешные итоги запусков с коррекцией стали бы основанием для запусков без нее, каковые и увенчались бы закономерным фейлом.

Случаи с беспилотником

Один раз здорово помогли те самые циклические счетчики. Беспилотник после отрыва от земли вдруг потерял стабильность и через несколько секунд упал (сломав, собака, в очередной раз часть дорогущего набора подъемных винтов). Тогда в телеметрии еще не было счетчиков ошибок канала CAN, потому что разработчик считал эту шину весьма стойкой к сбоям, и — с учетом того, что неудачные посылки отправляются контроллером CAN вновь и вновь, пока не будут приняты — с настройками по умолчанию надежной линией доставки команд. Поэтому был только циклический счетчик удачных посылок. И вот, судя по нему, частота выдачи сигналов управления на двигатели деградировала со штатных 50 герц аж где-то до 8, приведя к громадному фазовому сдвигу в контуре стабилизации, возбуждению и потере управляемости.

Как оказалось, сгубила аппарат именно способность CAN автоматически повторно слать неудачные пакеты. Из-за мороза нарушилось качество контактов в одном из абонентов, при полётной вибрации оттуда перли помехи, пакеты не доходили с первого раза, CAN упорно продолжал их слать, а в это время новые управляющие данные нельзя было отдать в выходной буфер CAN, потому что тот был еще занят. В итоге к моменту, когда пакет таки оказывался принят двигателем, он уже безнадежно устаревал. Отсюда вывод: если старый пакет управления не удалось отослать до появления нового — следует прекратить попытки и заменить пакет на более новый. Он, по крайней мере, будет адекватен текущей ситуации, и с ним шанс выжить выше, чем со старым.

Позже на этот же беспилотник ставили радиовысотомер. Необходимость применения именно радиовысотомера во весь рост встала после того, как аппарат, в попытках сесть, грациозно танцевал над свежим снегом на лидаре, взметая под собой пургу и приводя лидар в неистовство. Закончилось шоу тем, что перегрелся один из двигателей (остальные были близки к этому), аппарат послал такую жизнь к черту, выключил все четыре движка сразу и обрушился вниз, разметавшись по земле. С высотомером тоже все оказалось не слава богу, и это тоже выяснилось уже потом, при сравнительном анализе данных лидара и высотомера после очередной жесткой посадки: на скоростях движения выше 3 м/с в одном из направлений РВ принимался динамически врать об оставшемся расстоянии, и вычисление скорости движения на основе его данных создавало жуткий кавардак.

В другой раз аппарат раскрутил двигатели, поднялся, мелко подрагивая, метров на 15, а там вдруг резко накренился и, поочередно завывая движками и болтаясь по крену из стороны в сторону, понесся к земле. Анализ телеметрии показал, что была допущена ошибка при вводе передаточных чисел закона стабилизации по крену: их увеличили в несколько раз. То, что квадрик поднялся, объяснялось чистой случайностью: при подъеме возмущения были достаточно малы, чтобы контур стабилизации оставался устойчивым при их отработке — а наверху дунул ветер, и пошла писать губерния. К счастью, в тот момент величины передаточных чисел уже писались в телеметрию, хотя они тогда были статическими и большого смысла писать их не было: можно было увидеть эти числа непосредственно в коде прошивки. Но то еще когда бы пришло в голову, а тут сравнение цифр в каналах крена и тангажа в рамках анализа типового набора переменных сразу показало виновника.

В общем, господа, аве телеметрии! Надеюсь, у хабровчан найдется, чем дополнить этот кодекс и с чем поспорить: две-то головы лучше, чем одна.

[1] Можно сделать финт ушами и сопроводить запись о таком событии биркой времени его возникновения, разместив саму запись в потоке позже, когда будет возможность. Но это осложнит процедуру анализа. Хотя иногда приходится делать и так, когда точность знания момента очень важна, а принцип передачи времени и структура канала не дают возможности эту точность обеспечить даже с учетом приоритизации.

[2] Жизненный совет: очищайте флэшку перед установкой в модуль, чтобы не путаться потом, какие файлы новые, а какие остались с прошлых включений. А перед ответственным запуском — форматируйте, причем «полным» форматированием, а не «быстрым». Когда FAT слетит целиком, останется возможность руками вытащить данные из образа флэшки, и они будут расположены в этом образе последовательно.

Телеметрия

Информация может быть передана через компьютерные или телефонные сети, а также с помощью беспроводных сетей, таких как радио, Wi-Fi и т.п. В системах телеизмерения обычно применяют последовательные протоколы RS-485, RS-232, CAN и сетевые TCP/IP, Ethernet. Сейчас также используются сервера и компьютеры, содержащие в себе сочетание различных протоколов и встроенные средства обработки и отображения данных. Подобные системы позволяют собирать информацию с датчиков вне зависимости от физических границ (например, беспроводные датчики) и обеспечивают многофункциональность и интегрирование с другими механизмами.

В целях достижения должного уровня унификации принято придерживаться международной системы стандартов, разработанной Межведомственной комиссией по измерительным средствам (IRIG) для программного обеспечения и телеметрического оборудования.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *