Neste tutorial, vamos ver como configurar um mapa utilizando um sensor Lidar em Python. O sensor Lidar é utilizado para encontrar as suas coordenadas no espaço e para mapear.
Descrição do sensor Lidar
O sensor lidar é um sensor de distância a laser acoplado a um motor que o faz rodar. Comporta-se como um radar, detectando obstáculos a 360 graus e mapeando o espaço. É frequentemente utilizado em robótica para mapear e encontrar o seu caminho num ambiente e permitir o movimento autónomo.
O sensor Lidar utiliza uma placa de interface série para o ligar a um computador através de uma porta USB.
Para saber a que porta o dispositivo está ligado, vá ao Gestor de Dispositivos na secção Portas (COM e LPT) (aqui com3).

Testar o Lidar com a ferramenta oficial
A interface da ferramenta pode ser descarregada a partir do sítio Web oficial. Esta ferramenta permite-lhe visualizar os mapas obtidos com Lidar.
Uma vez iniciado o software, basta selecionar a porta do dispositivo e o modelo do Lidar. Quando o Lidar estiver ligado, pode iniciar a aquisição.

Instalar o pacote Python
Para utilizar o sensor Lidar com Python, utilizamos a biblioteca PyLidar3.
python -m pip install Pylidar3
Script de teste Lidar
Para verificar se o Pylidar foi instalado, pode utilizar o seguinte script, que mostra simplesmente as informações do dispositivo.
import PyLidar3
port = "COM3" #input("Enter port name which lidar is connected:") #windows
Obj = PyLidar3.YdLidarX4(port)
print("connecting to {}".format(port))
ret = Obj.Connect()
if(1):
print(ret)
print("device info: ",Obj.GetDeviceInfo())
Obj.Disconnect()
else:
print("Error connecting to device")
Apresentação do resultado da digitalização
Para o nosso primeiro mapa, vamos inicializar o objeto PyLidar3 e ligar-nos ao dispositivo
Obj = PyLidar3.YdLidarX4(port) ret = Obj.Connect()
De seguida, vamos definir alguns parâmetros de digitalização:
- duração da digitalização scanDuration
- limiar de dados a registar dataThr
- winLim limite da janela
Finalmente, vamos executar a medição lidar e apresentar a aquisição com matplotlib
import PyLidar3
import matplotlib.pyplot as plt
import math
import time
#init lidar
port = "COM3" #input("Enter port name which lidar is connected:") #windows
Obj = PyLidar3.YdLidarX4(port) #PyLidar3.your_version_of_lidar(port,chunk_size)
ret = Obj.Connect()
print(ret)
#ret = Obj.Connect()
#print(ret)
#parameters
scanDuration = 30 #scan for 30 seconds
dataThr = 1000 # disgard data below this value
winLim = 5000 # window limit in X and Y
#init data list on 360deg
x=[]
y=[]
for _ in range(360):
x.append(0)
y.append(0)
if(1):
deviceInfo = Obj.GetDeviceInfo()
print("device info : ",deviceInfo)
gen = Obj.StartScanning()
t = time.time() # start time
while (time.time() - t) < scanDuration:
data = next(gen)
for angle in range(0,360):
if(data[angle]>dataThr):
#x[angle] = data[angle] * math.cos(math.radians(angle))
#y[angle] = data[angle] * math.sin(math.radians(angle))
x[angle] = (x[angle] + data[angle] * math.cos(math.radians(angle))) / 2
y[angle] = (y[angle] + data[angle] * math.sin(math.radians(angle))) / 2
plt.clf()
plt.axis([-winLim,winLim,-winLim,winLim])
plt.title("Model: X4 Firmware: {} Hardware: {} SN: {}".format(deviceInfo['firmware_version'], deviceInfo['hardware_version'],deviceInfo['serial_number']))
plt.scatter(y, x, c='r', s=8)
plt.draw()
plt.pause(0.1)
Obj.StopScanning()
Obj.Disconnect()
else:
print("Error connecting to device")
plt.show()
Resultados
Depois de o script ter sido executado, podemos ver o processo de mapeamento em ação e o mapa a ser atualizado em tempo real.

Gestão de Lidar com threading
É possível gerir a medição num processo diferente da visualização para melhorar a fluidez. Como exemplo, utilizamos a biblioteca de threading. Vamos criar uma função de aquisição de dados scan(), que colocaremos numa thread.
threading.Thread(target=scan).start()
Isto significa que podemos processar os dados cartográficos sem interromper a aquisição da medição.
import PyLidar3
import matplotlib.pyplot as plt
import math
import time
import numpy as np
import threading
#init lidar
port = "COM3" #input("Enter port name which lidar is connected:") #windows
Obj = PyLidar3.YdLidarX4(port) #PyLidar3.your_version_of_lidar(port,chunk_size)
ret = Obj.Connect()
print(ret)
#ret = Obj.Connect()
#print(ret)
#parameters
scanDuration = 30 #scan for 30 seconds
dataThr = 1000 # disgard data below this value
winLim = 5000 # window limit in X and Y
buffnum = 1 # matrix size to average position
#init data list on 360deg
x = np.zeros((buffnum, 360))
y = np.zeros((buffnum, 360))
def scan():
nb=0
while is_scanning:
data = next(gen)
if nb>=buffnum-1:
nb=0
else:
nb+=1
for angle in range(0,360):
if(data[angle]>dataThr):
x[nb][angle] = data[angle] * math.cos(math.radians(angle))
y[nb][angle] = data[angle] * math.sin(math.radians(angle))
if(1):
deviceInfo = Obj.GetDeviceInfo()
print("device info : ",deviceInfo)
gen = Obj.StartScanning()
t = time.time() # start time
is_scanning = True
threading.Thread(target=scan).start()
while (time.time() - t) < scanDuration:
xmean = np.mean(x, axis=0)
ymean = np.mean(y, axis=0)
plt.clf()
plt.axis([-winLim,winLim,-winLim,winLim])
plt.title("Model: X4 Firmware: {} Hardware: {} SN: {}".format(deviceInfo['firmware_version'], deviceInfo['hardware_version'],deviceInfo['serial_number']))
#plt.scatter(y,x,c='r',s=8)
plt.scatter(ymean,xmean,c='r',s=8)
plt.draw()
plt.pause(0.05)
is_scanning = False
Obj.StopScanning()
Obj.Disconnect()
else:
print("Error connecting to device")
plt.show() #keep figure open at the end
Aplicação
- Mapeamento de um espaço
- Posicionar um robô no espaço e evitar obstáculos