Новая система от Смаллтим - SwiftAI Next Generation - автопилот+телеметрия+ИМУ

AlexSneg
baychi:

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

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

baychi
AlexSneg:

давайте универсальный протокол сделаем и опишем его.

Если еще и Сергей (msv) подключится, вообще здорово будет!

baychi

С разрешения Тимофея, цитирую его описание протокола кодирования данных для наземки на стороне модели:

------------------------------------------------------------------------------------------------------

  1. Для заковыривания данных в видеосигнал используется та же схема, что рисует ОСД
  2. Для заковыривания данных в видеосигнал используется DMA и SPI с (пиксельной) частотой 13.5 МГц. 26 пикселов картинки на бит данных.
  3. Данные идут в 4 строках с номерами 16,17,18,19 в каждом полукадре, полный пакет данных составляет 64 байта, в каждом полукадре уходит шматочек, состоящий из 4 байт из полного пакета.
  4. 1 байт данных шматочка уходит в одной строке и превращается в 3 байта в строке:
  • 1 байт :
    – бит 7 - всегда 1
    – бит 6 = 0 - это АП+ОСД, бит 6 = 1 - это ОСД
    – биты 5…2 - номер кадра%16 (0…15)
    – биты 0…1 - номер строки-16 (0…3)
  • 2 байт: байт данных
  • 3 байт: 255 минус байт 2 с предварительно переставленными нибблами

На приеме на стороне наземки выполняются следующие проверки:

  • для каждой строки проверяется равенство второго и третьего байт после обратной математики над третьим байтом. Елси проверка не проходит, то строка отбрасывается и дальнейшие проверки в текущем полукадре считаются проваленными.
  • в каждом полукадре для 4 принятых в нем строк проверяются номера строк, должны быть 0,1,2,3. Если не проверка не проходит, то эти строки отбрасываются
  • в каждом полукадре для 4 принятых в нем строк проверяется на одинаковость номер кадра (номер четырехбайтового шматочка данных, передаваемого в полукадре). Если не проверка не проходит, то эти строки отбрасываются.
  • если 4-байтовый шматочек в полукадре прошел все проверки, то он записывается в соответствующее ему место временного 64-байтного массива, и (всего шматочков 16 на 64 байта полной пачки) взводится соответствующий ему бит в 16-битной переменной, хранящей флаги корректности шматочков.
  • как только все 16 бит переменной, хранящей флаги корректности шматочков, становятся равны 1, делается копия временного массива в 64 байта и флаги корректности шматочков сбрасываются. Эта временная копия парсится.

Итого:

  • Пачка в 64 байта считается корректно принятой только тогда, когда пиняты все шматочки по 4 байта в полукадре. с частотой 50 Гц это получается ~3 полных обновления в секунду. Если выбивает данные в 1 -2 кадрах, то наземка будет ждать примерно 0.3 сек до того, пока не придут данные для этих шматочков из следующей пачки.
  • В процессе ожидания данных для битых шматочков допускается обновление данных в любом небитом шматочке, даже если шматочек уже был принят ранее.
  • Данные в 64-байтном массиве уложены так, что любой полетный параметр укладывается в границы одного шматочка.

Структура данных:

// data format:

GPS_CURLAT: .byte 4 // lsb = 0.00001 deg
GPS_CURLON: .byte 4 // lsb = 0.00001 deg
GPS_STARTLAT: .byte 4 // lsb = 0.00001 deg
GPS_STARTLON: .byte 4 // lsb = 0.00001 deg
GPS_CURSPEED: .byte 2 // lsb = 1kmh
GPS_STARTALT: .byte 2 // lsb = 1m
GPS_DZ: .byte 2 // lsb = 1m
GPS_HEADING: .byte 2 // lsb = 1deg
BARO_CURSPEED: .byte 2 // lsb = 1kmh
BARO_CURALT: .byte 2 // lsb = 1m
COMPASS_CURHEADING: .byte 2 // lsb = 1deg
COMPASS_BEARING_TO_BASE: .byte 2 // lsb = 1deg
AUTOPILOT_STATUS: .byte 1
GPS_NUMSATELLITES_BATTERYINDICATOR: .byte 1 // (low 4bits)/battery indicator(high 4 bits)
GPS_BEARING_TO_BASE: .byte 2 // lsb = 1deg
CURRENT: .byte 2 // lsb = 0.01A
MAH: .byte 2 // lsb = 1mAh
VOLTAGE1: .byte 2 // lsb = 0.01v
VOLTAGE2: .byte 2 // lsb = 0.01v
VOLTAGE3: .byte 2 // lsb = 0.01v
CUR_PITCH: .byte 1 // lsb = 1deg
CUR_ROLL: .byte 2 // lsb = 1deg
GPS_DISTANCE: .byte 2 // lsb = 1m
VARIOMETERS: .byte 1 // low 4 bits = GPS vario, high 4 bits = baro vario
RC_SIGNAL_VOLTAGE_VALUE_BITMASK: .byte 1 // bits 7,6,5 =1 - voltages 1,2,3 > 10v, bit4 = 1 - rc signal present, bits3…0 - numsticks
FLIGHT_TIME_SECONDS: .byte 2
TEMPERATURE: .byte 2 //lsb = 0.1c
--------------------------------------------------------------------------------------------------------

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

  1. Битовая скорость 2.5 МГц, в одной строке кодируется 140 бит (по две точки на бит в терминах старого ОСД или по 4 у нового АП).
  2. В четырех строках таким образом кодируется 560 бит или 70 байт. То есть один кадр передает целую структуру в 64 байта и еще 6 доп. байт. В дополнительных байтах идет CRC16 или CRC32 и счетчик обновлений.
  3. Одни и те-же данные повторяются 9 или 15 раз (в 9 или 15 кадрах). За секунду передается 5 или 3 обновления - как в текущей реализации.
  4. На приемной стороне проверяем целостность пакетов по CRC. Если хотя-бы один из 9/15 цел, используем его. Если все пакеты искажены, делаем из 9 или 15 искаженных еще один методом мажоритарного вычисления бит. Можно даже последовательно пытаться делать мажоритарное вычисление и проверку такого пакета по CRC на каждом этапе приема.
    Такой “усреденный” пакет эквивалентен 3-4-х кратному уменьшению шумов (10-12 дБ) в пакете, а 9-15 кратное повторение, само по себе дает такое увеличение вероятности приема. То есть суммарный выигрыш порядка 20 дБ.
  5. Считаем связь потерянной, если в течении 1 сек, не принято ни одного целого пакета.
smalltim
AlexSneg:

давайте универсальный протокол сделаем и опишем его

Я за любой кипиш, кроме голодовки. Но о совместимости со старыми АП и ОСД придется забыть.

Драган

Облетал сегодня Зеленого.
Графика понравилась. Горизонт тоже отлично отрабатывает, хотя и было внутри фюзеляжа -8.
Непонятки с калибровкой датчика тока - Каждый раз при включении показывает то 0,2 А (реальный расход без мотора в статике), то 5-7 А. Причем без перемычки на Aux2 разброс показаний ещё больше.

AlexSneg
baychi:

Я бы предложил такой алгоритм (для 64 байт, пока размер и ссодержимое структуры не обсуждаем).

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

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

rattis
Драган:

Каждый раз при включении показывает то 0,2 А (реальный расход без мотора в статике), то 5-7 А.

Как я понял, проблема будет решена только после выпуска нового датчика тока.
А так такая же фигня.

baychi
AlexSneg:

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

А почему нам недостаточно кадрового и строчного синхроимпульса? По ним все довольно точно синхронизируется. Выделитель синхры - традиционная LM1881.

smalltim:

Но о совместимости со старыми АП и ОСД придется забыть

Почему?
Считаешь Мега не потянет 2.5 МГц битовой скорости? Можно меньше сделать 1.25 МГц, например вдвое увеличив кол-во используемых строк.
Кстати из 625 строк PAL и 525 NTSC видимыми считаются только 576 и 480 соответчтвенно. То есть невидимых строк - 49 или 45, а в полукадре - 24 или 22. ИМХО смело можно задействовать не 4 изи них, а 8-12.

AlexSneg:

предлагаю преамбулу #AA несколько раз подряд, затем хеадер из двух байтов.

В принципе немого запаса по битам есть, можно и добавить.

Кстати, вот 2 интересных кадра, где видно кодирование данных наземки. Слева - SmallTim, справа - RVOSD:
У Вовы я насчитал 10 строк по 80-100 бит в строке.

msv

У меня именно 2,5мГц (20мГц проц/8 тактов). Только 96 бит в строке (12 байт). Сейчас передаю только координаты и азимут/элевацию для трекера поэтому хватает две строки. Было 4 строки, когда передавал все подряд. В каждой строке в начале стартовый байт для синхронизации приема, затем номер фрейма данный (для каждой строки свой) и в конце CRC16. Остается 8 байт данных на строку. Все конечно на мегах…

baychi
msv:

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

Восстановление данных используете? Или только отбрасывание?
В каждом кадре новые данные или заложенны повторы?
И каков результат по дальности на практике, на какой степени деградации картинки теряется связь?

msv

Отбрасываю только строку в которой не прошла проверка CRC. Все данные пока укладываются в полукадр (так и поленился писать логер и виртуальную приборную панель, как поначалу задумывал, поэтому убрал все лишнее…). На наземке контроль, если брак хотя бы в одной строке зажигается светодиод на 0.5сек и пикает бузер. Начинает мигать и пикать когда картинка на уровне срыва СИ.

baychi
msv:

Начинает мигать и пикать когда картинка на уровне срыва СИ.

Весьма хороший результат!
Что в качестве детектора СИ, LM1881?

smsinfo

Не хочется читать всю ветку с самого начала.
Подскажите вот такой вопрос.

  1. Поддержка коптеров появилась в новом автопилоте?
    2.Откуда автопилот берет питание, с сервразьемов от приемника, или с датчика тока или отдельное питание?
  2. Есть ли поддержка футабьего Sbus?
    Заранее спасибо за ответы.
baychi
smsinfo:

2.Откуда автопилот берет питание, с сервразьемов от приемника, или с датчика тока или отдельное питание?

АП питается отдельно, от любого источника напряжением 6-30 В. Сервы АП не питает.

smsinfo:
  1. Есть ли поддержка футабьего Sbus?

Да.

Остальное - не знаю.

rattis
smsinfo:
  1. Поддержка коптеров появилась в новом автопилоте?

Пока нет, но Тимофей обещал.
Сначала нужно прошивку для самолетов допилить.

smsinfo
baychi:

Сервы АП не питает.

Не понял ему ещё и повербокс мутить надо?

baychi
smsinfo:

Не понял ему ещё и повербокс мутить надо?

Нет. Просто подключите регуль или BEC на любой разъем PWM. Цепи +5 и GND PWM разъемов объединены.
БП АП не питает сервы ни на одном АП, так как токи там могут требоваться до 5-8 А. Этим занимается штатный “питатель борта”.

smsinfo

Возникает резонный вопрос Зачем ему отдельное питание тогда нужно?
Он мог бы питаться с этих же разъёмов что и серво.

baychi
smsinfo:

Зачем ему отдельное питание тогда нужно? Он мог бы питаться с этих же разъёмов что и серво.

А если у Вас нет питания борта (коптер)?
Или оно слишком слабое (микромодели).
Как в этом случае мерять напряжение основного акка?

smsinfo
baychi:

Как в этом случае мерять напряжение основного акка?

А разве он не датчиком тока это делает?

rattis
smsinfo:

А разве он не датчиком тока это делает?

Нет. Существующий датчик мерит только ток.
Напряжение измеряется на входе питания АП и на входе AUX V2.