Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update master #60

Merged
merged 23 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4b8916f
Update tf
Autumn60 Jul 26, 2023
4a19920
Update TF.unity
Autumn60 Jul 26, 2023
e026436
Update TFSensor.cs
Autumn60 Jul 26, 2023
c93fb7c
Add URDF2TF Converter
Autumn60 Jul 26, 2023
4786b17
Merge branch 'Field-Robotics-Japan:master' into feature/urdf2tf
Autumn60 Jul 26, 2023
3d72cf2
Add asmdef
Autumn60 Jul 26, 2023
0e1bcdb
Merge branch 'feature/urdf2tf' of https://github.com/Autumn60/UnitySe…
Autumn60 Jul 26, 2023
fba0e6e
Add UNITY_EDITOR preprocessor
Autumn60 Jul 26, 2023
a07929e
Merge pull request #46 from Autumn60/feature/urdf2tf
Autumn60 Jul 26, 2023
90c2618
Merge pull request #47 from Field-Robotics-Japan/feature/urdf2tf
Autumn60 Jul 26, 2023
3173cba
Add NavSatFix msg
Autumn60 Aug 2, 2023
b394aa8
Delete debuglog
Autumn60 Aug 2, 2023
ed8366b
Merge pull request #50 from arav-jp/feature/navsatfix_msg
Autumn60 Aug 2, 2023
7340276
Merge pull request #51 from Field-Robotics-Japan/feature/navsatfix_msg
Autumn60 Aug 2, 2023
f3de91b
Fix imu calc
Autumn60 Aug 9, 2023
c831458
Merge pull request #56 from Autumn60/fix/imuAccCalc
Autumn60 Aug 9, 2023
1a7234f
Add getter properties
Autumn60 Aug 9, 2023
aa8416f
Merge pull request #58 from Autumn60/feature/addGetterProperty
Autumn60 Aug 9, 2023
e09f0ae
Merge pull request #59 from Field-Robotics-Japan/feature/addGetterPro…
Autumn60 Aug 9, 2023
d1cb0a4
Merge pull request #57 from Field-Robotics-Japan/fix/imuAccCalc
Autumn60 Aug 9, 2023
339b873
Fix func name (#63)
Autumn60 Oct 26, 2023
bd9b3f9
Move TF sensor example scene (#72)
Autumn60 Dec 4, 2023
170369a
Update VelodyneMsgSerializer.cs (#70)
Autumn60 Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions Assets/UnitySensors/Runtime/Scripts/Sensors/IMU/IMUSensor.cs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Update does not contain noise model.
I will merge this in this case.
But we need to add them ASAP, at least gaussian noise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Livox and Velodyne, GaussianNoise is already implemented.
Currently, the GaussianNoise class is not implemented because the noise generation process is implemented within parallel and GPU processing.

LivoxとVelodyneについてはガウシアンノイズは実装済みです。
これらのノイズ生成処理は並列処理などの内部に実装されているため、GaussianNoiseクラス自体はまだありません。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not word this point well enough. Sorry about that. I thought the noise was necessary for GPS and IMU. We also confirmed that Livox and Velodyne are implemented without any problems.

Regarding the noise of GPS and IMU, I would like to merge them for the following reasons and set them as future issues. 1.

  1. GPS Noise We think it is necessary to change not only GussianNoise but also its variance and outlier setting depending on the FIX situation. Therefore, we would like to set this as an issue for future implementation. We would like to implement it after setting up the noise model. 2. We need to discuss whether or not drift noise should be implemented for IMU noise as well. We believe that it is necessary to deliberate whether drift noise should be implemented for IMU noise as well.

Since the commit contents of this PR are larger than the above concerns, we would like to prioritize to merge them first. I will raise an Issue regarding the concerns.

ノイズモデルについて言葉足らずでした。申し訳ありません。上記のReview時点では、GPSとIMUにノイズが必要だとと考えていました。また、LivoxとVelodyneについても問題なく実装されていることを確認しました。

GPSとIMUのノイズの実装については、以下の理由から本PRでは一旦無視し、今後の課題としたいと思います。1.

  1. GPSノイズ
    GussianNoiseだけでなく、分散や外れ値の設定もGPSのFIXの状況に応じて変更する必要があると考えています。そのため、今後の課題として設定し、どこまでノイズモデルを設定するか決定してから実装したいと考えます。
  2. IMUノイズ
    ドリフトノイズを実装すべきかどうか議論する必要があると考えます。こちらについてもどこまでノイズモデルを設定するか決定してから実装したいと考えます。

本PRのコミット内容は上記の懸念事項よりも大きいため、優先順位をつけて先にマージしたいと思います。懸念事項についてはIssueを立てておきます。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linked to #73 #74 for GPS and IMU noise models.

Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,19 @@ public class IMUSensor : Sensor
public Vector3 angularVelocity { get => _angularVelocity; }

public Vector3 localVelocity { get => _transform.InverseTransformDirection(_velocity); }
public Vector3 localAcceleration { get => _transform.InverseTransformDirection(_acceleration); }
public Vector3 localAcceleration { get => _transform.InverseTransformDirection(_acceleration.normalized) * _acceleration.magnitude; }

private float _dt { get => base._frequency_inv; }

private Vector3 _gravity;
private float _gravityMagnitude;

protected override void Init()
{
_transform = this.transform;

_gravity = Physics.gravity;
_gravityMagnitude = _gravity.magnitude;
}

protected override void UpdateSensor()
Expand All @@ -46,7 +52,7 @@ protected override void UpdateSensor()

_velocity = (_position - _position_last) / _dt;
_acceleration = (_velocity - _velocity_last) / _dt;
_acceleration += _transform.InverseTransformVector(Physics.gravity);
_acceleration += _transform.InverseTransformDirection(_gravity).normalized * _gravityMagnitude;

Quaternion rotation_delta = Quaternion.Inverse(_rotation_last) * _rotation;
rotation_delta.ToAngleAxis(out float angle, out Vector3 axis);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ public class LivoxSensor : Sensor
private uint _randomSeed;
private int _pointsNum;
public uint pointsNum { get=>(uint)(_pointsNum);}
public float minDistance { get => _minDistance; }
public float maxDistance { get => _maxDistance; }
public float maxIntensity { get => _maxIntensity; }

protected override void Init()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ public class VelodyneSensor : Sensor

private uint _randomSeed;
private int _pointsNum;

public uint pointsNum { get => (uint)_pointsNum; }
public int layersNum { get => _scanPattern.numOfLayer; }
public int azimuthResolution { get => _scanPattern.azimuthResolution; }
public float minDistance { get => _minDistance; }
public float maxDistance { get => _maxDistance; }
public float maxIntensity { get => _maxIntensity; }

protected override void Init()
{
Expand Down
75 changes: 68 additions & 7 deletions Assets/UnitySensors/Runtime/Scripts/Sensors/TF/TFSensor.cs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TF Sensor Sample is not added.
After adding them, I will merge it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TF is ROS onlyhttps://github.com/Field-Robotics-Japan/UnitySensors/pull/72

Since TF is one of the features that ROS has, I think the sample scene should only be implemented in UnitySensorsROS.

TFはROSの機能なので、UnitySensors側ではなくUnitySensorsROS側にのみサンプルシーンを置くべきだと考えています。
TFSensor.csがUnitySensors内に配置されているのは、ディレクトリ構成を統一するためです。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TFの機能を分離したPRをマージしました。
方針についても理解しました。本件はこれで問題ないのでマージします!!

Original file line number Diff line number Diff line change
@@ -1,14 +1,75 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnitySensors;

public class TFSensor : Sensor {
public class TFSensor : Sensor
{
public struct TFData
{
public string frame_id_parent;
public string frame_id_child;
public Vector3 position;
public Quaternion rotation;
};

[ReadOnly]
private Vector3 _position;
[SerializeField]
public string frame_id;
[SerializeField]
public TFSensor[] _children;

[ReadOnly]
private Quaternion _rotation;
private Transform _transform;

public Vector3 position { get => _position; }
public Quaternion rotation { get => _rotation; }
public TFData[] tf { get => GetTFData(); }

protected override void Init()
{
_transform = transform;
base.Init();
}

protected override void UpdateSensor()
{
base.UpdateSensor();
}

public TFData[] GetTFData()
{
List<TFData> tf = new List<TFData>();

Matrix4x4 worldToLocalMatrix = _transform.worldToLocalMatrix;
Quaternion worldToLocalQuaternion = Quaternion.Inverse(_transform.rotation);
foreach (TFSensor child in _children)
{
tf.AddRange(child.GetTFData(frame_id, worldToLocalMatrix, worldToLocalQuaternion));
}
return tf.ToArray();
}

public TFData[] GetTFData(string frame_id_parent, Matrix4x4 worldToLocalMatrix, Quaternion worldToLocalQuaternion)
{
List<TFData> tf = new List<TFData>();

TFData tfData;
tfData.frame_id_parent = frame_id_parent;
tfData.frame_id_child = frame_id;
tfData.position = worldToLocalMatrix * _transform.position;
tfData.rotation = worldToLocalQuaternion * _transform.rotation;
tf.Add(tfData);

worldToLocalMatrix = _transform.worldToLocalMatrix;
worldToLocalQuaternion = Quaternion.Inverse(_transform.rotation);
foreach (TFSensor child in _children)
{
tf.AddRange(child.GetTFData(frame_id, worldToLocalMatrix, worldToLocalQuaternion));
}
return tf.ToArray();
}

public void AddChild(TFSensor child)
{
List<TFSensor> children = _children!=null ? new List<TFSensor>(_children) : new List<TFSensor>();
children.Add(child);
_children = children.ToArray();
}
}
10 changes: 10 additions & 0 deletions Assets/UnitySensors/Samples/IMU/IMU.unity
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,16 @@ PrefabInstance:
propertyPath: m_RootOrder
value: 2
objectReference: {fileID: 0}
- target: {fileID: 8550806465241961968, guid: 884f57c81164231419af9316aaca015d,
type: 3}
propertyPath: m_LocalScale.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8550806465241961968, guid: 884f57c81164231419af9316aaca015d,
type: 3}
propertyPath: m_LocalScale.z
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8550806465241961968, guid: 884f57c81164231419af9316aaca015d,
type: 3}
propertyPath: m_LocalPosition.x
Expand Down
8 changes: 8 additions & 0 deletions Assets/UnitySensorsROS/Editor/URDF2TFConverter.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

136 changes: 136 additions & 0 deletions Assets/UnitySensorsROS/Editor/URDF2TFConverter/URDF2TFConverter.cs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sample scene and sample URDF is needed, I think.
But this is not the main sensors. Thus, if there are not, I will merge it.

Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

using UnitySensors;
using UnitySensors.ROS;

#if UNITY_EDITOR
class URDF2TFConverter : EditorWindow
{
private enum Mode
{
FromTextAsset,
FromFilePath
}

private Mode _mode;
private string _filePath;
private TextAsset _urdfFile;

[MenuItem("UnitySensorsROS/Generate TF Objects...")]
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(URDF2TFConverter));
}

private void OnGUI()
{
GUILayout.Label("Setting", EditorStyles.boldLabel);

EditorGUILayout.Space();

_mode = (Mode)EditorGUILayout.EnumPopup("Source", _mode);

if (_mode == Mode.FromTextAsset)
{
_urdfFile = EditorGUILayout.ObjectField("URDF File", _urdfFile, typeof(TextAsset), true) as TextAsset;
}
else
{
_filePath = EditorGUILayout.TextField("URDF File Path", _filePath);
}

EditorGUILayout.Space();

if (GUILayout.Button("Generate TF Objects"))
{
if (_mode == Mode.FromTextAsset && !_urdfFile) return;
Generate();
}
}

private void Generate()
{
XmlDocument doc = new XmlDocument();

if(_mode == Mode.FromTextAsset)
{
doc.LoadXml(_urdfFile.text);
}
else
{
doc.Load(_filePath);
}

XmlNode robot_node = doc.SelectSingleNode("robot");
GameObject robot_obj = new GameObject();
Transform robot_trans = robot_obj.transform;
string robot_name = robot_node.Attributes.GetNamedItem("name").Value;
robot_obj.name = robot_name;

Dictionary<string, Transform> links = new Dictionary<string, Transform>();
Dictionary<string, TFSensor> tfs = new Dictionary<string, TFSensor>();
links.Add(robot_name, robot_trans);

XmlNodeList link_nodes = robot_node.SelectNodes("link");
for (int i = 0; i < link_nodes.Count; i++)
{
GameObject link_obj = new GameObject();
string link_name = link_nodes[i].Attributes.GetNamedItem("name").Value;
link_obj.name = link_name;
links.Add(link_name, link_obj.transform);
TFSensor tf = link_obj.AddComponent<TFSensor>();
tf.frame_id = link_name;
tfs.Add(link_name, tf);
if (i == 0) link_obj.AddComponent<TFPublisher>();
}

XmlNodeList joint_nodes = robot_node.SelectNodes("joint");
for (int i = 0; i < joint_nodes.Count; i++)
{
string parent_name = joint_nodes[i].SelectSingleNode("parent").Attributes.GetNamedItem("link").Value;
string child_name = joint_nodes[i].SelectSingleNode("child").Attributes.GetNamedItem("link").Value;
links[child_name].parent = links[parent_name];
tfs[parent_name].AddChild(tfs[child_name]);

XmlNode origin_node = joint_nodes[i].SelectSingleNode("origin");
if (origin_node != null)
{
XmlNode xyz_node = origin_node.Attributes.GetNamedItem("xyz");
if (xyz_node != null)
{
string[] pos_str = xyz_node.Value.Split(' ');
Vector3 pos = new Vector3(-float.Parse(pos_str[1]), float.Parse(pos_str[2]), float.Parse(pos_str[0]));
links[child_name].localPosition = pos;
}
else
{
links[child_name].localPosition = Vector3.zero;
}

XmlNode rpy_node = origin_node.Attributes.GetNamedItem("rpy");
if (rpy_node != null)
{
string[] rot_str = rpy_node.Value.Split(' ');
Vector3 rot = new Vector3(-float.Parse(rot_str[1]), float.Parse(rot_str[2]), float.Parse(rot_str[0]));
links[child_name].localEulerAngles = rot * Mathf.Rad2Deg;
}
else
{
links[child_name].localEulerAngles = Vector3.zero;
}
}
}

foreach (Transform link in links.Values)
{
if (link.parent) continue;
link.parent = robot_trans;
}
}
}

#endif

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions Assets/UnitySensorsROS/Editor/UnitySensorsROSEditor.asmdef
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "UnitySensorsROSEditor",
"rootNamespace": "",
"references": [
"GUID:e9a473e6ad03eae4a89800bf81bd1594",
"GUID:fa38f881a10f6314fa784b8975c16eff"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ namespace UnitySensors.ROS
{
[RequireComponent(typeof(GPSSensor))]
[ExecuteAlways]
public class GPSPublisher : Publisher<GPSSensor, Serializer>
public class NMEAPublisher : Publisher<GPSSensor, Serializer>
{
[SerializeField]
private string _topicName = "gnss/raw_data";
[SerializeField]
private string _frame_id = "gnss_link";

[SerializeField]
private GPSSerializer _serializer_gps;
private NMEASerializer _serializer_gps;

protected override void Start()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using RosMessageTypes.Sensor;

namespace UnitySensors.ROS
{
[RequireComponent(typeof(GPSSensor))]
public class NavSatFixPublisher : Publisher<GPSSensor, Serializer>
{
[SerializeField]
private string _topicName = "gnss/raw_data";
[SerializeField]
private string _frame_id = "gnss_link";

[SerializeField]
private NavSatFixSerializer _serializer_navsat;

protected override void Init()
{
_ros.RegisterPublisher<NavSatFixMsg>(_topicName);
_serializer_navsat.Init(_frame_id);
}

protected override void Publish(float time)
{
_serializer_navsat.Serialize(time, _sensor.coordinate);
_ros.Publish(_topicName, _serializer_navsat.msg);
}
}
}

Loading
Loading