Лидар Delta2A от 3iRobotics. Пример на python

Delta2A — доступный сканирующий дальномер от Китайской компании 3iRobotics. В русском языке такие устройства часто называют лидарами, хотя дословный перевод английского слова — LiDAR, означает лишь непосредственно сам измеритель расстояния. Но мы будем всё же называть его лидаром, по то же причине, по которой сканирующий радиодальномер называем радаром.

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

Существуют дальномеры сканирующие пространство в 3-х измерениях. Цены на подобные устройства измеряются тысячами единиц иностранной валюты. Хотя, в последние годы, классические 2D и 3D лидары стали постепенно вытесняться так называемыми SolidState лидарами (они же — камеры глубины), которые являются более долговечными за счёт отсутствия движущихся частей, и по этой же причине менее дорогими.

Delta 2A может подключаться к компьютеру через USB (виртуальный COM-порт) или к микроконтроллеру через UART. Данные передаются со скоростью 230400 бод. С учетом того, что для хранения массива точек потребуется ещё и много оперативной памяти, к Arduino-подобным системам его подключать не имеет смысла. Потребуется ESP или STM32 с соответствующими параметрами. А лучше всего, иметь на борту робота полноценный, или хотя бы одноплатный компьютер.

Аппарат Delta2A обладает стандартными для устройств подобного класса характеристиками:

  • напряжение питания: 5 В;
  • рабочий ток: 500 мА;
  • частота вращения: 6,2 Гц;
  • измерения каждые: от 0,3 до 0,8 °;
  • измеряемые расстояния: от 0,13 до 8 м;
  • погрешность измерений: менее 1% (на расстоянии 5м);
  • DCV: менее 0,2%; 
  • интерфейс: UART (скорость 230400 бод);
  • длина волны лазера: 780 нм;
  • диапазон рабочих температур: от 0 до 45 °C;
  • вес: 175 г;
  • размеры: 107 x 76 x 53 г.

В этой статье мы рассмотрим протокол общения датчика с вычислителем и посмотрим его в работе.

Лидар Delta2A и аналогичные сканирующие дальномеры, а также камеры глубины, можно купить в интернет-магазине RobotClass:

В корзину

Протокол лидара Delta2A

За каждый оборот дальномер выдаёт серию из 16 пакетов данных. Каждый пакет представляет собой набор из некоторых служебных данных, параметров для оценки целостности пакета и массива значений измеренных расстояний (будем называть их точками). Длина пакета может варьироваться, в зависимости от скорости вращения мотора. В среднем, при питании о компьютера, каждый пакет содержит 51-52 точки.

С точки зрения программирования, пакет — это набор байт, из которого необходимо выделить нужные значения.

Индекс байтаПримерОписание
00xAAИндикатор начала пакета, всегда равен 0xAA
1-20x00, 0x91Длина пакета без учёта двух байт CRC, но включая индикатор начала
30x01Версия протокола: 0x01 — рабочий, 0x00 — ошибка
40x61Типа пакета
50xADИндикатор начала полезных данных
6-70x00, 0x47Длина полезных данных
80x82Скорость вращения мотора (множитель 0,05): 0x82 = 130 * 0,05об/с = 6,5об/с
9-100x00, 0x87Смещение угла для первого измерения в пакете (множитель 0,01)
11-120x69, 0x78Начальный угол в пакете (множитель 0,01): 27000 * 0,01 = 270
130x46Уровень сигнала №1
14-150x21, 0x3AДистанция №1 (множитель 0,25): 8506 * 0,25 = 2126мм
3N+20x5EУровень сигнала №47
3N+3, 3N+40x5E, 0x32Дистанция №47: 2414 * 0,25 = 6028мм
3N+5, 3N+60x35, 0xBCСумма всех байтов пакета (CRC), за исключением текущих двух

Программа

Специально для этого дальномера я написал небольшую библиотеку для Python, которая позволит получить данные в удобоваримом для дальнейших манипуляций виде. А именно, в виде numpy массива пар данных [угол, дистанция]. Для работы библиотеки потребуется дополнительно установить пакеты: numpy и matplotlib

В первом примере будем сохранять данные с лидара в файл формата CVS

import LidarDelta2A
import numpy as np

port = 'COM10'
lidar = LidarDelta2A.LidarDelta2A(port, baudrate = 230400) 



while not ready:
    data = lidar.handleData()

np.savetxt('output.csv', data, delimiter=',', fmt='%f')

COM10 — это порт, который определился в Windows при подключении лидара. В результате запуска скрипта, получим файл output.csv с результатами измерений за один оборот.

Второй пример интереснее — будем выводить точки на экран. Для этого потребуется с помощью matplotlib построить график типа scatter (набор несвязных точек). Если это делать в лоб, то мы получим весьма лагующую программу, даже на мощных ПК. Для ускорения используем функцию blit.

import LidarDelta2A
import signal
import time
import matplotlib.pyplot as plt
import math
import numpy as np

port = 'COM10'
lidar = LidarDelta2A.LidarDelta2A(port, baudrate = 230400) 

points = np.zeros((16*52,2))

def on_close(event):
    print('Closed window!')
    ready = 0

def signal_handler(sig, frame):
    print('Pressed Ctrl+C!')
    global ready
    ready = 0

signal.signal(signal.SIGINT, signal_handler)

fig, ax = plt.subplots()

fig.canvas.mpl_connect('close_event', on_close)

ln = ax.scatter(points[:,0], points[:,1], animated=True)
ax.set_xlim([-5000,5000])
ax.set_ylim([-5000,5000])

plt.show(block=False)
plt.pause(0.1)

bg = fig.canvas.copy_from_bbox(fig.bbox)
ax.draw_artist(ln)
fig.canvas.blit(fig.bbox)

to = 0.01
t = time.time()
nxt = time.time() + to

ready = 1
while ready:
    data = lidar.handleData()
    for i,v in enumerate(data):
        points[i] = [v[1] * math.cos(math.radians(v[0])), v[1] * math.sin(math.radians(v[0]))]

    if time.time() > nxt:
        nxt = time.time() + to

        fig.canvas.restore_region(bg)
        ln.set_offsets(points)
        ax.draw_artist(ln)
        fig.canvas.blit(fig.bbox)
        fig.canvas.flush_events()

plt.close("all")
lidar.stop()

Запускаем скрипт и получаем примерно такую картину. Результат достаточно устойчив.

Лидар Delta2A python matplotlib

Дальнейшие размышления

Сам по себе массив точек с лидара не имеет особой ценности. Разве что можно использовать его как детектор препятствий. Основное применение сканирующих дальномеров — это SLAM, метод одновременной локализации и построения карты. То есть благодаря точкам с лидара на движущемся роботе можно построить карту помещения и ещё определить координаты робота на этой карте.

Производитель Delta2A придаёт к своему изделию SDK, в котором есть и пакет для ROS, как раз для целей увязывания его со SLAM. К сожалению, всё SDK на китайском языке.

Полезные ссылки

Библиотека LidarDelta2A

https://github.com/robotclass/LidarDelta2A

SDK от 3iRobotics

https://download.robotclass.ru/SDK/Delta2A/Delta-2A.rar


Изменено:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.