Send more information to each camera

This is what I'm thinking so Parker can write code for it.

Change-Id: I766747ed6c1bf5adc8d1c29e5d1896b8806b6eb9
diff --git a/aos/time/time.cc b/aos/time/time.cc
index f585192..06f4b12 100644
--- a/aos/time/time.cc
+++ b/aos/time/time.cc
@@ -185,5 +185,17 @@
 #endif  // __linux__
 }
 
+#ifdef __linux__
+realtime_clock::time_point realtime_clock::now() noexcept {
+  struct timespec current_time;
+  if (clock_gettime(CLOCK_REALTIME, &current_time) != 0) {
+    PLOG(FATAL, "clock_gettime(%jd, %p) failed",
+         static_cast<uintmax_t>(CLOCK_REALTIME), &current_time);
+  }
+
+  return time_point(::std::chrono::seconds(current_time.tv_sec) +
+                    ::std::chrono::nanoseconds(current_time.tv_nsec));
+}
+#endif  // __linux__
 
 }  // namespace aos
diff --git a/aos/time/time.h b/aos/time/time.h
index 6f69aa7..136629c 100644
--- a/aos/time/time.h
+++ b/aos/time/time.h
@@ -24,7 +24,32 @@
   typedef ::std::chrono::time_point<monotonic_clock> time_point;
 
   static monotonic_clock::time_point now() noexcept;
-  static constexpr bool is_steady = true;
+  // This clock is still subject to rate adjustments based on adjtime, so it is
+  // not steady.
+  static constexpr bool is_steady = false;
+
+  // Returns the epoch (0).
+  static constexpr monotonic_clock::time_point epoch() {
+    return time_point(zero());
+  }
+
+  static constexpr monotonic_clock::duration zero() { return duration(0); }
+
+  static constexpr time_point min_time{
+      time_point(duration(::std::numeric_limits<duration::rep>::min()))};
+};
+
+class realtime_clock {
+ public:
+  typedef ::std::chrono::nanoseconds::rep rep;
+  typedef ::std::chrono::nanoseconds::period period;
+  typedef ::std::chrono::nanoseconds duration;
+  typedef ::std::chrono::time_point<monotonic_clock> time_point;
+
+#ifdef __linux__
+  static monotonic_clock::time_point now() noexcept;
+#endif  // __linux__
+  static constexpr bool is_steady = false;
 
   // Returns the epoch (0).
   static constexpr monotonic_clock::time_point epoch() {
diff --git a/y2019/jevois/BUILD b/y2019/jevois/BUILD
index 1ad056b..fde8c12 100644
--- a/y2019/jevois/BUILD
+++ b/y2019/jevois/BUILD
@@ -63,6 +63,7 @@
     visibility = ["//visibility:public"],
     deps = [
         "//aos/containers:sized_array",
+        "//aos/time",
         "//third_party/eigen",
     ],
 )
diff --git a/y2019/jevois/structures.h b/y2019/jevois/structures.h
index c82a089..15889c4 100644
--- a/y2019/jevois/structures.h
+++ b/y2019/jevois/structures.h
@@ -10,6 +10,7 @@
 #include "Eigen/Dense"
 
 #include "aos/containers/sized_array.h"
+#include "aos/time/time.h"
 
 namespace frc971 {
 namespace jevois {
@@ -106,6 +107,15 @@
 
 // This is all the information sent from the Teensy to each camera.
 struct CameraCalibration {
+  enum class CameraCommand {
+    // Stay in normal mode.
+    kNormal,
+    // Go to camera passthrough mode.
+    kCameraPassthrough,
+    // Go to being a useful USB device.
+    kUsb,
+  };
+
   bool operator==(const CameraCalibration &other) const {
     if (other.calibration != calibration) {
       return false;
@@ -120,6 +130,17 @@
   //
   // TODO(Parker): What are the details on how this is defined?
   Eigen::Matrix<float, 3, 4> calibration;
+
+  // A local timestamp from the Teensy. This starts at 0 when the Teensy is
+  // powered on.
+  aos::monotonic_clock::time_point teensy_now;
+
+  // A realtime timestamp from the roboRIO. This will be min_time if the roboRIO
+  // has never sent anything.
+  aos::realtime_clock::time_point realtime_now;
+
+  // What mode the camera should transition into.
+  CameraCommand camera_command;
 };
 
 // This is all the information the Teensy sends to the RoboRIO.
@@ -160,6 +181,9 @@
 
   // Whether the light ring for each camera should be on.
   std::bitset<5> light_rings;
+
+  // The current time.
+  aos::realtime_clock::time_point realtime_now;
 };
 
 }  // namespace jevois