여러 대의 USB 장치를 연결한다면 ttyUSB0, ttyUSB1, ttyUSB2, …, ttyACM0, ttyACM1, …처럼 번호가 부여된다. 그러나 이 번호는 컴퓨터를 재부팅하거나, USB 포트에 재연결하는 등 매번 변경된다. launch
파일에서 serial_port 값을 파라미터로 넣을 때 등 많은 경우에 이 값을 사용하는데, 매번 바뀌면 매번 조회하고 매번 모든 파일에 일일이 들어가 수정해주어야 한다.
따라서 이 문제를 해결하기 위해 장치마다 특정한 이름으로 고정하고 권한을 허용해줄 수 있는 방법이 있다. 예를 들어 카메라를 ttyUSB0
등이라 하지 않고 ttyCamera
라 하는 것이다.
이 방식을 간단히 udev 설정, 혹은 심볼릭 링크를 만들기라고 한다.
udev은 리눅스 커널을 위한 장치 관리자로, 주로 /dev 디렉터리의 장치 노드를 관리한다. 또한 하드웨어 장치가 시스템에 추가되거나 제거되는 동안 발생한 모든 사용자 공간 이벤트들을 관리한다. 우리에게는 USB를 컴퓨터에 꽂았을 때 연결된 기기를 관리한다고 보면 된다.
심볼릭 링크(Symbolic Link)는 말 그대로 무언가를 의미/상징하는 링크로, Winodws의 바로가기와 비슷하다 볼 수 있다. 링크를 연결해 원본 파일을 직접 사용하는 것처럼 만들 수 있다. 링크가 연결된 두 파일은 삭제, 수정 등 작업이 모두 동일하게 공유된다.
📌 사용 장비
- LiDAR(라이다): RPLIDAR A3
- GNSS(GPS) 보드: ublox C099-F9P
- AHRS(IMU): myAHRS+
- Arduino
필요한 정보는 Vender ID, Product ID, Serial Number 3가지이다.
[ 1 ] 장치를 연결한 뒤, USB 장치에 부여된 이름을 확인한다.
$ ls -al /dev/serial/by-id
[ 2 ] 기기의 Vendor ID(생산자), Product ID(제품번호)를 확인한다. 같은 제품(예: 아두이노 우노 보드)이라면 생산자나 제품 번호가 같을 수 있다. 이들은 다음 단계에서 알아볼 시리얼 번호가 다르다.
$ lsusb
위 사진에서 정리한 각 기기의 vendor ID, product ID는 아래와 같다.
기기 | Vendor ID | Product ID | Description |
---|---|---|---|
ublox C099-F9P (GNSS board) | 1546 | 01a9 | U-Blox AG |
myAHRS+ (IMU) | 0483 | 5740 | STMicroelectronics STM32F407 |
RPLiDAR | 10c4 | ea60 | Cygnal Integrated Products, Inc… |
[ 3 ] Serial Number(시리얼 번호)를 알아낸다. USB0, USB1, ACM0, ACM1 등 숫자는 본인의 상황에 맞게 바꿔가며 정보를 조회한다.
$ udevadm info -a /dev/ttyUSB0 | grep '{serial}'
리눅스 udev에서 사용할 rules를 추가하기 위해 rules 파일을 만들자.
[ 1 ] 파일을 생성한다. sudo
명령어를 통해 루트 권한으로 실행해야 문서 작성/수정이 가능하다. 파일 이름은 임의로 99-tty.rules
로 하였다. gedit
은 지에디트(gedit)라는 문서 편집기로 해당 파일을 작성하겠다는 의미이다. 따라서 아래 명령어를 입력하면 입력창이 열리며 문서 작성이 가능해진다.
$ cd /etc/udev/rules.d
$ sudo gedit 99-tty.rules
참고로 위에서 이동한 위치인 /etc/udev/rules.d
디렉토리로 가면 다른 rules
파일들도 존재하며 해당 공간은 root 권한이 있어야지만 읽고 쓸 수가 있다. 다른 파일들을 열어봐도 읽기전용으로만 열리며 이들은 udev rules를 따른다고 한다.
[ 2 ] 파일 내용을 입력하고 저장한다. 아래는 RPLIDAR A3(LiDAR), ublox C099-F9P (GNSS 보드), myAHRS+(IMU), Arduino에 이름을 부여한 예시이다.
SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ATTRS{serial}=="000001010000", SYMLINK+="ttyIMU"
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ATTRS{serial}=="0001", SYMLINK+="ttyLiDAR"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a9", SYMLINK+="ttyGPS"
SUBSYSTEM=="tty", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0042", ATTRS{serial}=="75834343639351A06141", SYMLINK+="ttyARDUINO"
한 문장이 하나의 조건문 격이다. 해당 조건에 부합한다면 지정된 이름을 부여하라는 의미이다. 위 예시가 100% 모든 사람과 기기에 맞는 형식은 아님에 주의하자.
SUBSYSTEM
은 디바이스의 서브 시스템으로, 위 예에서는tty
로 한다. ls
명령 등으로 장치에 부여되어 있는 이름을 보면 ttyUSB*, ttyACM* 등의 식으로 그 시스템이 tty임을 확인할 수 있었다.ATTRS{idVendor}
, ATTRS{idProduct}
, ATTRS{serial}
은 각각 Vendor ID(생산자), Product ID(제품번호), Seial Number(시리얼 번호)로, 앞서 알아낸 정보를 입력해준다.SYMLINK+
에는 장치에 부여하게 될 고유의 이름이다. 이곳에 원하는 이름을 입력해준다.ACTION
: 특정 상황에서 작업을 행하라는 뜻으로, ACTION=="add"
은 장치가 연결되면 인식하라는 의미가 된다.KERNEL
: 커널 이름으로, 디바이스가 입력해준 커널 이름과 일치할 때 작업을 행한다.MODE
: 읽기, 쓰기 등의 권한을 말한다.[ 3 ] udevadm 규칙을 reload/restart한다. 아래 명령어로 규칙을 재로딩했다가, 장치를 제거하고 다시 연결한다.
$ sudo service udev reload
$ sudo service udev restart
또는 아래의 명령어들도 있다.
$ sudo udevadm control --reload-rules
$ sudo service udev restart
[ 4 ] 장치명이 어떻게 바뀌어 있는지 다시 확인한다.
(1) 개별로 확인하고 싶을 때 예
$ sudo ls -l /dev/ttyLiDAR
(2) tty만 확인하고 싶을 때 예
또는 ls -al /dev/tty*
->
표시는 ttyLiDAR
의 원본이 ttyUSB2
라는 것을 의미한다. 즉, 각 기기의 ‘포트 이름이 고정되었다’ 혹은 ‘remap 되었다’고 할 수 있다. 또한 사진의 좌측을 보면 기기의 퍼미션(권한)도 바뀌어있음을 알 수 있다.
[ 5 ] 필요에 따라 장치 포트 이름(시리얼 포트)이 ttyUSB*, ttyACM* 등으로 설정된 곳(launch파일, 파라미터 파일 등)이 있다면 이를 바꾸어준다.
특정 기기의 패키지 설치 과정 중 스크립트(.sh
) 파일을 제공해주는 경우가 있다. udev 설정을 알아서 해주는 파일이다. 아래 예시는 rplidar 패키지의 예이다.
패키지 내 scripts/create_udev_rules.sh
파일의 내용은 다음과 같다. 설명을 주석으로 달아두었다.
rules.d
로 복사할 것이라는 rplidar_ros/scripts/rplidar.rules
파일의 내용은 아래와 같다.
ttyUSB*
의 커널을 가진, 10c4
에서 제조한 ea60
번호의 제품이 연결되었을 때, 모드(권한)를 777
로 하고 이름을 rplidar
로 한다는 뜻이다. 권한 설정에 관한 자세한 이론은 [ROS] Linux, ROS 주요 명령어에 나타내었다.
위에서 udev 설정을 일일히 알아내 한 것 대신, 이렇게 제공된 스크립트 파일을 단순히 실행시키는 것으로 설정을 간단히 수행할 수 있다.