Add foxglove_image_converter to camera pis

This makes it so that we can more readily debug issues live by sending
JPEGs across the network instead of attempting to forward raw images and
then requiring the browser to handle them.

Also add the foxglove_websocket binary so that you can connect to the
pi.

Change-Id: Ia2164184fcbd6c43435bc90e4315129a159fb0b1
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
diff --git a/aos/util/foxglove_websocket.cc b/aos/util/foxglove_websocket.cc
index 6ecb600..715ba13 100644
--- a/aos/util/foxglove_websocket.cc
+++ b/aos/util/foxglove_websocket.cc
@@ -3,7 +3,7 @@
 #include "aos/util/foxglove_websocket_lib.h"
 #include "gflags/gflags.h"
 
-DEFINE_string(config, "/app/aos_config.json", "Path to the config.");
+DEFINE_string(config, "aos_config.json", "Path to the config.");
 DEFINE_uint32(port, 8765, "Port to use for foxglove websocket server.");
 DEFINE_string(mode, "flatbuffer", "json or flatbuffer serialization.");
 DEFINE_bool(fetch_pinned_channels, true,
diff --git a/frc971/vision/BUILD b/frc971/vision/BUILD
index 3b011f2..936a441 100644
--- a/frc971/vision/BUILD
+++ b/frc971/vision/BUILD
@@ -122,7 +122,7 @@
     visibility = ["//visibility:public"],
     deps = [
         ":charuco_lib",
-        ":foxglove_image_converter",
+        ":foxglove_image_converter_lib",
         "//aos:init",
         "//aos/events/logging:log_reader",
         "//frc971/analysis:in_process_plotter",
@@ -257,9 +257,9 @@
 )
 
 cc_library(
-    name = "foxglove_image_converter",
-    srcs = ["foxglove_image_converter.cc"],
-    hdrs = ["foxglove_image_converter.h"],
+    name = "foxglove_image_converter_lib",
+    srcs = ["foxglove_image_converter_lib.cc"],
+    hdrs = ["foxglove_image_converter_lib.h"],
     visibility = ["//visibility:public"],
     deps = [
         ":charuco_lib",
@@ -293,7 +293,7 @@
         "@april_tag_test_image",
     ],
     deps = [
-        ":foxglove_image_converter",
+        ":foxglove_image_converter_lib",
         "//aos:configuration",
         "//aos/events:simulated_event_loop",
         "//aos/testing:googletest",
diff --git a/frc971/vision/calibration_accumulator.h b/frc971/vision/calibration_accumulator.h
index c4dcae9..93d68a5 100644
--- a/frc971/vision/calibration_accumulator.h
+++ b/frc971/vision/calibration_accumulator.h
@@ -8,7 +8,7 @@
 #include "aos/time/time.h"
 #include "frc971/control_loops/quaternion_utils.h"
 #include "frc971/vision/charuco_lib.h"
-#include "frc971/vision/foxglove_image_converter.h"
+#include "frc971/vision/foxglove_image_converter_lib.h"
 #include "frc971/wpilib/imu_batch_generated.h"
 
 namespace frc971 {
diff --git a/frc971/vision/foxglove_image_converter.cc b/frc971/vision/foxglove_image_converter_lib.cc
similarity index 85%
rename from frc971/vision/foxglove_image_converter.cc
rename to frc971/vision/foxglove_image_converter_lib.cc
index abde78b..f5ecb40 100644
--- a/frc971/vision/foxglove_image_converter.cc
+++ b/frc971/vision/foxglove_image_converter_lib.cc
@@ -1,7 +1,12 @@
-#include "frc971/vision/foxglove_image_converter.h"
+#include "frc971/vision/foxglove_image_converter_lib.h"
+
 #include <opencv2/imgcodecs.hpp>
 #include <opencv2/imgproc.hpp>
 
+DEFINE_int32(jpeg_quality, 95,
+             "Compression quality of JPEGs, 0-100; lower numbers mean lower "
+             "quality and resulting image sizes.");
+
 namespace frc971::vision {
 std::string_view ExtensionForCompression(ImageCompression compression) {
   switch (compression) {
@@ -19,7 +24,8 @@
   // imencode doesn't let us pass in anything other than an std::vector, and
   // performance isn't yet a big enough issue to try to avoid the copy.
   std::vector<uint8_t> buffer;
-  CHECK(cv::imencode(absl::StrCat(".", format), image, buffer));
+  CHECK(cv::imencode(absl::StrCat(".", format), image, buffer,
+                     {cv::IMWRITE_JPEG_QUALITY, FLAGS_jpeg_quality}));
   const flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data_offset =
       fbb->CreateVector(buffer);
   const struct timespec timestamp_t = aos::time::to_timespec(eof);
diff --git a/frc971/vision/foxglove_image_converter.h b/frc971/vision/foxglove_image_converter_lib.h
similarity index 100%
rename from frc971/vision/foxglove_image_converter.h
rename to frc971/vision/foxglove_image_converter_lib.h
diff --git a/frc971/vision/foxglove_image_converter_test.cc b/frc971/vision/foxglove_image_converter_test.cc
index 65b3b6b..e027de2 100644
--- a/frc971/vision/foxglove_image_converter_test.cc
+++ b/frc971/vision/foxglove_image_converter_test.cc
@@ -1,4 +1,4 @@
-#include "frc971/vision/foxglove_image_converter.h"
+#include "frc971/vision/foxglove_image_converter_lib.h"
 
 #include "aos/events/simulated_event_loop.h"
 #include "aos/json_to_flatbuffer.h"
diff --git a/y2023/BUILD b/y2023/BUILD
index 74ffaaf..c060688 100644
--- a/y2023/BUILD
+++ b/y2023/BUILD
@@ -6,10 +6,12 @@
     name = "pi_download",
     binaries = [
         "//frc971/vision:intrinsics_calibration",
+        "//aos/util:foxglove_websocket",
         "//y2023/vision:viewer",
         "//y2023/vision:aprilrobotics",
         "//y2022/localizer:localizer_main",
         "//y2023/constants:constants_sender",
+        "//y2023/vision:foxglove_image_converter",
         "//aos/network:web_proxy_main",
         "//aos/events/logging:log_cat",
         "//y2023/rockpi:imu_main",
diff --git a/y2023/vision/BUILD b/y2023/vision/BUILD
index 2cc4367..3295320 100644
--- a/y2023/vision/BUILD
+++ b/y2023/vision/BUILD
@@ -118,3 +118,14 @@
         "//aos/events:shm_event_loop",
     ],
 )
+
+cc_binary(
+    name = "foxglove_image_converter",
+    srcs = ["foxglove_image_converter.cc"],
+    visibility = ["//y2023:__subpackages__"],
+    deps = [
+        "//aos:init",
+        "//aos/events:shm_event_loop",
+        "//frc971/vision:foxglove_image_converter_lib",
+    ],
+)
diff --git a/y2023/vision/foxglove_image_converter.cc b/y2023/vision/foxglove_image_converter.cc
new file mode 100644
index 0000000..8f3032b
--- /dev/null
+++ b/y2023/vision/foxglove_image_converter.cc
@@ -0,0 +1,21 @@
+#include "frc971/vision/foxglove_image_converter_lib.h"
+
+#include "aos/init.h"
+#include "aos/events/shm_event_loop.h"
+
+DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+
+int main(int argc, char *argv[]) {
+  aos::InitGoogle(&argc, &argv);
+
+  aos::FlatbufferDetachedBuffer<aos::Configuration> config =
+      aos::configuration::ReadConfig(FLAGS_config);
+
+  aos::ShmEventLoop event_loop(&config.message());
+
+  frc971::vision::FoxgloveImageConverter converter(
+      &event_loop, "/camera", "/camera",
+      frc971::vision::ImageCompression::kJpeg);
+
+  event_loop.Run();
+}
diff --git a/y2023/y2023_pi_template.json b/y2023/y2023_pi_template.json
index fd9fccc..b6eaf04 100644
--- a/y2023/y2023_pi_template.json
+++ b/y2023/y2023_pi_template.json
@@ -165,7 +165,7 @@
       "source_node": "pi{{ NUM }}",
       "frequency": 40,
       "max_size": 1843456,
-      "num_readers": 4,
+      "num_readers": 6,
       "read_method": "PIN",
       "num_senders": 18
     },
@@ -417,6 +417,20 @@
       ]
     },
     {
+      "name": "foxglove_websocket",
+      "user": "pi",
+      "nodes": [
+        "pi{{ NUM }}"
+      ]
+    },
+    {
+      "name": "foxglove_image_converter",
+      "user": "pi",
+      "nodes": [
+        "pi{{ NUM }}"
+      ]
+    },
+    {
       "name": "constants_sender",
       "autorestart": false,
       "user": "pi",