home search
Perception
LiDAR
ROS
[LiDAR] RPLIDAR A3 사용법
2022. 01. 10
사용 환경 및 장비

Ubuntu 18.04 LTS / ROS Melodic / RPLIDAR A3

👋RPLIDAR 기기 특징

  • 라이다의 샘플 비율(sample rate, 초당 샘플 수)은 로봇이 얼마나 빠르고 정확하게 map을 만들 수 있는가 이며, RPLIDAR A3는 16,000회(16K)의 값을 갖는다. 이전 모델인 A1은 2K/4K, A2는 4K/8K이다.
  • 탐지 범위는 25m까지 지원하며, 시계방향으로 360° 전방향 회전하여 스캔하여 물체의 외곽선을 생성한다.
  • 두 가지 모드가 있어, enhanced mode와 outdoor mode가 있다.
    • Enhanced mode: 실내 환경에서의 최적/최대 기능을 지원한다.
    • Outdoor mode: 실외 환경에서 햇빛의 간섭에 영향을 덜 받도록 한다. 흰/검은 물체를 안정적으로 탐지하게 한다.

  • 광삼각법(laser triangulation ranging principle)을 사용한다. 광삼각법에 대한 참고사항은 아래 참고 자료에 링크를 걸어두었다.
  • 스캐닝 모터의 속도를 제어함으로써 사용자의 편의에 따라 스캔 주파수를 2hz에서 10hz까지 조절할 수 있다.
  • 다른 라이다가 그러하듯, SLAM에 유용히 쓰일 수 있다.

SLAM(Simultaneous localization and mapping)

용어를 번역하자면 동시적 위치추정 및 지도작성이다. SLAM은 자동차, 로봇 등이 미지의 환경(공간)에서 이동함과 동시에 주변을 탐색하며, 그 공간의 지도를 그리고 현 위치를 추정하는 개념이다.


📗rplidar ROS package

개요

rplidar는 RPLIDAR의 제조사인 Slamtec에서 관리하는 ROS 패키지로, 2D 레이저 스캐너 RPLIDAR A1, A3, A3 모델의 기본적 디바이스 핸들링을 지원한다. GitHub에서 소스를 다운받을 수 있다. 본인 ROS의 버전을 잘 살펴서 다운받자.

드라이버는 senser_msgs/LaserScan 데이터를 퍼블리시한다. 해당 내용은 아래서 자세히 다룬다.

ROS Node

rplidarNode는 RPLIDAR의 드라이버로, RPLIDAR의 SDK에서 raw scan 결과를 읽어 ROS LaserScan 메시지로 바꾸어준다.

SDK(Software Development Kit)

SDK(Software Development Kit)는 소프트웨어 개발 키트로, 하드웨어 플랫폼이나 운영체제(Operating System, OS), 프로그래밍 언어 제작사가 제공하는 도구이다. 기본적으로는 컴파일러, 디버거, API(Application Programming Interface) 등이 포함된다. 개발자는 SDK를 이용하여 특정 플랫폼이나, 시스템, 프로그래밍 언어에 따라 애플리케이션을 개발할 수 있다.

퍼블리시 토픽

노드는 레이저로부터 토픽 /scan을 퍼블리시하며, 메시지 형태는 sensor_msgs/LaserScan이다. 하이퍼링크를 따라가 직접 살펴보아도 좋다.

해당 메시지 파일을 자세히 살펴보자. 아래 내용은 sensor_msgs/LaserScan.msg의 Raw Message Definition을 그대로 가져온 것이다.

# Single scan from a planar laser range-finder
#
# If you have another ranging device with different behavior (e.g. a sonar
# array), please find or create a different message, since applications
# will make fairly laser-specific assumptions about this data

Header header            # timestamp in the header is the acquisition time of 
                         # the first ray in the scan.
                         #
                         # in frame frame_id, angles are measured around 
                         # the positive Z axis (counterclockwise, if Z is up)
                         # with zero angle being forward along the x axis
                         
float32 angle_min        # start angle of the scan [rad]
float32 angle_max        # end angle of the scan [rad]
float32 angle_increment  # angular distance between measurements [rad]

float32 time_increment   # time between measurements [seconds] - if your scanner
                         # is moving, this will be used in interpolating position
                         # of 3d points
float32 scan_time        # time between scans [seconds]

float32 range_min        # minimum range value [m]
float32 range_max        # maximum range value [m]

float32[] ranges         # range data [m] (Note: values < range_min or > range_max should be discarded)
float32[] intensities    # intensity data [device-specific units].  If your
                         # device does not provide intensities, please leave
                         # the array empty.
  • Header header
    • 자료형 Headerstd_msgs/Header.msg에 정의되어 있으며, unint32 seq, time stamp, string frame_id로 구성되어 있다.
    • time: 스캔하여 데이터를 획득한 시간
  • float32 angle_min [rad] : 스캔의 시작 각도
  • float32 angle_max [rad] : 스캔의 끝 각도
  • float32 angle_increment [rad] : 측정되는 각의 단위이다. 0.01이라면 0.01라디안 마다 측정이 이루어지는 것이다.
  • float32 scan_time [sec] : 측정되는 시간 간격
  • float32 range_min [m] : 최소 range(거리) 값
  • float32 range_max [m] : 최대 거리 값
  • float32[] ranges [m]
    • 최소 거리(range_min) 이상, 최대 거리(range_max) 이하의 거리 값들을 말한다.
    • 최소 각도(angle_min)부터 최대 각도(angle_max)까지 단위 각도(angle_increment)씩 분할한 하나하나를 요소로 하는 리스트이다.
    • 각 요소에는 해당 각도에서 측정한 거리가 담겨 있다. 장애물과 부딪히지 않았다면 inf로 표시된다.
    • [inf, inf, …, 1.3, 1.4, 1.3, …, inf, inf] 처럼 표시될 것이다.
    • 0.1°씩 측정하고 최소 각도가 -180°라면, 457번째 요소는 -180 + 0.1 * 457 = -134.3°도이며, 해당 각도에서 ranges[457]의 값은 -134.3°도에서 측정된 물체까지 거리 값이다.
  • float32[] intensities : 레이저가 부딪혀 돌아오는 강도를 담고 있다. 지원하는 기기에서만 표시되고, 그 외에서는 빈 배열이다.

위 사진은 RPLIDAR A3를 연결해 /scan 데이터를 rostopic echo 명령을 통해 출력한 결과이다. 주요 값의 예는 아래와 같다.

data value
angle_min -3.14159274101
angle_max 3.14159274101
angle_increment 0.00322876940481
range_min 0.15000000596
range_max 25.0

각도 및 거리의 표기

  • Z축 양의 방향으로(반시계방향, 오른손 엄지를 위로 했을 때 손가락이 감아지는 방향) 각도를 증가시킨다.
  • 0°는 x축을 따라 뻗어진다.

파라미터

라이다 작동에 필요한 파라미터는 아래와 같다. 해당 파라미터들은 rplidar.launch 파일에 <param> 태그로 나타나 있다.

파라미터 자료형 default 값 설명
serial_port string /dev/ttyUSB0 라이다가 연결된 시리얼 포트
serial_baudrate int 115200 시리얼 포트의 보 레이트. 통신 속도
frame_id string laser_frame 기기의 프레임 ID
inverted bool false 라이다가 inverted되어 마운드 되었는가 (뒤집어졌는가)
angle_compensate bool false 기기가 시야각 보상(angle compensation)이 필요한가
scan_mode string std::string() 스캔 모드
Baud Rate

보 레이트(Baud Rate)는 초당 전송 신호 요소 개수로, 심볼(Symbol, 의미 있는 데이터 묶음)을 얼마나 전송할 수 있는가를 나타낸다. 하나의 심볼을 쉽게 하나의 ‘데이터 묶음’이라고 표현하자. 시리얼 통신에서는 8bit를 데이터 묶음이라 한다. 그렇다면 100 baud rate라면 1초에 100개의 데이터 묶음, 즉 8*100=800bit를 전송한다는 이야기이다.


😎 작동

[1] GitHub에서 패키지를 /catkin_ws/src에 내려받고 빌드를 해준다.

$ git clone https://github.com/Slamtec/rplidar_ros
$ catkin_make 또는 cm

[2] USB 포트에 라이다를 연결한다. [3] 터미널에서 USB 포트를 확인하고, 권한을 허용한다.

$ ls -l /dev | grep ttyUSB
$ sudo chmod 666 /dev/ttyUSB0

[4] .launch 파일을 실행시켜 라이다를 작동시킨다. 실행 전, 실행할 파일에 기기 모델에 따라 파라미터 baudrate를 수정해주어야 한다. A1, A2 모델은 기본값으로 되어 있는 115200를, A3는 256000으로 변경해야 한다. 모든 .launch 파일은 /rplidar_ros/launch에 있다. 모델에 따라 나뉘어 파일 엄청 많다.

[4-1] Rviz가 함께 실행되는 버전: launch 파일을 실행함과 동시에 Rviz 창이 자동으로 켜진다. 필자가 사용하는 모델은 A3이므로 view_rplidar_a3.launch 파일을 실행시켰다.

$ roslaunch rplidar_ros view_rplidar_a3.launch

[4-2] 라이다 작동만 하는 버전: 가장 기본적 launch 파일이다.

$ roslaunch rplidar_ros rplidar.launch

[5] 추가적으로 라이다가 센싱한 값을 터미널에서 확인하고 싶다면 다른 터미널에서 아래 명령을 실행해보자.

# (1) 패키지에 포함된 스크립트를 실행함. 라이다가 받는 ranges[] 데이터를 나타냄
$ rosrun rplidar_ros rplidarNodeClient

# (2) rostopic echo로 /scan 메시지를 직접 출력함. rostopic list로 토픽 목록 확인 후 실행해보자.
$ rostopic echo /scan

위 우측 사진은 rplidarNodeClient를 작동시켰을 때의 터미널 출력이다. -180°(-3.14rad)부터 180°(3.14rad)까지에서의 인덱스 값과 거리값을 담고 있음을 알 수 있다.

😛 USB 포트 이름 remap

USB 허브를 이용하는 등 복수 개의 센서를 연결할 경우 매번 ttyUSB*의 번호가 바뀐다. 매번 이 번호를 확인하고 lauch 파일에서 바꿔주기에는 매우 번거롭다. 때문에 이를 이름으로 고정하면 매우 편리하다.

자세한 이론적 내용은 [Linux] USB 장치 이름 고정하기: udev 설정, Symbolic Link(심볼릭 링크) 만들기에 설명해두었다.

간단히 하자면, /rplidar_ros/script에 있는 rplidar.rules 파일을 /etc/udev/rules.d로 복사하여, ttyUSB*로 표시되던 라이다의 이름을 rplidar로 변경하며 권한을 777으로 한다는 뜻이다.

$ cd /catkin_ws/src/rplidar_ros
$ ./scripts/create_udev_rules.sh

결과적으로 이름이 바뀌었는지 확인하자.

$ ls -l /dev | grep rplidar

결과를 확인하면 rplidar라는 이름이 생성되었고, ttyUSB0로 연결이 되어 있다고 한다. 만약 연결 포트가 바뀌어 ttyUSB1로 변경되었대도 라이다는 여전히 rplidar로 뜰 것이다. 만약 rplidar라고 나오지 않는다면 컴퓨터를 재부팅해보자.

라이다의 이름이 바뀌었으니 rplidar.launch에서 파라미터의 값을 /dev/ttyUSB0에서 /dev/rplidar로 바꾸어주어야 한다.

<param name="serial_port" type="string" value="/dev/rplidar"/>

이름을 바꾸어주었으니 launch파일을 다시 실행해도 문제가 없을 것이다.


🧐 Rviz 시각화

위에서 view_rplidar_a3.launch를 실행시켰을 때 rviz가 동시에 실행되었었다. 스캔 결과가 점으로 표시되므로 어디가 어디인지 판별하기 힘들 때가 있으니, 축을 표시해보자.

좌측 하단의 Add 버튼을 클릭한 뒤, 나타나는 창에서 Axis를 선택하고 OK를 클릭해 추가한다.

화면 상에 축이 보이고, 마우스를 이용해 뷰를 조절할 수 있다.

X축은 빨강, Y축은 초록, Z축은 파랑색이다.


참고문헌

arrow_upward arrow_downward
loading