check optional access in y2022 drivetrain

Change-Id: Ic098c4a0931799237ff04d5e2524fa672ba81b49
Signed-off-by: James Kuszmaul <jabukuszmaul@gmail.com>
diff --git a/frc971/control_loops/drivetrain/hybrid_ekf.h b/frc971/control_loops/drivetrain/hybrid_ekf.h
index 2a972b6..fcbed76 100644
--- a/frc971/control_loops/drivetrain/hybrid_ekf.h
+++ b/frc971/control_loops/drivetrain/hybrid_ekf.h
@@ -330,6 +330,12 @@
     }
     return X_hat();
   }
+  std::optional<State> OldestState() {
+    if (observations_.empty()) {
+      return std::nullopt;
+    }
+    return observations_.begin()->X_hat;
+  }
 
   // Returns the most recent input vector.
   Input MostRecentInput() {
diff --git a/y2022/control_loops/drivetrain/localizer.cc b/y2022/control_loops/drivetrain/localizer.cc
index 3d02312..0735534 100644
--- a/y2022/control_loops/drivetrain/localizer.cc
+++ b/y2022/control_loops/drivetrain/localizer.cc
@@ -71,8 +71,15 @@
         monotonic_offset);
     // TODO: Finish implementing simple x/y/theta updater with state_at_capture.
     // TODO: Implement turret/camera processing logic on pi side.
-    const std::optional<State> state_at_capture =
+    std::optional<State> state_at_capture =
         ekf_.LastStateBeforeTime(capture_time);
+    if (!state_at_capture.has_value()) {
+      state_at_capture = ekf_.OldestState();
+      if (!state_at_capture.has_value()) {
+        return;
+      }
+    }
+
     Eigen::Matrix<float, HybridEkf::kNOutputs, HybridEkf::kNStates> H;
     H.setZero();
     H(0, StateIdx::kX) = 1;