![]() |
Выбор значения многозначной функции
Здравствуйте.
Существует ИК дальномер SHARP, который можно подключить к ЦАП и в зависимости от расстояния до объекта будет изменяться напряжение на выходе дальномера. Зависимость напряжения не только нелинейная, но и с "крохотным" изъяном : ![]() Отградуировав свой дальномер я получил похожую зависимость и пока у меня нет предположений как можно грамотно обработать получаемые данные. К примеру получив на выходе 1 Вольт, по графику видно что функция имеет два значения расстояния: 5 см и 65 см. Как вы наверное понимаете препятствие может возникнуть как на 5 так и на 65 сантиметрах. Отслеживать предыдущее значение расстояния по-моему неправильно из-за некоторого количества ошибок самого дальномера. Посоветуйте пожалуйста оптимальный алгоритм для обработки данных. |
не, тут нет никакого алгоритма. суть в том что в 0-й момент времени при включении дальномера если он покажет 1 вольт то хоть умри, а одно из 2-х значений не выбрать. аналогично если дальномером "сканируют" и наступает край препятствия - оно непонятно что значит 1 вольт даже если у нас есть безошибочная история значений.
нужен либо дублирующий дальномер с другими хар-ками или скажем чуть отодвинутый вглубь на 20 см. лично я бы просто сказал что дальномер с одним таким датчиком не пригоден мерить дистанции ближе 15 см, лучше поставить второй датчик имеющий более плоскую кривую на малых дистанциях. |
Tonny_Bennet, никак. По одному единственному значению, в условиях неоднозначности удаление объекта от наблюдателя не определить.
Тебе нужна либо вторая функция, и однозначная функция разности. Это может быть либо второй дальномер, либо несколько замеров дальности. Т.е. надо измерить окрестность точки, чтобы понять возрастает или убывает функция. Либо ввести условием измерение дальности от 15-20 сантиметров. Tonny_Bennet, расскажи, если можно, а в чем состоит глобальная задача? Робот "со зрением"? Манипулятор? |
Цитата:
Цитата:
Цитата:
Цитата:
В принципе вы ответили на мой вопрос и мне будет над чем задуматься. Спасибо. |
Ответили и хорошо. :) Просто сейчас несколько разовью и закончу мысль.
Раз мы говорим про колесное шасси, значит оно имеет свойство передвигаться. Значит у нас получается некоторый набор функций от дальномера. Под измерением окрестности точки я подразумевал множественный анализ дальности объекта. При движение взад-вперед +- 2,5 см можно определить, функция растет или убывает. Если с увеличением дальности функция растет, то объект лежит в пределах 15-20 см. Соотв. наоборот. Цитата:
Цитата:
Цитата:
в данный момент, как я понимаю шасси достаточно примитивно. Задачи которые обычно предъявляются к таким моделям -- самостоятельный объезд препятствий. Соотв. необходим анализ препятствий. И хорошо бы не просто знать о препятствии, но и знать его геометрическую форму. Т.е. производить сканирование пространства в полярной системе координат, и писать алгоритмы обсчета. А вот ту-у-ут возникает вопрос установки второго дальномера, также сканирующего пространство в полярной СК. При таком раскладе возникает масса интересных задач с приставкой стерео- и других. Уф. Мысль закончил! :) |
Цитата:
|
Tonny_Bennet, У тебя производная и значение по координате {y, dy/dx} однозначно определяют расстояние. Подбери аналитическую функцию - получишь модель для расчёта. Советую померять зависимость амплитуды шума, который даёт прибор от расстояния. Возможно окажется что на близких расстояниях шум больше - это поможет определиться стоя на месте, но затратив время. А в движении - как правильно сказал lxa85, твой робот должен паниковать, если при движении вперёд вольтаж резко падает.
|
Цитата:
Цитата:
Работая с оптическим дальномером я предполагал, что будет некоторая погрешность в измерениях до объектов разного цвета. Но то, что отличаться показания будут в несколько раз я не ждал. К примеру дальномер отградуированный на белый лист бумаги, с установленным препятствием чёрного цвета на 20 см показывает, что оно удалено на 35 сантиметров. Подумываю отказаться от этой затеи и воспользоваться ультразвуковым датчиком. |
Цитата:
Цитата:
1. В цикле записываешь N показаний y[i], взятых через одинаковый промежуток времени 2. Считаешь среднее M=sum(y[i], 0<i<N) /*псевдокод*/ 3. Считаешь дисперсию D=sum(pow(y[i]-M,2), 0<i<N) 4. Как правило "красивую" форму имеет ср.-кв. отклонение S=sqrt(D) Сделай несколько замеров с разным интервалом по времени между y[i] и с разными расстояниями, покажи графики, может что подскажем. |
Цитата:
И прав pva, надо искать некоторую аналитическую функцию т.к. объектов реального мира много. Они деревянные, железные, имеют собственную структуру, цвет, отражающие характеристики и т.д. Цитата:
Или пытаться анализировать отзвук и возвращаемую функцию. Обширнейшая теория звука в помощь! :) Tonny_Bennet, Слона едят по кусочкам. Создавай до крайней степени примитивную, но рабочую модель. Пусть она пока будет двигаться в "белом" пространстве. Будут проведены и готовы исследования -- ведешь "цветное" пространство. |
Цитата:
Цитата:
Цитата:
|
Цитата:
|
Контроллер можно настроить на автоматический опрос линии АЦП. Установил частоту опроса на 100 Гц. Устанавливал белое препятствие на расстоянии от 5 до 45 см с интервалом в 1 см. В цикле набирал по 1000 значений измерений. И дальше по алгоритму написал функцию расчёта дисперсии.
Код:
double[] compute_disperse(List<int> Y) ![]() |
В формуле дисперсии не хватает "поделить на N-1" (кажется я забыл это написать), поэтому отклонение на графике завышено в Sqrt(999) раз. Для качественного анализа это не смертельно.
1. Сглаживание лучше не делать, а просто отметить точки. На случайных данных сглаживание даёт сбивающие с толку эффекты. Сделай графики без сглаживания и без соединения точек. 2. Странно, что на 1000 точках отклонение так сильно прыгает. Можно посмотреть массивы в точках x=10 и x=15? Возможно там не гауссово распределение (например дальномер "видит" рисунок на припятсвии) 3. Функция отклика отличается от заявленной производителем (а может быть это эффект сглаживания) 4. Создаётся ощущение, что на дальних расстояниях шум выше Чтобы получить хорошие данные не особо себя затрудняя, можно поедположить, что медленное движение препятствия на дальномер не оказывает больших эффектов на статистику 1000-точечного замера. Тогда можно поставить АЦП на постоянную запись (сливать данные на винт, пусть в 2-мегабайтный файл) и с постоянной небольшой скоростью двигать препятствие на дальномер (с этим хорошо справится шаговый двигатель). Замерив время начала и окончания эксперимента, можно узнать скорость движения. Большой файл порезать на 2-килобайтные кусочки. В итоге всё сделает автоматика, а во время эсперимента можно пить чай. |
Цитата:
Цитата:
![]() Цитата:
1. установил препятствие на расстоянии L см 2. запустил сбор статистики измерений пока не наберётся N штук. 3. произвёл усреднение и рассчитал дисперсию по представленным формулам. 4. записал в файл 3 значения: L M D (расстояние до объекта, среднее значение измерений, дисперсия) Проделав данную процедуру 30 раз я получил набор значений (L M D) который построил в виде графика. Цитата:
Рисунка нет. Белый лист бумаги. Цитата:
Цитата:
|
Цитата:
Построил диаграмму. По оси абсцисс значения АЦП по оси ординат количество фиксаций данного события. ![]() |
Я имел в виду чтобы ты аттачил записанные файлы (семплы), я бы сам посмотрел нужные срезы :). Судя по гистограмме (подозреваю что это плотность распределения), распределение не нормальное, а лог-нормальное или что-то в этом роде. Похоже что на выходной сигнал дальномера где-то накладывается нелинейное усиление. Попробуй построить гистограмму плотности распределения от логарифма получаемых значений.
|
Цитата:
Цитата:
Цитата:
|
Цитата:
Стандартная процедура замеры плотности распределения такая (почти как ты описал): 1. записывается сигнал, дофига независимых отсчётов. 2. вещественная ось делится на равные отрезки (чем длинее отрезок - тем глаже, но меньше точек в гистограмме) 3. вычисляется сколько точек попали в каждый отрезок. Второй вариант (по смыслу то же самое): 1. дофига точек 2. Строится функция распределения = вероятность попадания числа в отрезок (-inf; x) как функция от x (сколько % точек меньше x). 3. плотность распределения - это производная функции распределения по x Цитата:
Снимать данные можно с любой частотой в диапазоне 100 - 10000 Гц (верх взял от балды, не принципиально). Нужно просто записать показания в файл (без обработки). Чем больше точек - тем представительней выборка. Советую от 1000 шт. Цитата:
Предположения не грозят, они могут помочь найти недостающий фактор, помогающий определить расстояние. |
на мой взгляд вы немного не в ту степь углубились. вообще измерение достаточно важное - оно показывает насколько хорошо работает датчик, но вообще графики странные получились.
вот почему - мат. ожидание соизмеримо с дисперсией. т.е. значение, которое точно соотносится с расстоянием (мат. ожидание), соизмеримо по размерам, если не больше, со средним размером ошибки (дисперсией). это фигово и так быть не должно, скорее всего ты неправильно посчитал дисперсию. вот почему - на рисунке с 10 см такой дисперсии явно нет - это факт. составь новые графики, возможно есть смысл увеличит на пару порядков замеры, уменьшив интервал между опросом (чтоб время не терять :-) ). ! но все это не поможет в проблемой перейти экстремум на графике вольты-расстояние. в коде программы для датчика эти данные бесполезны ибо поиск мат. ожидания для тебя будет всегда ибо один замер при поиске дистанции - лажа - тебе над делать больше. вот если бы там была некая нелинейность или какие нить особые места. п.с. с расстояние дисперсия по идеи должна расти. чем больше расстояние - тем больше шума набирает сигнал |
По поводу шаговых двигателей.
FDD. Там червячная передача, да и "платформа" уже имеется. Дальномер на ней закрепить и все. (габаритные размеры последнего не выяснял) |
Beyound, Дисперсия превышена в sqrt(999) раз - просто в формуле ошиблись. И с расстоянием может не расти, если это шум самого датчика или усилителя (пытаемся это выяснить). Если будет расти - это то, что нужно. Изначально по дисперсии планировалось отделить область до и после пика при замере дальности.
Цитата:
|
Вложений: 2
Цитата:
Цитата:
|
Цитата:
|
Вложений: 4
Цитата:
В общем, немного понятно, почему так прыгает дисперсия. При удалении от пика в низким напряждениям начинается совсем не гауссово поведение. 1. В сигнале присуствует независимая от расстояния периодическая помеха (возможно напряжение питания, но частота слишком низкая, около 20 Гц. Её можно увидеть по повторяющимся пикам на частотной диаграмме. 2. В области низких напряжений (см. quant.png) есть "дыры" (2 шт), в которые не попадают значения. Причём её форма зависит от дальности. Нужно посмотреть, как они ведут себя на разных расстояниях - возможно это тот фактор, который мы ищем. Ещё интересно, что происходит с областью низких напряжений при переходе через пик среднего значения напряжения при приближении к препятствию. Рекомендации будут такие: 1. определять расстояние не по среднему, а по моде (это точка, где максимальное значение плотности вероятности). 2. Пройтись по всему диапазону, можно снимать по 500 точек, и посмотреть, как ведёт себя область ниже моды. Должно быть хорошо видно на графике плотности (как bitmap.png), квантилей (quant.png), поведение периодической помехи может покажет фурье (fourier.png) или автокореляция (autocorr.png). у меня почему-то плотность распределния получилась гораздо симметричней, чем у тебя. Ты накладывал преобразование на данные? |
Цитата:
Цитата:
|
Цитата:
|
Столкнулся с проблемой.
Есть экземпляр ком-порта через который происходит обмен данными с модулем. Если я устанавливаю определённой командой автоопрос линии АЦП с заданной частотой, данные из модуля лезут сами. Добавляю обработчик событий ComPort.DataReceived += new SerialDataReceivedEventHandler(ComPort_DataReceived); в котором разбираю строки, пришедшие из порта и записываю данные в экземпляр некоторого класса Adc. Соответственно все расчёты (расстояния и т.д.) я провожу с экземпляром класса Adc. Что бы реализовать систему расчёта расстояния исходя не из текущего значения а из Цитата:
Код:
public int Value Написал новую процедуру расчёта расстояния. Она должна построить плотность распределения исходя из последних N измерений и найдя максимальное значение, посчитать и вернуть расстояние. Код:
Dictionary<int, int> chanals = new Dictionary<int, int>(); Подскажите пожалуйста в чём может быть проблема. |
Судя по коду ты используешь C#. Я в нём начинающий, могу на общих основаниях сказать что исключение может давать adc.HistValue[i], которую ты оба раза вызываешь.
Предлагаю изменить алгоритм таким образом: 1. Собираем статистику N точек (в обычный int[]) 2. Сортируем по возрастанию (обычный Array.sort<int>()) 3. Теперь задача найти самую длинную "горизонтальную палку" (обычный поиск максимума) Можно с уверенностью утверждать, что распределение унимодально, и что мода достаточно сосредоточенная, поэтому можно смело отбрасывать "палки" короче какого-то заранее заданного процента от N (надо подобрать на глаз). Этих палок скорее всего не больше 2-х. Можно даже сделать сглаживание: расположить между этими палками, согласно отношению их длин. |
Цитата:
У специалистов бы проконсультироваться... Цитата:
|
Извратился, пытаясь проверять на оба исключения...
Код:
try Периодически всё же возникает то одно то другое исключение. Понять почему оно появляется я не могу :( |
Вы ее в режиме отладки запустите и пошагово пройдите
и посмотрите какие значения |
Цитата:
По поводу украшения кода: неужели в данном случае код стал проще/быстрее/понятней/надёжней? |
Цитата:
Код:
if(chanals.Exists(adc.HistValue[i])) {} |
Цитата:
Код:
if(chanals.ContainsKey(adc.HistValue[i])) {} |
Цитата:
Цитата:
Цитата:
Прикрепляю скриншот окна студии. ![]() |
а зачем вы сделали ключом adc.HistValue[i], может лучше сделать ключом i, а adc.HistValue[i] - значением
|
Цитата:
В массиве HistValue хранятся последние N значений измерений. К примеру: 0371 0372 0351 0372 0372 0372 0371 0371 0371 0304 0372 0371 0371 0371 0371 И мне нужно посчитать сколько раз из N выпадало 371, сколько раз выпадало 372 и т.д. Поэтому я последовательно перебираю все значения из массива, и если ключ не создан я создаю пару из HistValue[i] и 1, если ключ уже был создан я просто увеличиваю значение на 1. Когда перебор окончен я ищу максимальное значение и узнаю какому ключу это значение соответствует. |
Цитата:
Но не понятно, что происходит на скриншоте, выглядит как будто значения в HistValue меняются на ходу попробуйте создать в функции массив в него скопировать HistValue и работать с этим массивом |
Цитата:
В таком случае получается, что во время вызова процедуры передаётся ссылка на объект а не копия объекта??? |
Цитата:
http://msdn.microsoft.com/ru-ru/libr...(v=vs.90).aspx |
Цитата:
Я как то всегда думал, что передавая объект методу в него попадает копия. Есть ли какой-нибудь механизм защиты от подобных проблем? ...редко приходится осмысливать и принимать фундаментальные изменения в восприятии мира :wow: |
Время: 13:19. |
Время: 13:19.
© OSzone.net 2001-