コードの自動フォーマット(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を使っているはず。
自分でcfgファイルを編集したい場合は次のリポジトリを参考にすると良さそう。
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は多分これを使ってる。
自分で.clang-formatを作りたい場合は以下のコマンドを実行する。以下はGoogleスタイルを使った場合だが、.clang-formatファイルを直接編集しても良い。
$ clang-format -dump-config -style=Google > .clang-format
ROS2のスタイルは以下に記述がある。
独自スタイルでフォーマットする場合は以下の通り。
$ ament_clang_format ./src --reformat --config .clang-format
package.xmlとCMakeLists.txtを次の行を追加するとcolcon test
でclang-formatのチェックが入ってくれる。(だが同時にuncrustifyのチェックも走る。残念ながらuncrustifyの外し方がわからなかった。)
- package.xml
<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でやってきて今からすべてのリポジトリをリフォーマットするのはコストの割にメリットが少ないという考えらしい。
コマンドラインからバイト型をパブリッシュする
忘れそうなので。
$ ros2 topic pub /topic std_msgs/msg/Byte "{data: {5}}" publisher: beginning loop publishing #1: std_msgs.msg.Byte(data=b'\x05') publishing #2: std_msgs.msg.Byte(data=b'\x05') publishing #3: std_msgs.msg.Byte(data=b'\x05') ros2 topic pub /topic std_msgs/msg/Byte "{data: {255}}" publisher: beginning loop publishing #1: std_msgs.msg.Byte(data=b'\xff') publishing #2: std_msgs.msg.Byte(data=b'\xff') publishing #3: std_msgs.msg.Byte(data=b'\xff')
256をパブリッシュするとFailed to populate field: bytes must be in range(0, 256)
と出るので多分あってる。
97,98,99...とパブリッシュすると表示上はa,b,c...に変換される。
ROS2のコピーライトのあれこれ
概要
ament_copyrightを改良することで、独自のコピーライトを作ってテストを通すことができます。
コマンドラインツールを使用して、コピーライトをあとからまとめて挿入できます。
動機
ROS2のパッケージを作るとき、コピーライトを書かなければなりませんが、いちいちコピペするのが面倒で書き忘れてエラーが出たりしてました。
また仕事でROS2のパッケージを作るときは企業独自のコピーライトを書きたいってときがあるのですが、独自のコピーライトでは、デフォルトのament_copyrightを使うとテストで引っかかってしまいます。
どうにかならないかと思い、いろいろ調べていると、ament_copyrightをを改良することで独自のコピーライトを作成できるということがわかりました。
以下のリポジトリをクローン→編集でできます。
やり方
- 上のリポジトリをクローン
- 次のファイルを書き換える。
- mycompany_ament_copyright/template/mycompany_contributing.txt
- コントリビューターへ伝えたいことを書く。
- mycompany_ament_copyright/template/mycompany_header.txt
- 各ファイルのヘッダー部分に必要なコピーライトを書く。
- mycompany_ament_copyright/template/mycompany_license.txt
- ライセンスファイルの記述を書く。
- setup.py
- 4行目と28~30行目を編集する。
- \mycompany_ament_copyright/__init__.py
- 18, 19行目を編集する。
- mycompany_ament_copyright/copyright_names.py
- 18行目を編集する。
- mycompany_ament_copyright/licenses.py
- 40行目を編集する。
- test/cases/mycompany_license/case.py
- mycompany_header.txtをコメントアウトしたテキストを書いておく。
- mycompany_ament_copyright/template/mycompany_contributing.txt
- colcon build & source install/setup.bashを実行する。
使い方
package.xmlに以下を追加する。
<test_depend>mycompany_ament_copyright</test_depend>
C++の場合はCMakeLists.txtに以下を追加する。
find_package(mycompany_ament_copyright REQUIRED)
colcon test
でテストを実行して、コピーライトが通っていることを確かめる。
コマンドラインツール
作成したmycompany_ament_copyrightはコマンドライトして使用できます。ヘルプは以下のような感じ。
$ mycompany_ament_copyright --help usage: mycompany_ament_copyright [-h] [--exclude [filename [filename ...]]] [--add-missing COPYRIGHT_NAME LICENSE] [--add-copyright-year [ADD_COPYRIGHT_YEAR [ADD_COPYRIGHT_YEAR ...]]] [--list-copyright-names] [--list-licenses] [--verbose] [--xunit-file XUNIT_FILE] [paths [paths ...]] Check code files for copyright and license information. positional arguments: paths The files or directories to check. For directories files ending in '.c', '.cc', '.cpp', '.cxx', '.h', '.hh', '.hpp', '.hxx', '.cmake', '.py' will be considered (except directories starting with '.' or '_' and 'setup.py' files beside 'package.xml' files). (default: ['.']) optional arguments: -h, --help show this help message and exit --exclude [filename [filename ...]] The filenames to exclude. (default: None) --add-missing COPYRIGHT_NAME LICENSE Add missing copyright notice and license information using the passed copyright holder and license (default: None) --add-copyright-year [ADD_COPYRIGHT_YEAR [ADD_COPYRIGHT_YEAR ...]] Add the current year to existing copyright notices (default: None) --list-copyright-names List names of known copyright holders (default: False) --list-licenses List names of known licenses (default: False) --verbose Show all files instead of only the ones with errors / modifications (default: False) --xunit-file XUNIT_FILE Generate a xunit compliant XML file (default: None)
この中で便利なのが--add-missing
オプションです。コピーライトがないすべてのファイルにコピーライトを追加してくれます。
ワークスペースで以下を実行するとワークスペース内のパッケージにヘッダーを追記します。
$ mycompany_ament_copyright --add-missing mycompany mycompany
開発中はコピーライトを書かず、リリースする際に一括でコピーライトを追記する、といったことが可能です。
ちなみにcolcon test
でコピーライトのテストを回避するには、
C++の場合、CMakeLists.txtのテストの項目に以下を追記します。
set(ament_cmake_copyright_FOUND TRUE) set(ament_cmake_cpplint_FOUND TRUE)
pythonの場合はros2 pkg create ...
で自動生成されるtestフォルダのtest_copyright.py
を削除すればいいです。