Browse Source

Streamline

- use calculator in personDetector
- fix exception when homography is not found
- carefully edit person collection; don't just clear and refill
Nick Steyer 1 year ago
parent
commit
24f5884f91

+ 1 - 1
Assets/CalibrationTestMarkerBehavior.cs

@@ -23,7 +23,7 @@ public class CalibrationTestMarkerBehavior : MonoBehaviour
         if (firstPersonFound != null)
         {
             var marker = GameObject.Find("CalibrationTestMarker");
-            marker.transform.position = PersonManager.CalculateUnityPosition(firstPersonFound);
+            marker.transform.position = firstPersonFound.GetUnityPosition();
         }
     }
 }

+ 4 - 1
Assets/StreetLight/Adapters/ZedPersonDetector.cs

@@ -39,7 +39,10 @@ namespace Assets.StreetLight.Adapters
 
             var detectedPersons = from p in persons
                                   let position = p.Get3DWorldPosition()
-                                  select new Person(p.id, new Vector3(position.x, position.y, position.z));
+                                  select new Person(p.id, null)
+                                  {
+                                      WorldPosition = new Vector3(position.x, position.y, position.z)
+                                  };
 
             PersonsDetected?.Invoke(this, detectedPersons.ToList());
         }

+ 1 - 1
Assets/StreetLight/PersonVisualizer.cs

@@ -34,7 +34,7 @@ namespace Assets.StreetLight
             foreach (var person in PersonManager.Persons.OrderBy(p => p.Id))
             {
                 GameObject sphere = spheres[count];
-                var unityPosition = PersonManager.CalculateUnityPosition(person);
+                var unityPosition = person.GetUnityPosition();
                 sphere.transform.position = new Vector3(unityPosition.x, unityPosition.y, unityPosition.z);
                 count++;
             }

+ 38 - 7
Assets/StreetLight/Poco/Person.cs

@@ -1,19 +1,50 @@
-using UnityEngine;
+using Assets.StreetLight.Scripts;
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using UnityEngine;
 
 namespace Assets.StreetLight.Poco
 {
-    public class Person
+    public class Person : INotifyPropertyChanged
     {
-        public int Id { get; set; }
+        public int Id { get; }
+        public event PropertyChangedEventHandler PropertyChanged;
 
-        // todo: add notify property changed
         // todo: make world position private and add get position method for unity position
-        public Vector3 WorldPosition { get; set; }
+        private Vector3 worldPosition = Vector3.zero;
+        private readonly PositionCalculator positionCalculator;
 
-        public Person(int id, Vector3 worldPosition)
+        public Vector3 WorldPosition
+        {
+            get => worldPosition;
+            set => OnPropertyChanged(ref worldPosition, value);
+        }
+
+        public Person(int id, PositionCalculator positionCalculator)
         {
             Id = id;
-            WorldPosition = worldPosition;
+            this.positionCalculator = positionCalculator;
+        }
+
+        public Vector3 GetUnityPosition()
+        {
+            if (positionCalculator == null)
+            {
+                throw new InvalidOperationException("Cannot calculate Unity position because the PositionCalculator is not initialized. This might occur when the homography file is not found or not in the right format.");
+            }
+
+            return positionCalculator.WorldPositionToUnityPosition(WorldPosition);
+        }
+
+
+        private void OnPropertyChanged<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
+        {
+            if (!field.Equals(value))
+            {
+                field = value;
+                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+            }
         }
     }
 }

+ 19 - 13
Assets/StreetLight/Scripts/PersonManager.cs

@@ -22,11 +22,15 @@ namespace Assets.StreetLight.Scripts
 
         void Start()
         {
-            if (File.Exists(Configuration.Instance.HomographyFilePath))
+            try
             {
                 var homographyArray = GetHomographyArrayFromFile();
                 PositionCalculator = new PositionCalculator(homographyArray);
             }
+            catch (Exception ex)
+            {
+                Debug.LogError($"Could not load homography: {ex.Message}");
+            }
 
             Persons = new ObservableCollection<Person>();
             personDetector = new ZedPersonDetector(FindObjectOfType<ZEDManager>());
@@ -59,23 +63,25 @@ namespace Assets.StreetLight.Scripts
             personDetector.PersonsDetected -= InvokeDetectionReady;
         }
 
-        public Vector3 CalculateUnityPosition(Person person)
+        private void PersonDetector_PersonsDetected(object sender, IEnumerable<Person> e)
         {
-            if (PositionCalculator == null)
+            var detectedIds = new HashSet<int>();
+            foreach (var detectedPerson in e)
             {
-                throw new InvalidOperationException("Cannot calculate Unity position because the PositionCalculator is not initialized. This might occur when the homography file is not found or not in the right format.");
+                var person = Persons.SingleOrDefault(p => p.Id == detectedPerson.Id);
+                if (person == null)
+                {
+                    person = new Person(detectedPerson.Id, PositionCalculator);
+                    Persons.Add(person);
+                }
+                person.WorldPosition = detectedPerson.WorldPosition;
+                detectedIds.Add(detectedPerson.Id);
             }
 
-            return PositionCalculator.WorldPositionToUnityPosition(person.WorldPosition);
-        }
-
-        private void PersonDetector_PersonsDetected(object sender, IEnumerable<Person> e)
-        {
-            // TODO: update carefully instead of clear and add all
-            Persons.Clear();
-            foreach (var person in e)
+            var personsToBeRemoved = Persons.Where(p => !detectedIds.Contains(p.Id)).ToArray();
+            foreach (var person in personsToBeRemoved)
             {
-                Persons.Add(person);
+                Persons.Remove(person);
             }
         }