/src/main/java/ch/ethz/idsc/sophus/app/ob/GeodesicFilterEvaluation.java

https://github.com/idsc-frazzoli/owl · Java · 132 lines · 122 code · 8 blank · 2 comment · 1 complexity · 300463ededc0faa2fac73b4f4d29f1f0 MD5 · raw file

  1. // code by ob
  2. package ch.ethz.idsc.sophus.app.ob;
  3. import java.io.IOException;
  4. import java.util.Iterator;
  5. import java.util.List;
  6. import ch.ethz.idsc.sophus.app.io.GokartPoseDataV1;
  7. import ch.ethz.idsc.sophus.math.win.SmoothingKernel;
  8. import ch.ethz.idsc.subare.util.HtmlUtf8;
  9. import ch.ethz.idsc.tensor.RealScalar;
  10. import ch.ethz.idsc.tensor.Scalar;
  11. import ch.ethz.idsc.tensor.Scalars;
  12. import ch.ethz.idsc.tensor.Tensor;
  13. import ch.ethz.idsc.tensor.io.HomeDirectory;
  14. import ch.ethz.idsc.tensor.io.ResourceData;
  15. /* package */ enum GeodesicFilterEvaluation {
  16. ;
  17. public static Tensor process(String data) throws IOException {
  18. ParameterMinimizer parameterMinimizer = new ParameterMinimizer();
  19. Tensor minimizer = parameterMinimizer.minimizer(data);
  20. GeodesicCurveEvaluation geodesicCurveEvaluation = new GeodesicCurveEvaluation(minimizer, data);
  21. geodesicCurveEvaluation.windowSizeCurves();
  22. geodesicCurveEvaluation.alphaCurves();
  23. return minimizer;
  24. }
  25. private static Scalar time(String data) {
  26. Tensor time = Tensor.of(ResourceData.of("/dubilab/app/pose/" + data + ".csv").stream() //
  27. .map(row -> row.extract(0, 1)));
  28. Scalar duration = time.Get(time.length() - 1, 0).subtract(time.Get(0, 0));
  29. return duration;
  30. }
  31. private static Scalar length(String data) {
  32. Scalar length = RealScalar.of(Tensor.of(ResourceData.of("/dubilab/app/pose/" + data + ".csv").stream() //
  33. .map(row -> row.extract(0, 1))).length());
  34. return length;
  35. }
  36. public static void htmlWriter(String data, Tensor minimizer) throws IOException {
  37. try (HtmlUtf8 htmlUtf8 = HtmlUtf8.page(HomeDirectory.Pictures(data.replace('/', '_') + ".html"))) {
  38. Tensor minimizingAlphas = minimizer.get(0);
  39. Tensor minimizingWindowSizes = minimizer.get(1);
  40. Tensor minimizingKernels = minimizer.get(2);
  41. Tensor minimizingErrors = minimizer.get(3).divide(length(data));
  42. htmlUtf8.appendln("<tr><th>Suggested Filter parameters for dataset: " + data + "</th></th>");
  43. htmlUtf8.appendln("<table>");
  44. htmlUtf8.appendln(
  45. "<tr><td width = 200>Minimizers: </td><td width = 200>alpha</td><td width = 200>WindowSize</td><td width = 200>Kernel</td><td width = 200>Resulting Error</td><td width = 200>Unit</td></tr>");
  46. htmlUtf8.appendln("<tr><td width = 200>Pose</td><td width = 200>" + minimizingAlphas.Get(0) + "</td><td width = 200>" + minimizingWindowSizes.Get(0)
  47. + "</td><td width = 200>" + SmoothingKernel.values()[Scalars.intValueExact(minimizingKernels.Get(0))] + "</td><td width = 200>"
  48. + minimizingErrors.Get(0) + "</td><td width = 200>[m]</td></tr>");
  49. htmlUtf8.appendln("<tr><td width = 200>Orientation</td><td width = 200>" + minimizingAlphas.Get(1) + "</td><td width = 200>"
  50. + minimizingWindowSizes.Get(1) + "</td><td width = 200>" + SmoothingKernel.values()[Scalars.intValueExact(minimizingKernels.Get(1))]
  51. + "</td><td width = 200>" + minimizingErrors.Get(1) + "</td><td width = 200>[rad]</td></tr>");
  52. htmlUtf8.appendln("<tr><td width = 200>Pose change</td><td width = 200>" + minimizingAlphas.Get(2) + "</td><td width = 200>"
  53. + minimizingWindowSizes.Get(2) + "</td><td width = 200>" + SmoothingKernel.values()[Scalars.intValueExact(minimizingKernels.Get(2))]
  54. + "</td><td width = 200>" + minimizingErrors.Get(2).divide(time(data)) + "</td><td width = 200>[m/s]</td></tr>");
  55. htmlUtf8.appendln("<tr><td width = 200>Orientation change</td><td width = 200>" + minimizingAlphas.Get(3) + "</td><td width = 200>"
  56. + minimizingWindowSizes.Get(3) + "</td><td width = 200>" + SmoothingKernel.values()[Scalars.intValueExact(minimizingKernels.Get(3))]
  57. + "</td><td width = 200>" + minimizingErrors.Get(3).divide(time(data)) + "</td><td width = 200>[rad/s]</td></tr>");
  58. htmlUtf8.appendln("</table>");
  59. htmlUtf8.appendln("<p>resulting errors refer to average error per measurement</p>");
  60. String name = "GeodesicFilterEvaluation_";
  61. String win = "windowSizeCurves";
  62. String alpha = "alphaCurves";
  63. htmlUtf8.appendln("<p><b>Error as a function of alpha:</b></p>");
  64. htmlUtf8.appendln("<p>Pose:</p>");
  65. htmlUtf8.appendln("<img src='" + name + data.replace('/', '_') + "_" + alpha + "_x.png' />");
  66. htmlUtf8.appendln("<p>Orientation:</p>");
  67. htmlUtf8.appendln("<img src='" + name + data.replace('/', '_') + "_" + alpha + "_a.png' />");
  68. htmlUtf8.appendln("<p>Pose change:</p>");
  69. htmlUtf8.appendln("<img src='" + name + data.replace('/', '_') + "_" + alpha + "_xdot.png' />");
  70. htmlUtf8.appendln("<p>Orientation change:</p>");
  71. htmlUtf8.appendln("<img src='" + name + data.replace('/', '_') + "_" + alpha + "_adot.png' />");
  72. htmlUtf8.appendln("<p><b>Error as a function of WindowSize:</b></p>");
  73. htmlUtf8.appendln("<p>Pose:</p>");
  74. htmlUtf8.appendln("<img src='" + name + data.replace('/', '_') + "_" + win + "_x.png' />");
  75. htmlUtf8.appendln("<p>Orientation:</p>");
  76. htmlUtf8.appendln("<img src='" + name + data.replace('/', '_') + "_" + win + "_a.png' />");
  77. htmlUtf8.appendln("<p>Pose change:</p>");
  78. htmlUtf8.appendln("<img src='" + name + data.replace('/', '_') + "_" + win + "_xdot.png' />");
  79. htmlUtf8.appendln("<p>Orientation change:</p>");
  80. htmlUtf8.appendln("<img src='" + name + data.replace('/', '_') + "_" + win + "_adot.png' />");
  81. FrequencyResponsePlot frequencyResponsePlot = new FrequencyResponsePlot(minimizer);
  82. frequencyResponsePlot.evaluate();
  83. htmlUtf8.appendln("<p><b>Frequency Responses: </b></p>");
  84. // change name of frequency responses s.t. they are not overwritten each time
  85. htmlUtf8.appendln("<img src='FrequencyResponsePlot_MagnitudeResponse_Test.png' />");
  86. htmlUtf8.appendln("<img src='FrequencyResponsePlot_PhaseResponse_Test.png' />");
  87. }
  88. }
  89. public static void htmlComparison(String data, Tensor minimizer, HtmlUtf8 htmlUtf8) {
  90. Tensor minimizingAlphas = minimizer.get(0);
  91. Tensor minimizingWindowSizes = minimizer.get(1);
  92. Tensor minimizingKernels = minimizer.get(2);
  93. Tensor minimizingErrors = minimizer.get(3).divide(length(data));
  94. htmlUtf8.appendln("<p><b>Suggested Filter parameters for dataset: " + data + "</b></p>");
  95. htmlUtf8.appendln("<table>");
  96. htmlUtf8.appendln(
  97. "<tr><td width = 200>Minimizers: </td><td width = 200>alpha</td><td width = 200>WindowSize</td><td width = 200>Kernel</td><td width = 200>Resulting Error</td><td width = 200>Unit</td></tr>");
  98. htmlUtf8.appendln("<tr><td width = 200>Pose</td><td width = 200>" + minimizingAlphas.Get(0) + "</td><td width = 200>" + minimizingWindowSizes.Get(0)
  99. + "</td><td width = 200>" + SmoothingKernel.values()[Scalars.intValueExact(minimizingKernels.Get(0))] + "</td><td width = 200>"
  100. + minimizingErrors.Get(0) + "</td><td width = 200>[m]</td></tr>");
  101. htmlUtf8.appendln("<tr><td width = 200>Orientation</td><td width = 200>" + minimizingAlphas.Get(1) + "</td><td width = 200>" + minimizingWindowSizes.Get(1)
  102. + "</td><td width = 200>" + SmoothingKernel.values()[Scalars.intValueExact(minimizingKernels.Get(1))] + "</td><td width = 200>"
  103. + minimizingErrors.Get(1) + "</td><td width = 200>[rad]</td></tr>");
  104. htmlUtf8.appendln("<tr><td width = 200>Pose change</td><td width = 200>" + minimizingAlphas.Get(2) + "</td><td width = 200>" + minimizingWindowSizes.Get(2)
  105. + "</td><td width = 200>" + SmoothingKernel.values()[Scalars.intValueExact(minimizingKernels.Get(2))] + "</td><td width = 200>"
  106. + minimizingErrors.Get(2).divide(time(data)) + "</td><td width = 200>[m/s]</td></tr>");
  107. htmlUtf8.appendln("<tr><td width = 200>Orientation change</td><td width = 200>" + minimizingAlphas.Get(3) + "</td><td width = 200>"
  108. + minimizingWindowSizes.Get(3) + "</td><td width = 200>" + SmoothingKernel.values()[Scalars.intValueExact(minimizingKernels.Get(3))]
  109. + "</td><td width = 200>" + minimizingErrors.Get(3).divide(time(data)) + "</td><td width = 200>[rad/s]</td></tr>");
  110. htmlUtf8.appendln("</table>");
  111. }
  112. public static void main(String[] args) throws IOException {
  113. List<String> list = GokartPoseDataV1.INSTANCE.list();
  114. Iterator<String> iterator = list.iterator();
  115. while (iterator.hasNext()) {
  116. String data = iterator.next();
  117. Tensor minimizer = GeodesicFilterEvaluation.process(data);
  118. GeodesicFilterEvaluation.htmlWriter(data, minimizer);
  119. try (HtmlUtf8 htmlUtf8 = HtmlUtf8.page(HomeDirectory.Pictures("ComparisonTest.html"))) {
  120. htmlComparison(data, minimizer, htmlUtf8);
  121. }
  122. }
  123. }
  124. }