제 구매처 : https://www.aliexpress.com/item/4001253880158.html?spm=a2g0s.9042311.0.0.51cd4c4dFsfQSj&fbclid=IwAR1rvYLt_6CMDVgvjOSD-1njVUQhOB2RBI6-sXNhqkfqUt-XzrxOjSF72IM 

 

13.55US $ |laser radar 360 degree laser radar scanning distance measuring sensor diy wireless transmission infrared data transmi

Smarter Shopping, Better Living! Aliexpress.com

www.aliexpress.com

윗 제품을 한 번 사서 살려봤는데, 제 능력보다는 어떤 이가 어제 딱 성공을 해서 웹에 올려놓은 덕에 저도 따라서 베껴서 성공했습니다.

 

동영상 페북 링크 : https://www.facebook.com/permalink.php?story_fbid=4071094949677690&id=100003316754962&notif_id=1626497694343936&notif_t=feedback_reaction_generic&ref=notif 

 

로그인 또는 가입하여 보기

Facebook에서 게시물, 사진 등을 확인하세요.

www.facebook.com

 

 

 

중요한 내용 : 

     제품 마크 : Radar_MB_1R2T_V1.5.8  or V.1.5.9 <==  제품 밑에 반드시 이 마크가 있는 제품에 국한된 내용입니다.

     헤더 : AA 55 28 28

     시리얼 속도 : 153600

     처음 테스트용 라이다와 PC의 연결은 흔한 $2짜리 USB<=>UART 모듈을 사용하시면 됩니다.

     핀 연결 : 저기 속도 조정 핀은 연결 안해도 됩니다.   

     Serial은 3.3V

     전원은 5V

중요한 화일들 :  화일 이름은 편하게 각자 정하면 됩니다.  저는 my_lidar.py라고 부릅니다.

   이게 메인 Working Code입니다. 

 

   Credit : Vidicon from Discord, Subject : zRGJcqa, #radar_mb_1r2t

 

아래 코드는 matplotlib를 사용해서 너무 느려서, 아래 코드를 사용하지 말고  PyQtGraph 라이브러리를 사용해서 완전히 다시 만든 코드를 사용하십시요.   속도가 100배는 차이가 나는 것 같습니다. 제가 직접 PyQtGraph를 배워가며 만들었습니다.

엄청 빠른 새 코드는 다음 링크에 있습니다. https://wise-self.tistory.com/78?category=1044077

 

아래 코드는 그냥 구조를 보기 좋으니 데이타 구조가 어떤가를 보기용으로만 쓸만합니다.

주의사항은 serial 라이브러리 설치시 pip3 install pyserial 을 해야지, pip3 install serial을 하시면 안됩니다.  (중요)

#!/usr/bin/env python3
import matplotlib.pyplot as plt
import sys
import serial
import time
from enum import Enum
import math

SERIAL_PORT = "/dev/ttyUSB0"

class State(Enum):
	START1 = 0
	START2 = 1
	HEADER = 2
	DATA = 3


def readbytes(file, count):
	data = ser.read(count)
	if len(data) != count:
		print("End of file")
		return False
	return data


if __name__ == "__main__":
		
	try:
		ser = serial.Serial(SERIAL_PORT, 153600, timeout=0.1) 
	except:
		print("could not connect to device")
		exit()
	counter = 0
	rmax = 10.0
	
	dist = plt.subplot(111, polar = True)
	
	data_lenght = 0
	start_angle = 0
	stop_angle = 0


	run = True
	step = (-math.pi*2) 
	try:
		state = State.START1
		while run:

			if state == State.START1:
				data = ser.read(1)
				#if data == False:
				#	break
				if data[0] == 0xAA:
					state = State.START2
				# else:
					# print("sync")
				continue
			elif state == State.START2:
				data = ser.read(1)
				#if data == False:
				#	break
				if data[0] == 0x55:
					state = State.HEADER
				else:
					state = State.START1
					# print("sync2")
				continue
			elif state == State.HEADER:
				data = ser.read(8)
				pack_type = data[0]
				data_lenght = int(data[1])
				start_angle = int(data[3] << 8) + int(data[2])
				stop_angle = int(data[5] << 8) + int(data[4])
				#unknown = int(data[7] << 8) + int(data[6])

				diff = stop_angle - start_angle
				if stop_angle < start_angle:
					diff =  0xB400 - start_angle + stop_angle

				angle_per_sample = 0
				if diff > 1 and (data_lenght-1) > 0:
					angle_per_sample = diff / (data_lenght-1)
				
				# print("[{}]\ttype:{},\tlenght {},\tstart: {},\tstop: {}, \tdiff: {} \tdiff: {}".format(counter, pack_type, data_lenght, start_angle, stop_angle, diff, angle_per_sample), end="\n")
				
				counter += 1
				if pack_type != 40:
					counter = 0

				state = State.DATA
				continue
				
			elif state == State.DATA:
				state = State.START1
				#read data
				data = ser.read(data_lenght * 3)
				#data = readbytes(f, data_lenght * 3) 
				if data == False:
					break
		
				angle_list = []
				distance_list = []
				quality_list = []
		
				for i in range(0, data_lenght):
					
					data0 = int(data[i*3 + 0])
					data1 = int(data[i*3 + 1])
					data2 = int(data[i*3 + 2]) 
					distance = (data2  << 8) + data1

					angle = (start_angle + angle_per_sample * i)
					anglef = step * (angle / 0xB400) 
					angle_list.append(anglef)

					distance_list.append(distance / 1000) # div to convert mm to meter
					quality_list.append(data0) 

				
				if pack_type != 40:
					plt.cla()
					continue # package contance no data skip plot

				dist.scatter(angle_list, distance_list, c = "purple", s = 3) # dot
				# dist.plot(angle_list, distance_list, c = "purple") # line 
				dist.scatter(angle_list, quality_list, c = "red", s = 1)

				dist.set_theta_offset(math.pi / 2)
				dist.set_rmax(rmax)
				dist.set_rmin(0.0)
				plt.pause(0.01)
				rmax = dist.get_rmax()
				
			else:
				print("error")
	

	except KeyboardInterrupt:
		run = False
		exit()

최근에 물건을 3개를 더 받았는데 그 중 2개가 Radar_MB_1R2T_V1.5.8  이 아니고 Radar_MB_1R2T_V1.5.9 이었습니다.

그리고 그 중 1개는 윗 코드로는 작동을 안해서 원인을 찾아보니, 오는 신호에서 type 이 다른 제품들은 40이었는데 이 한개만 60번으로 나오더군요.   찾아낸 방법은 코드의 라인 84번의 #를 풀면 라이다에서 나오는 신호를 분석해서 스크린에 뿌려줍니다.

그래서 그 제품 하나는 따로 코드를 만들었습니다.  라인 87과 120에 type의 값을 40에서 60으로 바꿨더니 작동하더군요.

======================================================================

저번에 이 라이다의 문제를 해결한 이가 이 라이다의 ROS v.1용 드라이버도 완성했습니다. 현재는 초벌입니다.

 https://github.com/Vidicon/mb_1r2t_ros

 

GitHub - Vidicon/mb_1r2t_ros: ROS1 driver for the mb_1r2t lidar

ROS1 driver for the mb_1r2t lidar. Contribute to Vidicon/mb_1r2t_ros development by creating an account on GitHub.

github.com

 

'폐품 Lidar 살리기' 카테고리의 다른 글

ESP32로 곧바로 라이다에 연결하기.  (0) 2022.02.24

+ Recent posts