Checking in debug_view, some extra missing utils, and the y2016 target_sender code.

Change-Id: I241947265da8f332c39862f4d0ddcdc2d29c7b68
diff --git a/aos/vision/debug/overlay.h b/aos/vision/debug/overlay.h
new file mode 100644
index 0000000..fbd6838
--- /dev/null
+++ b/aos/vision/debug/overlay.h
@@ -0,0 +1,198 @@
+#ifndef _AOS_VISION_IMAGE_DEBUG_OVERLAY_H_
+#define _AOS_VISION_IMAGE_DEBUG_OVERLAY_H_
+
+#include <string>
+#include <vector>
+
+#include "aos/vision/image/image_types.h"
+#include "aos/vision/math/segment.h"
+#include "aos/vision/math/vector.h"
+
+namespace aos {
+namespace vision {
+
+// Abstract away rendering to avoid compiling gtk for arm.
+// This should match a reduced cairo rendering api.
+class RenderInterface {
+ public:
+  RenderInterface() {}
+  RenderInterface(RenderInterface &&other) = delete;
+  RenderInterface(const RenderInterface &other) = delete;
+  ~RenderInterface() {}
+
+  virtual void Translate(double x, double y) = 0;
+  virtual void SetSourceRGB(double r, double g, double b) = 0;
+  virtual void MoveTo(double x, double y) = 0;
+  virtual void LineTo(double x, double y) = 0;
+  virtual void Circle(double x, double y, double r) = 0;
+  // negative in x, y, text_x, text_y measures from max in those value
+  virtual void Text(int x, int y, int text_x, int text_y,
+                    const std::string &text) = 0;
+  virtual void Stroke() = 0;
+};
+
+// Interface for a list of overlays to be drawn onto a debug image.
+// These will be passed into the running vision algorithms to output debug info,
+// so they must not have costly side-effects.
+class OverlayBase {
+ public:
+  OverlayBase() {}
+  virtual ~OverlayBase() {}
+
+  // Draws this overlay to the given canvas.
+  virtual void Draw(RenderInterface *render, double /* width */,
+                    double /* height */) = 0;
+
+  // Clears the entire overlay.
+  virtual void Reset() = 0;
+
+  PixelRef color = {255, 0, 0};
+  double scale = 1.0;
+};
+
+// A lambda that renders directly to the render interface.
+class LambdaOverlay : public OverlayBase {
+ public:
+  std::function<void(RenderInterface *, double, double)> draw_fn;
+  void Draw(RenderInterface *render, double width, double height) override {
+    if (draw_fn) draw_fn(render, width, height);
+  }
+  void Reset() override {}
+};
+
+// Lines rendered in a coordinate system where the origin is the center
+// of the screen
+class LinesOverlay : public OverlayBase {
+ public:
+  LinesOverlay() : OverlayBase() {}
+  ~LinesOverlay() {}
+
+  // build a segment for this line
+  void add_line(Vector<2> st, Vector<2> ed) { add_line(st, ed, color); }
+
+  // build a segment for this line
+  void add_line(Vector<2> st, Vector<2> ed, PixelRef newColor) {
+    lines_.emplace_back(
+        std::pair<Segment<2>, PixelRef>(Segment<2>(st, ed), newColor));
+  }
+
+  void add_point(Vector<2> pt) { add_point(pt, color); }
+
+  // add a new point connected to the last point in the line
+  void add_point(Vector<2> pt, PixelRef newColor) {
+    if (lines_.empty()) {
+      lines_.emplace_back(
+          std::pair<Segment<2>, PixelRef>(Segment<2>(pt, pt), newColor));
+    } else {
+      Vector<2> st = lines_.back().first.B();
+      lines_.emplace_back(
+          std::pair<Segment<2>, PixelRef>(Segment<2>(st, pt), newColor));
+    }
+  }
+
+  void Draw(RenderInterface *render, double w, double h) override {
+    render->Translate(w / 2.0, h / 2.0);
+    for (const auto &ln : lines_) {
+      PixelRef localColor = ln.second;
+      render->SetSourceRGB(localColor.r / 255.0, localColor.g / 255.0,
+                           localColor.b / 255.0);
+      render->MoveTo(scale * ln.first.A().x(), -scale * ln.first.A().y());
+      render->LineTo(scale * ln.first.B().x(), -scale * ln.first.B().y());
+      render->Stroke();
+    }
+  }
+
+  // Empting the list will blank the whole overlay
+  void Reset() override { lines_.clear(); }
+
+ private:
+  // lines in this over lay
+  std::vector<std::pair<Segment<2>, PixelRef>> lines_;
+};
+
+// Lines rendered in pixel coordinates (Should match up with the screen.)
+class PixelLinesOverlay : public OverlayBase {
+ public:
+  PixelLinesOverlay() : OverlayBase() {}
+  ~PixelLinesOverlay() {}
+
+  // build a segment for this line
+  void add_line(Vector<2> st, Vector<2> ed) { add_line(st, ed, color); }
+
+  // build a segment for this line
+  void add_line(Vector<2> st, Vector<2> ed, PixelRef newColor) {
+    lines_.emplace_back(
+        std::pair<Segment<2>, PixelRef>(Segment<2>(st, ed), newColor));
+  }
+
+  void start_new_profile() { start_profile = true; }
+
+  // add a new point connected to the last point in the line
+  void add_point(Vector<2> pt, PixelRef newColor) {
+    if (lines_.empty() || start_profile) {
+      lines_.emplace_back(
+          std::pair<Segment<2>, PixelRef>(Segment<2>(pt, pt), newColor));
+      start_profile = false;
+    } else {
+      Vector<2> st = lines_.back().first.B();
+      lines_.emplace_back(
+          std::pair<Segment<2>, PixelRef>(Segment<2>(st, pt), newColor));
+    }
+  }
+
+  void Draw(RenderInterface *render, double /*width*/,
+            double /*hieght*/) override {
+    for (const auto &ln : lines_) {
+      PixelRef localColor = ln.second;
+      render->SetSourceRGB(localColor.r / 255.0, localColor.g / 255.0,
+                           localColor.b / 255.0);
+      render->MoveTo(ln.first.A().x(), ln.first.A().y());
+      render->LineTo(ln.first.B().x(), ln.first.B().y());
+      render->Stroke();
+    }
+  }
+
+  // Empting the list will blank the whole overlay.
+  void Reset() override { lines_.clear(); }
+
+ private:
+  // Lines in this overlay.
+  std::vector<std::pair<Segment<2>, PixelRef>> lines_;
+  bool start_profile = false;
+};
+
+// Circles rendered in a coordinate system where the origin is the center
+// of the screen.
+class CircleOverlay : public OverlayBase {
+ public:
+  CircleOverlay() : OverlayBase() {}
+  ~CircleOverlay() {}
+
+  // build a circle as a point and radius
+  std::pair<Vector<2>, double> *add_circle(Vector<2> center, double radius) {
+    circles_.emplace_back(std::pair<Vector<2>, double>(center, radius));
+    return &(circles_.back());
+  }
+
+  void Draw(RenderInterface *render, double w, double h) {
+    render->Translate(w / 2.0, h / 2.0);
+    render->SetSourceRGB(color.r / 255.0, color.g / 255.0, color.b / 255.0);
+    for (const auto &circle : circles_) {
+      render->Circle(scale * circle.first.x(), -scale * circle.first.y(),
+                     scale * circle.second);
+      render->Stroke();
+    }
+  }
+
+  // empting the list will blank the whole overlay
+  void Reset() { circles_.clear(); }
+
+ private:
+  // circles in this overlay
+  std::vector<std::pair<Vector<2>, double>> circles_;
+};
+
+}  // vision
+}  // aos
+
+#endif  // _AOS_VISION_IMAGE_DEBUG_OVERLAY_H_