AWS 기술 블로그

드론 촬영 이미지를 AWS 클라우드로 전송하기

AWS Professional Services(ProServe) IoT 타이거 팀은 IoT 를 주제로 활발한 지식 공유 및 다양한 토이(Toy) 프로젝트를 진행하고 있습니다. 이번 게시글에서 소개드릴 내용은 드론에 관한 것입니다. 드론이 처음 도입된 군사용 무기에서부터 건설, 에너지, 물류, 재난구조, 교통 관측, 과학 연구, 농업, 촬영, 취재 등 각종 분야에서 활발하게 사용되고 있으며, 더 나아가 클라우드 서비스와 접목하여 지능형 서비스로 그 영역을 확장할 수 있습니다. 이에 드론을 클라우드와 연결해 이를 기반으로 다양한 지능형 서비스를 만들면 드론에 대한 활용도를 높일 수 있습니다.

이를 위해서 2편의 게시글에서 AWS 기반 지능형 드론 애플리케이션 구현 방법에 대해서 소개할 예정입니다. 먼저 1편에서는 드론에서 촬영한 영상과 사진을 클라우드로 전송하는 방법에 대해서 설명하고, 이후 2편에서는 드론에서 촬영한 영상과 사진에서 객체 인식을 하는 방법에 대해 소개할 예정입니다.

먼저 이번 게시글에서는 드론 제어 애플리케이션을 이용해 드론을 제어하고 촬영한 사진과 영상을 Jetson Nano 보드를 이용해서 AWS 클라우드로 전송하는 방법에 대해서 알아보기로 합니다.

솔루션 개요

드론에서 촬영한 영상이나 이미지를 클라우드로 전송하기 위한 솔루션는 다음과 같습니다.

  1. Tello 드론을 Jetson Nano 보드와 WiFi(인터넷 통신)로 연결한 후 드론에서 촬영한 영상이나 이미지를 Jetson Nano 보드로 보내도록 구성
  2. Jetson Nano 보드에서 클라우드와 통신이 가능하도록 WiFi를 연결 한 후 Jetson Nano 보드에서 드론 제어 애플리케이션 구동
  3. 사용자의 키보드 입력을 통해 드론을 제어하고, 드론 제어 애플리케이션이 영상이나 이미지를 클라우드로 전송할 수 있도록 구성

솔루션 아키텍처

Jetson Nano 보드는 네트워크 통신을 위해 2개의 WiFi 인터페이스를 가지고 있습니다. 그 중 1개는 Tello 드론과 연결되어 있고, 나머지 1개는 Amazon S3에 이미지/동영상 파일을 전송하기 위한 인터넷 통신용입니다. Tello 드론에서 촬영한 이미지는 무선 NIC 모듈을 통해서 드론 제어 애플리케이션으로 전달되고, 이후 EDIMAX WiFi를 통해 Amazon S3로 전송됩니다. Jetson Nano 보드 화면을 통해 드론 카메라가 촬영 중인 영상을 실시간으로 확인할 수 있으며, 외부 키보드 입력을 통해 드론 이착륙, 이동, 사진 촬영 및 파일 전송 등 다양한 동작을 수행할 수 있습니다.

사전 준비 사항

다음과 같은 사항이 사전에 준비되어야 합니다.

  1. Jetson Nano 4GB SUB Developer Kit
  2. Wireless-AC8265 Dual Mode AC8265 Wireless NIC Module
  3. Ryze Tech Tello Quadcopter Combo
  4.  Edimax WiFi 4 802.11n
  5. AWS Account

단계 요약

이번 게시글은 아래와 같은 단계로 구성됩니다.

  • 단계 1 : DJI Tello 드론 구성하기
  • 단계 2 : 무선 랜 카드 조립하기
  • 단계 3 : Jetson Nano 보드 설정하기
  • 단계 4 : EDIMAX WiFi 드라이버 설치 및 연결하기
  • 단계 5 : AWS CLI 및 boto3 설치하기
  • 단계 6 : Amazon S3 버킷 생성
  • 단계 7 : 드론 제어 애플리케이션 구동하기
  • 단계 8 : 드론 촬영 이미지를 AWS 클라우드에서 확인

단계 1 : DJI Tello 드론 구성하기

DJI사의 Tello 드론은 입문용, 교육용으로 많이 소개되는 제품으로 스마트폰 앱을 통해 쉽게 조종할 수 있으며, 프로그래밍 명령을 통한 비행 제어 기능 또한 제공하고 있습니다. 우선 스마트폰의 WiFi와 앱을 통해 Tello 드론과 연결을 해보겠습니다. 아이폰 기준, 앱스토어에서 Tello 앱을 통해 드론을 제어할 앱을 스마트폰에 설치하고, 드론과 연결합니다. Tello 드론을 구성하는 순서는 아래와 같습니다.

  1. Tello 앱을 시작하면, 화면 하단에 “기체가 기기에 연결되어 있지 않습니다” 라는 메시지를 확인할 수 있습니다.
  1. 드론 기체에 배터리를 장착하고, 측면의 전원 버튼을 눌러주면 기체 전면의 LED에 불이 들어오면서 켜지고, 깜빡거리면서 연결 대기모드가 됩니다.
  2. 드론 LED가 깜빡거릴 때, 스마트폰 WiFi 메뉴에서 “TELLO-*****“와 같은 네트워크가 검색되면, 해당 SSID로 연결합니다.
  3. 다시 스마트폰의 Tello 앱으로 돌아오면 자동으로 Tello 드론 기체와 연결된 Tello 앱 화면을 확인할 수 있습니다. 가상 조이스틱을 이용하여 Tello 드론을 조종하면 됩니다.

DJI Tello 드론에 대한 자세한 사용 설명은 공식 홈페이지(https://www.ryzerobotics.com/kr/tello)를 참고하면 됩니다.

단계 2 : 무선 랜 카드 조립하기

Jetson Nano 보드에서 드론과 AWS 간 네트워크 통신을 위해서는 2개의 무선랜이 필요합니다. Jetson Nano에는 무선랜이 장착되어 있지 않습니다. M.2 포트와 USB 포트를 통해서 무선랜 장착이 가능합니다. M.2 2230 무선랜 모듈인 Intel AC8265 와 USB 무선랜인 Edimax WiFi 를 장착합니다.

위 그림은 M.2 2230 규격의 무선랜 카드 Intel AC8265 와 안테나 입니다.

볼트 2개를 풀고 Jetson Nano 모듈을 제거하면 M.2 슬롯이 보입니다.

무선 랜카드 모듈을 연결하고 안테나도 연결합니다.

Jetson Nano 모듈을 연결하고 외부 안테나와 USB 포트에 Edimax WiFi 모듈까지 연결합니다.

단계 3 : Jetson Nano 보드 설정하기

Jetson Nano 보드 작업을 위해 모니터, 키보드 등 입출력 장치와 전원을 연결합니다. 기본으로 설정된 계정과 패스워드는 다음과 같습니다.

  • 계정 : jetson
  • 패스워드 : yahboom

참고 : 만약, Jetson Nano 보드에서 Low Voltage Warning 알림이 발생한다면, 전원 공급 장치를 교체해야 합니다.

시스템에 접속 후 인터넷 연결을 합니다. 연결 후, OS 및 Libraries 업데이트를 진행하고 필요한 패키지를 설치합니다.

$ sudo apt-get update
$ sudo apt-get full-upgrade
$ sudo apt install curl
$ curl https://bootstrap.pypa.io/pip/3.6/get-pip.py -o get-pip.py
$ sudo python3 get-pip.py
$ sudo pip install jetson-stats
$ jtop # To check the CPU/GPU/Memory system usage

업데이트와 설치가 완료된 후, 무선 NIC모듈을 통해 Tello 드론과 연결합니다. GUI화면 내 Network설정에서 Tello드론의 SSID를 찾아 연결하거나, 다음과 같이 터미널 CLI 명령어를 통해 연결할 수 있습니다.

$ ifconfig wlan0
$ nmcli d
$ nmcli r wifi on
$ nmcli d wifi list
$ nmcli d wifi connect [SSID] password [PASSWORD] # Ubuntu > Network 설정 화면에서도 연결 가능하다.
$ ping 8.8.8.8
$ sudo iw dev wlan0 set power_save off
$ sudo reboot now

주의 : 무선 NIC모듈이 지원하는 WiFi 버전으로 연결하여야합니다. 잘 모르겠다면 Wi-Fi 4 (802.11n)를 지원하는 2.4GHz대역으로 접속합니다.

단계 4 : EDIMAX WiFi 드라이버 설치 및 연결하기

앞서 Jeston 보드에서 Tello 드론과 통신하기 위한 Wireless LAN 연결을 완료 하였다면, 이후에는 AWS 서비스와 통신하기 위한 Wireless LAN 연결을 구성합니다. EDIMAX WiFi 드라이버는 아래와 같이 특정 버전의 파일을 다운로드 받아, 직접 빌드하여 설치할 수 있습니다.

$ wget https://www.edimax.com/edimax/mw/cufiles/files/download/Driver_Utility/EW-7811Un_V2/EW-7811Un_V2_Linux_Driver_1.0.1.3.zip; unzip EW-7811Un_V2_Linux_Driver_1.0.1.3.zip

만약, 404 에러가 발생한다면, EDIMAX 사이트에 접속하여 최신 드라이버 버전을 확인하여 다운로드 하면 됩니다. 현재 최신 버전은 1.0.1.3 입니다. 다운로드가 끝나면, 다음 명령어를 실행하여 설치합니다.

$ cd EW-7811Un_V2_Linux_Driver_1.0.1.3/
$ export ARCH=arm64
$ make
$ sudo make install 
$ sudo reboot now

재부팅이 끝난 후, EDIMAX USB 를 Jetson 보드의 USB Port 에 연결합니다.

이 후 ifconfig 명령어를 실행하여, 아래와 같이 두 개의 Wireless LAN 인터페이스 (wlan0, wlan1) 를 확인할 수 있습니다.

단계 5 : AWS CLI 및 boto3 설치하기

이제 드론에서 촬영한 사진과 동영상 등을 AWS Service와 연동하기 위해서는 몇 가지 소프트웨어를 나노 보드에 설치할 필요가 있습니다. 이를 위해 AWS CLI 및 Python AWS SDK인 boto3를 설치해야 합니다.

자세한 설치 가이드는 AWS CLI 설치boto3 설치를 참조할 수 있습니다.

  1. AWS CLI 설치
    터미널에서 아래 명령어를 실행하여 AWS CLI 를 설치합니다. 반드시 무선랜을 통해 인터넷 연결이 되어 있어야 합니다.

    $ curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
    $ unzip awscliv2.zip
    $ sudo ./aws/install

    설치가 완료되면 다음 명령어를 통해 AWS CLI 버전을 확인할 수 있습니다.

    aws --version

    위 명령어는 AWS CLI 최신 버전을 설치하기 때문에, 상세 버전은 설치 시기마다 다를 수 있습니다.

    AWS CLI 설치 이후에는 자격 증명 입력이 필요합니다. 아래 예제와 같이 여러분이 미리 발급받은 Access key/Secret key를 등록합니다. 해당 권한에는 드론에서 촬영한 영상물을 업로드 할 수 있도록 target S3 버킷에 대한 PutObject 등 필요한 권한이 정의되어 있어야 합니다.

    $ aws configure 
    AWS Access Key ID [None]: AKXXXXXXXXXXXXXXXXXX 
    AWS Secret Access Key [None]: wJalxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
    Default region name [None]: ap-northeast-2 
    Default output format [None]: json

    자세한 사항은 AWS 자격증명 구성을 참고할 수 있습니다.

    이어서 Python 용 AWS SDK 인 Boto3 를 설치합니다. 반드시 사전에 Python 이 설치되어 있어야 합니다.

  2. Boto3 설치
    아래 명령을 통해 Boto3를 설치합니다. 이 과정도 무선랜을 통해 인터넷 연결이 가능해야 합니다.

    $ python3 -m pip install boto3


    위와 같이 제대로 설치 되었다면 boto3를 import를 해도 에러가 발생하지 않습니다.

단계 6 : AWS S3 버킷 생성

드론이 촬영한 이미지를 저장할 S3 버킷을 생성합니다. 여기에서는 AWS CLI 방식을 사용하겠습니다. 그리고 생성하고자 하는 S3 버킷명은 “my-bucket-1234″ 라고 하겠습니다. S3 bucket 명은 전세계적으로 고유한 이름이어야 합니다.

aws s3api create-bucket \
    --bucket my-bucket-1234 \
    --region ap-northeast-2

상세한 내용은 S3 bucket 생성에 대한 내용을 참고할 수 있습니다.

해당 S3 버킷에 접근할 수 있도록 S3 버킷 정책을 생성한 후, Jetson Nano 보드에 설정한 AWS IAM 사용자(User) 혹은 역할(Role) 에 부여합니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::my-bucket-1234/",
                "arn:aws:s3:::my-bucket-1234/*"
            ]
        }
    ]
}

단계 7 : 드론 제어 애플리케이션 구동하기

다음은 드론의 동작을 키보드로 제어하고 사진을 촬영하여 S3 버킷에 업로드하는 애플리케이션 코드를 작성합니다. 코드는 파이썬 기반이고 소스 코드 파일 이름은 tello_control.py이라고 정하겠습니다. 구현한 코드의 설명은 아래와 같습니다.

우선 필요한 라이브러리를 불러오고  boto3의 S3 클라이언트를 생성합니다. 이때 S3 클라이언트는 단계 5에서 구성한 자격증명으로 AWS 계정에 접근하게 됩니다.

import datetime
import boto3
import cv2
from djitellopy import Tello

# Define default config values.
DEFAULT_BUCKET_NAME = "<YOUR-S3-BUCKET>"
DEFAULT_FILE_NAME = "drone_app"

# Create boto3's s3 client.
s3 = boto3.client("s3")

위에서 생성한 버킷명을 <YOUR-S3-BUCKET>에 대신 넣어줍니다.

다음으로 촬영한 이미지를 파일로 저장하고 S3 버킷에 업로드하는 함수를 정의합니다.

def take_picture_and_upload_s3(picture):
    print("'take_picture_and_upload_s3' is running...")

    now = datetime.datetime.now()
    now_datetime = now.strftime("%Y-%m-%d-%H:%M:%S")

    # Create filename from combination of default filename and current time
    filename_with_datetime = f"{DEFAULT_FILE_NAME}-{now_datetime}.png"

    # Save an image to a file
    cv2.imwrite(filename_with_datetime, picture)

    # Upload an image to S3
    file_path = f"./{filename_with_datetime}"
    s3.upload_file(file_path, DEFAULT_BUCKET_NAME, filename_with_datetime)
    print(f"The '{filename_with_datetime}' file has been uploaded to S3.")

다음은 메인 함수입니다. Tello 드론과 연결하고 입력 스트림에서 촬영 이미지를 읽을 수 있게 합니다. 드론을 이륙시킨 후 미리 정한 키보드 키로 전후, 좌우, 상하, 시계와 반시계 방향 회전, 이착륙 동작을 제어할 수 있게 합니다. 또한 키보드로 촬영한 이미지를 파일로 S3 버킷에 업로드하게 합니다.

if __name__ == "__main__":
    print("'main' function is running...")

    tello = Tello()
    tello.connect()

    tello.streamon()
    frame_read = tello.get_frame_read()

    tello.takeoff()

    while True:
        img = frame_read.frame
        cv2.imshow("drone", img)

        key = cv2.waitKey(1) & 0xFF
        if key == 27:  # ESC, exit
            break

        if key == ord("w"):  # forward
            tello.move_forward(30)
        elif key == ord("s"):  # backward
            tello.move_back(30)
        elif key == ord("a"):  # left
            tello.move_left(30)
        elif key == ord("d"):  # right
            tello.move_right(30)
        elif key == ord("e"):  # rotate clockwise
            tello.rotate_clockwise(30)
        elif key == ord("q"):  # rotate counter-clockwise
            tello.rotate_counter_clockwise(30)
        elif key == ord("r"):  # move up
            tello.move_up(30)
        elif key == ord("f"):  # move down
            tello.move_down(30)
        elif key == ord("k"):  # take off
            tello.takeoff()
        elif key == ord("l"):  # landing
            tello.land()
        elif key == ord("p"):  # take a picture and save it
            take_picture_and_upload_s3(frame_read.frame)

여기까지 작성한 파이썬 파일을 Jetson의 터미널에서 아래와 같이 실행하면 드론을 작동시키고 제어할 수 있습니다.

$ python3 ./tello_control.py 

단계 8 : 드론 촬영 이미지를 AWS 클라우드에서 확인

위의 사항들이 모두 구현되었다면 AWS 클라우드에서 이미지를 확인해 볼 수 있습니다.

  • AWS 관리 콘솔에서 Amazon S3로 이동합니다.
  • Amazon S3에서 해당 버킷으로 이동합니다.
  • 다음과 같이 업로드된 이미지를 확인할 수 있습니다.(여기에서는 “drone-ai-*”라는 이름의 버킷명이 사용되었습니다.)
  • 해당 object를 click을 한 뒤 “Open”을 누르면 파일이 다운로드 됩니다. 다운로드 받은 파일을 열어서 보면 드론에서 촬영한 이미지를 아래와 같이 확인 할 수 있습니다.

결론

이번 게시글에서는 드론에서 촬영한 영상과 사진을 클라우드로 전송하는 방법에 대해서 알아보았습니다. 드론을 활용할 수 있는 영역이 확대되면서, 이를 통해 생산되는 데이터를 분석하고 활용하기 위한 관심이 갈수록 높아지고 있습니다. AWS 클라우드와 연동한다면, 데이터 관리는 물론 누구나 손쉽게 데이터 분석 서비스를 이용할 수 있습니다. 이번 게시글에서 소개한 Jetson Nano 보드와 같은 오픈소스 하드웨어를 통해, 드론과 클라우드를 연결하고 클라우드 기반 지능형 드론 서비스를 만들 수 있을 것으로 기대합니다. 다음 게시글에서는 드론에서 촬영한 영상과 사진에서 객체 인식을 하는 방법에 대해 소개하겠습니다.

AWS ProServ팀의 정병우(IoT, Data Architect), 김성헌(Security Consultant), 최상연(Data Architect), 김조나스(Data Scientist)님이 이번 게시글 작성에 함께 참여했습니다.

Daeyeol Seo

Daeyeol Seo

서대열 IoT 아키텍트는 다양한 IoT 디바이스에 대한 개발 경험을 바탕으로 고객이 최적의 솔루션을 선택하여 비즈니스 성과를 달성할 수 있도록 고객과 함께 효율적인 IoT 아키텍처를 구성하는 역할을 수행하고 있습니다.

Hanguk Yoon

Hanguk Yoon

윤한국 Data Architect는 데이터 레이크 구축 및 마이그레이션과 모더나이제이션을 역할을 수행하며, 배치, 실시간 데이터 파이프라인 구축과 같은 빅데이터 분석 플랫폼 구축에 기술 지원하는 역할을 수행하고 있습니다.

Jiseong Kim

Jiseong Kim

김지성 Data Architect는 엔터프라이즈 고객을 대상으로 데이터레이크 마이그레이션과 모더나이제이션을 담당하며, 데이터웨어하우징, 데이터 파이프라인, 대용량 머신러닝과 같은 빅데이터 분석 플랫폼 구축 시 필요한 가이드와 기술 지원하는 역할을 수행하고 있습니다.

Jaewoong Choi

Jaewoong Choi

최재웅 DevOps Consultant는 클라우드로 전환하는 AWS 고객과 협력하여 비즈니스 목표를 달성하도록 DevOps 여정의 모든 단계에서 고객이 탄력적이고 효율적인 아키텍처와 파이프라인를 구축하도록 돕고 있습니다. DevOps, MLOps, 개발자 도구 및 MSA 에 관심이 많습니다.