Update WPILib, roborio compilers, and CTRE Phoenix libraries

This borrows heavily from work that Ravago did to initially get this
stuff working.

Tested rudimentary functionality on a test bench, ensured that we could:
* Enable the robot.
* Read joystick and button values.
* Switch between auto and teleop modes.
* Read sensor values (encoder, absolute encoder, potentiometer).
* Read PDP values.
* Drive PWM motors.
* Drive CANivore motors.

Non-WPILib changes are made to accommodate the upgrade roborio
compiler's improved pickiness.

Merge commit '125aac16d9bf03c833ffa18de2f113a33758a4b8' into HEAD

Change-Id: I8648956fb7517b2d784bf58e0a236742af7a306a
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
diff --git a/aos/actions/actions.h b/aos/actions/actions.h
index 9a62483..bda29cc 100644
--- a/aos/actions/actions.h
+++ b/aos/actions/actions.h
@@ -106,8 +106,8 @@
  public:
   // A convenient way to refer to the type of our goals.
   typedef T GoalType;
-  typedef typename std::remove_reference<decltype(
-      *static_cast<GoalType *>(nullptr)->params())>::type ParamType;
+  typedef typename std::remove_pointer<typename std::invoke_result<
+      decltype(&GoalType::params), const GoalType *>::type>::type ParamType;
 
   TypedAction(typename ::aos::Fetcher<Status> *status_fetcher,
               typename ::aos::Sender<GoalType> *goal_sender,
@@ -194,8 +194,8 @@
 class TypedActionFactory {
  public:
   typedef T GoalType;
-  typedef typename std::remove_reference<decltype(
-      *static_cast<GoalType *>(nullptr)->params())>::type ParamType;
+  typedef typename std::remove_pointer<typename std::invoke_result<
+      decltype(&GoalType::params), const GoalType *>::type>::type ParamType;
 
   explicit TypedActionFactory(::aos::EventLoop *event_loop,
                               const ::std::string &name)
diff --git a/aos/actions/actor.h b/aos/actions/actor.h
index b906059..c27f7dd 100644
--- a/aos/actions/actor.h
+++ b/aos/actions/actor.h
@@ -20,8 +20,8 @@
 class ActorBase {
  public:
   typedef T GoalType;
-  typedef typename std::remove_reference<decltype(
-      *static_cast<GoalType *>(nullptr)->params())>::type ParamType;
+  typedef typename std::remove_pointer<typename std::invoke_result<
+      decltype(&GoalType::params), const GoalType *>::type>::type ParamType;
 
   // Commonly used offset for autonomous phased loops
   static constexpr monotonic_clock::duration kLoopOffset =
diff --git a/aos/events/logging/BUILD b/aos/events/logging/BUILD
index 7201e70..7e8daf9 100644
--- a/aos/events/logging/BUILD
+++ b/aos/events/logging/BUILD
@@ -215,7 +215,10 @@
     hdrs = [
         "s3_fetcher.h",
     ],
-    target_compatible_with = ["@platforms//os:linux"],
+    target_compatible_with = [
+        "@platforms//os:linux",
+        "@platforms//cpu:x86_64",
+    ],
     visibility = ["//visibility:public"],
     deps = [
         ":buffer_encoder",
diff --git a/aos/events/logging/log_cat.cc b/aos/events/logging/log_cat.cc
index a2441c8..b9e940c 100644
--- a/aos/events/logging/log_cat.cc
+++ b/aos/events/logging/log_cat.cc
@@ -83,7 +83,7 @@
   aos::logger::SpanReader reader(argv[1]);
   absl::Span<const uint8_t> raw_log_file_header_span = reader.ReadMessage();
 
-  if (raw_log_file_header_span == absl::Span<const uint8_t>()) {
+  if (raw_log_file_header_span.empty()) {
     LOG(WARNING) << "Empty log file on " << reader.filename();
     return 0;
   }
@@ -98,7 +98,7 @@
   }
   while (true) {
     absl::Span<const uint8_t> maybe_header_data = reader.PeekMessage();
-    if (maybe_header_data == absl::Span<const uint8_t>()) {
+    if (maybe_header_data.empty()) {
       break;
     }
 
@@ -153,7 +153,7 @@
   while (true) {
     const aos::SizePrefixedFlatbufferSpan<aos::logger::MessageHeader> message(
         reader.ReadMessage());
-    if (message.span() == absl::Span<const uint8_t>()) {
+    if (message.span().empty()) {
       break;
     }
     CHECK(message.Verify());
diff --git a/aos/events/logging/log_edit.cc b/aos/events/logging/log_edit.cc
index 969d59c..e3cfc3a 100644
--- a/aos/events/logging/log_edit.cc
+++ b/aos/events/logging/log_edit.cc
@@ -55,7 +55,7 @@
 
     while (true) {
       absl::Span<const uint8_t> msg_data = span_reader.ReadMessage();
-      if (msg_data == absl::Span<const uint8_t>()) {
+      if (msg_data.empty()) {
         break;
       }
 
diff --git a/aos/events/logging/logfile_utils.cc b/aos/events/logging/logfile_utils.cc
index 342cf8b..94337d3 100644
--- a/aos/events/logging/logfile_utils.cc
+++ b/aos/events/logging/logfile_utils.cc
@@ -85,8 +85,7 @@
   if (!util::MkdirPIfSpace(filename, 0777)) {
     ran_out_of_space_ = true;
   } else {
-    fd_ = open(filename_.c_str(),
-               O_RDWR | O_CLOEXEC | O_CREAT | O_EXCL, 0774);
+    fd_ = open(filename_.c_str(), O_RDWR | O_CLOEXEC | O_CREAT | O_EXCL, 0774);
     if (fd_ == -1 && errno == ENOSPC) {
       ran_out_of_space_ = true;
     } else {
@@ -441,7 +440,8 @@
   // want to control and understand it here.  Changing the order can increase
   // the amount of padding bytes in the middle.
   //
-  // It is also easier to follow...  And doesn't actually make things much bigger.
+  // It is also easier to follow...  And doesn't actually make things much
+  // bigger.
   switch (log_type) {
     case LogType::kLogRemoteMessage:
       message_header_builder.add_queue_index(context.remote_queue_index);
@@ -575,8 +575,7 @@
   LOG(FATAL);
 }
 
-flatbuffers::uoffset_t PackMessageSize(LogType log_type,
-                                       size_t data_size) {
+flatbuffers::uoffset_t PackMessageSize(LogType log_type, size_t data_size) {
   static_assert(sizeof(flatbuffers::uoffset_t) == 4u,
                 "Update size logic please.");
   const flatbuffers::uoffset_t aligned_data_length =
@@ -934,7 +933,7 @@
 
 absl::Span<const uint8_t> SpanReader::ReadMessage() {
   absl::Span<const uint8_t> result = PeekMessage();
-  if (result != absl::Span<const uint8_t>()) {
+  if (!result.empty()) {
     ConsumeMessage();
   } else {
     is_finished_ = true;
@@ -977,7 +976,7 @@
   absl::Span<const uint8_t> config_data = span_reader->ReadMessage();
 
   // Make sure something was read.
-  if (config_data == absl::Span<const uint8_t>()) {
+  if (config_data.empty()) {
     return std::nullopt;
   }
 
@@ -996,7 +995,7 @@
   if (FLAGS_workaround_double_headers && !result.message().has_logger_sha1()) {
     while (true) {
       absl::Span<const uint8_t> maybe_header_data = span_reader->PeekMessage();
-      if (maybe_header_data == absl::Span<const uint8_t>()) {
+      if (maybe_header_data.empty()) {
         break;
       }
 
@@ -1035,7 +1034,7 @@
     data_span = span_reader.ReadMessage();
 
     // Make sure something was read.
-    if (data_span == absl::Span<const uint8_t>()) {
+    if (data_span.empty()) {
       return std::nullopt;
     }
   }
@@ -1079,7 +1078,7 @@
 
 std::shared_ptr<UnpackedMessageHeader> MessageReader::ReadMessage() {
   absl::Span<const uint8_t> msg_data = span_reader_.ReadMessage();
-  if (msg_data == absl::Span<const uint8_t>()) {
+  if (msg_data.empty()) {
     if (is_corrupted()) {
       LOG(ERROR) << "Total corrupted volumes: before = "
                  << total_verified_before_
@@ -1116,7 +1115,7 @@
     while (true) {
       absl::Span<const uint8_t> msg_data = span_reader_.ReadMessage();
 
-      if (msg_data == absl::Span<const uint8_t>()) {
+      if (msg_data.empty()) {
         if (!ignore_corrupt_messages_flag_) {
           LOG(ERROR) << "Total corrupted volumes: before = "
                      << total_verified_before_
@@ -1212,20 +1211,17 @@
     remote_queue_index = message.remote_queue_index();
   }
 
-  new (unpacked_message) UnpackedMessageHeader{
-      .channel_index = message.channel_index(),
-      .monotonic_sent_time = monotonic_clock::time_point(
+  new (unpacked_message) UnpackedMessageHeader(
+      message.channel_index(),
+      monotonic_clock::time_point(
           chrono::nanoseconds(message.monotonic_sent_time())),
-      .realtime_sent_time = realtime_clock::time_point(
+      realtime_clock::time_point(
           chrono::nanoseconds(message.realtime_sent_time())),
-      .queue_index = message.queue_index(),
-      .monotonic_remote_time = monotonic_remote_time,
-      .realtime_remote_time = realtime_remote_time,
-      .remote_queue_index = remote_queue_index,
-      .monotonic_timestamp_time = monotonic_clock::time_point(
+      message.queue_index(), monotonic_remote_time, realtime_remote_time,
+      remote_queue_index,
+      monotonic_clock::time_point(
           std::chrono::nanoseconds(message.monotonic_timestamp_time())),
-      .has_monotonic_timestamp_time = message.has_monotonic_timestamp_time(),
-      .span = span};
+      message.has_monotonic_timestamp_time(), span);
 
   if (data_size > 0) {
     memcpy(span.data(), message.data()->data(), data_size);
diff --git a/aos/events/logging/logfile_utils.h b/aos/events/logging/logfile_utils.h
index e034bfe..7105b0c 100644
--- a/aos/events/logging/logfile_utils.h
+++ b/aos/events/logging/logfile_utils.h
@@ -438,6 +438,24 @@
 // Stores MessageHeader as a flat header and inline, aligned block of data.
 class UnpackedMessageHeader {
  public:
+  UnpackedMessageHeader(
+      uint32_t channel_index, monotonic_clock::time_point monotonic_sent_time,
+      realtime_clock::time_point realtime_sent_time, uint32_t queue_index,
+      std::optional<monotonic_clock::time_point> monotonic_remote_time,
+      std::optional<realtime_clock::time_point> realtime_remote_time,
+      std::optional<uint32_t> remote_queue_index,
+      monotonic_clock::time_point monotonic_timestamp_time,
+      bool has_monotonic_timestamp_time, absl::Span<const uint8_t> span)
+      : channel_index(channel_index),
+        monotonic_sent_time(monotonic_sent_time),
+        realtime_sent_time(realtime_sent_time),
+        queue_index(queue_index),
+        monotonic_remote_time(monotonic_remote_time),
+        realtime_remote_time(realtime_remote_time),
+        remote_queue_index(remote_queue_index),
+        monotonic_timestamp_time(monotonic_timestamp_time),
+        has_monotonic_timestamp_time(has_monotonic_timestamp_time),
+        span(span) {}
   UnpackedMessageHeader(const UnpackedMessageHeader &) = delete;
   UnpackedMessageHeader &operator=(const UnpackedMessageHeader &) = delete;
 
diff --git a/aos/events/shm_event_loop_test.cc b/aos/events/shm_event_loop_test.cc
index 90a6d1c..132ef20 100644
--- a/aos/events/shm_event_loop_test.cc
+++ b/aos/events/shm_event_loop_test.cc
@@ -42,7 +42,7 @@
     }
     ::std::unique_ptr<ShmEventLoop> loop(new ShmEventLoop(configuration()));
     loop->set_name(name);
-    return std::move(loop);
+    return loop;
   }
 
   ::std::unique_ptr<EventLoop> MakePrimary(std::string_view name) override {
@@ -54,7 +54,7 @@
         ::std::unique_ptr<ShmEventLoop>(new ShmEventLoop(configuration()));
     primary_event_loop_ = loop.get();
     loop->set_name(name);
-    return std::move(loop);
+    return loop;
   }
 
   void Run() override { CHECK_NOTNULL(primary_event_loop_)->Run(); }
diff --git a/aos/events/simulated_event_loop.cc b/aos/events/simulated_event_loop.cc
index d2328fb..944a22b 100644
--- a/aos/events/simulated_event_loop.cc
+++ b/aos/events/simulated_event_loop.cc
@@ -67,10 +67,11 @@
   AlignedOwningSpan *const span = reinterpret_cast<AlignedOwningSpan *>(
       malloc(sizeof(AlignedOwningSpan) + size + kChannelDataAlignment - 1));
 
-  absl::Span mutable_span(
+  absl::Span<uint8_t> mutable_span(
       reinterpret_cast<uint8_t *>(RoundChannelData(&span->data[0], size)),
       size);
-  new (span) AlignedOwningSpan{.span = mutable_span};
+  // Use the placement new operator to construct an actual absl::Span in place.
+  new (&span->span) absl::Span(mutable_span);
 
   return std::make_pair(
       RawSender::SharedSpan(
@@ -1009,7 +1010,7 @@
   ::std::unique_ptr<SimulatedFetcher> fetcher(
       new SimulatedFetcher(event_loop, this));
   fetchers_.push_back(fetcher.get());
-  return ::std::move(fetcher);
+  return fetcher;
 }
 
 std::optional<uint32_t> SimulatedChannel::Send(
@@ -1584,7 +1585,7 @@
 
   VLOG(1) << scheduler_.distributed_now() << " " << NodeName(node())
           << monotonic_now() << " MakeEventLoop(\"" << result->name() << "\")";
-  return std::move(result);
+  return result;
 }
 
 void SimulatedEventLoopFactory::AllowApplicationCreationDuring(
diff --git a/aos/ipc_lib/lockless_queue.cc b/aos/ipc_lib/lockless_queue.cc
index 5f12423..f380848 100644
--- a/aos/ipc_lib/lockless_queue.cc
+++ b/aos/ipc_lib/lockless_queue.cc
@@ -692,7 +692,7 @@
   queue.Initialize();
   LocklessQueueWatcher result(queue.memory(), priority);
   if (result.watcher_index_ != -1) {
-    return std::move(result);
+    return result;
   } else {
     return std::nullopt;
   }
@@ -891,7 +891,7 @@
   queue.Initialize();
   LocklessQueueSender result(queue.memory(), channel_storage_duration);
   if (result.sender_index_ != -1) {
-    return std::move(result);
+    return result;
   } else {
     return std::nullopt;
   }
@@ -1199,7 +1199,7 @@
   queue.Initialize();
   LocklessQueuePinner result(queue.memory(), queue.const_memory());
   if (result.pinner_index_ != -1) {
-    return std::move(result);
+    return result;
   } else {
     return std::nullopt;
   }
diff --git a/aos/network/web_proxy.h b/aos/network/web_proxy.h
index 2b57c05..e38dcea 100644
--- a/aos/network/web_proxy.h
+++ b/aos/network/web_proxy.h
@@ -229,7 +229,7 @@
     bool requested = true;
   };
 
-  std::map<int, ChannelState> channels_;
+  std::map<size_t, ChannelState> channels_;
   const std::vector<std::unique_ptr<Subscriber>> &subscribers_;
 
   const std::vector<FlatbufferDetachedBuffer<MessageHeader>> config_headers_;