최종 평가 영상

1차 주행 영상

1차 주행 영상

풀영상 링크

2차 주행 영상

2차 주행 영상

풀영상 링크

중간 평가 결과

1st_test.png

  • 중간 평가 때는 자율주행으로 충돌하지 않고 1분 제한 시간 내에 도착하는 것이 목표였다. 안정적인 헤딩 로직 덕분에 무리 없이 20초만에 도착할 수 있었다.

최종 평과 결과

final_test.png

  • 최종 평가 때는 안정적인 자율주행 뿐만 아니라 카메라 비전을 통한 객체 인식 후 미션을 수행하는 것이 목표였다.
  • 1차 시도 때
    • 모든 장애물을 인식하고 안정적인 주행을 마치고 만점을 받을 수 있었다.
  • 2차 시도 때
    • 충돌 1회, 인식 문제 1회, 주차 구역 이탈로 감점이 있었다.

문제점 분석

2차 시도 때

  1. 빨간불을 인지하고 멈췄지만, 빨간불 인식이 순간 풀리면서 초록불로 바뀌기 전에 주행을 시작했다.
    • 빨간불을 2프레임 연속 인식하면 정지 모드가 되어 정지 후 초록불을 인식하고 빨간불이 사라지면 주행을 시작하는 로직이였지만
    • 빨간불을 순간 인식하지 못하고 신호등을 초록불로 인식해서 재주행 로직이 작동된 것으로 판단된다.
  2. 모든 장애물을 인식했지만, 좁아진 도로폭에서 조향하다가 아슬아슬하게 장애물에 부딪혔다.
    • Lab 공간에서 회색, 검은색, 빨간색에 대한 색은 설정 되어있었지만, 장애물 색인 파란색 계열은 설정되어 있지 않았다.
    • 디테일하게 색을 설정하지 않아, 평가시 조명 환경에 영향을 받아 조향량이 부족해졌고 충돌이 있었을 것으로 판단된다.
  3. 주차 마커를 인식하고 진행했지만, 주차 구역을 살짝 벗어나서 정지하였다.
    • 마지막 코너에서 장애물이 코너의 회전 반경을 줄이면서 주차 마커와 거리가 가까워졌다.
    • missing_frame 이후에 정지 로직이 작동하게 되는데 missig_frame 이 너무 길게 설정 되어 있어서 O 마커가 시야에서 사라진지 꽤 지났음에도 정지하지 않고 주행하여 주차 구역을 벗어나서 정지하게 된 것으로 판단된다.

문제점 개선

이미 프로젝트는 끝이 났지만, 해결책을 생각해보았다.

  1. 신호등 정지 로직에서 부족한 점이 무엇인가?

    빨간불을 잘못 인식한 경우를 대비해서 2프레임 연속 인식하면 트리거 되는 로직을 넣어두었다.

    2프레임이면 충분하다고 생각했지만, 순간 빨간불이 사라지고 초록불로 2프레임 우연히 인식할 수도 있다는 것을 보았다.

    실제 데이터 학습시 초록불 상황의 데이터가 부족하기에도 했고, 초록불 빛이 워낙 약하게 나오기도 했다.

    가끔 연습 주행 때도 비슷한 경우가 있었지만 잘 되는 경우가 더 많아 안일하게 방치한 것이 문제였던 것 같다.

    image.png

    • 실제로 초록색 불이 찍힌 사진이 빨간색 불에비해 매우 적었다는 사실을 평가 이후 피드백하는 과정에서 발견하였다.

    <빨간불이 사라지고 & 초록불이 보이면> 이라는 로직은 제어하기에 충분한 조건이였지만, 문제는 실제 센서 인식이 정확하다는 가정하에 내 로직이 보장 된다는 것이고, 노이즈가 끼고 비전 성능이 완벽하지 않은 상황이 발생할 수 있다는 것을 배웠다.

  2. 조향에서 부족한 점이 무엇인가?

    우리는 조향을 카메라로 이진화된 색을 구분하여 조향을 한다. 아래 사진과 같이 자동차는 여러 색이 섞여 있어서 특정 조건에서는 장애물로 인식해도 조향을 크게 하지 않을수도 있었다.

    스크린샷 2025-12-20 18.12.05.png

    • 파란색을 검정색으로 인식했기 때문에 검정 영역 도심이 더 왼쪽으로 계산될 수 없었다.

    연습 주행 때 한 번도 이렇게 조향량이 부족한 적이 없었어서 대비할 수 없었다. 최종 평가 때 처음 충돌이 있었던 거라 나도 당황을 많이 했다.

    인식하고 피해야하는 모든 물체에대해 색조정을 면밀히 해야한다는 것을 배웠다.

  3. 주차 마커가 시야에서 사라지고 정지하는 타이밍을 어떻게 알 것인가?

    지금은 주차 마커가 시야에서 사라지고 10프레임 연속 보이지 않으면 정지로 전환되는 로직이다.

    프레임당 인식 주기가 10ms이므로 0.01초마다 인식하고 이론상 0.1초 동안 보이지 않는다면 바로 정지했어야 한다.

    첫 번째 주행에서는 이론에 맞게 O가 시야에서 사라지자 마자 정지했지만, 어떤 이유에선지 두 번째 주행에서는 딜레이가 있었다. 연산량 때문에 딜레이가 있었나 추측하고 있긴 하지만 정확한 원인을 알 수 없었다.

느낀점

Sim-to-Real: 논리적 완벽함과 물리적 현실의 괴리

이번 프로젝트를 시작할 때, 나는 “알고리즘만 완벽하면 로봇은 완벽하게 움직인다”는 프로그래머의 관점을 가지고 있었다. 하지만 실제 하드웨어와 센서를 다루면서 마주한 현실은 전혀 달랐다. 이것은 로보틱스 분야에서 흔히 말하는 Sim-to-Real Gap의 축소판이었다.

1. 센서 데이터의 신뢰성 문제 (Garbage In, Garbage Out)

가장 큰 깨달음은 로직을 설계하는 것보다, 로직이 믿을 수 있는 데이터를 확보하는 것이 훨씬 어렵다는 점이었다.

  • 문제 상황: 2일차와 3일차에 겪었던 ‘조향 불안정’ 문제는 제어 알고리즘(PID)의 결함이 아니었다. 카메라가 그림자를 도로로 착각하거나, 빛 반사로 인해 검은색 도로를 회색으로 인식하는 노이즈 때문이었다.
  • 배운점: 아무리 정교한 PID 제어기와 FSM(유한 상태 머신)을 설계해도, 입력값인 heading_error 자체가 틀렸다면 출력값은 엉망이 될 수밖에 없다.
  • 해결: 이를 해결하기 위해 HSV 대신 Lab 색 공간을 도입하여 조도 변화에 강건함을 확보했고, 모폴로지 연산Connected Components 라벨링을 통해 “자동차가 밟고 있는 도로 덩어리”만 추출하는 전처리 과정을 구현했다. 이는 ‘제어’의 문제를 ‘인지’의 영역에서 해결한 공학적 접근이었다.

2. 물리적 제약과 소프트웨어의 타협

코딩 화면 속에서는 변수 값이 즉시 바뀌지만, 실제 물리 세계의 자동차는 관성이 있고 모터의 응답 지연이 존재한다.

  • 문제 상황: 장애물을 인식하고 즉시 조향 명령을 내려도, 모터가 토크를 발생시키고 타이어가 마찰력을 이겨내어 차체가 회전하기까지는 물리적 시간이 소요된다. 이로 인해 최종 평가 2차 시기에서 좁은 코너를 돌 때 미세한 충돌이 발생했다.
  • 배운점: 소프트웨어는 물리적 세계의 Latnecy와 Dynamics를 고려하여, 한 템포 더 빠르게 예측하고 더 보수적으로 판단해야 함을 배웠다.

엔지니어링 리더십: 설계 to 구현

팀의 리더이자 전체 시스템을 설계하고 구현하는 역할을 수행하며, 단순한 코더가 아닌 공학자를 경험할 수 있었다.

1. 시스템 아키텍처 설계: FSM과 YOLO의 결합

초기의 단발성 if-else 로직은 복잡한 미션 상황(신호등, 돌발 장애물, 주차)이 겹칠 때 스파게티 코드가 될 위험이 컸다. 이를 해결하기 위해 Layered Architecture를 도입했다.

  • Layer A (Perception): Lab 색 공간 변환, ROI 설정, YOLOv8n 객체 인식
  • Layer B (Decision): FSM 기반 상태 관리 (DRIVE → WAIT → HAZARD → PARKING)
  • Layer C (Control): PID 제어 및 모터 구동

이러한 모듈화 설계를 통해, 신호등 인식 오류가 발생했을 때 제어 로직을 건드리지 않고 ‘신호등 트리거 조건’만 수정하여 문제를 해결할 수 있었다. 이는 유지보수성과 확장성을 고려한 설계의 중요성을 입증했다.

2. 기술적 의사결정: Haar Cascade vs YOLOv8n

프로젝트 중간에 기존 예제 코드인 Haar Cascade를 버리고 YOLOv8n을 도입하기로 결정한 것은 큰 모험이었다.

  • 단점: 라즈베리 파이의 연산 자원 부족으로 전체 시스템이 느려질 수 있음.
  • 장점: 조명 변화와 객체 회전에 대한 압도적인 강건함(Robustness) 확보.
  • 결정: “빠르지만 부정확한 시스템”보다 “약간 느리더라도 신뢰할 수 있는 시스템”이 자율주행에 적합하다고 판단했다.
  • 결과: YoloAsyncRunner를 통해 추론과 주행 루프를 비동기로 분리함으로써 성능 저하를 방어했고, 결과적으로 복잡한 환경에서도 높은 인식률을 달성했다.

아쉬운 점과 향후 과제

완벽해 보였던 시스템도 극한의 상황(평가 당일의 조명, 미세하게 달라진 장애물 색상)에서는 허점을 드러냈다.

  1. 단일 센서의 한계: 카메라 하나에만 의존하다 보니, 시야각 밖의 상황이나 조명에 따른 색상 왜곡에 취약했다. 향후에는 LiDAR나 초음파 센서를 퓨전하여 거리 정보를 물리적으로 보정한다면 충돌 문제를 완벽히 해결할 수 있을 것이다.
  2. 데이터 다양성 부족: 최종 평가에서 빨간불을 놓친 것은 학습 데이터에 ‘다양한 조도의 초록불/빨간불’이 부족했기 때문이다. Data Augmentation 기법을 적극 활용하거나, 시뮬레이터(Gazebo)를 통해 가상 데이터를 확보하는 과정이 필요함을 느꼈다.

마치며: 공학적 직관의 완성

이번 P-project는 단순히 “자동차를 굴러가게 만드는 것”이 목표가 아니었다.

불확실한 현실 세계의 데이터 속에서 유의미한 정보를 찾아내고, 이를 바탕으로 최적의 판단을 내리는 자율주행의 기본을 탐구하는 과정이었다.

나는 이 과정에서 “센서 데이터는 거짓말을 할 수 있다”는 전제 하에 방어적인 로직을 설계하는 법을 배웠고, “최고의 알고리즘은 복잡한 수식이 아니라, 노이즈를 걸러내는 탄탄한 전처리에서 나온다”는 공학적 직관을 얻었다.

하드웨어 제어부터 딥러닝 모델 배포까지 전체 파이프라인을 직접 설계하고 구현하며 겪은 수많은 시행착오들은, 앞으로 어떤 복잡한 엔지니어링 문제를 마주하더라도 나에게 도움이 되는 기반이 될 것 같다.

Updated: