Анализ платформы автономного вождения Baidu Apollo

машинное обучение искусственный интеллект Автопилот

Недавно я узнал кое-что о проекте Apollo на платформе Baidu для самостоятельного вождения. Я поделюсь с вами некоторой информацией, которую я узнал ниже.

Введение в проект Аполлон

Apollo — это программная платформа, выпущенная Baidu для партнеров в автомобильной промышленности и автономном вождении. Выпущенная 19 апреля 2017 года, она призвана предоставить открытую, полную и безопасную программную платформу партнерам в автомобильной промышленности и автономном вождении, помогая им быстро создавать собственные полные комплекты в сочетании с транспортными средствами и аппаратными системами.Система автопилота. Название этой программы «Аполлон» заимствовано из значения программы высадки на Луну «Аполлон».

Вы можете почувствовать настоящий опыт вождения автомобиля Apollo здесь:Испытательный заезд беспилотного автомобиля Baidu Apollo 2.0 на выставке CES 2018 в Саннивейле, США.

SAE Level

Для автономного вождения SAE (Общество автомобильных инженеров, Американское общество автомобильных инженеров) International выпустило в 2014 году шесть различных уровней систем классификации от полностью ручных до полностью автоматизированных систем.Шесть уровней описываются следующим образом:

SAE Level Name System capability Driver involvement
0 No Automation None The human at the wheel steers, brakes, accelerates, and negotiates traffic.
1 Drive Assistance Under certain conditions, the car controls either the steering or the vehicle speed, but not both simultaneously. The driver performs all other aspects of driving and has full responsibility for monitoring the road and taking over if the assistance system fails to act appropriately.
2 Partial Automation The car can steer, accelerate, and brake in certain circumstances. Tactical maneuvers such as responding to traffic signals or changing lanes largely fall to the driver, as does scanning for hazards. The driver may have to keep a hand on the wheel as a proxy for paying attention.
3 Conditional Automatio В правильных условиях автомобиль может управлять большинством аспектов вождения, включая мониторинг окружающей среды.Система предлагает водителю вмешаться, когда он сталкивается со сценарием, в котором он не может ориентироваться. The driver must be available to take over at any time.
4 High Automation The car can operate without human input or oversight but only under select conditions defined by factors such as road type or geographic area. In a shared car restricted to a defined area, there may not be any. But in a privately owned Level 4 car, the driver might manage all driving duties on surface streets then become a passenger as the car enters a highway.
5 Full Automation The driverless car can operate on any road and in any conditions a human driver could negotiate. Entering a destination.

Адрес официального сайта проекта «Аполлон»:apollo.auto

На официальном сайте проекта «Аполлон» сообщается, что проект имеет следующие характеристики:

  • открытая емкость: Аполлон阿波罗Это открытая, полная и безопасная платформа, которая поможет партнерам в автомобильной промышленности и в области автономного вождения быстро создать собственную систему автономного вождения, объединив автомобили и аппаратные системы.
  • Делитесь ресурсами и ускоряйте инновации: открытая платформа Apollo, предоставляющая вам высокоточные картографические услуги с передовыми технологиями, широким охватом и высокой степенью автоматизации; единственный в мире открытый механизм моделирования с массивными данными; самый большой в мире объем открытых данных, основанный на алгоритме глубокого обучения автопилота. Конец.
  • Устойчивый беспроигрышный вариант: открытая платформа Apollo позволяет быстрее разрабатывать, тестировать и внедрять беспилотные автомобили. Чем больше участников, тем больше данных о вождении накапливается. По сравнению с закрытой системой, Apollo может развиваться быстрее, позволяя каждому участнику получать больше преимуществ, и платформа Apollo также станет лучше с вашим участием!

В настоящее время на его официальном сайте зарегистрировано около 100 партнеров.

План проекта «Аполлон» выглядит следующим образом:

  • 2017-07: возможности автономного вождения на закрытых площадках
  • 2017-12: Возможность автономного вождения в простых городских дорожных условиях
  • 2020-12: Полностью автономное вождение по шоссе и обычным городским дорогам

Основная цель недавно выпущенной версии Apollo 2.5 — автономное вождение L2.

Подробная информация об эволюции версии Apollo показана на следующем рисунке:

исходный код

Исходный код проекта Apollo можно найти здесь:github.com/ApolloAuto. В этот путь включены 5 проектов с открытым исходным кодом:

  • apollo: Исходный код платформы автономного вождения Apollo.
  • apollo-platform: Проект «Аполлон» основан наRobot Operating System ROS, вот соответствующий код. Выпущенный в настоящее время исходный код основан на ROS Indigo.
  • apollo-DuerOS: Apollo-DuerOS — это набор телематических продуктов, связанных с Apollo, который включает в себя несколько продуктов с открытым исходным кодом. Для DuerOS см. здесь:DuerOS.
  • apollo-kernel: ядро ​​Linux проекта Apollo.
  • ApolloAuto.github.io: документы, связанные с Apollo, к которым можно получить доступ черезapolloauto.github.ioПолучите доступ к этим документам.

скомпилировать и запустить

См. здесь, как скомпилировать и запустить проект Apollo:apolloauto.github.io.

Для выполнения этой задачи требуются среды Ubuntu и Docker.

После завершения компиляции вы можете ознакомиться с окружением через предусмотренную проектом функцию Dreamview на компьютере.Доступ к Dreamview осуществляется через браузер, а его интерфейс выглядит так:

Дополнительные инструкции по Dreamview см. здесь:Dreamview Usage Table

развивать

Разработка платформы Arbro состоит из следующих этапов:

  1. Понимание механизма автономного моделирования Dreamviewer и основных программных модулей ApolloAuto.
    • Узнайте, как алгоритмы работают в автомобилях
    • Начните разработку прямо сейчас, не используя настоящий автомобиль или оборудование
  2. Интеграция основного модуля
    • Модуль местоположения
    • Модуль восприятия: (поддерживает сторонние решения, такие как камеры на базе чипа Mobileye ES4 для разработки L2) Обрабатывает данные облака точек из лидара и возвращает сегментированную информацию об объекте по запросу.
    • Модуль планирования: рассчитать путь точной настройки и предоставить информацию о динамическом контроле транспортного средства для сегмента пути, обслуживаемого путем.
    • Модуль Routine: Находит локальную реализацию сегментов маршрута через интерфейс Navigator.
  3. HD карта. Для автономного вождения уровня 4 требуются карты высокой четкости. Поскольку беспилотным автомобилям необходимо реконструировать трехмерный мир в системе, координаты опорных объектов играют важную роль в перемещении карты и автономном вождении в реальном мире.
  4. Облачный движок сценариев на основе онлайн-моделирования и центр обработки данных.
    • Как партнер Baidu вам будет предоставлен сертификат Docker для отправки новых изображений и воспроизведения ваших алгоритмов, разработанных в облаке.
    • Создавайте сложные сценарии и управляйте ими, чтобы имитировать реальный опыт вождения.

Аполлон и РОС

Полное название ROS — Robot Operating System. Он содержит набор программных библиотек и инструментов с открытым исходным кодом, специально предназначенных для создания приложений для робототехники. Официальный адрес сайта здесь:www.ros.org.

В систему ROS входит ряд независимых узлов (узлов). между этими узлами черезМодель обмена сообщениями публикации/подпискиобщаться. Например, драйвер датчика можно реализовать как узел, а затем отправлять данные датчика наружу в виде публикации сообщений. Эти данные могут быть получены несколькими другими узлами, такими как: фильтры, системы регистрации и т. д.

Узлы в системе ROS могут располагаться на разных хостах, например: устройство Arduino публикует сообщения, ноутбук подписывается на эти сообщения, а телефон Android также отслеживает эти сообщения.

Система ROS включает в себя главный (Master) узел. Главный узел позволяет другим узлам опрашивать друг друга для связи. Все узлы должны быть зарегистрированы на главном узле, после чего они смогут взаимодействовать с другими узлами. Как показано ниже:

Те, кто знаком с системой Android, могут легко обнаружить, что это похоже на ServiceManager в Binder.

Связь между узлами осуществляется путем публикации и подписки на темы (Topics). Например, в роботизированной системе есть модуль камеры на роботе, который может получать данные изображения. Кроме того, на роботе есть модуль обработки изображений, которому необходимо получать данные изображения, и в то же время на персональном ПК есть еще один модуль, которому также нужны эти данные изображения. Ну и модуль камеры можно выпустить/image_dataЭта тема предназначена для подписки на два других модуля. Его структура показана на следующем рисунке:

Проект Apollo основан на ROS, но он был преобразован, в основном, включая следующие три аспекта:

  1. Оптимизация производительности связи
  2. Топология децентрализованной сети
  3. Расширение совместимости данных

Оптимизация производительности связи

В автономные транспортные средства включено большое количество датчиков, и эти датчики могут генерировать данные с очень высокой частотой, поэтому вся система требует высокой эффективности передачи данных. В системе ROS данные должны быть скопированы из публикации данных в подписные узлы. В случае большого объема данных очевидно, что это повлияет на эффективность передачи данных. Таким образом, первая трансформация проекта Apollo для ROS заключается в уменьшении количества копий данных через общую память для повышения производительности связи. Как показано ниже:

Топология децентрализованной сети

Как мы упоминали ранее, система ROS включает в себя главный узел для связи, и все остальные узлы полагаются на этот узел для связи. Таким образом, очевидно, что если на этом узле произойдет сбой связи, это повлияет на связь всей системы. Более того, во всей структуре также отсутствует механизм восстановления исключений.

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

Для получения дополнительной информации о RTPS см. здесь:Real-Time Publish-Subscribe

Расширение совместимости данных

Последним крупным улучшением проекта Apollo для ROS является корректировка формата данных.

В системе ROS файл описания msg используется для определения интерфейса сообщений между модулями. Но, к сожалению, модули разных версий трудно совместимы после обновления интерфейса.

Поэтому Аполлон выбрал GoogleProtocol Buffersотформатируйте данные, чтобы решить эту проблему.

Protocol Buffers – это язык описания данных, разработанный Google. Подобно XML, он может сериализовать структурированные данные и может использоваться для хранения данных, протоколов связи и т. д. Он не зависит от языка и платформы и чрезвычайно расширяем. На данном этапе официально поддерживаются C++, JAVA и Python, но можно найти большое количество сторонних пакетов расширения, охватывающих практически все языки.

Примечание. Если вы посмотрите на исходный код проекта Apollo, вы увидите множество папок с именем «proto», которые содержат структуры данных в формате Protocol Buffers (сокращенно protobuf).

аппаратная архитектура

Необходимое оборудование для Apollo 2.5 показано в таблице ниже:

К периферийным устройствам относятся следующие:

Аппаратная архитектура показана на следующем рисунке:

Архитектура программного обеспечения

Программная архитектура платформы Apollo показана на следующем рисунке:

В Apollo основные программные модули, которые работают, включают:

  • Восприятие: модуль восприятия распознает окружающий мир автономного транспортного средства. В модуле «Восприятие» есть два важных подмодуля: обнаружение препятствий и обнаружение сигналов светофора.
  • Прогноз: Модуль прогнозирования прогнозирует будущие траектории движения воспринимаемых препятствий.
  • Маршрутизация: модуль маршрутизации сообщает автономному транспортному средству, как добраться до места назначения по ряду полос или дорог.
  • Планирование: модуль планирования планирует пространственно-временную траекторию автономного транспортного средства.
  • Управление: модуль управления выполняет запланированные пространственно-временные траектории, генерируя управляющие команды, такие как газы, тормоза и рулевое управление.
  • CanBus: CanBus передает команды управления на интерфейс аппаратного обеспечения автомобиля. Он также передает информацию о стойке в систему программного обеспечения.
  • HD-Map: Предоставляет информацию о структуре дороги.
  • Локализация: этот модуль использует различные источники информации, такие как GPS, LiDAR и IMU, для оценки местоположения автономного транспортного средства.

Структура взаимодействия этих модулей показана на следующем рисунке:

Каждый модуль работает как независимый узел ROS на базе CarOS. Каждый узел модуля публикует и подписывается на определенные темы. Темы с подпиской используются в качестве входных данных, а опубликованные темы используются в качестве выходных данных.

О системной архитектуре платформы Apollo вы можете прочитать в этом документе:HOW TO UNDERSTAND ARCHITECTURE AND WORKFLOW.

Из этого документа мы видим:

  • Автономное транспортное средство управляется двигателем планирования через шину CAN (шина локальной сети контроллеров).
  • Для повышения эффективности вычислений модуль «Местоположение», модуль «Восприятие» и модуль «Планирование» работают вместе через P2P как независимые источники ввода и вывода.
  • Читая исходный код${MODULE_NAME}/confФайлы конфигурации в каталоге, мы можем получить основную информацию о темах, на которые модуль подписывается и публикует.
  • Каждый модуль запускаетсяInitНачинаются обратные вызовы интерфейса и регистрации.
  • На этом этапе будут зарегистрированы все модули:AdapterManager::Init. Часть фрагмента кода этой функции выглядит следующим образом:
void AdapterManager::Init(const AdapterManagerConfig &configs) {
  if (Initialized()) {
    return;
  }

  instance()->initialized_ = true;
  if (configs.is_ros()) {
    instance()->node_handle_.reset(new ros::NodeHandle());
  }

  for (const auto &config : configs.config()) {
    switch (config.type()) {
      case AdapterConfig::POINT_CLOUD:
        EnablePointCloud(FLAGS_pointcloud_topic, config);
        break;
      case AdapterConfig::GPS:
        EnableGps(FLAGS_gps_topic, config);
        break;
      case AdapterConfig::IMU:
        EnableImu(FLAGS_imu_topic, config);
        break;
      case AdapterConfig::RAW_IMU:
        EnableRawImu(FLAGS_raw_imu_topic, config);
        break;
      case AdapterConfig::CHASSIS:
        EnableChassis(FLAGS_chassis_topic, config);
        break;
      case AdapterConfig::LOCALIZATION:
        EnableLocalization(FLAGS_localization_topic, config);
        break;
      case AdapterConfig::PERCEPTION_OBSTACLES:
        EnablePerceptionObstacles(FLAGS_perception_obstacle_topic, config);
        break;
      case AdapterConfig::TRAFFIC_LIGHT_DETECTION:
        EnableTrafficLightDetection(FLAGS_traffic_light_detection_topic,
                                    config);
     ...

Ниже приводится некоторый анализ основных основных модулей системы.

основной модуль

apollo/modules/Содержит исходный код каждого модуля в системе.

При чтении этих исходных кодов вы обнаружите, что все классы этих основных модулей наследуются от общего базового класса ApolloApp, и соответствующая структура показана на следующем рисунке:

Структура класса ApolloApp показана на следующем рисунке:

Основные функции этого класса описываются следующим образом:

Имя функции инструкция
std::string Name() const Возвращает имя модуля
apollo::common::Status Init() Функция инициализации модуля, первая функция, которую запускает модуль
apollo::common::Status Start() функция запуска модуля
int Spin() точка входа модуля
void Stop() функция остановки модуля

существуетapollo_app.hВ этот заголовочный файл также включен макрос, облегчающий каждому модулю объявление основной функции.Соответствующий код выглядит следующим образом:

#define APOLLO_MAIN(APP)                                       \
  int main(int argc, char **argv) {                            \
    google::InitGoogleLogging(argv[0]);                        \
    google::ParseCommandLineFlags(&argc, &argv, true);         \
    signal(SIGINT, apollo::common::apollo_app_sigint_handler); \
    APP apollo_app_;                                           \
    ros::init(argc, argv, apollo_app_.Name());                 \
    apollo_app_.Spin();                                        \
    return 0;                                                  \
  }

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

Восприятие

Введение модуля

Беспилотные автомобили сохраняют дистанцию ​​​​от ближайшего транспортного средства на пути (CIPV) с помощью передних камер и радаров. Подмодуль также прогнозирует движение препятствия и информацию о местоположении (например, направление и скорость). Apollo 2.5 поддерживает скоростное автономное вождение по шоссе без каких-либо карт. Алгоритмы глубокой сети научились обрабатывать данные изображений. Производительность глубоких сетей со временем будет улучшаться по мере сбора большего количества данных.

Вход модуля:

  • данные радара
  • данные изображения
  • Внешние параметры для калибровки радарного датчика (из файла YAML)
  • Внешние и внутренние параметры для калибровки передней камеры (из файла YAML)
  • Скорость автомобиля и угловая скорость

Выход модуля:

  • Трехмерное отслеживание препятствий, информация о курсе, скорости и классификации
  • Информация о разметке полосы движения с подобранными параметрами кривой, пространственная информация, а также семантическая информация

Разрешение модуля

Модуль «Восприятие» должен быстро разобрать два типа информации в соответствии с входной информацией, а именно: дороги и объекты. Глубокая сеть основана на алгоритме YOLO.[1][2].

Apollo 2.5 не поддерживает немаркированные дороги с большой кривизной, в том числе местные дороги и перекрестки. Модуль восприятия основан на визуальном обнаружении с использованием глубоких сетей с ограниченными данными. Поэтому до тех пор, пока не будет выпущена лучшая сеть, водители должны водить машину с осторожностью и всегда быть готовыми отключить автономное вождение, повернув колеса в правильном направлении.

  • рекомендуемая дорога
    • Четкие белые полосы движения с обеих сторон
  • дорога не рекомендуется
    • дорога с большой кривизной
    • Дороги без разметки
    • перекресток
    • Точка стыковки или пунктирная линия полосы движения
    • дорога общего пользования

Для объектов он делится на статические объекты и динамические объекты. К статическим объектам относятся дороги, светофоры и т. д. К динамическим объектам относятся автомобили, велосипеды, пешеходы, животные и т. д.

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

Модуль восприятия находится вInitВ функции будет зарегистрирован ряд классов для завершения нормальной работы после запуска модуля.Соответствующие коды следующие:

void Perception::RegistAllOnboardClass() {
  /// regist sharedata
  RegisterFactoryLidarObjectData();
  RegisterFactoryRadarObjectData();
  RegisterFactoryCameraObjectData();
  RegisterFactoryCameraSharedData();
  RegisterFactoryCIPVObjectData();
  RegisterFactoryLaneSharedData();
  RegisterFactoryFusionSharedData();
  traffic_light::RegisterFactoryTLPreprocessingData();

  /// regist subnode
  RegisterFactoryLidarProcessSubnode();
  RegisterFactoryRadarProcessSubnode();
  RegisterFactoryCameraProcessSubnode();
  RegisterFactoryCIPVSubnode();
  RegisterFactoryLanePostProcessingSubnode();
  RegisterFactoryAsyncFusionSubnode();
  RegisterFactoryFusionSubnode();
  RegisterFactoryMotionService();
  lowcostvisualizer::RegisterFactoryVisualizationSubnode();
  traffic_light::RegisterFactoryTLPreprocessorSubnode();
  traffic_light::RegisterFactoryTLProcSubnode();
}

Мы можем использовать это как запись, чтобы понять логику каждого подмодуля.

отRegisterFactoryLidarProcessSubnodeНапример.

на самом деле не существует в кодеRegisterFactoryLidarProcessSubnodeЭта функция, определение функции фактически выполняется макросом. Соответствующий код выглядит следующим образом:

Lidar(также называемая LIDAR, LiDAR или LADAR) расшифровывается как Light Detection And Ranging, то есть лазерное обнаружение и измерение.

// /modules/perception/onboard/subnode.h
#define REGISTER_SUBNODE(name) REGISTER_CLASS(Subnode, name)


// /modules/perception/lib/base/registerer.h
#define REGISTER_CLASS(clazz, name)                                           \
  class ObjectFactory##name : public apollo::perception::ObjectFactory {      \
   public:                                                                    \
    virtual ~ObjectFactory##name() {}                                         \
    virtual perception::Any NewInstance() {                                   \
      return perception::Any(new name());                                     \
    }                                                                         \
  };                                                                          \
  inline void RegisterFactory##name() {                                       \
    perception::FactoryMap &map = perception::GlobalFactoryMap()[#clazz];     \
    if (map.find(#name) == map.end()) map[#name] = new ObjectFactory##name(); \
  }

пока вlidar_process_subnode.hиспользовал вышеуказанный макрос.

REGISTER_SUBNODE(LidarProcessSubnode);

Таким образом, имя генерируется какObjectFactoryLidarProcessSubnodeкласс, который наследуется отapollo::perception::ObjectFactory, и он содержит имяRegisterFactoryLidarProcessSubnodeФункция.

Прогноз

Введение модуля

Модуль прогнозирования принимает информацию о препятствиях от модуля восприятия. Информация, необходимая этому модулю, включает в себя положение, курс, скорость, ускорение и создает прогнозируемую траекторию с вероятностью препятствия.

Вход модуля:

  • Информация о препятствиях из модуля прогнозирования
  • Информация о местоположении из модуля локализации

Выход модуля:

  • Прогнозируемые траектории препятствий

Разрешение модуля

ПрогнозInitВ функцию добавлены три обратных вызова для получения обновлений от других модулей:

AdapterManager::AddLocalizationCallback(&Prediction::OnLocalization, this);
AdapterManager::AddPlanningCallback(&Prediction::OnPlanning, this);
AdapterManager::AddPerceptionObstaclesCallback(&Prediction::RunOnce, this);

Самое главное здесьPrediction::RunOnceэта функция. Эта функция содержит основную логику модуля Prediction, которая срабатывает при получении нового сообщения о препятствии.

В модуле Prediction есть три важных подмодуля.

Первая категория — Контейнер, который используется для хранения данных, полученных из подписанных каналов. включают:

  • Информация о воспринимаемых препятствиях
  • информация о местоположении автомобиля
  • Информация о программе автомобиля

Вторая категория — Evaluator, которая используется для прогнозирования маршрута и скорости для указанного препятствия. В настоящее время существует три типа оценщиков, в том числе:

  • Оценщик стоимости: рассчитать вероятность с помощью набора функций стоимости
  • Оценщик MLP: успешноМЛП модельвычислить вероятность
  • Оценщик RNN: успешномодель RNNвычислить вероятность

ОценщикПройтиEvaluatorManagerУправление классами, структура класса Evaluator показана на следующем рисунке:

Третьим важным подмодулем в модуле Prediction является Predictor. Он используется для прогнозирования траектории препятствий.

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

Аналогичным образом будетPredictorManagerдля управления предиктором.

Маршрутизация

Введение модуля

Модуль маршрутизации генерирует навигационную информацию по запросу.

Вход модуля:

  • данные карты
  • запрос, в том числе: начальная и конечная позиция

Выход модуля:

  • навигационная информация по маршруту

Разрешение модуля

Внутренняя структура модуля маршрутизации показана на следующем рисунке:

Входными данными для модуля маршрутизации являются данные карты и навигационные запросы, поэтому егоInitФункция построена вокруг этой логики:

apollo::common::Status Routing::Init() {
  const auto routing_map_file = apollo::hdmap::RoutingMapFile();
  AINFO << "Use routing topology graph path: " << routing_map_file;
  navigator_ptr_.reset(new Navigator(routing_map_file));
  CHECK(common::util::GetProtoFromFile(FLAGS_routing_conf_file, &routing_conf_))
      << "Unable to load routing conf file: " + FLAGS_routing_conf_file;

  AINFO << "Conf file: " << FLAGS_routing_conf_file << " is loaded.";

  hdmap_ = apollo::hdmap::HDMapUtil::BaseMapPtr();
  CHECK(hdmap_) << "Failed to load map file:" << apollo::hdmap::BaseMapFile();

  AdapterManager::Init(FLAGS_routing_adapter_config_filename);
  AdapterManager::AddRoutingRequestCallback(&Routing::OnRoutingRequest, this);
  return apollo::common::Status::OK();
}

Этот код фокусируется на следующих трех местах:

  • apollo::hdmap::RoutingMapFile()Содержит данные карты HD.
  • NavigatorОтвечая за навигацию, мы легко можем представить, что этот класс должен быть ядром модуля.
  • Routing::OnRoutingRequestФункция обратного вызова, которая получает запрос навигации.

существуетRouting::OnRoutingRequest, самое главное черезNavigator::SearchRouteдля поиска пути навигации.

void Routing::OnRoutingRequest(const RoutingRequest& routing_request) {
  AINFO << "Get new routing request:" << routing_request.DebugString();
  RoutingResponse routing_response;
  apollo::common::monitor::MonitorLogBuffer buffer(&monitor_logger_);
  const auto& fixed_request = FillLaneInfoIfMissing(routing_request);
  if (!navigator_ptr_->SearchRoute(fixed_request, &routing_response)) {
    AERROR << "Failed to search route with navigator.";

    buffer.WARN("Routing failed! " + routing_response.status().msg());
    return;
  }
  buffer.INFO("Routing success!");
  AdapterManager::PublishRoutingResponse(routing_response);
  return;
}

В настоящее время навигация в Apollo 2.5 основана наАлгоритм А*. Это алгоритм поиска наименьшей стоимости прохода для пути с несколькими узлами на плоскости графа. Алгоритм сочетает в себе преимущества поиска наилучшего первого и алгоритма Дейкстры: при выполнении эвристического поиска для повышения эффективности алгоритма он может гарантировать нахождение оптимального пути (на основе функции оценки).

Во время расчета алгоритма A* пробуются несколько путей. Как только препятствие встречается, точка на этом пути помечается как не требующая дальнейшего исследования (сплошная точка на диаграмме). Продолжайте исследовать, основываясь на оставшихся полых точках. В итоге получается оптимальный путь.

Следующий рисунок динамически описываетАлгоритм А*Алгоритмический процесс поиска целевого пути.

Планирование

Введение модуля

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

В текущую реализацию системы включены четыре планировщика:

  • RTKReplayPlanner (начиная с Apollo 1.0): планировщик воспроизведения RTK сначала загружает записанную траекторию при инициализации и отправляет соответствующие сегменты траектории на основе текущего системного времени и положения транспортного средства.
  • EMPlanner (начиная с Apollo 1.5. EM — это сокращение от Expectation Maximization): планировщик EM, который рассчитывает решения и маршруты для вождения на основе карт, маршрутов и препятствий. Метод, основанный на динамическом программировании (DP), сначала используется для определения исходного пути и профиля скорости, а затем метод, основанный на квадратичном программировании (QP), используется для дальнейшей оптимизации пути и профиля скорости для получения гладкой траектории.
  • LatticePlanner: планировщик сетки
  • NaviPlanner: это планировщик на основе относительной карты в реальном времени. Он использует систему координат FLU (Front-Left-Up) автомобиля для выполнения задач движения, следования, обгона, приближения, смены полосы движения и парковки.

Вход модуля:

  • Планировщик воспроизведения RTK:
    • Localization
    • Записанная трасса RTK
  • Планировщик ЭМ:
    • Localization
    • Perception
    • Prediction
    • HD Map
    • Routing

Выход модуля:

  • Бесстолкновительные и комфортные траектории позволяют выполнять модуль управления

Разрешение модуля

Модуль планирования инициализируетсяInitВ функции здесь будут прописаны все планировщики, а затем в соответствии с настройкой в ​​конфигурационном файле будет определяться используемый в данный момент планировщик. В настоящее время планировщик EM настроен в файле конфигурации.

Модуль планирования находится вStartВ функции установлен таймер для выполнения задачи синхронизации:

Status Planning::Start() {
  timer_ = AdapterManager::CreateTimer(
      ros::Duration(1.0 / FLAGS_planning_loop_rate), &Planning::OnTimer, this);
...

Planning::OnTimerГлавное позвонитьRunOnce(), который содержит основную логику модуля «Планирование». В настоящее время,FLAGS_planning_loop_rateЗначение равно 10. То есть частота запуска модуля «Планирование» составляет 10 раз в секунду.

В функции Planning::Plan маршрут рассчитывается через настроенный планировщик, а затем результат передается во внешний мир. Код ключа следующий:

Status Planning::Plan(const double current_time_stamp,
                      const std::vector<TrajectoryPoint>& stitching_trajectory,
                      ADCTrajectory* trajectory_pb) {
  auto* ptr_debug = trajectory_pb->mutable_debug();
  if (FLAGS_enable_record_debug) {
    ptr_debug->mutable_planning_data()->mutable_init_point()->CopyFrom(
        stitching_trajectory.back());
  }

  auto status = planner_->Plan(stitching_trajectory.back(), frame_.get());

  ExportReferenceLineDebug(ptr_debug);

  const auto* best_ref_info = frame_->FindDriveReferenceLineInfo();
  if (!best_ref_info) {
    std::string msg("planner failed to make a driving plan");
    AERROR << msg;
    if (last_publishable_trajectory_) {
      last_publishable_trajectory_->Clear();
    }
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }
  ptr_debug->MergeFrom(best_ref_info->debug());
  trajectory_pb->mutable_latency_stats()->MergeFrom(
      best_ref_info->latency_stats());
  // set right of way status
  trajectory_pb->set_right_of_way_status(best_ref_info->GetRightOfWayStatus());
  for (const auto& id : best_ref_info->TargetLaneId()) {
    trajectory_pb->add_lane_id()->CopyFrom(id);
  }

  best_ref_info->ExportDecision(trajectory_pb->mutable_decision());

  ...
  
  last_publishable_trajectory_->PrependTrajectoryPoints(
      stitching_trajectory.begin(), stitching_trajectory.end() - 1);

  for (size_t i = 0; i < last_publishable_trajectory_->NumOfPoints(); ++i) {
    if (last_publishable_trajectory_->TrajectoryPointAt(i).relative_time() >
        FLAGS_trajectory_time_high_density_period) {
      break;
    }
    ADEBUG << last_publishable_trajectory_->TrajectoryPointAt(i)
                  .ShortDebugString();
  }

  last_publishable_trajectory_->PopulateTrajectoryProtobuf(trajectory_pb);

  best_ref_info->ExportEngageAdvice(trajectory_pb->mutable_engage_advice());

  return status;
}

Контроль

Введение модуля

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

Вход модуля:

  • запланированный маршрут
  • состояние автомобиля
  • информация о местоположении
  • Запрос на изменение режима Dreamview AUTO

Выход модуля:

  • Команды управления (рулевое управление, акселератор, тормоз) на шасси

Разрешение модуля

Основная логика модуля управления также периодически выполняется через Таймер. функция срабатывает по времениControl::OnTimer, генерируется и отправляется команда:

void Control::OnTimer(const ros::TimerEvent &) {
  double start_timestamp = Clock::NowInSeconds();

  if (FLAGS_is_control_test_mode && FLAGS_control_test_duration > 0 &&
      (start_timestamp - init_time_) > FLAGS_control_test_duration) {
    AERROR << "Control finished testing. exit";
    ros::shutdown();
  }

  ControlCommand control_command;

  Status status = ProduceControlCommand(&control_command);
  AERROR_IF(!status.ok()) << "Failed to produce control command:"
                          << status.error_message();

  double end_timestamp = Clock::NowInSeconds();

  if (pad_received_) {
    control_command.mutable_pad_msg()->CopyFrom(pad_msg_);
    pad_received_ = false;
  }

  const double time_diff_ms = (end_timestamp - start_timestamp) * 1000;
  control_command.mutable_latency_stats()->set_total_time_ms(time_diff_ms);
  control_command.mutable_latency_stats()->set_total_time_exceeded(
      time_diff_ms < control_conf_.control_period());
  ADEBUG << "control cycle time is: " << time_diff_ms << " ms.";
  status.Save(control_command.mutable_header()->mutable_status());

  SendCmd(&control_command);
}

Модуль управления имеет три встроенных контроллера, и их структура и описание следующие:

  • LatController: боковой контроллер на основе LQR, который вычисляет цель поворота. Видеть:Vehicle Dynamics and Control.
  • LonController: продольный контроллер, вычисляет значения тормоза/дросселя.
  • MPCController: контроллер MPC, который сочетает в себе горизонтальные и вертикальные контроллеры.

заключительные замечания

В этой статье в основном проводится некоторое исследование и анализ на основе версии проекта Аполлон 2.5.

Мы также упоминали выше, что текущая версия 2.5 предназначена только для автономного вождения L2, в то время как Baidu планирует достичь автономного вождения L3 в 2019 году и автономного вождения L4 в 2021 году. Видно, что в следующий раз этот проект будет развиваться с очень высокой скоростью.

Кроме того, в этом году у меня как раз была возможность поучаствоватьCES в Шанхае. На выставке мы также увидели две беспилотные модели, представленные Baidu:

Один маленький автобус.

Также имеется небольшой транспортно-логистический комплекс.

В дальнейшем я продолжу уделять внимание этому проекту, и если будет больше информации, я продолжу делиться ею с вами.

Ссылки и рекомендуемая литература