Merge changes Ibf491d1c,I1a8db6fa,I8b47c486,I69911ec1

* changes:
  Update AWS C++ SDK to 1.10.34
  Debug Check added to catch RenameLogBase crash
  Add IsDisabled() to shm and simulated timers
  Add CHECK for remote timestamp channel frequencies
diff --git a/WORKSPACE b/WORKSPACE
index c926b0e..5e26090 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1228,7 +1228,7 @@
 )
 
 # This one is tricky to get an archive because it has recursive submodules. These semi-automated steps do work though:
-# git clone -b version1.9 --recurse-submodules --depth=1 https://github.com/aws/aws-sdk-cpp
+# git clone -b 1.10.34 --recurse-submodules --depth=1 https://github.com/aws/aws-sdk-cpp
 # cd aws-sdk-cpp
 # echo bsdtar -a -cf aws_sdk-version.tar.gz --ignore-zeros @\<\(git archive HEAD\) $(git submodule foreach --recursive --quiet 'echo @\<\(cd $displaypath \&\& git archive HEAD --prefix=$displaypath/\)')
 # Now run the command that printed, and the output will be at aws_sdk-version.tar.gz.
@@ -1237,8 +1237,8 @@
     build_file = "//debian:aws_sdk.BUILD",
     patch_args = ["-p1"],
     patches = ["//debian:aws_sdk.patch"],
-    sha256 = "1a2668722e5b5b2608a6ab21c876c1d98b5fd8c7d613129ced9561f5520817dc",
-    url = "https://www.frc971.org/Build-Dependencies/aws_sdk-19.0.0-RC1.tar.gz",
+    sha256 = "de6570d10c246189fd8c02100f7f0d9af8499a3ef94a131eeb85619f3bd6c604",
+    url = "https://www.frc971.org/Build-Dependencies/aws_sdk-1.10.34.tar.gz",
 )
 
 # Source code of LZ4 (files under lib/) are under BSD 2-Clause.
diff --git a/aos/events/event_loop.h b/aos/events/event_loop.h
index 68b5b35..471b625 100644
--- a/aos/events/event_loop.h
+++ b/aos/events/event_loop.h
@@ -484,6 +484,9 @@
   // Stop future calls to callback().
   virtual void Disable() = 0;
 
+  // Check if the timer is disabled
+  virtual bool IsDisabled() = 0;
+
   // Sets and gets the name of the timer.  Set this if you want a descriptive
   // name in the timing report.
   void set_name(std::string_view name) { name_ = std::string(name); }
diff --git a/aos/events/event_loop_param_test.cc b/aos/events/event_loop_param_test.cc
index 990cbe5..0c8e41e 100644
--- a/aos/events/event_loop_param_test.cc
+++ b/aos/events/event_loop_param_test.cc
@@ -524,6 +524,104 @@
   EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
 }
 
+// Tests that timer handler is enabled after setup (even if it is in the past)
+// and is disabled after running
+TEST_P(AbstractEventLoopTest, CheckTimerDisabled) {
+  auto loop = MakePrimary("primary");
+
+  auto timer = loop->AddTimer([this]() {
+    LOG(INFO) << "timer called";
+    Exit();
+  });
+
+  loop->OnRun([&loop, timer]() {
+    EXPECT_TRUE(timer->IsDisabled());
+    timer->Setup(loop->monotonic_now() + chrono::milliseconds(100));
+    EXPECT_FALSE(timer->IsDisabled());
+  });
+
+  Run();
+  EXPECT_TRUE(timer->IsDisabled());
+}
+
+// Tests that timer handler is enabled after setup (even if it is in the past)
+// and is disabled after running
+TEST_P(AbstractEventLoopTest, CheckTimerRunInPastDisabled) {
+  auto loop = MakePrimary("primary");
+
+  auto timer2 = loop->AddTimer([this]() {
+    LOG(INFO) << "timer called";
+    Exit();
+  });
+
+  auto timer = loop->AddTimer([&loop, timer2]() {
+    timer2->Setup(loop->monotonic_now() - chrono::nanoseconds(1));
+  });
+
+  loop->OnRun([&loop, timer]() {
+    timer->Setup(loop->monotonic_now() + chrono::seconds(1));
+    EXPECT_FALSE(timer->IsDisabled());
+  });
+
+  Run();
+  EXPECT_TRUE(timer2->IsDisabled());
+}
+
+// Tests that timer handler is not disabled even after calling Exit on the event
+// loop within the timer
+TEST_P(AbstractEventLoopTest, CheckTimerRepeatOnCountDisabled) {
+  auto loop = MakePrimary("primary");
+  int counter = 0;
+
+  auto timer = loop->AddTimer([&counter, this]() {
+    LOG(INFO) << "timer called";
+    counter++;
+    if (counter >= 5) {
+      Exit();
+    }
+  });
+
+  loop->OnRun([&loop, timer]() {
+    timer->Setup(loop->monotonic_now() + chrono::seconds(1),
+                 chrono::seconds(1));
+    EXPECT_FALSE(timer->IsDisabled());
+  });
+  Run();
+
+  // Sanity check
+  EXPECT_EQ(counter, 5);
+
+  // if you run the loop again, the timer will start running again
+  EXPECT_FALSE(timer->IsDisabled());
+
+  counter = 0;
+  Run();
+  timer->Disable();
+
+  EXPECT_TRUE(timer->IsDisabled());
+}
+
+// Tests that timer handler is not disabled even after calling Exit on the event
+// loop using an external timer
+TEST_P(AbstractEventLoopTest, CheckTimerRepeatTillEndTimerDisabled) {
+  auto loop = MakePrimary("primary");
+
+  auto timer = loop->AddTimer([]() { LOG(INFO) << "timer called"; });
+
+  loop->OnRun([&loop, timer]() {
+    timer->Setup(loop->monotonic_now() + chrono::seconds(1),
+                 chrono::seconds(1));
+    EXPECT_FALSE(timer->IsDisabled());
+  });
+
+  EndEventLoop(loop.get(), chrono::seconds(5));
+  Run();
+  EXPECT_FALSE(timer->IsDisabled());
+
+  timer->Disable();
+  EXPECT_TRUE(timer->IsDisabled());
+}
+
 // Tests that Fetch and FetchNext interleave as expected.
 TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
   auto loop1 = Make();
diff --git a/aos/events/logging/log_writer.cc b/aos/events/logging/log_writer.cc
index ab7d3c6..5671a3f 100644
--- a/aos/events/logging/log_writer.cc
+++ b/aos/events/logging/log_writer.cc
@@ -36,9 +36,9 @@
   timer_handler_->set_name("channel_poll");
   VLOG(1) << "Creating logger for " << FlatbufferToJson(node_);
 
-  // When we are logging remote timestamps, we need to be able to translate from
-  // the channel index that the event loop uses to the channel index in the
-  // config in the log file.
+  // When we are logging remote timestamps, we need to be able to translate
+  // from the channel index that the event loop uses to the channel index in
+  // the config in the log file.
   event_loop_to_logged_channel_index_.resize(
       event_loop->configuration()->channels()->size(), -1);
   for (size_t event_loop_channel_index = 0;
@@ -231,14 +231,20 @@
 }
 
 bool Logger::RenameLogBase(std::string new_base_name) {
-  if (new_base_name == log_namer_->base_name()) {
+  // TODO(Naman): Got a crash in RenameLogBase. Putting in a CHECK_NOTNULL to
+  // catch the bug if it happens again
+  if (new_base_name == CHECK_NOTNULL(log_namer_)->base_name()) {
     return true;
   }
   std::string current_directory = std::string(log_namer_->base_name());
   std::string new_directory = new_base_name;
 
   auto current_path_split = current_directory.rfind("/");
+  CHECK(current_path_split != std::string::npos)
+      << "Could not find / in the current directory path";
   auto new_path_split = new_directory.rfind("/");
+  CHECK(new_path_split != std::string::npos)
+      << "Could not find / in the new directory path";
 
   CHECK(new_base_name.substr(new_path_split) ==
         current_directory.substr(current_path_split))
@@ -365,9 +371,9 @@
   // worse.
   // TODO(austin): Test...
   //
-  // This is safe to call here since we have set last_synchronized_time_ as the
-  // same time as in the header, and all the data before it should be logged
-  // without ordering concerns.
+  // This is safe to call here since we have set last_synchronized_time_ as
+  // the same time as in the header, and all the data before it should be
+  // logged without ordering concerns.
   LogUntil(last_synchronized_time_);
 
   timer_handler_->Setup(event_loop_->monotonic_now() + polling_period_,
@@ -389,8 +395,8 @@
   std::unique_ptr<LogNamer> old_log_namer = std::move(log_namer_);
   log_namer_ = std::move(log_namer);
 
-  // Now grab a representative time on both the RT and monotonic clock.  Average
-  // a monotonic clock before and after to reduce the error.
+  // Now grab a representative time on both the RT and monotonic clock.
+  // Average a monotonic clock before and after to reduce the error.
   const aos::monotonic_clock::time_point beginning_time =
       event_loop_->monotonic_now();
   const aos::realtime_clock::time_point beginning_time_rt =
@@ -403,11 +409,11 @@
                  << "ns to swap log_namer";
   }
 
-  // Since we are going to log all in 1 big go, we need our log start time to be
-  // after the previous LogUntil call finished, but before 1 period after it.
-  // The best way to guarentee that is to pick a start time that is the earliest
-  // of the two.  That covers the case where the OS puts us to sleep between
-  // when we finish LogUntil and capture beginning_time.
+  // Since we are going to log all in 1 big go, we need our log start time to
+  // be after the previous LogUntil call finished, but before 1 period after
+  // it. The best way to guarentee that is to pick a start time that is the
+  // earliest of the two.  That covers the case where the OS puts us to sleep
+  // between when we finish LogUntil and capture beginning_time.
   const aos::monotonic_clock::time_point monotonic_start_time =
       std::min(last_synchronized_time_, beginning_time);
   const aos::realtime_clock::time_point realtime_start_time =
@@ -426,8 +432,9 @@
   // Note that WriteHeader updates last_synchronized_time_ to be the
   // current time when it is called, which is then the "start time"
   // of the new (restarted) log. This timestamp will be after
-  // the timestamp of the last message fetched on each channel, but is carefully
-  // picked per the comment above to not violate max_out_of_order_duration.
+  // the timestamp of the last message fetched on each channel, but is
+  // carefully picked per the comment above to not violate
+  // max_out_of_order_duration.
   WriteHeader(monotonic_start_time, realtime_start_time);
 
   const aos::monotonic_clock::time_point header_time =
@@ -762,8 +769,8 @@
 // Class to copy a context into the provided buffer.
 class ContextDataCopier : public DataEncoder::Copier {
  public:
-  ContextDataCopier(const Context &context, int channel_index,
-                     LogType log_type, EventLoop *event_loop)
+  ContextDataCopier(const Context &context, int channel_index, LogType log_type,
+                    EventLoop *event_loop)
       : DataEncoder::Copier(PackMessageSize(log_type, context.size)),
         context_(context),
         channel_index_(channel_index),
@@ -790,10 +797,10 @@
 // Class to copy a RemoteMessage into the provided buffer.
 class RemoteMessageCopier : public DataEncoder::Copier {
  public:
-  RemoteMessageCopier(
-      const message_bridge::RemoteMessage *message, int channel_index,
-      aos::monotonic_clock::time_point monotonic_timestamp_time,
-      EventLoop *event_loop)
+  RemoteMessageCopier(const message_bridge::RemoteMessage *message,
+                      int channel_index,
+                      aos::monotonic_clock::time_point monotonic_timestamp_time,
+                      EventLoop *event_loop)
       : DataEncoder::Copier(PackRemoteMessageSize()),
         message_(message),
         channel_index_(channel_index),
@@ -826,8 +833,8 @@
     // Write!
     const auto start = event_loop_->monotonic_now();
 
-    ContextDataCopier coppier(f.fetcher->context(), f.channel_index,
-                               f.log_type, event_loop_);
+    ContextDataCopier coppier(f.fetcher->context(), f.channel_index, f.log_type,
+                              event_loop_);
 
     writer->CopyMessage(&coppier, source_node_boot_uuid, start);
     RecordCreateMessageTime(start, coppier.end_time(), f);
@@ -852,7 +859,7 @@
 
     const auto start = event_loop_->monotonic_now();
     ContextDataCopier coppier(f.fetcher->context(), f.channel_index,
-                               LogType::kLogDeliveryTimeOnly, event_loop_);
+                              LogType::kLogDeliveryTimeOnly, event_loop_);
 
     timestamp_writer->CopyMessage(&coppier, event_loop_->boot_uuid(), start);
     RecordCreateMessageTime(start, coppier.end_time(), f);
@@ -902,7 +909,7 @@
         reliable, monotonic_timestamp_time);
 
     RemoteMessageCopier coppier(msg, channel_index, monotonic_timestamp_time,
-                                 event_loop_);
+                                event_loop_);
 
     contents_writer->CopyMessage(&coppier, UUID::FromVector(msg->boot_uuid()),
                                  start);
diff --git a/aos/events/shm_event_loop.cc b/aos/events/shm_event_loop.cc
index 5be5077..56d2357 100644
--- a/aos/events/shm_event_loop.cc
+++ b/aos/events/shm_event_loop.cc
@@ -599,6 +599,7 @@
 
     if (repeat_offset_ == std::chrono::seconds(0)) {
       timerfd_.Disable();
+      disabled_ = true;
     } else {
       // Compute how many cycles have elapsed and schedule the next iteration
       // for the next iteration in the future.
@@ -612,6 +613,7 @@
       event_.set_event_time(base_);
       shm_event_loop_->AddEvent(&event_);
       timerfd_.SetTime(base_, std::chrono::seconds(0));
+      disabled_ = false;
     }
   }
 
@@ -627,6 +629,7 @@
     repeat_offset_ = repeat_offset;
     event_.set_event_time(base_);
     shm_event_loop_->AddEvent(&event_);
+    disabled_ = false;
   }
 
   void Disable() override {
@@ -636,6 +639,8 @@
     disabled_ = true;
   }
 
+  bool IsDisabled() override { return disabled_; }
+
  private:
   ShmEventLoop *shm_event_loop_;
   EventHandler<ShmTimerHandler> event_;
@@ -647,7 +652,7 @@
 
   // Used to track if Disable() was called during the callback, so we know not
   // to reschedule.
-  bool disabled_ = false;
+  bool disabled_ = true;
 };
 
 // Adapter class to the timerfd and PhasedLoop.
diff --git a/aos/events/simulated_event_loop.cc b/aos/events/simulated_event_loop.cc
index 944a22b..22b9603 100644
--- a/aos/events/simulated_event_loop.cc
+++ b/aos/events/simulated_event_loop.cc
@@ -521,6 +521,8 @@
 
   void Disable() override;
 
+  bool IsDisabled() override;
+
  private:
   SimulatedEventLoop *simulated_event_loop_;
   EventHandler<SimulatedTimerHandler> event_;
@@ -529,6 +531,7 @@
 
   monotonic_clock::time_point base_;
   monotonic_clock::duration repeat_offset_;
+  bool disabled_ = true;
 };
 
 class SimulatedPhasedLoopHandler : public PhasedLoopHandler,
@@ -1201,6 +1204,7 @@
   token_ = scheduler_->Schedule(std::max(base, monotonic_now), this);
   event_.set_event_time(base_);
   simulated_event_loop_->AddEvent(&event_);
+  disabled_ = false;
 }
 
 void SimulatedTimerHandler::Handle() noexcept {
@@ -1232,8 +1236,10 @@
     token_ = scheduler_->Schedule(base_, this);
     event_.set_event_time(base_);
     simulated_event_loop_->AddEvent(&event_);
+    disabled_ = false;
+  } else {
+    disabled_ = true;
   }
-
   {
     ScopedMarkRealtimeRestorer rt(
         simulated_event_loop_->runtime_realtime_priority() > 0);
@@ -1251,8 +1257,11 @@
     }
     token_ = scheduler_->InvalidToken();
   }
+  disabled_ = true;
 }
 
+bool SimulatedTimerHandler::IsDisabled() { return disabled_; }
+
 SimulatedPhasedLoopHandler::SimulatedPhasedLoopHandler(
     EventScheduler *scheduler, SimulatedEventLoop *simulated_event_loop,
     ::std::function<void(int)> fn, const monotonic_clock::duration interval,
diff --git a/aos/network/BUILD b/aos/network/BUILD
index 96825e4..4794838 100644
--- a/aos/network/BUILD
+++ b/aos/network/BUILD
@@ -375,6 +375,21 @@
     deps = ["//aos/events:aos_config"],
 )
 
+aos_config(
+    name = "timestamp_channel_test_config",
+    src = "timestamp_channel_test.json",
+    flatbuffers = [
+        ":remote_message_fbs",
+        "//aos/events:ping_fbs",
+        "//aos/events:pong_fbs",
+        "//aos/network:message_bridge_client_fbs",
+        "//aos/network:message_bridge_server_fbs",
+        "//aos/network:timestamp_fbs",
+    ],
+    target_compatible_with = ["@platforms//os:linux"],
+    deps = ["//aos/events:aos_config"],
+)
+
 cc_test(
     name = "message_bridge_test",
     srcs = [
@@ -616,3 +631,19 @@
         "//aos/testing:googletest",
     ],
 )
+
+cc_test(
+    name = "timestamp_channel_test",
+    srcs = ["timestamp_channel_test.cc"],
+    data = [":timestamp_channel_test_config"],
+    deps = [
+        ":timestamp_channel",
+        "//aos:configuration",
+        "//aos/events:ping_fbs",
+        "//aos/events:shm_event_loop",
+        "//aos/events:simulated_event_loop",
+        "//aos/testing:googletest",
+        "//aos/testing:path",
+        "//aos/testing:tmpdir",
+    ],
+)
diff --git a/aos/network/message_bridge_test_combined_timestamps_common.json b/aos/network/message_bridge_test_combined_timestamps_common.json
index be79014..5d82965 100644
--- a/aos/network/message_bridge_test_combined_timestamps_common.json
+++ b/aos/network/message_bridge_test_combined_timestamps_common.json
@@ -75,8 +75,7 @@
     {
       "name": "/pi1/aos/remote_timestamps/pi2",
       "type": "aos.message_bridge.RemoteMessage",
-      "source_node": "pi1",
-      "frequency": 15
+      "source_node": "pi1"
     },
     {
       "name": "/pi2/aos/remote_timestamps/pi1",
diff --git a/aos/network/message_bridge_test_common.json b/aos/network/message_bridge_test_common.json
index 4623edb..a30734d 100644
--- a/aos/network/message_bridge_test_common.json
+++ b/aos/network/message_bridge_test_common.json
@@ -87,20 +87,17 @@
     {
       "name": "/pi1/aos/remote_timestamps/pi2/test/aos-examples-Ping",
       "type": "aos.message_bridge.RemoteMessage",
-      "source_node": "pi1",
-      "frequency": 15
+      "source_node": "pi1"
     },
     {
       "name": "/pi2/aos/remote_timestamps/pi1/test/aos-examples-Pong",
       "type": "aos.message_bridge.RemoteMessage",
-      "source_node": "pi2",
-      "frequency": 15
+      "source_node": "pi2"
     },
     {
       "name": "/pi1/aos/remote_timestamps/pi2/unreliable/aos-examples-Ping",
       "type": "aos.message_bridge.RemoteMessage",
-      "source_node": "pi1",
-      "frequency": 15
+      "source_node": "pi1"
     },
     {
       "name": "/pi1/aos",
diff --git a/aos/network/timestamp_channel.cc b/aos/network/timestamp_channel.cc
index fdaa031..f8f525f 100644
--- a/aos/network/timestamp_channel.cc
+++ b/aos/network/timestamp_channel.cc
@@ -109,6 +109,13 @@
 
   const Channel *timestamp_channel = finder.ForChannel(channel, connection);
 
+  // Sanity-check that the timestamp channel can actually support full-rate
+  // messages coming through on the source channel.
+  CHECK_GE(timestamp_channel->frequency(), channel->frequency())
+      << ": Timestamp channel "
+      << configuration::StrippedChannelToString(timestamp_channel)
+      << "'s rate is lower than the source channel.";
+
   {
     auto it = timestamp_loggers_.find(timestamp_channel);
     if (it != timestamp_loggers_.end()) {
diff --git a/aos/network/timestamp_channel_test.cc b/aos/network/timestamp_channel_test.cc
new file mode 100644
index 0000000..e3850ca
--- /dev/null
+++ b/aos/network/timestamp_channel_test.cc
@@ -0,0 +1,71 @@
+#include "aos/network/timestamp_channel.h"
+
+#include "aos/configuration.h"
+#include "aos/events/ping_generated.h"
+#include "aos/events/shm_event_loop.h"
+#include "aos/events/simulated_event_loop.h"
+#include "aos/testing/path.h"
+#include "aos/testing/tmpdir.h"
+#include "gtest/gtest.h"
+
+DECLARE_string(override_hostname);
+
+namespace aos::message_bridge::testing {
+class TimestampChannelTest : public ::testing::Test {
+ protected:
+  TimestampChannelTest()
+      : config_(aos::configuration::ReadConfig(aos::testing::ArtifactPath(
+            "aos/network/timestamp_channel_test_config.json"))) {
+    FLAGS_shm_base = aos::testing::TestTmpDir();
+    FLAGS_override_hostname = "pi1";
+  }
+  aos::FlatbufferDetachedBuffer<aos::Configuration> config_;
+};
+
+// Tests that creating a SimulatedEventLoopFactory with invalid remote timestamp
+// channel frequencies fails.
+TEST_F(TimestampChannelTest, SimulatedNetworkBridgeFrequencyMismatch) {
+  SimulatedEventLoopFactory factory(&config_.message());
+  EXPECT_DEATH(factory.RunFor(std::chrono::seconds(1)),
+               "rate is lower than the source channel");
+}
+
+class TimestampChannelParamTest
+    : public TimestampChannelTest,
+      public ::testing::WithParamInterface<
+          std::tuple<std::string, std::optional<std::string>>> {};
+
+// Tests whether we can or can't retrieve a timestamp channel depending on
+// whether it has a valid max frequency configured.
+TEST_P(TimestampChannelParamTest, ChannelFrequency) {
+  aos::ShmEventLoop event_loop(&config_.message());
+  ChannelTimestampSender timestamp_sender(&event_loop);
+  const aos::Channel *channel =
+      event_loop.GetChannel<aos::examples::Ping>(std::get<0>(GetParam()));
+  const std::optional<std::string> error_message = std::get<1>(GetParam());
+  if (error_message.has_value()) {
+    EXPECT_DEATH(timestamp_sender.SenderForChannel(
+                     channel, channel->destination_nodes()->Get(0)),
+                 error_message.value());
+  } else {
+    aos::Sender<RemoteMessage> *sender = timestamp_sender.SenderForChannel(
+        channel, channel->destination_nodes()->Get(0));
+    ASSERT_TRUE(sender != nullptr);
+    EXPECT_EQ(absl::StrCat("/pi1/aos/remote_timestamps/pi2",
+                           std::get<0>(GetParam()), "/aos-examples-Ping"),
+              sender->channel()->name()->string_view());
+  }
+}
+
+std::tuple<std::string, std::optional<std::string>> MakeParams(
+    std::string channel, std::optional<std::string> error) {
+  return std::make_tuple(channel, error);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    ChannelFrequencyTest, TimestampChannelParamTest,
+    ::testing::Values(MakeParams("/nominal", std::nullopt),
+                      MakeParams("/timestamps_too_fast", std::nullopt),
+                      MakeParams("/timestamps_too_slow",
+                                 "rate is lower than the source channel")));
+}  // namespace aos::message_bridge::testing
diff --git a/aos/network/timestamp_channel_test.json b/aos/network/timestamp_channel_test.json
new file mode 100644
index 0000000..f60cae8
--- /dev/null
+++ b/aos/network/timestamp_channel_test.json
@@ -0,0 +1,195 @@
+{
+  "channels": [
+    {
+      "name": "/pi1/aos",
+      "type": "aos.logging.LogMessageFbs",
+      "source_node": "pi1",
+      "frequency": 200,
+      "num_senders": 20,
+      "max_size": 2048
+    },
+    {
+      "name": "/pi2/aos",
+      "type": "aos.logging.LogMessageFbs",
+      "source_node": "pi2",
+      "frequency": 200,
+      "num_senders": 20,
+      "max_size": 2048
+    },
+    {
+      "name": "/pi1/aos",
+      "type": "aos.message_bridge.Timestamp",
+      "source_node": "pi1",
+      "frequency": 15,
+      "max_size": 200,
+      "destination_nodes": [
+        {
+          "name": "pi2",
+          "priority": 1,
+          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
+          "timestamp_logger_nodes": ["pi1"],
+          "time_to_live": 5000000
+        }
+      ]
+    },
+    {
+      "name": "/pi2/aos",
+      "type": "aos.message_bridge.Timestamp",
+      "source_node": "pi2",
+      "frequency": 15,
+      "max_size": 200,
+      "destination_nodes": [
+        {
+          "name": "pi1",
+          "priority": 1,
+          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
+          "timestamp_logger_nodes": ["pi2"],
+          "time_to_live": 5000000
+        }
+      ]
+    },
+    {
+      "name": "/pi1/aos/remote_timestamps/pi2/pi1/aos/aos-message_bridge-Timestamp",
+      "type": "aos.message_bridge.RemoteMessage",
+      "source_node": "pi1",
+      "frequency": 15
+    },
+    {
+      "name": "/pi2/aos/remote_timestamps/pi1/pi2/aos/aos-message_bridge-Timestamp",
+      "type": "aos.message_bridge.RemoteMessage",
+      "source_node": "pi2",
+      "frequency": 15
+    },
+    {
+      "name": "/pi1/aos",
+      "type": "aos.message_bridge.ServerStatistics",
+      "source_node": "pi1",
+      "frequency": 2
+    },
+    {
+      "name": "/pi2/aos",
+      "type": "aos.message_bridge.ServerStatistics",
+      "source_node": "pi2",
+      "frequency": 2
+    },
+    {
+      "name": "/pi1/aos",
+      "type": "aos.message_bridge.ClientStatistics",
+      "source_node": "pi1",
+      "frequency": 15
+    },
+    {
+      "name": "/pi2/aos",
+      "type": "aos.message_bridge.ClientStatistics",
+      "source_node": "pi2",
+      "frequency": 15
+    },
+    {
+      "name": "/pi1/aos",
+      "type": "aos.timing.Report",
+      "source_node": "pi1",
+      "frequency": 50,
+      "num_senders": 20,
+      "max_size": 2048
+    },
+    {
+      "name": "/pi2/aos",
+      "type": "aos.timing.Report",
+      "source_node": "pi2",
+      "frequency": 50,
+      "num_senders": 20,
+      "max_size": 2048
+    },
+    {
+      "name": "/pi1/aos/remote_timestamps/pi2/nominal/aos-examples-Ping",
+      "type": "aos.message_bridge.RemoteMessage",
+      "source_node": "pi1",
+      "frequency": 15
+    },
+    {
+      "name": "/pi1/aos/remote_timestamps/pi2/timestamps_too_slow/aos-examples-Ping",
+      "type": "aos.message_bridge.RemoteMessage",
+      "source_node": "pi1",
+      /* This frequency is configured lower than it should be. This will cause errors. */
+      "frequency": 5
+    },
+    {
+      "name": "/pi1/aos/remote_timestamps/pi2/timestamps_too_fast/aos-examples-Ping",
+      "type": "aos.message_bridge.RemoteMessage",
+      "source_node": "pi1",
+      /* This frequency is configured higher than it should be. This should not cause errors. */
+      "frequency": 10000
+    },
+    {
+      "name": "/nominal",
+      "type": "aos.examples.Ping",
+      "source_node": "pi1",
+      "frequency": 15,
+      "destination_nodes": [
+        {
+          "name": "pi2",
+          "timestamp_logger": "REMOTE_LOGGER",
+          "timestamp_logger_nodes": ["pi1"]
+        }
+      ]
+    },
+    {
+      "name": "/timestamps_too_slow",
+      "type": "aos.examples.Ping",
+      "source_node": "pi1",
+      "frequency": 15,
+      "destination_nodes": [
+        {
+          "name": "pi2",
+          "timestamp_logger": "REMOTE_LOGGER",
+          "timestamp_logger_nodes": ["pi1"]
+        }
+      ]
+    },
+    {
+      "name": "/timestamps_too_fast",
+      "type": "aos.examples.Ping",
+      "source_node": "pi1",
+      "frequency": 15,
+      "destination_nodes": [
+        {
+          "name": "pi2",
+          "timestamp_logger": "REMOTE_LOGGER",
+          "timestamp_logger_nodes": ["pi1"]
+        }
+      ]
+    }
+  ],
+  "maps": [
+    {
+      "match": {
+        "name": "/aos*",
+        "source_node": "pi1"
+      },
+      "rename": {
+        "name": "/pi1/aos"
+      }
+    },
+    {
+      "match": {
+        "name": "/aos*",
+        "source_node": "pi2"
+      },
+      "rename": {
+        "name": "/pi2/aos"
+      }
+    }
+  ],
+  "nodes": [
+    {
+      "name": "pi1",
+      "hostname": "pi1",
+      "port": 9971
+    },
+    {
+      "name": "pi2",
+      "hostname": "pi2",
+      "port": 9972
+    }
+  ]
+}
diff --git a/debian/aws_sdk.BUILD b/debian/aws_sdk.BUILD
index a77f5bb..46ac375 100644
--- a/debian/aws_sdk.BUILD
+++ b/debian/aws_sdk.BUILD
@@ -50,9 +50,9 @@
         "aws-cpp-sdk-core/include/aws/core/utils/crypto/openssl/*.h",
     ]),
     copts = [
-        "-DAWS_SDK_VERSION_MAJOR=19",
-        "-DAWS_SDK_VERSION_MINOR=0",
-        "-DAWS_SDK_VERSION_PATCH=\"\\\"0-RC1\"\\\"",
+        "-DAWS_SDK_VERSION_MAJOR=10",
+        "-DAWS_SDK_VERSION_MINOR=34",
+        "-DAWS_SDK_VERSION_PATCH=\"\\\"BRT\"\\\"",
         "-DENABLE_OPENSSL_ENCRYPTION",
         "-DENABLE_CURL_CLIENT",
         "-Wno-cast-align",
@@ -75,7 +75,7 @@
 genrule(
     name = "gen_Config",
     outs = ["crt/aws-crt-cpp/include/aws/crt/Config.h"],
-    cmd = "echo '#define AWS_CRT_CPP_VERSION \"19.0.0-RC1\"' > $@",
+    cmd = "echo '#define AWS_CRT_CPP_VERSION \"1.10.34\"' > $@",
     target_compatible_with = ["@platforms//os:linux"],
 )
 
@@ -88,15 +88,19 @@
     copts = [
         "-Wno-sign-compare",
         "-Wno-cast-qual",
+        "-Wno-tautological-type-limit-compare",
+        "-Wno-missing-field-initializers",
     ],
     includes = ["crt/aws-crt-cpp/include"],
     target_compatible_with = ["@platforms//os:linux"],
+    visibility = ["//visibility:public"],
     deps = [
         ":aws-c-auth",
         ":aws-c-common",
         ":aws-c-event-stream",
         ":aws-c-mqtt",
         ":aws-c-s3",
+        ":aws-c-sdkutils",
     ],
 )
 
@@ -109,6 +113,7 @@
         "#define AWS_HAVE_GCC_INLINE_ASM 1",
         "#undef AWS_HAVE_MSVC_MULX",
         "#define AWS_HAVE_EXECINFO 1",
+        "#define AWS_AFFINITY_METHOD 0",
         "END",
     ]),
     target_compatible_with = ["@platforms//os:linux"],
@@ -118,6 +123,7 @@
     name = "aws-c-common",
     srcs = glob([
         "crt/aws-crt-cpp/crt/aws-c-common/source/*.c",
+        "crt/aws-crt-cpp/crt/aws-c-common/source/external/*.c",
         "crt/aws-crt-cpp/crt/aws-c-common/source/posix/*.c",
     ]) + [
         ":gen_config",
@@ -156,6 +162,7 @@
     includes = ["crt/aws-crt-cpp/crt/aws-c-common/include"],
     target_compatible_with = ["@platforms//os:linux"],
     textual_hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-common/include/**/*.inl"]),
+    visibility = ["//visibility:public"],
 )
 
 # -march=armv8-a+crc
@@ -209,8 +216,10 @@
     ]),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-cal/include/**/*.h"]),
     copts = [
+        "-DOPENSSL_IS_AWSLC",
         "-Wno-incompatible-pointer-types",
         "-Wno-unused-function",
+        "-Wno-unused-parameter",
         "-Wno-cast-align",
         "-Wno-cast-qual",
     ],
@@ -235,6 +244,7 @@
     deps = [
         ":aws-c-auth",
         ":aws-c-common",
+        ":aws-checksums",
     ],
 )
 
@@ -242,6 +252,7 @@
     name = "aws-c-compression",
     srcs = glob(["crt/aws-crt-cpp/crt/aws-c-compression/source/*.c"]),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-compression/include/**/*.h"]),
+    copts = ["-Wno-cast-qual"],
     includes = ["crt/aws-crt-cpp/crt/aws-c-compression/include"],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
@@ -269,6 +280,21 @@
 )
 
 cc_library(
+    name = "aws-c-sdkutils",
+    srcs = glob(["crt/aws-crt-cpp/crt/aws-c-sdkutils/source/**/*.c"]),
+    hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-sdkutils/include/**/*.h"]),
+    copts = [
+        "-Wno-cast-align",
+        "-Wno-cast-qual",
+    ],
+    includes = ["crt/aws-crt-cpp/crt/aws-c-sdkutils/include"],
+    target_compatible_with = ["@platforms//os:linux"],
+    deps = [
+        ":aws-c-common",
+    ],
+)
+
+cc_library(
     name = "aws-c-auth",
     srcs = glob(["crt/aws-crt-cpp/crt/aws-c-auth/source/**/*.c"]),
     hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-auth/include/**/*.h"]),
@@ -282,6 +308,7 @@
         ":aws-c-common",
         ":aws-c-http",
         ":aws-c-io",
+        ":aws-c-sdkutils",
     ],
 )
 
@@ -292,11 +319,13 @@
     copts = [
         "-Wno-cast-qual",
         "-Wno-cast-align",
+        "-DAWS_MQTT_WITH_WEBSOCKETS",
     ],
     includes = ["crt/aws-crt-cpp/crt/aws-c-mqtt/include"],
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         ":aws-c-common",
+        ":aws-c-http",
         ":aws-c-io",
     ],
 )
@@ -309,8 +338,13 @@
         "crt/aws-crt-cpp/crt/aws-c-io/source/s2n/*.c",
         "crt/aws-crt-cpp/crt/aws-c-io/source/posix/*.c",
     ]),
-    hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-io/include/**/*.h"]),
+    hdrs = glob(["crt/aws-crt-cpp/crt/aws-c-io/include/**/*.h"]) + [
+        "crt/aws-crt-cpp/crt/aws-c-io/source/pkcs11_private.h",
+    ] + glob([
+        "crt/aws-crt-cpp/crt/aws-c-io/source/pkcs11/v2.40/*.h",
+    ]),
     copts = [
+        "-DUSE_S2N",
         "-DAWS_USE_EPOLL",
         "-Wno-cast-align",
         "-Wno-cast-qual",
@@ -335,6 +369,7 @@
         "crt/aws-crt-cpp/crt/s2n/utils/**/*.c",
         "crt/aws-crt-cpp/crt/s2n/stuffer/**/*.c",
         "crt/aws-crt-cpp/crt/s2n/crypto/**/*.c",
+        "crt/aws-crt-cpp/crt/s2n/pq-crypto/*.c",
     ]),
     hdrs = ["crt/aws-crt-cpp/crt/s2n/api/s2n.h"],
     copts = [
diff --git a/debian/aws_sdk.patch b/debian/aws_sdk.patch
index df613f5..8780e9b 100644
--- a/debian/aws_sdk.patch
+++ b/debian/aws_sdk.patch
@@ -4,89 +4,22 @@
 index 761455b..fc434ba 100644
 --- a/crt/aws-crt-cpp/crt/aws-c-cal/source/unix/openssl_platform_init.c
 +++ b/crt/aws-crt-cpp/crt/aws-c-cal/source/unix/openssl_platform_init.c
-@@ -34,7 +34,7 @@ struct openssl_evp_md_ctx_table *g_aws_openssl_evp_md_ctx_table = NULL;
+@@ -37,7 +37,7 @@ struct openssl_evp_md_ctx_table *g_aws_openssl_evp_md_ctx_table = NULL;
  /* 1.1 */
- extern HMAC_CTX *HMAC_CTX_new(void) __attribute__((weak)) __attribute__((used));
- extern void HMAC_CTX_free(HMAC_CTX *) __attribute__((weak)) __attribute__((used));
--extern int HMAC_CTX_reset(HMAC_CTX *) __attribute__((weak)) __attribute__((used));
-+//extern int HMAC_CTX_reset(HMAC_CTX *) __attribute__((weak)) __attribute__((used));
- 
+ extern HMAC_CTX *HMAC_CTX_new(void) __attribute__((weak, used));
+ extern void HMAC_CTX_free(HMAC_CTX *) __attribute__((weak, used));
+-extern int HMAC_CTX_reset(HMAC_CTX *) __attribute__((weak, used));
++//extern int HMAC_CTX_reset(HMAC_CTX *) __attribute__((weak, used));
+
  /* 1.0.2 */
- extern void HMAC_CTX_init(HMAC_CTX *) __attribute__((weak)) __attribute__((used));
-@@ -43,8 +43,8 @@ extern void HMAC_CTX_cleanup(HMAC_CTX *) __attribute__((weak)) __attribute__((us
+ extern void HMAC_CTX_init(HMAC_CTX *) __attribute__((weak, used));
+@@ -46,7 +46,7 @@ extern void HMAC_CTX_cleanup(HMAC_CTX *) __attribute__((weak)) __attribute__((us
  /* common */
- extern int HMAC_Update(HMAC_CTX *, const unsigned char *, size_t) __attribute__((weak)) __attribute__((used));
- extern int HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *) __attribute__((weak)) __attribute__((used));
--extern int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *) __attribute__((weak))
--__attribute__((used));
-+//extern int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *) __attribute__((weak))
-+//__attribute__((used));
- 
+ extern int HMAC_Update(HMAC_CTX *, const unsigned char *, size_t) __attribute__((weak, used));
+ extern int HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *) __attribute__((weak, used));
+-extern int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *) __attribute__((weak, used));
++//extern int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *) __attribute__((weak, used));
+
  /* libcrypto 1.1 stub for init */
  static void s_hmac_ctx_init_noop(HMAC_CTX *ctx) {
-@@ -393,9 +393,9 @@ void aws_cal_platform_init(struct aws_allocator *allocator) {
-         }
-     }
- 
--    if (!CRYPTO_get_id_callback()) {
--        CRYPTO_set_id_callback(s_id_fn);
--    }
-+    //if (!CRYPTO_get_id_callback()) {
-+        //CRYPTO_set_id_callback(s_id_fn);
-+    //}
- }
- 
- void aws_cal_platform_clean_up(void) {
-@@ -408,9 +408,9 @@ void aws_cal_platform_clean_up(void) {
-         aws_mem_release(s_libcrypto_allocator, s_libcrypto_locks);
-     }
- 
--    if (CRYPTO_get_id_callback() == s_id_fn) {
--        CRYPTO_set_id_callback(NULL);
--    }
-+    //if (CRYPTO_get_id_callback() == s_id_fn) {
-+        //CRYPTO_set_id_callback(NULL);
-+    //}
- }
- #if !defined(__GNUC__) || (__GNUC__ >= 4 && __GNUC_MINOR__ > 1)
- #    pragma GCC diagnostic pop
 Submodule crt/s2n contains modified content
-diff --git a/crt/aws-crt-cpp/crt/s2n/utils/s2n_asn1_time.c b/crt/aws-crt-cpp/crt/s2n/utils/s2n_asn1_time.c
-index 84dbc6df..d3566b81 100755
---- a/crt/aws-crt-cpp/crt/s2n/utils/s2n_asn1_time.c
-+++ b/crt/aws-crt-cpp/crt/s2n/utils/s2n_asn1_time.c
-@@ -46,7 +46,7 @@ typedef enum parser_state {
- } parser_state;
- 
- static inline long get_gmt_offset(struct tm *t) {
--#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__ANDROID__) || defined(ANDROID) || defined(__APPLE__) && defined(__MACH__)
-+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__ANDROID__) || defined(ANDROID) || defined(__APPLE__) && defined(__MACH__) || defined(__USE_MISC)
-     return t->tm_gmtoff;
- #else
-     return t->__tm_gmtoff;
-diff --git a/crt/aws-crt-cpp/crt/s2n/utils/s2n_init.c b/crt/aws-crt-cpp/crt/s2n/utils/s2n_init.c
-index 0f79f959..ae8122fb 100644
---- a/crt/aws-crt-cpp/crt/s2n/utils/s2n_init.c
-+++ b/crt/aws-crt-cpp/crt/s2n/utils/s2n_init.c
-@@ -45,7 +45,7 @@ int s2n_init(void)
-     GUARD_POSIX(s2n_security_policies_init());
-     GUARD_POSIX(s2n_config_defaults_init());
-     GUARD_POSIX(s2n_extension_type_init());
--    GUARD_AS_POSIX(s2n_pq_init());
-+    //GUARD_AS_POSIX(s2n_pq_init());
- 
-     S2N_ERROR_IF(atexit(s2n_cleanup_atexit) != 0, S2N_ERR_ATEXIT);
- 
-diff --git a/crt/aws-crt-cpp/crt/aws-c-common/include/aws/common/private/lookup3.inl b/crt/aws-crt-cpp/crt/aws-c-common/include/aws/common/private/lookup3.inl
-index 0f79f959..ae8122fb 100644
---- a/crt/aws-crt-cpp/crt/aws-c-common/include/aws/common/private/lookup3.inl
-+++ b/crt/aws-crt-cpp/crt/aws-c-common/include/aws/common/private/lookup3.inl
-@@ -533,7 +533,7 @@
-      * "CPROVER check pop". The masking trick does make the hash noticably
-      * faster for short strings (like English words).
-      */
--#ifndef VALGRIND
-+#if !defined(VALGRIND) && !__has_feature(address_sanitizer) && !__has_feature(memory_sanitizer)
- #ifdef CBMC
- #    pragma CPROVER check push
- #    pragma CPROVER check disable "pointer"
diff --git a/y2020/y2020_logger.json b/y2020/y2020_logger.json
index 451a2ee..911be81 100644
--- a/y2020/y2020_logger.json
+++ b/y2020/y2020_logger.json
@@ -190,7 +190,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "logger",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
diff --git a/y2020/y2020_pi_template.json b/y2020/y2020_pi_template.json
index 2b40728..cf54c23 100644
--- a/y2020/y2020_pi_template.json
+++ b/y2020/y2020_pi_template.json
@@ -199,7 +199,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "logger",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
@@ -249,7 +249,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "roborio",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     }
diff --git a/y2020/y2020_roborio.json b/y2020/y2020_roborio.json
index da52f28..eb97b1f 100644
--- a/y2020/y2020_roborio.json
+++ b/y2020/y2020_roborio.json
@@ -51,7 +51,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "roborio",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
diff --git a/y2022/y2022_imu.json b/y2022/y2022_imu.json
index bd2b326..bbe3a11 100644
--- a/y2022/y2022_imu.json
+++ b/y2022/y2022_imu.json
@@ -229,7 +229,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "logger",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
@@ -287,7 +287,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "roborio",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
@@ -351,7 +351,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "imu",
       "logger": "NOT_LOGGED",
-      "frequency": 200,
+      "frequency": 400,
       "num_senders": 2,
       "max_size": 200
     },
diff --git a/y2022/y2022_logger.json b/y2022/y2022_logger.json
index 0f790c7..01800bf 100644
--- a/y2022/y2022_logger.json
+++ b/y2022/y2022_logger.json
@@ -237,7 +237,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "logger",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
diff --git a/y2022/y2022_pi_template.json b/y2022/y2022_pi_template.json
index 99b04a1..4d3c427 100644
--- a/y2022/y2022_pi_template.json
+++ b/y2022/y2022_pi_template.json
@@ -218,14 +218,14 @@
     {
       "name": "/pi{{ NUM }}/aos/remote_timestamps/imu/pi{{ NUM }}/camera/y2022-vision-TargetEstimate",
       "type": "aos.message_bridge.RemoteMessage",
-      "frequency": 50,
+      "frequency": 80,
       "source_node": "pi{{ NUM }}",
       "max_size": 208
     },
     {
       "name": "/pi{{ NUM }}/aos/remote_timestamps/logger/pi{{ NUM }}/camera/y2022-vision-TargetEstimate",
       "type": "aos.message_bridge.RemoteMessage",
-      "frequency": 50,
+      "frequency": 80,
       "source_node": "pi{{ NUM }}",
       "max_size": 208
     },
@@ -300,7 +300,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "logger",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
@@ -350,7 +350,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "roborio",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     }
diff --git a/y2022/y2022_roborio.json b/y2022/y2022_roborio.json
index 85247ee..ff8d0c6 100644
--- a/y2022/y2022_roborio.json
+++ b/y2022/y2022_roborio.json
@@ -99,7 +99,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "roborio",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
diff --git a/y2022_bot3/y2022_bot3_imu.json b/y2022_bot3/y2022_bot3_imu.json
index 5673195..195592e 100644
--- a/y2022_bot3/y2022_bot3_imu.json
+++ b/y2022_bot3/y2022_bot3_imu.json
@@ -145,7 +145,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "roborio",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
diff --git a/y2022_bot3/y2022_bot3_roborio.json b/y2022_bot3/y2022_bot3_roborio.json
index 5f0b5ae..6485ed8 100644
--- a/y2022_bot3/y2022_bot3_roborio.json
+++ b/y2022_bot3/y2022_bot3_roborio.json
@@ -82,14 +82,14 @@
           ],
           "time_to_live": 5000000
         }
-      ] 
+      ]
     },
     {
       "name": "/roborio/aos/remote_timestamps/logger/roborio/aos/aos-starter-Status",
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "roborio",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
diff --git a/y2023/y2023_imu.json b/y2023/y2023_imu.json
index cc02067..7744281 100644
--- a/y2023/y2023_imu.json
+++ b/y2023/y2023_imu.json
@@ -229,7 +229,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "logger",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
@@ -287,7 +287,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "roborio",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
diff --git a/y2023/y2023_logger.json b/y2023/y2023_logger.json
index 09038ae..db313d2 100644
--- a/y2023/y2023_logger.json
+++ b/y2023/y2023_logger.json
@@ -207,7 +207,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "logger",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
diff --git a/y2023/y2023_pi_template.json b/y2023/y2023_pi_template.json
index 1430753..ba8f3c0 100644
--- a/y2023/y2023_pi_template.json
+++ b/y2023/y2023_pi_template.json
@@ -215,7 +215,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "logger",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },
@@ -265,7 +265,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "roborio",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     }
diff --git a/y2023/y2023_roborio.json b/y2023/y2023_roborio.json
index 4c5b282..e1306c2 100644
--- a/y2023/y2023_roborio.json
+++ b/y2023/y2023_roborio.json
@@ -99,7 +99,7 @@
       "type": "aos.message_bridge.RemoteMessage",
       "source_node": "roborio",
       "logger": "NOT_LOGGED",
-      "frequency": 20,
+      "frequency": 50,
       "num_senders": 2,
       "max_size": 200
     },