При проектировании систем в промышленной IoT или робототехнической среде вы неизбежно столкнетесь с задачей обработки огромного количества данных с датчиков и управляющих команд в реальном времени. ROS2 (Система управления роботами 2) может быть использован для решения этих проблем.
Хотя в названии ROS2 есть 'операционная система (OS)', это не настоящая операционная система, такая как Windows или Linux, а программный фреймворк, который помогает легко разрабатывать роботизированные приложения. В его названии есть 'робот', но его суть заключается в мощной асинхронной распределенной архитектуре связи.После того как мы поймем поток данных ROS2, используемый для эффективного сбора данных с датчиков, мы узнаем, как его проектировать и отлаживать.
1. Связь ROS2: DDS и асинхронная модель Pub/Sub
Первое понятие, которое нужно знать для понимания архитектуры ROS2, это DDS (Служба распределения данных). DDS была создана для быстрой и надежной передачи данных между устройствами в распределенной системе.международный стандарт связиэто.
Если традиционные веб-сервисы в основном полагались на синхронные REST API, где сервер отвечает на запросы клиентов, то в средах, работающих с данными в реальном времени, такой подход может привести к огромным узким местам. В отличие от этого, DDS использует модель публикации и подпискикоторая позволяет немедленно передавать данные в необходимые места каждый раз, когда они создаются, без необходимости клиенту запрашивать данные у сервера. Это позволяет обрабатывать огромное количество данных, которые одновременно поступают от множества датчиков, мгновенно и без задержек. Характеристики стандарта DDS следующие.
1.1 Структура Pub/Sub
-
Разделение производителей и потребителей: Publisher (например, узел датчика температуры), создающий данные, и Subscriber (например, узел сохранения в базе данных, узел рендеринга пользовательского интерфейса), потребляющий данные, не обязаны знать о существовании друг друга.
-
Гибкая масштабируемость:Просто отправляя и получая данные через определенную тему в качестве промежуточного медиа, добавление новых узлов мониторинга или удаление существующих во время работы системы становится очень гибким. Это также согласуется с современными архитектурными паттернами программного обеспечения, которые максимизируют гибкость системы, отделяя ответственность команд и запросов.
1.2 QoS (Качество сервиса)
Еще одной сильной стороной DDS является QoS. Когда состояние сети нестабильно, можно детализированно на уровне узла настраивать, отправлять ли все данные без условий или быстро отправлять только последние данные, что позволяет гибко реагировать на требования промышленной среды.
2. Моделирование данных сенсоров: Оптимизация бизнес-домена
Первое, что нужно для использования ROS2, это определить стандарты данных. В ROS2 интерфейс данных определяется с помощью файлов .msg. Для удобства управления структурой данных базовым является разделение пакета сообщений и пакета логики исполнения.
2.1 Создание пакета сообщений
Перейдите в рабочее пространство (например, ~/ros2_ws/src) в терминале и создайте пакет для сообщений. Обычно для управления зависимостями используется система сборки C++, а именно ament_cmake.
ros2 pkg create --build-type ament_cmake iiot_interfaces
2.2 Определение пользовательского сообщения
Хотя публикация и подписчики не знают о существовании друг друга, они должны знать о формате данных, который будет использоваться для передачи сообщений. Определите тип данных, включая метаданные (идентификатор устройства, код состояния и т. д.), которые могут быть использованы в реальной бизнес-среде.
# interfaces/msg/SensorData.msg
string device_id # 장비 고유 식별자 (예: "CNC_Machine_01")
int32 status_code # 장비 상태 코드 (0: 정상, 1: 경고, 2: 에러)
float64 temperature # 섭씨 온도
float64 vibration_hz # 진동 주파수 (Hz)
2.3 Обновление файла настроек пакета
Необходимо изменить файлы настроек, чтобы система сборки ROS2 (colcon) могла распознавать только что созданные файлы .msg и преобразовывать их в код на Python/C++.
[ Изменение package.xml ]
<buildtool_depend>
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
</buildtool_depend>
[ Изменение CMakeLists.txt ]
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/SensorData.msg"
)
Затем сначала соберите пакет сообщений с помощью команды colcon build --packages-select iiot_interfaces.
3. Реализация узла Pub/Sub
Теперь, когда спецификации данных готовы, необходимо написать узел Python, который будет производить и потреблять данные.
3.1 Создание логического пакета
Выполняется команда для создания нового пакета Python, который будет отвечать за обработку реальных данных, используя определенные выше типы данных.
ros2 pkg create --build-type ament_python ${패키지이름} --dependencies rclpy interfaces
3.2 Узел Publisher: Публикация данных датчиков
- sensor_pub.py Создание файла: считывает данные, которые поступают с настоящих аппаратных датчиков или IIoT-оборудования (например, станков с ЧПУ), в ROS2 Роль, которая продолжает публиковать по определенной теме в сетиЭто сценарий, который выполняет.
import rclpy
from rclpy.node import Node
import random
from iiot_interfaces.msg import SensorData
class SensorPublisher(Node):
def __init__(self):
super().__init__('sensor_publisher_node')
self.publisher_ = self.create_publisher(SensorData, '/machine_data', 10)
timer_period = 0.5
self.timer = self.create_timer(timer_period, self.publish_sensor_data)
self.get_logger().info('센서 퍼블리셔 노드가 시작되었습니다.')
def publish_sensor_data(self):
msg = SensorData()
msg.device_id = "CNC_Machine_01"
msg.status_code = 0 if random.random() > 0.1 else 1
msg.temperature = round(random.uniform(40.0, 85.0), 2)
msg.vibration_hz = round(random.uniform(10.0, 100.0), 2)
self.publisher_.publish(msg)
def main(args=None):
rclpy.init(args=args)
node = SensorPublisher()
try:
rclpy.spin(node)
except KeyboardInterrupt:
node.get_logger().info('사용자에 의해 종료되었습니다.')
finally:
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
3.3 Подписчик узел: получение и обработка данных
- создание файла data_sub.py: Публишер отправил данные с датчиков на тему (/machine_data) в сетироль получения, проверки и использованияделаем.
import rclpy
from rclpy.node import Node
from iiot_interfaces.msg import SensorData
class DataProcessor(Node):
def __init__(self):
super().__init__('data_processor_node')
self.subscription = self.create_subscription(
SensorData,
'/machine_data',
self.process_data,
10
)
self.get_logger().info('데이터 프로세서 노드가 구독을 시작했습니다.')
def process_data(self, msg):
if msg.status_code != 0 or msg.temperature > 80.0:
self.get_logger().warn(f'🚨 경고! [{msg.device_id}] 온도: {msg.temperature}°C (초과)')
else:
self.get_logger().info(f'정상: [{msg.device_id}] 온도: {msg.temperature}°C')
def main(args=None):
rclpy.init(args=args)
node = DataProcessor()
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
3.4 установка.py Точка Входа регистрация
Зарегистрируйте два сценария Python в setup.py, чтобы они могли выполняться, и снова соберите рабочее пространство с помощью colcon build.
entry_points={
'console_scripts': [
'sensor_pub = data_pipeline.sensor_pub:main',
'data_sub = data_pipeline.data_sub:main',
],
},
4. Устранение неполадок и методы отладки
Даже если код выглядит идеально в среде разработки, часто возникают ситуации, когда данные не проходят из-за проблем с изоляцией сети, несовпадением типов сообщений и т. д. ROS2 предоставляет мощные инструменты CLI для отслеживания этих проблем.
Откройте несколько терминалов и запустите каждый узел (ros2 run data_pipeline sensor_pub, ros2 run data_pipeline data_sub), а затем используйте нижеуказанные инструменты для диагностики системы.
4.1 Проверка списка узлов и информации
- ros2 node list: Команда для проверки, какие узлы активны в текущей сети.
$ ros2 node list
/sensor_publisher_node
/data_processor_node
- ros2 node info: Команда для получения подробной информации о том, какие темы определенный узел публикует/подписывается. Это первая команда, которую следует проверить, если узел ведет себя неожиданно.
$ ros2 node info /sensor_publisher_node
/sensor_publisher_node
Publishers:
/machine_data: iiot_interfaces/msg/SensorData
Subscribers:
...
4.2 Проверка состояния тем
- ros2 topic list: Команда для проверки, созданы ли темы для отправки данных. (-t параметр: возможно проверить тип сообщения)
$ ros2 topic list -t
/machine_data [iiot_interfaces/msg/SensorData]
/parameter_events [rcl_interfaces/msg/ParameterEvent]
- ros2 topic info: это команда для проверки, сколько издателей и подписчиков прикреплено к соответствующей теме. Если данные не поступают, необходимо проверить, отображается ли счетчик здесь как 0.
$ ros2 topic info /machine_data
Type: iiot_interfaces/msg/SensorData
Publisher count: 1
Subscription count: 1
4.3 Проверка получения данных
- ros2 topic echo: Перед написанием кода для подписчика это команда, которая позволяет увидеть состояние сырых данных, чтобы проверить, действительно ли данные проходят через текущую тему.
$ ros2 topic echo /machine_data
device_id: CNC_Machine_01
status_code: 0
temperature: 65.42
vibration_hz: 42.11
---
4.4 Понимание через диаграмму
- rqt_graph: Вводя rqt_graph в терминале, открывается GUI-окно. Оно рисует диаграмму с состоянием подключения всех работающих узлов и тем. Это самый интуитивно понятный инструмент, который позволяет одним взглядом понять, правильно ли сконструирована архитектура системы.
5. Заключение: переход к распределенной архитектуре
Мы рассмотрели весь цикл проектирования пользовательских сообщений для использования ROS2 и реализации узлов Pub/Sub на Python для отладки.
Основная идея ROS2 заключается в разделении каждого модуля системы независимо друг от друга через асинхронную связь на основе DDS. Это позволяет издателю, собирающему данные с датчиков, и подписчику, который их обрабатывает, обмениваться данными надежно, не беспокоясь о состоянии друг друга.
Архитектура ROS2 предлагает не только ответ на вопрос "Как отправлять данные с датчиков?", но и способы безопасного разделения и расширения модулей, когда система становится более сложной.
Rookie