はじめに
この記事はROS2 Advent Calendar 23日目の記事です。
本当は Roboclaw というモータードライバをROS2対応する記事を書く予定だったのですが、間に合いませんでした。こちらは別途目処が立ったらQiitaで紹介したいと思います。
さて、私は2017年に ROSのC++のソースコードをgdbでデバッグする方法 という記事をQiitaで執筆したのですが、この記事は今でも自分でよく見返すことがあります。
おそらくROS2での開発においても、gdbを使ってデバッグしようとした時にリファレンスが欲しくなることは間違いないでしょう。
ということで、ROS2を使ってC++のコードを書いた時にgdbでデバッグするときに、ros2 run
やros2 launch
を使った方法を日本語で簡単に解説しているサイトがないのでここに書き留めます。
準備
gdbを使用するためには、デバッグ情報を付与する必要があります。
colcon build
では以下のようにしてデバッグ情報付きでビルドをすることができます.
colcon build --cmake-args -DCMAKE_BUILD_TYPE=Debug
ROS1ではcatkin_make
でもcatkin build
でも直接CMakeに引数を与えていましたが、ROS2では--cmake-args
オプションをつける必要があるようです。
ros2 runでgdbを利用する
もちろん、ros2 run
にもrosrun
と同じように実行時に引数を与えることで、実行時にプレフィックスを指定することが可能です。例えばgdbを利用する場合には、以下のようなコマンドを実行します。
ros2 run --prefix 'gdb --args' pkg_name node_name
この書式はROS1と全く変わりありませんね。
ros2 launchでgdbを利用する
さて、roslaunch
のROS2版であるros2 launch
ですが、Dashing時点ではlaunchファイルをPythonでしか記述することができません。roslaunch
では<node>
タグにlaunch-prefix
属性を設定することができましたが、Pythonでも同じことが可能でしょうか?
結論から書くと、執筆時点ではgdbからNodeを立ち上げることはできましたが、gdbのプロンプトを使うことができませんでした。つまり、ブレークポイントを張ったりプログラムを実行したりすることができませんでした。何か方法はあると思うのですが、まだ見つけられていないので、今後調べたいと思います。
私が取った方法を念の為記述しておきます。Pythonでlaunchファイルを記述して、Nodeを立ち上げる際に使うlaunch_ros.actions.Node
クラスはlaunch.actions.ExecuteProcess
を基底クラスに持っていて、このクラスはコンストラクタに引数prefix
を持っています。そのため、launchファイルをPythonで記述して立ち上げるNodeをgdbでデバッグする場合には、以下のように記述してやれば良さそうです。
from launch import LaunchDescription
import launch_ros.actions
def generate_launch_description():
return LaunchDescription([
launch_ros.actions.Node(
package='pkg_name', node_executable='node_name',
output='screen', prefix='gdb --args'])
しかし、このlaunchファイルをros2 launch
から起動すると、以下のようにgdbからNodeは立ち上がるものの、先ほども書いたとおりgdbのプロンプトが起動しません。
user@hostname:~/ros2_ws# ros2 launch pkg_name node_name.launch.py
[INFO] [launch]: All log files can be found below /root/.ros/log/yyyy-mm-dd-HH-MM-SS-MS-hostname-5625
[INFO] [launch]: Default logging verbosity is set to INFO
<launch.launch_description.LaunchDescription object at 0x7f9cbc962748>
[INFO] [node_name-1]: process started with pid [5635]
[node_name-1] GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
[node_name-1] Copyright (C) 2018 Free Software Foundation, Inc.
[node_name-1] License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
[node_name-1] This is free software: you are free to change and redistribute it.
[node_name-1] There is NO WARRANTY, to the extent permitted by law. Type "show copying"
[node_name-1] and "show warranty" for details.
[node_name-1] This GDB was configured as "x86_64-linux-gnu".
[node_name-1] Type "show configuration" for configuration details.
[node_name-1] For bug reporting instructions, please see:
[node_name-1] <http://www.gnu.org/software/gdb/bugs/>.
[node_name-1] Find the GDB manual and other documentation resources online at:
[node_name-1] <http://www.gnu.org/software/gdb/documentation/>.
[node_name-1] For help, type "help".
[node_name-1] Type "apropos word" to search for commands related to "word"...
[node_name-1] Reading symbols from /root/ros2_ws/install/pkg_name/lib/pkg_name/node_name...done.
例えば、gdb --args
をgdb -ex run --args
にしてやれば、プログラムをとりあえず実行することができます。しかし、プロンプトが表示されないためSegmentation Faultで落ちてもバックトレースを表示することはできません。
Dashingではros2 launch
からPython以外で記述されたlaunchファイルを立ち上げることはできませんが、6日目の@youtalkさんの記事にもあったように、EloquentではXMLでlaunchファイルを記述できるようなので、そちらも追って試してみたいと思います。