Field-Robotics-Japan / UnitySensors

ROS/ROS2 enabled Sensor models (Assets) on Unity
Apache License 2.0
191 stars 28 forks source link

[IMU]Frequencyを上げると値が不安定になる #156

Open o-tatchan opened 2 months ago

o-tatchan commented 2 months ago

連投失礼します。 岡本と申します。

IMUの不具合報告になります。

IMUのFrequencyパラメーターを100以上に設定すると、速度・角速度の値が実際の値よりも大きく、また不安定になりました。

ご確認お願いいたします。

(以下に、速度・角速度それぞれの再現方法と動画を追記します)

o-tatchan commented 2 months ago

速度の具体的な再現方法と動画を追記します。

再現方法: ①Unity 標準のCubeオブジェクトを準備し、その中心部にIMU prefabを組み込む。 ②IMUのFrequencyパラメーターの値を100Hz以上に設定する。 ③Cubeに、一定速度で移動するようなスクリプトをアタッチする。

https://github.com/Field-Robotics-Japan/UnitySensors/assets/140692141/7c2845d6-284f-456b-90cd-0e44f7aa3933

https://github.com/Field-Robotics-Japan/UnitySensors/assets/140692141/779ba55f-8070-4dd4-9dac-396ed0136cf6

https://github.com/Field-Robotics-Japan/UnitySensors/assets/140692141/98f23975-4e39-47a6-9650-407abb978098

上の動画は、Cubeの速度をX軸正の向きに1[m/s]と設定したもので、IMUのFrequencyを上から順に20,100,1000と変化させたものです。

20Hzでは、IMUの速度のx成分はほぼ1[m/s]であり、期待通りの値といえます。 100Hzでは、IMUの速度のx成分はおよそ1[m/s]ですが、0.4[m/s]や3[m/s]のときもあり、値が安定しません。 1000Hzでは、6~10[m/s]と明らかに間違った値になります。

o-tatchan commented 2 months ago

角速度の具体的な再現方法と動画を追記します。

再現方法: ①Unity 標準のCubeオブジェクトを準備し、その中心部にIMU prefabを組み込む。 ②IMUのFrequencyパラメーターの値を100Hz以上に設定する。 ③Cubeに、Y軸回り一定角速度で回転するようなスクリプトをアタッチする。

https://github.com/Field-Robotics-Japan/UnitySensors/assets/140692141/b1e746d4-2873-4238-884e-efd008a900ed

https://github.com/Field-Robotics-Japan/UnitySensors/assets/140692141/02fe8504-6962-48ef-a31e-b8822b452ddc

https://github.com/Field-Robotics-Japan/UnitySensors/assets/140692141/025cdd92-67ed-4be2-aba6-76ef60a1e504

上の動画は、Cubeの角速度をY軸回りに3.14[rad/s]と設定したもので、IMUのFrequencyを上から順に20,100,1000と変化させたものです。

20Hzでは、Y軸回りの角速度はおよそ3.1[rad/s]で、本来の値に近くなっています。 100Hzでは、角速度は同じく3[rad/s]あたりですが、値がかなり不安定です。 1000Hzでは、角速度15[rad/s]あたりと、明らかに大きな値になっています。

Autumn60 commented 2 months ago

@o-tatchan

Issue報告ありがとうございます。 現在UnitySensorsを実行できる状況にないため確認は出来ませんが、現行(master, develop)のスクリプトにいくつかの問題点を見つけたため、ここに修正を記しておきます。

  1. https://github.com/Field-Robotics-Japan/UnitySensors/blob/develop/Assets/UnitySensors/Runtime/Scripts/Sensors/IMU/IMUSensor.cs#L61 _rotation_tmpを使うべき計算が_rotationを用いている。

  2. https://github.com/Field-Robotics-Japan/UnitySensors/blob/develop/Assets/UnitySensors/Runtime/Scripts/Sensors/IMU/IMUSensor.cs#L51 FixedUpdate()ではなくUpdate()に変更するべき。 private void FixedUpdate()をprotected override void Update()に置き換え、関数内の最終行にbase.Update();を追記。

o-tatchan commented 1 month ago

岡本です。

私の使用していたUnitySensorsは現行版ではないようでした。 (使用version: 2.0.0) 申し訳ございません。

現行版(2.0.4)で同様の実験をしたところ、次のような結果になりました。  速度:どのfrequencyでもおおよそ期待通りの計測値を得る。  角速度:frequency=20でも計測値が安定せず、さらに大きくすると計測値がzeroになってしまう。

また、2点の問題点(_rotation と FixedUpdate())の修正を試したところ、次のようになりました。  速度:どのfrequencyでも本来の5分の1程度の値が出るが、ある程度安定している。  角速度:どのfrequencyでも本来の5分の1程度の値が出るが、ある程度安定している。

なお、別issue (https://github.com/Field-Robotics-Japan/UnitySensors/issues/155) の問題は継続して発生しています。

以上、よろしくお願いいたします。

o-tatchan commented 1 month ago

岡本です。

上記の、本来の5分の1程度の値が出る問題は IMUSensor.cs 51行目の関数をFixedUpdate()からUpdate()に変更したのに対して、 関数内部での時間変位dtの値をTime.fixedDeltaTime()で取得しているためでした。

以上を踏まえ、次のどちらかの修正を行った際に期待通りの動作が確認できました。

1. IMUSensor.cs 61行目: _rotation → _rotation_tmp のみを修正する

2. IMUSensor.cs 61行目: _rotation → _rotation_tmp IMUSensor.cs 51行目: private void FixedUpdate() → protected override void Update() IMUSensor.cs ??行目: 上記関数内最終行にbase.Update();を追記 IMUSensor.cs 53行目: Time.fixedDeltaTime → Time.deltaTime

(私はFixedUpdateとUpdateの違いが理解できていないので、どちらの方が良いのか分かりません。)

以上、よろしくお願いいたします。

Autumn60 commented 1 month ago

@o-tatchan 検証大変助かります! もしよければ 2. の修正を行ったものについてmasterブランチ宛にPRを出していただくことは可能でしょうか?

o-tatchan commented 1 month ago

分かりました!!

o-tatchan commented 1 month ago

2.の修正内容でPR を送りました。 github初心者なので、送り方が間違えていたらすみません。

また、先ほど触っていて発見したのですが、 IMUをアタッチしたオブジェクトをUpdate()で動かすと問題ない値が出るのですが、 FixedUpdate()で動かしていると、2.の修正では正常に動かないことがあるようでした。

1.の修正では、オブジェクトの動作がFixedUpdate()かUpdate()かにかかわらず問題ありません。

1.の修正版が必要であれば改めてPRを送り直します。