D3-G 환경에서 Openpilot 구동

안녕하세요. DAPT 박찬 매니저 입니다.

D3-G 보드를 이용해 Openpilot를 구동하는 프로젝트에 대해 소개 드립니다.

오픈파일럿(OpenPilot)이란?

**오픈파일럿(OpenPilot)**은 전 세계 개발자 커뮤니티에서 활발히 발전되고 있는 오픈소스 기반의 자율주행 소프트웨어 플랫폼입니다. 일론 머스크의 테슬라 오토파일럿에 자극받아 Comma.ai라는 회사에서 시작된 이 프로젝트는, 상용차량의 ACC(어댑티브 크루즈 컨트롤), LKAS(차선 유지 보조) 기능을 대체할 수 있을 정도로 높은 수준의 주행 제어 알고리즘을 제공합니다.

OpenPilot은 차량의 CAN 통신을 통해 제어신호를 주고받으며, 다음과 같은 기능을 제공합니다:

  • 차간 거리 유지 (ACC)

  • 차선 중심 주행 (LKAS)

  • 자동 차선 변경 (일부 지원)

  • 신호등/정지선 인식 (내장된 딥러닝 모델 기반)

  • 드라이버 모니터링 (카메라 기반 졸음/부주의 감지)

오픈파일럿 구동 환경 구성

1. Micro SD 카드에 사용자 환경 설정

FlowPilot은 빌드 및 실행을 위해 8GB 이상의 저장 공간이 필요합니다. 따라서 Micro SD 카드를 삽입하여 해당 공간에 사용자를 생성하고 작업 환경을 구성합니다.

  1. Micro SD 카드를 삽입하고 ext4 형식으로 포맷합니다.

  2. 포맷한 SD 카드를 /home/flowpilot 경로에 마운트합니다.

  3. UUID를 이용하여 자동 마운트를 설정합니다. /etc/fstab 파일에 다음과 같이 추가합니다:

    UUID=YOUR_SD_UUID  /home/flowpilot  ext4  defaults  0  2
    
  4. 새로운 사용자 flowpilot을 생성합니다.

    sudo adduser flowpilot
    
  5. video, render, sudo 그룹 권한을 부여합니다:

    
    sudo usermod -aG video flowpilot
    sudo usermod -aG render flowpilot
    sudo usermod -aG sudo flowpilot
        
    

2. OpenCV 4.5.1 빌드

FlowPilot은 OpenCV와 OpenCL 기능을 사용하는데, 시스템에 맞는 OpenCV를 직접 빌드해야 합니다.

  1. OpenCV 소스를 클론하고 4.5.1 버전으로 체크아웃합니다:

    
    git clone https://github.com/opencv/opencv.git
    cd opencv
    git checkout 4.5.1
    mkdir build
    cd build
        
    
  2. FFmpeg 지원을 위한 패키지를 설치합니다:

    
    sudo apt install libavcodec-dev libavformat-dev libavutil-dev libswscale-dev
        
    
  3. 자바 지원을 위한 ant 패키지를 설치합니다:

    
    sudo apt install ant
        
    
  4. 다음과 같이 CMake를 사용해 빌드 설정을 구성합니다:

    
    cmake -DBUILD_SHARED_LIBS=ON \
          -DBUILD_opencv_java=ON \
          -DWITH_OPENCL=ON \
          -DWITH_OPENCL_SVM=ON \
          -DCMAKE_INSTALL_PREFIX=/usr \
          -DBUILD_opencv_python3=ON \
          -DWITH_FFMPEG=ON \
          ..
        
    
  5. 설정이 완료되면 설치를 진행합니다:

    
    sudo make install
        
    

3. FlowPilot 설치 스크립트 실행

FlowPilot 설치를 위한 자동 스크립트를 실행합니다.

  1. 스크립트를 다운로드하고 실행 권한을 부여합니다:

    
    cd ~
    wget https://github.com/cwal1220/flowpilot/blob/master/scripts/install-flowpilot-desktop
    chmod +x install-flowpilot-desktop
        
    
  2. 스크립트를 실행합니다:

    
    ./install-flowpilot-desktop
        
    

4. Prebuilt 라이브러리 설치

FlowPilot에서 사용하는 사전 컴파일된 OpenCL 및 TNN 라이브러리를 시스템에 복사합니다.

  1. 라이브러리 경로로 이동:

    cd ~/flowpilot/libs/topst-lib
    
  2. 아래의 압축 파일들을 해제하고 루트(/) 디렉토리에 복사합니다 (sudo 필요):

    • image_opencl.tar

    • image_tnn.tar

    tar -xvf image_opencl.tar
    tar -xvf image_tnn.tar
    
    # 이후 폴더 내의 library를 / (root) 경로로 복사
    

5. SCons를 이용한 FlowPilot 빌드

환경이 모두 준비되었으면 FlowPilot을 빌드합니다.

  1. 가상 환경에 진입하고 scons로 빌드합니다:

    
    cd ~/flowpilot
    pipenv shell
    scons -j4
        
    

6. Weston 서비스 정지 및 X11 환경 구축

기본 Weston 환경은 OpenPilot과 호환되지 않기 때문에 중지하고 X11 환경을 설치해야 합니다.

sudo systemctl stop weston
sudo apt install xserver-xorg x11-xserver-utils xinit xterm xfce4 -y

7. xorg.conf 설정

X 서버가 프레임버퍼 드라이버를 사용하도록 설정합니다.

sudo nano /etc/X11/xorg.conf

파일 내용은 다음과 같습니다:

Section "Device"
    Identifier "Framebuffer"
    Driver "fbdev"
EndSection

8. root 계정에서 .xsession 구성

X 세션에서 사용할 데스크탑 환경을 설정합니다.

echo xfce4-session > ~/.xsession

9. X 서버 시작

이제 X 서버를 시작해 GUI 환경을 띄울 수 있습니다.

startx

10. SSH 터미널에서 X 권한 부여

SSH로 접근한 터미널에서 X11 권한을 허용해줍니다.

sudo xhost +

11. FlowPilot 실행

이제 FlowPilot을 실행해봅니다.

cd ~/flowpilot
pipenv shell
./launch_flowpilot.sh

12. CAN Simulation 실행

OpenPilot은 차량의 CAN 데이터를 필수로 요구합니다. 차량이 연결되지 않은 환경에서는 다음과 같이 시뮬레이션을 통해 실행할 수 있습니다.

cd ~/flowpilot
pipenv shell
cd scripts
python3 dummy_params.py      # 카메라 파라미터 설정
python3 dummy_publishers.py  # CAN 데이터 시뮬레이션

신경망 성능 측정(PowerVR GPU, OpenCL 이용)

1. Backbone 신경망 성능 측정

모델 ARM(CPU+NEON) 평균(ms) OpenCL(GPU) 평균(ms) 성능 향상 배수
densenet 1959.094 877.451 2.23×
inception_v3 1890.281 1252.503 1.51×
inception_v4 3646.6 2633.775 1.38×
mobilenet_v1 177.294 37.843 4.69×
mobilenet_v2 166.41 23.814 6.99×
resnet50 939.185 163.348 5.75×
shufflenet_v2 54.521 8.662 6.29×
squeezenet_v1.0 338.188 231.337 1.46×
squeezenet_v1.1 172.083 32.181 5.35×

측정 환경: FP32 모델을 기준, 5회 반복 평균

2. Openpilot 신경망 성능 측정

OpenPilot F2 신경망

모델 디바이스 Min Time (ms) Max Time (ms) Avg Time (ms)
supercombo.tnnproto D3-G CPU only 780.012 786.255 781.493
supercombo.tnnproto D3-G GPU(OpenCL) 55.347 55.726 55.490

신경망 다운로드 링크: https://github.com/cwal1220/flowpilot/raw/refs/heads/master/selfdrive/assets/models/f2/supercombo.tnnmodel

OpenPilot F3 신경망

모델 디바이스 Min Time (ms) Max Time (ms) Avg Time (ms)
supercombo.tnnproto D3-G CPU only 1329.405 1330.590 1330.137
supercombo.tnnproto D3-G GPU(OpenCL) 92.221 95.406 94.461

신경망 다운로드 링크: https://github.com/cwal1220/flowpilot/blob/master/selfdrive/assets/models/f3/supercombo.tnnproto

동작 영상

1 Like

안녕하세요. 모우진입니다.

오 드디어, OpenPilot이 올라왔군요.

신경망 성능 측정의 1번 표에 질문이 있습니다.

  1. Backbone 신경망은 P.VR GPU로 작동한 것인가요?
  2. 혹시 테스트된 신경망 성능 값들이 ND에서 측정된 것도 있을까요? ND 비교값도 표에 추가 정리해 놓으면 AI-G 보드 판매에 도움이 될 수도 있지 않을까 싶습니다.

안녕하세요 팀장님.

문의주신 내용에 대해 답변 드립니다.

  1. Backbone 신경망은 P.VR GPU로 작동한 것인가요?

    1. → 네, ARM은 D3-G의 CPU(+neon), OpenCL은 D3-G의 GPU를 이용해 측정한 값입니다.
  2. 혹시 테스트된 신경망 성능 값들이 ND에서 측정된 것도 있을까요? ND 비교값도 표에 추가 정리해 놓으면 AI-G 보드 판매에 도움이 될 수도 있지 않을까 싶습니다.

    1. → AI-G 보드의 NPU를 이용해서 시간측정 후 결과 업로드 해 두겠습니다. 단, Layer 지원 여부에 따라서 동작이 불가능한 신경망이 있을 수 잇습니다.

감사합니다.

1 Like

넵! 알겠습니다.

Layer 문제는 어쩔 수 없는 부분이니까요 ㅜㅜ

답글, 감사합니다!!!

AI-G의 NPU를 이용해 측정한 결과 공유 드립니다~

모델 Input Shape FP32, D3-G CPU(+NEON) 평균(ms) FP32, D3-G GPU(OpenCL) 평균(ms) INT8, AI-G NPU 평균(ms) CPU 대비 NPU속도 GPU 대비 NPU속도
densenet 1, 3, 224, 224 1959.09 877.45 - - -
inception_v3 1, 3, 299, 299 1890.28 1252.50 16.96 111.45x 73.85x
inception_v4 1, 3, 299, 299 3646.60 2633.78 25.46 143.25x 103.46x
mobilenet_v1 1, 3, 224, 224 177.29 37.84 0.98 181.09x 38.65x
mobilenet_v2 1, 3, 224, 224 166.41 23.81 0.94 177.97x 25.46x
resnet50 1, 3, 224, 224 939.19 163.35 10.56 88.93x 15.46x
shufflenet_v2 1, 3, 224, 224 54.52 8.66 - - -
squeezenet_v1.0 1, 3, 227, 227 338.19 231.34 9.67 34.96x 23.91x
squeezenet_v1.1 1, 3, 224, 224 172.08 32.18 5.82 29.57x 5.53x

측정에 사용된 onnx 모델은 아래의 코드를 이용해 생성하였습니다.

import torch
import torchvision.models as models
import os

output_dir = "onnx_models"
os.makedirs(output_dir, exist_ok=True)

model_configs = [
#    ("densenet201", models.densenet201, (1, 3, 224, 224)),
    ("inception_v3", lambda: models.inception_v3(aux_logits=False), (1, 3, 299, 299)),
    ("mobilenet_v2", models.mobilenet_v2, (1, 3, 224, 224)),
    ("resnet50", models.resnet50, (1, 3, 224, 224)),
#    ("shufflenet_v2_x2_0", models.shufflenet_v2_x2_0, (1, 3, 224, 224)),
    ("squeezenet1_0", models.squeezenet1_0, (1, 3, 227, 227)),
    ("squeezenet1_1", models.squeezenet1_1, (1, 3, 224, 224)),
]

def export_onnx_model(model_name, model_fn, input_size):
    print(f"[INFO] Exporting {model_name}...")

    model = model_fn()
    model.eval()

    dummy_input = torch.randn(input_size)

    output_path = os.path.join(output_dir, f"{model_name}.onnx")

    torch.onnx.export(
        model,
        dummy_input,
        output_path,
        export_params=True,
        opset_version=11,
        do_constant_folding=True,
        input_names=["input"],
        output_names=["output"],
        dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}}
    )

    print(f"[OK] {model_name} exported to {output_path}")

for name, fn, input_shape in model_configs:
    try:
        export_onnx_model(name, fn, input_shape)
    except Exception as e:
        print(f"[ERROR] Failed to export {name}: {e}")


import torch
from pytorchcv.model_provider import get_model

model = get_model("mobilenet_w1", pretrained=True).eval()
dummy_input = torch.randn(1, 3, 224, 224)

torch.onnx.export(
    model,
    dummy_input,
    "mobilenet_v1.onnx",
    input_names=["input"],
    output_names=["output"],
    opset_version=11
)
import torch
import pretrainedmodels
import os

model_name = 'inceptionv4'
model = pretrainedmodels.__dict__[model_name](pretrained='imagenet')
model.eval()

dummy_input = torch.randn(1, 3, 299, 299)

onnx_path = os.path.join("onnx_models", f"{model_name}.onnx")
os.makedirs("onnx_models", exist_ok=True)

torch.onnx.export(
    model,
    dummy_input,
    onnx_path,
    input_names=["input"],
    output_names=["output"],
    export_params=True,
    opset_version=11,
    do_constant_folding=True,
    dynamic_axes={
        "input": {0: "batch_size"},
        "output": {0: "batch_size"}
    }
)


2 Likes