Компания Venti Technologies завершила миграцию программного обеспечения своих автономных машин с платформы ROS 1 Kinetic и Ubuntu 16.04 на ROS 2 Humble Hawksbill и Ubuntu 22.04. Процесс, занимавший около десяти месяцев, был проведен в сентябре 2024 года и позволил сохранить практически всю прикладную логику без остановки разработки продукта. Общая кодовая база на момент начала работ насчитывала примерно 1,5 миллиона строк, включая собственные исходники, тесты, сгенерированный код и сторонние зависимости. Миграция потребовала создания параллельной системы сборки, собственного слоя совместимости и проведения почти полугода валидации. При этом команда не переписывала вручную весь код, а создала условия для замены старой платформы новой, не вовлекая весь остальной продукт в процесс напрямую.
Основной причиной перехода стала необходимость обновления вычислительной платформы, так как ROS 1 Kinetic находилась за пределами официального срока поддержки с 2023 года. Старые версии библиотек PCL, Boost, а также сложности с обновлением NVIDIA-драйверов, CUDA и TensorRT ограничивали возможности оптимизации и использования современных AI-моделей. Команда Software Infrastructure пыталась продлить жизнь существующей системы за счет профилирования и оптимизации алгоритмов, что позволило сохранить работоспособность еще на два года, но этот подход привел к циклическому эффекту: производительность заканчивалась, ее восстанавливали, появлялись новые функции, и цикл повторялся. Обновление до ROS 1 Noetic рассматривалось как альтернатива, но требовало бы смены операционной системы на Ubuntu 20.04 и полного регрессионного тестирования, что не решало бы проблему долгосрочной поддержки, учитывая запланированный конец поддержки Noetic в мае 2025 года.
Для реализации миграции была выбрана стратегия «одна кодовая база, два независимых пути сборки». Вместо создания отдельной ветки с полной копией приложения, которая привела бы к рассинхронизации версий, команда создала новую систему сборки на базе Bazel, независимую от существующего catkin/CMake. Это позволило собирать один и тот же прикладной код параллельно для ROS 1 и ROS 2. Новые изменения попадали в общий исходный код, а не в две независимые версии, что давало возможность проверять новую платформу без отставания от основного продукта. Выбор Bazel был обусловлен его моделью явно описанных зависимостей и возможностью управления toolchain, что требовалось для построения альтернативной системы сборки без немедленного изменения действующей.
Центральным элементом миграции стал разработанный командой Software Infrastructure слой совместимости ROS Abstraction Layer. Его задача заключалась в воспроизведении интерфейса ROS 1 поверх ROS 2, используя шаблоны и выбор реализации на этапе компиляции. Это позволило приложению продолжать использовать знакомый интерфейс, например, публикацию сообщений через advertise и publish, в то время как внутренняя реализация использовала нативные API rclcpp. Такой подход исключил необходимость передачи сообщений между двумя одновременно работающими версиями middleware. Однако миграция столкнулась с проблемами, где схожие API скрывали разные модели поведения, например, в случае лatched topics. В ROS 2 для реализации аналогичного поведения требовалось не только настроить политику долговечности QoS transient_local на издателя, но и централизованно определить, что подписчики должны запрашивать соответствующую политику, что потребовало доработки слоя абстракции.