Jetson Nano에서 Intel RealSense D435 카메라 사용해보기

Jetson Nano에는 USB 3.1 gen2 포트가 4개 존재한다. 문득 집에서 놀고 있는 인텔 리얼센스 카메라가 있어 연결해보기 위해 작업 시작.

Intel에서 Intel® RealSense™ SDK의 arm64용 빌드된 패키지를 제공해주지 않으므로, Jetson Nano에서 사용하기 위해선 소스를 직접 빌드하여야 한다. 먼저 소스 빌드를 위해 필요한 패키지들을 설치한다.

$ sudo apt install libgtk-3-dev libxcursor-dev libxinerama-dev

다음으로 레포지토리 (https://github.com/IntelRealSense/librealsense)에서 최신 릴리즈된 소스를 받아온다. (https://github.com/IntelRealSense/librealsense/releases)

받아온 소스의 압축을 풀고,

$ tar zxf librealsense-2.21.0.tar.gz
$ cd librealsense.2.21.0
$ mkdir build
$ cd build 
$ cmake ..

정상적으로 종료되면, 빌드를 시작한다. 이때 메모리 부족이 일어나므로 이번 포스트와 마찬가지로 swap 파티션을 활성화 한다.

$ sudo swapon /swapfile

빌드 시작

$ make -j1

정상적으로 빌드가 완료되면, 이제 설치.

$ sudo make install

이제 리얼센스 카메라를 연결하고, 테스트용 프로그램인 realsense-viewer를 실행해본다.

$ realsense-viewer

카메라가 정상적으로 인식되고 USB 3.1 gen2로 연결되어 있음을 볼수 있다. 몇가지 테스트 해본 결과 Jetson Nano에서는 1280×720의 해상도를 처리하기엔 너무 느리다. 따라서 해상도를 640×480으로 변경하여 사용한다.

이제 카메라를 켜보면~,

Depth 이미지와 RGB 이미지가 정상적으로 잘 보인다. 코어의 성능때문인지 30프레임이 다 나오는 것 같진 않다.


주의사항! 현재 Jetson Nano에는 5V, 2.1A 어뎁터를 사용하여 연결하였는데, 위와 같이 코어의 성능을 뽑아쓰는 어플리케이션을 돌리다보면 갑자기 전원이 나가는 경우가 가끔씩 발생하였다. 좀더 높은 전류를 제공하는 어댑터를 사용하기를 권장함.

Jetson Nano에서 OpenCV 4.1 with CUDA 빌드

영상처리에 많이 사용되는 OpenCV를 Jetson Nano에서도 사용 가능하다. 빌드 과정은 PC에서와 동일하나 플랫폼의 특성 상 몇가지 다른 부분이 있다. 기본으로 설치되어 있는 패키지를 사용해도 되지만, CUDA를 활용하기 위해선 빌드 과정을 통해 설치하여야 한다.

L4T에는 cuda10.0이 이미 설치되어 있다.

OpenCV github 레포지토리에서 소스를 다운로드한다.

현재 릴리즈된 최신 버전은 4.1.0이다.

먼저 cmake를 설치한다.

$ sudo apt install cmake

다운로드한 압축파일 (opencv-4.1.0.tar.gz, opencv_contrib-4.1.0.tar.gz) 을 풀고, 다음과 같이 cmake를 이용해 빌드 파일을 생성한다.

$ cd opencv-4.1.0
$ mkdir build
$ cd build
$ cmake -DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.1.0/modules -DWITH_CUDA=ON -DCUDA_FAST_MATH=1 -DBUILD_EXAMPLES=ON  -DBUILD_opencv_python3=ON -DPYTHON3_INCLUDE_DIR2=/usr/include/python3.6m -DPYTHON3_NUMPY_INCLUDE_DIRS=/usr/lib/python3/dist-packages/numpy/core/include -DCUDA_ARCH_BIN="5.3" -DCUDA_ARCH_PTX=""  -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_EXAMPLES=OFF ..

각종 의존 패키지들을 체크하고 정상적으로 종료되면 다음과 같은 결과를 보여준다.

-- General configuration for OpenCV 4.1.0 =====================================
--   Version control:               unknown
-- 
--   Extra modules:
--     Location (extra):            /home/byeongkyu/Downloads/opencv_contrib-4.1.0/modules
--     Version control (extra):     unknown
-- 
--   Platform:
--     Timestamp:                   2019-05-02T04:43:14Z
--     Host:                        Linux 4.9.140-tegra aarch64
--     CMake:                       3.10.2
--     CMake generator:             Unix Makefiles
--     CMake build tool:            /usr/bin/make
--     Configuration:               Release
-- 
--   CPU/HW features:
--     Baseline:                    NEON FP16
--       required:                  NEON
--       disabled:                  VFPV3
-- 
--   C/C++:
--     Built as dynamic libs?:      YES
--     C++ Compiler:                /usr/bin/c++  (ver 7.4.0)
--     C++ flags (Release):         -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG  -DNDEBUG
--     C++ flags (Debug):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -g  -O0 -DDEBUG -D_DEBUG
--     C Compiler:                  /usr/bin/cc
--     C flags (Release):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -O3 -DNDEBUG  -DNDEBUG
--     C flags (Debug):             -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -g  -O0 -DDEBUG -D_DEBUG
--     Linker flags (Release):      -Wl,--gc-sections  
--     Linker flags (Debug):        -Wl,--gc-sections  
--     ccache:                      NO
--     Precompiled headers:         YES
--     Extra dependencies:          m pthread cudart_static dl rt nppc nppial nppicc nppicom nppidei nppif nppig nppim nppist nppisu nppitc npps cublas cufft -L/usr/local/cuda/lib64 -L/usr/lib/aarch64-linux-gnu
--     3rdparty dependencies:
-- 
--   OpenCV modules:
--     To be built:                 aruco bgsegm bioinspired calib3d ccalib core cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev datasets dnn dnn_objdetect dpm face features2d flann fuzzy gapi hfs highgui img_hash imgcodecs imgproc line_descriptor ml objdetect optflow phase_unwrapping photo plot python2 quality reg rgbd saliency shape stereo stitching structured_light superres surface_matching text tracking ts video videoio videostab xfeatures2d ximgproc xobjdetect xphoto
--     Disabled:                    world
--     Disabled by dependency:      -
--     Unavailable:                 cnn_3dobj cvv freetype hdf java js matlab ovis python3 sfm viz
--     Applications:                tests perf_tests examples apps
--     Documentation:               NO
--     Non-free algorithms:         NO
-- 
--   GUI: 
--     GTK+:                        NO
--     VTK support:                 NO
-- 
--   Media I/O: 
--     ZLib:                        /usr/lib/aarch64-linux-gnu/libz.so (ver 1.2.11)
--     JPEG:                        libjpeg-turbo (ver 2.0.2-62)
--     WEBP:                        build (ver encoder: 0x020e)
--     PNG:                         build (ver 1.6.36)
--     TIFF:                        build (ver 42 - 4.0.10)
--     JPEG 2000:                   build (ver 1.900.1)
--     OpenEXR:                     build (ver 1.7.1)
--     HDR:                         YES
--     SUNRASTER:                   YES
--     PXM:                         YES
--     PFM:                         YES
-- 
--   Video I/O:
--     DC1394:                      NO
--     FFMPEG:                      NO
--       avcodec:                   NO
--       avformat:                  NO
--       avutil:                    NO
--       swscale:                   NO
--       avresample:                NO
--     GStreamer:                   YES (1.14.1)
--     v4l/v4l2:                    YES (linux/videodev2.h)
-- 
--   Parallel framework:            pthreads
-- 
--   Trace:                         YES (built-in)
-- 
--   Other third-party libraries:
--     Lapack:                      NO
--     Eigen:                       YES (ver 3.3.4)
--     Custom HAL:                  YES (carotene (ver 0.0.1))
--     Protobuf:                    build (3.5.1)
-- 
--   NVIDIA CUDA:                   YES (ver 10.0, CUFFT CUBLAS FAST_MATH)
--     NVIDIA GPU arch:             53
--     NVIDIA PTX archs:
-- 
--   OpenCL:                        YES (no extra features)
--     Include path:                /home/byeongkyu/Downloads/opencv-4.1.0/3rdparty/include/opencl/1.2
--     Link libraries:              Dynamic load
-- 
--   Python 2:
--     Interpreter:                 /usr/bin/python2.7 (ver 2.7.15)
--     Libraries:                   /usr/lib/aarch64-linux-gnu/libpython2.7.so (ver 2.7.15rc1)
--     numpy:                       /usr/lib/python2.7/dist-packages/numpy/core/include (ver 1.13.3)
--     install path:                lib/python2.7/dist-packages/cv2/python-2.7
-- 
--   Python 3:
--     Interpreter:                 /usr/bin/python3 (ver 3.6.7)
--     Libraries:                   /usr/lib/aarch64-linux-gnu/libpython3.6m.so (ver 3.6.7)
--     numpy:                       /usr/lib/python3/dist-packages/numpy/core/include (ver )
--     install path:                lib/python3.6/dist-packages/cv2/python-3.6
-- 
--   Python (for build):            /usr/bin/python3
--
--   Java:                          
--     ant:                         NO
--     JNI:                         NO
--     Java wrappers:               NO
--     Java tests:                  NO
-- 
--   Install to:                    /usr/local
-- -----------------------------------------------------------------
-- 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/byeongkyu/Downloads/opencv-4.1.0/build

빌드 중 램 부족으로 인한 에러가 발생하므로, swap 파티션을 생성하여 이를 보완하도록 한다.

$ sudo fallocate -l 4.0G /swapfile
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile

부팅시마다 마운트 하도록 다음의 파일 수정
$ sudo vi /etc/fstab

라인 추가
/swapfile none swap 0 0

자, 이제 빌드를 시작해보면…

$ make -j1

코어 4개를 적극 활용하면 좋겠으나, 램이 4기가 밖에 없는 관계로 램 부족과 같은 에러가 발생하거나 아예 멈춰버리는 불상사가 발생한다. 따라서 쓰레드 1개로 빌드 시작! 컴파일 시간이 어마어마하게 걸리고 방열판이 엄청나게 뜨거워지므로 조심.

빌드가 완료되면, 완료된 파일들을 설치한다. 설치 경로는 /usr/local 이다.

$ sudo make install

이제 제대로 설치되었는지 확인해본다.

$ opencv_version 
4.1.0

$ python3
>>> import cv2
>>> cv2
<module 'cv2' from '/usr/local/lib/python3.6/dist-packages/cv2/python-3.6/cv2.cpython-36m-aarch64-linux-gnu.so'>
>>> cv2.__version__
'4.1.0'

일단 설치는 여기까지!

Jetson Nano 무선랜(wifi + bluetooth) 카드 장착

Jetson Nano엔 무선랜 기능이 포함되어 있지 않다. 라즈베리파이도 3b+ 모델에서는 무선랜 기능이 포함되어 있는데, 뭐 그냥 붙여줬으면 좋으련만… USB 동글 등을 이용해서 사용할수 있겠지만, Jetson Nano에는 pci-e 확장포트가 존재한다. 따라서 이 포트에 m.2 규격의 무선랜 모듈을 장착하여 사용할 수 있다.

주변에 쉽게 구할 수 있고, 나름 리눅스 친화적인 무선랜 모듈은 인텔 제품이며 여러가지 버전이 존재한다. 현재 Jetson Nano의 커널 버전은 4.9 (L4T) 버전이므로, 현재 구할 수 있는 무선랜 모듈 중 가장 나은 선택은 Intel ac8265이다. Intel ac9560이 좀더 최신 칩셋에 나은 기능을 갖고 있지만, 드라이버가 커널 4.14 이상에서만 동작하므로 현재로선 사용이 불가능하다.

약 3만원 정도에 구입이 가능하다. 단 구입할때 안테나도 같이 구매하여야 한다. Intel ac8265의 주요 사양은 https://ark.intel.com/content/www/us/en/ark/products/94150/intel-dual-band-wireless-ac-8265.html 에서 확인 가능하다.

Jetson Nano의 옆 나사 두개를 풀어주고 모듈을 제거하면, 확장기판 내에 m.2 슬롯이 존재함을 볼수 있다. 나사를 풀러주고 구입한 무선랜 모듈을 장착한다.

안테나도 연결해준다. 저런 패치형 안테나 말고도, 일반적인 스틱형 안테나도 장착할 수 있다. (NGFF antenna 또는 M.2 wireless antenna로 검색하면 됨)

다시 코어 모듈을 조립하고 전원을 인가한다. 부팅이 완료된 후 터미널을 열어 다음과 같이 입력하여 무선랜 카드가 잘 인식되었는지 확인한다.

$ lspci
00:01.0 PCI bridge: NVIDIA Corporation Device 0fae (rev a1)
00:02.0 PCI bridge: NVIDIA Corporation Device 0faf (rev a1)
01:00.0 Network controller: Intel Corporation Wireless 8265 / 8275 (rev 50)
02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 15)

이제 무선랜 및 블루투스 기능을 정상적으로 사용 가능하다.

끝!

Jetson Nano GPIO 사용 해보기

Jetson Nano에는 라즈베리파이와 마찬가지로 40핀의 GPIO 헤더가 존재한다. 이를 이용해 다양한 외부기기와 연결 가능한데, python의 라이브러리를 이용하면 사용자가 제어 가능하다.

먼저 필요한 패키지를 설치한다. python3는 기본 설치되어 있고, pip3는 설치해야 한다.

$ sudo apt install python3-pip

다음으로 Jetson.GPIO 패키지를 설치한다.

$ sudo pip3 install Jetson.GPIO

이제 python3를 실행하고 설치한 패키지를 import 해보면 다음과 같이 퍼미션 에러가 발생한다. 몇가지 설정이 필요하다.

>>> import Jetson.GPIO
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/dist-packages/Jetson/GPIO/__init__.py", line 1, in <module>
    from .gpio import *
  File "/usr/local/lib/python3.6/dist-packages/Jetson/GPIO/gpio.py", line 33, in <module>
    raise RuntimeError("The current user does not have permissions set to "
RuntimeError: The current user does not have permissions set to access the library functionalites. Please configure permissions or use the root user to run this

gpio 그룹을 생성하고 사용자를 gpio 그룹에 추가한다.

$ sudo groupadd -f -r gpio
$ sudo usermod -a -G gpio <user_id>

다음으로 udev 룰을 rules.d 디렉토리로 복사한다.

$ sudo cp /opt/nvidia/jetson-gpio/etc/99-gpio.rules /etc/udev/rules.d/

재부팅하거나, 다음과 같이 입력하여 udev 룰을 다시 불러온다. (재부팅해야 함.)

$ sudo udevadm control --reload-rules && sudo udevadm trigger

이제 python3를 실행한 다음, 패키지를 import 해보면, 정상적으로 사용 가능하다. 몇가지 예제 코드들이 /opt/nvidia/jetson-gpio/samples에 있으므로 참고하면 될듯하다. 사용법은 RPi.GPIO와 동일하다.

>>> import Jetson.GPIO as GPIO
>>> GPIO.setmode(GPIO.BOARD)
>>> GPIO.setup(33, GPIO.OUT)
>>> GPIO.output(33, GPIO.HIGH)
>>> GPIO.output(33, GPIO.LOW)

위와 같이 간단히 사용 가능하고, 인터럽트, 콜백함수 등 다양한 기능을 지원한다. 몇가지 주의 사항으로는,

  • GPIO의 전압은 5V가 아닌 3.3V
  • PWM 기능은 지원하지 않음
  • I2C, SPI는 각각 두개씩 지원
  • 몇가지 특수펑션들 사용하고, 전원관련 핀을 빼면 여분의 GPIO는 별로 없는듯.

상세한 핀아웃은 https://www.jetsonhacks.com/nvidia-jetson-nano-j41-header-pinout/을 참고하면 됨.

Jetson Nano Developer Kit 사양 & 크기 정보

Technical Specifications

GPU128-core Maxwell
CPUQuad-core ARM A57 @ 1.43 GHz
Memory4 GB 64-bit LPDDR4 25.6 GB/s
StoragemicroSD (not included)
Video Encode4K @ 30 | 4x 1080p @ 30 | 9x 720p @ 30 (H.264/H.265)
Video Decode4K @ 60 | 2x 4K @ 30 | 8x 1080p @ 30 | 18x 720p @ 30 (H.264/H.265)
Camera1x MIPI CSI-2 DPHY lanes
ConnectivityGigabit Ethernet, M.2 Key E
DisplayHDMI 2.0 and eDP 1.4
USB4x USB 3.0, USB 2.0 Micro-B
OthersGPIO, I2C, I2S, SPI, UART
Mechanical100 mm x 80 mm x 29 mm

보드 자체의 크기는 실제 측정해보면 100mm x 79mm 이다. 나사 홀의 위치는 다음과 같다.

Jetson Nano Developer Kit 개봉기

지난 달에 열린 GTC에서 NVIDIA가 JETSON NANO를 발표하였습니다. 라즈베리파이만한 크기에 가격도 저렴? ($99)하고, 게다가 CUDA 코어까지 내장되어 있어, 요즘 유행하는 머신러닝 알고리즘들을 테스트 해보거나, 가지고 놀기 좋게끔 만든 보드인듯 합니다.

한국은 공식판매처가 한컴MDS로 되어 있어, 맘편하게 하나 주문해봤는데, 오늘에서야 도착했습니다. 아마 다른 분들도 다 오늘쯤 받으시겠네요.^^

패키징은 벌것 없습니다. 딸랑 종이박스 하나이고, 내용물도 메뉴얼을 제외하면 보드 하나만 들어있습니다. 흔한 USB 케이블도 없네요. 녹색 커버를 열면 아래와 같이 보드가 담겨있는 봉투가 보이고,

그 밑에 간단한 보드 메뉴얼과, 보드 받침대? 역할을 하는 종이접기류가 보이네요.

보드는 정전기 방지 봉투가 잘 포장되어 있고, 뜯어보면 많이 보셨던 JETSON NANO가 들어있습니다. 뭐 크게 감흥이 있는 건 아니고, 나노 모듈에 확장보드 형태로 되어 있습니다.

뒷면은 부품들을 배치하지 않아, 거의 평면이고, 다만 단자들이 전부다 노출되어 있는 관계로 사용하실땐 받침이나 커버가 꼭 있어야겠네요. (위에서 본 종이접기처럼….)

한쪽면에 확장 커넥터들을 몰아놨습니다. 왼쪽부터 DC어댑터 단자(5V/4A max), HDMI, DP, USB3.0 x4, Ethernet, Micro USB B (전원공급용, 5V/2A) 이고요.

보드 오른쪽은 라즈베리파이와 유사하게 확장 포트들이 배치되어 있습니다. GPIO와 POE 등. 반대쪽엔 UART, POWER SW, RESET, 카메라를 연결할 수 있는 단자가 보이고요. 여기에 라즈베리파이에 사용했던 카메라를 꼽을수 있다네요.

나노모듈을 제거하면 밑에 PCIe 확장포트가 보입니다.

여기에 아래 제품과 같은 무선랜/블루트스 카드를 꼽으면 무선 연결이 가능해집니다. 다른 용도로도 사용이 가능할 것 같고요. 다만 안테나가 비포함되어 있으니 안테나도 같이 주문해야 합니다.

나노모듈 밑에는 MicroSD 카드를 꼽을수 있습니다. JETSON 웹페이지에서 이미지를 다운로드 받아 SD카드에 굽고, 끼워서 부팅하면 됩니다.

라즈베리파이와 크기를 비교하면 가로 길이는 비슷하지만, 세로 길이가 좀 깁니다. 하지만 라즈베리파이의 경우 확장커넥터들이 오른쪽에 밀려있는 관계로 실제 조립하거나 사용할때는 나노가 좀더 편리할 수도 있겠단 생각이 듭니다.

몇가지 아쉬운 점들이 보이는데, USB C 단자를 설계해 놓고 Micro USB B 단자를 꼽아놓은 점, USB포트에 커넥터들 임시땜빵, 오디오출력이 가능함에도 오디오출력 포트가 없다는 점 등이 있네요. RTC를 위한 배터리 단자도 자리만 남겨놓고 조립은 안했네요.

뭐.. 처음 제작된 제품이니 조만간 리비전되어 나올 듯 합니다. 전원을 넣고 부팅하면 Ubuntu 설치할 때와 마찬가지로 언어선택, 키보드, 계정 생성 등의 진행절차가 나오고 완료하면 Ubuntu로 부팅이 가능합니다. Ubuntu 버전은 18.04가 설치되어 있으며, 일단 처음 설치한 후의 느낌은 라즈베리파이보단 좀더 쾌적하게 움직인다 정도 입니다.