Blockly 툴박스에 카테고리 추가

Blockly를 실행하면 좌측 (혹은 설정에 의해서 하단)에 툴박스가 존재한다. 사용자의 필요에 따라 이 툴박스에 카테고리를 추가하는 등에 대한 작업을 할 수 있다.

툴박스에 설정은 toolbox_standard.js 파일에서 진행한다. 지난 포스팅에서 실행했던 디렉토리에서 toolbox_standard.js 파일을 열어보면…

var BLOCKLY_TOOLBOX_XML = BLOCKLY_TOOLBOX_XML || Object.create(null);

/* BEGINNING BLOCKLY_TOOLBOX_XML ASSIGNMENT. DO NOT EDIT. USE BLOCKLY DEVTOOLS. */
BLOCKLY_TOOLBOX_XML['standard'] =
// From XML string/file, replace ^\s?(\s*)?(<.*>)$ with \+$1'$2'
// Tweak first and last line.
'<xml>'
+ '<category name="Logic" colour="%{BKY_LOGIC_HUE}">'
+   '<block type="controls_if"></block>'
+   '<block type="logic_compare"></block>'
+   '<block type="logic_operation"></block>'
+   '<block type="logic_negate"></block>'
+   '<block type="logic_boolean"></block>'
+   '<block type="logic_null" disabled="true"></block>'
+   '<block type="logic_ternary"></block>'
+ '</category>'
+ '<category name="Loops" colour="%{BKY_LOOPS_HUE}">'
+   '<block type="controls_repeat_ext">'
+     '<value name="TIMES">'
+       '<shadow type="math_number">'
+         '<field name="NUM">10</field>'

...

와 같이 되어 있다. Javascript로 되어 있으며, 자세히 살펴보면 XML을 String 형태로 변환해서 사용함을 볼 수 있다. 주석에 나와 있는 것처럼, Blockly Dev Tools를 이용해서 만들어 줄 수 있지만, 간단한 작업은 본 파일을 수정하면 된다.

Custom이라는 카테고리를 추가해보도록 한다. 블럭은 아직 추가하지 않기로 한다. 카테코리를 추가하고 싶은 지점에 다음과 같이 추가한다.

+ '<category name="Custom" colour="100">'
+ '</category>'

이제 다시 웹페이지를 reload해서 보게 되면,

Custom 카테고리가 추가되어 있는 것을 볼 수 있다. 아직 블럭들이 추가되어 있지 않으므로, 클릭해도 블럭들은 보이지 않는다. 카테고리 사이에 구분자(Seperator)를 추가하려면 원하는 지점에 다음과 같이 추가한다.

여기까지.

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)

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

끝!

안드로이드 앱 여러 개 권한 요청

앱을 설치하고 처음 실행시 여러 개의 권한 요청 방법. requestPermissions 함수를 사용하는데, 두번째 인자인 퍼미션 목록은 String Array 타입이다. 즉 여러 개의 권한을 한꺼번에 요청 가능.

필요한 권한 목록을 ArrayList<String>에 저장하고, 목록이 완성되면 requestPermissions을 이용해 권한 요청

ArrayList<String> permissions = new ArrayList<String>();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
            permissions.add(Manifest.permission.RECORD_AUDIO);

...

if(permissions.size() > 0) {
            String[] reqPermissionArray = new String[permissions.size()];
            reqPermissionArray = permissions.toArray(reqPermissionArray);
            ActivityCompat.requestPermissions(this, reqPermissionArray, MY_PERMISSIONS_REQUEST_MULTI);
        }

사용자가 권한을 승인하거나 거절한 경우에 대한 대응은 onRequestPermissionsResult 함수에서 처리.

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

if(grantResults.length > 0) {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
    ...
    }

    ...
}

끗.

3D 프린트 이것저것 팁 & 의견

필라멘트

  • 일반 가정 집에서 ABS은 절대 사용 불가이다. 프린팅하는 동안 냄새도 고약하고, 건강엔 엄청 안좋다. PLA가 가장 무난하고, 강도를 필요로하는 것이라면 PETG를 사용하는 것을 추천함. (요즘은 PLA+ 등도 나오는데 뭐 별다른건 없는듯)
  • 난 PLA를 사용하다가 현재는 PETG를 사용중인데, 차이점은 PETG가 좀더 질기다라고 느껴진다. 출력이 완료되고 굳은 후 PLA는 힘을 주면 (엄청 쎄게) 똑 부러지는 반면 PETG는 살짝 구부려지다가 부러진다. 그러니깐 좀더 질기다라는게 맞는듯.
  • 싸구려 필라멘트는 저렴해서 좋긴한데, 필라멘트의 굵기가 일정하지 않거나 감겨있는 게 잘못되어 꼬여버리면 출력 중 필라멘트가 끊기는 참사가 발생함.

출력 팁

  • 출력시 바닥면이 뜨는 변형이 일어난다면, 바닥 온도를 살짝 올려보자.
  • 첫번째 레이어의 출력속도를 현저히 낮춰보는 것도 해결 방법.
  • 출력 후 옆면이 고르지 않게 나온다면, X, Y축의 벨트 텐션을 좀더 강하게 조정한다.
  • 출력 중 출력물이 안착이 안된고 날라다닌다면, 베드의 레벨링이 잘못된 경우이다. 레벨을 세심하게 조정해본다.
  • 첫번째 레이어가 좀더 크기 출력되는 경우 (일명 코끼리발 Elephant’s Foot 현상), 이를 보정하기 위한 옵션이 슬라이싱 툴에 존재한다. 정확히는 첫번째 레이어의 크기를 일정 비율만큼 줄이는 것임.
  • 간격이 떨어져있는 출력물에 거미줄 같이 지저분한 것이 많이 생긴다면, 출력 온도를 좀 낮춘다.

재미난 출력물들 찾기