Merge "Lower the exposure when we see lots of bright pixels."
diff --git a/y2019/vision/target_finder.cc b/y2019/vision/target_finder.cc
index f6e5ac4..83d4a01 100644
--- a/y2019/vision/target_finder.cc
+++ b/y2019/vision/target_finder.cc
@@ -26,6 +26,14 @@
       });
 }
 
+int TargetFinder::PixelCount(BlobList *imgs) {
+  int num_pixels = 0;
+  for (RangeImage &img : *imgs) {
+    num_pixels += img.npixels();
+  }
+  return num_pixels;
+}
+
 // Filter blobs on size.
 void TargetFinder::PreFilter(BlobList *imgs) {
   imgs->erase(
@@ -577,13 +585,11 @@
 }
 
 bool TargetFinder::TestExposure(const std::vector<IntermediateResult> &results,
-                                int *desired_exposure) {
+                                int pixel_count, int *desired_exposure) {
   // TODO(ben): Add these values to config file.
   constexpr double low_dist = 0.8;
-  constexpr double high_dist = 2.0;
   constexpr int low_exposure  = 60;
-  constexpr int mid_exposure  = 300;
-  constexpr int high_exposure = 500;
+  constexpr int mid_exposure  = 200;
 
   bool needs_update = false;
   if (results.size() > 0) {
@@ -591,10 +597,11 @@
     // based on the distance to that target.
     // First result should always be the closest target.
     if (results[0].extrinsics.z < low_dist) {
+      LOG(INFO) << "Low exposure";
       *desired_exposure = low_exposure;
-    } else if (results[0].extrinsics.z > high_dist) {
-      *desired_exposure = high_exposure;
+      close_bucket_ = 4;
     } else {
+      LOG(INFO) << "Mid exposure";
       *desired_exposure = mid_exposure;
     }
     if (*desired_exposure != current_exposure_) {
@@ -602,32 +609,23 @@
       current_exposure_ = *desired_exposure;
     }
   } else {
-    // We don't see a target, but part of the problem might
-    // be the exposure setting. Lets try changing it and see
-    // if things get better.
-    const int offset = std::rand() % 10;
-
-    // At random with 3/X probability try a higher or lower.
-    if (offset == 0) {
-      if (low_exposure != current_exposure_) {
-        needs_update = true;
-        current_exposure_ = low_exposure;
-        *desired_exposure = low_exposure;
-      }
-    } else if (offset == 1) {
-      if (mid_exposure != current_exposure_) {
-        needs_update = true;
-        current_exposure_ = mid_exposure;
-        *desired_exposure = mid_exposure;
-      }
-    } else if (offset == 2) {
-      if (high_exposure != current_exposure_) {
-        needs_update = true;
-        current_exposure_ = high_exposure;
-        *desired_exposure = high_exposure;
+    close_bucket_ = ::std::max(0, close_bucket_ - 1);
+    // It's been a while since we saw a target.
+    if (close_bucket_ == 0) {
+      if (pixel_count > 6000) {
+        if (low_exposure != current_exposure_) {
+          needs_update = true;
+          current_exposure_ = low_exposure;
+          *desired_exposure = low_exposure;
+        }
+      } else {
+        if (mid_exposure != current_exposure_) {
+          needs_update = true;
+          current_exposure_ = mid_exposure;
+          *desired_exposure = mid_exposure;
+        }
       }
     }
-    // If one of our cases is not hit don't change anything.
   }
   return needs_update;
 }
diff --git a/y2019/vision/target_finder.h b/y2019/vision/target_finder.h
index 0f1575c..d54dc2d 100644
--- a/y2019/vision/target_finder.h
+++ b/y2019/vision/target_finder.h
@@ -41,6 +41,8 @@
   // Value against which we threshold.
   static uint8_t GetThresholdValue() { return 100; }
 
+  int PixelCount(BlobList *imgs);
+
   // filter out obvious or durranged blobs.
   void PreFilter(BlobList *imgs);
 
@@ -72,7 +74,7 @@
       bool verbose);
 
   bool TestExposure(const std::vector<IntermediateResult> &results,
-                    int *desired_exposure);
+                    int pixel_count, int *desired_exposure);
 
   // Get the local overlay for debug if we are doing that.
   aos::vision::PixelLinesOverlay *GetOverlay() { return &overlay_; }
@@ -108,6 +110,8 @@
   size_t frame_count_;
   size_t valid_result_count_;
 
+  int close_bucket_ = 0;
+
   int current_exposure_ = 0;
 };
 
diff --git a/y2019/vision/target_sender.cc b/y2019/vision/target_sender.cc
index db33419..b7fed9a 100644
--- a/y2019/vision/target_sender.cc
+++ b/y2019/vision/target_sender.cc
@@ -202,6 +202,8 @@
     aos::vision::ImageFormat fmt{640, 480};
     aos::vision::BlobList imgs =
         aos::vision::FindBlobs(thresholder.Threshold(fmt, data.data(), 120));
+    const int num_pixels = finder.PixelCount(&imgs);
+    LOG(INFO) << "Number pixels: " << num_pixels;
     finder.PreFilter(&imgs);
     LOG(INFO) << "Blobs: " << imgs.size();
 
@@ -263,7 +265,7 @@
     LOG(INFO) << "Results: " << results.size();
 
     int desired_exposure;
-    if (finder.TestExposure(results, &desired_exposure)) {
+    if (finder.TestExposure(results, num_pixels, &desired_exposure)) {
       camera0->SetExposure(desired_exposure);
     }