Сенсоры в ROS: лидар, камера, IMU, одометрия
Робот действует на основе данных датчиков — разбираем основные сенсоры и их сообщения в ROS.
Сенсор (датчик) в ROS — это узел-драйвер, который читает физическое устройство и публикует измерения в топик стандартного типа из
sensor_msgs.
Четыре главных датчика мобильного робота
| Датчик | Сообщение | Что даёт | Частота |
| Лидар | sensor_msgs/LaserScan | расстояния по кругу | ~10 Гц |
| Камера | sensor_msgs/Image | кадры изображения | ~30 Гц |
| IMU | sensor_msgs/Imu | ускорения и угловые скорости | ~100 Гц |
| Одометрия | nav_msgs/Odometry | оценку позы по колёсам | ~50 Гц |
Лидар и LaserScan
Лидар — главный датчик навигации. Он крутится и измеряет расстояние до препятствий по кругу. Сообщение LaserScan хранит угол начала, угловой шаг и массив ranges — расстояния для каждого луча. Зная угол и расстояние, легко получить координаты точки препятствия.
IMU и одометрия — основа оценки движения
IMU (инерциальный датчик) меряет ускорения и повороты, но накапливает большую ошибку при интегрировании. Одометрия считает перемещение по оборотам колёс — точнее на коротком пути, но дрейфует из-за проскальзывания. На практике их объединяют (sensor fusion), получая оценку лучше, чем у каждого по отдельности.
Считаем одометрию сами
Одометрия дифференциального привода — чистая математика, без ROS. По пройденному пути левого и правого колеса считаем новое положение робота. Этот код можно запустить:
import math
# параметры робота
WHEEL_BASE = 0.32 # расстояние между колёсами, м
# старое положение
x, y, theta = 0.0, 0.0, 0.0
# за шаг колёса проехали (м)
d_left = 0.10
d_right = 0.12
# средний путь центра и изменение угла
d_center = (d_left + d_right) / 2
d_theta = (d_right - d_left) / WHEEL_BASE
# новое положение
x += d_center * math.cos(theta + d_theta / 2)
y += d_center * math.sin(theta + d_theta / 2)
theta += d_theta
print(f'x = {x:.3f} м')
print(f'y = {y:.3f} м')
print(f'theta = {math.degrees(theta):.1f} град')Вывод:
x = 0.110 м y = 0.003 м theta = 3.6 град
Правое колесо проехало чуть больше — робот сместился вперёд и слегка повернул влево. Именно так узел odometry на каждом шаге обновляет позу и публикует её в /odom.
Системы координат датчиков
Каждый датчик публикует данные в своём кадре (frame_id): лидар — в laser, камера — в camera_link, IMU — в imu_link. Чтобы свести их вместе (например, наложить препятствия с лидара на карту), нужен TF2. Поэтому корректные frame_id и stamp в Header сообщений датчиков — обязательны.
Как работает под капотом
Драйвер датчика — это узел, который через USB, последовательный порт или Ethernet общается с железом, читает сырые байты, преобразует их в физические величины и упаковывает в сообщение ROS с правильным Header. Частота публикации ограничена самим устройством: лидар физически крутится 10 раз в секунду, быстрее данных не будет. Камеры порождают огромный поток данных, поэтому для них особенно важен QoS best effort — терять кадры допустимо, лишь бы не копить задержку.
Частые ошибки
- Доверять голой одометрии. Она дрейфует; для точной позы нужна локализация или слияние датчиков.
- Игнорировать единицы и углы. Расстояния в метрах, углы в радианах — это соглашение ROS.
- Неверный frame_id датчика. Данные «повиснут» в воздухе, TF2 не свяжет их с роботом.
Итоги
- Датчики публикуют в стандартные типы sensor_msgs/nav_msgs.
- Лидар (LaserScan) — основа навигации; IMU и одометрия оценивают движение.
- Одометрию дифференциального привода считают по путям колёс.
- Каждый датчик в своём кадре; TF2 сводит их вместе.