23.12.2017

Акселерометр

На самом деле, первым моим желанием было написать не кренометр, а акселерометр, что бы замерять ускорение с места, с 0 до 100 км/ч.
Дело в том, что пару лет назад (о, как время-то летит) я прикупил себе маленький кроссовер, Tiguan. А автопроизводители, как известно, барыги жадные, вовсю используют ценовую дискриминацию для того, что бы максимизировать прибыль. Например, за порт USB в мультимедиа-системы некоторые просят доплатить 10 тыс. рублей или больше.
Или за форсирование двигателя просят несколько сотен тысяч рублей. Ну, то есть физически двигатель один и тот же, меняется только константы в блоке управления (может быть, и сам алгоритм в каких-то случаях, но мне известно только про данные). Разница в мощности одного и того же дефорсированного двигателя и его самой мощной модификации может составлять в районе сотни л.с., а разница в ценнике - в несколько сотен тысяч рублей. Это вот как раз мой случай.
Ну, а коли изменение параметров двигателя меняется так легко, то (спрос рождает предложение) появились мелкие конторки, которые за гораздо меньшую сумму, чем автопроизводитель, меняют прошивку в блоке управления двигателем на более мощную. Естественно, именно так я и поступил.
Не менее естественно, мне было интересно, реально ли были внесены изменения в прошивку или я заплатил деньги за воздух? Проще всего проверить это можно, замерив разгон до 100 км/ч. Если разгон занял меньше времени, чем по заводским характеристикам, значит, прошивка прошла успешно.
Понятно, что первым делом я выполнил такой замер, правда, вручную. Ручной замер показал, что прошивка прошла удачно. Одновременно с этим (банально, да?), выяснилось, что вручную замерять очень не удобно, соответственно, страдает точность измерений. Захотелось написать программку для замера ускорения, но так получилось, что сначала я сделал кренометр.
Но оно и к лучшему. Дело в том, что пользуясь калибровочной информацией кренометра можно очень точно получить информацию о момента начала заезда. Это можно сделать, во-первых, автоматически, а во-вторых, гораздо точнее, чем при использовании данных GPS.
Вот один из последних результатов, полученных при проверке готовой версии:
По-моему, неплохой результат, с учетом того, что он был получен на зимней шипованной резине при температуре +8 и на мокром асфальте. Заводские данные для дефорсированного мотора - 9.9 сек. Летом повторю заезд в сухих условиях и на нормальной резине. По идее, должен выехать из 8.5 сек, так это время соответствует 200 л.с., а у меня, теоретически, должно быть 239.
Теперь об особенностях разработки акселерометра. Основная проблема - получение точных данных. Несколько моментов:
1. GPS координаты могут быть очень неточны. Например, в условиях плотной застройки точность может быть около 5 м. Это значит, что с вероятность 68% реальное местонахождение находится в окружности радиусом 5 м вокруг переданных системой GPS координат. И с вероятностью 32%, что за пределами этого радиуса. Максимальная точность, что удавалось мне получить на моем смартфоне - 2 м. И если для больших скоростей (и больших перемещений за единицу времени) такая погрешность относительно не высока, то для медленных перемещений может приводить к совершенно не корректным результатам.
Вертикальная точность может быть еще хуже. Например, при отладке приложения я прошел пешком около 20-30 минут, от Октябрьского по Дружбе до Тольятти и далее в сторону Кирова. Так данные GPS показали, что за это время по высоте я переместился на несколько сотен метров, хотя реальный перепад высот не превышает и 10 метров.
Но в этом отношении есть и хорошая новость. С 2018 года некоторые смартфоны будут оснащаться новыми GPS-приемниками, которые принимают сигнал L-5, что повысить точность даже в условиях плотной застройки до нескольких десятков сантиметров.
2. Частота опроса GPS-приемника у большинства смартфонов не превышает 1 Гц. Для замера ускорения достаточно медленных машин, с разгоном более 10 сек. проблем тут особых нет. А вот если разгон занимает меньше 5-6 сек, то точность уже оставляет желать лучшего. Попытался найти смартфоны, которые могут возвращать данные GPS чаще, но найти их не смог. Но знаю, что есть профессиональные GPS-приемники, которые выдают сигнал 5 и 10 раз в секунду. Их периодичности будет вполне достаточно для автомобильного акселерометра даже в случае спортивного автомобиля.

Для более точного определения скорости я сначала планировал аппроксимировать траекторию автомобиля с помощью полинома. У меня есть серьезные основания полагать, что такой подход даст более точные результаты. Однако он усложняет автоматическое определение завершение заезда и повышает требование к торможение.
Поэтому пока остановился на самой простой схеме. Скорость определяется по левым производным по узлам траектории, а точное значение в заданных точка (40, 60, 80, 90, 100, 200 км/ч) - линейным приближением между рассчитанными скоростями в узлах.
Может быть, имеет смысл перейти на центральные производные, вроде бы у них меньше погрешность. Однако не понятно, даст ли это существенное улучшение при столь крупном шаге по времени.


06.12.2017

Кренометр

Как-то у одного френда в бложике увидел загадочную штуковину на торпеде с двумя круглыми шкалами-индикаторами. Поинтересовался у него, что это такое. Оказалось - кренометр.
Короче, такой приборчик, который замеряет крен и тангаж автомобиля в процессе движения. На самом деле при движении по шоссе вообще не нужен. А вот при движении вне дорог может пригодиться. Что бы ненароком не сделать уши перевернуться. Хотя опытные джиперы говорят, что настоящим профессионалам такие приборчики вообще ни к чему, у них отменные опыт и интуиция. 😉
У меня у самого скромненький паркетник, тем не менее, бывает, езжу по всяким буеракам. И реально не очень понимаю, не перевернется ли машина на сильном уклоне. Поэтому решил, что для меня кренометр - вещь полезная.
Посмотрел, таких приборчиков вагон и маленькая тележка, да и стоят не дорого. Но надо как-то их крепить, да и место занимают, а у меня и так там наставлено: радар-детектор, видеорегистратор, ну и иногда смартфон в качестве навигатора.

О! У меня же смартфон! А из него можно сделать отличный кренометр. 😀 В общем, решил запилить кренометр своими руками.
Сначала, по привычке, пытался писать на Delphi под Android. Но очень скоро понял, что это - совсем не торт. Поэтому перешел на нативный инструмент - Android Studio.

В общем, долго-долго я с ним возился, сделал более-менее рабочую версию. Думаю, дай-ка закину ее в Google Play. Зашел туда, глянул, а там - мама моя дорогая - этих кренометров/inclinometers каких только нету. И платных, и бесплатных, и с рекламой и без нее... Все такие красивые, с продвинутым интерфейсом и работают получше моего, похоже.
Но, тем не менее, закинул, пусть лежит.

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

Кстати, очень интересны всякие датчики в смартфонах, можно собирать и обрабатывать данные и что-нибудь с ними делать. Что  касается акселерометра, то он меня с одной стороны удивил своей чувствительностью, а с другой - своей неточностью.
В частности, вектор гравитации по длине может превышать 10 м/с2, а с другой стороны, его длина еще зависит от ориентации смартфона относительно поверхности Земли. Хотя, возможно, это особенность лишь моего экземпляра.

24.08.2017

Акустический (звуковой) кондиционер

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

Началась эта история очень давно, еще в 90-х годах. За это время тепловентилятор износился полностью и напрочь отказался работать. Попытки найти ему замену были безрезультатны.
Сначала был куплен другой тепловентилятор.Он, хоть и исправно обогревал, звучал надоедливо и плохо маскировал звуки. Я подумал, что в XXI веке можно решить проблему более технологичным способом и решил найти что-нибудь подходящее в интернете. Вот что я там обнаружил.
Один предприимчивый американец (как ни странно, не думал, что в США есть подобные проблемы) продает подобную механическую свистелку. Правда, с совершенно конским ценником, на который можно купить несколько тепловентиляторов.
Есть и электронные устройства, но предназначены они для защиты конфиденциальных переговоров от аудио прослушки по периметру. Стоимость у них еще больше. И не понятно, можно ли их использовать для таких бытовых целей.
Я же хотел найти какую-нибудь простенькую программу для компьютера, но почему-то ничего не нашлось. Может быть, я плохо искал, а может, такие проблемы, как у меня - редкость. И у большинства людей крепкая, устойчивая нервная система.

Так что не долго думая, я взял и накатал для себя такую простенькую программу, которая выполняет функцию акустического (звукового) кондиционера. Белый шум сгенерировать было очень легко, но он не очень подходит для засыпания, так как достаточно назойлив.Гораздо лучше использовать в этих целях серый шум. Отличается он от белого тем, что у него на средних частотах слышимого диапазона провал 6 дБ на октаву.
С серым шумом было сложнее, так как с цифровой обработкой звука я не очень знаком. В общем, получить чисто серый шум мне пока не удалось, но несколько более приятных на слух вариантов по сравнению с белым шумом у меня получились. Назвал я их Сероватый 1, 2 и 3. Лично мне нравится больше последний вариант.
Выбор вариантов оставил, так как они могут пригодится в том случае, если посторонние мешающие звуки находятся как раз в среднем диапазоне частот. Тогда их придется маскировать более "белым" шумом.
Саму программу генератора шума можно скачать здесь. Сам ею регулярно пользуюсь. После скачивания ее нужно куда-нибудь распаковать и просто запускать, никаких специальных требований у нее нет. Правда, запускается она в полное окно и показывает в нем содержимое этого блога. 😉
И да, при первом запуске сначала поставьте уровень громкости на минимум. Ведь белый шум - очень мощная штука. 😋

23.03.2016

И снова SSE

Пытался тут в очередной раз ускорить расчет векторного произведения для звуковых данных. С подачи Ивана в комментариях к моему посту о том, что нужно выполнять сразу четыре произведения, что должно дать существенный эффект.

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

Естественно, выглядит такой код странно. Переписал его же на цикл. Скорость выполнения снизилась почти в два раза. Чему, честно сказать, я удивился. Ни конвейер, ни суперскалярная архитектура и прочие достижения современного процессоростроения ничего не смогли противопоставить старой, как мир, оптимизации в лоб.

После чего я перешел к оптимизации под SSE. Основная проблема тут состоит в том, что изначально данные расположены не так, как было бы удобно их вычислять с использованием SSE. Но так как мне было любопытно, какой выигрыш даст SSE в том случае, если данные уже расположены правильно, то я сделал вид, что они лежат типа правильно.
Результат оказался забавным. Умножение сразу четырех векторов было почти в три раза быстрее, чем скалярный расчет с использованием цикла, и всего лишь в полтора раза быстрее скалярного варианта с развертыванием циклов.

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

Но засада состоит все же в том, что в реальности данные организованы не так, как нужно для корректных вычислений. Поэтому на пути к векторизации вычислений лежит преграда в виде транспонирования векторов. Это потребует дополнительных операций и пока не понятно, даст ли в результате SSE какой-то выигрыш и если даст, то какой?

Набор команд SSE меня слегка разочаровал. Нет, конечно, очень важно сделать векторные команды. Но не менее важно иметь и команды, которые готовят данные к векторным операциям. В данном случае меня интересовали команды сбора данных из разных участков памяти в один вектор, а также команда умножения вектора на скаляр.
Первая из требуемых мне команд появилась лишь в наборе AVX2. Что касается второй команды, то ее нет вовсе. Что, в принципе понятно, так как умножение на скаляр можно заменить скалярным умножением на вектор, заполненный одним и тем же числом. Однако, такая команда, которая умеет весь вектор заполнять одним числом, также появляется лишь в AVX2.
Беда же состоит в том, что мой процессор, хоть и не самый старый, тем не менее AVX2 не поддерживает. Поэтому вкусить немного радости от его использования не удалось. Пришлось ограничится скалярным вариантом. В этом и состоит разочарование и вопрос: неужели в большинстве прикладных задач, требующих векторных вычислений, данные уже лежать так, как надо?

В результате выигрыш от векторизации есть. И для случая векторного произведения он составляет целых 21.5%!
Вот более детальные результаты:
ТестРезультат, такты
Развернутый скалярный цикл642
Скалярный цикл1149
SSE с формирование вектора из скаляра436
SSE с использованием готового вектора, сформ. из скаляра425
SSE+Транспонирование с формирование вектора из скаляра504
SSE+Транспонирование с использованием готового вектора, сформ. из скаляра630


Хотя, возможно, я просто не умею их готовить (вектора в смысле)?

На всякий случай выложу фрагмент кода, с помощью которого получил указанные выше результаты. Код писан для случая wavelet-преобразования, поэтому на самом деле рассчитывается V1*V2 и V1*V3, то есть реально рассчитывается 8 векторных произведений, каждый вектор длиной 4.

22.03.2016

Арифметическое кодирование

Дабы усилить качество сжатия звука, решил попробовать вместо Хаффмана использовать арифметическое кодирование с динамической моделью. Использование динамической модели позволяет отказаться от хранения словаря вместе со сжатыми данными.
Сначала, правда, пришлось много повозиться с упрощением для максимальной эффективности кодера, переписанного мною на основе курсовой Александра Шендрикова много-много лет назад.

В общем, использование арифметического кодирования дает определенные преимущества по степени сжатия по сравнению с Хаффманом. Но платой за это является существенно более медленная работа. По скорости пока их не сравнивал. Зато можно сравнить по объему при прочих равных.
При размере окна кодирования 44100 отсчетов выигрыш арифметического кодирования составил 3%. При более мелком окне (1764 отсчетов) выигрыш значительнее и составляет  12.8%. Это за счет того, что не хранится словарь.

На текущий момент самый большой достигнутый мною коэффициент сжатия аудиоданных (правда, на одном и том же музыкальном файле) без заметных на мой слух искажения, составил 1/7 - 1/7.5. В данном случае не используется какая-либо психоакустическая модель. Если добавить ее, то, наверное, удастся приблизится к коэффициенту сжатия MPEG.
Но без использования психоакустической модели зато получается более точная фазовая картина звука и не забиваются тихие участки на фоне/после громких. Так что в каких-то специальных случаях такой подход может быть более полезен.

13.01.2016

Еще про звук

Как я и предполагал, переход к переменному коэффициенту сжатия (вариант постоянного битрейта), позволил достичь более высоких степеней сжатия. На текущий момент удалось сжать исходный файл в 7.5 раз без заметных на мой слух артефактов.
Собственно, главной задачей было тестирование на наличие артефактов на границах звуковых кадров. Пока могу констатировать, что артефакты отсутствуют.

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

27.12.2015

Звук

Попробовал сжать звук с помощью wavelet-преобразования.

Пока результат не настолько хорош, как я предполагал первоначально на основе анализа фрагмента файла. Использую нехитрый алгоритм по отсеиванию незначащих данных с постоянным квантизатором, удалось достичь коэффициента сжатия примерно 1:4.4. При более сильном сжатии даже на мой слабый слух искажения уж больно сильно заметны.

Немного, прямо скажем. Но резервы есть, если перейти на сжатие с переменным квантизатором.

А пока выкладываю два файла одни архивом. Один исходный, второй - после восстановления сжатого файла. Различия между ними есть, но я бы, честно говоря, не отличил, какой исходный, а какой сжатый. Интересно, удастся ли распознать кому-нибудь из читателей, где какой?

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