Что является лучшим подходом для одновременной работы цикла в реальном времени и функции не в реальном времени
Извините за плохое название, я действительно не знаю, как описать это вкратце...
Мой сценарий заключается в том, что для роботизированного приложения нам необходим цикл в реальном времени для управления двигателем каждые 1 мс. В то же время мы можем захотеть сделать что-то, что не требует требований в реальном времени, таких как планирование пути, обработка изображений, распознавание объектов и т. Д. Кроме того, часть результата от задачи не в реальном времени будет отправлена в управление двигателем в реальном времени. петля для управления роботом.
Для реального времени я использую Ubuntu с RT-Preempt Patch. Поэтому я могу запустить цикл управления в реальном времени в цикле while, как пример кода здесь.
Тем не менее, я понятия не имею для части не в реальном времени. По моему скромному мнению, я бы создал новый поток в том же процессе и запустил в этом потоке задачу не в реальном времени.
Так как я очень плохо знаком с программированием в реальном времени, я не знаю, в чем проблема моего дизайна. Кроме того, мне интересно, есть ли парадигма для разработки такой программы?
---РЕДАКТИРОВАТЬ---
Еще несколько подробностей о моем приложении.
Робот, чтобы быть более определенным, является рукой робота.
Для части в реальном времени вычисляются прямая кинематика, обратная кинематика и якобиан. А затем рассчитайте правильную команду вывода, используя простой ПИД-регулятор. Наконец, отправьте команду двигателя с помощью EtherCAT каждому двигателю.
Например, часть, не относящаяся к реальному времени, может взять поток PointCloud из kinect, выполнить некоторую предварительную обработку, рассчитать позу объекта на сцене, определить подходящую позу для захвата руки робота и, наконец, отправить цель каждой двигайтесь в режиме реального времени, чтобы рука робота фактически двигалась к цели и хваталась за объект. Весь процесс может занять около 10 секунд. Однако в то же время цикл реального времени должен продолжать работать и посылать правильную команду силы или команду положения, чтобы манипулятор робота удерживал свою первоначальную позу и стоял на месте.
Что касается связи между этими двумя частями, в большинстве случаев команда генерируется новым алгоритмом из части не в реальном времени и отправляет ее в часть реального времени, чтобы заставить руку робота двигаться. Однако иногда алгоритму в части не в реальном времени необходимо знать, например, текущую позицию конечного эффектора. Следовательно, часть без реального времени должна будет получать информацию от прямой кинематики, которая находится в части реального времени.
2 ответа
Что именно делает цикл в реальном времени? Я предполагаю (так как вы упомянули, что "каждую 1 миллисекунду выполняет управление двигателем"), выполните несколько очень коротких вычислений и выведите несколько байтов на устройство двигателя.
Что делает часть не в реальном времени? Я представляю какой-то пользовательский интерфейс???
Что за робот?
Планирование пути может потребовать сильного реального времени, особенно если робот движется быстро. Крылатая ракета или Google Car - это не то же самое, что маленький робот для робокупа. Потеря нескольких миллисекунд связи может привести к гибели людей в крылатой ракете или в Google Car, но это приемлемо для Robocup - вы потеряете только игру и, возможно, нанесете небольшой вред своему роботу.
При скорости 40 м / с (144 км / час, что немного выше предела скорости дороги на шоссе 130 км / ч во Франции), две миллисекунды означают 8 см, а если эти 8 см - человеческая плоть, это может означать убийство кого-либо.
Как две части взаимодействуют? Отправляет ли часть в реальном времени некоторую информацию другой части?
Возможно, две части могут быть разными процессами (а не потоками) с некоторой связью? Возможно использование разделяемой памяти с семафорами для синхронизации. Затем посмотрите на sem_overview(7) и shm_overview (7).
Обратите внимание, что на интерфейсе между частью реального времени и частью не-реального времени часть не-реального времени может фактически стать также и частью реального времени.
Суть в том, чтобы определить концептуальный интерфейс между двумя частями (в реальном времени и не в реальном времени) и решить, можете ли вы позволить себе потерять некоторые данные и некоторую синхронизацию (связь между двумя частями) или нет.
Если роль не в реальном времени состоит в том, чтобы просто отображать или устанавливать скорость (т.е. некоторый низкий и высокий порог), вы, вероятно, можете позволить себе иногда потерять некоторые данные или синхронизацию. Но зло в деталях (если робот - это настоящий автономный автомобиль, едущий по какой-то автомагистрали в стиле Google Car, вы, вероятно, не должны позволить себе потерять некоторые обмены, и тогда обе части станут в реальном времени!).
Как вы делите свою систему в реальном времени на обычные части, очень важно, как подчеркнул @Basile Starynkevitch.
Когда дело доходит до реализации в RT-Linux, части вашей системы с требованиями реального времени будут преобразованы в потоки реального времени, которые работают внутри ядра. Это позволяет им работать без выгрузки, но имеет один гигантский недостаток: в пользовательском пространстве нет никаких средств защиты, которых можно ожидать. Сбой потока в реальном времени означает сбой системы. По этой (и другим) причинам вы должны максимально ограничить компоненты реального времени.
Компоненты не в реальном времени вашей системы будут работать как обычные процессы Linux. Они могут работать вместе с любыми дорогостоящими алгоритмами планирования, которые вам нужны, и потоки в реальном времени будут вытеснять их и запускаться по мере необходимости. Сложной является связь, для которой предусмотрено два механизма: FIFO и общая память.
FIFO являются самыми простыми и позволяют однонаправленную связь (используйте две, если хотите двунаправленную). Это символьные устройства, и вам не нужно беспокоиться о совпадениях при чтении / записи. Больше от tldp.org.
Для передачи больших объемов данных предпочтительна общая память. С его помощью два процесса отображают один и тот же раздел в память. Но вы должны координировать между процессами / потоками, чтобы гарантировать, что один не читает в середине другого, пишущего и наоборот. Это на самом деле немного легче сделать, когда одна из сторон является потоком в реальном времени, потому что вы знаете, что поток в реальном времени не будет вытеснен. Больше от drdobbs.com.
Вам также необходимо знать о инверсии приоритетов (например, когда поток с высоким приоритетом должен ожидать, когда поток с низким приоритетом освободит общий ресурс).