MPC, или Model Predictive Control - это управление процессом, предназначенное для автоматизации системы датчиков / исполнительных механизмов, таких как промышленные энергосистемы, робототехника или, в данном случае: движение транспортного средства по трассе. Мы можем определять автомобиль и его положение (координаты x / y) относительно пути, а затем мы можем управлять им с помощью рулевого управления.

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

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

Моя модель

Используя симуляцию транспортного средства на треке с помощью игрового движка Unity, транспортное средство будет управляться с помощью управления процессом MPC (управление с прогнозированием модели). Это похоже на другой мой проект на GitHub, в котором для этой же задачи использовался ПИД-регулятор. Разница в том, что контроллер MPC (простите за избыточность слов, я предпочитаю эту формулировку) может эффективно моделировать будущие временные состояния и планировать заранее. Модель была оптимизирована на протяжении этого конечного временного горизонта для каждого исполнительного механизма, которым в данном случае является рулевое управление и дроссельная заслонка / тормоз. Дроссельная заслонка и торможение управляются одним и тем же срабатыванием через значения в диапазоне [1,1].

Вовлеченные шаги:

  • Разберитесь в методах доступа к автомобилю и управления им.
  • Преобразуйте метод MPC в код C ++ и внедрите его в main.cpp и mpc.cpp для управления автомобилем.
  • Наблюдайте и примите во внимание смоделированную задержку (в данном случае 100 мс) стека датчиков и оптимизируйте модель, используя эти знания.

Зависимости и компиляция кода C ++

Если вам небезразличны технические аспекты реализации, см. Более подробные инструкции в моем GitHub ReadMe her.

API управления транспортным средством

Используя сервер WebSocket, консольная программа C ++ взаимодействует с симулятором вождения через файл JSON, который принимает и считывает различные переменные телеметрии. К ним относятся: CTE, скорость, угол, дроссельная заслонка и угол поворота.

В этом контроллере MPC мне нужно будет следить за CTE, курсом и скоростью, нажимая на дроссельную заслонку (включая торможение при отрицательных значениях ниже 0) и угол поворота, пытаясь поддерживать максимально возможную скорость, оставаясь при этом безопасно в пределах полосы движения. Хотя в этом случае я зафиксировал скорость на определенном значении, чтобы стремиться к 60 милям в час. Ниже приведен код для чтения исходной телеметрии в C ++:

Алгоритм контроллера MPC

Целью этого является моделирование поведения динамических систем, в данном случае позиционирования и траектории транспортного средства. Это кинематическая модель, представляющая собой более продвинутую версию ПИД-регулятора из другого моего репозитория, которая не принимает во внимание будущие временные состояния. Это будет моделировать изменение зависимых переменных, вызванное изменениями в независимых переменных.

Это итерационный процесс, основанный на оптимизации состояний на конечном горизонте. Мы постараемся минимизировать стоимость (CTE, курс, скорость) транспортного средства на трассе. Это то, что называется онлайн-моделью, поскольку она рассчитывает «на лету».

Это алгоритм управления с несколькими переменными, который использует:

  • динамическая модель процесса.
  • история прошлых срабатываний.
  • оптимизация функции затрат (CTE, курс, скорость) на горизонте прогноза.

Ниже приведены математические обозначения для некоторых обновлений прогнозов состояния:

Код для реализации вышеизложенного выглядит следующим образом:

Переменные, указанные выше, объяснены:

  • X - местоположение автомобиля в координате X.
  • Y - местоположение автомобиля в координате Y.
  • PSI - направление транспортного средства (моделирование работает в радианах, алгоритм - в градусах). Для преобразования между ними используются две формулы:
  • CTE - Cross-Track-Error (расстояние автомобиля от идеальной (средней) линии пути)
  • EPSI - ошибка направления автомобиля (отличие от идеального и фактического, идеальное касается кривой дороги).

Настройка модели

Лично я считаю, что эти переменные лучше всего подходят для моей модели при целевой скорости 60 миль в час:

  • Длина временного шага - N - это количество путевых точек для прогнозирования срабатывания транспортного средства в будущем. В этом проекте я использовал длину 7, так как она предсказывала достаточное количество поворотов, но не работала слишком медленно для моего компьютера. Хотя у меня есть ощущение, что на более медленных процессорах может возникнуть проблема. На изображении ниже вы можете увидеть пример контроллера с 6 путевыми точками:

  • Продолжительность - dt - Истекшее время в 100 должно очень точно совпадать с задержкой 100 мс, встроенной в модель. В идеале, чем быстрее, тем лучше, но это требует больших затрат на ЦП системы.

Подгонка полинома

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

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

Имитация задержки стека датчиков

В основном исходном коде я увеличил позицию вперед по времени на latency = 0.1, чтобы представить задержку 100 мс при обнаружении позиционирования. Это было сделано путем повторной оценки положения транспортного средства, которое было обнаружено с помощью следующего кода:

В заключение

Это расширение моего предыдущего ПИД-регулятора, для которого у меня есть репозиторий GitHub. Чтобы получить настоящее удовольствие, подайте заявку на участие в программе Udacity Self-Driving Car NanoDegreee. Этот проект появится во втором семестре ближе к концу. Он научил меня огромному количеству тщательно отобранных навыков, которые пригодятся в такой карьере. Раньше большая часть этого материала относилась к научным статьям и учебникам по инженерным наукам. Наличие всего этого на адаптивном веб-сайте с видео и примерами кода - огромное преимущество. Затем проекты помогут вам по-настоящему вбить всю эту информацию.