Category: it

Category was added automatically. Read all entries about "it".

Sidious

Как убрать "медузу" и прочий мусор из поисковой выдачи

Чего-то вдруг голландская компания yandex N.V стала настойчиво запихивать мне в глотку "медузу" по поводу и без. Ладно, ещё могу понять, когда я искал весёлую картиночку "Один МиГ - и вы в Белоруссии" и первые две ссылки вели на эту горгону и на эхо. Причём в этот момент я попросил яндекс больше не показывать эти сайты, но разумеется никакого эффекта моя просьба не возымела.

А вчера я просто искал, что же это ЖЖ у меня не работает, не грузится и всё тут, написал что-то вроде "ЖЖ лежит" - и мне первой ссылкой статья на эту "медузу" про артемия лебедева, который с ЖЖ торжественно уходит. А почему ЖЖ висит, так и не понял, но к вечеру вроде зафурычил, и даже козёл Фрэнк среди ночи проснулся.

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

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

Collapse )

Не удивлюсь, если есть способ ГОРАЗДО ПРОЩЕ, просто не знаю, по каким словам его искать.
QuatCore

"16-битный" передатчик UART - окончание

Сегодня на удивление быстро с этой штукой разобрался:


Ну как, то есть я уверен, что UART работает правильно, что на 8 битах, что на 16, но почему-то алгоритм в этот раз точки в другом порядке расставил, и при попытке посчитать параметры сближения, получил крен 180° (!) и дальность меньше чем надо.

Ладно, с этим скоро разберёмся, посмотрю историю коммитов, что же я там поломал в последний раз, и нафига. А сначала подробности про UART.
Collapse )

"Ложная тревога": забыли в проекте "для железа" выставить параметр ijkEnabled=1, "включающий" одноимённую команду. А в данных алгоритмах она теперь вовсю используется, удобная вещь!

После очередного синтеза уже получил что надо:


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

А вот что за "мусор" внизу возник - ни малейшего понятия... Наверное, опять USB Blaster "шалит", а там посмотрим.
QuatCore

Оба алгоритма захвата - в загрузочный сектор! (512 байт)

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

Всего они заняли 254 слова кода, или 508 байт, то есть по-прежнему влезли в один блок внутренней памяти ПЛИС (БВП, он же EAB, Embedded Array Block). Ровно в той ПЛИС, которую я мучаю, 5576ХС4Т, таких блоков 24 штуки, а в той, куда хотелось бы вписаться, 5576ХС6Т (дофига радстойкая, в т.ч к тяжёлым заряженным частицам) - их всего 10.

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

Итого уже 40% доступной памяти для ХС6Т мы заняли, а ещё алгоритм сопровождения нужен! Он довольно-таки "мерзопакостный"...

Collapse )

И поглядим, что получается "по дальней дистанции", старые добрые координаты, соответствующие 300 метрам "прямой наводкой":


Ярко-зелёным показаны 4 точки, после того как их идентифицировали. В этот раз наиболее удобным мне показался порядок МБД-МДД2-МДД1-МДД3.

Синим выделен вектор с общей "экспонентой" 9, т.е значения X (от 0 до 2), Y, Z (от -1 до +1) нужно домножить на 29-1 = 256 метра.

Имеем X = 0x9591 = 38289 = 1,168 (в формате Q1.15). Умножаем на 256 - и выходит 299,13 метров.
Далее, Y = 0x0031 = 49 = 0,00149 (в формате Q1.15). Умножаем на 256 - выходит 38 сантиметров. Похоже, я и тут пожадничал в 4 раза (чтобы точность не потерять раньше времени), на самом деле должно быть 9,5 см "сдвиг вправо", т.к смотрим мы "левым глазом", а летим прямо по курсу.

И наконец, Z = 0xFE3D = -451 = -0,0138 (в формате Q1.15). Умножаем на 64 (помня, что "пожадничали") и получаем -0,881 метра. Это мы сейчас установили "началом координат мишени" центр стыковочного узла, но прибор закреплён на те самые 0,881 метра ВЫШЕ, вот и воспринимает картинку как сдвинутую вниз.

Кватернион (выделен фиолетовым) вообще получился единичным, т.е выражающий нулевой поворот. Да, так и должно быть, идём "прямой наводкой".

Это у нас работа по модельным данным, я макет мишени дальней дистанции так и не собрал до сих пор, всё с ближней дистанцией возился. По модельным данным оно приятно - всё совпадает :)
QuatCore

Алг. ближней дистанции, умножение матриц

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

И у нас уже была мааленькая процедура для умножения матрицы 3х4 на матрицу 4х2:

	;состояние регистров к этому моменту
	;Y = Points2D
	;X = Fx3
	;Z = Fx2
	;i=j=k=0
	;Inv неизвестен
	;C, Acc - неважно
	Compute4PointAffine	proc
				X		AffineMat
	;по сути, Z = X * Y, где все операнды - матрицы.
				k		1	;номер строки результата (и строки AffineMat)
		@@k_loop:	j		2	;номер столбца результата (и столбца Points2D)
		@@j_loop:	i		3	;номер столбца AffineMat и строки Points2D
				ZAcc		RoundZero	;обнулить до 1/2 мл. разр
		@@i_loop:	C		[X+4j+i]
				FMA		[Y+2i+k]
				iLOOP		@@i_loop
				Z		Matrix ;вообще AfTransf, но это промежуточная матрица, её занесём сюда (пока не наступило сопровождение, эти ячейки напрочь не нужны!)				
	;очередной результат готов...
				[Z+2j+k]	Acc
				jLOOP		@@j_loop
				kLOOP		@@k_loop
	;вот, какбе и всё...	
	Compute4PointAffine	endp


С массивом точек проблем не будет. Мы обращаемся к нему через [Y+2i+k], здесь i - номер точки, k - "номер координаты" (X:0, Y:1). Точек может быть сколько угодно, надо только перед началом цикла задать либо i=3 (как сейчас в коде) для мишени дальней дистанции, либо i=5 для ближней.

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

Collapse )

Но прежде чем проверить этот код, надо будет ещё обратить Y-координату у "обнаруженных точек", чтобы система координат была правой, и построить необходимую для работы матрицу 3х6...
QuatCore

Хотел выпендриться

Одно из замечаний к моему протоколу информационного обмена: ДОБАВЬ 16-битные заголовки к каждому сообщению!

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

Как положено, к командному слову есть бит чётности, и если он неверен - мы команду игнорируем "от греха подальше". Но им этого кажется недостаточно: вдруг нам так не повезёт, что ошибочно сменилось ДВА бита, и теперь мы решим, что надо выдать целевую информацию, хотя на самом деле заказывали телеметрию!

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

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

Но застрял с этим вопросом уже на несколько дней...

Collapse )

В общем, нельзя верить Википедии, и нельзя верить StackOverflow :) И по-моему, повторю я одно 5-битное значение 3 раза, добавлю бит чётности - и скажу, что так и надо!
QuatCore

Опять алгоритм обнаружения

Достал он меня, но надо доделывать, всё остальное фактически готово.

В прошлый раз, неделю назад, остановились на том, что компилятор неправильно воспринимал литералы с отрицательным знаком, например "Nil EQU -32768", из-за чего у нас не устанавливался правильно флаг TaskPending (о том, что мы ещё не отправили задания по предыдущему пятну), и всё рушилось.

Но когда компилятор поправили, программа снова не заработала нормально "в железе", приводя к "сбоям синхронизации", а под конец - опять к "исчерпанию заданий GPU". Поэтому ничего не остаётся, как запустить подправленную программу на симуляции и посмотреть, что там происходит.

Такая у нас картинка, 128х128, ч/б (1 бит):
Simulation1.png

и мы в порыве оптимизма начинаем со строки 14 (0x0E). Если начало прошло точно также, как прежде, у нас должно быть одно обнаруженное пятно (61;11) диаметром 3, и выданы задания на отрезки [0;59], [60;62], [63;127] и HSync. Сейчас поглядим, так ли это?



Collapse )
Ещё одной ошибкой меньше, но какая-то пакость там ещё осталась...
QuatCore

Алгоритм обнаружения на симуляции (2)

Продолжаем разбираться, в чём же проблема. Пока что мы успели пройти строки изображения, не содержащие пятно (там всё нормально), наткнулись на первую строку, содержащую "верхушку" пятна, добавили новое пятно (61;11) и диаметром 3. Чуть-чуть у нас "сбит прицел" - это должно было быть (60;13), но это не страшно.

Также мы выдали задания на обработку отрезков [0;59], [60;62] и [63;127], ну и на HSync разумеется, куда же без него - и замерли в ожидании результатов по первому из них. Даже на "покоцанном" кадре 128х128 процессор пока успевает обработать строку до прихода следующей - и то радость.

Проматываем к тому моменту, когда результаты появляются:


Ровно "в этот самый момент" идёт выдача строки, как видно по графе "X" и "Pixels". Т.е как только мы дошли до пикселя 59 - тут же и "кинулись в бой".

Максимальная яркость: 255, достигается при X=0x03A=58. Сейчас начнётся веселье...

Collapse )

Пора начинать сначала! Но одной ошибкой стало меньше - уже радость. Но сначала придётся бумажками позаниматься.
QuatCore

Алгоритм обнаружения на симуляции

На удивление долго эту симуляцию получал - сразу несколько подводных камней выползло. Уже не раз и не два замечаю: Quartus очень легкомысленно относится к инициализации регистров! Иногда инициализирует как написано - а зачастую НЕТ. Вот и сейчас, в первый раз процессор тупо "не запустился" - вижу, что висит SrcStall=1 и DestStall=1 - да так и висит, и мы остаёмся в PC=0 до скончания времён. Стал искать, каким образом так получилось, повтыкал побольше "выводов" - и тут-то всё запустилось как надо!

Потом пришлось вспоминать "особенность" моего модуля FastFreqDivider. Всем он хорош, но при "первом включении" отсчитывает больше, чем надо. И в генераторе тестового изображения он "превзошёл сам себя" - там было задано количество ПОЛЕЗНЫХ строк изображения: 128, и ещё 28 строк сверху (как в реальном сигнале CVI) и 10 строк снизу. Я посчитал, сколько времени должен занять один кадр - 2,67 мс, и задал время симуляции в 4 мс. Какое же было моё удивление, когда к окончанию отрезка первый кадр так и не закончился, и кадровый синхроимпульс не пришёл!

Оказалось: у меня для формирования кадровых синхроимпульсов стоит этот самый несчастный FastFreqDivider, для деления в 166 раз в нём используется 8-битный счётчик, который первый раз успевает досчитать до 256! Вот поэтому и выходит вместо 2,67 мс уже 4,12 мс - вот оно и вышло.

Теперь вот я забыл, как работает регистрация кадрового синхроимпульса, как так выходит, что только после СТРОЧНОГО импульса, идущего за кадровым, у нас хоть что-то сдвинулось с места:
QuatCoreAndGPU_for_simul.png

Collapse )

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

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

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

Дорабатываем программу обнаружения

Итак, видеопроцессор мы подрихтовали, даже сохранив такое же число логических элементов (ЛЭ). Теперь нужно подправить программу в нескольких местах.

Collapse )

На этом, как будто бы, всё. Осталось отсинтезировать - и посмотреть, что из всего этого выходит...
QuatCore

Управление осветителем через QuatCore

Похоже, я тут неправильную терминологию продвигал, считая, что делаю ФазоИмпульсную Модуляцию (ФИМ). Но посмотрев повнимательнее, обнаружил: на самом деле это частотно-импульсная модуляция (даже не уверен, что её сокращают до ЧИМ), она же Pulse-Frequency Modulation, PFM.

Именно в ней длительность импульса неизменна, но при этом частота их поступления меняется в широких пределах. В ФИМ и ШИМ частота следования фиксирована, в ШИМ меняется ширина импульса (логично), а в ФИМ - время его появления.

То есть, классический ФИМ - это те импульсы, что управляют симисторам в диммерах и "гашетках" электродрелей и прочих инструментов, работающих от 220 вольт: импульс для симистора всегда имеет одну длительность, ровно ту, которой достаточно для надёжного его отпирания, и частота их следования всегда одна и та же, 100 Гц, меняется лишь фаза - либо импульс приходит сразу же по пересечении нуля, давая максимальную мощность (ВСЕГДА открытый симистор), либо под самый конец, что соответствует предельно маленькой мощности.

А вот такой зверь, что у меня, как пишут, довольно редко встречается как раз-таки из-за своей "непредсказуемости" - довольно сложно работать с сигналом, частота которого варьируется от 20 кГц до 12,5 МГц :) Хотя нишевые применения есть, например, понижающие преобразователи на малых нагрузках, когда совсем "истончать" импульс не хочется (там кроме переключения ничего толком не останется, половина энергии начнёт в тепло уходить), уж лучше зафиксировать длительность импульса, просто выпускать их пореже!

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

Collapse )

Осталось дописать программу, чтобы она управляла осветителем и отображала текущую яркость на ЖК-экранчике - и потом уже поразвлекаться с разнокалиберными генераторами ШИМ, ЧИМ и пр, какой из них для нас будет наиболее подходящим! Вот чем угодно готов заняться, лишь бы "алгоритм обнаружения" не отлаживать!