設定ファイルから見るLiDARシミュレータの世界
この記事はLiDAR Advent Calendar 2023の12/06分の記事です。
いろんなシミュレータのLiDARに関する設定ファイルの読書感想文です。
3D LiDARの簡単な分類
シミュレータの話に入る前に、一度シミュレーション対象であるLiDARをみておきましょう。 ここでは細かな動作原理の違いを考えずに出力される点群の特徴をざっくりと捉えていきます。
回転式LiDAR
昔からよくあり、現在でも主流のLiDARの種類です。 レーザーと受光センサのユニットを水平に回転させるため、水平360°にセンシングできることが特徴です。 1ユニットでは縦方向に視野を広げることができないため、ピッチ角を変化させた複数ユニットを用いることが多いです。 垂直方向の点群密度を増やすにはユニットを増やす必要があるため、水平方向の点群密度に対して縦方向の点群密度は粗くなりがちです。
SolidState式LiDAR
回転式(機械式)と対比されることが多いSolidState式は機械的な可動部が存在しない(または小さい*1)LiDARの種類です。
回転式とは違って光源を動かさずに光を曲げたり加工したりして走査する必要があるため、回転式に比べて水平視野はどうしても狭くなります。 一方で構造次第で垂直方向にも自由度を持てるので、垂直方向の点群密度を容易に上げることが可能です。 カメラの画像のような縦横比がほぼ同じ解像度をもつLiDARが多いですが、独自のスキャンパターンを持つLiDARも少なくありません。
シミュレータ選手紹介
今回見ていくシミュレータの選手紹介です。 オープンソースで提供されているもののみを対象としています。 3D LiDARは自動運転で使われることが多い関係上、自動運転向けシミュレータが多くなりました。
シミュレータ | 概要 |
---|---|
Gazebo | ROS向けデフォルトのシミュレータ |
Choreonoid | 産総研発の国産シミュレータ |
UnitySensors | Unityでセンサをシミュレーションするためのシミュレータ、というよりはライブラリ? |
CARLA | 自動運転業界でデファクトスタンダードになっているシミュレータ |
LGSVL | 旧Autoware向け標準シミュレータ |
AWSIM | 現Autoware向け標準シミュレータ |
各シミュレータの設定ファイル
一番最初に触れたように3D LiDARはそれぞれ独自の構成を持っています。
LiDARシミュレータで多くの種類のLiDARに対応するために、構造の違いをパラメータの違いで表現できるように一般化して実装されます。
この構造の一般化方式が色濃く出るのがLiDARセンサのために設定ファイルです。
さぁ、設定ファイルからLiDARシミュレータの世界に飛び込んでみましょう。
※一部ソースコードも含みますが、一般化できていれば設定ファイルとして扱います。
Gazebo(Classic)
垂直・水平方向に過不足なく表現力を持ったフォーマットです。 LiDAR以外にも深度カメラでも使えるように配慮されたフォーマットのように思えます。
<ray> <scan> <horizontal> <samples>32</samples> <resolution>1</resolution> <min_angle>-3.14156</min_angle> <max_angle>3.14156</max_angle> </horizontal> <vertical> <samples>3</samples> <resolution>1</resolution> <min_angle>-0.02</min_angle> <max_angle>0.02</max_angle> </vertical> </scan> <range> <min>0.05</min> <max>70</max> <resolution>0.02</resolution> </range> </ray>
Choreonoid
最低限のシンプルなパラメータで構造を表現しています。 視野角を下限上限の2パラメータではなく角度の1パラメータで表現しているため、 上方向などある方向に偏った視野をもつ3D LiDARを表現できないことに注意です。
yawRange: 180 yawStep: 0.4 pitchRange: 30.0 pitchStep: 2.0 scanRate: 20 maxDistance: 100.0
参考:URL
UnitySensors
このシミュレータは設定ファイルを持たず、それぞれのセンサーに専用実装を持っています。 しかし、以下のように実質設定ファイルとなっている箇所もあります。
[SerializeField] private RotatingLiDARScanPattern _scanPattern; [SerializeField] private float _minDistance = 0.0f; [SerializeField] private float _maxDistance = 100.0f; [SerializeField] private float _maxIntensity = 255.0f; [SerializeField] private float _gaussianNoiseSigma = 0.0f;
参考:URL
スキャンパターンは現状以下のようなものがサポートされているようです
名前 | 特徴 |
---|---|
RotatingLiDARScanPattern | 回転式LiDAR用の実装。垂直方向の角度は細かく設定できるようになっているのが特徴 |
CSVLiDARScanPattern | CSVファイルからスキャンパターンを読み込む。Livoxのような複雑なパターンも再現可 |
CARLA
回転式LiDARに特化した設定ファイルとなっています。 回転式以外の表現は難しいですが、流石自動運転向けと言ったところで大気減衰率やドロップオフ(点群の消失)に関するパラメータが充実しており、 天候によるLiDARセンシングの変化もシミュレーションできるようになっているようです。
Blueprint attribute | Type | Default |
---|---|---|
channels |
int | 32 |
range |
float | 10.0 |
points_per_second |
int | 56000 |
rotation_frequency |
float | 10.0 |
upper_fov |
float | 10.0 |
lower_fov |
float | -30.0 |
horizontal_fov |
float | 360.0 |
atmosphere_attenuation_rate |
float | 0.004 |
dropoff_general_rate |
float | 0.45 |
dropoff_intensity_limit |
float | 0.8 |
dropoff_zero_intensity |
float | 0.4 |
sensor_tick |
float | 0.0 |
noise_stddev |
float | 0.0 |
参考:URL
LGSVL
こちらも回転式LiDARに特化した設定ファイルになっています。 カスタムLiDARでは一様にならないことも多い各センサーの垂直方向の角度は細かく設定できるようになっているのが特徴で、 形状の表現力としてはCARLAよりも上になります。
Name = "Lidar32-NonUniform", LaserCount = 32, MinDistance = 0.5f, MaxDistance = 100.0f, RotationFrequency = 10, // 5 .. 20 MeasurementsPerRotation = 1500, // 900 .. 3600 FieldOfView = 41.33f, VerticalRayAngles = new List<float> { -25.0f, -1.0f, -1.667f, -15.639f, -11.31f, 0.0f, -0.667f, -8.843f, -7.254f, 0.333f, -0.333f, -6.148f, -5.333f, 1.333f, 0.667f, -4.0f, -4.667f, 1.667f, 1.0f, -3.667f, -3.333f, 3.333f, 2.333f, -2.667f, -3.0f, 7.0f, 4.667f, -2.333f, -2.0f, 15.0f, 10.333f, -1.333f }, CenterAngle = 10.0f,
参考:URL
AWSIM
UnitySensorsのCSVLiDARScanPatternに似てレーザー一本一本を設定することができます。 注目すべきはtimeOffsetでタイミングのズレを設定できるところです。 UnitySensorsも同じく任意形状のスキャンパターンを設定できますが、時刻の設定ができないためLivoxのようなレーザーが一本しかないLiDARしか表現できません。 一方で、AWSIMは複数本のレーザーを持つLiDARはもちろんの事、フラッシュ式のようなタイミングが特殊なLiDARに対する表現力を持っています。 また、この設定項目があるということは、スキャン中にセンサーが移動することによる点群の歪み*2もシミュレーションできるのかもしれません。
public static LaserArray VelodyneVLP16 => new LaserArray { centerOfMeasurementLinearOffsetMm = new Vector3(0.0f, 37.7f, 0.0f), focalDistanceMm = 0.0f, lasers = new[] { new Laser {verticalAngularOffsetDeg = +15.0f, verticalLinearOffsetMm = +11.2f, ringId = 0, timeOffset = 0.0f }, new Laser {verticalAngularOffsetDeg = -1.0f, verticalLinearOffsetMm = -0.7f, ringId = 8, timeOffset = 0.002304f }, new Laser {verticalAngularOffsetDeg = +13.0f, verticalLinearOffsetMm = +9.7f, ringId = 1, timeOffset = 0.004608f }, new Laser {verticalAngularOffsetDeg = -3.0f, verticalLinearOffsetMm = -2.2f, ringId = 9, timeOffset = 0.006912f }, new Laser {verticalAngularOffsetDeg = +11.0f, verticalLinearOffsetMm = +8.1f, ringId = 2, timeOffset = 0.009216f }, new Laser {verticalAngularOffsetDeg = -5.0f, verticalLinearOffsetMm = -3.7f, ringId = 10, timeOffset = 0.011520f }, new Laser {verticalAngularOffsetDeg = +9.0f, verticalLinearOffsetMm = +6.6f, ringId = 3, timeOffset = 0.013824f }, new Laser {verticalAngularOffsetDeg = -7.0f, verticalLinearOffsetMm = -5.1f, ringId = 11, timeOffset = 0.016128f }, new Laser {verticalAngularOffsetDeg = +7.0f, verticalLinearOffsetMm = +5.1f, ringId = 4, timeOffset = 0.018432f }, new Laser {verticalAngularOffsetDeg = -9.0f, verticalLinearOffsetMm = -6.6f, ringId = 12, timeOffset = 0.020736f }, new Laser {verticalAngularOffsetDeg = +5.0f, verticalLinearOffsetMm = +3.7f, ringId = 5, timeOffset = 0.023040f }, new Laser {verticalAngularOffsetDeg = -11.0f, verticalLinearOffsetMm = -8.1f, ringId = 13, timeOffset = 0.025344f }, new Laser {verticalAngularOffsetDeg = +3.0f, verticalLinearOffsetMm = +2.2f, ringId = 6, timeOffset = 0.027648f }, new Laser {verticalAngularOffsetDeg = -13.0f, verticalLinearOffsetMm = -9.7f, ringId = 14, timeOffset = 0.029952f }, new Laser {verticalAngularOffsetDeg = +1.0f, verticalLinearOffsetMm = +0.7f, ringId = 7, timeOffset = 0.032256f }, new Laser {verticalAngularOffsetDeg = -15.0f, verticalLinearOffsetMm = -11.2f, ringId = 15, timeOffset = 0.034560f }, } };
参考:URL
最後に
本当はもっと色々なことを書こうと思っていたのですが、想像以上に長くなりそうだったので別の記事に分けようと思います。 それではまた次の記事で。
ディープラーニングとやらの力をお借りして喋らせるやつの力をお借りして喋るROS2パッケージをババーっと作った
この記事はROS2アドベントカレンダー2022,12/14(つまり昨日)の記事です.
ROS2のカレンダー | Advent Calendar 2022 - Qiita
遅れてすみません.
はじめに
ロボコンに出ました.ロボットを喋らせました.
Unfortunately our robot could not restart for the last challenge of WRS FCSC Trial at #IROS22, because of a damaged power line. We are glad to have the opportunity to demonstrate our manipulation system at the exhibition.
— Cross Progress (@CrossProgress) 2022年10月26日
Many thanks for cheering our challenge! pic.twitter.com/VKpUuG2hCQ
これはこれでロボットらしくて良かったです.
でも大会終わって思ったんですよ,もうちょっと流暢に喋らせたいなって.
で,作りました.
ディープラーニングとやらの力をお借りして喋らせるやつの力をお借りしてしゃべるROS2パッケージを!
今回はこれを作った話について書こうと思います.
下調べ
まず,今どんな喋るROSパッケージがあるのか調べてみました.
ロボコンで使ったのはこれです.お世話になりました.
知り合いが作ってるパッケージも見つけました.
よく見たらこちらの方が少し世に出たのが早いんですね.
きっと作者の方は思ったのでしょう,「なければ作れば良いのでは」と
他にも色々見てみましたが,バックエンドがespeak系だったり最近のイケてそうな声が出せそうなROS(2)パッケージはありませんでした.
なければ作れば良いのでは
という訳で僕も作り始めました.
バックエンドはVOICEVOXを使うことにしました.
VOICEROIDやVOICEPEAKも見ていたんですが,せっかく作るからには色々な人に使ってもらえるようにしたかったので有料の壁はやっぱり高かったです.(ごめんなさい)
その点,VOICEVOXは無料しかも商用利用可でここまで高品質な話し声を出せるのは素直にすごいと思いました.(ちゃんとマネタイズできてるのか気になってくる社会人1年生であった)
探していると,なんとDockerコンテナも提供されていてなんとまぁ使いやすいことでしょう!
https://hub.docker.com/r/voicevox/voicevox_engine
共通化
早くパッケージを作りたい気持ちを抑えて,ふと思いました
GitHub - ActiveIntelligentSystemsLab/japanese_tts_ros: 日本語テキストを音声として出力するROS node
GitHub - hakuturu583/openjtalk_ros: ros bridge for openjtalk
はじめに出てきたこの2つのパッケージ,めちゃめちゃ似ているんですよね.
よく考えたらそれもそう,音声合成で喋らせるROSパッケージって
- 合成音声エンジンに音声合成をさせる
- 出てきた音声ファイルを再生する
をやっているだけなんですよね.
このまま,僕が上の2つのパッケージを参考にしてまた似たようなパッケージを作ってもいいかもしれません.
でも基本のところが同じなら1つのパッケージで色々な合成エンジンを切り替えられると楽しいんじゃないかと思ったわけです.
プラグイン化計画
さて,色々なエンジンを切り替えるとなると,まずは各エンジンに対して音声合成させる部分をプラグインに切り出す.
そして,共通処理を扱う母艦プログラムを作れば,あとは母艦プログラムに好きなプラグインを差し込めばいけそうな気がしてきました.
イメージはこんな感じ
という訳でできたのがこちら!
設計は甘いとは思いますが,なにせ基本の音声合成の手順が単純なのでこれでも色々な音声合成エンジンに対して簡単にプラグインを実装できるようになったのではないかと思います.
OpenJTalkプラグイン
母艦プログラムができてもプラグイン実装がないとこのプログラムは喋りません.
まずは試しにOpenJTalkのプラグインを作ってみました.
自分が作ったプログラムを通して聞く音声はなんだか少し温かみがある気がしました(寝ろ
VOICEVOXプラグイン
さて,待ちに待ったVOICEVOXプラグイン.
遠回りが過ぎましたが準備はバッチリであとはこれを実装するのみです!
VOICEVOXはどうやらDockerコンテナを立ち上げると,HTTPのAPIサーバーが立ち上がってそれを叩けば音声合成ができるようです.
今回はC++でプログラムを作るのでMicrosoftのC++ REST SDKというライブラリを使ってAPIを叩くことにしました.
このライブラリのクセがなかなか強くて途中ちょっと苦労もしましたが, 無事出来上がったのがこちらです!
おお,喋る!!
実装終わったのは昨日(12/14)の夜,それも仕事のミーティングが長引いて疲れ果てていましたが,流石にちょっと感動しました.
(その後,頭の死んでいた僕はTwitterのTLに流れて来るツイートを読ませてひとしきり遊びました.)
このリポジトリのREADMEだけはしっかりと書いたので是非みなさんも試してみてください!
あ,ROS2 Humbleでしか動作確認していないので気をつけてくださいね.
動かなかったりしたらIssue・プルリク待ってます.
最後に
ふとした思いつきをババーっとプログラム書いて,ババーっとこうして記事に書きましたがやっててとても楽しかったです.
こんな雑な記事を書くのもはじめてでしたが,こういうスピード感ある記事執筆もアドカレ感が出ていいなと思いました.
プログラムは色々雑ですが,それでも基礎部分は割といい感じに設計したつもりです. これからも雑な部分は少しづつ直していこうと思いますので,使ってみたり,別のプラグイン作ったよ〜って人は是非教えてほしいです.泣いて喜びます.
ROS2でヘッダファイルのインストール先が変わったらしい
※この記事はCalendar for ROS2 | Advent Calendar 2022 - Qiita,2日目の記事である
※である調で書いてしまったので文章が多少高圧的に感じられるかもしれないがご容赦願いたい
ROS2 Humbleを早々と試している人々の中には既に気付いている方もいらっしゃるかもしれない.
そう,ヘッダファイルのインストール先が変わっているのである!!
嘘だと思うなら下の画像を見て欲しい.
GalacticとHumbleでフォルダ構成が違うことが分かっていただけると思う.
Galacticではstd_msgs
フォルダの直下にmsg
フォルダがあるのだが,Humbleではさらにもう一つstd_msgs
フォルダを挟んでいる.
この記事では,この変更がどうして行われたかを解説していく.
読み進める人への注意 : この記事は要求される事前知識が多い割に読んで得られる知見は少ない.ROSの勉強にはなると思うが...
事前知識
記事を読み進める前に頭に入れておきたい事前知識たち. 単語を見て理解できるなら飛ばしてもらって構わない.
マージインストール
詳細
コマンド
colcon build --merge-install
起こること
パッケージのインストール先が変わる 例えば,ヘッダファイルのインストール先は以下のようになる
インストールの種類 | ヘッダファイルのインストール先 |
---|---|
通常 | colcon_ws/install/<package_name>/include |
マージインストール | colcon_ws/install/include/<package_name> |
得られる効果
全パッケージのlib
フォルダを環境変数に入れようとすると,通常インストールの場合では
各パッケージにそれぞれに対して colcon_ws/install/<package_name>/lib
を追加する必要がある.
しかし,マージインストールしているとcolcon_ws/install/lib
を追加するだけで事足りる.
因みに自分が確認した限りでは通常インストールで膨れ上がる環境変数は以下の通り
- AMENT_PREFIX_PATH
- CMAKE_PREFIX_PATH
- PYTHONPATH
- LD_LIBRARY_PATH
ワークスペースのオーバーレイ / アンダーレイ
詳細
Creating a workspace — ROS 2 Documentation: Galactic documentation
簡単に言うと,ROSのワークスペースが複数あって,両方で source path/to/setup.bash
をした時,先にsource
したワークスペースのことを「アンダーレイ」,後にsource
したワークスペースのことを「オーバーレイ」と呼ぶ.
aptでインストールしたROSパッケージのバージョンが気に入らない時,手元のワークスペースにソースコードをcloneしてビルドすると思いますが, このような状況ではこの仕様がうまく働く.
もし,オーバーレイのパッケージが優先されない場合,オーバーレイである手元のワークスペースにソースコードからビルドしたにもかかわらず, アンダーレイにあるaptでインストールしたバージョンの使用を強制されるかもしれない.
何が問題だったのか?
ヘッダファイルのインストール先が変わる原因となる現象は下のIssueで報告されている. github.com
一言で言うと,「特定の状況でをファイルの参照先がおかしくなる」 のである.
特定の状況とは以下のようなものだ
このような状況は特におかしなものではない.
特に,aptでインストールされる/opt/ros/humble
以下のワークスペースはマージインストールと同じ状態になっており,aptでインストールしたパッケージをオーバーレイにクローンする
そして,ros2
コマンドでアンダーレイ / オーバーレイ両方のワークスペースに存在するパッケージを呼び出しても,オーバーレイのパッケージが優先されることで解決されるはずである.
しかし,今回のIssueではマージインストールを併用した場合,オーバーレイが優先されなくなってしまうという報告がなされているのである.
詳しく
今回のバグを再現するために作られたリポジトリを簡素化して説明する
以下のような構成のワークスペースとパッケージを考える
それぞれのパッケージの情報として,パッケージの名前,パッケージのインクルードパス(パス),他のパッケージへの依存を書いている.
ここで,理想的な依存関係は当然こうなる
しかし,実際は以下のようになってしまうというのが今回の問題である.
では,どうしてそんなことが起こっているのか,更に細かく見ていく.
Dパッケージを中心に書くとこうなる
では,次にそれぞれがヘッダファイルを持っていると考えてコンパイラの気持ちになってみる.
d.hppは以下の手順でプリプロセスでインクルードが展開されていく
ここで,③のA/a.hpp
の展開を更に詳しく見てみる
まず,A/a.hpp
を展開するにはファイルがどこにあるか探すわけだが,コンパイラは依存パスを順番に精査していく.
本来なら,オーバーレイのAパッケージがある~/ros2_ws/install/A/include
でA/a.hpp
が見つかって欲しい.
しかし,依存パスの順番的に,はじめにアンダーレイの /opt/ros/humble/include
を探索するのだが,
この配下にはA/a.hpp
が存在するため,間違ったファイルがヒットして展開なされてしまうというわけだ.
もちろん,ここでアンダーレイでマージインストールなされていなければ,Bのパスを通じて間違ったAのパスにつながることもないので問題は発生しない.
どう対策したのか?
対策の検討
問題に対して,OpenRoboticsのShaneLoretzs氏によって4つの対策案が挙げられています.
それぞれ簡単に紹介すると
- ①CMake でインクルード ディレクトリを並べ替える
- ②ヘッダファイルを1階層深い場所にインストールする
- ③colconでパッケージの重複を検知してどうにかする
- ④colconでパッケージの重複を検知して知らせる(そして解決はユーザーに任せる)
といった感じになる. 詳しくは原文を参照して欲しいが, ①③はかなり無理がある解決策で④は解決そのものを諦めている.
という事で,選ばれた②について説明していく. ちなみに,④も②の予防策として採用されることになっている.
選ばれた解決策
「ヘッダファイルを1階層深い場所にインストールする」とはどういうことかと言うと,
CMakeLists.txt
で
install(DIRECTORY include/ DESTINATION include)
と書いてヘッダファイルをインストールしていたところを,
install(DIRECTORY include/ DESTINATION include/${PROJECT_NAME})
と書いて更に1階層深い場所にインストールする,ということである.
そう,これこそがタイトルにもある「ROS2でヘッダファイルのインストール先が変わったらしい」と言うことである!!!!
では気になるのは,なぜこれが問題の解決策になるのか?ということであろう.
インストール先が変えることによる効果
まず,対策前後のアンダーレイにおけるマージインストールの結果を見ていこう
対策の前後がそれぞれ記事の冒頭に示した比較画像のgalactic/humbleのようになっていることがわかるだろう.
また,install
文が変わったことによって,インストール先だけではなく,依存パスも変化する.
Dパッケージの場合は次のように変化する.
赤太字で示した場所が変化点である.
この変更によって,問題の原因であった「Bのパスを通じて間違ったAのパスにつながる」ことがなくなったことにお気づきだろうか?
インストールする階層を1つ深くするだけでマージインストール時にもユニークなパスになるようにできるとはよく考えたものである.
解決策の実装
さて,この解決策というのは,アンダーレイのワークスペースに格納される可能性のあるパッケージに実装されなければならない.
とりわけ,aptでインストールされて/opt/ros/humble
以下にマージインストールされるros/rosdistro
に掲載されたリポジトリ群は絶対にアンダーレイになってしまうわけで早急な実装が求められる.
かくして,ROSコミュニティの面々はひたすら解決策の実装に明け暮れるのであった...
ちょうど一年前の話である.
当時rollingだったそれらの解決策がマージされたパッケージたちは,humbleのパッケージとして世に放たれた.
マージから1年後,humbleでヘッダファイルのインストール先が変化したことに気付いた筆者はこうしてこの記事を書くことになったわけである.
ROS2パッケージをリリースしよう!準備編
ROSのbloomを使ったパッケージリリースについてはネットに素晴らしい有用な記事があるのですが, GitHubの仕様変更やROS2の公式リリースリポジトリ置き場など, 新しい部分については日本語情報が少ないので情報を残しておきます.
準備するもの
パッケージをリリースするには以下のものが必要です.
必要なもの | 備考 |
---|---|
GitHubアカウント | 当然必要 |
GitHubアクセストークン | リリース用ツールに権限を与えるのに使います |
リリースしたいROS2リポジトリ | これがないと始まらない |
リリース用リポジトリ | 作り方は2通り |
GitHubアカウント,リリースしたいROS2リポジトリは当然あるものとして,残りの2つについて解説します.
GitHubアクセストークン
本来なら,パッケージのリリースではたくさんのGitHub上での操作を人間が手動で行う必要があります.
bloomはそんな大変な作業を人間に変わって自動でやってくれるツールです.
しかし,GitHub上での操作には認証が求められるため,ツールにアクセス権限を付与する必要があります.
また,近年GitHubではパスワードによる認証が禁止されたため,パスワードを求められた際にはアクセストークンを入力する必要があります.
詳しい作成方法はこちらです.
アクセストークン作成ページ : https://github.com/settings/tokens
アクセストークンには「repo」と「workflow」の権限を設定してください.
リリース用リポジトリ
パッケージをリリースするためにはソースコードが入ったリポジトリとは別に,<パッケージの名前>-release
という名前のリリース用のリポジトリが必要です.
リリース用リポジトリの中身はパッケージの内容を基にbloomが勝手に管理するので開発者はリポジトリを作るだけでOKです.
リポジトリの作成場所ですが,自分の場所に作る方法・公式の場所に作る方法の2通りあるのでそれぞれについて説明します.
公式の場所に作る方法
公式のリリースリポジトリの置き場所がこちらです.
ここにリリースリポジトリを作る手順は以下のとおりです.
手順自体は簡単ですが,メンテナの方の対応を待たなければいけませんので,時間がかかることは理解しておいてください.
急ぎの場合は「自分の場所に作る方法」を検討するのも手です.
issueを立ててリポジトリの追加をお願いする
こちらのリポジトリにIssueを立てて,リポジトリ追加のお願いをしていきます.
Issueを追加しようとすると,3つのIssueテンプレートが現れるので,「New release team」を選択して次に進みます.
- チーム名(英小文字とアンダーバーのみ)
- リリースしたいリポジトリ
- メンテナの情報
の3つの情報を埋めてIssueを立てられたらメンテナの人がリポジトリを作ってくれるのを待ちます.
Issueをどう書けばいいかわからない場合は過去のIssueを参考にしてみましょう.
例えば,自分が立てたIssueがこれです↓
大抵,1週間以内にメンテナ欄に追加したユーザーはOrganizationに追加され,チームの追加,空のリリースリポジトリの作成までをros2-gbpのメンテナの方がやってくださいます.
ここまで来たらようやく,リリースリポジトリの準備が終わりです.
最後に作業をやって頂いたメンテナの方への感謝を忘れずに!
自分の場所に作る方法
これはROS1のリリース用リポジトリと同じです.
自分で好きなOrganizationなり自分のユーザーディレクトリなりに<パッケージの名前>-release
という名前の空リポジトリを作るだけです.
気軽にリリースしたい場合や,急ぎのリリースの場合はこちらの方が良いかもしれません.
作成したリリースリポジトリにmaster
ブランチを作る
最近,GitHubではリポジトリを新規作成した時のデフォルトブランチは master
からmain
に変わりました.
しかし,bloomは古いツールなので,master
をデフォルトブランチとして扱うため,master
ブランチの作成が必須です.
準備完了
これでリリースに必要なものは揃いました!
ということで,準備編はここまでです.
あとのリリースの手順は,GitHubのパスワードを求められた時にアクセストークンを入力するところ以外はネットにある日本語情報を参考にすると良いでしょう.
この記事は特に分かりやすくて良いですね!
気が向けば,リリース編も書こうと思いますが,期待しないでください.
参考
アクセストークン周りに関して
公式の場所へのリリースリポジトリ作成に関して
ROS2のCMakeを簡単に!~ament_cmake_auto~
この記事はROS/ROS2アドベントカレンダー2020の18日目の記事です
こんな経験はありませんか?
ROS2のCMakeLists.txtを書いていてこんな経験はありませんか?
- package.xmlで依存関係を変えたらCMakeも書き換えないといけない...
- ROS2のコンポーネント指向,便利だけどCMake書くのが面倒...
- 毎回同じような内容を書く割には抜け漏れが起こりやすい...
その悩み,”ament_cmake_auto”が解決します!
ament_cmake_autoを使うとROS2のCMakeを簡潔に書くことが出来るようになります*1.
では,実際にどれくらい簡潔に書けるのかを見ていきます.
ament_cmake_autoを使ったCMakeLists.txt
最小限のサンプルがこちらになります.
cmake_minimum_required(VERSION 3.5) project(example) find_package(ament_cmake_auto REQUIRED) ament_auto_find_build_dependencies() ament_auto_add_library(${PROJECT_NAME} SHARED src/example.cpp include/example.hpp) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) ament_lint_auto_find_test_dependencies() endif() ament_auto_package()
あれ?依存関係は??
exportしなくていいの???
installは????
まともにROS2のCMakeを書いたことがある人なら頭の中がはてなマークでいっぱいになると思います.
でも大丈夫,"ament_cmake_auto"がぜ〜んぶやってくれます.
関数群
具体的にどのようなことをやってくれているのかを関数ごとに見ていきます.
詳しくは実装*2をご覧ください.
ament_auto_add_executable
実行ファイル生成に関して
- add_executable
- target_include_directories
- target_link_libraries
- ament_target_dependencies
をまとめてやってくれます
ament_auto_add_library
ライブラリ生成に関して
- add_library
- target_include_directories
- target_link_libraries
- ament_target_dependencies
をまとめてやってくれます
ament_auto_find_build_dependencies
package.xmlから依存を読み取ってfind_packageしてくれます.
ament_auto_generate_code
メッセージのファイルを探してヘッダーなどを自動生成してくれるようですが,未実装のようです.
今後に期待
ament_auto_package
- ament_export_include_directories
- ament_export_libraries
- install
export,install関係を全部やってくれます
最後に
ros2に標準でついてくるament_cmake_autoですが, 非常に便利なのに使っている人も文献も少ないように思えた*3ので今回記事にしてみました.
*1:ROS1でもcatkin_simpleというCMakeを簡単に書くためのパッケージがあります
*2:https://github.com/ament/ament_cmake/tree/master/ament_cmake_auto/cmake
*3:使われているのをAutowareのROS2バージョンであるAutoware.Auto以外に見たことがない...
colconで補完を出す
colcon build
するときとかにcolcon
と打ってからTABキーで補完をだそうとしてうまくいかない経験はありませんか?
colconで補完が出ない!
colcon
と打ってからTABキーを押すと以下のようにディレクトリが表示されます.
今欲しい補完はそれじゃない...
$ colcon <TAB> build/ install/ log/ src/
colcon b
くらいまで打って補完を出すとcolcon build/
になってしまい,エラーを吐かれます.
colcon build/ usage: colcon [-h] [--log-base LOG_BASE] [--log-level LOG_LEVEL] {build,extension-points,extensions,graph,info,list,metadata,test,test-result,version-check} ... colcon: error: argument verb_name: invalid choice: 'build/' (choose from 'build', 'extension-points', 'extensions', 'graph', 'info', 'list', 'metadata', 'test', 'test-result', 'version-check')
catkin
ならちゃんと補完出てたのに!!
補完を出す
colconの補完はpython3-colcon-argcomplete
というパッケージで提供されています.
ROS2のインストール時に一緒に入ってくるはずなので追加でインストールする必要はありません.
ただ,補完を有効にするためにスクリプトを読み込む必要があります.
スクリプトは/usr/share/colcon_argcomplete/hook/
というディレクトリにあり,colcon-argcomplete.bash
を読み込めばOKです.*1
$ colcon <TAB> build extension-points extensions graph info list --log-base --log-level metadata test test-result version-check
しっかり出ましたね.
よく使う人は.bashrc
に
source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash
と書いておくと良いでしょう
参考
ROS2でコードチェック!
TL;DR
## コードチェック! colcon test ## エラー内容を確認! colcon test-result --verbose
コーディング規約
ROS2にはコーディング規約*1があります.*2 ROS2のプログラムを書いている読者の皆さんなら当然規約に則っているとは思いますが,細かいところまできっちり守るのは中々難しいものです.
というわけでROS2のコードチェックを自動化する方法を紹介したいと思います.
確認
ここで述べるものがなければコードチェックがうまく動きませんので動かない場合は確認してみてください.
CMakeLists.txt
よほど変な方法でパッケージを作っていない限り,CMakeLists.txt
の最後の方に以下の記述があると思います.
if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) # the following line skips the linter which checks for copyrights # uncomment the line when a copyright and license is not present in all source files #set(ament_cmake_copyright_FOUND TRUE) # the following line skips cpplint (only works in a git repo) # uncomment the line when this package is not in a git repo #set(ament_cmake_cpplint_FOUND TRUE) ament_lint_auto_find_test_dependencies() endif()
もしない場合はCMakeLists.txt
の最後にあるament_package()
の記述の直前に追加しておきましょう.
package.xml
こちらも通常,はじめから追加されているはずですが念の為.
<test_depend>ament_lint_auto</test_depend> <test_depend>ament_lint_common</test_depend>
記述が無ければ追加しておきましょう.
チェックの実行
colcon build
した後に以下を実行しましょう.
colcon test
コードチェックはたったこれだけで実行できます. 簡単ですね.
エラーの確認
チェックを実行したら何かしらエラーが出ます.
Starting >>> crane_bt_executor --- stderr: crane_bt_executor Errors while running CTest --- Finished <<< crane_bt_executor [4.00s] [ with test failures ]
しかし,colcon test
だけではこのようにエラーの有無しか分かりません.
エラーを修正するためには「どこで」「どのような」エラーが出ているかという情報が必要です.
そこで次のコマンドを実行します.
colcon test-result --verbose
以下のような文字列が大量*3に吐き出されて面食らうかも知れませんが何ということはありません.
- crane_bt_executor.cpplint build/include_what_you_use [4] (/root/ros2_ws/src/crane/crane_bt_executor/include/crane_bt_executor/behavior_tree/multi_robot_sequence.hpp:54) <<< failure message Add #include <memory> for shared_ptr<> >>>
しっかり読めば解決策も書いてありますので一つ一つ丁寧に直していきましょう.
ament_lint_autoの気持ちになるですよー
正直,このコードチェックはかなり厳しいです.
はじめのうちは大量のエラーを出して修正に時間がかかりますが慣れると素早くできるようになります.
また,そもそもの話としてエラーが少ないプログラムを書けるようになるので心配する必要はありません.
特にチェックが1発で通った*4ときは中々の快感です.
CI
どうせならチェックの実行自体も自動化してしまいましょう.
Gitlab CI/CDやGithub Actionsを使えば簡単にできます.
https://github.com/SSL-Roots/consai2r2/actions/runs/8872558/workflow
CIの設定など細かいことは省きますが結局の所,colcon test
を実行しておけばOKです.
次回予告
今回はコードチェックの仕方やエラーの確認方法について書きました.
次回以降は具体的なエラーの内容や運用する上でのtipsなど書いていこうと思います.