Neodroid  0.2.0
Machine Learning Environment Prototyping Tool
PoseDeviance.cs
Go to the documentation of this file.
4 using UnityEngine;
5 
6 namespace droid.Runtime.Prototyping.Evaluation {
10  [AddComponentMenu(EvaluationComponentMenuPath._ComponentMenuPath
11  + "PoseDeviance"
12  + EvaluationComponentMenuPath._Postfix)]
18  public override float InternalEvaluate() {
19  var signal = this._default_reward;
20 
21  /*if (this._playable_area != null && !this._playable_area.Bounds.Intersects(this._actor_transform.ActorBounds)) {
22  #if NEODROID_DEBUG
23  if (this.Debugging) {
24  Debug.Log("Outside playable area");
25  }
26  #endif
27  this.ParentEnvironment.Terminate("Outside playable area");
28  }*/
29 
30  var distance =
31  Mathf.Abs(Vector3.Distance(this._goal.transform.position,
32  this._actor_transform.transform.position));
33  var angle = Quaternion.Angle(this._goal.transform.rotation, this._actor_transform.transform.rotation);
34  #if NEODROID_DEBUG
35  if (this.Debugging) {
36  Debug.Log($"Distance: {distance}");
37  Debug.Log($"Angle: {angle}");
38  }
39  #endif
40 
41  if (!this._sparse) {
42  if (this._inverse) {
43  signal -= Mathf.Pow(this._distance_base, distance);
44  signal -= Mathf.Pow(this._angle_base, angle);
45  } else {
46  signal += this._distance_nominator / (Mathf.Pow(this._distance_base, distance) + float.Epsilon);
47  signal += this._angle_nominator / (Mathf.Pow(this._angle_base, angle) + float.Epsilon);
48 
49  if (this._state_full) {
50  if (signal <= this._peak_reward) {
51  signal = 0.0f;
52  } else {
53  this._peak_reward = signal;
54  }
55  }
56  }
57  }
58 
59  if (distance < this._goal_reached_radius) {
60  #if NEODROID_DEBUG
61  if (this.Debugging) {
62  Debug.Log("Within range of goal");
63  }
64  #endif
65 
66  signal += this._solved_reward;
67  if (this._terminate_on_goal_reached) {
68  this.ParentEnvironment?.Terminate("Within range of goal");
69  }
70  }
71 
72  if (this._has_collided) {
73  this.ParentEnvironment?.Terminate("Actor has collided");
74  }
75 
76  #if NEODROID_DEBUG
77  if (this.Debugging) {
78  Debug.Log($"Frame Number: {this.ParentEnvironment?.CurrentFrameNumber}, "
79  + $"Terminated: {this.ParentEnvironment?.Terminated}, "
80  + $"Last Reason: {this.ParentEnvironment?.LastTerminationReason}, "
81  + $"Internal Feedback Signal: {signal}, "
82  + $"Distance: {distance}");
83  }
84  #endif
85 
86  return signal;
87  }
88 
92  public override void InternalReset() {
93  this._peak_reward = 0.0f;
94  this._has_collided = false;
95  }
96 
100  protected override void PostSetup() {
101  if (!this._goal) {
102  this._goal = FindObjectOfType<Transform>();
103  }
104 
105  if (!this._actor_transform) {
106  this._actor_transform = FindObjectOfType<Transform>();
107 
108  var remote_sensor =
109  this._actor_transform.GetComponentInChildren<ChildColliderSensor<Collider, Collision>>();
110  if (!remote_sensor) {
111  var col = this._actor_transform.GetComponentInChildren<Collider>();
112  if (col) {
113  remote_sensor = col.gameObject.AddComponent<ChildColliderSensor<Collider, Collision>>();
114  }
115  }
116 
117  if (remote_sensor) {
118  remote_sensor.Caller = this;
119  remote_sensor.OnTriggerEnterDelegate = this.OnChildTriggerEnter;
120  remote_sensor.OnCollisionEnterDelegate = this.OnChildTriggerEnter;
121  }
122  }
123 
124  if (this._obstructions == null || this._obstructions.Length <= 0) {
125  this._obstructions = FindObjectsOfType<Obstruction>();
126  }
127 
128  if (!this._playable_area) {
129  this._playable_area = FindObjectOfType<BoundingBox>();
130  }
131  }
132 
133  void OnChildTriggerEnter(GameObject child_sensor_game_object, Collision collision) {
134  this._has_collided = true;
135  }
136 
137  void OnChildTriggerEnter(GameObject child_sensor_game_object, Collider collider1) {
138  this._has_collided = true;
139  }
140 
141  #region Fields
142 
143  [Header("Specific", order = 102)]
144  [SerializeField]
145  float _peak_reward;
146 
147  [SerializeField] [Range(0.1f, 10f)] float _distance_base = 2f;
148  [SerializeField] [Range(0.1f, 10f)] float _distance_nominator = 5f;
149  [SerializeField] [Range(0.1f, 10f)] float _angle_base = 6f;
150  [SerializeField] [Range(0.1f, 10f)] float _angle_nominator = 3f;
151 
152  [SerializeField] bool _sparse = true;
153  [SerializeField] bool _inverse = false;
154  [SerializeField] Transform _goal = null;
155 
156  [SerializeField] Transform _actor_transform = null;
157 
158  [SerializeField] BoundingBox _playable_area = null;
159 
160  [SerializeField] Obstruction[] _obstructions = null;
161 
162  [SerializeField] bool _state_full = false;
163  [SerializeField] float _goal_reached_radius = 0.01f; // Equivalent to 1 cm.
164 
165  [SerializeField] bool _terminate_on_obstruction_collision = true; //TODO: implement
166  [SerializeField] bool _has_collided = false;
167  [SerializeField] bool _terminate_on_goal_reached = true;
168 
169  #endregion
170  }
171 }