OSD на ATmega1281

varvar

Недавно решил проверить, можно ли сгенерировать видео на MSP430 и LM1881 - был приятно удивлен - не можно, а, видимо, нужно 😃 Причем процессор и делать почти ничего не должен. Одно прерывание - от Vsync - сбрасываю счетчики. Hsync заведен на вход таймера - при приходе следующий таймер настораживается на время, когда должна пойти развертка своего изображения, ну и считает строки. Дальше процессор просто отдыхает автоматически выбрасывая посылки через SPI контроллером прямого доступа. Первый канал DMA выплевывает первый байт буферной строки по готовности настороженного таймера. Второй канал выплевывает в буфер SPI байты по его готовности, сколько байт закажешь. Все! И никаких разрывов. Нужно только буферную строку приготовить или если вся память используется как видеобуфер, менять адрес для DMA. Программа написана на С++, никаких ассемблерных вставок, и еще операционка успевает крутиться. Если это можно назвать программой - практически только аппаратуру инициализировать и несколько строк в обработчике прерывания. Внешнего кристалла не надо - внутри калиброванный генератор 32 кгц и умножитель - я поставил 24 мгц. При цене процессора 1.5-2 доллара - неплохо.
Никаких ухищрении для того, чтобы изображение не дышало не надо - все делается на железном уровне.
Сделать в двух строках еще один канал для вывода черных каемочек пока не получилось - всего 3 канала DMA, ставить процессор с 7 каналами не хочется - куда мне столько ног?
А на счет IMU - похоже, пора. Гироскоп с акселерометром в одном флаконе с доставкой уже продают дешевле 7 долларов. Можно поставить не нормальный кальман, а два простейших, выдрано из моей проверенной программы, в свою очередь откуда-то скопипасчено (налетят знатоки - по ушам надают за безграмотность и незнание арифметики, а свое решение все равно при себе оставят):

const float Sw[2][2]={0.001, 0.003, 0.003, 0.003};
  const float dT=0.05;
  const float Sz=0.07701688;

float roll_kalman_update(float gyro_rate, float accel_angle)
{
  float s_00;
  float angle_err;
  float K_00;
  float K_10;
  float AP[2][2];
  float APAT[2][2];
  float KCPAT[2][2];

  static float angle=0;
  static float bias=0;

  static float P[2][2];

  angle += dT*gyro_rate - dT*bias;
  angle_err = accel_angle - angle;
  s_00 = P[0][0] + Sz;
  if (s_00 == 0) s_00 = 0.001;

  AP[0][0] = P[0][0] - dT * P[1][0];
  AP[0][1] = P[0][1] - dT * P[1][1];
  AP[1][0] = P[1][0];
  AP[1][1] = P[1][1];

  K_00 = AP[0][0] / s_00;
  K_10 = AP[1][0] / s_00;
  angle += K_00 * angle_err;
  bias  += K_10 * angle_err;

  APAT[0][0] = AP[0][0] - AP[0][1] * dT;
  APAT[0][1] = AP[0][1];
  APAT[1][0] = AP[1][0] - AP[1][1] * dT;
  APAT[1][1] = AP[1][1];

  KCPAT[0][0] = K_00 * P[0][0] - K_00 * P[0][1] * dT;
  KCPAT[0][1] = K_00 * P[0][1];
  KCPAT[1][0] = K_10 * P[0][0] - K_10 * P[0][1] * dT;
  KCPAT[1][1] = K_10 * P[0][1];

  P[0][0] = APAT[0][0] - KCPAT[0][0] + Sw[0][0];
  P[0][1] = APAT[0][1] - KCPAT[0][1] + Sw[0][1];
  P[1][0] = APAT[1][0] - KCPAT[1][0] + Sw[1][0];
  P[1][1] = APAT[1][1] - KCPAT[1][1] + Sw[1][1];

  return angle;
}
msv

Владимир, надеюсь мои сомнения не воспримете как “…по ушам надают за безграмотность и незнание арифметики…”. 😃
DMA- замечательная штука… Но не решает проблемы неопределенностью времени входа в прерывание, которое, имхо, существует практически для всех процов в несколько тактов. Вы, для определения момента времени начала вывода строки, используете последовательно два прерывания, и вроде бы визуально строка должна заметно подергиваться по горизонтали.

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

Я пока для начала хочу попробовать банальный DCM. Забавно, но похоже получиться уместить весь код и по объему и по скорости даже с float на меге8 …

ЗЫ Может у кого есть идеи по модулятору OSD, способному выдавать качественное наложение белого и черного без искажений исходной цветовой поднесущей?

varvar
msv:

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

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

С фильтром одна гадость есть - он не работает, когда самолет вверх ногами - там точка разрыва. Для стабилизированного полета не очень реальная ситуация, а для индикации - нужно фильтр дофильтровывать 😃 вручную, когда угол близок к 180. При проходе через разрыв фильтр действительно с ума сходит. Но не надолго 😃
Да, и я писал - алгоритм не мой, откуда-то скопированный и немного подправленный в основном для лучшей читаемости. Ответственности я за него не несу 😃, на авторство тем более не претендую.

msv

Те. проц можно сконфигурировать, что-бы дернув ножкой можно аппаратно запустить таймер, который в свою очередь аппаратно запустит DMA? Реально круто (как сказала бы младшая дочь), почти ПЛИС получается…
Мертвые углы это другая проблема… Тангаж всегда определен, поскольку это угол между осью X и горизонтальной плоскостью и имеет значения +90…-90град. А вот крен (+180…-180) при углах тангажа близких к 90град действительно неопределен, в чем даже вики сознается… Это видно и из выражения Roll=atan2(y, z);, где при тангаже близкому к ±90град Z стремится к нулю. Во всех алгоритмах, которые я смотрел, это только проблема конечной интерпретации.

varvar
msv:

Те. проц можно сконфигурировать, что-бы дернув ножкой можно аппаратно запустить таймер, который в свою очередь аппаратно запустит DMA?

Об этом я и пытаюсь сказать. Делалось вообще-то абсолютно другая вещь, но вот как-то вылезло, что и видео можно сформировать. Конверсионный продукт 😃 Сегодня подключил к реальному телевизору - понял, что слегка все не так красиво. PLL плавает - нужно все-таки кварц ставить 😦 , а не 32 кгц умножать до 24 мгц. Но в интернете ни разу не встречал, чтобы кто-то OSD делал на MSP. Разве что пинг-понг доисторический в старых аппликухах лежит.

Vlado

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

С этим разберемся I hope so.
Как с последними прошивками и фичами?

msv
Vlado:

Как с последними прошивками и фичами?

Модулятор вперед… 😃

Vlado
msv:

Модулятор вперед… 😃

Всмысле.
Ах да да да конечно
ближе к выходным посмотрим модулятор. Цветовая поднесущая 4.43, плюс полоса
цветоразностного сигнала, полагаю в районе 1-1.5МГц.

Vlado

Вот пока нацелился на такой вариант фильтра может кто и побыстрее меня соберет L=28uH, C=47p.

msv

Игорь, режекторный фильтр это еще не решение проблемы (тут практически достаточно одного контура- “пробки”)…
Кстати, не хотелось бы связываться контурами, может есть для этого ПАВы?
Если его ставить на выход осд до сумматора, то как сложить сигналы с камеры и osd что-бы уровень белого osd был на уровне белого видеосигнала при его любом текущем значении (ставить мультиплексор- опять получим “разрывы” в поднесущей), а уровень черного, соответственно, на уровне черного?
Если после сложения, то как добавить поднесущую цвета (в идеале без подкрашивания OSD текущим цветом)?
Конечно все это наверняка решаемо, но надеюсь, что есть простое, оригинальное и красивое решение.
ЗЫ Интересно бы подсмотреть, как сделано у “конкурентов”… 😃

Vlado
msv:

Игорь, режекторный фильтр это еще не решение проблемы (тут практически достаточно одного контура- “пробки”)…
Кстати, не хотелось бы связываться контурами, может есть для этого ПАВы?
Если его ставить на выход осд до сумматора, то как сложить сигналы с камеры и osd что-бы уровень белого osd был на уровне белого видеосигнала при его любом текущем значении (ставить мультиплексор- опять получим “разрывы” в поднесущей), а уровень черного, соответственно, на уровне черного?
Если после сложения, то как добавить поднесущую цвета (в идеале без подкрашивания OSD текущим цветом)?
Конечно все это наверняка решаемо, но надеюсь, что есть простое, оригинальное и красивое решение.
ЗЫ Интересно бы подсмотреть, как сделано у “конкурентов”… 😃

Не ПАВ а керамика, вроде даже есть на 4.43 по типу режекции звуковой поднесущей. Но заламывают цену мама не горюй.

Vlado
avisenja:

Ceramic Trap XT SERIES Frequency range: 3.58MHz, 4.43MHz
Shenzhen, China. 😉

Используют как фильтр и дискриминатор но не режекторный фильтр.

avisenja

Вы ПДФ-ку смотрели или вам менеджер ответил, хотя какой там менеджер, разница во времени 4 часа - они там спят ещё.

Пишите менеджеру и спрашивайте что вам надо, в Шенжене и чёрта можно найти;), сам только две недели как оттуда прилетел.😵

24 days later
msv

Похвастаюсь…
Сделал QRP тест своей LRS. Мощность зажал до ~20мВт ( на приборе первое деление 100мВт, показывал мнооого меньше). Антенны и на приемнике и на передатчике- штыри. На передатчике честный штырь с тремя противовесами под 45 град, пол метра над крышей авто, КСВ чуть больше 1. На расстоянии 2км, высоте 150м уровни -70dbm, ни одного дропа… Причина возврата- выполнил полетное задание.
Вчера облетал свой IMU. Железо: мега8 (вообще первоначально думал сделать на нем только интерфейс для опроса сенсоров и сброса на хост, на котором отладил бы математику, и уж потом… выбрать под потребности необходимый проц…)+сенсоры. Алгоритм - классический DCM (изменения косметические). Пока математика без компаса (че-то не понравилось как у авторов сделано,да и флэша в меге может не хватить), с постоянной заданной линейной скоростью для расчета центробежных ускорений. Работает… ну уж точно не хуже пиросенсоров… Проблемы предсказуемые, основная- после долгих вращений из-за неточной коррекции центробежки не сразу точно встает в 0 по крену. Но для полетов вполне удолетворительно, в режиме стабилизации уронить не просто, авто-режимы отрабатывают нормально. Если нужны исходники адаптированные именно под эти сенсоры, выложу…

Vlado

а как с OSD?

Причина возврата- выполнил полетное задание.

ооо… звучит многообещающе.

На передатчике честный штырь с тремя противовесами под 45 град

буду банален, но при наличии такой крыши… никакой ground-play не нужен.
ИМХО 5/8 то что доктор прописал.

На расстоянии 2км, высоте 150м уровни -70dbm

судя по цифрам запас по расстоянию раз 10 и если еще 5/8 совсем гуд будет.

Петруччо

Сергей, а что вы скажете насчет вот такой www.ebay.com/itm/271031471551 IMU? Заказал себе недавно, жду теперь. Думал сначала взять как у вас, но решил попробовать что всё-таки за зверь этот Digital motion processor.
Я не буду слишком нахальным, спросив нет ли у вас исходников для расчёта DCM?

msv

Ну эти сенсоры уж точно не хуже моих…
Теория DCM легко находится гуглом: “direction cosine matrix imu”.
Исходники по: “ArduIMU_1.9”
Если хотите, могу выложить свой адапт+отладочный софт на BCB6, но там мин. комментариев.
На данный момент понял, что много лучше для расчета центробежки использовать скорость GPS, а не заданную константой. Ведь при полете по ветру и против она может отличаться в разы.
И пока засада… на хосте все нормально, на МК тот же код вызывает при больших скоростях заметную не устраняемую ошибку между ориентацией по акселю и гиры.

Петруччо

спс за наводку, DCM пошукаю по тырьнету.

msv:

заметную не устраняемую ошибку

я так понимаю это в купе ошибка интегрирования + дрейфы сенсоров…именно поэтому я решил взять invensense и покурить их DMP, заодно попробовать пропусть это через калмана, если таки до меня дойдет его логика работы😵 только вот мучать сразу решил кортекс-м4.

msv

Решил, проблему… Мой косячок… На столе работает замечательно…
калман, кортекс… Это все здорово… Но имхо важнее четко понимать физический смысл каждой строки алгоритма и четко представлять все его ограничения… В этом смысле DCM не превзойден своей гениальной простотой и очевидностью. А уж что влез в мегу8, сам не ожидал…
Вообще по плану инерциалку думал слепить только к следующему сезону, долго и нудно отлаживаясь долгими зимними вечерами. На удивление за недельку работы по вечерам склепал платку и адаптировал математику. Неожиданно сложно (целых два дня ушло) оказалась реализовать софтовый интерфейс с OSD (SPI, TWI, UART там уже недоступны).

Vlado:

а как с OSD?

Могу выложить прошивку последней версии с вертикальной парой пиросенсоров (наверное больше не буду ее поддерживать).

Vlado:

буду банален, но при наличии такой крыши… никакой ground-play не нужен.

Ну не play, конечно, а plane… 😃 Первоначально был штырек-четвертушка прямо в разъем. Тоже посчитал, что земли хватит… Но стало интересно померить КСВ. Попробовал коаксиальную слепить, на удивление не смог согласовать… А вот “классика”, сделаная в размер, сразу идеально согласовалась. Более того, по сравнению со штырьком в разъеме (видимо тоже не слишком был согласован…) показала почти +6dbm. Так что пока вполне доволен, только хранить и перевозить эту раскоряку конечно не очень удобно…

Vlado

Могу выложить прошивку последней версии с вертикальной парой пиросенсоров (наверное больше не буду ее поддерживать).

А ну сбросьте на майл. А что значит не поддерживать, те OSD как понимаю (творческая неудача ) и почил?
Антенки: либо блямба магнит либо отверстие в крыше ( я так понимаю не желательно ) предпочтительно 5/8. 1/4 из стальной проволоки в центре крыши с хорошим контактом ( теоретически 36 Ом плюс потерь на 14 Ом ), плюс блямбочка (емкость удлинняющая ) на кончике, тоже должно быть гуд.

ВитГо

делаю генерацию видео на меге32 (в 16ой памяти мало)

сделал текст 40х28 с графическим полем 88х72 которое можно размещать в произвольном месте (командой)

у графического окна есть пока 2 режима
общее разрешение 88х72 может выводиться в разрешении 320х224 (в разрешении текста)

и в разрешении 160х224 (по горизонтали в 2 раза крупнее)

все вертикальные линии получились ровные - уделил этому специальное внимание

ссылки на файлы в большом разрешении
vg.ucoz.ru/_fr/0/0708507.jpg
vg.ucoz.ru/_fr/0/5946348.jpg

может быть использовать как модуль наложения изображения в OSD ?
в качестве контроллера атмега 328
для общения с внешним миром - планирую uart или i2c (spi занят на дисплей)

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

в принципе сейчас делаю другие графические режимы (текстовый 20х28 и графический (полностью графика) 160х92 )

8 days later