# Artefactsを使用した回帰テストの自動化とパラメータ調整

Site [llms.txt](/ja/llms.txt)

---

> [!WARNING] Deprecated
> ROS1のサポートは現在非推奨ですが、ワークフローの参考として引き続き使用できます

ロボットシステムの開発中、開発者は新機能の開発やコンポーネントの統合のために多数のテストを実行します。このチュートリアルでは、**Artefacts**プラットフォームが具体的な例を用いて、以下の3つの一般的なユースケースによりロボット開発をより効率的にする方法を紹介します：

1. 回帰テスト：自動的に実行され、合格/不合格の基準を判定するテスト。これらのテストは新機能が既存の機能を壊さないことを保証します。
2. 再現性テスト：同じパラメータセットで多数のテストを実行し、非決定的な挙動を定量化します。
3. アルゴリズムパラメータの調整：異なるパラメータで多数のテストを実行し、指標を最適化するための最適なセットを見つけます。


ロボティクスのユースケースに関連しながらも、最小限のコードで設定不要なチュートリアルを提供するため、ROS1とそのシンプルな**turtlesim**シミュレータを用いた参照実装を構築しました。

ここで紹介するArtefactsの概念はすべて、ROS1やturtlesimの例を超えて一般的に適用できます。これらはあなた自身のユースケースの参考やレシピとして機能することを意図しています。

以下の各例には、テストの根拠 + テスト説明 + テスト結果が含まれており、Artefactsを活用する方法について明確なガイダンスを提供しています。このチュートリアルでは実装の詳細を最小限に抑えていますが、すべてのユースケースをサポートするデモコードは[demo-ros1-turtlesim]で確認できます。

チュートリアルの例は概念の複雑さに応じて段階的に進むよう選ばれているため、順番に従うことをお勧めします。ROS1と[turtlesim](http://wiki.ros.org/turtlesim)の事前知識があることを前提としています。

## 1. 回帰テスト

**根拠：** 複雑なシステムにおけるベストプラクティス：既に実装された機能が後続の実装によって劣化しないことを保証するテストを定義すること：回帰テスト。

**テスト説明:** 主な特徴は、テストが自動的に最初から最後まで実行され、合格/不合格をArtefactsダッシュボードに報告できることです。

この例では、以下のように回帰テストを定義します：

- 亀は正方形の軌跡（4つの等長直線移動と3回のその場回転）を実行するよう指示されます
- 成功基準：亀の最終位置が開始位置の近くにあること（ループ軌道が完了している）
![Turtle Trajectory](/images/user-guide/tutorial_ros1_turtlesim/turtleTrajectory.png)

**テストのセットアップ:**

rostestとArtefactsのセットアップは簡単です:

1. 以下の要件を満たす `rostest` テストクラスを作成する。
    1. `unittest.TestCase` を継承する。
    2. テストの「準備」機能を実行する `setUp()` メソッドを提供する。例えば、ロボットを開始位置に配置し、テストに必要なリソースを準備する。
    3. テストの「実行」（亀に正方形のループ軌道を実行するためのコマンドを送信するなど）とテストの「検証」機能（成功基準の確認：ループ軌道が完了しているか）を実行する `test_mytest()` メソッドを提供する。
    4. テスト終了時に必要なクリーンアップを実行する `tearDown()` メソッドを提供する。
    5. 詳細については [test node source](https://github.com/art-e-fact/demo-ros1-turtlesim/blob/main/ros_workspace/src/turtle_simple/src/TestTurtleSimple.py) の例を参照してください。
2. このテストノードを `.launch` ファイルの<test>ノードでラップする。必要に応じて他のノードを追加する。 [launch file](https://github.com/art-e-fact/demo-ros1-turtlesim/blob/main/ros_workspace/src/turtle_simple/launch/turtle_simple.launch)の例を参照。
3. これらのファイルがROSパッケージの一部であり、ROSワークスペースがビルドされてソースされていることを確認する。
4.  [設定ファイル構文ドキュメント](/configuration/artefacts-yaml)に従って、 `artefacts.yaml` ファイルを作成する。 [参照例](https://github.com/art-e-fact/demo-ros1-turtlesim/blob/main/artefacts.yaml)を参照。以下のようにシンプルにできます：

```yaml
project: demo-ros1-turtlesim
jobs:
  turtle_regression:
    type: test
    runtime:
      simulator: turtlesim
      framework: ros1:noetic
    scenarios:
      settings:
        - name: simple_regression_test
	        ros_testpackage: turtle_simple
	        ros_testfile: turtle_simple.launch
```

このテストの実行は、以下の3つの方法のいずれかで行えます：

  - 開発/テスト用にローカルで： `artefacts run rover_trajectory`
  - Artefactsインフラでリモートに： `artefacts run-remote rover_trajectory`
  - **CIユースケースに最適：** インフラで自動的に、リポジトリへの今後のプッシュごとにテストが実行されます： ([リポジトリをArtefactsダッシュボードにリンクする](https://app.artefacts.com/home)).


**まとめ：**

回帰テストについては：これらのテストを継続的インテグレーションパイプラインに含めることで、新しい開発が以前に機能していた機能を壊した場合にアラートが発生することを保証できます。

より一般的には、このシンプルなセットアップは実際に、Artefactsの使用と任意の種類のテストの作成に関する基本的な内容をすべてカバーしています：

- すべてのテストは同じArrange/Act/Assert（準備/実行/検証）方法論に従います。ここでROS1では `rostest` と `unittest`を使用しました。 ArtefactsはROS2と `launch_test` （およびその他のフレームワーク）もサポートしています。
- シンプルなYAML設定ファイルを作成することで、Artefactsは私たちのテストを取得し、テストの起動、ログ記録、テスト結果の解析を自動的に調整します。
- テスト結果は自動的にArtefactsダッシュボードにアップロードされ、そこで閲覧、比較、共有することができます。
- シンプルなコマンドにより、開発者はテストをローカルで実行するか、クラウド上のArtefactsインフラで実行するかを選択できます。

## 2. 再現性テスト

Artefactsの重要な機能は、多数（本当に多数！）のテストを簡単に調整できることです：この例では、YAML設定ファイルに1つの追加概念（パラメータのリスト）を加えるだけで、50のテストを自動的に実行します。
また、 `rosbag_postprocess` スクリプトを使用して各テストの終了時にテスト指標を自動的に計算する方法も紹介します。

**根拠：** 50のテストを実行することで、シミュレーションやテスト設定の非決定的な側面を特定し定量化することができます。これは再現性テストと呼ばれます。同一のパラメータでテストを実行した際の指標のばらつきを定量化することで、将来の実装が実際に計算された指標の改善/劣化につながるのか（あるいは単に統計的なばらつきの影響なのか）を適切な確信度で結論付けることができます。

**テスト説明：**

この例は前述のturtlesimの正方形軌道の上に構築しています。

この再現性テストをより現実的にするため、シミュレートされたホイールオドメトリセンサーを作成し、そこから亀の位置を計算するノードを追加します (see [turtle_odom.py](https://github.com/art-e-fact/demo-ros1-turtlesim/blob/main/ros_workspace/src/turtle_odometry/src/turtle_odom.py)参照)。これは、IMUとモーターエンコーダデータをカルマンフィルターに融合したり、SLAMを実装したり、その他の位置推定フレームワークを使用したりする可能性のあるロボティクスアプリケーションに関連するスタンドインです。

各テスト実行について、以下のようなさまざまな指標を計算し、実行ごとにどのように変化するかを確認します：
  - `cumulative distance_final`: テスト中に亀が移動した総距離（グラウンドトゥルース）
  - `error horizontal final`: 軌道の終了時における、推定された亀のx位置とy位置とグラウンドトゥルースとの間の誤差（ユークリッド距離、メートル単位）
  - `error orientation final`: 軌道の終了時における、推定された亀のヨー（向き）方向とグラウンドトゥルースとの間の誤差（絶対値、度単位）
  - `time delta max`: 各推定メッセージとグラウンドトゥルースメッセージ間の最大タイムスタンプ不一致。低い値は誤差指標が一貫して計算されることを保証します。

**テストのセットアップ：**

Artefactsを使用すると、わずかな追加手順だけで済みます：

1. 指標を計算するためのポスト処理スクリプトを作成します。このスクリプトはrosbagを入力として受け取り、metrics.jsonファイルを出力します。例： [turtle_post_process.py](https://github.com/art-e-fact/demo-ros1-turtlesim/blob/main/ros_workspace/src/turtle_odometry/src/turtle_post_process.py)
2. `artefacts.yaml`を以下のように設定します：
    - 必要なROSトピックをrosbagに記録する： `rosbag_record` キーを追加
    - 各テストの終了時にポスト処理スクリプトを実行する： `rosbag_postprocess`キーを追加
    - X回のテストの実行とデータのログ記録を自動的に調整する： `params` キーの下に、X個のダミー値のリストを持つダミーパラメータを追加

`artefacts.yaml` ファイルの[参照例](https://github.com/art-e-fact/demo-ros1-turtlesim/blob/main/artefacts.yaml) を参照してください。以下のようにシンプルにできます：
```yaml
project: demo-ros1-turtlesim
jobs:
  turtle_repeat:
    type: test
    runtime:
      simulator: turtlesim
      framework: ros1:noetic
    scenarios:
      settings:
        - name: turtle_repeatability
          ros_testpackage: turtle_odometry
          ros_testfile: test_odometry.launch
          rosbag_record: all
          rosbag_postprocess: turtle_post_process.py
          params:
            dummy: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]  # Artefacts will run 10 scenarios, each with the value from this parameter list
```

このテストはローカル (`artefacts run turtle_repeatability`) またはArtefactsインフラで実行できます。どちらの場合も、Artefactsは10のテストを順番に自動的に実行します。その後、各テストの結果はArtefactsダッシュボードのクラウドにログ記録されます。

Artefactダッシュボードはテスト中に作成されたすべてのファイルを、豊富な視覚化をサポートして表示します。特に、HTML形式のグラフ  (例 [plotly製](https://plotly.com/python/))が表示されます。
![Artefacts Dashboard With Rich Visualizations](/images/user-guide/tutorial_ros1_turtlesim/dashboard.png)
Artefactsダッシュボードから、灰色の矢印ボタンをクリックすると、すべてのシナリオの結果をCSVでエクスポートしてさらに分析することができます。

**テスト結果：**

シンプルな分析 ( [jupyter notebook](https://github.com/art-e-fact/demo-ros1-turtlesim/blob/main/ros_workspace/src/turtle_odometry/src/post_processing_analysis.ipynb)の例を参照)では、各指標の統計を計算しグラフを作成します：

![Metric Statistics](/images/user-guide/tutorial_ros1_turtlesim/metric_statistics.png)

シミュレーションの非決定的な性質により、まったく同じ条件で実行されたテストの指標でも変動が生じます。

これらの変動は、後続のテストで誤った結論に達しないように定量化することが重要です：

- 指標の変化が1標準偏差内にあるパラメータ調整やアルゴリズム変更は、おそらく改善でも劣化でもなく、単に再現性の問題によるものです。
- CIパイプラインの一部として、回帰をフラグする基準は厳密な閾値ではなく区間であるべきです。区間設定の例：中央値 ± 3シグマ（次の点も参照：CIでは、複数のテストを実行し中央値の結果を閾値と比較することで、偽陽性と偽陰性に対してより堅牢になります）
- 外れ値は発生する可能性があります：結論を確認するためにテストを数回実行してください。

**まとめ**

YAML設定ファイルにXパラメータをリストとして指定するだけで、Artefactsは自動的にXテストを実行し、すべての結果をArtefactsダッシュボードに保存します。

後処理スクリプトを指定するだけで、Artefactsは各テストの終了時にそれを実行し、結果の指標を各テストのArtefactダッシュボードにアップロードできます。

テスト中に作成されたすべてのファイルは、豊富な視覚化サポートとともにアップロードされます。これにより、より深い洞察を得るためのテスト結果のインタラクティブな探索が可能になります。


## 3. アルゴリズムパラメータの調整

**根拠：**

従来、ロボティクスにおけるパラメータ調整は時間がかかり、エラーが発生しやすい理由は以下の通りです：

- パラメータ探索空間が大きく、多くのテストを繰り返し実行する必要があります。各テストを手動でセットアップし、監視し、結果を確認することは退屈で時間がかかります。
- テスト結果を追跡し、再現可能なテスト条件を手動で確保することは退屈でエラーが発生しやすいです。

Artefactsは、テストの各側面を指定し、パラメータ化し、パラメータセット間で自動的にグリッド検索を実行しながら、すべての結果をログに記録し、中央ダッシュボードに表示するフレームワークを提供します。

**テスト説明：**
この例は前述のturtlesimの再現性テストの上に構築しています。

今回の目標は、実際に亀の位置推定精度を向上させることです。具体的には、 `horizontal error final` と `orientation error final` の2つの指標を最小化することです。
この例では、調整可能なパラメータは `odom_tuning_theta` と `odom_tuning_forward`の2つだけで、これらは亀のモックセンサーを使用したオドメトリ計算に影響します

これら2つのパラメータそれぞれに10個の値をテストすると、すでに100の組み合わせになります。これは従来の/手動テスト設定では扱いにくいでしょう！しかし、Artefactsを使えば簡単に設定でき、昼食時にテストを実行させ、その後Artefactsダッシュボードで結果を確認できます。

**テストのセットアップ：**

上記の2つのテスト設定を基に、さらに2つの要素を実装するだけです：

- コードベースとArtefacts間のパラメータインターフェースを追加します。各テストの開始時に、 `artefacts.yaml` に渡された各パラメータはArtefactsによってROS `rosparam` サーバーで利用可能になります。そのため、起動時に `rosparam` サーバーをチェックするための数行をオドメトリノードに追加するだけです([`rospy.get_param('test/odom_tuning_theta')`](https://github.com/art-e-fact/demo-ros1-turtlesim/blob/2d6770c405c00e6cbd5e6a824398a476a62e69a3/ros_workspace/src/turtle_odometry/src/turtle_odom.py#L46)).
- パラメータ自体をリストとして `artefacts.yaml` に追加します。これらはArtefactsによって実装された自動グリッドカバレッジの基礎として機能します：パラメータの組み合わせごとにテストシナリオがトリガーされます ([完全な例](https://github.com/art-e-fact/demo-ros1-turtlesim/blob/main/artefacts.yaml))。 例えば、以下の.yamlでは102=10010^2 = 100
102=100のテストシナリオが作成されます！

```yaml
project: demo-ros1-turtlesim
jobs:
  turtle_grid:
    type: test
    runtime:
      simulator: turtlesim
      framework: ros1:noetic
    scenarios:
      settings:
        - name: turtle_gridsearch
          ros_testpackage: turtle_odometry
          ros_testfile: turtle_odometry.launch
          rosbag_record: all
          rosbag_postprocess: turtle_post_process.py --skip_figures
          params:
            test/odom_tuning_theta: [0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5]
            test/odom_tuning_forward: [0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5]
```

**テスト結果**:

Artefactsダッシュボードからジョブ結果をCSVとしてダウンロードした後、各シナリオの関心のある2つの指標をプロットできます ([jupyterノートブック](https://github.com/art-e-fact/demo-ros1-turtlesim/blob/main/ros_workspace/src/turtle_odometry/src/post_processing_analysis.ipynb)参照)：

![Results Metrics](/images/user-guide/tutorial_ros1_turtlesim/results_metrics.png)

ここでは値が低いほど良く、目標は両方の指標を共同で最小化することです。
両方の指標にわたって結果を比較することをより実用的にするために、性能指標（figure of merit）を定義するのが一般的です：

$FoM = \displaystyle\sum_i w_i * m_i$   ここで各 $w_i$ は各指標 $m_i$ に割り当てられた重みです

これらはプロジェクトの目標に従って選択すべきです（例えば、方向誤差を最小化することと水平誤差を最小化することのどちらが重要か？）。ここでは、方向誤差1度が水平誤差10cmに相当すると選択します。
次に、100のシナリオそれぞれの性能指標をプロットします：

![Results fom](/images/user-guide/tutorial_ros1_turtlesim/results_fom.png)

パラメータの関数として性能指標をプロットすることで、検索内でのトレンドを見つけることができます。ここでは、両方のパラメータの値が低いほど性能指標が低くなり、以下の図に示されています：

![Results Surface](/images/user-guide/tutorial_ros1_turtlesim/results_surface.png)

最高の位置推定精度につながるパラメータは次のとおりです：

- odom_tuning_theta = 0.001
- odom_tuning_forward = 0.001


**まとめ**

この例では、一度だけの設定後、Artefactsに単一のコマンドで100のテストを実行するよう指示しました。その後、計算されたすべての指標をCSVとしてエクスポートし、これを使用して亀の位置推定アルゴリズムを調整するための最適なパラメータセットを特定しました。この方法論は、多くの異なるパラメータ値を試す必要のあるあらゆる種類のアルゴリズムの調整に適用できます。

## 結論

このチュートリアルでは、一般的なロボティクス開発のユースケースでArtefactsを使用する方法を説明しました：

1. Artefacts と `rostest` でテストを記述し、ローカルとArtefactsインフラのクラウドの両方で自動的に実行する方法。
2. Artefactsに一連のテストを自動的に実行するよう指示する方法と、各テストの終了時に任意の後処理を実行する方法。
3. Artefactsに自動的にパラメータ範囲でテストを実行するよう指示し、Artefactsダッシュボードからすべての結果をダウンロードしてアルゴリズムを調整する方法。
