nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

Ошибка в измерении крена: ларчик просто открывался

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

У меня на фоне развлечений с матрицами сразу же мысль была, что я не с той стороны её умножал. Но сразу же терзали сомнения: А КАКАЯ РАЗНИЦА, С КАКОЙ СТОРОНЫ УМНОЖАТЬ? Когда "косинус" я получил, сложив диагональные элементы, а "синус" - вычитая друг из друга два оставшихся, то кажется не важным, с какой стороны умножать.

Так оно есть!
Возьмём произвольную матрицу 2x2:


И построим "матрицу поворота" из неё:


Умножим на неё "слева":


Получили симметричную матрицу, как и хотели, и тут никуда не денешься, нельзя назвать входную матрицу "неправильной", для произвольной матрицы должно получиться именно так!

А теперь попробуем взамен умножить на неё "справа":


Это ДРУГАЯ матрица, но всё равно симметричная, что бы мы не подали на вход!

Сразу же возникает два вопроса: какая из этих двух матриц верная, и почему же у нас не получилась ни та, ни другая???


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

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

По второму вопросу, я думал, что возникает какая-то странная ошибка во время перемножения матриц. Начал смотреть "осциллограммы", проверять, какие значения пошли на вход, а какие получились на выходе. Тут же повторял эти вычисления в любимом PhysUnitCalc, и всё сошлось. Достаёт откуда надо, и вычисляет как надо, но РЕЗУЛЬТАТ НЕПРАВИЛЬНЫЙ.

Наконец, решил проверить, а СИНУС и КОСИНУС крена мы посчитали верно???

У нас, если в целых числах записать, была матрица



Складываем элементы главной диагонали, получаем 44263. Вычитаем два других, выходит 6440.

Если теперь их отнормировать, выходит co=32427, si=4718

Но у нас в прошлый раз вышло co=32153, si=6319. НУ СОВСЕМ НЕ ТО!!!

И довольно быстро становится ясно, в чём дело: значение 44263 у нас "насытилось" до 32767, и потом после нормировки вышло ровно то, что вышло!

А потом, с неправильным углом крена, понятно, что ничего не выправилось. В общем-то, и мы наблюдали на картинке, что всё равно неровно оно стоит! Вот только факт, что сумма квадратов получилась равной единице, как-то "убаюкал". Ну так немудрено, после нормировки, что так и будет...

Да, с таким крупным изображением мишени мы ещё не имели дела в этом алгоритме, вот и прохлопали переполнение. А за счёт насыщаемой арифметики результат получился НЕДОСТАТОЧНО КРИВЫМ, выглядел разумно, если не приглядываться.

Осталось понять, как это исправить. С беззнаковыми числами от 0 до 65535 мы тоже работать умеем, но здесь оно не подойдёт. Если мишень развернуть на 180°, мы с тем же успехом получим -44263, т.е здесь числа должны быть знаковыми.

Ну, значит, команды Acc ("занести значение в аккумулятор") заменяем на DIV2 ("занести значение, делёное на 2"), а PM (Plus-Minus) на DIV2PM, команду, которую мы по-моему вообще ни разу ещё не применили!

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

;нам понадобятся [Y]+[Y+3] и [Y+1]-[Y+2]			
;скорее,         [Y+3]+[Y] и [Y+2]-[Y+1]
		ijk	0x0023	;Inv=k=0, i=1, j=3
		Z	QuatY 	;в этом кватернионе построим,используя Y/Z значения как временные
				;(потом они занулятся)				
	@@sico:	DIV2	[Y+i^j]
		Inv	i
		DIV2PM	[Y+i]
		[Z+i]	Acc
		iLOOP	@@sico


И ещё инициализацию регистра Z вынесли из цикла (где она делалась нахаляву, пока АЛУ сильно занят) в начало цикла, потому что возникал Hazard между командой на запись ijk и на чтение [Y+i^j], и транслятор всё равно вставлял NOP. Маленькая радость, код сократился до 156 слов (312 байт).

Узелок на память: на самой большой дальности в 300 метров, когда все числа в этой матрице получаются маленькими, после этого деления на 2 может не успеть за 13 итераций отнормировать, надо будет проверить и ещё пару итераций добавить по необходимости.


Смотрим дамп памяти после работы исправленной программы:


Фиолетовым выделена матрица, вот теперь она действительно симметричная, оба элемента вне диагонали 0x007A, это примерно 0,0037.

Синим выделен кватернион. Два последних числа - это пока что co = 32427, si = 4718. Вот теперь всё правильно, с точностью до последнего бита. atan(4718/32427) ≈ 8,278°. Попробуем повернуть изображение на этот угол:


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

Можно двигаться дальше, к вычислению масштаба.
Tags: ПЛИС, математика, программки, работа, странные девайсы
Subscribe

  • Лестница для самых жадных

    В эти выходные побывал на даче, после 3-недельной "самоизоляции". Забавно, как будто зима началась! Особенно грязные галоши остались на улице, в…

  • Возвращаемся к макету

    Очень давно макетом видеоизмерителя параметров сближения не занимался: сначала "громко думал" по поводу измерения его положения на аппарате, а потом…

  • Минутка живописи

    В процессе разгребания содержимого квартиры (после нескольких ремонтов) дошёл, наконец, и до картин. В кои-то веки их повесил. Куда их вешать -…

  • Костыль ноутбуку и кабели Франкенштейна (это не я!)

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

  • Атомный файлсервер, убитые петухи и харакири андроида

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

  • Ещё про яркий светильник и ИБП

    Всё-таки применил лежащее дома барахло наиболее простым образом: А ещё наконец-то замерял температуру теплоотвода яркого светильника на кухне,…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments