コードの自動フォーマット(ROS2 Foxy)

ROS2ではcolcon testでテストが動いてくれますが、このとき、コードが決められたルール通りにコーディングされているかチェックが入ります。 テストが通らないと気持ち悪いので直すのですが、いちいち手で直していると面倒です。そこでamentのCLIツールを使ってコードを自動で整形します。

環境

  • OS:Ubuntu 20.04
  • ROS version:foxy

ament_uncrustify

インストールは以下の通り。

$ sudo apt install -y ros-foxy-ament-cmake-uncrustify ros-foxy-ament-uncrustify

使い方は次の通り。

$ ~/ros2_ws # ワークスペースへ移動
$ ament_uncrustify

次のような感じでスタイルを満たしていないコードを出力してくれる。

Code style divergence in file 'src/ros2_tutorial_collection/tutorial_publisher/src/talker.cpp':

--- src/ros2_tutorial_collection/tutorial_publisher/src/talker.cpp
+++ src/ros2_tutorial_collection/tutorial_publisher/src/talker.cpp.uncrustify
@@ -27,2 +27,3 @@
-class Talker : public rclcpp::Node {
- private:
+class Talker : public rclcpp::Node
+{
+private:
@@ -32,3 +33,4 @@
- public:
-  Talker(const std::string& node_name, const std::string& topic_name)
-      : Node(node_name) {
+public:
+  Talker(const std::string & node_name, const std::string & topic_name)
+  : Node(node_name)
+  {
@@ -41,3 +43,3 @@
-      RCLCPP_INFO(this->get_logger(), "%s", msg_.data.c_str());
-      this->pub_->publish(msg_);
-    };
+        RCLCPP_INFO(this->get_logger(), "%s", msg_.data.c_str());
+        this->pub_->publish(msg_);
+      };
@@ -49 +51,2 @@
-int main(int argc, char* argv[]) {
+int main(int argc, char * argv[])
+{

間違いがたくさんあるので、このままだとcolcon testしたときにエラーが出てしまう。

そこで--reformatオプションを追加して自動フォーマットする。

$ ament_uncrustify --reformat

次のような表示が出てリフォーマットが完了する。

$ Code style divergence in file 'src/ros2_tutorial_collection/tutorial_publisher/src/talker.cpp': reformatted file

これだとcolcon testしてもちゃんとテストが通る。

スタイルは次のURLを使っているはず。

github.com

自分でcfgファイルを編集したい場合は次のリポジトリを参考にすると良さそう。

github.com

ament_clang_format

clang-format形式でコードが記述されているかチェックしてくれる。

インストールは次の通り。

$ sudo apt install -y clang-format
$ sudo apt install -y ros-foxy-ament-cmake-clang-format ros-foxy-ament-clang-format

使い方は次の通り。

$ cd ~/ros2_ws # ワークスペースへ移動
$ ament_clang_format

このままだとbuildフォルダやinstallフォルダまで見に行ってしまうので、ソースコードのあるパスだけ指定する場合は以下を実行する。

$ ament_clang_format ./src

間違いを自動で修正するには--reformatオプションをつける。

$ ament_clang_format --reformat ./src

すると自動的にソースコードを.clang-formatのスタイルに合わせてフォーマットしてくれる。

どんなスタイルでフォーマットするかは.clang-formatに記述する。デフォルトの.clang-formatは多分これを使ってる。

github.com

自分で.clang-formatを作りたい場合は以下のコマンドを実行する。以下はGoogleスタイルを使った場合だが、.clang-formatファイルを直接編集しても良い。

$ clang-format -dump-config -style=Google > .clang-format

ROS2のスタイルは以下に記述がある。

docs.ros.org

独自スタイルでフォーマットする場合は以下の通り。

$ ament_clang_format ./src --reformat --config .clang-format

package.xmlとCMakeLists.txtを次の行を追加するとcolcon testでclang-formatのチェックが入ってくれる。(だが同時にuncrustifyのチェックも走る。残念ながらuncrustifyの外し方がわからなかった。)

<buildtool_depend>ament_cmake</buildtool_depend>
<test_depend>ament_cmake_clang_format</test_depend>
  • CMakeLists.txt
find_package(ament_cmake REQUIRED)
if(BUILD_TESTING)
  find_package(ament_cmake_clang_format REQUIRED)
  ament_clang_format()
endif()

どっちがいいの?

clang-formatのほうが新しいし、ユーザー数も多い。uncrustifyはそうでもない様子。ただROS2のデフォルトはuncrustifyを採用している。clang-formatのほうが将来性はあるという認識はあるようだが、これまでuncrustifyでやってきて今からすべてのリポジトリをリフォーマットするのはコストの割にメリットが少ないという考えらしい。

github.com