ROS2 + Qt: есть хорошее решение?

Я создал Qt GUI на Python из кода (не из редактора Qt, поэтому я не использую файлы qml). Я хочу, чтобы он мог подписаться на темы ROS2 и обновлять графический интерфейс в соответствии с полученными сообщениями, а также публиковать данные при нажатии кнопки. Проблема в том, что Qt требует app.exec(), а ROS требует запуска node.spin(), оба из которых являются бесконечными циклами. Похоже, что в Интернете есть несколько руководств по ROS + Qt, но все они ориентированы на ROS1. Я не могу найти пример кода для ROS2 + Qt.

Как я могу интегрировать свой Qt GUI с ROS2?


person robbertfm    schedule 06.04.2020    source источник


Ответы (1)


Я использовал класс, который одновременно является QObject и rclcpp::Node:

class RosWorker : public QObject, public rclcpp::Node

RosWorker получает сообщения через публичные слоты от Qt и отправляет их в ROS через rclcpp::Publisher::publish(). Он принимает сообщения ROS по классическому принципу обратного вызова и отправляет их Qt с общедоступными сигналами.

Затем я создаю экземпляр RosWorker (std::shared_ptr<RosWorker> node_;) в моем классе MainWindow (наследующем QMainWindow) и запускаю узел в отдельном потоке:

void
MainWindow::rosSpinThread()
{
  rclcpp::spin(node_);
  rclcpp::shutdown();
}

с участием

MainWindow::MainWindow
{
  ros_spin_thread_ = std::thread{std::bind(&MainWindow::rosSpinThread, this)};
}

Более того, вам необходимо объявить типы сообщений ROS как настраиваемые типы, например:

Q_DECLARE_METATYPE(geometry_msg::msg::Pose)  // Outside of any namespace.

и

qRegisterMetaType<geometry_msg::msg::Pose>();  // In MainWindow's constructor.

Моя первая интуиция заключалась в том, чтобы иметь класс, унаследованный от rclcpp::Node, только с экземпляром MainWindow, но мне не удалось заставить его работать таким образом.

person Gaël Ecorchard    schedule 24.07.2020