roboforum.ru

Технический форум по робототехнике.

Точная генерация PWM на Линуксе

Точная генерация PWM на Линуксе

andreynech » 06 сен 2011, 17:22

Народ, посетила меня проблема, может кто-нибудь сталкивался уже с чем-то похожим или просто может высказать соображения... Буду очень признателен!

Я делаю танчик на борту у которого стоит BeagleBoard (beagleboard.org) с Линуксом. К ней подключен wlan, usb-камера, usb gps мышка и через I2C компас и сонар. Видео компримируется и шлется по сети "водителю". Т.е можно ездить через Интернет. Это всё вобщем работает...

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

Эту проблему часто решают на микроконтроллере. Но посмотрев на то, что у меня максимальная загрузка проца не BeagleBoard-e (ВВ) не превышает 70% я подумал, что жалко не использовать такие вычислительные ресурсы. Поэтому решил попробовать реализовать общение с сенсорами и моторами полностью на ВВ.

Но Линукс не real-time система, поэтому я решил использовать Xenomai.org для real-time части. В качестве теста, решил поупрвлять стандартным серво мотором с помощью PWM которые генеряться через GPIO pin программой работающей на ВВ.

Вот тут собственно я и наткнулся на проблему - при загруженной системе, серво начинает дергаться. Это явно признак того, что PWM-ы генеряться не точно. Честно-говоря, я не могу себе представить, что даже при загрузке в 60%-70% 600MHz ARM не в состоянии сгенерить точно сигналы в миллисекундном диапазоне (импульсы должны идти с интервалом 20мс и ширина 1-2мс). Я сильно надеюсь, что можно что-нибудь подкрутить в Линуксе или Xenomai чтобы добиться большей точности.

В связи с этим вопрос - нет ли у кого-нибудь опыта работы с Линукс/Xenomai или вообще опыта решения аналогичных проблем. Я написал более подробный блог по поводу этой проблемы (на английском). Тамже можно почитать подробности про проект.

Еще мне было бы интересно услышать мнение по поводу общей идеи избавиться от микроконтроллера. Может я зря заморачиваюсь с этим? Основным аргументом для меня является надежда на то, что таким образом я смогу упростить всю систему и эффективнее использовать имеющиеся вычислительные ресурсы. Т.е. не надо будет интегрировить компилятор и библиотеки для микроконтроллера в систему построения всего проекта (Makefile-ы и т.д), не надо будет организовывать какое-то общение между МК и ВВ, что в свою очередь упростит железки и программу. Ну и в добавок вес, цена и занимаемое место тоже сократится.

Вобщем, буду признателен за любые соображения на эту тему.


Андрей.

Re: Точная генерация PWM на Линуксе

Strijar » 06 сен 2011, 20:14

Написать свой драйвер pwm который будет выдерживать точно длинну импульса с помощью udelay(). Правда в это время процессор будет именно простаивать - но зато точно.

Хотя можно попробовать и без udelay - но нет гарантии что при сильной загрузке будет работать гарантированно. Какая там тактовая? Может и хватит.
Последний раз редактировалось Strijar 06 сен 2011, 20:17, всего редактировалось 2 раз(а).

Re: Точная генерация PWM на Линуксе

Michael_K » 06 сен 2011, 20:14

andreynech писал(а):Честно-говоря, я не могу себе представить, что даже при загрузке в 60%-70% 600MHz ARM не в состоянии сгенерить точно сигналы в миллисекундном диапазоне

Вы и сами прекрасно понимаете, что проблема не в арме, а в оси.
Я не знаю, как именно организовано в ксеномай и тем более, как вы реализуете работу с ШИМом.
Вероятно у оси есть какие-то тайм-слайсы, которые на порядок больше необходимой вам точности или что-то в таком духе.

andreynech писал(а):Еще мне было бы интересно услышать мнение по поводу общей идеи избавиться от микроконтроллера. Может я зря заморачиваюсь с этим?

Зря заморачиваетесь с этим.
Если не хотите компиляторов-мейк-файлов и т.п. можно тупо купить готовый модуль в местном магазине или зашить ОРФА (см. местную вики) в свой контроллер. Они так и позиционируются как приложения к ББ.

Re: Точная генерация PWM на Линуксе

Strijar » 06 сен 2011, 20:20

Честно-говоря, я не могу себе представить, что даже при загрузке в 60%-70% 600MHz ARM не в состоянии сгенерить точно сигналы в миллисекундном диапазоне (импульсы должны идти с интервалом 20мс и ширина 1-2мс)


Из userspace он и не сможет - это не его задача. Из драйвера вполне. Я на 200мгц получал доступ в драйвер меньше чем 10мс ("тик" точней было не померять) Это при загрузке "под завязку".

Re: Точная генерация PWM на Линуксе

avr123.nm.ru » 06 сен 2011, 20:34

микро секунды.

Re: Точная генерация PWM на Линуксе

Strijar » 06 сен 2011, 20:37

avr123.nm.ru писал(а):микро секунды.


Не важно - udelay оперирует наносекундами ;)

Re: Точная генерация PWM на Линуксе

noonv » 07 сен 2011, 09:31

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

Re: Точная генерация PWM на Линуксе

NorthStar » 07 сен 2011, 09:52

Есть вот такая микросхема http://www.arduino.cc/playground/Learning/TLC5940, которая будет за вас генерировать точный PWM. Это не микроконтроллер. Можете поискать Shield на ее основе. Это явно проще, чем с Линуксом гемороиться.

Re: Точная генерация PWM на Линуксе

Strijar » 07 сен 2011, 10:26

NorthStar писал(а):Есть вот такая микросхема http://www.arduino.cc/playground/Learning/TLC5940, которая будет за вас генерировать точный PWM


Зачем тогда вообще использовать 600Мгц проц если навешивать на него кучу обвеса?

Это явно проще, чем с Линуксом гемороиться.


А можно использовать FPGA, это будет проще чем с кучей рассыпухи гемороиться ;)

Re: Точная генерация PWM на Линуксе

=DeaD= » 07 сен 2011, 10:36

Strijar писал(а):Зачем тогда вообще использовать 600Мгц проц если навешивать на него кучу обвеса?

Это вы спросите производителей чипсетов для материнских плат и прочих специализированных контроллеров - "Зачем это всё, если есть процессор на 4 ядра и 3ГГц?" :wink:

Re: Точная генерация PWM на Линуксе

devel » 07 сен 2011, 11:12

я бы поставил сопроцессор ввода/вывода, который обрабатывал все риалтаймовские задачи.

Re: Точная генерация PWM на Линуксе

linvinus » 07 сен 2011, 11:59

andreynech, проблема не в линуксе, а в том как вы решаете задачу.
Линукс универсальная многозадачная система, есть несколько планировщиков задач и прерываний.
Есть специальные проекты по адаптации ядра для работы в реалтайм режиме, это ветка -rt
xenomai - как я понял как раз адаптирован для -rt

Тут смотрели примеры?
http://www.xenomai.org/documentation/xe ... mples.html

Ещё есть вариант использовать audio выходы, если вам достаточно двух каналов.
В этом случае pwm будет на плечах кодека, вам нужно будет только подавать специальные аудио данные через alsa или oss.

Re: Точная генерация PWM на Линуксе

andreynech » 07 сен 2011, 12:43

Ух, вчера вечером, уходя с работы глянул - ни одного ответа не было. А сейчас открыл - а тут 11 штук уже! :) Спасибо за комментарии! Сейчас буду отвечать...

Re: Точная генерация PWM на Линуксе

Сергей » 07 сен 2011, 14:02

И советую не уповать на real-time. Конечное дискретное время может не удовлетворять вашим потребностям.

Re: Точная генерация PWM на Линуксе

andreynech » 07 сен 2011, 14:09

Перед тем как на конкретные вопросы отвечать, хотел пару слов сказать про Xenomai. Это что-то типа мини real-time OS. Иногда его еще супервизором называют. Он запускает Линукс как одну из своих задач и может его останавливать если есть необходимость (более приоритетная задача готова к выполнению). Т.е. поток (thread) запущеный с помощью Xenomai-ного API попадает под контроль супервизора и если нужно, то может выполняеться даже с более высоким приоритетом чем Линукс. За счет этого они добиваются хороших real-time характеристик (лучше чем preempt_rt patch который решает все внутри ядра). Собственно поэтому я и решил Xenomai использовать и вобщем поэтому и удивляюсь, что не идеально получилось и пытаюсь разобраться в чем проблема.

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

Strijar писал(а):Написать свой драйвер pwm который будет выдерживать точно длинну импульса с помощью udelay(). Правда в это время процессор будет именно простаивать - но зато точно.

Хотя можно попробовать и без udelay - но нет гарантии что при сильной загрузке будет работать гарантированно. Какая там тактовая? Может и хватит.

Писать драйвер мне тоже посоветовали на Xenomai-ном форуме. Но только не для Линукса, а для Xenomai. У них там тоже есть понятие драйвера и вроде бы он еще более точно выполняется. Ну и конечно посоветовали работать с таймерами в драйвере а не ждать, чтобы не тормозить всю систему.

Michael_K писал(а):Вы и сами прекрасно понимаете, что проблема не в арме, а в оси.
Я не знаю, как именно организовано в ксеномай и тем более, как вы реализуете работу с ШИМом.
Вероятно у оси есть какие-то тайм-слайсы, которые на порядок больше необходимой вам точности или что-то в таком духе.

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

Michael_K писал(а):Зря заморачиваетесь с этим.
Если не хотите компиляторов-мейк-файлов и т.п. можно тупо купить готовый модуль в местном магазине или зашить ОРФА (см. местную вики) в свой контроллер. Они так и позиционируются как приложения к ББ.

Ну я на самом деле не так уж и боюсь МК :) . Я умею с ними работать. Тут наверно больше дело принципа - ну раз теоретически можно сделать более компактный вариант с меньшим колличеством компонентов, то почему бы не постараться?!

Strijar писал(а):Из userspace он и не сможет - это не его задача. Из драйвера вполне. Я на 200мгц получал доступ в драйвер меньше чем 10мс ("тик" точней было не померять) Это при загрузке "под завязку".

Ну я не совсем в userspace. Как я в начале написал, поток, запущеный с помощью Xenomai-ного API, попадает под контроль супервизора. Т.е. если я правильно понимаю, он как-то сбоку от Линукса уже работает.

noonv писал(а):вопрос интересный, но мне кажется, что работу с железом лучше производить через отдельный контроллер. Просто, прозрачно и ресурсы не нужно тратить (если пока и есть свободные - это не проблема :D )

Ну тасчет простоты я не совсем согласен. При работе с МК нужно будет самому очень точно планировать работу с таймерами, следить чтобы разные задачи, работающие с разной частотой (например генерация ШИМ и чтение и обработка данных с гиро/акселерометров) не мешали друг другу. Плюс надо будет организовать какой-то протокол общения между МК и основным компом. При использовании Xenomai это проще решается. Все работает в одном адресном пространстве. Плинировщик задач сам решает как работать с таймерами чтобы все задачи вовремя запускались и т.д. Т.е. просто говорю - запусти мне две периодические задачи с частотой 50Гц и 20Гц и могу быть уверенным, что мои функции будут вызваны в нужный момент. Мне кажется это проще чем с МК.

noonv писал(а):у вас в блоге показана работа со стереопарой. правильно ли я понимаю, что бигла только передаёт картинки с камер на ПК и обрабатывать их на самой плате не предусматривается?

Да, на бигле я снимаю кадр с двух камер, склеиваю их вместе, компримирую в h264 и передаю на "водительский" комп. Большую часть этой работы делает Gstreamer. Причем есть заинтегрированные TI-шные кодеки которые используют DSP. Вот тут можно посмотреть примеры пайплайнов для gstreamer-а которые я использую. Потом, на водительской стороне, после раскодирования, я делаю из двух склеяных кадров (левый и правый) анаглифную картинку. Использую OpenCV для этого. Сделать анаглиф легко и самому, но я всеравно планирую интенсивно OpenCV использовать, поэтому для анаглифа тоже им воспользовался. Если интересно, то вот тут эта функция.

devel писал(а):я бы поставил сопроцессор ввода/вывода, который обрабатывал все риалтаймовские задачи.

Это наверно логично, но я пытаюсь уменьшить колличество компонент в системе. Если не получится, то наверно так и поступлю.

linvinus писал(а):andreynech, проблема не в линуксе, а в том как вы решаете задачу.
Линукс универсальная многозадачная система, есть несколько планировщиков задач и прерываний.
Есть специальные проекты по адаптации ядра для работы в реалтайм режиме, это ветка -rt
xenomai - как я понял как раз адаптирован для -rt

Как я писал в начале, Xenomai и ветка -rt (preempt-rt patch) это два разных подхода сделать из Линукса real-time систему. Xenomai дает лучшие результаты, но он всетаки "чужеродное" тело. Preempt-rt patch значительно более элегантное и "родное" для ядра решение, но пока оно дает результаты хуже чем Xenomai. Хотя, я думаю что будущее за preempt-rt. Я думаю когда-нибудь они его доведут таки до ума.

linvinus писал(а):Тут смотрели примеры?
http://www.xenomai.org/documentation/xe ... mples.html

Да, конечно смотрел. На самом деле то что у меня сейчас работает, это измененный trivial-periodic.c. Вот, если интересно мой исходник. pwm_func() это как раз функция, которая уже непосредственно генерит ШИМ.

linvinus писал(а):Ещё есть вариант использовать audio выходы, если вам достаточно двух каналов.
В этом случае pwm будет на плечах кодека, вам нужно будет только подавать специальные аудио данные через alsa или oss.

Ну я бы не хотел ограничиваться двумя выходами. Да и я вобщем хочу разобраться почему мой вариант не совсем хорошо работает. Я надеюсь, что если я научусь точно генерить ШИМ-ы, то потом смогу использовать ту же рехнику для работы с сенсорами и для других real-time задач.

Еще раз спасибо большое всем за комментарии!

Андрей.


Rambler\'s Top100 Mail.ru counter