Потёмкинская деревня - 2

Oct 19, 2021 21:42

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

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

Вот что-то наваял...




Решил - пока такая оказия, нужно написать "парсер" сообщений информационного обмена по МКО (он же Mil-Std 1553, он же ГОСТ Р 52070-2003). Традиционно - без жуткого количество if'ов или case'ов, а расписав древовидную структуру всех этих сообщений. Интроспекция, полиморфизм, вот это вот всё, на старом добром Delphi :) Фрагмент файла конфигурации:

UTF8object TVipsMilStdDescription
DeviceAddress = 6
object ALL_BS: TVIPSmessage
isRTtoBC = false
isBroadcast = true
subAddress = 31
WordCount = 17
Caption = 'Синхронизация (с СД)'
Header = 0
object SyncWord: TFixedPointVIPSdata
Caption = 'PRF_NO'
Description = 'Номер текущего Processing Frame БВС, диапазон 0..99'
Unsigned = true
NumberOfIntegerBits = 16
end
end
object VIPS_FT: TVIPSmessage
isRTtoBC = false
isBroadcast = false
subAddress = 17
WordCount = 25
Caption = 'Полётное задание'
Header = 43690
object FT_CNT: TFixedPointVIPSdata
Caption = 'FT_CNT'
Description = 'Цикл.счётчик'
Unsigned = true
NumberOfIntegerBits = 16
end
object LED: TMultiBitFieldVIPSdata
Caption = 'LED'
Description = 'Режим работы осветителя (0-отключён, 1-в первой половине вычислительного такта,2-во второй половине)'
BitCount = 2
end
object UseCartes: TBitFieldVIPSdata
Caption = 'UseCartes'
Description = 'Использовать декартовы координаты вместо сферических'
end
object AcqL: TBitFieldVIPSdata
Caption = 'AcqL'
Description = 'Разрешение захвата дальней дистанции'
end
object AcqS: TBitFieldVIPSdata
Caption = 'AcqS'
Description = 'Разрешение захвата ближней дистанции'
end
object Trk: TBitFieldVIPSdata
Caption = 'Trk'
Description = 'Разрешение сопровождения'
end
object StereoEn: TBitFieldVIPSdata
Caption = 'StereoEn'
Description = 'Разрешение работы стереорежима'
end
object MDDen: TBitFieldVIPSdata
Caption = 'MDDen'
Description = 'Разрешение работы по МДД на ближней дистанции'
end
object UseCov: TBitFieldVIPSdata
Caption = 'UseCov'
Description = 'Вычислять ковариационную матрицу шума измерений'
end
object FT_Reserved0: TMultiBitFieldVIPSdata
Caption = 'Reserved0'
Description = 'Эти биты пока не задействованы'
BitCount = 7
end
object ShortRange: TFixedPointVIPSdata
Caption = 'ShortRange'
Description = 'Дистанция, с которой ВИПС начинает работать с отдельными элементами МБД, метры'
Unsigned = true
NumberOfIntegerBits = 9
UnitName = 'м'
end
object VelLW: TFixedPointVIPSdata
Caption = 'VelLW'
Description = 'Размер окна для оценки скорости сближения на дальней дистанции'
Unsigned = true
NumberOfIntegerBits = 16
end
object VelSW: TFixedPointVIPSdata
Caption = 'VelSW'
Description = 'Размер окна для оценки скорости сближения на ближней дистанции'
Unsigned = true
NumberOfIntegerBits = 16
end
object VelThr: TFixedPointVIPSdata
Caption = 'VelThr'
Description = 'Дистанция, на которой переключается размер окна, метры'
Unsigned = true
NumberOfIntegerBits = 9
UnitName = 'м'
end
object Alpha: TFixedPointVIPSdata
Caption = 'Alpha'
Description = 'Угловой размер пикселя (до сих пор не определились с размерностью)'
Unsigned = true
NumberOfIntegerBits = 16
end
object r0: TFloatVectorVIPSdata
Caption = 'r0'
Description = 'Смещение между системами координат ВИПС и ПТК'
UnitName = 'м'
ExpBias = -2
end
object Lambda: TQuatVIPSdata
Caption = 'Lambda'
Description = 'Кватернион перехода между системами координат'
end
object DeltaR: TFloatVectorVIPSdata
Caption = 'DeltaR'
Description = 'Вектор стереобазы'
UnitName = 'м'
ExpBias = -2
end
object DeltaLambda: TQuatVIPSdata
Caption = 'DeltaLambda'
Description = 'Кватернион стереобазы'
end
end

До сих пор не нарадуюсь, как одной строкой MilStdDesc.LoadFromFile('config.txt'); на полном автомате создаются все необходимые экземпляры классов, причём какой именно класс нужен - заранее (на этапе компиляции) неизвестно, там давным-давно была весьма хитрючая механика реализована с метаклассами, которая позволяет избежать жутких "абстрактных фабрик".

И сейчас, для теста, я примерно так вызываю парсинг:

MilStdDesc.ShowMilStdMessage([$3222,$AAAA,$58DF,$0000], false, System.SysUtils.Now);

Потом, ясное дело, данные будут не "ручками" введены, а приходить либо с COM-порта, а в дальнейшем - по штатному МКО.

Ещё один скриншот, это как бы "начало работы", где мы передаём полётное задание:



Как видно, кое-какие ошибки он вылавливает. В самом начале мы "зачем-то" передали лишнее слово - заявлено было 2, а передали 3. То же самое будет, если нам в ответ вернут лишнего, хотя я не уверен пока, что мы это "лишнее" вообще будем дожидаться - может сразу возьмём сколько надо, а остальное проигнорируем.

Также проверяется контрольная сумма, допустимость подадреса и направления передачи данных, а также "недостающие" данные.

Синие - сообщения, которые отправляются с компьютера на прибор. Зелёные - ответ от прибора. Красное - если что-то неправильно.

Все возможные сообщения уже "вбиты" в файл конфигурации, но ещё остался небольшой должок: "переменные" поля!

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

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

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

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

странные девайсы, ПЛИС, программки, работа

Previous post Next post
Up