はじめに
先日、自宅で自己位置推定やSLAMで遊んでみたいと思い、安価なDepthセンサを探すことにしました。 Kinect v1は持っているのですが、あれはUSB以外に電源が必要だったり、本体が大きいなど若干今では使いにくいため、もう少し新しいものがないかとメルカリを見ていたらrealsenseの数年前のモデルが5000円ほどで出ているのを見つけました。 intel製でLinuxやROSの公式サポートもあるようなので、これは安心かと思い購入しました。 が、しかし、意外とすんなりというわけには行きませんでした。製品が古いため公式でサポートされているのはUbuntu 16.04までで、現行の20.04や18.04でもコンパイルエラーが出るという状態でした。
準備
基本的は以下のサイトを参考にしました。
https://qiita.com/h_tajiri/items/3709333223778b749130
まず、ROS noeticが公式手順でセットアップされていることが前提となります。
https://github.com/IntelRealSense/librealsense
https://github.com/IntelRealSense/realsense-ros
realsense R200をROSで動かすためには、librealsenseとreansense-rosという2つのROSパッケージが必要です。前者はintel公式のライブラリでROSパッケージとしても単体としても利用できます。後者はlibrealsenseをROSノードとしてラッピングしたもののようです。 注意点は、上記のリポジトリは両方とも最新のものでは新しいrealsenseしかサポートしておらず、R200のような旧機種はリポジトリやタグを切り替えなければならないということです。
まず、catkinのワークスペースを作り、その中に上記リポジトリをクローンしていきます。
librealsenseについては、上記Gitのreadme記載には罠があります。readmeにはタグv1.12.1を使用するように書かれていますが、これはincludeの記載漏れなどがあってチェックがザルな昔のgcc(5系など)でないとコンパイルできません。 これを直したものがlegacyブランチとなっているため、今回はこれを利用します。
realsense-rosも同様に、R200をサポートしていた当時のブランチ(indigo-devel)に切り替えを行います。
mkdir -p ~/catkin_ws/src
cd ~/catkin/src
git clone -b legacy https://github.com/IntelRealSense/librealsense.git
git clone -b indigo-devel https://github.com/IntelRealSense/realsense-ros.git
また、必要パッケージも入れます。
sudo apt update
sudo apt install libusb-1.0-0-dev pkg-config libglfw3-dev
18.04以降で動かすための修正
さて、ここでいくつかの修正が必要になりました。
librealsense
まず、librealsenseをそのままコンパイルすると、デバイスとの通信のバックエンドにv4l2という、LinuxのUSBカメラなどを扱うための機能を利用しようとしますが、18.04以降のカーネルではどうしても以下のようなioctlエラーが発生してしまい、カメラに接続することができませんでした。
[ERROR] [1598715656.999810423]: /camera/driver - Error calling rs_create_context ( api_version:11201 ):
UVCIOC_CTRL_QUERY:UVC_SET_CUR error 25, Inappropriate ioctl for device
カーネル依存ではどうしようもないかと思いながらソースを見ていたら、CMakeLists.txtで以下のような記述を見つけました。
if(WIN32)
configure_msvc_runtime()
set(BACKEND RS_USE_WMF_BACKEND)
set(REALSENSE_DEF CMake/realsense.def)
# Makes VS15 find the DLL when trying to run examples/tests
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
elseif(APPLE)
set(BACKEND RS_USE_LIBUVC_BACKEND)
else()
set(BACKEND RS_USE_V4L2_BACKEND)
endif()
どうもLinuxではV4L2を利用し、Mac OS Xではlibusbを使用するように設定されるようです。libusbはLinuxでも利用できるため、もしやと思い以下のように書き換えてみたところ、ビンゴで、画像取得できるようになりました。
if(WIN32)
configure_msvc_runtime()
set(BACKEND RS_USE_WMF_BACKEND)
set(REALSENSE_DEF CMake/realsense.def)
# Makes VS15 find the DLL when trying to run examples/tests
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
elseif(APPLE)
set(BACKEND RS_USE_LIBUVC_BACKEND)
else()
#set(BACKEND RS_USE_V4L2_BACKEND)
set(BACKEND RS_USE_LIBUVC_BACKEND)
endif()
realsense-ros
そしてもう一つはrealsense-rosです。これは内部でROS側のPCL(Point cloud library)を利用していますが、それがどうも当時からバージョンが上がったのかC++14が必須になったようで、ヘッダのコンパイルでエラーが出ます。このため、realsense-rosのC++バージョンを11から14に変更します。
# Set compile flags
set(CMAKE_CXX_FLAGS "-fPIE -fPIC -std=c++11 -O2 -D_FORTIFY_SOURCE=2 -fstack-protector -Wformat -Wformat-security -Wall ${CMAKE_CXX_FLAGS}")
↓
# Set compile flags
set(CMAKE_CXX_FLAGS "-fPIE -fPIC -std=c++14 -O2 -D_FORTIFY_SOURCE=2 -fstack-protector -Wformat -Wformat-security -Wall ${CMAKE_CXX_FLAGS}")
udevルールなどのインストール
librealsenseリポジトリを見ると、udevルールや、それに対応して接続したときにリセットするためのスクリプトなどが付属しているので、セットアップしておきます。
udevルール
cd ~/catkin_ws/src/librealsense
sudo cp config/99-realsense-libusb.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && udevadm trigger
接続したときにリセットを送るためのスクリプト?
cd ~/catkin_ws/src/librealsense/scripts
sudo ./install-r200-udev-fix.sh
ビルド
ここまで来たらビルドできるはずです。
cd ~/catkin_ws
catkin_make
動作テスト
参考サイトのとおりです。
使用する全ての端末で、先程コンパイルしたワークスペースにパスを通すため以下を実行してください。 恒常的に使用するなら.bashrcに入れるのも手です。
source ~/catkin_ws/devel/setup.bash
以下のコマンドをそれぞれ別の端末で入力していきます。 ROS関連ではどうも端末が画面に溢れてきますので、terminatorという端末ソフトを使ってウィンドウを分割して使うのがおすすめです。
# terminal 1
roscore
# terminal 2
roslaunch realsense_camera r200_nodelet_rgbd.launch
# terminal 3
rosrun tf static_transform_publisher 0.0 0.0 0.0 0.0 0.0 0.0 \map camera_link 100
# terminal 4
rosrun rviz rviz -d $(rospack find realsense_camera)/rviz/realsenseRvizConfiguration1.rviz
rvizにdepth画像や点群が表示されると思います。