작업환경: Ubuntu18.04, ROS 는 root (not virtual)로 설치한 상황이며 나머지 디펜던시는 모두 virtualenv에서 진행 (아래에 자세히 설명함)
배경지식
원래는 segmatch라는 리포였다가 (17 ICRA 시절) 이름이 segmap (18 RSS 시절) 으로 바뀌었다.
segmap 공식 리포 (ethz-asl/segmap) 의 경우 빌드하려면 딥러닝 기반 segmap말고 안딥러닝인 segmatch를 쓰고 싶어도 tensorflow_ros_cpp 를 무적권 빌드해야해서 너무 불키하다.
그래서 인터넷에 segmatch 포크본들이 돌아다니고 있어서 해보니까 왠지 안된다.
그래서 그냥 공식리포본에서 tensorflow_ros_cpp 를 빌드를 어찌저찌 해내기로 결심하였다.
과정
수많은 삽질들이 있었으나 작동하는 사항만을 아래 기술해보자.
일단 모든 과정들을 virtual env 에서 하면 된다. (모든 캣킨 빌드들 및 로스실행 포함). tf 를 virtualenv 에서 설치하는 게 편하기 때문.
일단 segmap 저자의 리드미에서 하라는 순서로 해도되지만, 내 기준에 먼저 해놓으면 좋은것부터 이제 설명해보자.
일단 작업할 virtual environment 를 만들자.
$ virtualenv ~/segmapenv # 하면 만들어지고$ source ~/segmapenv/bin/activate # 하면 접속됨 (conda activate 같은 것 같다). 그러면 앞에 (env name) 이 뜬다(segmapenv)$ # 예시
그럼 ~/segmapenv 에 대충 mkdir home 해서 home 밑에서 작업해보자
이제 tensorflow 를 설치해야 한다.
간편하게 pip install 하면 안되냐 싶겠지만 segmap 이 쓰고 있는 tensorflow_ros_cpp 라는 모듈이 그러면 안된다.
간단히 이유를 설명하자면 tf를 설치하는 방법에는 세가지가 있다. 1. pip, 2. bazel, 3. tensorflow_catkin
1은 잘 알테고 (하지만 지금 이걸로 설치하면 마지막에 API가 달라서? segmapper 가 링크가 안된다 — 다른 디펜던시 컴파일 20분(-j32의 경우)~2시간 겨우겨우 기다리고 마지막에 빌드 에러나는 환장하는 상황을 볼 수 있다), 3은 몰라도 되고 (궁금하면 따로 찾아보자)
결론은 2번 방법인 bazel 로 설치해야 한다. bazel은 구글이 만든 빌드툴 어쩌구 저쩌구… 그렇다고 한다. 뭐 자세히 알필요는 없고
암튼 2로 해야 하는이유는 tensorflow_ros_cpp 의 깃 리포에 가보면 표들이 있는데 https://github.com/tradr-project/tensorflow_ros_cpp
Ubuntu 18.04 64bits, Python 2.7.6, ROS Melodic 의 경우 1.8.0 tf version을 사용할 시 bazel cpu 및 gpu 에만 체크표시가 되어있다. 여기 보면 ABI difference problems 라는 말이 나오는데 이게 위에서 말한 20분 기다리고 마지막에 에러날때 볼 수 있는 현상이다. 이 고생을 안하려면 무적권 bazel 로 설치하자.
https://github.com/tradr-project/tensorflow_ros_cpp#custom-compilation-of-tensorflow-using-bazel 를 읽어보자.
그나저나 일단 tf src를 받아야 한다. https://www.tensorflow.org/install/source?hl=ko 여기 잘 나와있음.
segmap저자는 1.8.0 을 쓰라고 하니 (언제적 버전이지만…) 시키는 대로 하자. 해당 브랜치로 변경해주어야 한다.
(segmapenv)$ git checkout r1.8
직접 빌드하는경우 configuration 을 정해줘야 하므로 ./configure 하자. 근데 계속 엔터를 갈기면 된다. 즉 디폴트 옵션으로 하면됨.
우리는 1.8.0 을 빌드할것이므로
그리고 cpu 버전으로 일단 빌드하고 있다. 내 목표는 segmap까지도 필요없고 segmatch만 쓰는 것이므로…
따라서 다음 명령어를 해주면 된다. 고 나와있다. (근데 일케 하지마시오)
(segmapenv)$ bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package # 이 때 저 // 까지 모두 포함해서 한줄로 써주면 된다. 헷갈리면 다시 여기를 보자 https://www.tensorflow.org/install/source?hl=ko
근데 이대로 하면 안됨. 안된다. 안된다. 안된다. 안된다. 안된다.
https://www.tensorflow.org/install/source?hl=ko 여기서 하려고 하는거는 빌드를 직접 내 입맛에 맞는 configuration 으로 해서 결국에는 pip 패키지를 만들려고 하는건데
우리의 목표는 아예 pip 패키지 아니기 때문. segmap 리드미에 pip 로 설치하라 되어있는데 안됨
Follow the Installing TensorFlow from Sources guide up to “Configure the installation” (including), and build the C++ library with the following command:
bazel build --config=opt --define framework_shared_object=false tensorflow:libtensorflow_cc.so You don’t need to continue with the guide building or installing the pip package (but you might be interested, because a custom-built tensorflow can provide you with higher performance even in Python).
그니껜 bazel을 쓰긴 쓸건데 https://www.tensorflow.org/install/source?hl=ko 있는대로 할필요 없다는 뜻임
그리고 bazel build 뒤에 붙은 옵션들도 tf site에 있는 것과 다른데 절대 위의 명령어로 해주어야 한다.
라고 해서 뒤에 이상한 옵션들이 더 붙는데 이거는 pip 도 찾긴찾을래? 라는 거 므로 사실 ON으로 하면 안된다. segmap_ws/src/tensorflow_ros_cpp 밑에 CMakeLists.txt 가 있는데 거기서 bazel 말고 다른애들을 찾을 가능성을 다 off 해주자. 즉
# variables affecting the search for the tensorflow libraryset(FORCE_TF_PIP_SEARCH OFF CACHE BOOL “Whether to search for pip-installed Tensorflow even on systems using C++11 ABI”)set(DISABLE_TF_PIP_SEARCH ON CACHE BOOL “Whether to skip search for pip-installed Tensorflow”)set(FORCE_TF_BAZEL_SEARCH ON CACHE BOOL “Whether to search for bazel-compiled Tensorflow even if tensorflow was already found”)set(DISABLE_TF_BAZEL_SEARCH OFF CACHE BOOL “Whether to skip search for bazel-compiled Tensorflow”)set(FORCE_TF_CATKIN_SEARCH OFF CACHE BOOL “Whether to search for tensorflow_catkin even if tensorflow was already found”)set(DISABLE_TF_CATKIN_SEARCH ON CACHE BOOL “Whether to skip search for tensorflow_catkin”)
그리고 그 좀 아래에 보면 bazel로 tensorflow_ros_cpp를 빌드 할때 두 가지를 얘가 끌어다가 쓰는 걸 알수있다.
# variables affecting bazel searchset(TF_BAZEL_LIBRARY “{CATKIN_DEVEL_PREFIX}/../libtensorflow_cc.so” CACHE STRING “Path to the bazel-compiled Tensorflow C++ library”)set(TF_BAZEL_SRC_DIR “{CATKIN_DEVEL_PREFIX}/../tensorflow-include-base” CACHE STRING “Path to the Tensorflow sources directory”)
즉 .so 파일과 tensorflow source 가 필요한건데 tensorflow source 의 경로는 지금 어쩌구…../tensorflow-include-base 라고 되어있는데 귀찮으니까 절대경로로 바꿔주자. 아까 tensorflow git clone 했던 그 디렉토리를 해주면 된다.
그럼 이제 아까 bazel build 로 만든 .so 파일이 어딘가 있는데 일단 대충 탐색기에서보면 못찾겠다. 이때 find 명령어를 써주자
(segmapenv)$ cd /
(segmapenv)$ sudo find .-name*libtensorflow_cc.so*
그리고 다시 segmap_ws/src/tensorflow_ros_cpp 의 CMakeLists.txt 로 돌아가서 .so 를 찾는 라인에 경로를 저 내가 복사해놓은 어딘가붙여넣을 경로 로 바꿔주면 된다.
근데 기본적으로 {CATKIN_DEVEL_PREFIX}/../libtensorflow_cc.so 라고 되어 있는데 이거는 catkin workspace (devel, build, src있는 그 경로) 경로를 의미한다. 나는 cmakelist 에 저 - - 라인을 바꾸기 귀찮아서 so파일을 아예 workspace (devel build src와 같은 위치) 에 복사해버림.
그러고 나서 (아참 catkin_tools 를 미리 설치해야 함 그래야 catkin build 를 쓸수있음)
(segmapenv)$ catkin build tensorflow_ros_cpp
하니까 한 30초 안걸려서 빌드가 다 됐다.
이제 진짜 마지막으로 아래 명령어를 해주면
(segmapenv)$ catkin build segmapper
segmapper 및 segmapper 가 필요로 하는 디펜던시들이 모두 컴파일이 된다.
근데 pcl_catkin 이랑 gtsam이 진짜 개오래 걸린다. 그래서 조금이라도 더 빨리 해주기 위해서
나는 i9–9900 을 사용중이어서 코어가 16개 (virtual로는 총 32개) 여서
(segmapenv)$ catkin build segmapper -j32
라고 해주었다.
그러면 20분정도 걸린다. 램은 많이 쓸때는 40G까지 올라간듯 (64기가 장착중)
코어가 많아도 램딸리면 터질수있으니 이거는 자기 시스템에 맞게 조절바람.
그러면 마지막에
이런 화면이 뜨면 모두가 잘 빌드가 된것이다! ㅠㅠ
(segmapenv)$ source devel/setup.bash
를 해주고
저자가 올려둔 데이터 (KITTI 00 번과 05번, 각 16G, 10G) 를 http://robotics.ethz.ch/~asl-datasets/segmap/segmap_data/ 여기서 받아서 적절한 위치에 bag file 을 놓아두고
하면 되는데 gedit kitti_loop_closure.launch 해서 여기보면 bagfile 경로를 지정하게 되어있다. 그거를 내가 위치시킨 경로로 바꿔주면 아마 실행 될것임.
참고로 kitti_loop_closure.launch 가 17 ICRA의 segmatch이고 cnn_kitti_loop_closure.launch가 18 RSS의 segmap 이다. (암튼 segmatch를 쓰고싶어도 tensorflow_ros_cpp를 컴파일해야했던 ㅠㅠ)
근데 틀면 기본적으로 rviz 에서는 아무것도 안보여지는데 저자가 올려둔 rviz config 파일을 같이 틀어야 아마 보여질듯 http://robotics.ethz.ch/~asl-datasets/segmap/segmap_data/kitti/
근데 귀찮으니까 그냥 왼쪽 아래에서 add 해주고 target/representation인가…? 이거를 틀면 잘 실행되고 있음을 알 수 있다. 자세한건 정광욱님의 플레이 영상을 보면 참고가 됨. https://www.youtube.com/watch?v=Hb7Agk8fs10&t=3s
05번을 다 돌아보았다.
그나저나 다 돌고 런치파일을 실행한 터미널을 ctrl+C 하면 알아서 로그 파일과 결과파일을 /tmp/ 어딘가에 저장해준다. (어디 저장했다고 경로가 뜸)