C++

C++는 SLAM의 실무 언어입니다. 이후 레벨에서 공부할 거의 모든 시스템 --- ORB-SLAM, DSO, VINS-Mono, KinectFusion --- 이 C++로 작성되어 있는데, SLAM은 제한된 하드웨어에서 실시간으로 카메라 프레임, IMU 패킷, 최적화 문제를 처리해야 하기 때문입니다. 이 레벨에서 “C++를 안다”는 것은 단순한 문법이 아니라, SLAM 코드베이스가 사용하는 특정한 관용구와 툴체인에서 생산적으로 작업할 수 있다는 것을 의미합니다.

Modern C++ (C++11/14/17/20). SLAM 코드는 현대적 관용구에 전적으로 의존합니다: 범위 기반 for 루프, auto, 람다 함수, std::thread, 스마트 포인터, 이동 의미론(move semantics). 이동 의미론은 특히 중요한데, SLAM은 큰 객체(이미지, 포인트 클라우드, 디스크립터 행렬)를 여기저기로 전달하며, 핫 루프에서 우발적인 깊은 복사를 감당할 수 없기 때문입니다.

OOP와 디자인 패턴. SLAM 시스템은 상호작용하는 모듈들 --- 트래커, 로컬 매퍼, 루프 클로저, 맵 데이터베이스 ---로 구조화되며, 이들은 스레드 간에 상태를 공유합니다. 상속 대 합성, 센서 추상화를 위한 인터페이스, 흔한 패턴(맵 데이터베이스를 위한 싱글턴, 센서 드라이버를 위한 팩토리, 발행/구독 스타일 콜백을 위한 관찰자)을 이해하면 ORB-SLAM 같은 대규모 코드베이스를 읽기 쉬워집니다.

데이터 구조와 알고리즘. 최근접 이웃 검색을 위한 kd-트리와 해시 그리드, 키프레임 제거를 위한 우선순위 큐, 공가시성(covisibility)과 포즈 그래프 구조를 위한 그래프 등 복잡도를 끊임없이 따지게 됩니다. 올바른 컨테이너(std::vectorstd::unordered_map)를 선택하는 것은 프레임 레이트에 눈에 보이는 영향을 미칩니다.

컴파일러와 빌드 시스템. 실제 프로젝트는 Make나 Ninja를 구동하는 CMake로 빌드됩니다. Eigen/OpenCV를 찾고, 최적화 플래그(-O3, -march=native)를 설정하고, 서드파티 서브모듈을 관리하는 CMakeLists.txt를 읽고 쓰게 될 것입니다. SLAM 스타일의 최소한의 CMakeLists.txt:

cmake_minimum_required(VERSION 3.16)
project(my_vo)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BUILD_TYPE Release)          # forget this and everything is "slow"

find_package(OpenCV REQUIRED)
find_package(Eigen3 REQUIRED)

add_executable(vo main.cpp)
target_link_libraries(vo ${OpenCV_LIBS} Eigen3::Eigen)

컴파일러가 대략 무엇을 하는지(인라이닝, 벡터화, 디버그 대 릴리스 빌드)를 알면, “느린” SLAM 시스템이 흔히 단순한 디버그 빌드일 뿐임을 이해할 수 있습니다.

C++에서의 OpenCV. OpenCV는 기본적인 이미지 처리 레이어입니다: 이미지 읽기와 왜곡 보정, 특징 검출(cv::ORB, cv::SIFT), 매칭(cv::BFMatcher, cv::FlannBasedMatcher), 자세 추정(cv::solvePnP), 캘리브레이션(cv::calibrateCamera). 최소한의 특징 파이프라인은 다음과 같습니다:

cv::Ptr<cv::ORB> orb = cv::ORB::create(2000);
std::vector<cv::KeyPoint> kps;
cv::Mat desc;
orb->detectAndCompute(img, cv::noArray(), kps, desc);

cv::BFMatcher matcher(cv::NORM_HAMMING);
std::vector<cv::DMatch> matches;
matcher.match(desc_prev, desc, matches);

실제 SLAM 시스템에서의 동시성

실시간 SLAM 시스템은 여러 세분화 수준에서 병렬성을 적극적으로 활용합니다:

흔한 함정

SLAM에서의 의미

이 레벨 위의 모든 레벨은 여러분이 중간 규모의 C++ 코드베이스를 읽고, 빌드하고, 수정할 수 있다고 가정합니다. 논문을 재현한다는 것은 보통 C++ 리포지터리를 클론하고, 로컬의 Eigen/OpenCV 버전에 맞게 CMake 빌드를 고치고, 시간이 어디로 가는지 프로파일링하는 것을 의미합니다. C++ 유창성은 또한 SLAM 시스템을 사용하는 것에서 바꾸는 것으로 --- 특징 검출기를 교체하거나, 센서를 추가하거나, 스레딩이나 SIMD로 병목을 최적화하는 것으로 --- 넘어가게 해주는 것입니다.

실습

관련 문서