漱石枕流

勉強、開発したことのメモ

ROS開発のためのEmacs設定

ROSをC++で開発する際に、データタイプや名前空間をいちいち正確に書くのは正直しんどい。特にmsg、srv、actionファイルからどのようなデータ構造体が生成されたのかは確認しづらい(ConstPtr& を付け忘れて醜いコンパイルエラーが出るのはよくある)。また困ったことにflycheckのサーチパスに/opt/ros/kinetic/include~/catkin_ws/devel/includeを入れても、どういうわけかそれらを認識してくれない。ネットで探していたところironyを使ってROSパッケージのシンタックスチェックを行う方法を見つけた

Add include paths to flycheck and to company-irony? - Emacs Stack Exchange

のでメモ。これから説明する方法でROSパッケージの補完、コード・リーディングができるようになる。

手順1

自分がこれからビルドしようとしているパッケージに以下を追記

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

そのままcatkin_makeする。すると~/catkin_ws/buildcompile_commands.jsonが生成される。これはrtagsironyがソースファイルのパースやコード補完を行うために必要となる。後述のrtagsはCMakeLists.txtのあるディレクトリを自動で探してくれるが、compile_commands.json~/catkin_ws/build/に生成されるので、~/catkin_ws/jsonへのシンボリックリンクを貼っておくと自動で解析を行ってくれるようである。

(~/catkin_ws/)$ ln -sf build/compile_commands.json compile_commands.json

これをIronyに読み込ませていく。

手順2

melpaからironyyasnippetrtagsなどをインストール。自分は以下の記事を参照した。

C++11時代のEmacs C++コーディング環境

手順3

まずirony, yasnippetシンタックスチェック(静的解析)やコードの補完を行えるようにする。

$ cd catkin_ws/src
$ emacs my_pkg/***/src/node.cpp

Emacsを開いたら環境変数irony-cdb-search-directory-listを次のように打ち込んで編集

M-x irony-cdb-json-add-compile-commands-path

下のようにProject rootを聞かれるので~/catkin_ws/build/を指定する。次にCompile commandsを聞かれるので、同ディレクトリのcompile_commands.jsonを読みこませる。

Project root: ~/catkin_ws/build
Comiple commands: ~/catkin_ws/build/compile_commands.json

これで完了。さらにC-h v irony-cdb-search-directory-list環境変数irony-cdb-search-directory-listにbuildを付け加えておいた(念の為)。

f:id:amazingsoblin:20180702232007p:plain
ironyの設定

手順2の設定でEmacs起動時にironyが自動で起動するようになっているはずなので、再度.cppを開く。

$ emacs my_pkg/***/src/node.cpp

うまくいけばirony-serverが起動してシンタックスチェックを開始する。写真のようにros::の途中まで打ち込むと補完が行われるし、変数の型のチェックもリアルタイムで行われる。

f:id:amazingsoblin:20180702231150p:plain
補完

また自分で定義したmsgから自動生成される.hファイル(~/catkin_ws/devel/include/mypkg/内に置かれる)についても補完を行ってくれる。特にyasnippetを使えばテンプレートパラメータや関数の変数のリストも補完してくれるので、かなり便利である。

手順4

次にrtagsでコード・リーディングできるようにする。こうすると/opt/ros/kinetic/include内のファイルまで型や名前空間を追跡できるので、内部実装も覗けるようになる。手順2にしたがってrtagsとrtags-modeをインストールした後、rdmrcコマンドを使えることを確認する。

$ which rdm
/usr/bin/rdm
$ rdm --daemon

rtagsのタグを生成する。

$ 
$ cd ~/catkin_ws/build
$ rc -J .

rcコマンドがjsonの読み込みを開始するので、落ち着くまで待つ。Emacsでcppファイルを開き、タグジャンプしたい関数などにカーソルを合わせてM-.(Altを押しっぱなしにして-と.を順番に押す)すると定義されている箇所に飛べる。写真ではros::ServiceServer上にカーソルを合わせてジャンプしたところ/opt/ros/kinetic/include/rosに飛んだ。

f:id:amazingsoblin:20180702234252p:plain
ros::ServiceServerの定義にジャンプ

キーバインドは手順2の設定参照。

もちろん自分で作ったパッケージについてもCMAKE_EXPORT_COMPILE_COMMANDSをONにすれば、補完やタグジャンプを行えるようになる。

ROSのC++テンプレートメタプログラミングをふんだんに使っているので、ironyyasnippetで静的解析や補完を行いながら開発しないとどこでコンパイルエラーがどこで発生しているのか分かりづらい。

その他

.launch.urdf.xacroファイルを開くときにnxml-modeにするとインデントと閉じタグを勝手に入れてくれる。yamlファイルもyaml-modeでインデントできる。

(add-to-list 'auto-mode-alist '("\\.urdf" . nxml-mode))
(add-to-list 'auto-mode-alist '("\\.xacro" . nxml-mode))
(add-to-list 'auto-mode-alist '("\\.launch" . nxml-mode))
(add-to-list 'auto-mode-alist '("\\.yaml" . yaml-mode))

以上でかなり効率よく開発できる。

追記: clang-format

ROSにも以下のようなC++のスタイルガイドが存在するようである。

github.com