Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Выбор значения многозначной функции (http://forum.oszone.net/showthread.php?t=238295)

Tonny_Bennet 10-07-2012 13:51 1949271

Выбор значения многозначной функции
 
Здравствуйте.

Существует ИК дальномер SHARP, который можно подключить к ЦАП и в зависимости от расстояния до объекта будет изменяться напряжение на выходе дальномера. Зависимость напряжения не только нелинейная, но и с "крохотным" изъяном :



Отградуировав свой дальномер я получил похожую зависимость и пока у меня нет предположений как можно грамотно обработать получаемые данные. К примеру получив на выходе 1 Вольт, по графику видно что функция имеет два значения расстояния: 5 см и 65 см. Как вы наверное понимаете препятствие может возникнуть как на 5 так и на 65 сантиметрах. Отслеживать предыдущее значение расстояния по-моему неправильно из-за некоторого количества ошибок самого дальномера.

Посоветуйте пожалуйста оптимальный алгоритм для обработки данных.

Beyound 10-07-2012 18:50 1949429

не, тут нет никакого алгоритма. суть в том что в 0-й момент времени при включении дальномера если он покажет 1 вольт то хоть умри, а одно из 2-х значений не выбрать. аналогично если дальномером "сканируют" и наступает край препятствия - оно непонятно что значит 1 вольт даже если у нас есть безошибочная история значений.
нужен либо дублирующий дальномер с другими хар-ками или скажем чуть отодвинутый вглубь на 20 см. лично я бы просто сказал что дальномер с одним таким датчиком не пригоден мерить дистанции ближе 15 см, лучше поставить второй датчик имеющий более плоскую кривую на малых дистанциях.

lxa85 10-07-2012 19:18 1949451

Tonny_Bennet, никак. По одному единственному значению, в условиях неоднозначности удаление объекта от наблюдателя не определить.
Тебе нужна либо вторая функция, и однозначная функция разности. Это может быть либо второй дальномер, либо несколько замеров дальности.
Т.е. надо измерить окрестность точки, чтобы понять возрастает или убывает функция.
Либо ввести условием измерение дальности от 15-20 сантиметров.
Tonny_Bennet, расскажи, если можно, а в чем состоит глобальная задача? Робот "со зрением"? Манипулятор?

Tonny_Bennet 10-07-2012 23:04 1949633

Цитата:

Цитата Beyound
лучше поставить второй датчик имеющий более плоскую кривую на малых дистанциях. »

В принципе резонно, но пока есть толкьо один датчик. Будем крутиться как получится :)

Цитата:

Цитата lxa85
Это может быть либо второй дальномер, либо несколько замеров дальности.
Т.е. надо измерить окрестность точки, чтобы понять возрастает или убывает функция. »

В этом случае прийдётся изменить положение дальномера что-бы промерить окрестности точки... да и промерив окрестность получу я снова тот самый 1 Вольт и буду дальше думать какое там расстояние ;)

Цитата:

Цитата lxa85
Либо ввести условием измерение дальности от 15-20 сантиметров. »

Правильно ли я понял, что если дальномер засунуть в некоторую трубу длинной 20 см, тем самым физически ограничить приближение объектов к дальномеру можно полностью доверять его показаниям. Костыль достойный верстальщика под IE ;)

Цитата:

Цитата lxa85
в чем состоит глобальная задача? Робот "со зрением"? Манипулятор? »

Хочу собрать платформу на колёсном шасси, с wi-fi модулем, камерой и монитором. В планах управление с Android-устройства.

В принципе вы ответили на мой вопрос и мне будет над чем задуматься. Спасибо.

lxa85 11-07-2012 00:37 1949669

Ответили и хорошо. :) Просто сейчас несколько разовью и закончу мысль.
Раз мы говорим про колесное шасси, значит оно имеет свойство передвигаться. Значит у нас получается некоторый набор функций от дальномера.
Под измерением окрестности точки я подразумевал множественный анализ дальности объекта. При движение взад-вперед +- 2,5 см можно определить, функция растет или убывает. Если с увеличением дальности функция растет, то объект лежит в пределах 15-20 см. Соотв. наоборот.
Цитата:

Цитата Tonny_Bennet
Правильно ли я понял, что если дальномер засунуть в некоторую трубу длинной 20 см, тем самым физически ограничить приближение объектов к дальномеру можно полностью доверять его показаниям. »

Совершенно верно.
Цитата:

Цитата Tonny_Bennet
Костыль достойный верстальщика под IE »

Ни, такой гадостью мы не занимались. :) Просто практика создания костылей, без IE. :)
Цитата:

Цитата Tonny_Bennet
Хочу собрать платформу на колёсном шасси, с wi-fi модулем, камерой и монитором. »

В развитие темы:
в данный момент, как я понимаю шасси достаточно примитивно. Задачи которые обычно предъявляются к таким моделям -- самостоятельный объезд препятствий. Соотв. необходим анализ препятствий. И хорошо бы не просто знать о препятствии, но и знать его геометрическую форму. Т.е. производить сканирование пространства в полярной системе координат, и писать алгоритмы обсчета.
А вот ту-у-ут возникает вопрос установки второго дальномера, также сканирующего пространство в полярной СК. При таком раскладе возникает масса интересных задач с приставкой стерео- и других.

Уф. Мысль закончил! :)

Tonny_Bennet 11-07-2012 10:30 1949786

Цитата:

Цитата lxa85
в данный момент, как я понимаю шасси достаточно примитивно. Задачи которые обычно предъявляются к таким моделям -- самостоятельный объезд препятствий. Соотв. необходим анализ препятствий. И хорошо бы не просто знать о препятствии, но и знать его геометрическую форму. Т.е. производить сканирование пространства в полярной системе координат, и писать алгоритмы обсчета.
А вот ту-у-ут возникает вопрос установки второго дальномера, также сканирующего пространство в полярной СК. При таком раскладе возникает масса интересных задач с приставкой стерео- и других.
Уф. Мысль закончил! »

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

pva 12-07-2012 00:38 1950341

Tonny_Bennet, У тебя производная и значение по координате {y, dy/dx} однозначно определяют расстояние. Подбери аналитическую функцию - получишь модель для расчёта. Советую померять зависимость амплитуды шума, который даёт прибор от расстояния. Возможно окажется что на близких расстояниях шум больше - это поможет определиться стоя на месте, но затратив время. А в движении - как правильно сказал lxa85, твой робот должен паниковать, если при движении вперёд вольтаж резко падает.

Tonny_Bennet 12-07-2012 17:15 1950744

Цитата:

Цитата pva
Советую померять зависимость амплитуды шума, который даёт прибор от расстояния. »

Что есть "амплитуда шума"?

Цитата:

Цитата pva
А в движении - как правильно сказал lxa85, твой робот должен паниковать, если при движении вперёд вольтаж резко падает. »

Эту часть я уже прописал :) Спасибо.

Работая с оптическим дальномером я предполагал, что будет некоторая погрешность в измерениях до объектов разного цвета. Но то, что отличаться показания будут в несколько раз я не ждал. К примеру дальномер отградуированный на белый лист бумаги, с установленным препятствием чёрного цвета на 20 см показывает, что оно удалено на 35 сантиметров.

Подумываю отказаться от этой затеи и воспользоваться ультразвуковым датчиком.

pva 12-07-2012 21:10 1950893

Цитата:

Цитата Tonny_Bennet
Подумываю отказаться от этой затеи »

Не спеши, отказаться всегда успеешь. При движении можешь поделить изменение расстояния на скорость движения - тогда получишь информацию о цвете. И это только дальномером!
Цитата:

Цитата Tonny_Bennet
"амплитуда шума"? »

Под амплитудой шума я понимаю среднеквадратичное отклонение показаний, снятых в одном и том же положении. Конечно же имеет практический смысл считать только среднее за определённый период времени:
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] и с разными расстояниями, покажи графики, может что подскажем.

lxa85 12-07-2012 21:14 1950896

Цитата:

Цитата Tonny_Bennet
Работая с оптическим дальномером я предполагал, что будет некоторая погрешность в измерениях до объектов разного цвета. Но то, что отличаться показания будут в несколько раз я не ждал. К примеру дальномер отградуированный на белый лист бумаги, с установленным препятствием чёрного цвета на 20 см показывает, что оно удалено на 35 сантиметров. »

Аааа! :) А я хотел спросить про цветность объектов, но видать оставил вопрос на потом и благополучно забыл.
И прав pva, надо искать некоторую аналитическую функцию т.к. объектов реального мира много. Они деревянные, железные, имеют собственную структуру, цвет, отражающие характеристики и т.д.
Цитата:

Цитата Tonny_Bennet
Подумываю отказаться от этой затеи и воспользоваться ультразвуковым датчиком. »

Различные коэф. поглощения звука? Ковер, ножка стола(дерево), бетон, различные типы обоев на стене?
Или пытаться анализировать отзвук и возвращаемую функцию. Обширнейшая теория звука в помощь! :)
Tonny_Bennet, Слона едят по кусочкам. Создавай до крайней степени примитивную, но рабочую модель. Пусть она пока будет двигаться в "белом" пространстве. Будут проведены и готовы исследования -- ведешь "цветное" пространство.

Tonny_Bennet 12-07-2012 22:52 1950930

Цитата:

Цитата pva
Под амплитудой шума я понимаю среднеквадратичное отклонение показаний, снятых в одном и том же положении. Конечно же имеет практический смысл считать только среднее за определённый период времени:
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] и с разными расстояниями, покажи графики, может что подскажем. »

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

Цитата:

Цитата lxa85
Различные коэф. поглощения звука? Ковер, ножка стола(дерево), бетон, различные типы обоев на стене?
Или пытаться анализировать отзвук и возвращаемую функцию. Обширнейшая теория звука в помощь! »

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

Цитата:

Цитата lxa85
Слона едят по кусочкам. Создавай до крайней степени примитивную, но рабочую модель. Пусть она пока будет двигаться в "белом" пространстве. Будут проведены и готовы исследования -- ведешь "цветное" пространство. »

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

lxa85 13-07-2012 00:38 1950969

Цитата:

Цитата Tonny_Bennet
Но в то же время чтобы всё проверить приходится отдаляться от основной идеи. »

Скажу по секрету - в том и есть "Наука" :crazy: :)

Tonny_Bennet 13-07-2012 13:03 1951202

Контроллер можно настроить на автоматический опрос линии АЦП. Установил частоту опроса на 100 Гц. Устанавливал белое препятствие на расстоянии от 5 до 45 см с интервалом в 1 см. В цикле набирал по 1000 значений измерений. И дальше по алгоритму написал функцию расчёта дисперсии.

Код:

        double[] compute_disperse(List<int> Y)
        {
            int[] y =  Y.ToArray();

            double M = 0;

            for (int i=0; i< y.Length;i++)
            {
                M += y[i];
            }

            M = M / y.Length;

            double D = 0;

            for (int i=0; i< y.Length; i++)
            {
                D += Math.Pow(y[i] - M,2);
            }

            return new double[] { M, Math.Sqrt(D) };
        }

Построил график в программе AdvancedGrapher. Применил сглаживание. Зелёная линия это арифметическое среднее. Красная - дисперсия. По оси абсцисс расстояние. По оси ординат значения в некоторых единицах АЦП (можно однозначно перевести в вольты).

pva 13-07-2012 14:46 1951269

В формуле дисперсии не хватает "поделить на N-1" (кажется я забыл это написать), поэтому отклонение на графике завышено в Sqrt(999) раз. Для качественного анализа это не смертельно.

1. Сглаживание лучше не делать, а просто отметить точки. На случайных данных сглаживание даёт сбивающие с толку эффекты. Сделай графики без сглаживания и без соединения точек.
2. Странно, что на 1000 точках отклонение так сильно прыгает. Можно посмотреть массивы в точках x=10 и x=15? Возможно там не гауссово распределение (например дальномер "видит" рисунок на припятсвии)
3. Функция отклика отличается от заявленной производителем (а может быть это эффект сглаживания)
4. Создаётся ощущение, что на дальних расстояниях шум выше

Чтобы получить хорошие данные не особо себя затрудняя, можно поедположить, что медленное движение препятствия на дальномер не оказывает больших эффектов на статистику 1000-точечного замера. Тогда можно поставить АЦП на постоянную запись (сливать данные на винт, пусть в 2-мегабайтный файл) и с постоянной небольшой скоростью двигать препятствие на дальномер (с этим хорошо справится шаговый двигатель). Замерив время начала и окончания эксперимента, можно узнать скорость движения. Большой файл порезать на 2-килобайтные кусочки. В итоге всё сделает автоматика, а во время эсперимента можно пить чай.

Tonny_Bennet 13-07-2012 15:14 1951285

Цитата:

Цитата pva
В формуле дисперсии не хватает "поделить на N-1" (кажется я забыл это написать), поэтому отклонение на графике завышено в Sqrt(999) раз. Для качественного анализа это не смертельно. »

В своём коде я делил на N.

Цитата:

Цитата pva
1. Сглаживание лучше не делать, а просто отметить точки. На случайных данных сглаживание даёт сбивающие с толку эффекты. Сделай графики без сглаживания и без соединения точек. »



Цитата:

Цитата pva
2. Странно, что на 1000 точках отклонение так сильно прыгает. Можно посмотреть массивы в точках x=10 и x=15? Возможно там не гауссово распределение (например дальномер "видит" рисунок на припятсвии) »

Хм, может я не правильно понял. Просто постараюсь ещё раз описать свои действия:

1. установил препятствие на расстоянии L см
2. запустил сбор статистики измерений пока не наберётся N штук.
3. произвёл усреднение и рассчитал дисперсию по представленным формулам.
4. записал в файл 3 значения: L M D (расстояние до объекта, среднее значение измерений, дисперсия)

Проделав данную процедуру 30 раз я получил набор значений (L M D) который построил в виде графика.

Цитата:

Цитата pva
Можно посмотреть массивы в точках x=10 и x=15? Возможно там не гауссово распределение (например дальномер "видит" рисунок на припятсвии) »

Т.е. стоит посмотреть на распределение экспериментальных данных при измерении в одной точке?
Рисунка нет. Белый лист бумаги.

Цитата:

Цитата pva
3. Функция отклика отличается от заявленной производителем (а может быть это эффект сглаживания) »

В первом посте я просто взял картинку из даташита другого оптического дальномера. Вид линии совпадает с оригиналом и я не считаю это каким-либо отклонением.

Цитата:

Цитата pva
Чтобы получить хорошие данные не особо себя затрудняя, можно поедположить, что медленное движение препятствия на дальномер не оказывает больших эффектов на статистику 1000-точечного замера. Тогда можно поставить АЦП на постоянную запись (сливать данные на винт, пусть в 2-мегабайтный файл) и с постоянной небольшой скоростью двигать препятствие на дальномер (с этим хорошо справится шаговый двигатель). Замерив время начала и окончания эксперимента, можно узнать скорость движения. Большой файл порезать на 2-килобайтные кусочки. В итоге всё сделает автоматика, а во время эсперимента можно пить чай. »

Отличный вариант но вот шагового двигателя у меня нету :(

Tonny_Bennet 13-07-2012 16:09 1951310

Цитата:

Цитата pva
Можно посмотреть массивы в точках x=10 и x=15? »

Установил препятствие на 10 см.

Построил диаграмму. По оси абсцисс значения АЦП по оси ординат количество фиксаций данного события.


pva 13-07-2012 20:59 1951444

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

Tonny_Bennet 14-07-2012 13:03 1951628

Цитата:

Цитата pva
Я имел в виду чтобы ты аттачил записанные файлы (семплы), я бы сам посмотрел нужные срезы »

На каких расстояниях записать?

Цитата:

Цитата pva
Судя по гистограмме (подозреваю что это плотность распределения), распределение не нормальное, а лог-нормальное или что-то в этом роде. »

Я не могу сказать как это называется, но могу ещё раз рассказать как я получил эту гистрограмму. Я установил препятствие на 10 см. Запустил опрос датчика и смотрел сколько раз из 1000 будет появляться то или иное значение. Соответственно записывал количество регистраций значения Чем выше палочка тем больше раз выпадало это значение. На данном примере значение 368 регистрировалось 637 раз из тысячи. А значение 369 - 173 раза из тысячи.

Цитата:

Цитата pva
Похоже что на выходной сигнал дальномера где-то накладывается нелинейное усиление. »

Откуда такие предположения и чем они мне грозят?

pva 14-07-2012 21:35 1951873

Цитата:

Цитата Tonny_Bennet
Я не могу сказать как это называется, но могу ещё раз рассказать как я получил эту гистрограмму. Я установил препятствие на 10 см. Запустил опрос датчика и смотрел сколько раз из 1000 будет появляться то или иное значение. »

немного теории чисто чтобы знать как это называется:
Стандартная процедура замеры плотности распределения такая (почти как ты описал):
1. записывается сигнал, дофига независимых отсчётов.
2. вещественная ось делится на равные отрезки (чем длинее отрезок - тем глаже, но меньше точек в гистограмме)
3. вычисляется сколько точек попали в каждый отрезок.
Второй вариант (по смыслу то же самое):
1. дофига точек
2. Строится функция распределения = вероятность попадания числа в отрезок (-inf; x) как функция от x (сколько % точек меньше x).
3. плотность распределения - это производная функции распределения по x

Цитата:

Цитата Tonny_Bennet
На каких расстояниях записать? »

Мне понравились расстояния 10 и 15 см, потому что там явный скачок и провал ср-кв. отклонения. В идеале было бы хорошо посмотреть "типичный" сингал и "сильное отклонение от нормы", а расстояние любое от 10 до 30 см.

Снимать данные можно с любой частотой в диапазоне 100 - 10000 Гц (верх взял от балды, не принципиально). Нужно просто записать показания в файл (без обработки). Чем больше точек - тем представительней выборка. Советую от 1000 шт.

Цитата:

Цитата Tonny_Bennet
Откуда такие предположения и чем они мне грозят? »

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

Beyound 15-07-2012 20:38 1952303

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

lxa85 15-07-2012 21:41 1952343

По поводу шаговых двигателей.
FDD. Там червячная передача, да и "платформа" уже имеется.
Дальномер на ней закрепить и все. (габаритные размеры последнего не выяснял)

pva 15-07-2012 23:33 1952408

Beyound, Дисперсия превышена в sqrt(999) раз - просто в формуле ошиблись. И с расстоянием может не расти, если это шум самого датчика или усилителя (пытаемся это выяснить). Если будет расти - это то, что нужно. Изначально по дисперсии планировалось отделить область до и после пика при замере дальности.
Цитата:

Цитата lxa85
FDD »

матричный принтер круче (формата a3 особенно)!

Tonny_Bennet 16-07-2012 11:11 1952644

Вложений: 2
Цитата:

Цитата pva
Стандартная процедура замеры плотности распределения такая (почти как ты описал):
1. записывается сигнал, дофига независимых отсчётов.
2. вещественная ось делится на равные отрезки (чем длинее отрезок - тем глаже, но меньше точек в гистограмме)
3. вычисляется сколько точек попали в каждый отрезок. »

Учитывая что значения строго дискретны у меня и получилось плотность распределения.

Цитата:

Цитата pva
Мне понравились расстояния 10 и 15 см, потому что там явный скачок и провал ср-кв. отклонения. В идеале было бы хорошо посмотреть "типичный" сингал и "сильное отклонение от нормы", а расстояние любое от 10 до 30 см. »

Прикрепляю измерения на 10 и 15 см. Частота измерений 200 Гц. Набирал до 3000 событий.

Tonny_Bennet 16-07-2012 11:14 1952648

Цитата:

Цитата pva
Дисперсия превышена в sqrt(999) раз - просто в формуле ошиблись »

В том месте где среднее неправильно посчитали?

pva 16-07-2012 16:56 1952891

Вложений: 4
Цитата:

Цитата Tonny_Bennet
В том месте где среднее неправильно посчитал »

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

1. В сигнале присуствует независимая от расстояния периодическая помеха (возможно напряжение питания, но частота слишком низкая, около 20 Гц. Её можно увидеть по повторяющимся пикам на частотной диаграмме.
2. В области низких напряжений (см. quant.png) есть "дыры" (2 шт), в которые не попадают значения. Причём её форма зависит от дальности. Нужно посмотреть, как они ведут себя на разных расстояниях - возможно это тот фактор, который мы ищем. Ещё интересно, что происходит с областью низких напряжений при переходе через пик среднего значения напряжения при приближении к препятствию.

Рекомендации будут такие:
1. определять расстояние не по среднему, а по моде (это точка, где максимальное значение плотности вероятности).
2. Пройтись по всему диапазону, можно снимать по 500 точек, и посмотреть, как ведёт себя область ниже моды. Должно быть хорошо видно на графике плотности (как bitmap.png), квантилей (quant.png), поведение периодической помехи может покажет фурье (fourier.png)
или автокореляция (autocorr.png).


у меня почему-то плотность распределния получилась гораздо симметричней, чем у тебя. Ты накладывал преобразование на данные?

Tonny_Bennet 17-07-2012 10:19 1953338

Цитата:

Цитата pva
1. определять расстояние не по среднему, а по моде (это точка, где максимальное значение плотности вероятности). »

Для этого нужно набирать некоторую статистику в момент измерения. У меня начали возникать некоторые проблемы с алгоритмом. Немного позже подробнее расскажу в чём именно.

Цитата:

Цитата pva
2. Пройтись по всему диапазону, можно снимать по 500 точек, и посмотреть, как ведёт себя область ниже моды. »

Потребуется некоторое время для измерений.

Tonny_Bennet 17-07-2012 10:36 1953349

Цитата:

Цитата pva
у меня почему-то плотность распределния получилась гораздо симметричней, чем у тебя. Ты накладывал преобразование на данные? »

Нет, преобразований не делал

Tonny_Bennet 18-07-2012 12:26 1954150

Столкнулся с проблемой.

Есть экземпляр ком-порта через который происходит обмен данными с модулем. Если я устанавливаю определённой командой автоопрос линии АЦП с заданной частотой, данные из модуля лезут сами. Добавляю обработчик событий ComPort.DataReceived += new SerialDataReceivedEventHandler(ComPort_DataReceived); в котором разбираю строки, пришедшие из порта и записываю данные в экземпляр некоторого класса Adc. Соответственно все расчёты (расстояния и т.д.) я провожу с экземпляром класса Adc. Что бы реализовать систему расчёта расстояния исходя не из текущего значения а из

Цитата:

Цитата pva
определять расстояние не по среднему, а по моде (это точка, где максимальное значение плотности вероятности). »

Я решил добавить в класс очередь в которой хранить последние N значений.

Код:

        public int Value
        {
            get { return _value; }
            set
            {
                _value = value;
                if (_hist_of_value.Count >= 1000)
                {
                    var a = _hist_of_value.Dequeue();
                }
                _hist_of_value.Enqueue(value);
            }
        }

        private Queue<int> _hist_of_value = new Queue<int>(1000);
     
        public int[] HistValue
        {
            get
            {
                return _hist_of_value.ToArray();
            }
        }

Добавил поле, которое должно вернуть последние значения в виде целочисленного массива.

Написал новую процедуру расчёта расстояния. Она должна построить плотность распределения исходя из последних N измерений и найдя максимальное значение, посчитать и вернуть расстояние.

Код:

  Dictionary<int, int> chanals = new Dictionary<int, int>();

                for (int i = 0; i < adc.HistValue.Length; i++)
                {

                    try
                    {
                        chanals[adc.HistValue[i]] += 1;
                    }
                    catch (KeyNotFoundException)
                    {
                        chanals.Add(adc.HistValue[i], 1);
                    }

                }

При запуску стали возникать ошибки в месте chanals.Add(adc.HistValue[i], 1); " Элемент с тем же ключом уже был добавлен." У меня и сейчас мало предположений почему если нет ключа процедура отработала блок try {} и потом вызвала ошибку. Единственное, что может прийти в голову так это то, что в процедуру подсчёта расстояния передаётся ссылка на объект Adc а не его копия на момент вызова, и за время проверки try {} объект успевает измениться и возникает исключение.

Подскажите пожалуйста в чём может быть проблема.

pva 18-07-2012 22:02 1954493

Судя по коду ты используешь C#. Я в нём начинающий, могу на общих основаниях сказать что исключение может давать adc.HistValue[i], которую ты оба раза вызываешь.

Предлагаю изменить алгоритм таким образом:
1. Собираем статистику N точек (в обычный int[])
2. Сортируем по возрастанию (обычный Array.sort<int>())
3. Теперь задача найти самую длинную "горизонтальную палку" (обычный поиск максимума)
Можно с уверенностью утверждать, что распределение унимодально, и что мода достаточно сосредоточенная, поэтому можно смело отбрасывать "палки" короче какого-то заранее заданного процента от N (надо подобрать на глаз). Этих палок скорее всего не больше 2-х. Можно даже сделать сглаживание: расположить между этими палками, согласно отношению их длин.

Tonny_Bennet 19-07-2012 00:00 1954555

Цитата:

Цитата pva
Судя по коду ты используешь C#. Я в нём начинающий, могу на общих основаниях сказать что исключение может давать adc.HistValue[i], которую ты оба раза вызываешь. »

Да это С#.... и по-моему здесь проблема из-за того, что одну переменную изменяют в разных потоках... (по моему чтение из ком-порта это отдельный поток)
У специалистов бы проконсультироваться...

Цитата:

Цитата pva
Предлагаю изменить алгоритм таким образом:
1. Собираем статистику N точек (в обычный int[])
2. Сортируем по возрастанию (обычный Array.sort<int>())
3. Теперь задача найти самую длинную "горизонтальную палку" (обычный поиск максимума) »

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

Tonny_Bennet 19-07-2012 15:01 1954845

Извратился, пытаясь проверять на оба исключения...

Код:

                try
                {
                    chanals[adc.HistValue[i]] += 1;
                }
                catch (KeyNotFoundException)
                {
                    try
                    {
                        chanals.Add(adc.HistValue[i], 1);
                    }
                    catch(ArgumentException)
                    {
                        chanals[adc.HistValue[i]] += 1;
                    }
                }


Периодически всё же возникает то одно то другое исключение. Понять почему оно появляется я не могу :(

ferget 19-07-2012 17:20 1954936

Вы ее в режиме отладки запустите и пошагово пройдите

и посмотрите какие значения

pva 19-07-2012 21:51 1955050

Цитата:

Цитата ferget
Вы ее в режиме отладки запустите »

В этом случае в ком-порт может вывалиться кака. Лучше записать данные из порта в файл, и запустить отладку на данных из файла. Мой любимый метод: вывалить в файл, загрузить в мат.пакет и изголяться над данными в поисках истины.

По поводу украшения кода: неужели в данном случае код стал проще/быстрее/понятней/надёжней?

Delirium 20-07-2012 02:12 1955143

Цитата:

Цитата Tonny_Bennet
chanals.Add(adc.HistValue[i], 1); " Элемент с тем же ключом уже был добавлен." »

Что, если проверять перед добавлением, типа
Код:

if(chanals.Exists(adc.HistValue[i])) {}
Или подобного функционала нет?

ferget 20-07-2012 08:06 1955195

Цитата:

Цитата Delirium
Или подобного функционала нет? »

есть

Код:

if(chanals.ContainsKey(adc.HistValue[i])) {}

Tonny_Bennet 20-07-2012 12:59 1955401

Цитата:

Цитата pva
В этом случае в ком-порт может вывалиться кака. Лучше записать данные из порта в файл, и запустить отладку на данных из файла. Мой любимый метод: вывалить в файл, загрузить в мат.пакет и изголяться над данными в поисках истины. »

Попробую.

Цитата:

Цитата Delirium
Что, если проверять перед добавлением, типа
Код:
if(chanals.Exists(adc.HistValue[i])) {}
Или подобного функционала нет? »

Цитата:

Цитата ferget
есть
Код:
if(chanals.ContainsKey(adc.HistValue[i])) {} »

Спасибо за советы. Делал по примеру из MSDN а там был с try {} catch () {}. Переделал на проверку с блоком if. Всё равно периодически возникает Исключение.
Прикрепляю скриншот окна студии.

ferget 20-07-2012 14:06 1955466

а зачем вы сделали ключом adc.HistValue[i], может лучше сделать ключом i, а adc.HistValue[i] - значением

Tonny_Bennet 20-07-2012 14:21 1955475

Цитата:

Цитата ferget
а зачем вы сделали ключом 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. Когда перебор окончен я ищу максимальное значение и узнаю какому ключу это значение соответствует.

ferget 20-07-2012 14:41 1955488

Цитата:

Цитата Tonny_Bennet
И мне нужно посчитать сколько раз из N выпадало 371, сколько раз выпадало 372 и т.д. Поэтому я последовательно перебираю все значения из массива, и если ключ не создан я создаю пару из HistValue[i] и 1, если ключ уже был создан я просто увеличиваю значение на 1. Когда перебор окончен я ищу максимальное значение и узнаю какому ключу это значение соответствует. »

Спасибо, понятно

Но не понятно, что происходит на скриншоте, выглядит как будто значения в HistValue меняются на ходу

попробуйте создать в функции массив в него скопировать HistValue и работать с этим массивом

Tonny_Bennet 20-07-2012 15:14 1955514

Цитата:

Цитата ferget
Но не понятно, что происходит на скриншоте, выглядит как будто значения в HistValue меняются на ходу
попробуйте создать в функции массив в него скопировать HistValue и работать с этим массивом »

Скопировал. Вроде работает нормально.

В таком случае получается, что во время вызова процедуры передаётся ссылка на объект а не копия объекта???

ferget 20-07-2012 16:04 1955557

Цитата:

Цитата Tonny_Bennet
В таком случае получается, что во время вызова процедуры передаётся ссылка на объект а не копия объекта??? »

Классы относятся к ссылочным типам
http://msdn.microsoft.com/ru-ru/libr...(v=vs.90).aspx

Tonny_Bennet 20-07-2012 17:08 1955608

Цитата:

Цитата ferget
Классы относятся к ссылочным типам
http://msdn.microsoft.com/ru-ru/libr...(v=vs.90).aspx »

Хм.... т.е. передавая объект созданного мною класса в качестве параметра некоторому методу, метод будет работать неоднозначно, если в процессе работы метода переданный объект изменяется.

Я как то всегда думал, что передавая объект методу в него попадает копия.

Есть ли какой-нибудь механизм защиты от подобных проблем?

...редко приходится осмысливать и принимать фундаментальные изменения в восприятии мира :wow:


Время: 13:19.

Время: 13:19.
© OSzone.net 2001-