PositionCalculator.cs 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using Assets.StreetLight.Interfaces;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using OpenCvSharp;
  5. using System;
  6. using Unity.VisualScripting;
  7. using Assets.StreetLight.Serialization;
  8. using MathNet;
  9. using MathNet.Numerics.LinearAlgebra;
  10. using MathNet.Numerics.LinearAlgebra.Double;
  11. using System.Linq.Expressions;
  12. internal class PositionCalculator : IPositionCalculator
  13. {
  14. // World to Unity Position
  15. private List<Tuple<Vector3, Vector3>> calibrationVectors;
  16. private Matrix<double> lambda;
  17. public PositionCalculator(List<Tuple<Vector3, Vector3>> calibrationVectors)
  18. {
  19. this.calibrationVectors = calibrationVectors;
  20. var cv = calibrationVectors;
  21. Matrix<double> matrixA = DenseMatrix.OfArray(new double[,]
  22. { {cv[0].Item1.x, cv[0].Item1.z, 1, 0, 0, 0, -cv[0].Item2.x*cv[0].Item1.x, -cv[0].Item2.x*cv[0].Item1.z},
  23. {0, 0, 0, cv[0].Item1.x, cv[0].Item1.z, 1, -cv[0].Item2.z*cv[0].Item1.x, -cv[0].Item2.z*cv[0].Item1.z},
  24. {cv[1].Item1.x, cv[1].Item1.z, 1, 0, 0, 0, -cv[1].Item2.x*cv[1].Item1.x, -cv[1].Item2.x*cv[1].Item1.z},
  25. {0, 0, 0, cv[1].Item1.x, cv[1].Item1.z, 1, -cv[1].Item2.z*cv[1].Item1.x, -cv[1].Item2.z*cv[1].Item1.z},
  26. {cv[2].Item1.x, cv[2].Item1.z, 1, 0, 0, 0, -cv[2].Item2.x*cv[2].Item1.x, -cv[2].Item2.x*cv[2].Item1.z},
  27. {0, 0, 0, cv[2].Item1.x, cv[2].Item1.z, 1, -cv[2].Item2.z*cv[2].Item1.x, -cv[2].Item2.z*cv[2].Item1.z},
  28. {cv[3].Item1.x, cv[3].Item1.z, 1, 0, 0, 0, -cv[3].Item2.x*cv[3].Item1.x, -cv[3].Item2.x*cv[3].Item1.z},
  29. {0, 0, 0, cv[3].Item1.x, cv[3].Item1.z, 1, -cv[3].Item2.z*cv[3].Item1.x, -cv[3].Item2.z*cv[3].Item1.z}
  30. });
  31. Matrix<double> matrixB = DenseMatrix.OfArray(new double[,]
  32. {
  33. {cv[0].Item2.x},
  34. {cv[0].Item2.z},
  35. {cv[1].Item2.x},
  36. {cv[1].Item2.z},
  37. {cv[2].Item2.x},
  38. {cv[2].Item2.z},
  39. {cv[3].Item2.x},
  40. {cv[3].Item2.z}
  41. }
  42. );
  43. var lambda = (matrixA.Transpose() * matrixA).Inverse() * matrixA.Transpose() * matrixB;
  44. //lambda = lambda.InsertRow(lambda.RowCount, DenseVector.OfArray(new double[] { 1 }));
  45. //lambda = lambda.Resize(3, 3);
  46. this.lambda = DenseMatrix.OfArray(new double[,]
  47. {
  48. { lambda[0,0], lambda[1,0], lambda[2,0]},
  49. { lambda[3,0], lambda[4,0], lambda[5,0]},
  50. { lambda[6,0], lambda[7,0], 1}
  51. });
  52. testCalibration();
  53. }
  54. public Vector3 WorldPositionToUnityPosition(Vector3 worldPosition)
  55. {
  56. var vector = DenseVector.OfArray(new double[] { worldPosition.x, worldPosition.z, 1 });
  57. var output = lambda * vector;
  58. var scaledOutput = output / output[2];
  59. return new Vector3((float)scaledOutput[0], 0, (float)scaledOutput[1]);
  60. throw new System.NotImplementedException();
  61. }
  62. private void testCalibration()
  63. {
  64. foreach(var c in calibrationVectors)
  65. {
  66. var test = DenseVector.OfArray(new double[] { c.Item1.x, c.Item1.z, 1 });
  67. var testOutput = lambda * test;
  68. var scaledTestOutput = testOutput / testOutput[2];
  69. }
  70. }
  71. }