Переглянути джерело

Dashboard fully integrated with Unity/ROS2

rparedis 3 роки тому
батько
коміт
931c62e199
56 змінених файлів з 884 додано та 210 видалено
  1. 9 1
      .gitignore
  2. 29 29
      README.md
  3. 32 0
      Unity/LineRobot/Assets/MyGui.cs
  4. 1 1
      Unity/LineRobot/Assets/PublishColorSensor.cs
  5. 5 4
      Unity/LineRobot/Assets/Scenes/SampleScene.unity
  6. 8 0
      Unity/LineRobot/Assets/Scripts/SteeringLineRobot.cs
  7. 12 3
      Unity/LineRobot/Assets/VelocitySetpointGeneration.cs
  8. BIN
      Unity/LineRobot/Library/ArtifactDB
  9. BIN
      Unity/LineRobot/Library/Artifacts/0c/0c171bc6f48aed1a7f44182171c825e7
  10. BIN
      Unity/LineRobot/Library/Artifacts/13/13c6cb2ed07807b4827c30ec528a4547
  11. BIN
      Unity/LineRobot/Library/Artifacts/53/5383ecdc9ad82219fdef72092091cba6
  12. BIN
      Unity/LineRobot/Library/Artifacts/5d/5d0fd463be364529271032522634cdc2
  13. BIN
      Unity/LineRobot/Library/Artifacts/6a/6a5781cacb85208f883d8e932bcdd95f
  14. BIN
      Unity/LineRobot/Library/Artifacts/72/7255b9b06cb44178b9e4fa64f457f8cb
  15. BIN
      Unity/LineRobot/Library/Artifacts/76/764d04ac85a89f75753c04d1d29632b0
  16. BIN
      Unity/LineRobot/Library/Artifacts/8d/8dd52a1db1889e07220e6208b414fa84
  17. BIN
      Unity/LineRobot/Library/Artifacts/94/94fd2f043cf412948ac1da52c13bd0f6
  18. BIN
      Unity/LineRobot/Library/Artifacts/ae/ae4fffe3ed5cb65cae3f21a683b98e44
  19. BIN
      Unity/LineRobot/Library/Artifacts/af/afc0a08794f5430e83261d559b0bafc5
  20. BIN
      Unity/LineRobot/Library/Artifacts/b0/b0da69e056d8975d215bdeddda446f9f
  21. BIN
      Unity/LineRobot/Library/Artifacts/be/bebf115011c6f13e8ef30ba3338eacd7
  22. BIN
      Unity/LineRobot/Library/Artifacts/c9/c932df19492cc5f2f27997bbdd7abc30
  23. BIN
      Unity/LineRobot/Library/Artifacts/c9/c975656a5e63ce3db365ba766744774c
  24. BIN
      Unity/LineRobot/Library/Artifacts/e6/e6ef1196519fac26c9d6027d67b099d7
  25. BIN
      Unity/LineRobot/Library/Artifacts/f0/f086ccef78640ab9a8e8cb6f55062e59
  26. BIN
      Unity/LineRobot/Library/Artifacts/fc/fc629665642fcca6e08441272833fd08
  27. BIN
      Unity/LineRobot/Library/Artifacts/ff/ff64ca9787359506d79455ce7b2daffb
  28. 43 43
      Unity/LineRobot/Library/CurrentLayout-default.dwlt
  29. BIN
      Unity/LineRobot/Library/InspectorExpandedItems.asset
  30. BIN
      Unity/LineRobot/Library/SceneVisibilityState.asset
  31. BIN
      Unity/LineRobot/Library/ScriptAssemblies/Assembly-CSharp.dll
  32. BIN
      Unity/LineRobot/Library/ScriptAssemblies/Assembly-CSharp.pdb
  33. BIN
      Unity/LineRobot/Library/ShaderCache/8/86ed30a39d6fe55d6002e29602828535.bin
  34. BIN
      Unity/LineRobot/Library/ShaderCache/EditorEncounteredVariants
  35. BIN
      Unity/LineRobot/Library/ShaderCache/d/d1a0682cb2dcbc0a869d33b6c25285f4.bin
  36. BIN
      Unity/LineRobot/Library/SourceAssetDB
  37. 1 1
      Unity/LineRobot/Library/StateCache/SceneView/ed/ed9c0a48af780ce5af524569e3967665.json
  38. 30 0
      Unity/LineRobot/Logs/ApiUpdaterCheck.txt
  39. 480 0
      Unity/LineRobot/Logs/AssetImportWorker0.log
  40. 6 0
      Unity/LineRobot/Logs/shadercompiler-AssetImportWorker0.log
  41. 6 0
      Unity/LineRobot/Logs/shadercompiler-UnityShaderCompiler.exe0.log
  42. 7 4
      Unity/LineRobot/ProjectSettings/DynamicsManager.asset
  43. 0 8
      dashboard/.idea/.gitignore
  44. 0 8
      dashboard/.idea/dashboard.iml
  45. 0 34
      dashboard/.idea/inspectionProfiles/Project_Default.xml
  46. 0 6
      dashboard/.idea/inspectionProfiles/profiles_settings.xml
  47. 0 4
      dashboard/.idea/misc.xml
  48. 0 8
      dashboard/.idea/modules.xml
  49. 0 6
      dashboard/.idea/other.xml
  50. 0 6
      dashboard/.idea/vcs.xml
  51. 28 2
      dashboard/README.md
  52. 71 22
      dashboard/main.py
  53. 41 0
      dashboard/ros2/lfr_msgs/CMakeLists.txt
  54. 11 0
      dashboard/ros2/lfr_msgs/msg/State.msg
  55. 24 0
      dashboard/ros2/lfr_msgs/package.xml
  56. 40 20
      dashboard/vision.py

+ 9 - 1
.gitignore

@@ -5,4 +5,12 @@
 */__pycache__/
 *.unitypackage
 /ros2-windows/
-/.vs/
+/.vs/
+/dashboard/ros2/build/
+/dahsboard/ros2/install/
+/dahsboard/ros2/log/
+dashboard/.idea/
+
+dashboard/ros2/install/
+
+dashboard/ros2/log/

+ 29 - 29
README.md

@@ -1,49 +1,46 @@
-# Line Robot
+# Line Following Robot
 
-## Linerobot digital shadow
-This repo is the development of a digital shadow in Unity3D. It concerns a Lego line follower, for which the mechanics, a similar  control-algirtm for linefollowing, is implemented.
-This basically is a red-sensor which follows the left-side of a white line. 
+**Note:** _This repository is a "fork" of [Edward's work](https://msdl.uantwerpen.be/git/edward/linerobot). Because of certain git configurations, an actual fork could not be
+created. The work in this repository should be more platform-independent._
 
-Remarks: The mechanics have been altered to be able to be able for the control-strategy to be succesfull.
-The location of the sensor has been changed. Physically a sensor between the two driven wheels will not result in a feasbily linefollower.
+## Line Following Robot Digital Shadow
+This repo is the development of a Digital Shadow (DS) in Unity3D. It concerns a LEGO Line Following Robot (LFR), for which the mechanics, a similar control-algorithm for linefollowing, is implemented.
+This basically is a red-sensor which follows the left-side of a white line (i.e., anti-clockwise). 
 
-The sensor is achieved with a camera with a limited scope (70x70 pixels) for which all "red" pixels are averaged. Thus an average value will result (0=no red, 1 = full red).
-Besised the sensor (part of the sensor actually) is a red spotlight.
+Remarks: The mechanics have been altered for the control-strategy to be succesfull.
+The location of the sensor has been changed. Physically a sensor between the two driven wheels will not result in a feasable linefollower.
+
+The sensor is achieved with a camera with a limited scope (70x70 pixels) for which all "red" pixels are averaged. Thus an average value will result (0 = no red, 1 = full red).
+Besides, the sensor (part of the sensor actually) is a red spotlight.
 
 Additonally a normal cameraimage (jpeg-stream) is created and also a depth-image (image-stream).
-The images  are streamed over DDS and can be observed in any application that used DDS.
+The images are streamed over DDS and can be observed in any application that used DDS.
 The format in which the images are sent are standardised ROS-messages.
 
-ROS2 relies on DDS and the topics are read by 
-
 ## Hardware configuration
-Windows-10 and VMware Workstation is installed on a laptop.
-Unity3D runs on Windows-10. A Ubuntu-VM is made with ROS2 on it (but any ROS2 instance in "the" network will suffice).
-
-## DDS
-Communication of DDS is specified in a configuration file. When you run the Unity-application (in the Editor or standalone)
-this configuration file needs to be called first. This is done in a batch-filw which runs Vortex DDS and than Unity (must be done in the same command window).
+The full system should work on Windows 10, with Unity3D 2020+. While it has not (yet) been tested on Linux-systems (currently being investigated), it should work out-of-the-box as well.
 
-Vortex DDS needs to be installed. See https://bitbucket.org/edhage/dds-for-unity/src/master/.
+## DDS and ROS2 in Unity3D
+Wheras the old repository used VortexDDS and a detailed configuration for DDS communication, this is not required anymore in this new version.
+All this is handled using the [Robotec.ai plugin for ROS2](https://github.com/RobotecAI/ros2-for-unity).
 
-For the use of DDS in Unity an open source repo is used (see above). Be aware that 
-[here](https://bitbucket.org/edhage/dds-for-unity/src/master/Vortex/) the Vortex installer is placed (so you do not have to copy it from the Adlink-website).
 
+## ROS2 on the Host
+[ROS2](https://docs.ros.org/en/galactic/Installation/Ubuntu-Install-Binary.html) needs to be installed on the machine.
 
-## ROS2
-https://docs.ros.org/en/galactic/Installation/Ubuntu-Install-Binary.html 
-I installed ROS2 Galactic, but newer versions are also okay (I wrote a package but typically they can be used for any newer version).
-ROS2 versions start with a letter in alphabetical order, "G" for Galactic, "F" for Foxy is older. Be aware that you DO NOT INSTALL ROS. Must be ROS2.
-https://docs.ros.org/en/galactic/index.html
+I installed ROS2 Galactic (https://docs.ros.org/en/galactic/index.html), but newer versions are also okay.
+ROS2 versions start with a letter in alphabetical order, "G" for Galactic, "F" for Foxy is older. **Be aware that you DO NOT INSTALL ROS. Must be ROS2.**
 
 Galactic works with Ubuntu Focal (20.04.3 LTS). Recommended is to install this Ubuntu.
 
-The package in directory ROS contains python files and C++ files.
+**Note:** _Fedora 36 currently has no way of using ROS2, due to compilation issues with ament. See also [this StackOverflow issue](https://github.com/ament/ament_lint/issues/388)_.
+
+The package in directory ROS contains Python files and C++ files.
 You need to build the files in the "ROS2"-way (with colcon and lots of assisting files).
-The python you can run without building, it will not be "known" as part of the package, but it works.
+The Python you can run without building, it will not be "known" as part of the package, but it works.
 
 In a terminal you can already watch some topics.
-"ros2 topic list" will list all available topics.
+`ros2 topic list` will list all available topics.
 If you installed rqt (done by default I think) you can run the GUI (easier).
 "ros2 run rqt_gui rqt_gui"
 
@@ -55,8 +52,11 @@ Than it shows the image with a colormap (depth-2-colormap).
 
 Additionally we would be able to re-pulish the topic under another topic-name, and than it could be shown in rqt_gui.
 
+## Dashboard
+The repository comes with a simple-to-use dashboard for identifying the DS of the LFR. Take a look in the `/dashboard` folder for more information.
+
 ## Database 
-A MongoDB is used to store timedata (currently only the position and orientation of the linerobot every second).
+A MongoDB is used to store timedata (currently only the position and orientation of the LFR every second).
 
 Instaal a MongoDB and readup on howto do that (A DB can be stored locally or in the cloud)
 

+ 32 - 0
Unity/LineRobot/Assets/MyGui.cs

@@ -1,6 +1,7 @@
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
+using ROS2;
 
 public class MyGui : MonoBehaviour
 {
@@ -8,6 +9,29 @@ public class MyGui : MonoBehaviour
     public GameObject shadowbox;
 
 
+    public string TopicName = "lfr/handbrake";
+
+    private ROS2UnityComponent ros2Unity;
+    private ROS2Node ros2Node;
+    private IPublisher<std_msgs.msg.Bool> chatter_pub;
+    private ISubscription<std_msgs.msg.Bool> chatter_sub;
+
+    private void Start()
+    {
+        ros2Unity = GetComponent<ROS2UnityComponent>();
+
+        if (ros2Unity.Ok())
+        {
+            if (ros2Node == null)
+            {
+                ros2Node = ros2Unity.CreateNode("ROS2LFRgui");
+                chatter_pub = ros2Node.CreatePublisher<std_msgs.msg.Bool>(TopicName);
+                chatter_sub = ros2Node.CreateSubscription<std_msgs.msg.Bool>(TopicName, msg => robot.handBrake = msg.Data);
+            }
+        }
+    }
+
+
     private void OnGUI()
     {
 
@@ -21,6 +45,14 @@ public class MyGui : MonoBehaviour
             {
                 robot.handBrake = true;
             }
+
+        }
+
+        std_msgs.msg.Bool msg = new std_msgs.msg.Bool();
+        msg.Data = robot.handBrake;
+        if (ros2Unity.Ok())
+        {
+            chatter_pub.Publish(msg);
         }
 
         if (GUI.Button(new Rect(10, 50, 150, 20), "Toggle Shade"))

+ 1 - 1
Unity/LineRobot/Assets/PublishColorSensor.cs

@@ -7,7 +7,7 @@ public class PublishColorSensor : MonoBehaviour
 {
 
     public GetSumRed SensorValue;
-    public string TopicName = "rt/redsensor";
+    public string TopicName = "lfr/redsensor";
 
     private ROS2UnityComponent ros2Unity;
     private ROS2Node ros2Node;

+ 5 - 4
Unity/LineRobot/Assets/Scenes/SampleScene.unity

@@ -484,7 +484,7 @@ MonoBehaviour:
   m_Name: 
   m_EditorClassIdentifier: 
   SensorValue: {fileID: 1823308758}
-  TopicName: rt/redsensor
+  TopicName: lfr/redsensor
 --- !u!114 &392296680
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -499,6 +499,7 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   robot: {fileID: 3212287658190039934}
   shadowbox: {fileID: 878907878}
+  TopicName: lfr/handbrake
 --- !u!114 &392296681
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -561,7 +562,7 @@ MonoBehaviour:
   m_Name: 
   m_EditorClassIdentifier: 
   timeBetweenRequests: 0.2
-  TopicName: rt/depth_image
+  TopicName: lfr/depth_image
   frame_id: 1
   shader: {fileID: 7200000, guid: 16b8366b4724e3f47bcb2fd11d8c7991, type: 3}
 --- !u!81 &396615289
@@ -654,7 +655,7 @@ MonoBehaviour:
   m_Name: 
   m_EditorClassIdentifier: 
   timeBetweenRequests: 0.2
-  TopicName: rt/depth_processor
+  TopicName: lfr/depth_processor
   frame_id: 1
   mater: {fileID: 2100000, guid: 4a2440c87fd96694ea56b7990a068fdc, type: 2}
 --- !u!114 &396615294
@@ -8034,7 +8035,7 @@ MonoBehaviour:
   KSpeedController: 1.42
   leftspeedsetpoint: 1
   rightspeedsetpoint: 1
-  handBrake: 0
+  handBrake: 1
   speed: 0
   lefttorqueout: 0
   righttorqueout: 0

+ 8 - 0
Unity/LineRobot/Assets/Scripts/SteeringLineRobot.cs

@@ -97,8 +97,16 @@ public class SteeringLineRobot : MonoBehaviour
     }
     private void FixedUpdate()
     {
+        // Prevent robot from "sliding"
+        var rb = GetComponent<Rigidbody>();
+        rb.isKinematic = handBrake;
         wheelColliderLeft.ConfigureVehicleSubsteps(criticalSpeed, stepsBelow, stepsAbove);
+
         speed = transform.InverseTransformVector(body.velocity).x;
+        if(handBrake)
+        {
+            speed = 0.0F;
+        }
 
         if (handBrake == true)
         {

+ 12 - 3
Unity/LineRobot/Assets/VelocitySetpointGeneration.cs

@@ -52,8 +52,17 @@ public class VelocitySetpointGeneration : MonoBehaviour
         }
 
         omega = K * dimlessvalue;
-        float NettoForwardSpeed = ForwardSpeed; // Mathf.Max(ForwardSpeed - Mathf.Abs(omega * DistanceCenterToWheel), ForwardSpeed/4f);
-        Robot.leftspeedsetpoint = NettoForwardSpeed - omega * DistanceCenterToWheel;
-        Robot.rightspeedsetpoint = NettoForwardSpeed + omega * DistanceCenterToWheel;
+
+        if (Robot.handBrake)
+        {
+            Robot.leftspeedsetpoint = 0.0F;
+            Robot.rightspeedsetpoint = 0.0F;
+        }
+        else
+        {
+            float NettoForwardSpeed = ForwardSpeed; // Mathf.Max(ForwardSpeed - Mathf.Abs(omega * DistanceCenterToWheel), ForwardSpeed/4f);
+            Robot.leftspeedsetpoint = NettoForwardSpeed - omega * DistanceCenterToWheel;
+            Robot.rightspeedsetpoint = NettoForwardSpeed + omega * DistanceCenterToWheel;
+        }
     }
 }

BIN
Unity/LineRobot/Library/ArtifactDB


BIN
Unity/LineRobot/Library/Artifacts/0c/0c171bc6f48aed1a7f44182171c825e7


BIN
Unity/LineRobot/Library/Artifacts/13/13c6cb2ed07807b4827c30ec528a4547


BIN
Unity/LineRobot/Library/Artifacts/53/5383ecdc9ad82219fdef72092091cba6


BIN
Unity/LineRobot/Library/Artifacts/5d/5d0fd463be364529271032522634cdc2


BIN
Unity/LineRobot/Library/Artifacts/6a/6a5781cacb85208f883d8e932bcdd95f


BIN
Unity/LineRobot/Library/Artifacts/72/7255b9b06cb44178b9e4fa64f457f8cb


BIN
Unity/LineRobot/Library/Artifacts/76/764d04ac85a89f75753c04d1d29632b0


BIN
Unity/LineRobot/Library/Artifacts/8d/8dd52a1db1889e07220e6208b414fa84


BIN
Unity/LineRobot/Library/Artifacts/94/94fd2f043cf412948ac1da52c13bd0f6


BIN
Unity/LineRobot/Library/Artifacts/ae/ae4fffe3ed5cb65cae3f21a683b98e44


BIN
Unity/LineRobot/Library/Artifacts/af/afc0a08794f5430e83261d559b0bafc5


BIN
Unity/LineRobot/Library/Artifacts/b0/b0da69e056d8975d215bdeddda446f9f


BIN
Unity/LineRobot/Library/Artifacts/be/bebf115011c6f13e8ef30ba3338eacd7


BIN
Unity/LineRobot/Library/Artifacts/c9/c932df19492cc5f2f27997bbdd7abc30


BIN
Unity/LineRobot/Library/Artifacts/c9/c975656a5e63ce3db365ba766744774c


BIN
Unity/LineRobot/Library/Artifacts/e6/e6ef1196519fac26c9d6027d67b099d7


BIN
Unity/LineRobot/Library/Artifacts/f0/f086ccef78640ab9a8e8cb6f55062e59


BIN
Unity/LineRobot/Library/Artifacts/fc/fc629665642fcca6e08441272833fd08


BIN
Unity/LineRobot/Library/Artifacts/ff/ff64ca9787359506d79455ce7b2daffb


+ 43 - 43
Unity/LineRobot/Library/CurrentLayout-default.dwlt

@@ -65,10 +65,10 @@ MonoBehaviour:
   m_Children: []
   m_Position:
     serializedVersion: 2
-    x: 308
+    x: 441
     y: 0
-    width: 949
-    height: 823
+    width: 816
+    height: 726
   m_MinSize: {x: 202, y: 221}
   m_MaxSize: {x: 4002, y: 4021}
   m_ActualView: {fileID: 17}
@@ -175,7 +175,7 @@ MonoBehaviour:
   m_MinSize: {x: 680, y: 342}
   m_MaxSize: {x: 16005, y: 8042}
   vertical: 0
-  controlID: 85
+  controlID: 143
 --- !u!114 &8
 MonoBehaviour:
   m_ObjectHideFlags: 52
@@ -221,7 +221,7 @@ MonoBehaviour:
     x: 0
     y: 0
     width: 1257
-    height: 823
+    height: 726
   m_MinSize: {x: 304, y: 221}
   m_MaxSize: {x: 8004, y: 4021}
   vertical: 0
@@ -243,8 +243,8 @@ MonoBehaviour:
     serializedVersion: 2
     x: 0
     y: 0
-    width: 308
-    height: 823
+    width: 441
+    height: 726
   m_MinSize: {x: 100, y: 100}
   m_MaxSize: {x: 4000, y: 4000}
   m_ActualView: {fileID: 18}
@@ -270,9 +270,9 @@ MonoBehaviour:
   m_Position:
     serializedVersion: 2
     x: 0
-    y: 823
+    y: 726
     width: 1257
-    height: 124
+    height: 221
   m_MinSize: {x: 102, y: 121}
   m_MaxSize: {x: 4002, y: 4021}
   m_ActualView: {fileID: 21}
@@ -282,7 +282,7 @@ MonoBehaviour:
   - {fileID: 14}
   - {fileID: 15}
   m_Selected: 1
-  m_LastSelected: 0
+  m_LastSelected: 3
 --- !u!114 &12
 MonoBehaviour:
   m_ObjectHideFlags: 52
@@ -338,9 +338,9 @@ MonoBehaviour:
   m_SceneHierarchy:
     m_TreeViewState:
       scrollPos: {x: 0, y: 0}
-      m_SelectedIDs: 
-      m_LastClickedID: 0
-      m_ExpandedIDs: 70fbffff
+      m_SelectedIDs: dc4b0000
+      m_LastClickedID: 19420
+      m_ExpandedIDs: 6efbffff70fbffff1c490000844900008e490000bc4a0000c04a0000ca4a0000d04a0000dc4b0000
       m_RenameOverlay:
         m_UserAcceptedRename: 0
         m_Name: 
@@ -415,10 +415,10 @@ MonoBehaviour:
     m_Tooltip: 
   m_Pos:
     serializedVersion: 2
-    x: 218.40001
-    y: 532.8
-    width: 1002.8
-    height: 250.59998
+    x: -1649
+    y: 799
+    width: 1255
+    height: 200
   m_ViewDataDictionary: {fileID: 0}
   m_PosLeft: {x: 0, y: 0}
   m_PosRight: {x: 0, y: 0}
@@ -470,10 +470,10 @@ MonoBehaviour:
     m_Tooltip: 
   m_Pos:
     serializedVersion: 2
-    x: -1341
+    x: -1208
     y: 73
-    width: 947
-    height: 802
+    width: 814
+    height: 705
   m_ViewDataDictionary: {fileID: 0}
   m_SerializedViewNames: []
   m_SerializedViewValues: []
@@ -481,7 +481,7 @@ MonoBehaviour:
   m_ShowGizmos: 0
   m_TargetDisplay: 0
   m_ClearColor: {r: 0, g: 0, b: 0, a: 0}
-  m_TargetSize: {x: 947, y: 781}
+  m_TargetSize: {x: 814, y: 684}
   m_TextureFilterMode: 0
   m_TextureHideFlags: 61
   m_RenderIMGUI: 1
@@ -496,10 +496,10 @@ MonoBehaviour:
     m_VRangeLocked: 0
     hZoomLockedByDefault: 0
     vZoomLockedByDefault: 0
-    m_HBaseRangeMin: -473.5
-    m_HBaseRangeMax: 473.5
-    m_VBaseRangeMin: -390.5
-    m_VBaseRangeMax: 390.5
+    m_HBaseRangeMin: -407
+    m_HBaseRangeMax: 407
+    m_VBaseRangeMin: -342
+    m_VBaseRangeMax: 342
     m_HAllowExceedBaseRangeMin: 1
     m_HAllowExceedBaseRangeMax: 1
     m_VAllowExceedBaseRangeMin: 1
@@ -517,23 +517,23 @@ MonoBehaviour:
       serializedVersion: 2
       x: 0
       y: 21
-      width: 947
-      height: 781
+      width: 814
+      height: 684
     m_Scale: {x: 1, y: 1}
-    m_Translation: {x: 473.5, y: 390.5}
+    m_Translation: {x: 407, y: 342}
     m_MarginLeft: 0
     m_MarginRight: 0
     m_MarginTop: 0
     m_MarginBottom: 0
     m_LastShownAreaInsideMargins:
       serializedVersion: 2
-      x: -473.5
-      y: -390.5
-      width: 947
-      height: 781
+      x: -407
+      y: -342
+      width: 814
+      height: 684
     m_MinimalGUI: 1
   m_defaultScale: 1
-  m_LastWindowPixelSize: {x: 947, y: 802}
+  m_LastWindowPixelSize: {x: 814, y: 705}
   m_ClearInEditMode: 1
   m_NoCameraWarning: 1
   m_LowResolutionForAspectRatios: 01000000000000000001
@@ -562,8 +562,8 @@ MonoBehaviour:
     serializedVersion: 2
     x: -1649
     y: 73
-    width: 306
-    height: 802
+    width: 439
+    height: 705
   m_ViewDataDictionary: {fileID: 0}
   m_ShowContextualTools: 0
   m_WindowGUID: c2bad47ba94a2bf41ad53eca9bdf5f39
@@ -576,9 +576,9 @@ MonoBehaviour:
   m_PlayAudio: 0
   m_AudioPlay: 0
   m_Position:
-    m_Target: {x: 0, y: 0, z: 0}
+    m_Target: {x: -0.12981132, y: 0.12046242, z: -0.36892748}
     speed: 2
-    m_Value: {x: 0, y: 0, z: 0}
+    m_Value: {x: -0.12981132, y: 0.12046242, z: -0.36892748}
   m_RenderMode: 0
   m_CameraMode:
     drawMode: 0
@@ -625,13 +625,13 @@ MonoBehaviour:
     m_GridAxis: 1
     m_gridOpacity: 0.5
   m_Rotation:
-    m_Target: {x: 0.06991476, y: -0.9164922, z: 0.18387069, w: 0.34842005}
+    m_Target: {x: 0.16596341, y: -0.6515316, z: 0.14911501, w: 0.7251062}
     speed: 2
-    m_Value: {x: 0.06991298, y: -0.91646886, z: 0.183866, w: 0.34841117}
+    m_Value: {x: 0.16595913, y: -0.6515148, z: 0.14911117, w: 0.7250875}
   m_Size:
-    m_Target: 10
+    m_Target: 0.5409923
     speed: 2
-    m_Value: 10
+    m_Value: 0.5409923
   m_Ortho:
     m_Target: 1
     speed: 2
@@ -879,9 +879,9 @@ MonoBehaviour:
   m_Pos:
     serializedVersion: 2
     x: -1649
-    y: 896
+    y: 799
     width: 1255
-    height: 103
+    height: 200
   m_ViewDataDictionary: {fileID: 0}
 --- !u!114 &22
 MonoBehaviour:

BIN
Unity/LineRobot/Library/InspectorExpandedItems.asset


BIN
Unity/LineRobot/Library/SceneVisibilityState.asset


BIN
Unity/LineRobot/Library/ScriptAssemblies/Assembly-CSharp.dll


BIN
Unity/LineRobot/Library/ScriptAssemblies/Assembly-CSharp.pdb


BIN
Unity/LineRobot/Library/ShaderCache/8/86ed30a39d6fe55d6002e29602828535.bin


BIN
Unity/LineRobot/Library/ShaderCache/EditorEncounteredVariants


BIN
Unity/LineRobot/Library/ShaderCache/d/d1a0682cb2dcbc0a869d33b6c25285f4.bin


BIN
Unity/LineRobot/Library/SourceAssetDB


Різницю між файлами не показано, бо вона завелика
+ 1 - 1
Unity/LineRobot/Library/StateCache/SceneView/ed/ed9c0a48af780ce5af524569e3967665.json


+ 30 - 0
Unity/LineRobot/Logs/ApiUpdaterCheck.txt

@@ -268,3 +268,33 @@ C# parse time         : 216ms
 candidates check time : 48ms
 console write time    : 0ms
 
+[api-updater (non-obsolete-error-filter)] 6/24/2022 1:50:33 PM : Starting C:/Program Files/Unity/Hub/Editor/2020.3.36f1/Editor/Data/Tools/ScriptUpdater/APIUpdater.NonObsoleteApiUpdaterDetector.exe
+[api-updater (non-obsolete-error-filter)] 
+----------------------------------
+jit/startup time      : 1062.3602ms
+moved types parse time: 65ms
+candidates parse time : 1ms
+C# parse time         : 855ms
+candidates check time : 58ms
+console write time    : 1ms
+
+[api-updater (non-obsolete-error-filter)] 6/24/2022 2:02:25 PM : Starting C:/Program Files/Unity/Hub/Editor/2020.3.36f1/Editor/Data/Tools/ScriptUpdater/APIUpdater.NonObsoleteApiUpdaterDetector.exe
+[api-updater (non-obsolete-error-filter)] 
+----------------------------------
+jit/startup time      : 95.4531ms
+moved types parse time: 55ms
+candidates parse time : 1ms
+C# parse time         : 194ms
+candidates check time : 31ms
+console write time    : 0ms
+
+[api-updater (non-obsolete-error-filter)] 6/24/2022 2:35:57 PM : Starting C:/Program Files/Unity/Hub/Editor/2020.3.36f1/Editor/Data/Tools/ScriptUpdater/APIUpdater.NonObsoleteApiUpdaterDetector.exe
+[api-updater (non-obsolete-error-filter)] 
+----------------------------------
+jit/startup time      : 89.5303ms
+moved types parse time: 55ms
+candidates parse time : 1ms
+C# parse time         : 210ms
+candidates check time : 47ms
+console write time    : 0ms
+

+ 480 - 0
Unity/LineRobot/Logs/AssetImportWorker0.log

@@ -0,0 +1,480 @@
+Using pre-set license
+Built from 'master' branch; Version is '2020.3.36f1 (71f96b79b9f0) revision 7469419'; Using compiler version '192528614'; Build Type 'Release'
+OS: 'Windows 10  (10.0.19044) 64bit Professional' Language: 'en' Physical Memory: 16238 MB
+BatchMode: 1, IsHumanControllingUs: 0, StartBugReporterOnCrash: 0, Is64bit: 1, IsPro: 0
+
+COMMAND LINE ARGUMENTS:
+C:\Program Files\Unity\Hub\Editor\2020.3.36f1\Editor\Unity.exe
+-adb2
+-batchMode
+-noUpm
+-name
+AssetImportWorker0
+-projectPath
+C:/Users/randy/Documents/git/linerobot/Unity/LineRobot
+-logFile
+Logs/AssetImportWorker0.log
+-srvPort
+61597
+Successfully changed project path to: C:/Users/randy/Documents/git/linerobot/Unity/LineRobot
+C:/Users/randy/Documents/git/linerobot/Unity/LineRobot
+Using Asset Import Pipeline V2.
+Refreshing native plugins compatible for Editor in 374.00 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Initialize engine version: 2020.3.36f1 (71f96b79b9f0)
+[Subsystems] Discovering subsystems at path C:/Program Files/Unity/Hub/Editor/2020.3.36f1/Editor/Data/Resources/UnitySubsystems
+[Subsystems] Discovering subsystems at path C:/Users/randy/Documents/git/linerobot/Unity/LineRobot/Assets
+GfxDevice: creating device client; threaded=0
+Direct3D:
+    Version:  Direct3D 11.0 [level 11.1]
+    Renderer: Intel(R) HD Graphics 620 (ID=0x5916)
+    Vendor:   
+    VRAM:     8119 MB
+    Driver:   30.0.100.9865
+Initialize mono
+Mono path[0] = 'C:/Program Files/Unity/Hub/Editor/2020.3.36f1/Editor/Data/Managed'
+Mono path[1] = 'C:/Program Files/Unity/Hub/Editor/2020.3.36f1/Editor/Data/MonoBleedingEdge/lib/mono/unityjit'
+Mono config path = 'C:/Program Files/Unity/Hub/Editor/2020.3.36f1/Editor/Data/MonoBleedingEdge/etc'
+Using monoOptions --debugger-agent=transport=dt_socket,embedding=1,server=y,suspend=n,address=127.0.0.1:56644
+Begin MonoManager ReloadAssembly
+Registering precompiled unity dll's ...
+Register platform support module: C:/Program Files/Unity/Hub/Editor/2020.3.36f1/Editor/Data/PlaybackEngines/WindowsStandaloneSupport/UnityEditor.WindowsStandalone.Extensions.dll
+Registered in 0.002734 seconds.
+Native extension for WindowsStandalone target not found
+Refreshing native plugins compatible for Editor in 71.60 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Mono: successfully reloaded assembly
+- Completed reload, in  1.213 seconds
+Domain Reload Profiling:
+	ReloadAssembly (1213ms)
+		BeginReloadAssembly (85ms)
+			ExecutionOrderSort (0ms)
+			DisableScriptedObjects (0ms)
+			BackupInstance (0ms)
+			ReleaseScriptingObjects (0ms)
+			CreateAndSetChildDomain (1ms)
+		EndReloadAssembly (828ms)
+			LoadAssemblies (82ms)
+			RebuildTransferFunctionScriptingTraits (0ms)
+			SetupTypeCache (392ms)
+			ReleaseScriptCaches (0ms)
+			RebuildScriptCaches (32ms)
+			SetupLoadedEditorAssemblies (224ms)
+				LogAssemblyErrors (0ms)
+				InitializePlatformSupportModulesInManaged (4ms)
+				SetLoadedEditorAssemblies (0ms)
+				RefreshPlugins (72ms)
+				BeforeProcessingInitializeOnLoad (10ms)
+				ProcessInitializeOnLoadAttributes (95ms)
+				ProcessInitializeOnLoadMethodAttributes (43ms)
+				AfterProcessingInitializeOnLoad (0ms)
+				EditorAssembliesLoaded (0ms)
+			ExecutionOrderSort2 (0ms)
+			AwakeInstancesAfterBackupRestoration (0ms)
+Platform modules already initialized, skipping
+Registering precompiled user dll's ...
+Registered in 0.157265 seconds.
+Begin MonoManager ReloadAssembly
+Native extension for WindowsStandalone target not found
+Refreshing native plugins compatible for Editor in 9.79 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Mono: successfully reloaded assembly
+- Completed reload, in  1.423 seconds
+Domain Reload Profiling:
+	ReloadAssembly (1424ms)
+		BeginReloadAssembly (188ms)
+			ExecutionOrderSort (0ms)
+			DisableScriptedObjects (5ms)
+			BackupInstance (0ms)
+			ReleaseScriptingObjects (0ms)
+			CreateAndSetChildDomain (22ms)
+		EndReloadAssembly (1165ms)
+			LoadAssemblies (127ms)
+			RebuildTransferFunctionScriptingTraits (0ms)
+			SetupTypeCache (426ms)
+			ReleaseScriptCaches (0ms)
+			RebuildScriptCaches (48ms)
+			SetupLoadedEditorAssemblies (436ms)
+				LogAssemblyErrors (0ms)
+				InitializePlatformSupportModulesInManaged (5ms)
+				SetLoadedEditorAssemblies (1ms)
+				RefreshPlugins (10ms)
+				BeforeProcessingInitializeOnLoad (70ms)
+				ProcessInitializeOnLoadAttributes (325ms)
+				ProcessInitializeOnLoadMethodAttributes (17ms)
+				AfterProcessingInitializeOnLoad (8ms)
+				EditorAssembliesLoaded (0ms)
+			ExecutionOrderSort2 (0ms)
+			AwakeInstancesAfterBackupRestoration (2ms)
+Platform modules already initialized, skipping
+========================================================================
+Worker process is ready to serve import requests
+Launched and connected shader compiler UnityShaderCompiler.exe after 0.14 seconds
+Refreshing native plugins compatible for Editor in 9.95 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Unloading 2266 Unused Serialized files (Serialized files now loaded: 0)
+System memory in use before: 184.4 MB.
+System memory in use after: 184.5 MB.
+
+Unloading 719 unused Assets to reduce memory usage. Loaded Objects now: 2020.
+Total: 4.666600 ms (FindLiveObjects: 0.248300 ms CreateObjectMapping: 0.127200 ms MarkObjects: 3.865200 ms  DeleteObjects: 0.424700 ms)
+
+AssetImportParameters requested are different than current active one (requested -> active):
+  custom:framework-win-MediaFoundation: 216162199b28c13a410421893ffa2e32 -> 
+  custom:video-decoder-ogg-theora: a1e56fd34408186e4bbccfd4996cb3dc -> 
+  custom:container-muxer-webm: aa71ff27fc2769a1b78a27578f13a17b -> 
+  custom:container-demuxer-webm: 4f35f7cbe854078d1ac9338744f61a02 -> 
+  custom:container-demuxer-ogg: 62fdf1f143b41e24485cea50d1cbac27 -> 
+  custom:video-encoder-webm-vp8: eb34c28f22e8b96e1ab97ce403110664 -> 
+  custom:video-codec-MediaFoundation-h265: 746d11721c4dcdbdad8f713fa42b33f4 -> 
+  custom:video-decoder-webm-vp8: 9c59270c3fd7afecdb556c50c9e8de78 -> 
+  custom:audio-decoder-ogg-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+  custom:audio-encoder-webm-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+========================================================================
+Received Import Request.
+  path: Assets/PhysicMaterialRotatingBall.physicMaterial
+  artifactKey: Guid(7f679d79de4252b4e889b26928d1428c) Importer(815301076,1909f56bfc062723c751e8b465ee728b)
+Start importing Assets/PhysicMaterialRotatingBall.physicMaterial using Guid(7f679d79de4252b4e889b26928d1428c) Importer(815301076,1909f56bfc062723c751e8b465ee728b)  -> (artifact id: 'fe7c8a46022fee755aaf5d739b083827') in 0.058683 seconds 
+========================================================================
+Received Prepare
+Registering precompiled user dll's ...
+Registered in 0.329497 seconds.
+Begin MonoManager ReloadAssembly
+Native extension for WindowsStandalone target not found
+Refreshing native plugins compatible for Editor in 25.80 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Mono: successfully reloaded assembly
+- Completed reload, in  2.596 seconds
+Domain Reload Profiling:
+	ReloadAssembly (2597ms)
+		BeginReloadAssembly (280ms)
+			ExecutionOrderSort (0ms)
+			DisableScriptedObjects (15ms)
+			BackupInstance (0ms)
+			ReleaseScriptingObjects (0ms)
+			CreateAndSetChildDomain (72ms)
+		EndReloadAssembly (2180ms)
+			LoadAssemblies (256ms)
+			RebuildTransferFunctionScriptingTraits (0ms)
+			SetupTypeCache (926ms)
+			ReleaseScriptCaches (2ms)
+			RebuildScriptCaches (102ms)
+			SetupLoadedEditorAssemblies (643ms)
+				LogAssemblyErrors (0ms)
+				InitializePlatformSupportModulesInManaged (9ms)
+				SetLoadedEditorAssemblies (1ms)
+				RefreshPlugins (26ms)
+				BeforeProcessingInitializeOnLoad (139ms)
+				ProcessInitializeOnLoadAttributes (435ms)
+				ProcessInitializeOnLoadMethodAttributes (23ms)
+				AfterProcessingInitializeOnLoad (11ms)
+				EditorAssembliesLoaded (0ms)
+			ExecutionOrderSort2 (0ms)
+			AwakeInstancesAfterBackupRestoration (10ms)
+Platform modules already initialized, skipping
+Refreshing native plugins compatible for Editor in 23.17 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Unloading 2247 Unused Serialized files (Serialized files now loaded: 0)
+System memory in use before: 183.0 MB.
+System memory in use after: 183.2 MB.
+
+Unloading 714 unused Assets to reduce memory usage. Loaded Objects now: 2023.
+Total: 5.146000 ms (FindLiveObjects: 0.543100 ms CreateObjectMapping: 0.283300 ms MarkObjects: 4.052100 ms  DeleteObjects: 0.265500 ms)
+
+AssetImportParameters requested are different than current active one (requested -> active):
+  custom:framework-win-MediaFoundation: 216162199b28c13a410421893ffa2e32 -> 
+  custom:video-decoder-ogg-theora: a1e56fd34408186e4bbccfd4996cb3dc -> 
+  custom:container-muxer-webm: aa71ff27fc2769a1b78a27578f13a17b -> 
+  custom:container-demuxer-webm: 4f35f7cbe854078d1ac9338744f61a02 -> 
+  custom:container-demuxer-ogg: 62fdf1f143b41e24485cea50d1cbac27 -> 
+  custom:video-encoder-webm-vp8: eb34c28f22e8b96e1ab97ce403110664 -> 
+  custom:video-codec-MediaFoundation-h265: 746d11721c4dcdbdad8f713fa42b33f4 -> 
+  custom:video-decoder-webm-vp8: 9c59270c3fd7afecdb556c50c9e8de78 -> 
+  custom:audio-decoder-ogg-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+  custom:audio-encoder-webm-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+========================================================================
+Received Prepare
+Registering precompiled user dll's ...
+Registered in 0.204838 seconds.
+Begin MonoManager ReloadAssembly
+Native extension for WindowsStandalone target not found
+Refreshing native plugins compatible for Editor in 9.63 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Mono: successfully reloaded assembly
+- Completed reload, in  1.229 seconds
+Domain Reload Profiling:
+	ReloadAssembly (1229ms)
+		BeginReloadAssembly (136ms)
+			ExecutionOrderSort (0ms)
+			DisableScriptedObjects (5ms)
+			BackupInstance (0ms)
+			ReleaseScriptingObjects (0ms)
+			CreateAndSetChildDomain (42ms)
+		EndReloadAssembly (1012ms)
+			LoadAssemblies (125ms)
+			RebuildTransferFunctionScriptingTraits (0ms)
+			SetupTypeCache (400ms)
+			ReleaseScriptCaches (1ms)
+			RebuildScriptCaches (44ms)
+			SetupLoadedEditorAssemblies (314ms)
+				LogAssemblyErrors (0ms)
+				InitializePlatformSupportModulesInManaged (5ms)
+				SetLoadedEditorAssemblies (1ms)
+				RefreshPlugins (10ms)
+				BeforeProcessingInitializeOnLoad (61ms)
+				ProcessInitializeOnLoadAttributes (215ms)
+				ProcessInitializeOnLoadMethodAttributes (15ms)
+				AfterProcessingInitializeOnLoad (7ms)
+				EditorAssembliesLoaded (0ms)
+			ExecutionOrderSort2 (0ms)
+			AwakeInstancesAfterBackupRestoration (2ms)
+Platform modules already initialized, skipping
+Refreshing native plugins compatible for Editor in 9.96 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Unloading 2247 Unused Serialized files (Serialized files now loaded: 0)
+System memory in use before: 183.1 MB.
+System memory in use after: 183.2 MB.
+
+Unloading 714 unused Assets to reduce memory usage. Loaded Objects now: 2026.
+Total: 3.380400 ms (FindLiveObjects: 0.236600 ms CreateObjectMapping: 0.098100 ms MarkObjects: 2.864200 ms  DeleteObjects: 0.178500 ms)
+
+AssetImportParameters requested are different than current active one (requested -> active):
+  custom:framework-win-MediaFoundation: 216162199b28c13a410421893ffa2e32 -> 
+  custom:video-decoder-ogg-theora: a1e56fd34408186e4bbccfd4996cb3dc -> 
+  custom:container-muxer-webm: aa71ff27fc2769a1b78a27578f13a17b -> 
+  custom:container-demuxer-webm: 4f35f7cbe854078d1ac9338744f61a02 -> 
+  custom:container-demuxer-ogg: 62fdf1f143b41e24485cea50d1cbac27 -> 
+  custom:video-encoder-webm-vp8: eb34c28f22e8b96e1ab97ce403110664 -> 
+  custom:video-codec-MediaFoundation-h265: 746d11721c4dcdbdad8f713fa42b33f4 -> 
+  custom:video-decoder-webm-vp8: 9c59270c3fd7afecdb556c50c9e8de78 -> 
+  custom:audio-decoder-ogg-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+  custom:audio-encoder-webm-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+========================================================================
+Received Prepare
+Registering precompiled user dll's ...
+Registered in 0.174676 seconds.
+Begin MonoManager ReloadAssembly
+Native extension for WindowsStandalone target not found
+Refreshing native plugins compatible for Editor in 10.79 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Mono: successfully reloaded assembly
+- Completed reload, in  1.228 seconds
+Domain Reload Profiling:
+	ReloadAssembly (1229ms)
+		BeginReloadAssembly (145ms)
+			ExecutionOrderSort (0ms)
+			DisableScriptedObjects (5ms)
+			BackupInstance (0ms)
+			ReleaseScriptingObjects (0ms)
+			CreateAndSetChildDomain (43ms)
+		EndReloadAssembly (1013ms)
+			LoadAssemblies (127ms)
+			RebuildTransferFunctionScriptingTraits (0ms)
+			SetupTypeCache (397ms)
+			ReleaseScriptCaches (1ms)
+			RebuildScriptCaches (51ms)
+			SetupLoadedEditorAssemblies (312ms)
+				LogAssemblyErrors (0ms)
+				InitializePlatformSupportModulesInManaged (5ms)
+				SetLoadedEditorAssemblies (1ms)
+				RefreshPlugins (11ms)
+				BeforeProcessingInitializeOnLoad (62ms)
+				ProcessInitializeOnLoadAttributes (210ms)
+				ProcessInitializeOnLoadMethodAttributes (15ms)
+				AfterProcessingInitializeOnLoad (8ms)
+				EditorAssembliesLoaded (0ms)
+			ExecutionOrderSort2 (0ms)
+			AwakeInstancesAfterBackupRestoration (2ms)
+Platform modules already initialized, skipping
+Refreshing native plugins compatible for Editor in 11.29 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Unloading 2247 Unused Serialized files (Serialized files now loaded: 0)
+System memory in use before: 183.1 MB.
+System memory in use after: 183.2 MB.
+
+Unloading 714 unused Assets to reduce memory usage. Loaded Objects now: 2029.
+Total: 3.273600 ms (FindLiveObjects: 0.260000 ms CreateObjectMapping: 0.117600 ms MarkObjects: 2.732200 ms  DeleteObjects: 0.162700 ms)
+
+AssetImportParameters requested are different than current active one (requested -> active):
+  custom:framework-win-MediaFoundation: 216162199b28c13a410421893ffa2e32 -> 
+  custom:video-decoder-ogg-theora: a1e56fd34408186e4bbccfd4996cb3dc -> 
+  custom:container-muxer-webm: aa71ff27fc2769a1b78a27578f13a17b -> 
+  custom:container-demuxer-webm: 4f35f7cbe854078d1ac9338744f61a02 -> 
+  custom:container-demuxer-ogg: 62fdf1f143b41e24485cea50d1cbac27 -> 
+  custom:video-encoder-webm-vp8: eb34c28f22e8b96e1ab97ce403110664 -> 
+  custom:video-codec-MediaFoundation-h265: 746d11721c4dcdbdad8f713fa42b33f4 -> 
+  custom:video-decoder-webm-vp8: 9c59270c3fd7afecdb556c50c9e8de78 -> 
+  custom:audio-decoder-ogg-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+  custom:audio-encoder-webm-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+========================================================================
+Received Prepare
+Registering precompiled user dll's ...
+Registered in 0.258342 seconds.
+Begin MonoManager ReloadAssembly
+Native extension for WindowsStandalone target not found
+Refreshing native plugins compatible for Editor in 14.06 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Mono: successfully reloaded assembly
+- Completed reload, in  2.875 seconds
+Domain Reload Profiling:
+	ReloadAssembly (2876ms)
+		BeginReloadAssembly (244ms)
+			ExecutionOrderSort (0ms)
+			DisableScriptedObjects (10ms)
+			BackupInstance (0ms)
+			ReleaseScriptingObjects (0ms)
+			CreateAndSetChildDomain (74ms)
+		EndReloadAssembly (2512ms)
+			LoadAssemblies (242ms)
+			RebuildTransferFunctionScriptingTraits (0ms)
+			SetupTypeCache (731ms)
+			ReleaseScriptCaches (1ms)
+			RebuildScriptCaches (89ms)
+			SetupLoadedEditorAssemblies (610ms)
+				LogAssemblyErrors (0ms)
+				InitializePlatformSupportModulesInManaged (7ms)
+				SetLoadedEditorAssemblies (1ms)
+				RefreshPlugins (14ms)
+				BeforeProcessingInitializeOnLoad (132ms)
+				ProcessInitializeOnLoadAttributes (416ms)
+				ProcessInitializeOnLoadMethodAttributes (30ms)
+				AfterProcessingInitializeOnLoad (10ms)
+				EditorAssembliesLoaded (0ms)
+			ExecutionOrderSort2 (0ms)
+			AwakeInstancesAfterBackupRestoration (4ms)
+Platform modules already initialized, skipping
+Refreshing native plugins compatible for Editor in 20.43 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Unloading 2247 Unused Serialized files (Serialized files now loaded: 0)
+System memory in use before: 183.1 MB.
+System memory in use after: 183.3 MB.
+
+Unloading 714 unused Assets to reduce memory usage. Loaded Objects now: 2032.
+Total: 8.910700 ms (FindLiveObjects: 0.557900 ms CreateObjectMapping: 0.372200 ms MarkObjects: 7.520300 ms  DeleteObjects: 0.458100 ms)
+
+AssetImportParameters requested are different than current active one (requested -> active):
+  custom:framework-win-MediaFoundation: 216162199b28c13a410421893ffa2e32 -> 
+  custom:video-decoder-ogg-theora: a1e56fd34408186e4bbccfd4996cb3dc -> 
+  custom:container-muxer-webm: aa71ff27fc2769a1b78a27578f13a17b -> 
+  custom:container-demuxer-webm: 4f35f7cbe854078d1ac9338744f61a02 -> 
+  custom:container-demuxer-ogg: 62fdf1f143b41e24485cea50d1cbac27 -> 
+  custom:video-encoder-webm-vp8: eb34c28f22e8b96e1ab97ce403110664 -> 
+  custom:video-codec-MediaFoundation-h265: 746d11721c4dcdbdad8f713fa42b33f4 -> 
+  custom:video-decoder-webm-vp8: 9c59270c3fd7afecdb556c50c9e8de78 -> 
+  custom:audio-decoder-ogg-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+  custom:audio-encoder-webm-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+========================================================================
+Received Prepare
+Registering precompiled user dll's ...
+Registered in 0.428450 seconds.
+Begin MonoManager ReloadAssembly
+Native extension for WindowsStandalone target not found
+Refreshing native plugins compatible for Editor in 17.78 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Mono: successfully reloaded assembly
+- Completed reload, in  3.242 seconds
+Domain Reload Profiling:
+	ReloadAssembly (3243ms)
+		BeginReloadAssembly (347ms)
+			ExecutionOrderSort (0ms)
+			DisableScriptedObjects (10ms)
+			BackupInstance (0ms)
+			ReleaseScriptingObjects (0ms)
+			CreateAndSetChildDomain (97ms)
+		EndReloadAssembly (2691ms)
+			LoadAssemblies (325ms)
+			RebuildTransferFunctionScriptingTraits (0ms)
+			SetupTypeCache (1041ms)
+			ReleaseScriptCaches (2ms)
+			RebuildScriptCaches (129ms)
+			SetupLoadedEditorAssemblies (872ms)
+				LogAssemblyErrors (0ms)
+				InitializePlatformSupportModulesInManaged (13ms)
+				SetLoadedEditorAssemblies (2ms)
+				RefreshPlugins (18ms)
+				BeforeProcessingInitializeOnLoad (140ms)
+				ProcessInitializeOnLoadAttributes (640ms)
+				ProcessInitializeOnLoadMethodAttributes (37ms)
+				AfterProcessingInitializeOnLoad (20ms)
+				EditorAssembliesLoaded (1ms)
+			ExecutionOrderSort2 (0ms)
+			AwakeInstancesAfterBackupRestoration (6ms)
+Platform modules already initialized, skipping
+Refreshing native plugins compatible for Editor in 14.60 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Unloading 2247 Unused Serialized files (Serialized files now loaded: 0)
+System memory in use before: 183.1 MB.
+System memory in use after: 183.3 MB.
+
+Unloading 714 unused Assets to reduce memory usage. Loaded Objects now: 2035.
+Total: 4.118200 ms (FindLiveObjects: 0.283500 ms CreateObjectMapping: 0.166800 ms MarkObjects: 3.373400 ms  DeleteObjects: 0.292500 ms)
+
+AssetImportParameters requested are different than current active one (requested -> active):
+  custom:framework-win-MediaFoundation: 216162199b28c13a410421893ffa2e32 -> 
+  custom:video-decoder-ogg-theora: a1e56fd34408186e4bbccfd4996cb3dc -> 
+  custom:container-muxer-webm: aa71ff27fc2769a1b78a27578f13a17b -> 
+  custom:container-demuxer-webm: 4f35f7cbe854078d1ac9338744f61a02 -> 
+  custom:container-demuxer-ogg: 62fdf1f143b41e24485cea50d1cbac27 -> 
+  custom:video-encoder-webm-vp8: eb34c28f22e8b96e1ab97ce403110664 -> 
+  custom:video-codec-MediaFoundation-h265: 746d11721c4dcdbdad8f713fa42b33f4 -> 
+  custom:video-decoder-webm-vp8: 9c59270c3fd7afecdb556c50c9e8de78 -> 
+  custom:audio-decoder-ogg-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+  custom:audio-encoder-webm-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+========================================================================
+Received Prepare
+Registering precompiled user dll's ...
+Registered in 0.294934 seconds.
+Begin MonoManager ReloadAssembly
+Native extension for WindowsStandalone target not found
+Refreshing native plugins compatible for Editor in 19.76 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Mono: successfully reloaded assembly
+- Completed reload, in  3.193 seconds
+Domain Reload Profiling:
+	ReloadAssembly (3198ms)
+		BeginReloadAssembly (597ms)
+			ExecutionOrderSort (0ms)
+			DisableScriptedObjects (51ms)
+			BackupInstance (0ms)
+			ReleaseScriptingObjects (0ms)
+			CreateAndSetChildDomain (251ms)
+		EndReloadAssembly (2436ms)
+			LoadAssemblies (345ms)
+			RebuildTransferFunctionScriptingTraits (0ms)
+			SetupTypeCache (1143ms)
+			ReleaseScriptCaches (5ms)
+			RebuildScriptCaches (95ms)
+			SetupLoadedEditorAssemblies (596ms)
+				LogAssemblyErrors (0ms)
+				InitializePlatformSupportModulesInManaged (10ms)
+				SetLoadedEditorAssemblies (1ms)
+				RefreshPlugins (20ms)
+				BeforeProcessingInitializeOnLoad (120ms)
+				ProcessInitializeOnLoadAttributes (396ms)
+				ProcessInitializeOnLoadMethodAttributes (34ms)
+				AfterProcessingInitializeOnLoad (15ms)
+				EditorAssembliesLoaded (0ms)
+			ExecutionOrderSort2 (0ms)
+			AwakeInstancesAfterBackupRestoration (3ms)
+Platform modules already initialized, skipping
+Refreshing native plugins compatible for Editor in 38.93 ms, found 675 plugins.
+Preloading 0 native plugins for Editor in 0.00 ms.
+Unloading 2247 Unused Serialized files (Serialized files now loaded: 0)
+System memory in use before: 183.1 MB.
+System memory in use after: 183.3 MB.
+
+Unloading 714 unused Assets to reduce memory usage. Loaded Objects now: 2038.
+Total: 13.223600 ms (FindLiveObjects: 2.845200 ms CreateObjectMapping: 0.561700 ms MarkObjects: 9.193000 ms  DeleteObjects: 0.616300 ms)
+
+AssetImportParameters requested are different than current active one (requested -> active):
+  custom:framework-win-MediaFoundation: 216162199b28c13a410421893ffa2e32 -> 
+  custom:video-decoder-ogg-theora: a1e56fd34408186e4bbccfd4996cb3dc -> 
+  custom:container-muxer-webm: aa71ff27fc2769a1b78a27578f13a17b -> 
+  custom:container-demuxer-webm: 4f35f7cbe854078d1ac9338744f61a02 -> 
+  custom:container-demuxer-ogg: 62fdf1f143b41e24485cea50d1cbac27 -> 
+  custom:video-encoder-webm-vp8: eb34c28f22e8b96e1ab97ce403110664 -> 
+  custom:video-codec-MediaFoundation-h265: 746d11721c4dcdbdad8f713fa42b33f4 -> 
+  custom:video-decoder-webm-vp8: 9c59270c3fd7afecdb556c50c9e8de78 -> 
+  custom:audio-decoder-ogg-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+  custom:audio-encoder-webm-vorbis: bf7c407c2cedff20999df2af8eb42d56 -> 
+AssetImportWorkerClient::OnTransportError - code=2 error=End of file

+ 6 - 0
Unity/LineRobot/Logs/shadercompiler-AssetImportWorker0.log

@@ -0,0 +1,6 @@
+Base path: 'C:/Program Files/Unity/Hub/Editor/2020.3.36f1/Editor/Data', plugins path 'C:/Program Files/Unity/Hub/Editor/2020.3.36f1/Editor/Data/PlaybackEngines'
+Cmd: initializeCompiler
+
+Unhandled exception: Protocol error - failed to read magic number (error -2147483644, transferred 0/4)
+
+Quitting shader compiler process

Різницю між файлами не показано, бо вона завелика
+ 6 - 0
Unity/LineRobot/Logs/shadercompiler-UnityShaderCompiler.exe0.log


+ 7 - 4
Unity/LineRobot/ProjectSettings/DynamicsManager.asset

@@ -3,11 +3,12 @@
 --- !u!55 &1
 PhysicsManager:
   m_ObjectHideFlags: 0
-  serializedVersion: 11
+  serializedVersion: 13
   m_Gravity: {x: 0, y: -9.81, z: 0}
   m_DefaultMaterial: {fileID: 0}
-  m_BounceThreshold: 2
-  m_SleepThreshold: 0.005
+  m_BounceThreshold: 10
+  m_DefaultMaxDepenetrationVelocity: 50
+  m_SleepThreshold: 0.01
   m_DefaultContactOffset: 0.01
   m_DefaultSolverIterations: 6
   m_DefaultSolverVelocityIterations: 1
@@ -22,6 +23,7 @@ PhysicsManager:
   m_AutoSyncTransforms: 0
   m_ReuseCollisionCallbacks: 1
   m_ClothInterCollisionSettingsToggle: 0
+  m_ClothGravity: {x: 0, y: -9.81, z: 0}
   m_ContactPairsMode: 0
   m_BroadphaseType: 0
   m_WorldBounds:
@@ -31,4 +33,5 @@ PhysicsManager:
   m_FrictionType: 0
   m_EnableEnhancedDeterminism: 0
   m_EnableUnifiedHeightmaps: 1
-  m_DefaultMaxAngluarSpeed: 7
+  m_SolverType: 0
+  m_DefaultMaxAngularSpeed: 7

+ 0 - 8
dashboard/.idea/.gitignore

@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml

+ 0 - 8
dashboard/.idea/dashboard.iml

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="PYTHON_MODULE" version="4">
-  <component name="NewModuleRootManager">
-    <content url="file://$MODULE_DIR$" />
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>

+ 0 - 34
dashboard/.idea/inspectionProfiles/Project_Default.xml

@@ -1,34 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <profile version="1.0">
-    <option name="myName" value="Project Default" />
-    <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
-      <option name="ignoredPackages">
-        <value>
-          <list size="3">
-            <item index="0" class="java.lang.String" itemvalue="tqdm" />
-            <item index="1" class="java.lang.String" itemvalue="matplotlib" />
-            <item index="2" class="java.lang.String" itemvalue="bokeh" />
-          </list>
-        </value>
-      </option>
-    </inspection_tool>
-    <inspection_tool class="PyPep8Inspection" enabled="false" level="WEAK WARNING" enabled_by_default="false">
-      <option name="ignoredErrors">
-        <list>
-          <option value="E128" />
-          <option value="E701" />
-          <option value="E101" />
-        </list>
-      </option>
-    </inspection_tool>
-    <inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
-      <option name="ignoredErrors">
-        <list>
-          <option value="N802" />
-          <option value="N806" />
-          <option value="N803" />
-        </list>
-      </option>
-    </inspection_tool>
-  </profile>
-</component>

+ 0 - 6
dashboard/.idea/inspectionProfiles/profiles_settings.xml

@@ -1,6 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <settings>
-    <option name="USE_PROJECT_PROFILE" value="false" />
-    <version value="1.0" />
-  </settings>
-</component>

+ 0 - 4
dashboard/.idea/misc.xml

@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
-</project>

+ 0 - 8
dashboard/.idea/modules.xml

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/.idea/dashboard.iml" filepath="$PROJECT_DIR$/.idea/dashboard.iml" />
-    </modules>
-  </component>
-</project>

+ 0 - 6
dashboard/.idea/other.xml

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="PySciProjectComponent">
-    <option name="PY_SCI_VIEW_SUGGESTED" value="true" />
-  </component>
-</project>

+ 0 - 6
dashboard/.idea/vcs.xml

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
-  </component>
-</project>

+ 28 - 2
dashboard/README.md

@@ -7,7 +7,7 @@ Digital Shadow (DS).
 It is important that `ROS2` is enabled in the environment that
 runs the main code. This will also enable the `rclpy` module.
 
-## Properties
+### Properties
 This dashboard does the following things:
 
 1. It reads a depth image from ROS2 and displays it using the 
@@ -17,4 +17,30 @@ This dashboard does the following things:
    to another ROS2 connection.
 3. The sensor data is read and visualized in a history plot.
 4. The robot states (both the system under study and the model)
-   are read from ROS2 and visualized in the plot (if they exist).
+   are read from ROS2 and visualized in the plot (if they exist).
+
+### How to Compile
+For the dashboard to work, it is required that the `lfr_msgs`
+package for ROS2 communication is compiled. This package is
+located inside the `ros2` folder. In order to compile, execute
+the following steps.
+
+1. Open a clean environment (i.e., terminal, powershell...). For
+   _Windows_, this must be a _Visual Studio Command Prompt_ to
+   allow  for compilation.
+2. Make sure ROS2 is enabled by sourcing the global `setup` or
+   `local_setup` script. This is presumably located in the
+   `/opt/` folder.
+3. Execute one of the following commands in the `ros2` folder
+   (choose which one applies):
+   <br/>**Windows:** `colcon build --merge-install --packages-select lfr_msgs`
+   <br/>**Linux/Mac OS:** `colcon build --packages-select lfr_msgs`
+
+### How to Run
+1. Open a clean environment (i.e., terminal, powershell...).
+   This may be the same environment as used for the compilation.
+2. Enable ROS2 (and the `lfr_msgs` package) by sourcing the
+   `setup` or `local_setup` script from `ros2/install`.
+   _You may need to compile this package in the `ros2` directory
+   first (see above)._
+3. Launch the `main.py` script from the environment.

+ 71 - 22
dashboard/main.py

@@ -15,6 +15,7 @@ try:
 	from rclpy.node import Node
 	import std_msgs.msg
 	import sensor_msgs.msg
+	import lfr_msgs.msg
 	import threading
 
 	_ROS2_FOUND = True
@@ -33,9 +34,15 @@ class Dashboard:
 		self.DEPTH_SIZE = 300
 		self.PLOT_SIZE = 600
 		self.REDSENSOR_HISTORY = 100
+		self.INTEGRATION_INTERVAL = 400  # ms
 
-		self.data = {
-			"redsensor": []
+		self.__finished = False
+
+		self.state = {
+			"redsensor": [],
+			"handbrake": True,
+			"sys_history": [],
+			"sim_history": [],
 		}
 
 		# Show the depth image
@@ -69,13 +76,20 @@ class Dashboard:
 		self.colfig_canvas = FigureCanvasTkAgg(self.colfig, master=self.right)
 		self.colfig_canvas.draw()
 		self.colfig_canvas.get_tk_widget().pack(side="top", padx=5, pady=2)
+		self.brake_button = tk.Button(self.right, text="Toggle Handbrake Off", command=self.toggle_brake)
+		self.brake_button.pack(side="top", fill="x", padx=5, pady=2)
 
 		# Create the drawing canvas
 		self.canvas = tk.Canvas(self.viewpanel, width=self.PLOT_SIZE, height=self.PLOT_SIZE)
-		# self.canvas = FigureCanvasTkAgg(fig, master=self.root)  # A Tk DrawingArea
-		# self.canvas.draw()
-		# self.canvas.get_tk_widget().grid(column=1, row=1)
-		self.canvas.pack(side="top", fill="both", expand="yes")
+		self.fig = plt.figure(figsize=(5, 5), dpi=100)
+		self.fig_ax = self.fig.add_subplot(111)
+		self.fig_ax.set_xlim((0.2, 0.9))
+		self.fig_ax.set_ylim((0.1, 0.8))
+		self.fig_sys_line, = self.fig_ax.plot([], [], c="red", marker='.', alpha=.5)
+		self.fig_sim_line, = self.fig_ax.plot([], [], c="blue", marker='.', alpha=.5)
+		self.canvas = FigureCanvasTkAgg(self.fig, master=self.viewpanel)
+		self.canvas.draw()
+		self.canvas.get_tk_widget().pack(side="top", fill="both", expand="yes")
 
 		self.viewpanel.pack(side="left", fill="both", expand="yes")
 		self.right.pack(side="right", fill="both", expand="no")
@@ -84,38 +98,64 @@ class Dashboard:
 
 		# ROS2
 		if _ROS2_FOUND:
-			rclpy.init()
-
 			self.node = Node("dashboardLFR")
+			self.state_publisher = self.node.create_publisher(lfr_msgs.msg.State, "lfr/state_sys", 10)
+			self.brake_publisher = self.node.create_publisher(std_msgs.msg.Bool, "lfr/handbrake", 10)
 			self.create_listeners()
 			self.spinner = threading.Thread(target=lambda: rclpy.spin(self.node), daemon=True)
 			self.spinner.start()
 
+	def done(self):
+		return self.__finished
 
 	def on_close(self):
+		self.__finished = True
 		if _ROS2_FOUND:
-			rclpy.shutdown()
-			self.root.quit()
+			self.node.destroy_node()
 			self.spinner.join(1)
+			self.root.quit()
 		else:
 			self.root.quit()
 
 	def create_listeners(self):
-		self.node.create_subscription(sensor_msgs.msg.Image, "rt/depth_processor", self.update_depthimage, 10)
-		self.node.create_subscription(sensor_msgs.msg.Image, "rt/depth_processor", self.update_processimage, 10)
-		self.node.create_subscription(std_msgs.msg.Float32, "rt/redsensor", self.update_redsensor, 10)
-		self.colfig_ani = animation.FuncAnimation(self.colfig, lambda _: self.update_redsensor_plot(), interval=100)
+		self.node.create_subscription(sensor_msgs.msg.Image, "lfr/depth_processor", self.update_depthimage, 10)
+		self.node.create_subscription(sensor_msgs.msg.Image, "lfr/depth_processor", self.update_processimage, 10)
+		self.node.create_subscription(std_msgs.msg.Float32, "lfr/redsensor", self.update_redsensor, 10)
+		self.node.create_subscription(lfr_msgs.msg.State, "lfr/state_sys", self.update_system, 10)
+		self.node.create_subscription(std_msgs.msg.Bool, "lfr/handbrake", self.update_handbrake, 10)
+		self.colfig_ani = animation.FuncAnimation(self.colfig, lambda _: self.update_redsensor_plot(), interval=self.INTEGRATION_INTERVAL)
+		self.fig_ani = animation.FuncAnimation(self.fig, lambda _: self.update_plot(), interval=self.INTEGRATION_INTERVAL)
 
 	def update_redsensor(self, msg):
-		self.data["redsensor"].append(msg.data)
+		self.state["redsensor"].append(msg.data)
 		self.colvalue_label.config(text="Sensor Value: %.5f" % msg.data)
 
+	def update_system(self, msg):
+		state = msg.x, msg.y, msg.w
+		self.state["sys_history"].append(state)
+
+	def update_handbrake(self, msg):
+		self.state["handbrake"] = msg.data
+		self.brake_button.config(text="Toggle Handbrake %s" % ("Off" if msg.data else "On"))
+
+	def toggle_brake(self):
+		if _ROS2_FOUND and rclpy.ok():
+			msg = std_msgs.msg.Bool()
+			msg.data = not self.state["handbrake"]
+			self.brake_publisher.publish(msg)
+
 	def update_redsensor_plot(self):
-		while len(self.data["redsensor"]) > self.REDSENSOR_HISTORY:
-			self.data["redsensor"].pop(0)
-		data = self.data["redsensor"][:]
+		while len(self.state["redsensor"]) > self.REDSENSOR_HISTORY:
+			self.state["redsensor"].pop(0)
+		data = self.state["redsensor"][:]
 		self.colfig_line.set_data(list(range(len(data))), data)
 
+	def update_plot(self):
+		system = self.state["sys_history"][:]
+		xs = [x for x, _, __ in system]
+		ys = [1. - y for _, y, __ in system]
+		self.fig_sys_line.set_data(xs, ys)
+
 	def update_depthimage(self, msg):
 		if self.dit is not None:
 			self.depth_image_canvas.delete(self.dit)
@@ -147,11 +187,20 @@ class Dashboard:
 
 		self.processed_image_canvas.itemconfig(self.pi, image=self.processed_image)
 
-		# TODO: send identified state via ROS2
-		if _ROS2_FOUND:
-			pass
+		# send identified state via ROS2
+		if _ROS2_FOUND and rclpy.ok():
+			q = lfr_msgs.msg.State()
+			q.x = float(state[0])
+			q.y = float(state[1])
+			q.w = float(state[2])
+			self.state_publisher.publish(q)
 
 
 if __name__ == '__main__':
+	rclpy.init()
+
 	app = Dashboard()
-	app.root.mainloop()
+	app.root.mainloop()
+
+	# TODO: somehow this hangs the termination of the program..
+	# rclpy.shutdown()

+ 41 - 0
dashboard/ros2/lfr_msgs/CMakeLists.txt

@@ -0,0 +1,41 @@
+cmake_minimum_required(VERSION 3.5)
+project(lfr_msgs)
+
+# Default to C99
+if(NOT CMAKE_C_STANDARD)
+  set(CMAKE_C_STANDARD 99)
+endif()
+
+# Default to C++14
+if(NOT CMAKE_CXX_STANDARD)
+  set(CMAKE_CXX_STANDARD 14)
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+  add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+# find dependencies
+find_package(ament_cmake REQUIRED)
+# uncomment the following section in order to fill in
+# further dependencies manually.
+# find_package(<dependency> REQUIRED)
+
+find_package(rosidl_default_generators REQUIRED)
+
+rosidl_generate_interfaces(${PROJECT_NAME}
+  "msg/State.msg"
+)
+
+if(BUILD_TESTING)
+  find_package(ament_lint_auto REQUIRED)
+  # the following line skips the linter which checks for copyrights
+  # uncomment the line when a copyright and license is not present in all source files
+  #set(ament_cmake_copyright_FOUND TRUE)
+  # the following line skips cpplint (only works in a git repo)
+  # uncomment the line when this package is not in a git repo
+  #set(ament_cmake_cpplint_FOUND TRUE)
+  ament_lint_auto_find_test_dependencies()
+endif()
+
+ament_package()

+ 11 - 0
dashboard/ros2/lfr_msgs/msg/State.msg

@@ -0,0 +1,11 @@
+# This represents the state of the LFR
+
+# Because the LFR mainly focuses on a top-view, only an (x, y) pair
+# is required for the position. As for the heading, another value, w,
+# will be stored.
+# Note: while this could be done with a simple geometry_msgs.msg.Vector3,
+# the usage of a custom datatype allows for more flexibility and reuse.
+
+float64 x
+float64 y
+float64 w

+ 24 - 0
dashboard/ros2/lfr_msgs/package.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
+<package format="3">
+  <name>lfr_msgs</name>
+  <version>0.0.1</version>
+  <description>A simple set of messages that will be used in the LFR project.</description>
+  <maintainer email="randy.paredis@uantwerpen.be">Randy Paredis</maintainer>
+  <license>MIT</license>
+
+  <buildtool_depend>ament_cmake</buildtool_depend>
+
+  <build_depend>rosidl_default_generators</build_depend>
+
+  <exec_depend>rosidl_default_runtime</exec_depend>
+
+  <member_of_group>rosidl_interface_packages</member_of_group>
+
+  <test_depend>ament_lint_auto</test_depend>
+  <test_depend>ament_lint_common</test_depend>
+
+  <export>
+    <build_type>ament_cmake</build_type>
+  </export>
+</package>

+ 40 - 20
dashboard/vision.py

@@ -6,7 +6,7 @@ CLIPPING_MASK_MAX = 2.0
 CLIPPING_MASK_NEAR = 0.9
 CLIPPING_MASK_FAR = 1.0
 
-EPSILON = 1e-10
+EPSILON = 1e-20
 ARROWLENGTH = 20
 
 # State variables
@@ -65,32 +65,52 @@ def process(image, size):
 			#   small distances can occur due to the object detection
 			pdist = _tuple_distance(ccenter, _prev_pos)
 			if pdist < EPSILON:
-				# You have actually moved
+				# You have not actually moved
 				ccenter = _prev_pos
+			else:
+				# pv is the normalized direction identified in the robot
+				pv = (ccenter[0] - _prev_pos[0]) / pdist, (ccenter[1] - _prev_pos[1]) / pdist
+				heading = np.arctan2(pv[1], pv[0])
 
-			# pv is the normalized direction identified in the robot
-			pv = (ccenter[0] - _prev_pos[0]) / pdist, (ccenter[1] - _prev_pos[1]) / pdist
-			heading = np.arctan2(pv[1], pv[0])
-
-			cv2.arrowedLine(repr_image, ccenter, (ccenter[0] + int(pv[0] * ARROWLENGTH), ccenter[1] + int(pv[1] * ARROWLENGTH)),
-			                (255, 0, 0), 2, tipLength=0.3)
-
-			if _prev_heading is not None:
-				# inconsistencies in the object detection may result in an opposite angle
-				angle_diff = abs(_prev_heading - heading)
-				while angle_diff > np.pi / 2:
-					if heading > _prev_heading:
-						heading -= np.pi
-					else:
-						heading += np.pi
+				cv2.arrowedLine(repr_image, ccenter, (ccenter[0] + int(pv[0] * ARROWLENGTH), ccenter[1] + int(pv[1] * ARROWLENGTH)),
+				                (255, 0, 0), 2, tipLength=0.3)
+
+				if _prev_heading is not None:
+					# inconsistencies in the object detection may result in an opposite angle
 					angle_diff = abs(_prev_heading - heading)
+					while angle_diff > np.pi / 2:
+						if heading > _prev_heading:
+							heading -= np.pi
+						else:
+							heading += np.pi
+						angle_diff = abs(_prev_heading - heading)
 
 		_prev_heading = heading
 		_prev_pos = ccenter
 
-	# TODO: from image coords to world coords (wrt center of camera?)
-	# TODO: field of view transformation!
-	return repr_image, (ccenter[0], ccenter[1], heading)
+	# field of view transformation
+	#   NOTE: the obtained image uses a cone for the distance, it is the
+	#         vertical component instead!
+	mid = int(size / 2), int(size / 2)
+	cd = image[mid[0]][mid[1]][0]
+	try:
+		pd = image[ccenter[0]][ccenter[1]][0]
+		mid_xy = (mid[0] - ccenter[0]) ** 2 + (mid[1] + ccenter[1]) ** 2
+		pd = np.sqrt(mid_xy - pd ** 2)
+	except:
+		pd = 0
+	if pd == 0 or pd > cd:
+		pd = (CLIPPING_MASK_NEAR + CLIPPING_MASK_FAR) / 2
+
+	ratio = 1
+	if cd != 0:
+		ratio = pd / cd
+	ncenter = (np.asarray(ccenter) - np.asarray(mid)) * ratio + np.asarray(mid)
+
+	cv2.circle(repr_image, (int(ncenter[0]), int(ncenter[1])), 4, (255, 100, 0), -1)
+
+	# NOTE: the origin is the top left corner of the image!
+	return repr_image, (ncenter[0] / size, ncenter[1] / size, heading)
 
 
 def _findLargestContour(contours):