Nest all namespaces

The compiler supports this now.  We can type less going forward.
No functional changes.

Signed-off-by: Stephan Pleines <pleines.stephan@gmail.com>
Change-Id: I29d6fa4f9aacc0e381f1a7637294db0392466995
diff --git a/aos/actions/action_test.cc b/aos/actions/action_test.cc
index ea46ed8..c7c3c48 100644
--- a/aos/actions/action_test.cc
+++ b/aos/actions/action_test.cc
@@ -13,10 +13,7 @@
 #include "aos/events/simulated_event_loop.h"
 #include "aos/testing/path.h"
 
-namespace aos {
-namespace common {
-namespace actions {
-namespace testing {
+namespace aos::common::actions::testing {
 
 namespace chrono = ::std::chrono;
 
@@ -515,7 +512,4 @@
   event_loop_factory_.RunFor(chrono::seconds(2));
 }
 
-}  // namespace testing
-}  // namespace actions
-}  // namespace common
-}  // namespace aos
+}  // namespace aos::common::actions::testing
diff --git a/aos/actions/actions.cc b/aos/actions/actions.cc
index 764cb6c..133101b 100644
--- a/aos/actions/actions.cc
+++ b/aos/actions/actions.cc
@@ -1,8 +1,6 @@
 #include "aos/actions/actions.h"
 
-namespace aos {
-namespace common {
-namespace actions {
+namespace aos::common::actions {
 
 void ActionQueue::EnqueueAction(::std::unique_ptr<Action> action) {
   if (current_action_) {
@@ -70,6 +68,4 @@
   return false;
 }
 
-}  // namespace actions
-}  // namespace common
-}  // namespace aos
+}  // namespace aos::common::actions
diff --git a/aos/actions/actor.cc b/aos/actions/actor.cc
index 6a91c74..727b7a9 100644
--- a/aos/actions/actor.cc
+++ b/aos/actions/actor.cc
@@ -1,7 +1 @@
 #include "aos/actions/actor.h"
-
-namespace aos {
-namespace common {
-namespace actions {}  // namespace actions
-}  // namespace common
-}  // namespace aos
diff --git a/aos/condition_test.cc b/aos/condition_test.cc
index c83dc19..1551cb0 100644
--- a/aos/condition_test.cc
+++ b/aos/condition_test.cc
@@ -21,8 +21,7 @@
 #include "aos/time/time.h"
 #include "aos/type_traits/type_traits.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 namespace chrono = ::std::chrono;
 
@@ -382,5 +381,4 @@
   EXPECT_FALSE(child3.Hung());
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/configuration_test.cc b/aos/configuration_test.cc
index 560e5eb..e5fe303 100644
--- a/aos/configuration_test.cc
+++ b/aos/configuration_test.cc
@@ -13,9 +13,7 @@
 #include "aos/testing/test_logging.h"
 #include "aos/util/file.h"
 
-namespace aos {
-namespace configuration {
-namespace testing {
+namespace aos::configuration::testing {
 
 using aos::testing::ArtifactPath;
 namespace chrono = std::chrono;
@@ -1168,6 +1166,4 @@
   ASSERT_EQ(971, channel->frequency());
 }
 
-}  // namespace testing
-}  // namespace configuration
-}  // namespace aos
+}  // namespace aos::configuration::testing
diff --git a/aos/containers/error_list_test.cc b/aos/containers/error_list_test.cc
index b819ba5..94eabf9 100644
--- a/aos/containers/error_list_test.cc
+++ b/aos/containers/error_list_test.cc
@@ -4,8 +4,7 @@
 
 #include "aos/json_to_flatbuffer_generated.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 enum class TestEnum : int8_t {
   FOO = 0,
@@ -112,5 +111,4 @@
   EXPECT_EQ(b.size(), 3);
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/containers/inlined_vector_test.cc b/aos/containers/inlined_vector_test.cc
index 7368844..c9f2dd2 100644
--- a/aos/containers/inlined_vector_test.cc
+++ b/aos/containers/inlined_vector_test.cc
@@ -6,8 +6,7 @@
 
 DECLARE_bool(die_on_malloc);
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Checks that we don't malloc until/unless we need to increase the size of the
 // vector.
@@ -45,5 +44,4 @@
   zero.push_back(1);
   ASSERT_EQ(1, zero[0]);
 }
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/containers/priority_queue_test.cc b/aos/containers/priority_queue_test.cc
index 64456c4..f27a206 100644
--- a/aos/containers/priority_queue_test.cc
+++ b/aos/containers/priority_queue_test.cc
@@ -2,8 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Effectively copies the implementation of ::std::less just to demonstrate how
 // things work.
@@ -172,5 +171,4 @@
   EXPECT_EQ(11, it->a);
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/containers/ring_buffer_test.cc b/aos/containers/ring_buffer_test.cc
index b4cf1fb..c06ef0e 100644
--- a/aos/containers/ring_buffer_test.cc
+++ b/aos/containers/ring_buffer_test.cc
@@ -3,8 +3,7 @@
 #include "glog/logging.h"
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // A class which is implicitly convertible to and from int, and tracks object
 // lifetimes.
@@ -206,5 +205,4 @@
   EXPECT_EQ(i, buffer_.size());
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/containers/sized_array_test.cc b/aos/containers/sized_array_test.cc
index d055f40..645d669 100644
--- a/aos/containers/sized_array_test.cc
+++ b/aos/containers/sized_array_test.cc
@@ -2,8 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Tests the various ways of accessing elements.
 TEST(SizedArrayTest, ElementAccess) {
@@ -240,5 +239,4 @@
   EXPECT_EQ(a.size(), 1);
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/die_test.cc b/aos/die_test.cc
index 8c0a703..6b33b50 100644
--- a/aos/die_test.cc
+++ b/aos/die_test.cc
@@ -2,13 +2,11 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 TEST(DieDeathTest, Works) {
   EXPECT_EXIT(Die("str=%s num=%d\n", "hi", 5),
               ::testing::KilledBySignal(SIGABRT), ".*str=hi num=5\n");
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/events/epoll.cc b/aos/events/epoll.cc
index 340d0cd..8c5c3e1 100644
--- a/aos/events/epoll.cc
+++ b/aos/events/epoll.cc
@@ -15,8 +15,7 @@
 
 #include "aos/time/time.h"
 
-namespace aos {
-namespace internal {
+namespace aos::internal {
 
 TimerFd::TimerFd()
     : fd_(timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK)) {
@@ -298,5 +297,4 @@
       << ": Failed to " << operation << " epoll fd: " << event_data->fd;
 }
 
-}  // namespace internal
-}  // namespace aos
+}  // namespace aos::internal
diff --git a/aos/events/epoll_test.cc b/aos/events/epoll_test.cc
index b725747..e1be563 100644
--- a/aos/events/epoll_test.cc
+++ b/aos/events/epoll_test.cc
@@ -6,9 +6,7 @@
 #include "glog/logging.h"
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace internal {
-namespace testing {
+namespace aos::internal::testing {
 
 // A simple wrapper around both ends of a pipe along with some helpers to easily
 // read/write data through it.
@@ -204,6 +202,4 @@
   epoll_.Run();
 }
 
-}  // namespace testing
-}  // namespace internal
-}  // namespace aos
+}  // namespace aos::internal::testing
diff --git a/aos/events/event_loop_param_test.cc b/aos/events/event_loop_param_test.cc
index 5ec494f..58bfd9b 100644
--- a/aos/events/event_loop_param_test.cc
+++ b/aos/events/event_loop_param_test.cc
@@ -15,8 +15,7 @@
 #include "aos/logging/logging.h"
 #include "aos/realtime.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 namespace {
 namespace chrono = ::std::chrono;
 }  // namespace
@@ -3692,5 +3691,4 @@
   EXPECT_EQ(SendTestMessage(sender1), RawSender::Error::kMessagesSentTooFast);
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/events/glib_main_loop_test.cc b/aos/events/glib_main_loop_test.cc
index aabab68..6fced6d 100644
--- a/aos/events/glib_main_loop_test.cc
+++ b/aos/events/glib_main_loop_test.cc
@@ -10,8 +10,7 @@
 #include "aos/events/shm_event_loop.h"
 #include "aos/testing/path.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 using aos::testing::ArtifactPath;
 
 const FlatbufferDetachedBuffer<Configuration> &Config() {
@@ -128,5 +127,4 @@
   EXPECT_EQ(runs, 1);
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/events/logging/config_remapper_test.cc b/aos/events/logging/config_remapper_test.cc
index a1fedb2..f33f421 100644
--- a/aos/events/logging/config_remapper_test.cc
+++ b/aos/events/logging/config_remapper_test.cc
@@ -14,8 +14,7 @@
 #include "aos/testing/tmpdir.h"
 #include "multinode_logger_test_lib.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 using namespace logger::testing;
 using namespace logger;
 namespace chrono = std::chrono;
@@ -97,5 +96,4 @@
   EXPECT_EQ(channel->type()->string_view(), "aos.timing.Report");
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/events/logging/log_namer.cc b/aos/events/logging/log_namer.cc
index 6682ae3..3bbca3b 100644
--- a/aos/events/logging/log_namer.cc
+++ b/aos/events/logging/log_namer.cc
@@ -19,8 +19,7 @@
 
 DECLARE_int32(flush_size);
 
-namespace aos {
-namespace logger {
+namespace aos::logger {
 
 NewDataWriter::NewDataWriter(LogNamer *log_namer, const Node *node,
                              const Node *logger_node,
@@ -1192,5 +1191,4 @@
                      &data_writer->writer);
 }
 
-}  // namespace logger
-}  // namespace aos
+}  // namespace aos::logger
diff --git a/aos/events/logging/log_writer.cc b/aos/events/logging/log_writer.cc
index bc81a4b..f840c22 100644
--- a/aos/events/logging/log_writer.cc
+++ b/aos/events/logging/log_writer.cc
@@ -13,8 +13,7 @@
 #include "aos/network/timestamp_channel.h"
 #include "aos/sha256.h"
 
-namespace aos {
-namespace logger {
+namespace aos::logger {
 namespace {
 using message_bridge::RemoteMessage;
 namespace chrono = std::chrono;
@@ -921,5 +920,4 @@
   }
 }
 
-}  // namespace logger
-}  // namespace aos
+}  // namespace aos::logger
diff --git a/aos/events/logging/logfile_sorting.cc b/aos/events/logging/logfile_sorting.cc
index f67a88a..2eaf00b 100644
--- a/aos/events/logging/logfile_sorting.cc
+++ b/aos/events/logging/logfile_sorting.cc
@@ -27,8 +27,7 @@
 DEFINE_bool(quiet_sorting, false,
             "If true, sort with minimal messages about truncated files.");
 
-namespace aos {
-namespace logger {
+namespace aos::logger {
 namespace {
 namespace chrono = std::chrono;
 
@@ -2381,5 +2380,4 @@
   return false;
 }
 
-}  // namespace logger
-}  // namespace aos
+}  // namespace aos::logger
diff --git a/aos/events/logging/logfile_utils_test.cc b/aos/events/logging/logfile_utils_test.cc
index ea56d8d..30a0ada 100644
--- a/aos/events/logging/logfile_utils_test.cc
+++ b/aos/events/logging/logfile_utils_test.cc
@@ -22,9 +22,7 @@
 #include "aos/testing/tmpdir.h"
 #include "aos/util/file.h"
 
-namespace aos {
-namespace logger {
-namespace testing {
+namespace aos::logger::testing {
 namespace chrono = std::chrono;
 using aos::message_bridge::RemoteMessage;
 using aos::testing::ArtifactPath;
@@ -3386,6 +3384,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace logger
-}  // namespace aos
+}  // namespace aos::logger::testing
diff --git a/aos/events/logging/logger_test.cc b/aos/events/logging/logger_test.cc
index 5990a7a..3f0b182 100644
--- a/aos/events/logging/logger_test.cc
+++ b/aos/events/logging/logger_test.cc
@@ -26,9 +26,7 @@
 #include "aos/events/logging/lzma_encoder.h"
 #endif
 
-namespace aos {
-namespace logger {
-namespace testing {
+namespace aos::logger::testing {
 
 namespace chrono = std::chrono;
 using aos::message_bridge::RemoteMessage;
@@ -579,6 +577,4 @@
   EXPECT_EQ(replay_count, sent_messages);
 }
 
-}  // namespace testing
-}  // namespace logger
-}  // namespace aos
+}  // namespace aos::logger::testing
diff --git a/aos/events/logging/multinode_logger_test.cc b/aos/events/logging/multinode_logger_test.cc
index b8d07a2..3c438e3 100644
--- a/aos/events/logging/multinode_logger_test.cc
+++ b/aos/events/logging/multinode_logger_test.cc
@@ -12,9 +12,7 @@
 #include "aos/network/timestamp_generated.h"
 #include "aos/testing/tmpdir.h"
 
-namespace aos {
-namespace logger {
-namespace testing {
+namespace aos::logger::testing {
 
 namespace chrono = std::chrono;
 using aos::message_bridge::RemoteMessage;
@@ -4682,6 +4680,4 @@
   auto result = ConfirmReadable(filenames);
 }
 
-}  // namespace testing
-}  // namespace logger
-}  // namespace aos
+}  // namespace aos::logger::testing
diff --git a/aos/events/logging/multinode_logger_test_lib.cc b/aos/events/logging/multinode_logger_test_lib.cc
index 9b3e00c..ed62a2e 100644
--- a/aos/events/logging/multinode_logger_test_lib.cc
+++ b/aos/events/logging/multinode_logger_test_lib.cc
@@ -11,9 +11,7 @@
 
 DECLARE_bool(force_timestamp_loading);
 
-namespace aos {
-namespace logger {
-namespace testing {
+namespace aos::logger::testing {
 
 using aos::testing::ArtifactPath;
 
@@ -626,6 +624,4 @@
   return result;
 }
 
-}  // namespace testing
-}  // namespace logger
-}  // namespace aos
+}  // namespace aos::logger::testing
diff --git a/aos/events/pingpong_test.cc b/aos/events/pingpong_test.cc
index d35192a..c52e8eb 100644
--- a/aos/events/pingpong_test.cc
+++ b/aos/events/pingpong_test.cc
@@ -7,8 +7,7 @@
 #include "aos/json_to_flatbuffer.h"
 #include "aos/testing/path.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 using aos::testing::ArtifactPath;
 
@@ -168,5 +167,4 @@
   EXPECT_EQ(pi2_ping_count, 1001);
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/events/shm_event_loop_test.cc b/aos/events/shm_event_loop_test.cc
index 2134687..4db0c7d 100644
--- a/aos/events/shm_event_loop_test.cc
+++ b/aos/events/shm_event_loop_test.cc
@@ -10,8 +10,7 @@
 #include "aos/network/team_number.h"
 #include "aos/realtime.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 namespace {
 namespace chrono = ::std::chrono;
 
@@ -447,5 +446,4 @@
 INSTANTIATE_TEST_SUITE_P(ShmEventLoopPinDeathTest, ShmEventLoopDeathTest,
                          ::testing::Values(ReadMethod::PIN));
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/events/simulated_event_loop_test.cc b/aos/events/simulated_event_loop_test.cc
index 23badae..050c9a3 100644
--- a/aos/events/simulated_event_loop_test.cc
+++ b/aos/events/simulated_event_loop_test.cc
@@ -19,8 +19,7 @@
 #include "aos/network/timestamp_generated.h"
 #include "aos/testing/path.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 namespace {
 
 using aos::testing::ArtifactPath;
@@ -2462,5 +2461,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/events/simulated_network_bridge.cc b/aos/events/simulated_network_bridge.cc
index 3ed39fa..5c97292 100644
--- a/aos/events/simulated_network_bridge.cc
+++ b/aos/events/simulated_network_bridge.cc
@@ -7,8 +7,7 @@
 #include "aos/events/simulated_event_loop.h"
 #include "aos/network/remote_message_generated.h"
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 
 // This class delays messages forwarded between two factories.
 //
@@ -760,5 +759,4 @@
   });
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/events/timing_statistics.cc b/aos/events/timing_statistics.cc
index caf71da..ea3f2d2 100644
--- a/aos/events/timing_statistics.cc
+++ b/aos/events/timing_statistics.cc
@@ -4,8 +4,7 @@
 
 #include "aos/events/event_loop_generated.h"
 
-namespace aos {
-namespace internal {
+namespace aos::internal {
 
 void RawFetcherTiming::set_timing_report(timing::Fetcher *new_fetcher) {
   fetcher = new_fetcher;
@@ -74,5 +73,4 @@
   timer->mutate_count(0);
 }
 
-}  // namespace internal
-}  // namespace aos
+}  // namespace aos::internal
diff --git a/aos/events/timing_statistics_test.cc b/aos/events/timing_statistics_test.cc
index 9a7fefc..a8a45eb 100644
--- a/aos/events/timing_statistics_test.cc
+++ b/aos/events/timing_statistics_test.cc
@@ -4,9 +4,7 @@
 
 #include "aos/flatbuffers.h"
 
-namespace aos {
-namespace internal {
-namespace testing {
+namespace aos::internal::testing {
 
 TEST(TimingStatistic, StatisticsTest) {
   flatbuffers::FlatBufferBuilder fbb;
@@ -67,6 +65,4 @@
   EXPECT_NEAR(statistic.message().standard_deviation(), 5.2372293656638, 1e-6);
 }
 
-}  // namespace testing
-}  // namespace internal
-}  // namespace aos
+}  // namespace aos::internal::testing
diff --git a/aos/flatbuffer_introspection_test.cc b/aos/flatbuffer_introspection_test.cc
index a4b09f7..cc7d627 100644
--- a/aos/flatbuffer_introspection_test.cc
+++ b/aos/flatbuffer_introspection_test.cc
@@ -6,8 +6,7 @@
 #include "aos/testing/path.h"
 #include "aos/util/file.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 using aos::testing::ArtifactPath;
 
@@ -487,5 +486,4 @@
       "Need to provide a schema");
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/flatbuffer_merge_test.cc b/aos/flatbuffer_merge_test.cc
index 4c59879..a2ac088 100644
--- a/aos/flatbuffer_merge_test.cc
+++ b/aos/flatbuffer_merge_test.cc
@@ -9,8 +9,7 @@
 #include "aos/json_to_flatbuffer.h"
 #include "aos/json_to_flatbuffer_generated.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 std::string_view FromFbb(const flatbuffers::FlatBufferBuilder &fbb) {
   return std::string_view(
@@ -589,5 +588,4 @@
 // TODO(austin): unions
 // TODO(austin): struct
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/flatbuffers_test.cc b/aos/flatbuffers_test.cc
index 333d5d7..c4113e9 100644
--- a/aos/flatbuffers_test.cc
+++ b/aos/flatbuffers_test.cc
@@ -7,8 +7,7 @@
 #include "aos/json_to_flatbuffer_generated.h"
 #include "aos/testing/tmpdir.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Tests that Verify works.
 TEST(FlatbufferTest, Verify) {
@@ -87,5 +86,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/ipc_lib/aos_sync.cc b/aos/ipc_lib/aos_sync.cc
index 6bf5d8c..b1a9fb0 100644
--- a/aos/ipc_lib/aos_sync.cc
+++ b/aos/ipc_lib/aos_sync.cc
@@ -1054,9 +1054,7 @@
   return !__atomic_exchange_n(m, 0, __ATOMIC_SEQ_CST);
 }
 
-namespace aos {
-namespace linux_code {
-namespace ipc_lib {
+namespace aos::linux_code::ipc_lib {
 
 // Sets an extra offset between mutexes and the value we use for them in the
 // robust list (only the forward pointers). This is used to work around a kernel
@@ -1070,6 +1068,4 @@
 // This is mainly useful for testing.
 bool HaveLockedMutexes() { return my_robust_list::HaveLockedMutexes(); }
 
-}  // namespace ipc_lib
-}  // namespace linux_code
-}  // namespace aos
+}  // namespace aos::linux_code::ipc_lib
diff --git a/aos/ipc_lib/event_test.cc b/aos/ipc_lib/event_test.cc
index 40c48b2..eda9156 100644
--- a/aos/ipc_lib/event_test.cc
+++ b/aos/ipc_lib/event_test.cc
@@ -8,8 +8,7 @@
 #include "aos/testing/test_logging.h"
 #include "aos/time/time.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 namespace chrono = ::std::chrono;
 namespace this_thread = ::std::this_thread;
@@ -89,5 +88,4 @@
   EXPECT_GE(finish_time - start_time, kWaitTime);
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/ipc_lib/index.cc b/aos/ipc_lib/index.cc
index 4701f51..b6796b6 100644
--- a/aos/ipc_lib/index.cc
+++ b/aos/ipc_lib/index.cc
@@ -3,8 +3,7 @@
 #include <sstream>
 #include <string>
 
-namespace aos {
-namespace ipc_lib {
+namespace aos::ipc_lib {
 
 ::std::string QueueIndex::DebugString() const {
   if (valid()) {
@@ -29,5 +28,4 @@
   }
 }
 
-}  // namespace ipc_lib
-}  // namespace aos
+}  // namespace aos::ipc_lib
diff --git a/aos/ipc_lib/index_test.cc b/aos/ipc_lib/index_test.cc
index dca75a0..8e0da6d 100644
--- a/aos/ipc_lib/index_test.cc
+++ b/aos/ipc_lib/index_test.cc
@@ -3,9 +3,7 @@
 #include "glog/logging.h"
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace ipc_lib {
-namespace testing {
+namespace aos::ipc_lib::testing {
 
 class QueueIndexTest : public ::testing::Test {
  protected:
@@ -204,6 +202,4 @@
 #endif
 }
 
-}  // namespace testing
-}  // namespace ipc_lib
-}  // namespace aos
+}  // namespace aos::ipc_lib::testing
diff --git a/aos/ipc_lib/lockless_queue.cc b/aos/ipc_lib/lockless_queue.cc
index f033e60..a26b564 100644
--- a/aos/ipc_lib/lockless_queue.cc
+++ b/aos/ipc_lib/lockless_queue.cc
@@ -22,8 +22,7 @@
 DEFINE_bool(dump_lockless_queue_data, false,
             "If true, print the data out when dumping the queue.");
 
-namespace aos {
-namespace ipc_lib {
+namespace aos::ipc_lib {
 namespace {
 
 class GrabQueueSetupLockOrDie {
@@ -1662,5 +1661,4 @@
   ::std::cout << "}" << ::std::endl;
 }
 
-}  // namespace ipc_lib
-}  // namespace aos
+}  // namespace aos::ipc_lib
diff --git a/aos/ipc_lib/lockless_queue_death_test.cc b/aos/ipc_lib/lockless_queue_death_test.cc
index 92ad8a8..ccf95f7 100644
--- a/aos/ipc_lib/lockless_queue_death_test.cc
+++ b/aos/ipc_lib/lockless_queue_death_test.cc
@@ -27,9 +27,7 @@
 #include "aos/realtime.h"
 #include "aos/testing/test_logging.h"
 
-namespace aos {
-namespace ipc_lib {
-namespace testing {
+namespace aos::ipc_lib::testing {
 
 namespace chrono = ::std::chrono;
 
@@ -216,6 +214,4 @@
 
 #endif
 
-}  // namespace testing
-}  // namespace ipc_lib
-}  // namespace aos
+}  // namespace aos::ipc_lib::testing
diff --git a/aos/ipc_lib/lockless_queue_test.cc b/aos/ipc_lib/lockless_queue_test.cc
index 5b57aa9..bfd9916 100644
--- a/aos/ipc_lib/lockless_queue_test.cc
+++ b/aos/ipc_lib/lockless_queue_test.cc
@@ -39,9 +39,7 @@
 #endif
              "Number of threads to race");
 
-namespace aos {
-namespace ipc_lib {
-namespace testing {
+namespace aos::ipc_lib::testing {
 
 namespace chrono = ::std::chrono;
 
@@ -566,6 +564,4 @@
 
 #endif
 
-}  // namespace testing
-}  // namespace ipc_lib
-}  // namespace aos
+}  // namespace aos::ipc_lib::testing
diff --git a/aos/ipc_lib/memory_mapped_queue.cc b/aos/ipc_lib/memory_mapped_queue.cc
index 594febb..d73b850 100644
--- a/aos/ipc_lib/memory_mapped_queue.cc
+++ b/aos/ipc_lib/memory_mapped_queue.cc
@@ -6,8 +6,7 @@
 
 #include "absl/strings/str_cat.h"
 
-namespace aos {
-namespace ipc_lib {
+namespace aos::ipc_lib {
 
 std::string ShmFolder(std::string_view shm_base, const Channel *channel) {
   CHECK(channel->has_name());
@@ -140,5 +139,4 @@
   PCHECK(munmap(const_cast<void *>(const_data_), size_) == 0);
 }
 
-}  // namespace ipc_lib
-}  // namespace aos
+}  // namespace aos::ipc_lib
diff --git a/aos/ipc_lib/queue_racer.cc b/aos/ipc_lib/queue_racer.cc
index 27f3835..aa73f2b 100644
--- a/aos/ipc_lib/queue_racer.cc
+++ b/aos/ipc_lib/queue_racer.cc
@@ -8,8 +8,7 @@
 
 #include "aos/ipc_lib/event.h"
 
-namespace aos {
-namespace ipc_lib {
+namespace aos::ipc_lib {
 namespace {
 
 struct ThreadPlusCount {
@@ -428,5 +427,4 @@
   }
 }
 
-}  // namespace ipc_lib
-}  // namespace aos
+}  // namespace aos::ipc_lib
diff --git a/aos/ipc_lib/robust_ownership_tracker.cc b/aos/ipc_lib/robust_ownership_tracker.cc
index f106113..13edebc 100644
--- a/aos/ipc_lib/robust_ownership_tracker.cc
+++ b/aos/ipc_lib/robust_ownership_tracker.cc
@@ -2,8 +2,7 @@
 
 #include "aos/ipc_lib/lockless_queue.h"
 
-namespace aos {
-namespace ipc_lib {
+namespace aos::ipc_lib {
 
 ::std::string RobustOwnershipTracker::DebugString() const {
   ::std::stringstream s;
@@ -21,5 +20,4 @@
   return s.str();
 }
 
-}  // namespace ipc_lib
-}  // namespace aos
+}  // namespace aos::ipc_lib
diff --git a/aos/ipc_lib/shm_observers.cc b/aos/ipc_lib/shm_observers.cc
index 04a6214..2f28e46 100644
--- a/aos/ipc_lib/shm_observers.cc
+++ b/aos/ipc_lib/shm_observers.cc
@@ -1,8 +1,6 @@
 #include "aos/ipc_lib/shm_observers.h"
 
-namespace aos {
-namespace linux_code {
-namespace ipc_lib {
+namespace aos::linux_code::ipc_lib {
 
 ShmAccessorObserver before_observer = nullptr, after_observer = nullptr;
 
@@ -12,6 +10,4 @@
   after_observer = after;
 }
 
-}  // namespace ipc_lib
-}  // namespace linux_code
-}  // namespace aos
+}  // namespace aos::linux_code::ipc_lib
diff --git a/aos/ipc_lib/signalfd.cc b/aos/ipc_lib/signalfd.cc
index f23d0be..d25151d 100644
--- a/aos/ipc_lib/signalfd.cc
+++ b/aos/ipc_lib/signalfd.cc
@@ -12,8 +12,7 @@
 
 #include "glog/logging.h"
 
-namespace aos {
-namespace ipc_lib {
+namespace aos::ipc_lib {
 namespace {
 
 // Wrapper which propagates msan information.
@@ -118,5 +117,4 @@
   return result;
 }
 
-}  // namespace ipc_lib
-}  // namespace aos
+}  // namespace aos::ipc_lib
diff --git a/aos/ipc_lib/signalfd_test.cc b/aos/ipc_lib/signalfd_test.cc
index 40c0a13..2f349c1 100644
--- a/aos/ipc_lib/signalfd_test.cc
+++ b/aos/ipc_lib/signalfd_test.cc
@@ -5,9 +5,7 @@
 
 #include "aos/testing/test_logging.h"
 
-namespace aos {
-namespace ipc_lib {
-namespace testing {
+namespace aos::ipc_lib::testing {
 
 // Tests in this file use separate threads to isolate all manipulation of signal
 // masks between test cases.
@@ -72,6 +70,4 @@
                "Some other code unblocked one or more of our signals");
 }
 
-}  // namespace testing
-}  // namespace ipc_lib
-}  // namespace aos
+}  // namespace aos::ipc_lib::testing
diff --git a/aos/json_to_flatbuffer_test.cc b/aos/json_to_flatbuffer_test.cc
index 4900711..85e21d4 100644
--- a/aos/json_to_flatbuffer_test.cc
+++ b/aos/json_to_flatbuffer_test.cc
@@ -7,8 +7,7 @@
 #include "aos/json_to_flatbuffer_generated.h"
 #include "aos/testing/path.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 class JsonToFlatbufferTest : public ::testing::Test {
  public:
@@ -402,5 +401,4 @@
           ArtifactPath("aos/json_to_flatbuffer_test_spaces.json"))));
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/libc/aos_strerror_test.cc b/aos/libc/aos_strerror_test.cc
index abd867e..06a012a 100644
--- a/aos/libc/aos_strerror_test.cc
+++ b/aos/libc/aos_strerror_test.cc
@@ -4,9 +4,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace libc {
-namespace testing {
+namespace aos::libc::testing {
 
 // Tries a couple of easy ones.
 TEST(StrerrorTest, Basic) {
@@ -24,6 +22,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace libc
-}  // namespace aos
+}  // namespace aos::libc::testing
diff --git a/aos/libc/aos_strsignal_test.cc b/aos/libc/aos_strsignal_test.cc
index d854aab..7e91d46 100644
--- a/aos/libc/aos_strsignal_test.cc
+++ b/aos/libc/aos_strsignal_test.cc
@@ -5,9 +5,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace libc {
-namespace testing {
+namespace aos::libc::testing {
 
 // Tries a couple of easy ones.
 TEST(StrsignalTest, Basic) {
@@ -45,6 +43,4 @@
 }
 #endif
 
-}  // namespace testing
-}  // namespace libc
-}  // namespace aos
+}  // namespace aos::libc::testing
diff --git a/aos/libc/dirname.cc b/aos/libc/dirname.cc
index bc34496..e73030c 100644
--- a/aos/libc/dirname.cc
+++ b/aos/libc/dirname.cc
@@ -1,7 +1,6 @@
 #include "aos/libc/dirname.h"
 
-namespace aos {
-namespace libc {
+namespace aos::libc {
 namespace {
 
 ::std::string DoDirname(const ::std::string &path, size_t last_slash) {
@@ -35,5 +34,4 @@
   return DoDirname(path, last_slash);
 }
 
-}  // namespace libc
-}  // namespace aos
+}  // namespace aos::libc
diff --git a/aos/libc/dirname_test.cc b/aos/libc/dirname_test.cc
index d003936..501b752 100644
--- a/aos/libc/dirname_test.cc
+++ b/aos/libc/dirname_test.cc
@@ -4,9 +4,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace libc {
-namespace testing {
+namespace aos::libc::testing {
 
 // Tests the examples from the Linux man-pages release 3.44 dirname(3).
 TEST(DirnameTest, ManPageExamples) {
@@ -74,6 +72,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace libc
-}  // namespace aos
+}  // namespace aos::libc::testing
diff --git a/aos/logging/context.cc b/aos/logging/context.cc
index d1a6b03..5e5d53c 100644
--- a/aos/logging/context.cc
+++ b/aos/logging/context.cc
@@ -22,9 +22,7 @@
 
 #include "aos/logging/implementations.h"
 
-namespace aos {
-namespace logging {
-namespace internal {
+namespace aos::logging::internal {
 namespace {
 
 // TODO(brians): Differentiate between threads with the same name in the same
@@ -114,6 +112,4 @@
   delete_current_context = false;
 }
 
-}  // namespace internal
-}  // namespace logging
-}  // namespace aos
+}  // namespace aos::logging::internal
diff --git a/aos/logging/dynamic_logging.cc b/aos/logging/dynamic_logging.cc
index 1120a94..a3461b5 100644
--- a/aos/logging/dynamic_logging.cc
+++ b/aos/logging/dynamic_logging.cc
@@ -2,8 +2,7 @@
 
 #include "glog/logging.h"
 
-namespace aos {
-namespace logging {
+namespace aos::logging {
 
 DynamicLogging::DynamicLogging(aos::EventLoop *event_loop)
     : application_name_(event_loop->name()) {
@@ -31,5 +30,4 @@
   FLAGS_v = command.vlog_level();
 }
 
-}  // namespace logging
-}  // namespace aos
+}  // namespace aos::logging
diff --git a/aos/logging/dynamic_logging_test.cc b/aos/logging/dynamic_logging_test.cc
index 9b78113..70e491d 100644
--- a/aos/logging/dynamic_logging_test.cc
+++ b/aos/logging/dynamic_logging_test.cc
@@ -11,9 +11,7 @@
 
 using aos::testing::ArtifactPath;
 
-namespace aos {
-namespace logging {
-namespace testing {
+namespace aos::logging::testing {
 
 namespace chrono = std::chrono;
 
@@ -90,6 +88,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace logging
-}  // namespace aos
+}  // namespace aos::logging::testing
diff --git a/aos/logging/implementations.cc b/aos/logging/implementations.cc
index 3b4f905..da9e72b 100644
--- a/aos/logging/implementations.cc
+++ b/aos/logging/implementations.cc
@@ -8,8 +8,7 @@
 #include "aos/logging/printf_formats.h"
 #include "aos/time/time.h"
 
-namespace aos {
-namespace logging {
+namespace aos::logging {
 namespace internal {
 namespace {
 
@@ -83,5 +82,4 @@
   return context->implementation;
 }
 
-}  // namespace logging
-}  // namespace aos
+}  // namespace aos::logging
diff --git a/aos/logging/implementations_test.cc b/aos/logging/implementations_test.cc
index d08f85f..693a91e 100644
--- a/aos/logging/implementations_test.cc
+++ b/aos/logging/implementations_test.cc
@@ -14,9 +14,7 @@
 using ::testing::AssertionResult;
 using ::testing::AssertionSuccess;
 
-namespace aos {
-namespace logging {
-namespace testing {
+namespace aos::logging::testing {
 
 namespace chrono = ::std::chrono;
 
@@ -241,6 +239,4 @@
   ASSERT_EQ(curr_impl, GetImplementation().get());
 }
 
-}  // namespace testing
-}  // namespace logging
-}  // namespace aos
+}  // namespace aos::logging::testing
diff --git a/aos/logging/interface.cc b/aos/logging/interface.cc
index 233357d..e0ce6a8 100644
--- a/aos/logging/interface.cc
+++ b/aos/logging/interface.cc
@@ -12,8 +12,7 @@
 #include "aos/logging/context.h"
 #include "aos/logging/implementations.h"
 
-namespace aos {
-namespace logging {
+namespace aos::logging {
 namespace internal {
 
 size_t ExecuteFormat(char *output, size_t output_size, const char *format,
@@ -62,8 +61,7 @@
   }
 }
 
-}  // namespace logging
-}  // namespace aos
+}  // namespace aos::logging
 
 void log_do(log_level level, const char *format, ...) {
   va_list ap;
diff --git a/aos/logging/log_namer.cc b/aos/logging/log_namer.cc
index 4e9e00e..16ba0f2 100644
--- a/aos/logging/log_namer.cc
+++ b/aos/logging/log_namer.cc
@@ -33,8 +33,7 @@
               "The folder to log to.  If empty, search for the /media/sd*1/ "
               "folder and place logs there.");
 
-namespace aos {
-namespace logging {
+namespace aos::logging {
 namespace {
 void AllocateLogName(char **filename, const char *directory,
                      const char *basename) {
@@ -187,5 +186,4 @@
   return log_base_name.value();
 }
 
-}  // namespace logging
-}  // namespace aos
+}  // namespace aos::logging
diff --git a/aos/mutex/mutex_test.cc b/aos/mutex/mutex_test.cc
index ea57362..54e9201 100644
--- a/aos/mutex/mutex_test.cc
+++ b/aos/mutex/mutex_test.cc
@@ -17,8 +17,7 @@
 #include "aos/time/time.h"
 #include "aos/util/death_test_log_implementation.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 namespace chrono = ::std::chrono;
 namespace this_thread = ::std::this_thread;
@@ -322,5 +321,4 @@
   mutex->~Mutex();
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/network/message_bridge_client.cc b/aos/network/message_bridge_client.cc
index ef727eb..4a1992a 100644
--- a/aos/network/message_bridge_client.cc
+++ b/aos/network/message_bridge_client.cc
@@ -12,8 +12,7 @@
     wants_sctp_authentication, false,
     "When set, try to use SCTP authentication if provided by the kernel");
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 
 using ::aos::util::ReadFileToVecOrDie;
 
@@ -42,8 +41,7 @@
   return EXIT_SUCCESS;
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/aos/network/message_bridge_client_lib.cc b/aos/network/message_bridge_client_lib.cc
index bb233a9..620a069 100644
--- a/aos/network/message_bridge_client_lib.cc
+++ b/aos/network/message_bridge_client_lib.cc
@@ -34,8 +34,7 @@
 // To restore it, run:
 //   tc qdisc del dev eth0 root netem
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 namespace {
 namespace chrono = std::chrono;
 
@@ -541,5 +540,4 @@
   sender.CheckOk(sender.Send(builder.Finish()));
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/message_bridge_client_status.cc b/aos/network/message_bridge_client_status.cc
index 272e49e..9ca8418 100644
--- a/aos/network/message_bridge_client_status.cc
+++ b/aos/network/message_bridge_client_status.cc
@@ -7,8 +7,7 @@
 #include "aos/events/event_loop.h"
 #include "aos/network/message_bridge_client_generated.h"
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 namespace {
 namespace chrono = std::chrono;
 
@@ -240,5 +239,4 @@
                               kStatisticsPeriod);
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/message_bridge_protocol.cc b/aos/network/message_bridge_protocol.cc
index c661c4c..c527957 100644
--- a/aos/network/message_bridge_protocol.cc
+++ b/aos/network/message_bridge_protocol.cc
@@ -9,8 +9,7 @@
 #include "aos/flatbuffers.h"
 #include "aos/network/connect_generated.h"
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 
 aos::FlatbufferDetachedBuffer<aos::message_bridge::Connect> MakeConnectMessage(
     const Configuration *config, const Node *my_node,
@@ -66,5 +65,4 @@
   return fbb.Release();
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/message_bridge_retry_test.cc b/aos/network/message_bridge_retry_test.cc
index 4110a76..8229c99 100644
--- a/aos/network/message_bridge_retry_test.cc
+++ b/aos/network/message_bridge_retry_test.cc
@@ -18,10 +18,7 @@
 
 DECLARE_int32(force_wmem_max);
 
-namespace aos {
-
-namespace message_bridge {
-namespace testing {
+namespace aos::message_bridge::testing {
 
 void SendPing(aos::Sender<examples::Ping> *sender, int value) {
   aos::Sender<examples::Ping>::Builder builder = sender->MakeBuilder();
@@ -136,6 +133,4 @@
                          ::testing::Values(Param{
                              "message_bridge_test_common_config.json", false}));
 
-}  // namespace testing
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge::testing
diff --git a/aos/network/message_bridge_server.cc b/aos/network/message_bridge_server.cc
index be6cc8e..64c57f5 100644
--- a/aos/network/message_bridge_server.cc
+++ b/aos/network/message_bridge_server.cc
@@ -14,8 +14,7 @@
     wants_sctp_authentication, false,
     "When set, try to use SCTP authentication if provided by the kernel");
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 
 using ::aos::util::ReadFileToVecOrDie;
 
@@ -43,8 +42,7 @@
   return EXIT_SUCCESS;
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/aos/network/message_bridge_server_lib.cc b/aos/network/message_bridge_server_lib.cc
index 4f582e7..a2df830 100644
--- a/aos/network/message_bridge_server_lib.cc
+++ b/aos/network/message_bridge_server_lib.cc
@@ -57,8 +57,7 @@
 
 DECLARE_bool(use_sctp_authentication);
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 namespace chrono = std::chrono;
 
 // How often we should poll for the active SCTP authentication key.
@@ -862,5 +861,4 @@
   sender.CheckOk(sender.Send(builder.Finish()));
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/message_bridge_server_status.cc b/aos/network/message_bridge_server_status.cc
index f540b1e..0e8c6b0 100644
--- a/aos/network/message_bridge_server_status.cc
+++ b/aos/network/message_bridge_server_status.cc
@@ -12,8 +12,7 @@
 #include "aos/network/timestamp_filter.h"
 #include "aos/network/timestamp_generated.h"
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 namespace {
 
 namespace chrono = std::chrono;
@@ -507,5 +506,4 @@
                               kPingPeriod);
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/message_bridge_test.cc b/aos/network/message_bridge_test.cc
index cc46926..c211c89 100644
--- a/aos/network/message_bridge_test.cc
+++ b/aos/network/message_bridge_test.cc
@@ -16,10 +16,7 @@
 #include "aos/testing/path.h"
 #include "aos/util/file.h"
 
-namespace aos {
-
-namespace message_bridge {
-namespace testing {
+namespace aos::message_bridge::testing {
 
 // Note: All of these tests spin up ShmEventLoop's in separate threads to allow
 // us to run the "real" message bridge. This requires extra threading and timing
@@ -1440,6 +1437,4 @@
               true},
         Param{"message_bridge_test_common_config.json", false}));
 
-}  // namespace testing
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge::testing
diff --git a/aos/network/message_bridge_test_lib.cc b/aos/network/message_bridge_test_lib.cc
index 16e4a4b..0062bfd 100644
--- a/aos/network/message_bridge_test_lib.cc
+++ b/aos/network/message_bridge_test_lib.cc
@@ -2,8 +2,7 @@
 
 DECLARE_string(boot_uuid);
 
-namespace aos {
-namespace message_bridge::testing {
+namespace aos::message_bridge::testing {
 
 namespace chrono = std::chrono;
 using aos::testing::ArtifactPath;
@@ -286,5 +285,4 @@
   pi2_test_thread.reset();
 }
 
-}  // namespace message_bridge::testing
-}  // namespace aos
+}  // namespace aos::message_bridge::testing
diff --git a/aos/network/multinode_timestamp_filter.cc b/aos/network/multinode_timestamp_filter.cc
index b4ebef4..0a0385e 100644
--- a/aos/network/multinode_timestamp_filter.cc
+++ b/aos/network/multinode_timestamp_filter.cc
@@ -64,8 +64,7 @@
 #define SOLVE_VLOG(solve_number, v) \
   LOG_IF(INFO, SOLVE_VLOG_IS_ON(solve_number, v))
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 namespace {
 namespace chrono = std::chrono;
 using aos::logger::BootDuration;
@@ -3359,5 +3358,4 @@
   }
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/multinode_timestamp_filter_test.cc b/aos/network/multinode_timestamp_filter_test.cc
index 9aa76c0..e581a74 100644
--- a/aos/network/multinode_timestamp_filter_test.cc
+++ b/aos/network/multinode_timestamp_filter_test.cc
@@ -10,9 +10,7 @@
 #include "aos/network/testing_time_converter.h"
 #include "aos/network/timestamp_filter.h"
 
-namespace aos {
-namespace message_bridge {
-namespace testing {
+namespace aos::message_bridge::testing {
 
 namespace chrono = std::chrono;
 using aos::monotonic_clock;
@@ -538,6 +536,4 @@
       << derivatives.df_slope_limited;
 }
 
-}  // namespace testing
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge::testing
diff --git a/aos/network/rawrtc.cc b/aos/network/rawrtc.cc
index db4de07..e519b2e 100644
--- a/aos/network/rawrtc.cc
+++ b/aos/network/rawrtc.cc
@@ -17,8 +17,7 @@
 DEFINE_int32(max_ice_port, -1,
              "Maximum port number to use for ICE candidates.");
 
-namespace aos {
-namespace web_proxy {
+namespace aos::web_proxy {
 namespace {
 enum {
   TRANSPORT_BUFFER_LENGTH = 1048576,  // 1 MiB
@@ -299,5 +298,4 @@
   }
 }
 
-}  // namespace web_proxy
-}  // namespace aos
+}  // namespace aos::web_proxy
diff --git a/aos/network/sctp_client.cc b/aos/network/sctp_client.cc
index a9567a2..32347fd 100644
--- a/aos/network/sctp_client.cc
+++ b/aos/network/sctp_client.cc
@@ -18,8 +18,7 @@
              "Timeout in milliseconds for retrying the INIT packet when "
              "connecting to the message bridge server");
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 
 SctpClient::SctpClient(std::string_view remote_host, int remote_port,
                        int streams, std::string_view local_host, int local_port,
@@ -67,5 +66,4 @@
 #endif
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/sctp_lib.cc b/aos/network/sctp_lib.cc
index 99a7f09..829ae67 100644
--- a/aos/network/sctp_lib.cc
+++ b/aos/network/sctp_lib.cc
@@ -26,8 +26,7 @@
 DEFINE_bool(disable_ipv6, false, "disable ipv6");
 DEFINE_int32(rmem, 0, "If nonzero, set rmem to this size.");
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 
 namespace {
 const char *sac_state_tbl[] = {"COMMUNICATION_UP", "COMMUNICATION_LOST",
@@ -788,5 +787,4 @@
   }
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/sctp_server.cc b/aos/network/sctp_server.cc
index f4dba39..7f7a0ae 100644
--- a/aos/network/sctp_server.cc
+++ b/aos/network/sctp_server.cc
@@ -18,8 +18,7 @@
 #include "aos/network/sctp_lib.h"
 #include "aos/unique_malloc_ptr.h"
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 
 SctpServer::SctpServer(int streams, std::string_view local_host, int local_port,
                        SctpAuthMethod requested_authentication)
@@ -109,5 +108,4 @@
 #endif
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/team_number.cc b/aos/network/team_number.cc
index 8885b52..28ee67a 100644
--- a/aos/network/team_number.cc
+++ b/aos/network/team_number.cc
@@ -13,8 +13,7 @@
     "If set, this forces the hostname of this node to be the provided "
     "hostname.");
 
-namespace aos {
-namespace network {
+namespace aos::network {
 namespace team_number_internal {
 
 std::optional<uint16_t> ParseRoborioTeamNumber(
@@ -150,5 +149,4 @@
   return number;
 }
 
-}  // namespace network
-}  // namespace aos
+}  // namespace aos::network
diff --git a/aos/network/team_number_test.cc b/aos/network/team_number_test.cc
index 68727e2..1ca3fc2 100644
--- a/aos/network/team_number_test.cc
+++ b/aos/network/team_number_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace network {
-namespace testing {
+namespace aos::network::testing {
 
 using team_number_internal::ParsePiTeamNumber;
 using team_number_internal::ParseRoborioTeamNumber;
@@ -49,6 +47,4 @@
   EXPECT_FALSE(ParsePiNumber("pi-971"));
 }
 
-}  // namespace testing
-}  // namespace network
-}  // namespace aos
+}  // namespace aos::network::testing
diff --git a/aos/network/testing_time_converter.cc b/aos/network/testing_time_converter.cc
index 9dc5fff..255826e 100644
--- a/aos/network/testing_time_converter.cc
+++ b/aos/network/testing_time_converter.cc
@@ -9,8 +9,7 @@
 #include "aos/network/multinode_timestamp_filter.h"
 #include "aos/time/time.h"
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 
 namespace chrono = std::chrono;
 
@@ -125,5 +124,4 @@
   return result;
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/timestamp_channel.cc b/aos/network/timestamp_channel.cc
index 52032f5..778c2e7 100644
--- a/aos/network/timestamp_channel.cc
+++ b/aos/network/timestamp_channel.cc
@@ -10,8 +10,7 @@
             "channels are configured to have at least as great a frequency as "
             "the corresponding data channel.");
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 
 ChannelTimestampFinder::ChannelTimestampFinder(
     const Configuration *configuration, const std::string_view name,
@@ -143,5 +142,4 @@
   return result.first->second.get();
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/timestamp_filter.cc b/aos/network/timestamp_filter.cc
index 9736679..914f993 100644
--- a/aos/network/timestamp_filter.cc
+++ b/aos/network/timestamp_filter.cc
@@ -11,8 +11,7 @@
 #include "aos/configuration.h"
 #include "aos/time/time.h"
 
-namespace aos {
-namespace message_bridge {
+namespace aos::message_bridge {
 namespace {
 namespace chrono = std::chrono;
 using logger::BootDuration;
@@ -1786,5 +1785,4 @@
   }
 }
 
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge
diff --git a/aos/network/timestamp_filter_test.cc b/aos/network/timestamp_filter_test.cc
index 07f7d6d..f3b7290 100644
--- a/aos/network/timestamp_filter_test.cc
+++ b/aos/network/timestamp_filter_test.cc
@@ -9,9 +9,7 @@
 #include "aos/json_to_flatbuffer.h"
 #include "aos/macros.h"
 
-namespace aos {
-namespace message_bridge {
-namespace testing {
+namespace aos::message_bridge::testing {
 
 namespace chrono = std::chrono;
 using aos::monotonic_clock;
@@ -1673,6 +1671,4 @@
   EXPECT_EQ(estimator.GetFilter(node_b)->timestamps_size(), 2u);
 }
 
-}  // namespace testing
-}  // namespace message_bridge
-}  // namespace aos
+}  // namespace aos::message_bridge::testing
diff --git a/aos/network/web_proxy.cc b/aos/network/web_proxy.cc
index d48d700..15ebb66 100644
--- a/aos/network/web_proxy.cc
+++ b/aos/network/web_proxy.cc
@@ -34,8 +34,7 @@
               "If we have not received any ack's in this amount of time, we "
               "start to continue sending messages.");
 
-namespace aos {
-namespace web_proxy {
+namespace aos::web_proxy {
 WebsocketHandler::WebsocketHandler(::seasocks::Server *server,
                                    aos::EventLoop *event_loop,
                                    StoreHistory store_history,
@@ -699,5 +698,4 @@
   }
 }
 
-}  // namespace web_proxy
-}  // namespace aos
+}  // namespace aos::web_proxy
diff --git a/aos/network/web_proxy_utils.cc b/aos/network/web_proxy_utils.cc
index d6148d4..f4468ab 100644
--- a/aos/network/web_proxy_utils.cc
+++ b/aos/network/web_proxy_utils.cc
@@ -1,7 +1,6 @@
 #include "aos/network/web_proxy_utils.h"
 
-namespace aos {
-namespace web_proxy {
+namespace aos::web_proxy {
 
 namespace {
 // Recommended max size is 64KiB for compatibility reasons. 256KiB theoretically
@@ -98,5 +97,4 @@
   return buffers;
 }
 
-}  // namespace web_proxy
-}  // namespace aos
+}  // namespace aos::web_proxy
diff --git a/aos/realtime.cc b/aos/realtime.cc
index 22b864e..72daa6b 100644
--- a/aos/realtime.cc
+++ b/aos/realtime.cc
@@ -53,14 +53,13 @@
     FLAGS_tcmalloc_release_rate;
 
 namespace aos {
-namespace logging {
-namespace internal {
+
+namespace logging::internal {
 
 // Implemented in aos/logging/context.cc.
 void ReloadThreadName() __attribute__((weak));
 
-}  // namespace internal
-}  // namespace logging
+}  // namespace logging::internal
 
 namespace {
 
diff --git a/aos/realtime_test.cc b/aos/realtime_test.cc
index 97f21c8..348489b 100644
--- a/aos/realtime_test.cc
+++ b/aos/realtime_test.cc
@@ -8,8 +8,7 @@
 
 DECLARE_bool(die_on_malloc);
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Tests that ScopedRealtime handles the simple case.
 TEST(RealtimeTest, ScopedRealtime) {
@@ -133,8 +132,7 @@
 
 #endif
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
 
 // We need a special gtest main to force die_on_malloc support on.  Otherwise
 // we can't test CHECK statements before turning die_on_malloc on globally.
diff --git a/aos/seasocks/seasocks_logger.cc b/aos/seasocks/seasocks_logger.cc
index 440a3ba..a9d83bc 100644
--- a/aos/seasocks/seasocks_logger.cc
+++ b/aos/seasocks/seasocks_logger.cc
@@ -4,8 +4,7 @@
 
 #include "seasocks/PrintfLogger.h"
 
-namespace aos {
-namespace seasocks {
+namespace aos::seasocks {
 
 void SeasocksLogger::log(::seasocks::Logger::Level level, const char *message) {
   // Convert Seasocks error codes to glog.
@@ -33,5 +32,4 @@
   LOG_AT_LEVEL(glog_level) << "Seasocks: " << message;
 }
 
-}  // namespace seasocks
-}  // namespace aos
+}  // namespace aos::seasocks
diff --git a/aos/starter/mock_starter.cc b/aos/starter/mock_starter.cc
index 9f9a2b5..541e17f 100644
--- a/aos/starter/mock_starter.cc
+++ b/aos/starter/mock_starter.cc
@@ -1,7 +1,6 @@
 #include "aos/starter/mock_starter.h"
 
-namespace aos {
-namespace starter {
+namespace aos::starter {
 
 MockStarter::MockStarter(aos::EventLoop *event_loop)
     : event_loop_(event_loop),
@@ -119,5 +118,4 @@
   }
 }
 
-}  // namespace starter
-}  // namespace aos
+}  // namespace aos::starter
diff --git a/aos/starter/starter_rpc_lib.cc b/aos/starter/starter_rpc_lib.cc
index 4e9ceef..891355e 100644
--- a/aos/starter/starter_rpc_lib.cc
+++ b/aos/starter/starter_rpc_lib.cc
@@ -6,8 +6,7 @@
 #include "aos/flatbuffer_merge.h"
 #include "aos/starter/starterd_lib.h"
 
-namespace aos {
-namespace starter {
+namespace aos::starter {
 
 namespace {
 State ExpectedStateForCommand(Command command) {
@@ -307,5 +306,4 @@
                    status_fetcher.CopyFlatBuffer()));
 }
 
-}  // namespace starter
-}  // namespace aos
+}  // namespace aos::starter
diff --git a/aos/starter/starter_test.cc b/aos/starter/starter_test.cc
index e68cf05..d26f414 100644
--- a/aos/starter/starter_test.cc
+++ b/aos/starter/starter_test.cc
@@ -17,8 +17,7 @@
 
 using aos::testing::ArtifactPath;
 
-namespace aos {
-namespace starter {
+namespace aos::starter {
 
 class ThreadedStarterRunner {
  public:
@@ -572,5 +571,4 @@
   ASSERT_FALSE(starter.event_loop()->is_running());
 }
 
-}  // namespace starter
-}  // namespace aos
+}  // namespace aos::starter
diff --git a/aos/starter/starterd_lib.cc b/aos/starter/starterd_lib.cc
index bf0fc31..95210c0 100644
--- a/aos/starter/starterd_lib.cc
+++ b/aos/starter/starterd_lib.cc
@@ -20,8 +20,7 @@
               "Number of threads to spin up to initialize the queue.  0 means "
               "use the main thread.");
 
-namespace aos {
-namespace starter {
+namespace aos::starter {
 
 const aos::Channel *StatusChannelForNode(const aos::Configuration *config,
                                          const aos::Node *node) {
@@ -315,5 +314,4 @@
           << shm_base_;
 }
 
-}  // namespace starter
-}  // namespace aos
+}  // namespace aos::starter
diff --git a/aos/stl_mutex/stl_mutex_test.cc b/aos/stl_mutex/stl_mutex_test.cc
index 5e88c56..5343974 100644
--- a/aos/stl_mutex/stl_mutex_test.cc
+++ b/aos/stl_mutex/stl_mutex_test.cc
@@ -4,8 +4,7 @@
 
 #include "aos/die.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 class StlMutexDeathTest : public ::testing::Test {
  protected:
@@ -65,5 +64,4 @@
   EXPECT_DEATH(mutex.unlock(), ".*multiple unlock.*");
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/testing/gtest_main.cc b/aos/testing/gtest_main.cc
index 2fb77fe..6071bde 100644
--- a/aos/testing/gtest_main.cc
+++ b/aos/testing/gtest_main.cc
@@ -14,16 +14,13 @@
 DEFINE_string(log_file, "",
               "Print all log messages to FILE instead of standard output.");
 
-namespace aos {
-
-namespace testing {
+namespace aos::testing {
 
 // Actually declared/defined in //aos/testing:test_logging.
 void SetLogFileName(const char *filename) __attribute__((weak));
 void ForcePrintLogsDuringTests() __attribute__((weak));
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
 
 GTEST_API_ int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
diff --git a/aos/testing/path.cc b/aos/testing/path.cc
index f63fd97..cb17c73 100644
--- a/aos/testing/path.cc
+++ b/aos/testing/path.cc
@@ -2,8 +2,7 @@
 
 #include "absl/strings/str_cat.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Returns the path to the provided artifact which works when built both as an
 // external target and in the repo.
@@ -13,5 +12,4 @@
   return absl::StrCat("../org_frc971/", path);
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/testing/prevent_exit.cc b/aos/testing/prevent_exit.cc
index b640fe7..7c8da60 100644
--- a/aos/testing/prevent_exit.cc
+++ b/aos/testing/prevent_exit.cc
@@ -6,8 +6,7 @@
 
 #include "glog/logging.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 namespace {
 
 void TerminateExitHandler() { _exit(EXIT_SUCCESS); }
@@ -16,5 +15,4 @@
 
 void PreventExit() { CHECK_EQ(atexit(TerminateExitHandler), 0); }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/testing/prevent_exit.h b/aos/testing/prevent_exit.h
index ee39fdb..75e8a1a 100644
--- a/aos/testing/prevent_exit.h
+++ b/aos/testing/prevent_exit.h
@@ -1,8 +1,7 @@
 #ifndef AOS_TESTING_PREVENT_EXIT_H_
 #define AOS_TESTING_PREVENT_EXIT_H_
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Registers an exit handler (using atexit(3)) which will call _exit(2).
 // Intended to be called in a freshly fork(2)ed process where it will run before
@@ -10,7 +9,6 @@
 // being run.
 void PreventExit();
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
 
 #endif  // AOS_TESTING_PREVENT_EXIT_H_
diff --git a/aos/testing/random_seed.cc b/aos/testing/random_seed.cc
index 8f26d07..302612e 100644
--- a/aos/testing/random_seed.cc
+++ b/aos/testing/random_seed.cc
@@ -2,8 +2,7 @@
 
 #include <cstdlib>
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 int RandomSeed() {
   const char *from_environment = getenv("TEST_RANDOM_SEED");
@@ -13,5 +12,4 @@
   return 1;
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/testing/random_seed.h b/aos/testing/random_seed.h
index 825e7b1..11bfe99 100644
--- a/aos/testing/random_seed.h
+++ b/aos/testing/random_seed.h
@@ -1,15 +1,13 @@
 #ifndef AOS_TESTING_RANDOM_SEED_H_
 #define AOS_TESTING_RANDOM_SEED_H_
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Returns the random seed to use for testing.
 //
 // This is ${TEST_RANDOM_SEED} if it is set or 1.
 int RandomSeed();
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
 
 #endif  // AOS_TESTING_RANDOM_SEED_H_
diff --git a/aos/testing/test_logging.cc b/aos/testing/test_logging.cc
index a2042e2..56875bb 100644
--- a/aos/testing/test_logging.cc
+++ b/aos/testing/test_logging.cc
@@ -11,8 +11,7 @@
 
 using ::aos::logging::LogMessage;
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 namespace {
 
 class TestLogImplementation : public logging::HandleMessageLogImplementation {
@@ -138,5 +137,4 @@
   TestLogImplementation::GetInstance()->PrintMessagesAsTheyComeIn();
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/testing/test_logging_test.cc b/aos/testing/test_logging_test.cc
index f39c6cf..5731545 100644
--- a/aos/testing/test_logging_test.cc
+++ b/aos/testing/test_logging_test.cc
@@ -6,8 +6,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Tests logging from multiple threads.
 // tsan used to complain about this.
@@ -25,5 +24,4 @@
   thread.join();
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/testing/test_shm.cc b/aos/testing/test_shm.cc
index 8dc189a..1b168ea 100644
--- a/aos/testing/test_shm.cc
+++ b/aos/testing/test_shm.cc
@@ -7,8 +7,7 @@
 #include "aos/logging/logging.h"
 #include "aos/testing/test_logging.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 namespace {
 
 const size_t kCoreSize = 0x100000;
@@ -35,5 +34,4 @@
   global_core = NULL;
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/testing/tmpdir.cc b/aos/testing/tmpdir.cc
index 7287603..0953a21 100644
--- a/aos/testing/tmpdir.cc
+++ b/aos/testing/tmpdir.cc
@@ -5,8 +5,7 @@
 
 #include "aos/ipc_lib/shm_base.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 namespace {
 std::string TestTmpDirOr(std::string fallback) {
@@ -22,5 +21,4 @@
 
 void SetTestShmBase() { SetShmBase(TestTmpDirOr(FLAGS_shm_base)); }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/time/time.cc b/aos/time/time.cc
index 6ba9543..6a25aa9 100644
--- a/aos/time/time.cc
+++ b/aos/time/time.cc
@@ -45,8 +45,7 @@
 
 #ifdef __linux__
 
-namespace std {
-namespace this_thread {
+namespace std::this_thread {
 template <>
 void sleep_until(const ::aos::monotonic_clock::time_point &end_time) {
   struct timespec end_time_timespec;
@@ -68,8 +67,7 @@
   } while (returnval != 0);
 }
 
-}  // namespace this_thread
-}  // namespace std
+}  // namespace std::this_thread
 
 #endif  // __linux__
 
diff --git a/aos/time/time_test.cc b/aos/time/time_test.cc
index d5c82f2..63a145b 100644
--- a/aos/time/time_test.cc
+++ b/aos/time/time_test.cc
@@ -8,9 +8,7 @@
 #include "aos/macros.h"
 #include "aos/util/death_test_log_implementation.h"
 
-namespace aos {
-namespace time {
-namespace testing {
+namespace aos::time::testing {
 
 namespace chrono = std::chrono;
 
@@ -226,6 +224,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace time
-}  // namespace aos
+}  // namespace aos::time::testing
diff --git a/aos/util/bitpacking_test.cc b/aos/util/bitpacking_test.cc
index 087c719..0f534a1 100644
--- a/aos/util/bitpacking_test.cc
+++ b/aos/util/bitpacking_test.cc
@@ -5,8 +5,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Tests MaskOnes with small arguments.
 TEST(MaskOnesTest, Small) {
@@ -384,5 +383,4 @@
   EXPECT_EQ(0.75f, (IntToFloatLinear<2>(-1.0f, 1.0f, 3)));
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/util/file.cc b/aos/util/file.cc
index 973ab3c..ef958c6 100644
--- a/aos/util/file.cc
+++ b/aos/util/file.cc
@@ -15,8 +15,7 @@
 
 #include "aos/scoped/scoped_fd.h"
 
-namespace aos {
-namespace util {
+namespace aos::util {
 
 std::string ReadFileToStringOrDie(const std::string_view filename) {
   std::optional<std::string> r = MaybeReadFileToString(filename);
@@ -283,5 +282,4 @@
       << ": Failed to write " << bytes.size() << " bytes.";
 }
 
-}  // namespace util
-}  // namespace aos
+}  // namespace aos::util
diff --git a/aos/util/file_test.cc b/aos/util/file_test.cc
index 905a2cd..b3f1e66 100644
--- a/aos/util/file_test.cc
+++ b/aos/util/file_test.cc
@@ -10,9 +10,7 @@
 #include "aos/realtime.h"
 #include "aos/testing/tmpdir.h"
 
-namespace aos {
-namespace util {
-namespace testing {
+namespace aos::util::testing {
 
 using ::testing::ElementsAre;
 
@@ -144,6 +142,4 @@
   EXPECT_EQ("", ReadFileToStringOrDie(test_file));
 }
 
-}  // namespace testing
-}  // namespace util
-}  // namespace aos
+}  // namespace aos::util::testing
diff --git a/aos/util/math_test.cc b/aos/util/math_test.cc
index a243e53..df68f00 100644
--- a/aos/util/math_test.cc
+++ b/aos/util/math_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace math {
-namespace testing {
+namespace aos::math::testing {
 
 bool AngleEqual(double a1, double a2) {
   double diff = a1 - a2;
@@ -84,6 +82,4 @@
   EXPECT_FALSE(PointsAreCCW<double>(c, b, a));
 }
 
-}  // namespace testing
-}  // namespace math
-}  // namespace aos
+}  // namespace aos::math::testing
diff --git a/aos/util/options_test.cc b/aos/util/options_test.cc
index ee228cb..f560fe6 100644
--- a/aos/util/options_test.cc
+++ b/aos/util/options_test.cc
@@ -2,8 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 class OptionsTest : public ::testing::Test {
  public:
@@ -52,5 +51,4 @@
   EXPECT_FALSE(one_three.AllSet(kOne | kTwo | kThree | kFour));
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/util/phased_loop.cc b/aos/util/phased_loop.cc
index 1f61775..476cc3f 100644
--- a/aos/util/phased_loop.cc
+++ b/aos/util/phased_loop.cc
@@ -2,8 +2,7 @@
 
 #include "glog/logging.h"
 
-namespace aos {
-namespace time {
+namespace aos::time {
 
 PhasedLoop::PhasedLoop(const monotonic_clock::duration interval,
                        const monotonic_clock::time_point monotonic_now,
@@ -79,5 +78,4 @@
   return result;
 }
 
-}  // namespace time
-}  // namespace aos
+}  // namespace aos::time
diff --git a/aos/util/phased_loop_test.cc b/aos/util/phased_loop_test.cc
index cfe0107..af33567 100644
--- a/aos/util/phased_loop_test.cc
+++ b/aos/util/phased_loop_test.cc
@@ -5,9 +5,7 @@
 
 #include "aos/time/time.h"
 
-namespace aos {
-namespace time {
-namespace testing {
+namespace aos::time::testing {
 
 using ::std::chrono::milliseconds;
 using ::std::chrono::nanoseconds;
@@ -304,6 +302,4 @@
   EXPECT_EQ(4, loop.Iterate((last_time - kOffset) + (kInterval * 4)));
 }
 
-}  // namespace testing
-}  // namespace time
-}  // namespace aos
+}  // namespace aos::time::testing
diff --git a/aos/util/scoped_pipe_test.cc b/aos/util/scoped_pipe_test.cc
index 0e024c2..80059f8 100644
--- a/aos/util/scoped_pipe_test.cc
+++ b/aos/util/scoped_pipe_test.cc
@@ -7,9 +7,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace util {
-namespace testing {
+namespace aos::util::testing {
 
 // Tests using uint32_t read/write methods on the ScopedPipe objects.
 TEST(ScopedPipeTest, IntegerPipe) {
@@ -67,6 +65,4 @@
   ASSERT_NE(0, fcntl(pipe.read->fd(), F_GETFD) & FD_CLOEXEC);
 }
 
-}  // namespace testing
-}  // namespace util
-}  // namespace aos
+}  // namespace aos::util::testing
diff --git a/aos/util/threaded_consumer_test.cc b/aos/util/threaded_consumer_test.cc
index 96375f0..36f3121 100644
--- a/aos/util/threaded_consumer_test.cc
+++ b/aos/util/threaded_consumer_test.cc
@@ -2,8 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace util {
+namespace aos::util {
 
 // We expect it to be able to pass through everything we submit and recieves it
 // in the order that we submitted it. It should also be able to take in more
@@ -140,5 +139,4 @@
   EXPECT_EQ(counter, 1);
 }
 
-}  // namespace util
-}  // namespace aos
+}  // namespace aos::util
diff --git a/aos/util/trapezoid_profile.cc b/aos/util/trapezoid_profile.cc
index e74110f..938ca75 100644
--- a/aos/util/trapezoid_profile.cc
+++ b/aos/util/trapezoid_profile.cc
@@ -4,8 +4,7 @@
 
 using ::Eigen::Matrix;
 
-namespace aos {
-namespace util {
+namespace aos::util {
 
 TrapezoidProfile::TrapezoidProfile(::std::chrono::nanoseconds delta_time)
     : maximum_acceleration_(0), maximum_velocity_(0), timestep_(delta_time) {
@@ -118,5 +117,4 @@
   deceleration_time_ = (goal_velocity - top_velocity) / deceleration_;
 }
 
-}  // namespace util
-}  // namespace aos
+}  // namespace aos::util
diff --git a/aos/util/trapezoid_profile_test.cc b/aos/util/trapezoid_profile_test.cc
index afd64ea..92b9996 100644
--- a/aos/util/trapezoid_profile_test.cc
+++ b/aos/util/trapezoid_profile_test.cc
@@ -3,9 +3,7 @@
 #include "Eigen/Dense"
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace util {
-namespace testing {
+namespace aos::util::testing {
 
 class TrapezoidProfileTest : public ::testing::Test {
  public:
@@ -120,6 +118,4 @@
   EXPECT_EQ(position()(0), 1.0);
 }
 
-}  // namespace testing
-}  // namespace util
-}  // namespace aos
+}  // namespace aos::util::testing
diff --git a/aos/util/wrapping_counter.cc b/aos/util/wrapping_counter.cc
index f98d7e3..ead4781 100644
--- a/aos/util/wrapping_counter.cc
+++ b/aos/util/wrapping_counter.cc
@@ -1,7 +1,6 @@
 #include "aos/util/wrapping_counter.h"
 
-namespace aos {
-namespace util {
+namespace aos::util {
 
 WrappingCounter::WrappingCounter(int32_t initial_count)
     : count_(initial_count), last_count_(0) {}
@@ -15,5 +14,4 @@
   return count_;
 }
 
-}  // namespace util
-}  // namespace aos
+}  // namespace aos::util
diff --git a/aos/util/wrapping_counter_test.cc b/aos/util/wrapping_counter_test.cc
index 3ef503b..17605a0 100644
--- a/aos/util/wrapping_counter_test.cc
+++ b/aos/util/wrapping_counter_test.cc
@@ -4,9 +4,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace util {
-namespace testing {
+namespace aos::util::testing {
 
 TEST(WrappingCounterTest, Basic) {
   WrappingCounter test_counter;
@@ -53,6 +51,4 @@
   test_wrapping(0, 255);
 }
 
-}  // namespace testing
-}  // namespace util
-}  // namespace aos
+}  // namespace aos::util::testing
diff --git a/aos/uuid_collision_test.cc b/aos/uuid_collision_test.cc
index 05bbccd..99b870b 100644
--- a/aos/uuid_collision_test.cc
+++ b/aos/uuid_collision_test.cc
@@ -6,8 +6,7 @@
 
 #include "aos/uuid.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Tests that modest numbers of UUID::Random() calls cannot create UUID
 // collisions (to test that we have not *completely* messed up the random number
@@ -40,5 +39,4 @@
     values.insert(value);
   }
 }
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/uuid_test.cc b/aos/uuid_test.cc
index 74e7935..f6ed21e 100644
--- a/aos/uuid_test.cc
+++ b/aos/uuid_test.cc
@@ -3,8 +3,7 @@
 #include "glog/logging.h"
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace testing {
+namespace aos::testing {
 
 // Tests that random UUIDs are actually random, and we can convert them to a
 // string.  Not very exhaustive, but it is a good smoke test.
@@ -52,5 +51,4 @@
   EXPECT_EQ(u_span, u2);
 }
 
-}  // namespace testing
-}  // namespace aos
+}  // namespace aos::testing
diff --git a/aos/vision/blob/codec.cc b/aos/vision/blob/codec.cc
index 51ae129..be11281 100644
--- a/aos/vision/blob/codec.cc
+++ b/aos/vision/blob/codec.cc
@@ -1,7 +1,6 @@
 #include "aos/vision/blob/codec.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 size_t CalculateSize(const BlobList &blob_list) {
   size_t count = Int16Codec::kSize;
@@ -55,5 +54,4 @@
   return data;
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/blob/codec_test.cc b/aos/vision/blob/codec_test.cc
index d510e58..889dfbb 100644
--- a/aos/vision/blob/codec_test.cc
+++ b/aos/vision/blob/codec_test.cc
@@ -4,8 +4,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 TEST(CodecTest, WriteRead) {
   BlobList blobl;
@@ -34,5 +33,4 @@
   EXPECT_EQ(real_len, CalculateSize(blobl));
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/blob/contour.cc b/aos/vision/blob/contour.cc
index 6a56f9e..5e82d4c 100644
--- a/aos/vision/blob/contour.cc
+++ b/aos/vision/blob/contour.cc
@@ -1,7 +1,6 @@
 #include "aos/vision/blob/contour.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 namespace {
 // Half-loop of a contour.
@@ -191,5 +190,4 @@
   return plst[0].st;
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/blob/find_blob.cc b/aos/vision/blob/find_blob.cc
index ab65e34..8ee8e92 100644
--- a/aos/vision/blob/find_blob.cc
+++ b/aos/vision/blob/find_blob.cc
@@ -2,8 +2,7 @@
 
 #include "aos/vision/blob/disjoint_set.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 struct BlobBuilder {
   BlobBuilder(int i) : min_y(i) {}
@@ -173,5 +172,4 @@
   return blob_set.MoveBlobs();
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/blob/hierarchical_contour_merge.cc b/aos/vision/blob/hierarchical_contour_merge.cc
index c7de4de..06c34d4 100644
--- a/aos/vision/blob/hierarchical_contour_merge.cc
+++ b/aos/vision/blob/hierarchical_contour_merge.cc
@@ -5,8 +5,7 @@
 
 #include "aos/vision/blob/disjoint_set.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 namespace {
 
@@ -248,5 +247,4 @@
   }
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/blob/move_scale.cc b/aos/vision/blob/move_scale.cc
index 1caa479..45337fc 100644
--- a/aos/vision/blob/move_scale.cc
+++ b/aos/vision/blob/move_scale.cc
@@ -1,7 +1,6 @@
 #include "aos/vision/blob/move_scale.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 RangeImage MoveScale(const RangeImage &img, int dx, int dy, int scale) {
   std::vector<std::vector<ImageRange>> out_range_list;
@@ -38,5 +37,4 @@
   }
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/blob/range_image.cc b/aos/vision/blob/range_image.cc
index bf8d09f..92f77cc 100644
--- a/aos/vision/blob/range_image.cc
+++ b/aos/vision/blob/range_image.cc
@@ -3,8 +3,7 @@
 #include <algorithm>
 #include <cmath>
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 namespace {
 
 // Merge sort of multiple range images into a single range image.
@@ -142,5 +141,4 @@
   return area;
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/blob/test_utils.cc b/aos/vision/blob/test_utils.cc
index 7664f8a..0e7240f 100644
--- a/aos/vision/blob/test_utils.cc
+++ b/aos/vision/blob/test_utils.cc
@@ -1,7 +1,6 @@
 #include "aos/vision/blob/test_utils.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 RangeImage LoadFromTestData(int mini, const char *data) {
   // Consume initial return.
@@ -39,5 +38,4 @@
   return RangeImage(mini, std::move(rows));
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/blob/threshold.cc b/aos/vision/blob/threshold.cc
index c4f8a9e..5403bbd 100644
--- a/aos/vision/blob/threshold.cc
+++ b/aos/vision/blob/threshold.cc
@@ -2,8 +2,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 namespace {
 
 constexpr int kChunkSize = 8;
@@ -123,5 +122,4 @@
   }
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/blob/threshold_test.cc b/aos/vision/blob/threshold_test.cc
index 67f7116..4b23f3e 100644
--- a/aos/vision/blob/threshold_test.cc
+++ b/aos/vision/blob/threshold_test.cc
@@ -9,9 +9,7 @@
 #include "aos/vision/blob/range_image.h"
 #include "aos/vision/image/image_types.h"
 
-namespace aos {
-namespace vision {
-namespace testing {
+namespace aos::vision::testing {
 
 class YuyvYThresholdTest : public ::testing::Test {
  public:
@@ -189,6 +187,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision::testing
diff --git a/aos/vision/blob/transpose.cc b/aos/vision/blob/transpose.cc
index fe4d4a9..b59e8c5 100644
--- a/aos/vision/blob/transpose.cc
+++ b/aos/vision/blob/transpose.cc
@@ -3,8 +3,7 @@
 #include <algorithm>
 #include <limits>
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 RangeImage Transpose(const RangeImage &img) {
   enum EventT {
@@ -87,5 +86,4 @@
   return RangeImage(min_y, std::move(rows));
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/blob/transpose_test.cc b/aos/vision/blob/transpose_test.cc
index 6582b5d..a4a9705 100644
--- a/aos/vision/blob/transpose_test.cc
+++ b/aos/vision/blob/transpose_test.cc
@@ -7,8 +7,7 @@
 
 #include "aos/vision/blob/test_utils.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 TEST(TransposeTest, Tranpspose) {
   RangeImage img = LoadFromTestData(20, R"(
@@ -27,5 +26,4 @@
   EXPECT_EQ(ShortDebugPrint({img}), ShortDebugPrint({c}));
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/debug/aveugle-source.cc b/aos/vision/debug/aveugle-source.cc
index 65a8e84..46b9694 100644
--- a/aos/vision/debug/aveugle-source.cc
+++ b/aos/vision/debug/aveugle-source.cc
@@ -7,8 +7,7 @@
 #include "aos/vision/image/camera_params.pb.h"
 #include "aos/vision/image/image_stream.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 class AveugleImageSource : public ImageSource {
  public:
@@ -73,5 +72,4 @@
 
 REGISTER_IMAGE_SOURCE("jevois", AveugleImageSource);
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/debug/blob_log-source.cc b/aos/vision/debug/blob_log-source.cc
index 4dd5675..c5ee67c 100644
--- a/aos/vision/debug/blob_log-source.cc
+++ b/aos/vision/debug/blob_log-source.cc
@@ -14,8 +14,7 @@
 #include "aos/vision/debug/debug_framework.h"
 #include "aos/vision/debug/overlay.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 namespace {
 
@@ -365,5 +364,4 @@
 
 REGISTER_IMAGE_SOURCE("blob_log", BlobLogImageSource);
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/debug/camera-source.cc b/aos/vision/debug/camera-source.cc
index 578ebc1..685b7eb 100644
--- a/aos/vision/debug/camera-source.cc
+++ b/aos/vision/debug/camera-source.cc
@@ -7,8 +7,7 @@
 #include "aos/vision/image/camera_params.pb.h"
 #include "aos/vision/image/image_stream.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 class CameraImageSource : public ImageSource {
  public:
@@ -63,5 +62,4 @@
 
 REGISTER_IMAGE_SOURCE("camera", CameraImageSource);
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/debug/debug_framework.cc b/aos/vision/debug/debug_framework.cc
index 0b0d2c7..770eefd 100644
--- a/aos/vision/debug/debug_framework.cc
+++ b/aos/vision/debug/debug_framework.cc
@@ -9,8 +9,7 @@
 #include "aos/vision/events/epoll_events.h"
 #include "aos/vision/image/jpeg_routines.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 // Detect screen height on smaller monitors.
 int GetScreenHeight() {
@@ -176,5 +175,4 @@
   replay.Loop()->RunWithGtkMain();
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/debug/debug_window.cc b/aos/vision/debug/debug_window.cc
index b998c03..40d1468 100644
--- a/aos/vision/debug/debug_window.cc
+++ b/aos/vision/debug/debug_window.cc
@@ -12,8 +12,7 @@
 
 #include "aos/vision/image/image_types.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 template <typename T, gboolean (T::*DrawMethod)(cairo_t *cr)>
 gboolean DrawCallback(GtkWidget *, cairo_t *cr, gpointer data) {
@@ -181,5 +180,4 @@
   cairo_restore(cr_);
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/debug/jpeg_list-source.cc b/aos/vision/debug/jpeg_list-source.cc
index ecc3f14..7c6c9dc 100644
--- a/aos/vision/debug/jpeg_list-source.cc
+++ b/aos/vision/debug/jpeg_list-source.cc
@@ -6,8 +6,7 @@
 #include "aos/vision/debug/debug_framework.h"
 #include "aos/vision/image/image_dataset.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 class JpegListImageSource : public ImageSource {
  public:
@@ -65,5 +64,4 @@
 
 REGISTER_IMAGE_SOURCE("jpeg_list", JpegListImageSource);
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/debug/tcp-source.cc b/aos/vision/debug/tcp-source.cc
index de406ae..7749f5c 100644
--- a/aos/vision/debug/tcp-source.cc
+++ b/aos/vision/debug/tcp-source.cc
@@ -12,8 +12,7 @@
 #include "aos/vision/debug/debug_framework.h"
 #include "aos/vision/events/tcp_client.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 // Reads packets in the form:
 // uint32 length
@@ -152,5 +151,4 @@
 
 REGISTER_IMAGE_SOURCE("tcp", TCPImageSource);
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/events/epoll_events.cc b/aos/vision/events/epoll_events.cc
index e417f0d..1a5ad7e 100644
--- a/aos/vision/events/epoll_events.cc
+++ b/aos/vision/events/epoll_events.cc
@@ -10,8 +10,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace aos {
-namespace events {
+namespace aos::events {
 
 void EpollEvent::DirectEvent(uint32_t events) {
   if ((events & ~(EPOLLIN | EPOLLPRI | EPOLLERR)) != 0) {
@@ -72,5 +71,4 @@
   return r;
 }
 
-}  // namespace events
-}  // namespace aos
+}  // namespace aos::events
diff --git a/aos/vision/events/gtk_event.cc b/aos/vision/events/gtk_event.cc
index e1e4e08..7df0716 100644
--- a/aos/vision/events/gtk_event.cc
+++ b/aos/vision/events/gtk_event.cc
@@ -9,8 +9,7 @@
 #include "aos/logging/logging.h"
 #include "aos/vision/events/epoll_events.h"
 
-namespace aos {
-namespace events {
+namespace aos::events {
 
 void EpollLoop::RunWithGtkMain() {
   int timeout;
@@ -69,5 +68,4 @@
   exit(EXIT_SUCCESS);
 }
 
-}  // namespace events
-}  // namespace aos
+}  // namespace aos::events
diff --git a/aos/vision/events/intrusive_free_list.h b/aos/vision/events/intrusive_free_list.h
index 0373741..db096b7 100644
--- a/aos/vision/events/intrusive_free_list.h
+++ b/aos/vision/events/intrusive_free_list.h
@@ -1,8 +1,7 @@
 #ifndef _AOS_VISION_EVENTS_INTRUSIVE_FREE_LIST_H_
 #define _AOS_VISION_EVENTS_INTRUSIVE_FREE_LIST_H_
 
-namespace aos {
-namespace events {
+namespace aos::events {
 
 // Hey! Maybe you want a doubly linked list that frees things for you!
 // This allows the entry to delete itself, removing it from the list, or
@@ -75,7 +74,6 @@
   T *begin_;
 };
 
-}  // namespace events
-}  // namespace aos
+}  // namespace aos::events
 
 #endif  // _AOS_VISION_EVENTS_INTRUSIVE_FREE_LIST_H_
diff --git a/aos/vision/events/tcp_client.cc b/aos/vision/events/tcp_client.cc
index 0a926db..65b646c 100644
--- a/aos/vision/events/tcp_client.cc
+++ b/aos/vision/events/tcp_client.cc
@@ -15,8 +15,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace aos {
-namespace events {
+namespace aos::events {
 
 namespace {
 int MakeSocketNonBlocking(int sfd) {
@@ -63,5 +62,4 @@
 TcpClient::TcpClient(const std::string &hostname, int portno)
     : EpollEvent(OpenClient(hostname, portno)) {}
 
-}  // namespace events
-}  // namespace aos
+}  // namespace aos::events
diff --git a/aos/vision/events/tcp_server.cc b/aos/vision/events/tcp_server.cc
index cf4dd7f..fa2a369 100644
--- a/aos/vision/events/tcp_server.cc
+++ b/aos/vision/events/tcp_server.cc
@@ -16,8 +16,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace aos {
-namespace events {
+namespace aos::events {
 
 namespace {
 
@@ -108,5 +107,4 @@
   loop()->Add(Construct(infd));
 }
 
-}  // namespace events
-}  // namespace aos
+}  // namespace aos::events
diff --git a/aos/vision/events/udp.cc b/aos/vision/events/udp.cc
index 2aaac82..cf7ad23 100644
--- a/aos/vision/events/udp.cc
+++ b/aos/vision/events/udp.cc
@@ -4,8 +4,7 @@
 
 #include "glog/logging.h"
 
-namespace aos {
-namespace events {
+namespace aos::events {
 
 TXUdpSocket::TXUdpSocket(const std::string &ip_addr, int port)
     : fd_(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) {
@@ -49,5 +48,4 @@
   return result;
 }
 
-}  // namespace events
-}  // namespace aos
+}  // namespace aos::events
diff --git a/aos/vision/events/udp_test.cc b/aos/vision/events/udp_test.cc
index 33fb4d6..506be28 100644
--- a/aos/vision/events/udp_test.cc
+++ b/aos/vision/events/udp_test.cc
@@ -2,8 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace events {
+namespace aos::events {
 
 TEST(UDPTest, SendRecv) {
   RXUdpSocket rx(1109);
@@ -19,5 +18,4 @@
   EXPECT_EQ(txdata[3], rxdata[3]);
 }
 
-}  // namespace events
-}  // namespace aos
+}  // namespace aos::events
diff --git a/aos/vision/image/image_dataset.cc b/aos/vision/image/image_dataset.cc
index a15ccb4..82a8886 100644
--- a/aos/vision/image/image_dataset.cc
+++ b/aos/vision/image/image_dataset.cc
@@ -4,8 +4,7 @@
 
 #include "aos/vision/image/image_types.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 namespace {
 std::string GetFileContents(const std::string &filename) {
@@ -82,5 +81,4 @@
   return images;
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/image/image_stream.cc b/aos/vision/image/image_stream.cc
index 62f5e81..fe42efc 100644
--- a/aos/vision/image/image_stream.cc
+++ b/aos/vision/image/image_stream.cc
@@ -2,8 +2,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 void ImageStreamEvent::ProcessHelper(
     DataRef data, aos::monotonic_clock::time_point timestamp) {
@@ -14,5 +13,4 @@
   ProcessImage(data, timestamp);
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/image/jpeg_routines.cc b/aos/vision/image/jpeg_routines.cc
index b41729f..9d46895 100644
--- a/aos/vision/image/jpeg_routines.cc
+++ b/aos/vision/image/jpeg_routines.cc
@@ -14,8 +14,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 namespace {
 
@@ -248,5 +247,4 @@
   return true;
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/aos/vision/math/vector_test.cc b/aos/vision/math/vector_test.cc
index 8c5244d..214a50c 100644
--- a/aos/vision/math/vector_test.cc
+++ b/aos/vision/math/vector_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace aos {
-namespace vision {
-namespace testing {
+namespace aos::vision::testing {
 
 class VectorTest : public ::testing::Test {
  protected:
@@ -71,6 +69,4 @@
   EXPECT_NEAR(M_PI / 3, vec5.AngleToZero(), 0.0001);
 }
 
-}  // namespace testing
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision::testing
diff --git a/aos/vision/tools/jpeg_vision_test.cc b/aos/vision/tools/jpeg_vision_test.cc
index ef2ec6d..553419a 100644
--- a/aos/vision/tools/jpeg_vision_test.cc
+++ b/aos/vision/tools/jpeg_vision_test.cc
@@ -25,8 +25,7 @@
 #include "aos/vision/image/reader.h"
 #include "aos/vision/math/vector.h"
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 void DrawVLine(ImagePtr ptr, int x, PixelRef color = {255, 0, 0}) {
   for (int y = 0; y < ptr.fmt().h; ++y) {
@@ -108,8 +107,7 @@
   int dx = 0;
   int dy = 0;
 };
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
 
 int main(int argc, char *argv[]) {
   ::aos::logging::Init();
diff --git a/frc971/analysis/in_process_plotter.cc b/frc971/analysis/in_process_plotter.cc
index b327c54..b537aa4 100644
--- a/frc971/analysis/in_process_plotter.cc
+++ b/frc971/analysis/in_process_plotter.cc
@@ -2,8 +2,7 @@
 
 #include "aos/configuration.h"
 
-namespace frc971 {
-namespace analysis {
+namespace frc971::analysis {
 
 namespace {
 const char *kDataPath = "frc971/analysis/cpp_plot";
@@ -168,5 +167,4 @@
   next_top_ = 0;
 }
 
-}  // namespace analysis
-}  // namespace frc971
+}  // namespace frc971::analysis
diff --git a/frc971/analysis/py_log_reader.cc b/frc971/analysis/py_log_reader.cc
index 6ee6c69..57d57d0 100644
--- a/frc971/analysis/py_log_reader.cc
+++ b/frc971/analysis/py_log_reader.cc
@@ -27,8 +27,7 @@
 #include "aos/init.h"
 #include "aos/json_to_flatbuffer.h"
 
-namespace frc971 {
-namespace analysis {
+namespace frc971::analysis {
 namespace {
 
 // All the data corresponding to a single message.
@@ -300,8 +299,7 @@
 }
 
 }  // namespace
-}  // namespace analysis
-}  // namespace frc971
+}  // namespace frc971::analysis
 
 PyMODINIT_FUNC PyInit_py_log_reader(void) {
   return frc971::analysis::InitModule();
diff --git a/frc971/autonomous/base_autonomous_actor.cc b/frc971/autonomous/base_autonomous_actor.cc
index 22909be..2156045 100644
--- a/frc971/autonomous/base_autonomous_actor.cc
+++ b/frc971/autonomous/base_autonomous_actor.cc
@@ -18,8 +18,7 @@
 namespace this_thread = ::std::this_thread;
 namespace drivetrain = frc971::control_loops::drivetrain;
 
-namespace frc971 {
-namespace autonomous {
+namespace frc971::autonomous {
 
 BaseAutonomousActor::BaseAutonomousActor(
     ::aos::EventLoop *event_loop,
@@ -678,5 +677,4 @@
   }
 }
 
-}  // namespace autonomous
-}  // namespace frc971
+}  // namespace frc971::autonomous
diff --git a/frc971/can_logger/asc_logger.cc b/frc971/can_logger/asc_logger.cc
index 96b2e96..6848938 100644
--- a/frc971/can_logger/asc_logger.cc
+++ b/frc971/can_logger/asc_logger.cc
@@ -2,8 +2,7 @@
 
 #include <linux/can.h>
 
-namespace frc971 {
-namespace can_logger {
+namespace frc971::can_logger {
 
 AscLogger::AscLogger(aos::EventLoop *event_loop, const std::string &filename)
     : output_(filename), event_loop_(event_loop) {
@@ -138,5 +137,4 @@
   file << "\n";
 }
 
-}  // namespace can_logger
-}  // namespace frc971
+}  // namespace frc971::can_logger
diff --git a/frc971/can_logger/can_logger.cc b/frc971/can_logger/can_logger.cc
index 7a6c0fe..e7e1e6f 100644
--- a/frc971/can_logger/can_logger.cc
+++ b/frc971/can_logger/can_logger.cc
@@ -1,7 +1,6 @@
 #include "frc971/can_logger/can_logger.h"
 
-namespace frc971 {
-namespace can_logger {
+namespace frc971::can_logger {
 
 CanLogger::CanLogger(aos::ShmEventLoop *event_loop,
                      std::string_view channel_name,
@@ -84,5 +83,4 @@
   return true;
 }
 
-}  // namespace can_logger
-}  // namespace frc971
+}  // namespace frc971::can_logger
diff --git a/frc971/codelab/basic.cc b/frc971/codelab/basic.cc
index 66f08f9..a78da41 100644
--- a/frc971/codelab/basic.cc
+++ b/frc971/codelab/basic.cc
@@ -1,7 +1,6 @@
 #include "frc971/codelab/basic.h"
 
-namespace frc971 {
-namespace codelab {
+namespace frc971::codelab {
 
 Basic::Basic(::aos::EventLoop *event_loop, const ::std::string &name)
     : frc971::controls::ControlLoop<Goal, Position, Status, Output>(event_loop,
@@ -45,5 +44,4 @@
   }
 }
 
-}  // namespace codelab
-}  // namespace frc971
+}  // namespace frc971::codelab
diff --git a/frc971/codelab/basic_test.cc b/frc971/codelab/basic_test.cc
index e9820bc..b2ad83e 100644
--- a/frc971/codelab/basic_test.cc
+++ b/frc971/codelab/basic_test.cc
@@ -18,9 +18,7 @@
 #include "frc971/control_loops/control_loop_test.h"
 #include "frc971/control_loops/team_number_test_environment.h"
 
-namespace frc971 {
-namespace codelab {
-namespace testing {
+namespace frc971::codelab::testing {
 
 namespace chrono = ::std::chrono;
 using aos::monotonic_clock;
@@ -238,6 +236,4 @@
   basic_simulation_.VerifyResults(0.0, false);
 }
 
-}  // namespace testing
-}  // namespace codelab
-}  // namespace frc971
+}  // namespace frc971::codelab::testing
diff --git a/frc971/constants.h b/frc971/constants.h
index 0367937..48b8ca9 100644
--- a/frc971/constants.h
+++ b/frc971/constants.h
@@ -6,8 +6,7 @@
 #include "frc971/control_loops/control_loops_generated.h"
 #include "frc971/zeroing/constants_generated.h"
 
-namespace frc971 {
-namespace constants {
+namespace frc971::constants {
 
 typedef frc971::zeroing::HallEffectZeroingConstantsT HallEffectZeroingConstants;
 
@@ -53,7 +52,6 @@
   }
 };
 
-}  // namespace constants
-}  // namespace frc971
+}  // namespace frc971::constants
 
 #endif  // FRC971_CONSTANTS_H_
diff --git a/frc971/constants/constants_sender_test.cc b/frc971/constants/constants_sender_test.cc
index 5e551c1..e4920d3 100644
--- a/frc971/constants/constants_sender_test.cc
+++ b/frc971/constants/constants_sender_test.cc
@@ -11,8 +11,7 @@
 #include "frc971/constants/testdata/constants_data_generated.h"
 #include "frc971/constants/testdata/constants_list_generated.h"
 
-namespace frc971::constants {
-namespace testing {
+namespace frc971::constants::testing {
 
 using aos::testing::ArtifactPath;
 
@@ -121,5 +120,4 @@
       "Invalid field name");
 }
 
-}  // namespace testing
-}  // namespace frc971::constants
+}  // namespace frc971::constants::testing
diff --git a/frc971/control_loops/binomial.h b/frc971/control_loops/binomial.h
index 4f4c4dc..9ccc824 100644
--- a/frc971/control_loops/binomial.h
+++ b/frc971/control_loops/binomial.h
@@ -1,8 +1,7 @@
 #ifndef FRC971_CONTROL_LOOPS_BINOMIAL_H_
 #define FRC971_CONTROL_LOOPS_BINOMIAL_H_
 
-namespace frc971 {
-namespace control_loops {
+namespace frc971::control_loops {
 
 // Computes the factorial of n
 constexpr double Factorial(int n) {
@@ -18,7 +17,6 @@
   return Factorial(n) / (Factorial(k) * Factorial(n - k));
 }
 
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops
 
 #endif  // FRC971_CONTROL_LOOPS_BINOMIAL_H_
diff --git a/frc971/control_loops/binomial_test.cc b/frc971/control_loops/binomial_test.cc
index 482790e..dc25e23 100644
--- a/frc971/control_loops/binomial_test.cc
+++ b/frc971/control_loops/binomial_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace testing {
+namespace frc971::control_loops::testing {
 
 // Tests some factorials.
 TEST(BinomialTest, Factorial) {
@@ -39,6 +37,4 @@
   EXPECT_EQ(1.0, Binomial(4, 4));
 }
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::testing
diff --git a/frc971/control_loops/c2d_test.cc b/frc971/control_loops/c2d_test.cc
index 14b4952..47a87a0 100644
--- a/frc971/control_loops/c2d_test.cc
+++ b/frc971/control_loops/c2d_test.cc
@@ -6,9 +6,7 @@
 
 #include "frc971/control_loops/runge_kutta.h"
 
-namespace frc971 {
-namespace controls {
-namespace testing {
+namespace frc971::controls::testing {
 
 class C2DTest : public ::testing::Test {
  public:
@@ -86,6 +84,4 @@
   EXPECT_LT((A_d - A_d_fast).norm(), 1e-20);
 }
 
-}  // namespace testing
-}  // namespace controls
-}  // namespace frc971
+}  // namespace frc971::controls::testing
diff --git a/frc971/control_loops/coerce_goal.cc b/frc971/control_loops/coerce_goal.cc
index ccad84a..4a7f3ed 100644
--- a/frc971/control_loops/coerce_goal.cc
+++ b/frc971/control_loops/coerce_goal.cc
@@ -3,7 +3,3 @@
 #include "Eigen/Dense"
 
 #include "frc971/control_loops/polytope.h"
-
-namespace frc971 {
-namespace control_loops {}  // namespace control_loops
-}  // namespace frc971
diff --git a/frc971/control_loops/coerce_goal_test.cc b/frc971/control_loops/coerce_goal_test.cc
index 95520db..dc69b70 100644
--- a/frc971/control_loops/coerce_goal_test.cc
+++ b/frc971/control_loops/coerce_goal_test.cc
@@ -6,8 +6,7 @@
 
 #include "frc971/control_loops/polytope.h"
 
-namespace frc971 {
-namespace control_loops {
+namespace frc971::control_loops {
 
 namespace {
 
@@ -213,5 +212,4 @@
   EXPECT_EQ(result(1, 0), 0);
 }
 
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops
diff --git a/frc971/control_loops/control_loop.cc b/frc971/control_loops/control_loop.cc
index 3b475a9..63fe703 100644
--- a/frc971/control_loops/control_loop.cc
+++ b/frc971/control_loops/control_loop.cc
@@ -1,5 +1 @@
 #include "frc971/control_loops/control_loop.h"
-
-namespace frc971 {
-namespace controls {}  // namespace controls
-}  // namespace frc971
diff --git a/frc971/control_loops/control_loop_test.cc b/frc971/control_loops/control_loop_test.cc
index 6704bf5..28e3504 100644
--- a/frc971/control_loops/control_loop_test.cc
+++ b/frc971/control_loops/control_loop_test.cc
@@ -1,7 +1,3 @@
 #include "frc971/control_loops/control_loop_test.h"
 
 #include <chrono>
-
-namespace frc971 {
-namespace testing {}  // namespace testing
-}  // namespace frc971
diff --git a/frc971/control_loops/double_jointed_arm/demo_path.cc b/frc971/control_loops/double_jointed_arm/demo_path.cc
index 8d549d1..5b52bf3 100644
--- a/frc971/control_loops/double_jointed_arm/demo_path.cc
+++ b/frc971/control_loops/double_jointed_arm/demo_path.cc
@@ -4,9 +4,7 @@
 #include <initializer_list>
 #include <memory>
 
-namespace frc971 {
-namespace control_loops {
-namespace arm {
+namespace frc971::control_loops::arm {
 
 ::std::vector<::std::array<double, 6>> FlipPath(
     ::std::initializer_list<::std::array<double, 6>> list) {
@@ -210,6 +208,4 @@
   return ::std::unique_ptr<Path>(new Path(Path::Reversed(*MakeDemoPath())));
 }
 
-}  // namespace arm
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::arm
diff --git a/frc971/control_loops/double_jointed_arm/dynamics.cc b/frc971/control_loops/double_jointed_arm/dynamics.cc
index 2842ad4..4910e6c 100644
--- a/frc971/control_loops/double_jointed_arm/dynamics.cc
+++ b/frc971/control_loops/double_jointed_arm/dynamics.cc
@@ -2,9 +2,7 @@
 
 DEFINE_bool(gravity, true, "If true, enable gravity.");
 
-namespace frc971 {
-namespace control_loops {
-namespace arm {
+namespace frc971::control_loops::arm {
 
 Dynamics::Dynamics(ArmConstants arm_constants)
     : arm_constants_(arm_constants),
@@ -32,6 +30,4 @@
       beta_(arm_constants_.l0 * arm_constants_.r1 * arm_constants_.m1),
       gamma_(arm_constants_.j1 +
              arm_constants_.r1 * arm_constants_.r1 * arm_constants_.m1) {}
-}  // namespace arm
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::arm
diff --git a/frc971/control_loops/double_jointed_arm/dynamics_test.cc b/frc971/control_loops/double_jointed_arm/dynamics_test.cc
index 5234af5..9f68ddc 100644
--- a/frc971/control_loops/double_jointed_arm/dynamics_test.cc
+++ b/frc971/control_loops/double_jointed_arm/dynamics_test.cc
@@ -4,10 +4,7 @@
 
 #include "frc971/control_loops/double_jointed_arm/test_constants.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace arm {
-namespace testing {
+namespace frc971::control_loops::arm::testing {
 
 // Tests that zero inputs result in no acceleration and no motion.
 // This isn't all that rigerous, but it's a good start.
@@ -48,7 +45,4 @@
                   .isApprox(X));
 }
 
-}  // namespace testing
-}  // namespace arm
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::arm::testing
diff --git a/frc971/control_loops/double_jointed_arm/ekf.cc b/frc971/control_loops/double_jointed_arm/ekf.cc
index f8ec6d6..b1ae70a 100644
--- a/frc971/control_loops/double_jointed_arm/ekf.cc
+++ b/frc971/control_loops/double_jointed_arm/ekf.cc
@@ -12,9 +12,7 @@
 DEFINE_double(distal_voltage_error_uncertainty, 2.0,
               "Distal joint voltage error uncertainty.");
 
-namespace frc971 {
-namespace control_loops {
-namespace arm {
+namespace frc971::control_loops::arm {
 
 namespace {
 // TODO(austin): When tuning this, make sure to verify that you are waiting
@@ -108,6 +106,4 @@
        P_;
 }
 
-}  // namespace arm
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::arm
diff --git a/frc971/control_loops/double_jointed_arm/graph.cc b/frc971/control_loops/double_jointed_arm/graph.cc
index b5a70ab..a60a000 100644
--- a/frc971/control_loops/double_jointed_arm/graph.cc
+++ b/frc971/control_loops/double_jointed_arm/graph.cc
@@ -3,9 +3,7 @@
 #include <algorithm>
 #include <cassert>
 
-namespace frc971 {
-namespace control_loops {
-namespace arm {
+namespace frc971::control_loops::arm {
 
 SearchGraph::SearchGraph(size_t num_vertexes, std::initializer_list<Edge> edges)
     : SearchGraph(num_vertexes, ::std::vector<Edge>(edges)) {}
@@ -66,6 +64,4 @@
   return vertexes_[vertex].cached_distance;
 }
 
-}  // namespace arm
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::arm
diff --git a/frc971/control_loops/double_jointed_arm/graph_test.cc b/frc971/control_loops/double_jointed_arm/graph_test.cc
index 7b14ced..771d1a0 100644
--- a/frc971/control_loops/double_jointed_arm/graph_test.cc
+++ b/frc971/control_loops/double_jointed_arm/graph_test.cc
@@ -2,10 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace arm {
-namespace testing {
+namespace frc971::control_loops::arm::testing {
 
 class HeapTest {
  public:
@@ -65,7 +62,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace arm
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::arm::testing
diff --git a/frc971/control_loops/double_jointed_arm/trajectory.cc b/frc971/control_loops/double_jointed_arm/trajectory.cc
index 05a2d17..8b5129d 100644
--- a/frc971/control_loops/double_jointed_arm/trajectory.cc
+++ b/frc971/control_loops/double_jointed_arm/trajectory.cc
@@ -13,9 +13,7 @@
 DEFINE_double(lqr_distal_pos, 0.20, "Position LQR gain");
 DEFINE_double(lqr_distal_vel, 4.0, "Velocity LQR gain");
 
-namespace frc971 {
-namespace control_loops {
-namespace arm {
+namespace frc971::control_loops::arm {
 
 Path Path::Reversed(const Path &p) {
   ::std::vector<::std::array<double, 6>> list(p.distances().size());
@@ -621,6 +619,4 @@
   omega_ = trajectory_->OmegaT(goal_(0), goal_(1));
 }
 
-}  // namespace arm
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::arm
diff --git a/frc971/control_loops/double_jointed_arm/trajectory_test.cc b/frc971/control_loops/double_jointed_arm/trajectory_test.cc
index 99575e9..88962f9 100644
--- a/frc971/control_loops/double_jointed_arm/trajectory_test.cc
+++ b/frc971/control_loops/double_jointed_arm/trajectory_test.cc
@@ -7,10 +7,7 @@
 #include "frc971/control_loops/double_jointed_arm/ekf.h"
 #include "frc971/control_loops/double_jointed_arm/test_constants.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace arm {
-namespace testing {
+namespace frc971::control_loops::arm::testing {
 
 // Tests that we can pull out values along the path.
 TEST(TrajectoryTest, Theta) {
@@ -210,7 +207,4 @@
       final_theta_t.isApprox(trajectory.path().Theta(follower.goal(0))));
 }
 
-}  // namespace testing
-}  // namespace arm
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::arm::testing
diff --git a/frc971/control_loops/drivetrain/camera_test.cc b/frc971/control_loops/drivetrain/camera_test.cc
index a55ebad..baf2995 100644
--- a/frc971/control_loops/drivetrain/camera_test.cc
+++ b/frc971/control_loops/drivetrain/camera_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace testing {
+namespace frc971::control_loops::testing {
 
 // Check that a Target's basic operations work.
 TEST(TargetTest, BasicTargetTest) {
@@ -208,6 +206,4 @@
         Reading({0.0, 1.0, 0.0, ::std::numeric_limits<double>::infinity()}),
         Reading({0.0, 1.0, 0.0, ::std::numeric_limits<double>::quiet_NaN()})));
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::testing
diff --git a/frc971/control_loops/drivetrain/distance_spline.cc b/frc971/control_loops/drivetrain/distance_spline.cc
index 04a1add..bcd9d4c 100644
--- a/frc971/control_loops/drivetrain/distance_spline.cc
+++ b/frc971/control_loops/drivetrain/distance_spline.cc
@@ -5,9 +5,7 @@
 #include "aos/logging/logging.h"
 #include "frc971/control_loops/drivetrain/spline.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 
 ::std::vector<float> DistanceSpline::BuildDistances(size_t num_alpha) {
   num_alpha = num_alpha == 0 ? 100 * splines().size() : num_alpha;
@@ -233,6 +231,4 @@
   return {index, alpha - index};
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
diff --git a/frc971/control_loops/drivetrain/distance_spline_test.cc b/frc971/control_loops/drivetrain/distance_spline_test.cc
index 60f83b9..806d39e 100644
--- a/frc971/control_loops/drivetrain/distance_spline_test.cc
+++ b/frc971/control_loops/drivetrain/distance_spline_test.cc
@@ -13,10 +13,7 @@
 
 DEFINE_bool(plot, false, "If true, plot");
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
-namespace testing {
+namespace frc971::control_loops::drivetrain::testing {
 
 // Test fixture with a spline from 0, 0 to 1, 1
 class ParameterizedDistanceSplineTest
@@ -187,7 +184,4 @@
                                 1.5, 2.0, 1.0, 1.0, 0.0, 0.0)
                                    .finished()))})));
 
-}  // namespace testing
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain::testing
diff --git a/frc971/control_loops/drivetrain/drivetrain.cc b/frc971/control_loops/drivetrain/drivetrain.cc
index be4cf6f..cdccd7d 100644
--- a/frc971/control_loops/drivetrain/drivetrain.cc
+++ b/frc971/control_loops/drivetrain/drivetrain.cc
@@ -24,9 +24,7 @@
 using ::aos::monotonic_clock;
 namespace chrono = ::std::chrono;
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 
 namespace {
 // Maximum variation to allow in the gyro when zeroing.
@@ -627,6 +625,4 @@
   return builder.Finish();
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
diff --git a/frc971/control_loops/drivetrain/drivetrain_lib_test.cc b/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
index 3e17822..3cce7d2 100644
--- a/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
+++ b/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
@@ -27,10 +27,7 @@
 DEFINE_string(output_file, "",
               "If set, logs all channels to the provided logfile.");
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
-namespace testing {
+namespace frc971::control_loops::drivetrain::testing {
 
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
@@ -1639,7 +1636,4 @@
 
 // TODO(austin): Make sure the profile reset code when we disable works.
 
-}  // namespace testing
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain::testing
diff --git a/frc971/control_loops/drivetrain/drivetrain_states.h b/frc971/control_loops/drivetrain/drivetrain_states.h
index 9ea2518..70ad69d 100644
--- a/frc971/control_loops/drivetrain/drivetrain_states.h
+++ b/frc971/control_loops/drivetrain/drivetrain_states.h
@@ -1,9 +1,7 @@
 #ifndef FRC971_CONTROL_LOOPS_DRIVETRAIN_DRIVETRAIN_STATES_H_
 #define FRC971_CONTROL_LOOPS_DRIVETRAIN_DRIVETRAIN_STATES_H_
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops ::drivetrain {
 
 enum KalmanState {
   kLeftPosition = 0,
@@ -17,8 +15,6 @@
 
 enum OutputState { kLeftVoltage = 0, kRightVoltage = 1 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
 
 #endif  // FRC971_CONTROL_LOOPS_DRIVETRAIN_DRIVETRAIN_STATES_H_
diff --git a/frc971/control_loops/drivetrain/drivetrain_test_lib.cc b/frc971/control_loops/drivetrain/drivetrain_test_lib.cc
index ab7e280..c8e4dee 100644
--- a/frc971/control_loops/drivetrain/drivetrain_test_lib.cc
+++ b/frc971/control_loops/drivetrain/drivetrain_test_lib.cc
@@ -20,10 +20,7 @@
 
 DEFINE_bool(plot, false, "If true, plot");
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
-namespace testing {
+namespace frc971::control_loops::drivetrain::testing {
 
 namespace {
 // TODO(Comran): Make one that doesn't depend on the actual values for a
@@ -383,7 +380,4 @@
 #endif
 }
 
-}  // namespace testing
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain::testing
diff --git a/frc971/control_loops/drivetrain/drivetrain_uc.q.cc b/frc971/control_loops/drivetrain/drivetrain_uc.q.cc
index 2a2870c..bc71e4e 100644
--- a/frc971/control_loops/drivetrain/drivetrain_uc.q.cc
+++ b/frc971/control_loops/drivetrain/drivetrain_uc.q.cc
@@ -2,8 +2,7 @@
 
 #include <cinttypes>
 
-namespace frc971 {
-namespace control_loops {
+namespace frc971::control_loops {
 
 GearLogging::GearLogging() { Zero(); }
 
@@ -104,5 +103,4 @@
 
 DrivetrainQueue_Status::DrivetrainQueue_Status() { Zero(); }
 
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops
diff --git a/frc971/control_loops/drivetrain/gear.h b/frc971/control_loops/drivetrain/gear.h
index 8fabb69..ff43e20 100644
--- a/frc971/control_loops/drivetrain/gear.h
+++ b/frc971/control_loops/drivetrain/gear.h
@@ -1,10 +1,7 @@
 #ifndef FRC971_CONTROL_LOOPS_GEAR_H_
 #define FRC971_CONTROL_LOOPS_GEAR_H_
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
-
+namespace frc971::control_loops::drivetrain {
 // The state of the shift.
 enum class Gear { HIGH, LOW, SHIFTING_UP, SHIFTING_DOWN };
 
@@ -18,8 +15,6 @@
   return gear == Gear::LOW || gear == Gear::HIGH;
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
 
 #endif  // FRC971_CONTROL_LOOPS_GEAR_H_
diff --git a/frc971/control_loops/drivetrain/hybrid_ekf_test.cc b/frc971/control_loops/drivetrain/hybrid_ekf_test.cc
index 01028c0..2119c7d 100644
--- a/frc971/control_loops/drivetrain/hybrid_ekf_test.cc
+++ b/frc971/control_loops/drivetrain/hybrid_ekf_test.cc
@@ -9,10 +9,7 @@
 #include "frc971/control_loops/drivetrain/drivetrain_test_lib.h"
 #include "frc971/control_loops/drivetrain/trajectory.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
-namespace testing {
+namespace frc971::control_loops::drivetrain::testing {
 
 typedef HybridEkf<>::StateIdx StateIdx;
 typedef HybridEkf<>::InputIdx InputIdx;
@@ -503,7 +500,4 @@
       "make_h");
 }
 
-}  // namespace testing
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain::testing
diff --git a/frc971/control_loops/drivetrain/improved_down_estimator.cc b/frc971/control_loops/drivetrain/improved_down_estimator.cc
index 71347e2..b7b3878 100644
--- a/frc971/control_loops/drivetrain/improved_down_estimator.cc
+++ b/frc971/control_loops/drivetrain/improved_down_estimator.cc
@@ -5,9 +5,7 @@
 
 #include "frc971/control_loops/quaternion_utils.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 
 void QuaternionUkf::Reset() {
   // The various noise matrices are tuned to provide values that seem
@@ -319,6 +317,4 @@
   return builder.Finish();
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
diff --git a/frc971/control_loops/drivetrain/improved_down_estimator_test.cc b/frc971/control_loops/drivetrain/improved_down_estimator_test.cc
index 376c131..c128429 100644
--- a/frc971/control_loops/drivetrain/improved_down_estimator_test.cc
+++ b/frc971/control_loops/drivetrain/improved_down_estimator_test.cc
@@ -11,9 +11,7 @@
 #include "frc971/control_loops/quaternion_utils.h"
 #include "frc971/control_loops/runge_kutta.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace testing {
+namespace frc971::control_loops::testing {
 
 namespace {
 // Check if two quaternions are logically equal, to within some reasonable
@@ -221,6 +219,4 @@
          "covariance.";
 }
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::testing
diff --git a/frc971/control_loops/drivetrain/libspline.cc b/frc971/control_loops/drivetrain/libspline.cc
index f275c17..57abe69 100644
--- a/frc971/control_loops/drivetrain/libspline.cc
+++ b/frc971/control_loops/drivetrain/libspline.cc
@@ -10,9 +10,7 @@
 #include "frc971/control_loops/drivetrain/trajectory.h"
 #include "y2020/control_loops/drivetrain/drivetrain_base.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 
 extern "C" {
 // Based on spline.h
@@ -204,6 +202,4 @@
 void SetUpLogging() { ::aos::network::OverrideTeamNumber(971); }
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
diff --git a/frc971/control_loops/drivetrain/line_follow_drivetrain.cc b/frc971/control_loops/drivetrain/line_follow_drivetrain.cc
index 355710c..e54376c 100644
--- a/frc971/control_loops/drivetrain/line_follow_drivetrain.cc
+++ b/frc971/control_loops/drivetrain/line_follow_drivetrain.cc
@@ -8,9 +8,7 @@
 #include "frc971/control_loops/c2d.h"
 #include "frc971/control_loops/dlqr.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 namespace {
 namespace chrono = ::std::chrono;
 }  // namespace
@@ -308,6 +306,4 @@
   return line_follow_logging_builder.Finish();
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
diff --git a/frc971/control_loops/drivetrain/line_follow_drivetrain_test.cc b/frc971/control_loops/drivetrain/line_follow_drivetrain_test.cc
index d2ebb4e..ed018b9 100644
--- a/frc971/control_loops/drivetrain/line_follow_drivetrain_test.cc
+++ b/frc971/control_loops/drivetrain/line_follow_drivetrain_test.cc
@@ -14,10 +14,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
-namespace testing {
+namespace frc971::control_loops::drivetrain::testing {
 
 class LineFollowDrivetrainTest : public ::testing::Test {
  public:
@@ -395,7 +392,4 @@
                                    0.125 * state.x() * state.x();
                           })));
 
-}  // namespace testing
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain::testing
diff --git a/frc971/control_loops/drivetrain/localization/puppet_localizer.cc b/frc971/control_loops/drivetrain/localization/puppet_localizer.cc
index 8a60ea5..9215702 100644
--- a/frc971/control_loops/drivetrain/localization/puppet_localizer.cc
+++ b/frc971/control_loops/drivetrain/localization/puppet_localizer.cc
@@ -1,8 +1,6 @@
 #include "frc971/control_loops/drivetrain/localization/puppet_localizer.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 
 PuppetLocalizer::PuppetLocalizer(
     aos::EventLoop *event_loop,
@@ -98,6 +96,4 @@
   }
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
diff --git a/frc971/control_loops/drivetrain/localization/puppet_localizer_test.cc b/frc971/control_loops/drivetrain/localization/puppet_localizer_test.cc
index 1a71d5a..a4338a8 100644
--- a/frc971/control_loops/drivetrain/localization/puppet_localizer_test.cc
+++ b/frc971/control_loops/drivetrain/localization/puppet_localizer_test.cc
@@ -18,10 +18,7 @@
 DEFINE_string(output_folder, "",
               "If set, logs all channels to the provided logfile.");
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
-namespace testing {
+namespace frc971::control_loops::drivetrain::testing {
 
 using frc971::control_loops::drivetrain::DrivetrainConfig;
 using frc971::control_loops::drivetrain::Goal;
@@ -207,7 +204,4 @@
   EXPECT_TRUE(VerifyEstimatorAccurate(5e-3));
 }
 
-}  // namespace testing
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain::testing
diff --git a/frc971/control_loops/drivetrain/polydrivetrain.cc b/frc971/control_loops/drivetrain/polydrivetrain.cc
index b52b67f..c20e4ab 100644
--- a/frc971/control_loops/drivetrain/polydrivetrain.cc
+++ b/frc971/control_loops/drivetrain/polydrivetrain.cc
@@ -1,7 +1 @@
 #include "frc971/control_loops/drivetrain/polydrivetrain.h"
-
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
diff --git a/frc971/control_loops/drivetrain/spline.cc b/frc971/control_loops/drivetrain/spline.cc
index 609d3b1..a7f749e 100644
--- a/frc971/control_loops/drivetrain/spline.cc
+++ b/frc971/control_loops/drivetrain/spline.cc
@@ -1,8 +1,6 @@
 #include "frc971/control_loops/drivetrain/spline.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 
 ::Eigen::Matrix<double, 2, 6> Spline4To6(
     const ::Eigen::Matrix<double, 2, 4> &control_points) {
@@ -36,6 +34,4 @@
   return new_control_points;
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
diff --git a/frc971/control_loops/drivetrain/spline_test.cc b/frc971/control_loops/drivetrain/spline_test.cc
index 6498fb6..6d84d53 100644
--- a/frc971/control_loops/drivetrain/spline_test.cc
+++ b/frc971/control_loops/drivetrain/spline_test.cc
@@ -9,10 +9,7 @@
 
 DEFINE_bool(plot, false, "If true, plot");
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
-namespace testing {
+namespace frc971::control_loops::drivetrain::testing {
 
 std::string TestName() {
   const ::testing::TestInfo *info =
@@ -258,7 +255,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain::testing
diff --git a/frc971/control_loops/drivetrain/splinedrivetrain.cc b/frc971/control_loops/drivetrain/splinedrivetrain.cc
index 977529f..508967c 100644
--- a/frc971/control_loops/drivetrain/splinedrivetrain.cc
+++ b/frc971/control_loops/drivetrain/splinedrivetrain.cc
@@ -11,9 +11,7 @@
 #include "frc971/control_loops/drivetrain/drivetrain_output_generated.h"
 #include "frc971/control_loops/drivetrain/drivetrain_status_generated.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 
 SplineDrivetrain::SplineDrivetrain(const DrivetrainConfig<double> &dt_config)
     : dt_config_(dt_config),
@@ -268,6 +266,4 @@
   return MakeTrajectoryLogging(builder->fbb());
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
diff --git a/frc971/control_loops/drivetrain/ssdrivetrain.cc b/frc971/control_loops/drivetrain/ssdrivetrain.cc
index e1c4dac..74cc6ff 100644
--- a/frc971/control_loops/drivetrain/ssdrivetrain.cc
+++ b/frc971/control_loops/drivetrain/ssdrivetrain.cc
@@ -9,9 +9,7 @@
 #include "frc971/control_loops/polytope.h"
 #include "frc971/control_loops/state_feedback_loop.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 
 DrivetrainMotorsSS::DrivetrainMotorsSS(
     const DrivetrainConfig<double> &dt_config, StateFeedbackLoop<7, 2, 4> *kf,
@@ -300,6 +298,4 @@
       profiled_gyro_left_right(kRightVelocity));
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
diff --git a/frc971/control_loops/drivetrain/trajectory.cc b/frc971/control_loops/drivetrain/trajectory.cc
index 76a6784..36d0947 100644
--- a/frc971/control_loops/drivetrain/trajectory.cc
+++ b/frc971/control_loops/drivetrain/trajectory.cc
@@ -12,9 +12,7 @@
 #include "frc971/control_loops/hybrid_state_feedback_loop.h"
 #include "frc971/control_loops/state_feedback_loop.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 
 namespace {
 float DefaultConstraint(ConstraintType type) {
@@ -906,6 +904,4 @@
   return result;
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
diff --git a/frc971/control_loops/drivetrain/trajectory_generator.cc b/frc971/control_loops/drivetrain/trajectory_generator.cc
index d022b34..8e3e0f8 100644
--- a/frc971/control_loops/drivetrain/trajectory_generator.cc
+++ b/frc971/control_loops/drivetrain/trajectory_generator.cc
@@ -1,8 +1,6 @@
 #include "frc971/control_loops/drivetrain/trajectory_generator.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 
 TrajectoryGenerator::TrajectoryGenerator(aos::EventLoop *event_loop,
                                          const DrivetrainConfig<double> &config)
@@ -26,6 +24,4 @@
            aos::RawSender::Error::kOk);
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
diff --git a/frc971/control_loops/drivetrain/trajectory_plot.cc b/frc971/control_loops/drivetrain/trajectory_plot.cc
index 207df18..8c3ef47 100644
--- a/frc971/control_loops/drivetrain/trajectory_plot.cc
+++ b/frc971/control_loops/drivetrain/trajectory_plot.cc
@@ -40,9 +40,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
+namespace frc971::control_loops::drivetrain {
 
 void Main() {
   const DrivetrainConfig<double> config =
@@ -229,9 +227,7 @@
   }
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain
 
 int main(int argc, char **argv) {
   ::gflags::ParseCommandLineFlags(&argc, &argv, false);
diff --git a/frc971/control_loops/drivetrain/trajectory_test.cc b/frc971/control_loops/drivetrain/trajectory_test.cc
index 82ae312..fbf8970 100644
--- a/frc971/control_loops/drivetrain/trajectory_test.cc
+++ b/frc971/control_loops/drivetrain/trajectory_test.cc
@@ -23,10 +23,7 @@
 DEFINE_string(output_file, "",
               "If set, logs all channels to the provided logfile.");
 
-namespace frc971 {
-namespace control_loops {
-namespace drivetrain {
-namespace testing {
+namespace frc971::control_loops::drivetrain::testing {
 
 namespace chrono = ::std::chrono;
 
@@ -602,7 +599,4 @@
 // fast...  We want to maybe replan when we get behind, or something.  Maybe
 // stop moving the setpoint like our 2018 arm?
 
-}  // namespace testing
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::drivetrain::testing
diff --git a/frc971/control_loops/fixed_quadrature_test.cc b/frc971/control_loops/fixed_quadrature_test.cc
index 0615031..5241c08 100644
--- a/frc971/control_loops/fixed_quadrature_test.cc
+++ b/frc971/control_loops/fixed_quadrature_test.cc
@@ -4,9 +4,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace testing {
+namespace frc971::control_loops::testing {
 
 // Tests that integrating y = cos(x) works.
 TEST(GaussianQuadratureTest, Cos) {
@@ -28,6 +26,4 @@
       ::std::sin(0.5), -std::cos(0.5) + std::cos(0))));
 }
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::testing
diff --git a/frc971/control_loops/flywheel/flywheel_controller.cc b/frc971/control_loops/flywheel/flywheel_controller.cc
index dc82147..aa8087f 100644
--- a/frc971/control_loops/flywheel/flywheel_controller.cc
+++ b/frc971/control_loops/flywheel/flywheel_controller.cc
@@ -3,9 +3,8 @@
 #include <chrono>
 
 #include "aos/logging/logging.h"
-namespace frc971 {
-namespace control_loops {
-namespace flywheel {
+
+namespace frc971::control_loops::flywheel {
 
 // Class to current limit battery current for a flywheel controller.
 class CurrentLimitedStateFeedbackController
@@ -173,6 +172,4 @@
 
 double FlywheelController::velocity() const { return loop_->X_hat(1, 0); }
 
-}  // namespace flywheel
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::flywheel
diff --git a/frc971/control_loops/gaussian_noise.cc b/frc971/control_loops/gaussian_noise.cc
index ddfa0f3..1d0747c 100644
--- a/frc971/control_loops/gaussian_noise.cc
+++ b/frc971/control_loops/gaussian_noise.cc
@@ -1,7 +1,6 @@
 #include "frc971/control_loops/gaussian_noise.h"
 
-namespace frc971 {
-namespace control_loops {
+namespace frc971::control_loops {
 
 GaussianNoise::GaussianNoise(unsigned int seed, double stddev)
     : stddev_(stddev), generator_(seed), distribution_(0.0, 1.0) {
@@ -12,5 +11,4 @@
   return sample + (distribution_(generator_) * stddev_);
 }
 
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops
diff --git a/frc971/control_loops/hybrid_state_feedback_loop_test.cc b/frc971/control_loops/hybrid_state_feedback_loop_test.cc
index b9a0307..92f62b2 100644
--- a/frc971/control_loops/hybrid_state_feedback_loop_test.cc
+++ b/frc971/control_loops/hybrid_state_feedback_loop_test.cc
@@ -4,9 +4,7 @@
 
 #include "frc971/control_loops/state_feedback_loop.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace testing {
+namespace frc971::control_loops::testing {
 
 StateFeedbackHybridPlantCoefficients<3, 1, 1>
 MakeIntegralShooterPlantCoefficients() {
@@ -199,6 +197,4 @@
   EXPECT_TRUE(R_discrete.isApprox(test_loop.observer().R(), 0.001));
 }
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::testing
diff --git a/frc971/control_loops/jacobian_test.cc b/frc971/control_loops/jacobian_test.cc
index 57c9d7f..5606004 100644
--- a/frc971/control_loops/jacobian_test.cc
+++ b/frc971/control_loops/jacobian_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace testing {
+namespace frc971::control_loops::testing {
 
 ::Eigen::Matrix<double, 4, 4> A = (::Eigen::Matrix<double, 4, 4>() << 1, 2, 4,
                                    1, 5, 2, 3, 4, 5, 1, 3, 2, 1, 1, 3, 7)
@@ -35,6 +33,4 @@
   EXPECT_TRUE(NewB.isApprox(B));
 }
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::testing
diff --git a/frc971/control_loops/polytope_test.cc b/frc971/control_loops/polytope_test.cc
index 0a01248..542c981 100644
--- a/frc971/control_loops/polytope_test.cc
+++ b/frc971/control_loops/polytope_test.cc
@@ -8,8 +8,7 @@
 
 #include "aos/testing/test_logging.h"
 
-namespace frc971 {
-namespace controls {
+namespace frc971::controls {
 
 class HPolytopeTest : public ::testing::Test {
  protected:
@@ -102,5 +101,4 @@
               .finished())));
 }
 
-}  // namespace controls
-}  // namespace frc971
+}  // namespace frc971::controls
diff --git a/frc971/control_loops/pose_test.cc b/frc971/control_loops/pose_test.cc
index 845dda7..9b3b51f 100644
--- a/frc971/control_loops/pose_test.cc
+++ b/frc971/control_loops/pose_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace testing {
+namespace frc971::control_loops::testing {
 
 // Test that basic accessors on an individual Pose object work as expected.
 TEST(PoseTest, BasicPoseTest) {
@@ -195,6 +193,4 @@
   EXPECT_FALSE(l6.Intersects(l5));
 }
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::testing
diff --git a/frc971/control_loops/position_sensor_sim.cc b/frc971/control_loops/position_sensor_sim.cc
index 222af5d..7933213 100644
--- a/frc971/control_loops/position_sensor_sim.cc
+++ b/frc971/control_loops/position_sensor_sim.cc
@@ -2,8 +2,7 @@
 
 #include <cmath>
 
-namespace frc971 {
-namespace control_loops {
+namespace frc971::control_loops {
 
 /* Index pulse/segment Explanation:
  *
@@ -237,5 +236,4 @@
   return builder->Finish();
 }
 
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops
diff --git a/frc971/control_loops/position_sensor_sim_test.cc b/frc971/control_loops/position_sensor_sim_test.cc
index 4be0dc4..2189589 100644
--- a/frc971/control_loops/position_sensor_sim_test.cc
+++ b/frc971/control_loops/position_sensor_sim_test.cc
@@ -11,8 +11,7 @@
 #include "aos/die.h"
 #include "frc971/control_loops/control_loops_generated.h"
 
-namespace frc971 {
-namespace control_loops {
+namespace frc971::control_loops {
 
 class PositionSensorSimTest : public ::testing::Test {
  protected:
@@ -460,5 +459,4 @@
   EXPECT_NEAR(position->single_turn_absolute_encoder(), 0.1, 1e-10);
 }
 
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops
diff --git a/frc971/control_loops/profiled_subsystem.cc b/frc971/control_loops/profiled_subsystem.cc
index 4a90bf5..dc1a377 100644
--- a/frc971/control_loops/profiled_subsystem.cc
+++ b/frc971/control_loops/profiled_subsystem.cc
@@ -1,8 +1,6 @@
 #include "frc971/control_loops/profiled_subsystem.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace internal {
+namespace frc971::control_loops::internal {
 
 double UseUnlessZero(double target_value, double default_value) {
   if (target_value != 0.0) {
@@ -12,6 +10,4 @@
   }
 }
 
-}  // namespace internal
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::internal
diff --git a/frc971/control_loops/quaternion_utils.cc b/frc971/control_loops/quaternion_utils.cc
index bce78d0..dc5b411 100644
--- a/frc971/control_loops/quaternion_utils.cc
+++ b/frc971/control_loops/quaternion_utils.cc
@@ -3,8 +3,7 @@
 #include "Eigen/Dense"
 #include "Eigen/Geometry"
 
-namespace frc971 {
-namespace controls {
+namespace frc971::controls {
 namespace {
 
 double SinXoverX(double x) {
@@ -132,5 +131,4 @@
   return result;
 }
 
-}  // namespace controls
-}  // namespace frc971
+}  // namespace frc971::controls
diff --git a/frc971/control_loops/quaternion_utils_test.cc b/frc971/control_loops/quaternion_utils_test.cc
index 32b1915..4e9e97a 100644
--- a/frc971/control_loops/quaternion_utils_test.cc
+++ b/frc971/control_loops/quaternion_utils_test.cc
@@ -10,9 +10,7 @@
 #include "frc971/control_loops/jacobian.h"
 #include "frc971/control_loops/runge_kutta.h"
 
-namespace frc971 {
-namespace controls {
-namespace testing {
+namespace frc971::controls::testing {
 
 // Tests that small perturbations around a couple quaternions averaged out
 // return the original quaternion.
@@ -212,6 +210,4 @@
   EXPECT_NEAR(0.0, (uz - integral3 * uz).norm(), 5e-2);
 }
 
-}  // namespace testing
-}  // namespace controls
-}  // namespace frc971
+}  // namespace frc971::controls::testing
diff --git a/frc971/control_loops/runge_kutta_test.cc b/frc971/control_loops/runge_kutta_test.cc
index e07c469..1022a47 100644
--- a/frc971/control_loops/runge_kutta_test.cc
+++ b/frc971/control_loops/runge_kutta_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace testing {
+namespace frc971::control_loops::testing {
 
 // Tests that integrating dx/dt = e^x works.
 TEST(RungeKuttaTest, Exponential) {
@@ -92,6 +90,4 @@
   EXPECT_NEAR(y1(0, 0), RungeKuttaTimeVaryingSolution(6.0)(0, 0), 1e-7);
 }
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::testing
diff --git a/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.cc b/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.cc
index 1fd9049..ea24ff3 100644
--- a/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.cc
+++ b/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.cc
@@ -22,8 +22,7 @@
 
 using ::frc971::control_loops::PositionSensorSimulator;
 
-namespace frc971 {
-namespace control_loops {
+namespace frc971::control_loops {
 namespace {
 constexpr double kNoiseScalar = 0.01;
 
@@ -841,5 +840,4 @@
                             ZeroingErrorTest);
 INSTANTIATE_TYPED_TEST_SUITE_P(My, IntakeSystemTest, TestTypes);
 
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops
diff --git a/frc971/control_loops/team_number_test_environment.cc b/frc971/control_loops/team_number_test_environment.cc
index a8f4ca7..1a3ccf6 100644
--- a/frc971/control_loops/team_number_test_environment.cc
+++ b/frc971/control_loops/team_number_test_environment.cc
@@ -2,14 +2,10 @@
 
 #include "aos/network/team_number.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace testing {
+namespace frc971::control_loops::testing {
 
 void TeamNumberEnvironment::SetUp() {
   ::aos::network::OverrideTeamNumber(kTeamNumber);
 }
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::testing
diff --git a/frc971/control_loops/voltage_cap/voltage_cap.cc b/frc971/control_loops/voltage_cap/voltage_cap.cc
index d6d8456..aab355c 100644
--- a/frc971/control_loops/voltage_cap/voltage_cap.cc
+++ b/frc971/control_loops/voltage_cap/voltage_cap.cc
@@ -2,8 +2,7 @@
 
 #include <limits>
 
-namespace frc971 {
-namespace control_loops {
+namespace frc971::control_loops {
 
 void VoltageCap(double max_voltage, double voltage_one, double voltage_two,
                 double *out_voltage_one, double *out_voltage_two) {
@@ -91,5 +90,4 @@
   VoltageCap(12.0, voltage_one, voltage_two, out_voltage_one, out_voltage_two);
 }
 
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops
diff --git a/frc971/control_loops/voltage_cap/voltage_cap_test.cc b/frc971/control_loops/voltage_cap/voltage_cap_test.cc
index ea812b9..b77d107 100644
--- a/frc971/control_loops/voltage_cap/voltage_cap_test.cc
+++ b/frc971/control_loops/voltage_cap/voltage_cap_test.cc
@@ -4,9 +4,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace control_loops {
-namespace testing {
+namespace frc971::control_loops::testing {
 
 class VoltageTest : public ::testing::Test {};
 
@@ -240,6 +238,4 @@
   EXPECT_EQ(5.0, voltage_two);
 }
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace frc971
+}  // namespace frc971::control_loops::testing
diff --git a/frc971/input/action_joystick_input.cc b/frc971/input/action_joystick_input.cc
index dfd229e..ae3346c 100644
--- a/frc971/input/action_joystick_input.cc
+++ b/frc971/input/action_joystick_input.cc
@@ -8,8 +8,7 @@
 
 using ::frc971::input::driver_station::ControlBit;
 
-namespace frc971 {
-namespace input {
+namespace frc971::input {
 
 void ActionJoystickInput::RunIteration(
     const ::frc971::input::driver_station::Data &unsorted_data) {
@@ -74,5 +73,4 @@
   AutoEnded();
 }
 
-}  // namespace input
-}  // namespace frc971
+}  // namespace frc971::input
diff --git a/frc971/input/driver_station_data.cc b/frc971/input/driver_station_data.cc
index 18d96fd..06d2d69 100644
--- a/frc971/input/driver_station_data.cc
+++ b/frc971/input/driver_station_data.cc
@@ -2,9 +2,7 @@
 
 #include "glog/logging.h"
 
-namespace frc971 {
-namespace input {
-namespace driver_station {
+namespace frc971::input::driver_station {
 
 Data::Data() : current_values_(), old_values_() {}
 
@@ -119,6 +117,4 @@
   return current_values_.joysticks[axis.joystick() - 1].axis[axis.number() - 1];
 }
 
-}  // namespace driver_station
-}  // namespace input
-}  // namespace frc971
+}  // namespace frc971::input::driver_station
diff --git a/frc971/input/drivetrain_input.cc b/frc971/input/drivetrain_input.cc
index 5aedd0e..be61cc4 100644
--- a/frc971/input/drivetrain_input.cc
+++ b/frc971/input/drivetrain_input.cc
@@ -18,8 +18,7 @@
 
 namespace drivetrain = frc971::control_loops::drivetrain;
 
-namespace frc971 {
-namespace input {
+namespace frc971::input {
 
 const ButtonLocation kShiftHigh(2, 3), kShiftHigh2(2, 2), kShiftLow(2, 1);
 
@@ -371,5 +370,4 @@
   return drivetrain_input_reader;
 }
 
-}  // namespace input
-}  // namespace frc971
+}  // namespace frc971::input
diff --git a/frc971/input/joystick_input.cc b/frc971/input/joystick_input.cc
index d0d9bc0..19eaa37 100644
--- a/frc971/input/joystick_input.cc
+++ b/frc971/input/joystick_input.cc
@@ -6,8 +6,7 @@
 #include "aos/logging/logging.h"
 #include "frc971/input/robot_state_generated.h"
 
-namespace frc971 {
-namespace input {
+namespace frc971::input {
 
 void JoystickInput::HandleData(const ::aos::JoystickState *joystick_state) {
   data_.Update(joystick_state);
@@ -60,5 +59,4 @@
   RunIteration(data_);
 }
 
-}  // namespace input
-}  // namespace frc971
+}  // namespace frc971::input
diff --git a/frc971/input/redundant_joystick_data.cc b/frc971/input/redundant_joystick_data.cc
index a25e6c3..752239d 100644
--- a/frc971/input/redundant_joystick_data.cc
+++ b/frc971/input/redundant_joystick_data.cc
@@ -2,9 +2,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace frc971 {
-namespace input {
-namespace driver_station {
+namespace frc971::input::driver_station {
 
 RedundantData::RedundantData(const Data &data) : joystick_map_(), data_(data) {
   // Start with a naive map.
@@ -98,6 +96,4 @@
   return data_.GetAxis(mapped_location);
 }
 
-}  // namespace driver_station
-}  // namespace input
-}  // namespace frc971
+}  // namespace frc971::input::driver_station
diff --git a/frc971/orin/apriltag.cc b/frc971/orin/apriltag.cc
index 1cb0f88..dd253d1 100644
--- a/frc971/orin/apriltag.cc
+++ b/frc971/orin/apriltag.cc
@@ -22,8 +22,7 @@
 #include "frc971/orin/threshold.h"
 #include "frc971/orin/transform_output_iterator.h"
 
-namespace frc971 {
-namespace apriltag {
+namespace frc971::apriltag {
 namespace {
 
 typedef std::chrono::duration<float, std::milli> float_milli;
@@ -1151,5 +1150,4 @@
   first_ = false;
 }
 
-}  // namespace apriltag
-}  // namespace frc971
+}  // namespace frc971::apriltag
diff --git a/frc971/orin/apriltag_detect.cc b/frc971/orin/apriltag_detect.cc
index eecc056..69c93cc 100644
--- a/frc971/orin/apriltag_detect.cc
+++ b/frc971/orin/apriltag_detect.cc
@@ -31,8 +31,7 @@
                           zarray_t *poly1);
 };
 
-namespace frc971 {
-namespace apriltag {
+namespace frc971::apriltag {
 namespace {
 
 void HostFitLine(LineFitMoments moments, double *lineparam01,
@@ -519,5 +518,4 @@
   zarray_sort(detections_, detection_compare_function);
 }
 
-}  // namespace apriltag
-}  // namespace frc971
+}  // namespace frc971::apriltag
diff --git a/frc971/orin/crcv_generator.cc b/frc971/orin/crcv_generator.cc
index 5c72385..a3f1f03 100644
--- a/frc971/orin/crcv_generator.cc
+++ b/frc971/orin/crcv_generator.cc
@@ -15,8 +15,8 @@
 // ahead-of-time optimized functions as directed by command-line arguments.
 // https://halide-lang.org/tutorials/tutorial_lesson_15_generators.html has an
 // introduction to much of the magic in this file.
-namespace frc971 {
-namespace orin {
+
+namespace frc971::orin {
 namespace {
 
 template <typename T>
@@ -142,8 +142,7 @@
   }
 };
 
-}  // namespace orin
-}  // namespace frc971
+}  // namespace frc971::orin
 
 HALIDE_REGISTER_GENERATOR(frc971::orin::YCbCr, ycbcr)
 HALIDE_REGISTER_GENERATOR(frc971::orin::YCbCr422, ycbcr422)
diff --git a/frc971/orin/cuda.cc b/frc971/orin/cuda.cc
index 89b1529..6bcc79c 100644
--- a/frc971/orin/cuda.cc
+++ b/frc971/orin/cuda.cc
@@ -7,8 +7,7 @@
     sync, false,
     "If true, force synchronization after each step to isolate errors better.");
 
-namespace frc971 {
-namespace apriltag {
+namespace frc971::apriltag {
 
 size_t overall_memory = 0;
 
@@ -25,5 +24,4 @@
   if (FLAGS_sync) CheckAndSynchronize(message);
 }
 
-}  // namespace apriltag
-}  // namespace frc971
+}  // namespace frc971::apriltag
diff --git a/frc971/orin/line_fit_filter.cc b/frc971/orin/line_fit_filter.cc
index 954976a..737079f 100644
--- a/frc971/orin/line_fit_filter.cc
+++ b/frc971/orin/line_fit_filter.cc
@@ -8,8 +8,7 @@
 
 // #define DEBUG_BLOB_NUMBER 401
 
-namespace frc971 {
-namespace apriltag {
+namespace frc971::apriltag {
 
 static_assert(sizeof(LineFitPoint) == 40, "Size of LineFitPoint changed");
 static_assert(sizeof(int4) == 16, "Size of int4 changed");
@@ -1231,5 +1230,4 @@
   return os;
 }
 
-}  // namespace apriltag
-}  // namespace frc971
+}  // namespace frc971::apriltag
diff --git a/frc971/orin/points.cc b/frc971/orin/points.cc
index dbf5496..7dc36f2 100644
--- a/frc971/orin/points.cc
+++ b/frc971/orin/points.cc
@@ -3,8 +3,7 @@
 #include <iomanip>
 #include <ostream>
 
-namespace frc971 {
-namespace apriltag {
+namespace frc971::apriltag {
 
 std::ostream &operator<<(std::ostream &os, const QuadBoundaryPoint &point) {
   std::ios_base::fmtflags original_flags = os.flags();
@@ -31,5 +30,4 @@
 
 static_assert(sizeof(IndexPoint) == 8, "IndexPoint didn't pack right.");
 
-}  // namespace apriltag
-}  // namespace frc971
+}  // namespace frc971::apriltag
diff --git a/frc971/orin/threshold.cc b/frc971/orin/threshold.cc
index 79ccced..4254b71 100644
--- a/frc971/orin/threshold.cc
+++ b/frc971/orin/threshold.cc
@@ -4,8 +4,7 @@
 
 #include "frc971/orin/cuda.h"
 
-namespace frc971 {
-namespace apriltag {
+namespace frc971::apriltag {
 namespace {
 
 // 1280 -> 2 * 128 * 5
@@ -202,5 +201,4 @@
   }
 }
 
-}  // namespace apriltag
-}  // namespace frc971
+}  // namespace frc971::apriltag
diff --git a/frc971/orin/transform_output_iterator.h b/frc971/orin/transform_output_iterator.h
index 051baea..cdda637 100644
--- a/frc971/orin/transform_output_iterator.h
+++ b/frc971/orin/transform_output_iterator.h
@@ -1,8 +1,7 @@
 #ifndef FRC971_TRANSFORM_OUTPUT_ITERATOR_
 #define FRC971_TRANSFORM_OUTPUT_ITERATOR_
 
-namespace frc971 {
-namespace apriltag {
+namespace frc971::apriltag {
 
 // template class that allows conversions at the output of a cub algorithm
 template <typename InputType, typename OutputType, typename ConversionOp,
@@ -86,7 +85,6 @@
   OutputType *ptr;
 };
 
-}  // namespace apriltag
-}  // namespace frc971
+}  // namespace frc971::apriltag
 
 #endif  // FRC971_TRANSFORM_OUTPUT_ITERATOR_
diff --git a/frc971/shifter_hall_effect.h b/frc971/shifter_hall_effect.h
index 991386d..4a0197c 100644
--- a/frc971/shifter_hall_effect.h
+++ b/frc971/shifter_hall_effect.h
@@ -1,8 +1,7 @@
 #ifndef FRC971_SHIFTER_HALL_EFFECT_H_
 #define FRC971_SHIFTER_HALL_EFFECT_H_
 
-namespace frc971 {
-namespace constants {
+namespace frc971::constants {
 
 // Contains the constants for mapping the analog voltages that the shifter
 // sensors return to the shifter position.  The code which uses this is trying
@@ -28,7 +27,6 @@
   double high_gear_middle;
 };
 
-}  // namespace constants
-}  // namespace frc971
+}  // namespace frc971::constants
 
 #endif
diff --git a/frc971/shooter_interpolation/interpolation.cc b/frc971/shooter_interpolation/interpolation.cc
index 66b2cf9..1faa046 100644
--- a/frc971/shooter_interpolation/interpolation.cc
+++ b/frc971/shooter_interpolation/interpolation.cc
@@ -4,12 +4,10 @@
 #include <utility>
 #include <vector>
 
-namespace frc971 {
-namespace shooter_interpolation {
+namespace frc971::shooter_interpolation {
 
 double Blend(double coefficient, double a1, double a2) {
   return (1 - coefficient) * a1 + coefficient * a2;
 }
 
-}  // namespace shooter_interpolation
-}  // namespace frc971
+}  // namespace frc971::shooter_interpolation
diff --git a/frc971/shooter_interpolation/interpolation_test.cc b/frc971/shooter_interpolation/interpolation_test.cc
index 92a2b76..3409282 100644
--- a/frc971/shooter_interpolation/interpolation_test.cc
+++ b/frc971/shooter_interpolation/interpolation_test.cc
@@ -8,8 +8,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace shooter_interpolation {
+namespace frc971::shooter_interpolation {
 
 struct TestShotParams {
   double angle;
@@ -72,5 +71,4 @@
   ASSERT_EQ(TestShotParams({10, 567.323}), interpolation.Get(5));
 }
 
-}  // namespace shooter_interpolation
-}  // namespace frc971
+}  // namespace frc971::shooter_interpolation
diff --git a/frc971/solvers/convex_test.cc b/frc971/solvers/convex_test.cc
index 213e70b..21f2f8c 100644
--- a/frc971/solvers/convex_test.cc
+++ b/frc971/solvers/convex_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace solvers {
-namespace testing {
+namespace frc971::solvers::testing {
 
 const Eigen::IOFormat kHeavyFormat(Eigen::StreamPrecision, 0, ", ",
                                    ",\n                        "
@@ -101,6 +99,4 @@
   EXPECT_NEAR((result - Eigen::Vector2d(4.0, 4.0)).norm(), 0.0, 1e-6);
 }
 
-}  // namespace testing
-}  // namespace solvers
-}  // namespace frc971
+}  // namespace frc971::solvers::testing
diff --git a/frc971/solvers/sparse_convex.cc b/frc971/solvers/sparse_convex.cc
index 7e2a6ca..714b21c 100644
--- a/frc971/solvers/sparse_convex.cc
+++ b/frc971/solvers/sparse_convex.cc
@@ -5,8 +5,7 @@
 #include <Eigen/Sparse>
 #include <Eigen/SparseLU>
 
-namespace frc971 {
-namespace solvers {
+namespace frc971::solvers {
 
 Eigen::VectorXd SparseSolver::Rt(const Derivatives &derivatives,
                                  Eigen::VectorXd y, double t_inverse) {
@@ -356,5 +355,4 @@
   }
 }
 
-}  // namespace solvers
-}  // namespace frc971
+}  // namespace frc971::solvers
diff --git a/frc971/solvers/sparse_convex_test.cc b/frc971/solvers/sparse_convex_test.cc
index 63a9409..490e8e2 100644
--- a/frc971/solvers/sparse_convex_test.cc
+++ b/frc971/solvers/sparse_convex_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace solvers {
-namespace testing {
+namespace frc971::solvers::testing {
 
 const Eigen::IOFormat kHeavyFormat(Eigen::StreamPrecision, 0, ", ",
                                    ",\n                        "
@@ -98,6 +96,4 @@
   EXPECT_NEAR((result - Eigen::Vector2d(4.0, 4.0)).norm(), 0.0, 1e-6);
 }
 
-}  // namespace testing
-}  // namespace solvers
-}  // namespace frc971
+}  // namespace frc971::solvers::testing
diff --git a/frc971/vision/calibration_accumulator.cc b/frc971/vision/calibration_accumulator.cc
index 3b0bcc6..d8abd33 100644
--- a/frc971/vision/calibration_accumulator.cc
+++ b/frc971/vision/calibration_accumulator.cc
@@ -21,8 +21,7 @@
 DEFINE_bool(save_valid_only, false,
             "If true, only save images with valid pose estimates");
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 using aos::distributed_clock;
 using aos::monotonic_clock;
 namespace chrono = std::chrono;
@@ -278,5 +277,4 @@
                 gyro, accel * kG);
 }
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
diff --git a/frc971/vision/charuco_lib.cc b/frc971/vision/charuco_lib.cc
index 8e8acc3..c24d02c 100644
--- a/frc971/vision/charuco_lib.cc
+++ b/frc971/vision/charuco_lib.cc
@@ -38,8 +38,7 @@
 
 DECLARE_bool(enable_ftrace);
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace chrono = std::chrono;
 using aos::monotonic_clock;
 
@@ -600,5 +599,4 @@
   return os;
 }
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
diff --git a/frc971/vision/extrinsics_calibration.cc b/frc971/vision/extrinsics_calibration.cc
index 9459c84..6017258 100644
--- a/frc971/vision/extrinsics_calibration.cc
+++ b/frc971/vision/extrinsics_calibration.cc
@@ -14,8 +14,7 @@
 #include "frc971/vision/charuco_lib.h"
 #include "frc971/vision/visualize_robot.h"
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 
 namespace chrono = std::chrono;
 using aos::distributed_clock;
@@ -1008,5 +1007,4 @@
   filter.Visualize(calibration_parameters);
 }
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
diff --git a/frc971/vision/intrinsics_calibration.cc b/frc971/vision/intrinsics_calibration.cc
index 452dd74..b4d3825 100644
--- a/frc971/vision/intrinsics_calibration.cc
+++ b/frc971/vision/intrinsics_calibration.cc
@@ -23,8 +23,7 @@
               "Intrinsics to use for estimating board pose prior to solving "
               "for the new intrinsics.");
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace {
 
 void Main() {
@@ -52,8 +51,7 @@
 }
 
 }  // namespace
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/frc971/vision/intrinsics_calibration_lib.cc b/frc971/vision/intrinsics_calibration_lib.cc
index 6cf53e8..ab03e01 100644
--- a/frc971/vision/intrinsics_calibration_lib.cc
+++ b/frc971/vision/intrinsics_calibration_lib.cc
@@ -1,7 +1,6 @@
 #include "frc971/vision/intrinsics_calibration_lib.h"
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 
 IntrinsicsCalibration::IntrinsicsCalibration(
     aos::EventLoop *event_loop, std::string_view pi, std::string_view camera_id,
@@ -241,5 +240,4 @@
     LOG(INFO) << "Skipping calibration due to not enough images.";
   }
 }
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
diff --git a/frc971/vision/media_device.cc b/frc971/vision/media_device.cc
index a369cfb..46f3419 100644
--- a/frc971/vision/media_device.cc
+++ b/frc971/vision/media_device.cc
@@ -20,8 +20,7 @@
 #include "aos/scoped/scoped_fd.h"
 #include "aos/util/file.h"
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 
 void Entity::Log() const {
   LOG(INFO) << "  { \"id\": " << id() << ",";
@@ -408,5 +407,4 @@
   }
 }
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
diff --git a/frc971/vision/v4l2_reader.cc b/frc971/vision/v4l2_reader.cc
index 1404ec5..2d67c9c 100644
--- a/frc971/vision/v4l2_reader.cc
+++ b/frc971/vision/v4l2_reader.cc
@@ -9,8 +9,7 @@
 DEFINE_bool(ignore_timestamps, false,
             "Don't require timestamps on images.  Used to allow webcams");
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 
 V4L2ReaderBase::V4L2ReaderBase(aos::EventLoop *event_loop,
                                std::string_view device_name,
@@ -401,5 +400,4 @@
   PCHECK(ImageSensorIoctl(VIDIOC_S_EXT_CTRLS, &controls) == 0);
 }
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
diff --git a/frc971/vision/visualize_robot.cc b/frc971/vision/visualize_robot.cc
index 0c7a536..d13668e 100644
--- a/frc971/vision/visualize_robot.cc
+++ b/frc971/vision/visualize_robot.cc
@@ -6,8 +6,7 @@
 #include <opencv2/highgui/highgui.hpp>
 #include <opencv2/imgproc.hpp>
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 
 void VisualizeRobot::SetDefaultViewpoint(int image_width, double focal_length) {
   // 10 meters above the origin, rotated so the camera faces straight down
@@ -106,5 +105,4 @@
   DrawLine(rr_corner, fr_corner, color);
 }
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
diff --git a/frc971/vision/visualize_robot_sample.cc b/frc971/vision/visualize_robot_sample.cc
index 6ca7a9c..ad1d6b6 100644
--- a/frc971/vision/visualize_robot_sample.cc
+++ b/frc971/vision/visualize_robot_sample.cc
@@ -14,8 +14,7 @@
 #include "aos/time/time.h"
 #include "frc971/vision/visualize_robot.h"
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 
 // Show / test the basics of visualizing the robot frames
 void Main(int /*argc*/, char ** /* argv */) {
@@ -45,8 +44,7 @@
   cv::imshow("Display", image_mat);
   cv::waitKey();
 }
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/frc971/wpilib/ADIS16448.cc b/frc971/wpilib/ADIS16448.cc
index 597c5e8..c8aadfd 100644
--- a/frc971/wpilib/ADIS16448.cc
+++ b/frc971/wpilib/ADIS16448.cc
@@ -11,8 +11,7 @@
 #include "aos/time/time.h"
 #include "frc971/wpilib/imu_generated.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 using ::aos::monotonic_clock;
 namespace chrono = ::std::chrono;
@@ -424,5 +423,4 @@
   return true;
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/ADIS16470.cc b/frc971/wpilib/ADIS16470.cc
index 1612ee8..0b3d45c 100644
--- a/frc971/wpilib/ADIS16470.cc
+++ b/frc971/wpilib/ADIS16470.cc
@@ -8,8 +8,7 @@
 #include "aos/time/time.h"
 #include "hal/HAL.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 namespace {
 namespace chrono = std::chrono;
 namespace registers {
@@ -516,5 +515,4 @@
   spi_->Write(buffer2, sizeof(buffer2));
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/buffered_pcm.cc b/frc971/wpilib/buffered_pcm.cc
index f356722..c64bbdc 100644
--- a/frc971/wpilib/buffered_pcm.cc
+++ b/frc971/wpilib/buffered_pcm.cc
@@ -7,8 +7,7 @@
 #include "hal/HAL.h"
 #include "hal/Ports.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 BufferedPcm::BufferedPcm(int module) : module_(module) {
   for (int i = 0; i < 8; ++i) {
@@ -53,5 +52,4 @@
   }
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/buffered_solenoid.cc b/frc971/wpilib/buffered_solenoid.cc
index a4b337e..f6defcb 100644
--- a/frc971/wpilib/buffered_solenoid.cc
+++ b/frc971/wpilib/buffered_solenoid.cc
@@ -2,10 +2,8 @@
 
 #include "frc971/wpilib/buffered_pcm.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 void BufferedSolenoid::Set(bool value) { pcm_->DoSet(number_, value); }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/buffered_solenoid.h b/frc971/wpilib/buffered_solenoid.h
index f0a4c11..1f127c5 100644
--- a/frc971/wpilib/buffered_solenoid.h
+++ b/frc971/wpilib/buffered_solenoid.h
@@ -1,8 +1,7 @@
 #ifndef FRC971_WPILIB_BUFFERED_SOLENOID_H_
 #define FRC971_WPILIB_BUFFERED_SOLENOID_H_
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 class BufferedPcm;
 
@@ -22,7 +21,6 @@
   friend class BufferedPcm;
 };
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
 
 #endif  // FRC971_WPILIB_BUFFERED_SOLENOID_H_
diff --git a/frc971/wpilib/dma_edge_counting.cc b/frc971/wpilib/dma_edge_counting.cc
index 4e8a158..c84bc15 100644
--- a/frc971/wpilib/dma_edge_counting.cc
+++ b/frc971/wpilib/dma_edge_counting.cc
@@ -2,8 +2,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 bool DMAEdgeCounter::ExtractValue(const DMASample &sample) const {
   return sample.Get(input_);
@@ -101,5 +100,4 @@
   }
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/drivetrain_writer.cc b/frc971/wpilib/drivetrain_writer.cc
index 0afbe20..2966481 100644
--- a/frc971/wpilib/drivetrain_writer.cc
+++ b/frc971/wpilib/drivetrain_writer.cc
@@ -6,8 +6,7 @@
 #include "frc971/wpilib/ahal/PWM.h"
 #include "frc971/wpilib/loop_output_handler.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 void DrivetrainWriter::Write(
     const ::frc971::control_loops::drivetrain::Output &output) {
@@ -39,5 +38,4 @@
   }
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/encoder_and_potentiometer.cc b/frc971/wpilib/encoder_and_potentiometer.cc
index 578fb96..8a94e15 100644
--- a/frc971/wpilib/encoder_and_potentiometer.cc
+++ b/frc971/wpilib/encoder_and_potentiometer.cc
@@ -3,8 +3,7 @@
 #include "aos/logging/logging.h"
 #include "aos/realtime.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 bool DMAEncoder::DoUpdateFromSample(const DMASample &sample) {
   if (index_last_value_) {
@@ -20,5 +19,4 @@
   return false;
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/fpga_time_conversion.cc b/frc971/wpilib/fpga_time_conversion.cc
index 6f9a267..3ca9984 100644
--- a/frc971/wpilib/fpga_time_conversion.cc
+++ b/frc971/wpilib/fpga_time_conversion.cc
@@ -2,8 +2,7 @@
 
 #include "aos/util/compiler_memory_barrier.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 std::optional<std::chrono::nanoseconds> CalculateFpgaOffset() {
   aos_compiler_memory_barrier();
@@ -32,5 +31,4 @@
   return monotonic_now.time_since_epoch() - fpga_average;
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/gyro_interface.cc b/frc971/wpilib/gyro_interface.cc
index a90e95a..eb23b48 100644
--- a/frc971/wpilib/gyro_interface.cc
+++ b/frc971/wpilib/gyro_interface.cc
@@ -10,8 +10,7 @@
 #define M_PI 3.14159265358979323846
 #endif
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 GyroInterface::GyroInterface() : gyro_(new frc::SPI(frc::SPI::kOnboardCS0)) {
   // The gyro goes up to 8.08MHz.
@@ -146,5 +145,4 @@
   return result;
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/gyro_sender.cc b/frc971/wpilib/gyro_sender.cc
index ac88acb..934daf8 100644
--- a/frc971/wpilib/gyro_sender.cc
+++ b/frc971/wpilib/gyro_sender.cc
@@ -16,8 +16,7 @@
 #include "frc971/queues/gyro_uid_generated.h"
 #include "frc971/zeroing/averager.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
@@ -145,5 +144,4 @@
   }
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/interrupt_edge_counting.cc b/frc971/wpilib/interrupt_edge_counting.cc
index 9b63b84..4fc2172 100644
--- a/frc971/wpilib/interrupt_edge_counting.cc
+++ b/frc971/wpilib/interrupt_edge_counting.cc
@@ -5,8 +5,7 @@
 #include "aos/realtime.h"
 #include "aos/time/time.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 void EdgeCounter::GatherPolledValue() {
   shadow_values_.polled_value = input_->Get();
@@ -103,5 +102,4 @@
   return true;
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/joystick_sender.cc b/frc971/wpilib/joystick_sender.cc
index 26f7545..f3b97f6 100644
--- a/frc971/wpilib/joystick_sender.cc
+++ b/frc971/wpilib/joystick_sender.cc
@@ -8,8 +8,7 @@
 #include "frc971/wpilib/ahal/DriverStation.h"
 #include "hal/HAL.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 using aos::Joystick;
 
@@ -138,5 +137,4 @@
   });
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/loop_output_handler_test.cc b/frc971/wpilib/loop_output_handler_test.cc
index b3fbb0d..f3b4aef 100644
--- a/frc971/wpilib/loop_output_handler_test.cc
+++ b/frc971/wpilib/loop_output_handler_test.cc
@@ -10,9 +10,7 @@
 #include "aos/time/time.h"
 #include "frc971/wpilib/loop_output_handler_test_generated.h"
 
-namespace frc971 {
-namespace wpilib {
-namespace testing {
+namespace frc971::wpilib::testing {
 namespace {
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
@@ -118,6 +116,4 @@
             loop_output.last_time() + chrono::milliseconds(100));
 }
 
-}  // namespace testing
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib::testing
diff --git a/frc971/wpilib/pdp_fetcher.cc b/frc971/wpilib/pdp_fetcher.cc
index 0526806..5b02bb5 100644
--- a/frc971/wpilib/pdp_fetcher.cc
+++ b/frc971/wpilib/pdp_fetcher.cc
@@ -8,8 +8,7 @@
 #include "frc971/wpilib/ahal/PowerDistributionPanel.h"
 #include "frc971/wpilib/pdp_values_generated.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 namespace chrono = ::std::chrono;
 
@@ -50,5 +49,4 @@
   }
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/sensor_reader.cc b/frc971/wpilib/sensor_reader.cc
index 1486042..447e3b4 100644
--- a/frc971/wpilib/sensor_reader.cc
+++ b/frc971/wpilib/sensor_reader.cc
@@ -17,8 +17,7 @@
 DEFINE_int32(pwm_offset, 5050 / 2,
              "Offset of reading the sensors from the start of the PWM cycle");
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 SensorReader::SensorReader(::aos::ShmEventLoop *event_loop)
     : event_loop_(event_loop),
@@ -180,5 +179,4 @@
   }
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/spi_rx_clearer.cc b/frc971/wpilib/spi_rx_clearer.cc
index 1faa3f6..09bbbc8 100644
--- a/frc971/wpilib/spi_rx_clearer.cc
+++ b/frc971/wpilib/spi_rx_clearer.cc
@@ -8,8 +8,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 SpiRxClearer::SpiRxClearer() {
   const int fd = AOS_PCHECK(open("/dev/mem", O_RDWR));
@@ -40,5 +39,4 @@
   AOS_LOG(FATAL, "Failed to clear the RX FIFO\n");
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/wpilib_interface.cc b/frc971/wpilib/wpilib_interface.cc
index d1703ce..f5825c8 100644
--- a/frc971/wpilib/wpilib_interface.cc
+++ b/frc971/wpilib/wpilib_interface.cc
@@ -6,8 +6,7 @@
 #include "frc971/wpilib/ahal/Utility.h"
 #include "hal/HAL.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 flatbuffers::Offset<aos::RobotState> PopulateRobotState(
     aos::Sender<::aos::RobotState>::Builder *builder, int32_t my_pid) {
@@ -36,5 +35,4 @@
   return robot_state_builder.Finish();
 }
 
-}  // namespace wpilib
-}  // namespace frc971
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/wpilib_utils.cc b/frc971/wpilib/wpilib_utils.cc
index 937acd9..d6bc696 100644
--- a/frc971/wpilib/wpilib_utils.cc
+++ b/frc971/wpilib/wpilib_utils.cc
@@ -1,7 +1,6 @@
 #include "frc971/wpilib/wpilib_utils.h"
 
-namespace frc971 {
-namespace wpilib {
+namespace frc971::wpilib {
 
 bool SafePotVoltageRange(::frc971::constants::Range subsystem_range,
                          double potentiometer_offset,
@@ -22,5 +21,4 @@
           (kMinVoltage + limit_buffer) < max_range_voltage &&
           max_range_voltage < (kMaxVoltage - limit_buffer));
 }
-}  // namespace wpilib
-}  // namespace frc971
\ No newline at end of file
+}  // namespace frc971::wpilib
diff --git a/frc971/wpilib/wpilib_utils_test.cc b/frc971/wpilib/wpilib_utils_test.cc
index 2b21438..e9781b9 100644
--- a/frc971/wpilib/wpilib_utils_test.cc
+++ b/frc971/wpilib/wpilib_utils_test.cc
@@ -4,9 +4,7 @@
 #include "aos/testing/test_logging.h"
 #include "frc971/constants.h"
 
-namespace frc971 {
-namespace wpilib {
-namespace testing {
+namespace frc971::wpilib::testing {
 namespace {
 
 double climber_pot_translate_inverse_test(double position) {
@@ -153,6 +151,4 @@
 }
 
 }  // namespace
-}  // namespace testing
-}  // namespace wpilib
-}  // namespace frc971
\ No newline at end of file
+}  // namespace frc971::wpilib::testing
diff --git a/frc971/zeroing/absolute_and_absolute_encoder.cc b/frc971/zeroing/absolute_and_absolute_encoder.cc
index 03ef3f1..b9ba33d 100644
--- a/frc971/zeroing/absolute_and_absolute_encoder.cc
+++ b/frc971/zeroing/absolute_and_absolute_encoder.cc
@@ -8,8 +8,7 @@
 #include "aos/logging/logging.h"
 #include "frc971/zeroing/wrap.h"
 
-namespace frc971 {
-namespace zeroing {
+namespace frc971::zeroing {
 
 AbsoluteAndAbsoluteEncoderZeroingEstimator::
     AbsoluteAndAbsoluteEncoderZeroingEstimator(
@@ -234,5 +233,4 @@
   return builder.Finish();
 }
 
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing
diff --git a/frc971/zeroing/absolute_and_absolute_encoder_test.cc b/frc971/zeroing/absolute_and_absolute_encoder_test.cc
index 5dac38b..08ab924 100644
--- a/frc971/zeroing/absolute_and_absolute_encoder_test.cc
+++ b/frc971/zeroing/absolute_and_absolute_encoder_test.cc
@@ -6,9 +6,7 @@
 
 #include "frc971/zeroing/zeroing_test.h"
 
-namespace frc971 {
-namespace zeroing {
-namespace testing {
+namespace frc971::zeroing::testing {
 
 using constants::AbsoluteAndAbsoluteEncoderZeroingConstants;
 
@@ -343,6 +341,4 @@
               ::testing::ElementsAre(ZeroingError::OFFSET_MOVED_TOO_FAR));
 }
 
-}  // namespace testing
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing::testing
diff --git a/frc971/zeroing/absolute_encoder.cc b/frc971/zeroing/absolute_encoder.cc
index aa68acf..f5e3e3d 100644
--- a/frc971/zeroing/absolute_encoder.cc
+++ b/frc971/zeroing/absolute_encoder.cc
@@ -8,8 +8,7 @@
 #include "aos/containers/error_list.h"
 #include "frc971/zeroing/wrap.h"
 
-namespace frc971 {
-namespace zeroing {
+namespace frc971::zeroing {
 
 AbsoluteEncoderZeroingEstimator::AbsoluteEncoderZeroingEstimator(
     const constants::AbsoluteEncoderZeroingConstants &constants)
@@ -181,5 +180,4 @@
   return builder.Finish();
 }
 
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing
diff --git a/frc971/zeroing/absolute_encoder_test.cc b/frc971/zeroing/absolute_encoder_test.cc
index 6e78faa..aa2fb9f 100644
--- a/frc971/zeroing/absolute_encoder_test.cc
+++ b/frc971/zeroing/absolute_encoder_test.cc
@@ -5,9 +5,7 @@
 
 #include "frc971/zeroing/zeroing_test.h"
 
-namespace frc971 {
-namespace zeroing {
-namespace testing {
+namespace frc971::zeroing::testing {
 
 using constants::AbsoluteEncoderZeroingConstants;
 
@@ -169,6 +167,4 @@
               ::testing::ElementsAre(ZeroingError::LOST_ABSOLUTE_ENCODER));
 }
 
-}  // namespace testing
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing::testing
diff --git a/frc971/zeroing/averager_test.cc b/frc971/zeroing/averager_test.cc
index 50eac72..d4f154a 100644
--- a/frc971/zeroing/averager_test.cc
+++ b/frc971/zeroing/averager_test.cc
@@ -2,8 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace zeroing {
+namespace frc971::zeroing {
 
 class AveragerTest : public ::testing::Test {
  protected:
@@ -57,5 +56,4 @@
   ASSERT_EQ(0.0, averager.GetAverage()(0, 0));
 }
 
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing
diff --git a/frc971/zeroing/continuous_absolute_encoder.cc b/frc971/zeroing/continuous_absolute_encoder.cc
index a47a491..ebaf101 100644
--- a/frc971/zeroing/continuous_absolute_encoder.cc
+++ b/frc971/zeroing/continuous_absolute_encoder.cc
@@ -8,8 +8,7 @@
 #include "aos/containers/error_list.h"
 #include "frc971/zeroing/wrap.h"
 
-namespace frc971 {
-namespace zeroing {
+namespace frc971::zeroing {
 
 ContinuousAbsoluteEncoderZeroingEstimator::
     ContinuousAbsoluteEncoderZeroingEstimator(
@@ -165,5 +164,4 @@
   return builder.Finish();
 }
 
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing
diff --git a/frc971/zeroing/continuous_absolute_encoder_test.cc b/frc971/zeroing/continuous_absolute_encoder_test.cc
index 75d6de0..f0b1415 100644
--- a/frc971/zeroing/continuous_absolute_encoder_test.cc
+++ b/frc971/zeroing/continuous_absolute_encoder_test.cc
@@ -6,9 +6,7 @@
 #include "frc971/zeroing/wrap.h"
 #include "frc971/zeroing/zeroing_test.h"
 
-namespace frc971 {
-namespace zeroing {
-namespace testing {
+namespace frc971::zeroing::testing {
 
 using constants::ContinuousAbsoluteEncoderZeroingConstants;
 
@@ -193,6 +191,4 @@
               ::testing::ElementsAre(ZeroingError::LOST_ABSOLUTE_ENCODER));
 }
 
-}  // namespace testing
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing::testing
diff --git a/frc971/zeroing/hall_effect_and_position.cc b/frc971/zeroing/hall_effect_and_position.cc
index e074668..99454e4 100644
--- a/frc971/zeroing/hall_effect_and_position.cc
+++ b/frc971/zeroing/hall_effect_and_position.cc
@@ -6,8 +6,7 @@
 
 #include "glog/logging.h"
 
-namespace frc971 {
-namespace zeroing {
+namespace frc971::zeroing {
 
 HallEffectAndPositionZeroingEstimator::HallEffectAndPositionZeroingEstimator(
     const ZeroingConstants &constants)
@@ -123,5 +122,4 @@
   return builder.Finish();
 }
 
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing
diff --git a/frc971/zeroing/hall_effect_and_position_test.cc b/frc971/zeroing/hall_effect_and_position_test.cc
index c9ddf65..d49d900 100644
--- a/frc971/zeroing/hall_effect_and_position_test.cc
+++ b/frc971/zeroing/hall_effect_and_position_test.cc
@@ -4,9 +4,7 @@
 
 #include "frc971/zeroing/zeroing_test.h"
 
-namespace frc971 {
-namespace zeroing {
-namespace testing {
+namespace frc971::zeroing::testing {
 
 class HallEffectAndPositionZeroingTest : public ZeroingTest {
  protected:
@@ -130,6 +128,4 @@
   EXPECT_FALSE(estimator.zeroed());
 }
 
-}  // namespace testing
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing::testing
diff --git a/frc971/zeroing/pot_and_absolute_encoder.cc b/frc971/zeroing/pot_and_absolute_encoder.cc
index f62b393..bef6f2d 100644
--- a/frc971/zeroing/pot_and_absolute_encoder.cc
+++ b/frc971/zeroing/pot_and_absolute_encoder.cc
@@ -8,8 +8,7 @@
 #include "aos/containers/error_list.h"
 #include "frc971/zeroing/wrap.h"
 
-namespace frc971 {
-namespace zeroing {
+namespace frc971::zeroing {
 
 PotAndAbsoluteEncoderZeroingEstimator::PotAndAbsoluteEncoderZeroingEstimator(
     const constants::PotAndAbsoluteEncoderZeroingConstants &constants)
@@ -200,5 +199,4 @@
   return builder.Finish();
 }
 
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing
diff --git a/frc971/zeroing/pot_and_absolute_encoder_test.cc b/frc971/zeroing/pot_and_absolute_encoder_test.cc
index 4cd3821..00e69bf 100644
--- a/frc971/zeroing/pot_and_absolute_encoder_test.cc
+++ b/frc971/zeroing/pot_and_absolute_encoder_test.cc
@@ -5,9 +5,7 @@
 
 #include "frc971/zeroing/zeroing_test.h"
 
-namespace frc971 {
-namespace zeroing {
-namespace testing {
+namespace frc971::zeroing::testing {
 
 using constants::PotAndAbsoluteEncoderZeroingConstants;
 
@@ -149,6 +147,4 @@
               ::testing::ElementsAre(ZeroingError::LOST_ABSOLUTE_ENCODER));
 }
 
-}  // namespace testing
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing::testing
diff --git a/frc971/zeroing/pot_and_index.cc b/frc971/zeroing/pot_and_index.cc
index 0f1e9e0..fb82f22 100644
--- a/frc971/zeroing/pot_and_index.cc
+++ b/frc971/zeroing/pot_and_index.cc
@@ -4,8 +4,7 @@
 
 #include "glog/logging.h"
 
-namespace frc971 {
-namespace zeroing {
+namespace frc971::zeroing {
 
 PotAndIndexPulseZeroingEstimator::PotAndIndexPulseZeroingEstimator(
     const constants::PotAndIndexPulseZeroingConstants &constants)
@@ -131,5 +130,4 @@
   return builder.Finish();
 }
 
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing
diff --git a/frc971/zeroing/pot_and_index_test.cc b/frc971/zeroing/pot_and_index_test.cc
index f2e464f..ef90661 100644
--- a/frc971/zeroing/pot_and_index_test.cc
+++ b/frc971/zeroing/pot_and_index_test.cc
@@ -4,9 +4,7 @@
 
 #include "frc971/zeroing/zeroing_test.h"
 
-namespace frc971 {
-namespace zeroing {
-namespace testing {
+namespace frc971::zeroing::testing {
 
 using constants::PotAndIndexPulseZeroingConstants;
 
@@ -278,6 +276,4 @@
   ASSERT_TRUE(estimator.error());
 }
 
-}  // namespace testing
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing::testing
diff --git a/frc971/zeroing/pulse_index.cc b/frc971/zeroing/pulse_index.cc
index c0831e8..6e9a502 100644
--- a/frc971/zeroing/pulse_index.cc
+++ b/frc971/zeroing/pulse_index.cc
@@ -5,8 +5,7 @@
 
 #include "glog/logging.h"
 
-namespace frc971 {
-namespace zeroing {
+namespace frc971::zeroing {
 
 void PulseIndexZeroingEstimator::Reset() {
   max_index_position_ = ::std::numeric_limits<double>::lowest();
@@ -112,5 +111,4 @@
   return builder.Finish();
 }
 
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing
diff --git a/frc971/zeroing/pulse_index_test.cc b/frc971/zeroing/pulse_index_test.cc
index bd257f7..c07644d 100644
--- a/frc971/zeroing/pulse_index_test.cc
+++ b/frc971/zeroing/pulse_index_test.cc
@@ -4,9 +4,7 @@
 
 #include "frc971/zeroing/zeroing_test.h"
 
-namespace frc971 {
-namespace zeroing {
-namespace testing {
+namespace frc971::zeroing::testing {
 
 using constants::EncoderPlusIndexZeroingConstants;
 
@@ -127,6 +125,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing::testing
diff --git a/frc971/zeroing/relative_encoder_test.cc b/frc971/zeroing/relative_encoder_test.cc
index 6256fe7..28fe978 100644
--- a/frc971/zeroing/relative_encoder_test.cc
+++ b/frc971/zeroing/relative_encoder_test.cc
@@ -3,9 +3,7 @@
 #include "frc971/zeroing/zeroing.h"
 #include "frc971/zeroing/zeroing_test.h"
 
-namespace frc971 {
-namespace zeroing {
-namespace testing {
+namespace frc971::zeroing::testing {
 
 class RelativeEncoderZeroingTest : public ZeroingTest {
  protected:
@@ -35,6 +33,4 @@
   EXPECT_DOUBLE_EQ(GetEstimatorPosition(&estimator), 0.1);
 }
 
-}  // namespace testing
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing::testing
diff --git a/frc971/zeroing/unwrap_test.cc b/frc971/zeroing/unwrap_test.cc
index b71c8b6..0a185b1 100644
--- a/frc971/zeroing/unwrap_test.cc
+++ b/frc971/zeroing/unwrap_test.cc
@@ -2,9 +2,7 @@
 
 #include "frc971/zeroing/wrap.h"
 
-namespace frc971 {
-namespace zeroing {
-namespace testing {
+namespace frc971::zeroing::testing {
 
 TEST(SensorTest, UnwrapOnce) {
   // Test the sensor moving over the maximum range value and wrapping once
@@ -63,6 +61,4 @@
   EXPECT_EQ(sensor.Unwrap(0.2), 0.2);   // move = 1.0, wrap -1
 }
 
-}  // namespace testing
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing::testing
diff --git a/frc971/zeroing/wrap.cc b/frc971/zeroing/wrap.cc
index 1a0504f..2e0e3bc 100644
--- a/frc971/zeroing/wrap.cc
+++ b/frc971/zeroing/wrap.cc
@@ -2,8 +2,7 @@
 
 #include <cmath>
 
-namespace frc971 {
-namespace zeroing {
+namespace frc971::zeroing {
 
 UnwrapSensor::UnwrapSensor(double sensor_offset, double sensor_range)
     : sensor_offset_(sensor_offset), sensor_range_(sensor_range) {
@@ -64,5 +63,4 @@
   return remainder(value - nearest, period) + nearest;
 }
 
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing
diff --git a/frc971/zeroing/wrap.h b/frc971/zeroing/wrap.h
index f96b9fb..1d10d58 100644
--- a/frc971/zeroing/wrap.h
+++ b/frc971/zeroing/wrap.h
@@ -1,8 +1,7 @@
 #ifndef FRC971_ZEROING_WRAP_H_
 #define FRC971_ZEROING_WRAP_H_
 
-namespace frc971 {
-namespace zeroing {
+namespace frc971::zeroing {
 
 // UnwrapSensor takes in a sensor value from a sensor that loops in a certain
 // interval. ex(the sensor moves from 0 to 10 and back to 0 while moving the
@@ -50,7 +49,6 @@
   return Wrap(nearest, value, period);
 }
 
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing
 
 #endif  // FRC971_ZEROING_WRAP_H_
diff --git a/frc971/zeroing/wrap_test.cc b/frc971/zeroing/wrap_test.cc
index 6597e03..b5d990b 100644
--- a/frc971/zeroing/wrap_test.cc
+++ b/frc971/zeroing/wrap_test.cc
@@ -4,9 +4,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace zeroing {
-namespace testing {
+namespace frc971::zeroing::testing {
 
 // Tests some various positive and negative values for wrap.
 TEST(WrapTest, TestWrap) {
@@ -52,6 +50,4 @@
   EXPECT_NEAR(1.0f, Wrap(5.0f, -9.0f, 10.0f), 1e-6f);
 }
 
-}  // namespace testing
-}  // namespace zeroing
-}  // namespace frc971
+}  // namespace frc971::zeroing::testing
diff --git a/motors/algorithms.cc b/motors/algorithms.cc
index 6edb532..c429a84 100644
--- a/motors/algorithms.cc
+++ b/motors/algorithms.cc
@@ -1,7 +1,6 @@
 #include "motors/algorithms.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 
 BalancedReadings BalanceReadings(const ReadingsToBalance to_balance) {
   // TODO(Brian): Get rid of the floating point divides.
@@ -46,5 +45,4 @@
   return result;
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/algorithms_test.cc b/motors/algorithms_test.cc
index bdf51d7..cf3ce3d 100644
--- a/motors/algorithms_test.cc
+++ b/motors/algorithms_test.cc
@@ -6,9 +6,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace motors {
-namespace testing {
+namespace frc971::motors::testing {
 
 class BalanceReadingsTest : public ::testing::Test {
  protected:
@@ -97,6 +95,4 @@
   CheckReadingsResult({{3424, 5013, 3424}, {2, 2, 2}});
 }
 
-}  // namespace testing
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors::testing
diff --git a/motors/big/medium_salsa.cc b/motors/big/medium_salsa.cc
index ab0f3d6..b754715 100644
--- a/motors/big/medium_salsa.cc
+++ b/motors/big/medium_salsa.cc
@@ -11,8 +11,7 @@
 #include "motors/usb/usb_serial.h"
 #include "motors/util.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 struct MediumAdcReadings {
@@ -342,5 +341,4 @@
   return 0;
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/big/motor_controls.cc b/motors/big/motor_controls.cc
index db9878d..a0fcd76 100644
--- a/motors/big/motor_controls.cc
+++ b/motors/big/motor_controls.cc
@@ -2,8 +2,7 @@
 
 #include "motors/peripheral/configuration.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 template <int kRows, int kCols>
@@ -240,5 +239,4 @@
   return debug_[theta];
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/button_board.cc b/motors/button_board.cc
index 1d20fdb..e509ea6 100644
--- a/motors/button_board.cc
+++ b/motors/button_board.cc
@@ -16,8 +16,7 @@
 #include "motors/usb/usb.h"
 #include "motors/util.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 struct JoystickAdcReadings {
@@ -405,5 +404,4 @@
   return 0;
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/core/itm.cc b/motors/core/itm.cc
index 3405881..767a0a8 100644
--- a/motors/core/itm.cc
+++ b/motors/core/itm.cc
@@ -2,9 +2,7 @@
 
 #include "motors/core/kinetis.h"
 
-namespace frc971 {
-namespace motors {
-namespace itm {
+namespace frc971::motors::itm {
 namespace {
 
 // 480000 works for a bit but eventually errors out with an stlink-v2 and
@@ -52,6 +50,4 @@
   ITM.LAR = 0;
 }
 
-}  // namespace itm
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors::itm
diff --git a/motors/fet12/fet12.cc b/motors/fet12/fet12.cc
index b6f2a45..61562be 100644
--- a/motors/fet12/fet12.cc
+++ b/motors/fet12/fet12.cc
@@ -12,8 +12,7 @@
 #include "motors/print/print.h"
 #include "motors/util.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 struct Fet12AdcReadings {
@@ -332,5 +331,4 @@
   return 0;
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/fet12/fet12v2.cc b/motors/fet12/fet12v2.cc
index b0a0acc..9591331 100644
--- a/motors/fet12/fet12v2.cc
+++ b/motors/fet12/fet12v2.cc
@@ -14,8 +14,7 @@
 #include "motors/print/print.h"
 #include "motors/util.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 constexpr double Kv = 22000.0 * 2.0 * M_PI / 60.0 / 30.0 * 3.6;
@@ -718,5 +717,4 @@
   return 0;
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/fet12/motor_controls.cc b/motors/fet12/motor_controls.cc
index 0ef7e3c..adc1839 100644
--- a/motors/fet12/motor_controls.cc
+++ b/motors/fet12/motor_controls.cc
@@ -2,8 +2,7 @@
 
 #include "motors/peripheral/configuration.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 template <int kRows, int kCols>
@@ -245,5 +244,4 @@
   return debug_[theta];
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/fet12/power_wheels.cc b/motors/fet12/power_wheels.cc
index 893d92f..20453dc 100644
--- a/motors/fet12/power_wheels.cc
+++ b/motors/fet12/power_wheels.cc
@@ -11,8 +11,7 @@
 #include "motors/usb/usb.h"
 #include "motors/util.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 struct Fet12AdcReadings {
@@ -347,5 +346,4 @@
   return 0;
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/math.cc b/motors/math.cc
index 574ef9a..5eac813 100644
--- a/motors/math.cc
+++ b/motors/math.cc
@@ -2,8 +2,7 @@
 
 #include <math.h>
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace math_internal {
 
 float sin_float_table[SinCosFloatTableSize() + 1]
@@ -35,5 +34,4 @@
   }
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/math_test.cc b/motors/math_test.cc
index fb72454..63e812f 100644
--- a/motors/math_test.cc
+++ b/motors/math_test.cc
@@ -3,9 +3,7 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace motors {
-namespace testing {
+namespace frc971::motors::testing {
 
 class SinCosIntTest : public ::testing::Test {
  public:
@@ -95,6 +93,4 @@
   CheckSinCos(0.2);
 }
 
-}  // namespace testing
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors::testing
diff --git a/motors/motor.cc b/motors/motor.cc
index ed1296c..d2c977c 100644
--- a/motors/motor.cc
+++ b/motors/motor.cc
@@ -12,8 +12,7 @@
 extern "C" float analog_ratio(uint16_t reading);
 extern "C" float absolute_wheel(uint16_t reading);
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 
 Motor::Motor(BigFTM *pwm_ftm, LittleFTM *encoder_ftm, MotorControls *controls,
              const ::std::array<volatile uint32_t *, 3> &output_registers)
@@ -445,5 +444,4 @@
   return (counts_per_cycle() + width) / 2;
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/peripheral/adc.cc b/motors/peripheral/adc.cc
index 64f1557..11a91ff 100644
--- a/motors/peripheral/adc.cc
+++ b/motors/peripheral/adc.cc
@@ -2,8 +2,7 @@
 
 #include "motors/core/kinetis.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 #define ADC_SC2_BASE \
@@ -58,5 +57,4 @@
   ADC_INIT_SINGLE(1, (adc1_channels == AdcChannels::kB) ? ADC_CFG2_MUXSEL : 0);
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/peripheral/adc_dma.cc b/motors/peripheral/adc_dma.cc
index 15d50eb..11cdbb6 100644
--- a/motors/peripheral/adc_dma.cc
+++ b/motors/peripheral/adc_dma.cc
@@ -52,8 +52,7 @@
 //   8. Read ADC0.RB and ADC1.RB
 //   9. Go back to step #3
 
-namespace frc971 {
-namespace teensy {
+namespace frc971::teensy {
 namespace {
 
 constexpr uint32_t pdb_sc(int pdb_input) {
@@ -275,5 +274,4 @@
                 V_PDB_EN(3) /* Enable our two */;
 }
 
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy
diff --git a/motors/peripheral/spi.cc b/motors/peripheral/spi.cc
index 8c4ad11..59ff651 100644
--- a/motors/peripheral/spi.cc
+++ b/motors/peripheral/spi.cc
@@ -4,8 +4,7 @@
 
 #include "motors/core/time.h"
 
-namespace frc971 {
-namespace teensy {
+namespace frc971::teensy {
 
 Spi::~Spi() {
   DisableTransmitInterrupt();
@@ -136,5 +135,4 @@
   return true;
 }
 
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy
diff --git a/motors/peripheral/uart.cc b/motors/peripheral/uart.cc
index 0617e3f..408bbfd 100644
--- a/motors/peripheral/uart.cc
+++ b/motors/peripheral/uart.cc
@@ -2,8 +2,7 @@
 
 #include <stdint.h>
 
-namespace frc971 {
-namespace teensy {
+namespace frc971::teensy {
 
 // Currently hard-coded for 8-bit + no parity + start bit + stop bit.
 void Uart::Initialize(int baud_rate) {
@@ -152,5 +151,4 @@
   }
 }
 
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy
diff --git a/motors/peripheral/uart_buffer_test.cc b/motors/peripheral/uart_buffer_test.cc
index 223c029..0ee5a49 100644
--- a/motors/peripheral/uart_buffer_test.cc
+++ b/motors/peripheral/uart_buffer_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace teensy {
-namespace testing {
+namespace frc971::teensy::testing {
 
 // Tests that using PushSpan with single characters works correctly.
 TEST(UartBufferTest, PushSpanSingle) {
@@ -281,6 +279,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy::testing
diff --git a/motors/pistol_grip/controller.cc b/motors/pistol_grip/controller.cc
index a88b9a0..b7c7ae5 100644
--- a/motors/pistol_grip/controller.cc
+++ b/motors/pistol_grip/controller.cc
@@ -25,8 +25,7 @@
 extern const float kTriggerCoggingTorque0[4096];
 extern const float kTriggerCoggingTorque1[4096];
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 ::std::atomic<const float *> trigger_cogging_torque{nullptr};
@@ -1154,5 +1153,4 @@
   return 0;
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/pistol_grip/controller_adc.cc b/motors/pistol_grip/controller_adc.cc
index 498c4e2..1e89f98 100644
--- a/motors/pistol_grip/controller_adc.cc
+++ b/motors/pistol_grip/controller_adc.cc
@@ -2,8 +2,7 @@
 
 #include "motors/peripheral/adc.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 
 void AdcInitSmall() {
   AdcInitCommon();
@@ -96,5 +95,4 @@
   return r;
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/pistol_grip/drivers_station.cc b/motors/pistol_grip/drivers_station.cc
index a1cd6d9..1cf570b 100644
--- a/motors/pistol_grip/drivers_station.cc
+++ b/motors/pistol_grip/drivers_station.cc
@@ -15,8 +15,7 @@
 #include "motors/usb/usb.h"
 #include "motors/util.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 // TODO(Brian): Move this and the other two test functions somewhere else.
@@ -308,5 +307,4 @@
   return 0;
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/pistol_grip/motor_controls.cc b/motors/pistol_grip/motor_controls.cc
index a9c909f..ec01677 100644
--- a/motors/pistol_grip/motor_controls.cc
+++ b/motors/pistol_grip/motor_controls.cc
@@ -2,8 +2,7 @@
 
 #include "motors/peripheral/configuration.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 template <int kRows, int kCols>
@@ -209,5 +208,4 @@
   return debug_[theta];
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/print/itm.cc b/motors/print/itm.cc
index 7f472c0..be657bc 100644
--- a/motors/print/itm.cc
+++ b/motors/print/itm.cc
@@ -6,8 +6,7 @@
 
 #include "motors/core/itm.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 template <int kPort>
@@ -96,5 +95,4 @@
   return buffer.size();
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/print/semihosting.cc b/motors/print/semihosting.cc
index a266ad6..310bb49 100644
--- a/motors/print/semihosting.cc
+++ b/motors/print/semihosting.cc
@@ -4,8 +4,7 @@
 
 #include "motors/core/semihosting.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 
 ::std::unique_ptr<PrintingImplementation> CreatePrinting(
     const PrintingParameters & /*parameters*/) {
@@ -23,5 +22,4 @@
   return buffer.size() - operation.Execute();
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/print/uart.cc b/motors/print/uart.cc
index 4cfb001..f125789 100644
--- a/motors/print/uart.cc
+++ b/motors/print/uart.cc
@@ -4,8 +4,7 @@
 
 #include "motors/core/kinetis.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 ::std::atomic<teensy::InterruptBufferedUart *> global_stdout{nullptr};
@@ -65,5 +64,4 @@
   return len;
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/print/usb.cc b/motors/print/usb.cc
index 9284ecd..45734b5 100644
--- a/motors/print/usb.cc
+++ b/motors/print/usb.cc
@@ -4,8 +4,7 @@
 
 #include "motors/core/kinetis.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 ::std::atomic<teensy::AcmTty *> global_stdout{nullptr};
@@ -62,5 +61,4 @@
   global_stdout.store(&stdout_tty_, ::std::memory_order_release);
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/seems_reasonable/spring.cc b/motors/seems_reasonable/spring.cc
index 79ac751..80bcd31 100644
--- a/motors/seems_reasonable/spring.cc
+++ b/motors/seems_reasonable/spring.cc
@@ -4,8 +4,7 @@
 
 #include "frc971/zeroing/wrap.h"
 
-namespace motors {
-namespace seems_reasonable {
+namespace motors::seems_reasonable {
 namespace {
 
 constexpr float kTwoPi = 2.0 * M_PI;
@@ -200,5 +199,4 @@
   last_error_ = error;
 }
 
-}  // namespace seems_reasonable
-}  // namespace motors
+}  // namespace motors::seems_reasonable
diff --git a/motors/seems_reasonable/spring_test.cc b/motors/seems_reasonable/spring_test.cc
index bcc2a8a..d78a80b 100644
--- a/motors/seems_reasonable/spring_test.cc
+++ b/motors/seems_reasonable/spring_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace motors {
-namespace seems_reasonable {
-namespace testing {
+namespace motors::seems_reasonable::testing {
 
 // Tests that NextGoal always returns the next goal.
 TEST(GoalTest, TestNextGoal) {
@@ -30,6 +28,4 @@
   EXPECT_NEAR(-2.0 * M_PI + 1.0, PreviousGoal(1.0, 1.0), 1e-6);
 }
 
-}  // namespace testing
-}  // namespace seems_reasonable
-}  // namespace motors
+}  // namespace motors::seems_reasonable::testing
diff --git a/motors/simple_receiver.cc b/motors/simple_receiver.cc
index bb10353..2ae0c9b 100644
--- a/motors/simple_receiver.cc
+++ b/motors/simple_receiver.cc
@@ -19,8 +19,7 @@
 #include "motors/seems_reasonable/spring.h"
 #include "motors/util.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 using ::frc971::constants::ShifterHallEffect;
@@ -799,5 +798,4 @@
   }
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/simpler_receiver.cc b/motors/simpler_receiver.cc
index 808fb83..7fad0b8 100644
--- a/motors/simpler_receiver.cc
+++ b/motors/simpler_receiver.cc
@@ -17,8 +17,7 @@
 #include "motors/seems_reasonable/polydrivetrain_dog_motor_plant.h"
 #include "motors/util.h"
 
-namespace frc971 {
-namespace motors {
+namespace frc971::motors {
 namespace {
 
 using ::frc971::constants::ShifterHallEffect;
@@ -449,5 +448,4 @@
   }
 }
 
-}  // namespace motors
-}  // namespace frc971
+}  // namespace frc971::motors
diff --git a/motors/usb/cdc.cc b/motors/usb/cdc.cc
index e082156..5a668d8 100644
--- a/motors/usb/cdc.cc
+++ b/motors/usb/cdc.cc
@@ -19,8 +19,7 @@
     }                                        \
   } while (false)
 
-namespace frc971 {
-namespace teensy {
+namespace frc971::teensy {
 namespace {
 
 // Aka the Communications Device Class code, the Communications Class code,
@@ -428,5 +427,4 @@
   }
 }
 
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy
diff --git a/motors/usb/constants.h b/motors/usb/constants.h
index 58c9ecc..6970639 100644
--- a/motors/usb/constants.h
+++ b/motors/usb/constants.h
@@ -3,8 +3,7 @@
 
 #include <stdint.h>
 
-namespace frc971 {
-namespace teensy {
+namespace frc971::teensy {
 
 enum class Direction : uint32_t {
   kTx = 1 << 1,
@@ -108,7 +107,6 @@
                              static_cast<uint32_t>(Data01::kData1));
 }
 
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy
 
 #endif  // MOTORS_USB_CONSTANTS_H_
diff --git a/motors/usb/constants_test.cc b/motors/usb/constants_test.cc
index 4d11349..66e0ea5 100644
--- a/motors/usb/constants_test.cc
+++ b/motors/usb/constants_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace teensy {
-namespace testing {
+namespace frc971::teensy::testing {
 
 TEST(EndpointBufferStateTest, Filling) {
   EXPECT_TRUE(BufferStateHasEmpty(EndpointBufferState::kBothEmptyEvenFirst));
@@ -61,6 +59,4 @@
             BufferStateAfterEmpty(EndpointBufferState::kBothFullEvenFirst));
 }
 
-}  // namespace testing
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy::testing
diff --git a/motors/usb/hid.cc b/motors/usb/hid.cc
index f42842b..5efa431 100644
--- a/motors/usb/hid.cc
+++ b/motors/usb/hid.cc
@@ -1,7 +1,6 @@
 #include "motors/usb/hid.h"
 
-namespace frc971 {
-namespace teensy {
+namespace frc971::teensy {
 namespace {
 
 constexpr uint8_t hid_class() { return 0x03; }
@@ -210,5 +209,4 @@
   }
 }
 
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy
diff --git a/motors/usb/interrupt_out.cc b/motors/usb/interrupt_out.cc
index 568e5c5..30f024e 100644
--- a/motors/usb/interrupt_out.cc
+++ b/motors/usb/interrupt_out.cc
@@ -1,7 +1,6 @@
 #include "motors/usb/interrupt_out.h"
 
-namespace frc971 {
-namespace teensy {
+namespace frc971::teensy {
 
 void InterruptOut::Initialize() {
   interface_ = AddInterface();
@@ -86,5 +85,4 @@
   }
 }
 
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy
diff --git a/motors/usb/queue.cc b/motors/usb/queue.cc
index 270ad74..3d2e283 100644
--- a/motors/usb/queue.cc
+++ b/motors/usb/queue.cc
@@ -4,8 +4,7 @@
 
 #include <algorithm>
 
-namespace frc971 {
-namespace teensy {
+namespace frc971::teensy {
 
 size_t Queue::Read(char *out_data, size_t out_size) {
   const size_t read_cursor = read_cursor_.load(::std::memory_order_relaxed);
@@ -30,5 +29,4 @@
   return r;
 }
 
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy
diff --git a/motors/usb/queue_test.cc b/motors/usb/queue_test.cc
index fed54d6..8973a6c 100644
--- a/motors/usb/queue_test.cc
+++ b/motors/usb/queue_test.cc
@@ -2,9 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace teensy {
-namespace testing {
+namespace frc971::teensy::testing {
 
 TEST(QueueTest, Basic) {
   Queue queue(64);
@@ -40,6 +38,4 @@
   ASSERT_TRUE(queue.empty());
 }
 
-}  // namespace testing
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy::testing
diff --git a/motors/usb/usb.cc b/motors/usb/usb.cc
index 2c64b61..e5e581b 100644
--- a/motors/usb/usb.cc
+++ b/motors/usb/usb.cc
@@ -6,8 +6,7 @@
 
 #include "motors/util.h"
 
-namespace frc971 {
-namespace teensy {
+namespace frc971::teensy {
 namespace {
 
 // The mask of interrupts we care about.
@@ -1068,5 +1067,4 @@
   *MutableBdtEntry(endpoint, direction, odd) = bdt_entry;
 }
 
-}  // namespace teensy
-}  // namespace frc971
+}  // namespace frc971::teensy
diff --git a/y2014/actors/autonomous_actor.cc b/y2014/actors/autonomous_actor.cc
index 07c6855..7486f47 100644
--- a/y2014/actors/autonomous_actor.cc
+++ b/y2014/actors/autonomous_actor.cc
@@ -17,8 +17,7 @@
 #include "y2014/queues/auto_mode_generated.h"
 #include "y2014/queues/hot_goal_generated.h"
 
-namespace y2014 {
-namespace actors {
+namespace y2014::actors {
 
 namespace chrono = ::std::chrono;
 namespace this_thread = ::std::this_thread;
@@ -432,5 +431,4 @@
   return true;
 }
 
-}  // namespace actors
-}  // namespace y2014
+}  // namespace y2014::actors
diff --git a/y2014/actors/shoot_actor.cc b/y2014/actors/shoot_actor.cc
index 0719062..691e3de 100644
--- a/y2014/actors/shoot_actor.cc
+++ b/y2014/actors/shoot_actor.cc
@@ -9,8 +9,7 @@
 #include "y2014/control_loops/shooter/shooter_goal_generated.h"
 #include "y2014/control_loops/shooter/shooter_status_generated.h"
 
-namespace y2014 {
-namespace actors {
+namespace y2014::actors {
 
 constexpr double ShootActor::kOffsetRadians;
 constexpr double ShootActor::kClawShootingSeparation;
@@ -199,5 +198,4 @@
   return false;
 }
 
-}  // namespace actors
-}  // namespace y2014
+}  // namespace y2014::actors
diff --git a/y2014/constants.cc b/y2014/constants.cc
index ff22b8a..5ff44d4 100644
--- a/y2014/constants.cc
+++ b/y2014/constants.cc
@@ -21,8 +21,7 @@
 #define M_PI 3.14159265358979323846
 #endif
 
-namespace y2014 {
-namespace constants {
+namespace y2014::constants {
 namespace {
 
 const uint16_t kCompTeamNumber = 971;
@@ -261,5 +260,4 @@
   return *values[team_number];
 }
 
-}  // namespace constants
-}  // namespace y2014
+}  // namespace y2014::constants
diff --git a/y2014/control_loops/claw/claw.cc b/y2014/control_loops/claw/claw.cc
index 2fb93b4..39ee7a4 100644
--- a/y2014/control_loops/claw/claw.cc
+++ b/y2014/control_loops/claw/claw.cc
@@ -40,9 +40,7 @@
 // If a claw runs up against a movable limit, move both claws outwards to get
 // out of the condition.
 
-namespace y2014 {
-namespace control_loops {
-namespace claw {
+namespace y2014::control_loops::claw {
 
 using ::frc971::HallEffectTracker;
 using ::frc971::control_loops::DoCoerceGoal;
@@ -1019,6 +1017,4 @@
   was_enabled_ = enabled;
 }
 
-}  // namespace claw
-}  // namespace control_loops
-}  // namespace y2014
+}  // namespace y2014::control_loops::claw
diff --git a/y2014/control_loops/claw/claw_lib_test.cc b/y2014/control_loops/claw/claw_lib_test.cc
index 8886cda..de9b6bc 100644
--- a/y2014/control_loops/claw/claw_lib_test.cc
+++ b/y2014/control_loops/claw/claw_lib_test.cc
@@ -15,10 +15,7 @@
 #include "y2014/control_loops/claw/claw_position_generated.h"
 #include "y2014/control_loops/claw/claw_status_generated.h"
 
-namespace y2014 {
-namespace control_loops {
-namespace claw {
-namespace testing {
+namespace y2014::control_loops::claw::testing {
 
 using ::aos::monotonic_clock;
 using ::frc971::HallEffectStructT;
@@ -659,7 +656,4 @@
   VerifyNearGoal();
 }
 
-}  // namespace testing
-}  // namespace claw
-}  // namespace control_loops
-}  // namespace y2014
+}  // namespace y2014::control_loops::claw::testing
diff --git a/y2014/control_loops/drivetrain/drivetrain_base.cc b/y2014/control_loops/drivetrain/drivetrain_base.cc
index be4f238..d9f396e 100644
--- a/y2014/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2014/control_loops/drivetrain/drivetrain_base.cc
@@ -13,8 +13,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2014 {
-namespace control_loops {
+namespace y2014::control_loops {
 
 const DrivetrainConfig<double> &GetDrivetrainConfig() {
   // TODO(austin): Switch over to using the profile.
@@ -51,5 +50,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace control_loops
-}  // namespace y2014
+}  // namespace y2014::control_loops
diff --git a/y2014/control_loops/shooter/shooter.cc b/y2014/control_loops/shooter/shooter.cc
index 2a3e0d0..b0ce4ba 100644
--- a/y2014/control_loops/shooter/shooter.cc
+++ b/y2014/control_loops/shooter/shooter.cc
@@ -9,9 +9,7 @@
 #include "y2014/constants.h"
 #include "y2014/control_loops/shooter/shooter_motor_plant.h"
 
-namespace y2014 {
-namespace control_loops {
-namespace shooter {
+namespace y2014::control_loops::shooter {
 
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
@@ -688,6 +686,4 @@
   return output_builder.Finish();
 }
 
-}  // namespace shooter
-}  // namespace control_loops
-}  // namespace y2014
+}  // namespace y2014::control_loops::shooter
diff --git a/y2014/control_loops/shooter/shooter_lib_test.cc b/y2014/control_loops/shooter/shooter_lib_test.cc
index d7fc0ea..6c6c7e7 100644
--- a/y2014/control_loops/shooter/shooter_lib_test.cc
+++ b/y2014/control_loops/shooter/shooter_lib_test.cc
@@ -19,10 +19,7 @@
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
 
-namespace y2014 {
-namespace control_loops {
-namespace shooter {
-namespace testing {
+namespace y2014::control_loops::shooter::testing {
 
 using ::frc971::control_loops::testing::kTeamNumber;
 using ::y2014::control_loops::shooter::kMaxExtension;
@@ -808,7 +805,4 @@
 
 // TODO(austin): Test all the timeouts...
 
-}  // namespace testing
-}  // namespace shooter
-}  // namespace control_loops
-}  // namespace y2014
+}  // namespace y2014::control_loops::shooter::testing
diff --git a/y2014/joystick_reader.cc b/y2014/joystick_reader.cc
index 5349334..232a0ce 100644
--- a/y2014/joystick_reader.cc
+++ b/y2014/joystick_reader.cc
@@ -25,9 +25,7 @@
 
 #define OLD_DS 0
 
-namespace y2014 {
-namespace input {
-namespace joysticks {
+namespace y2014::input::joysticks {
 
 const ButtonLocation kDriveControlLoopEnable1(1, 7),
     kDriveControlLoopEnable2(1, 11);
@@ -441,9 +439,7 @@
                                      "no drivetrain status");
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2014
+}  // namespace y2014::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2014/wpilib_interface.cc b/y2014/wpilib_interface.cc
index b27e381..016b17a 100644
--- a/y2014/wpilib_interface.cc
+++ b/y2014/wpilib_interface.cc
@@ -55,8 +55,7 @@
 namespace shooter = ::y2014::control_loops::shooter;
 using std::make_unique;
 
-namespace y2014 {
-namespace wpilib {
+namespace y2014::wpilib {
 
 // TODO(Brian): Fix the interpretation of the result of GetRaw here and in the
 // DMA stuff and then removing the * 2.0 in *_translate.
@@ -769,7 +768,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2014
+}  // namespace y2014::wpilib
 
 AOS_ROBOT_CLASS(::y2014::wpilib::WPILibRobot);
diff --git a/y2014_bot3/actors/autonomous_actor.cc b/y2014_bot3/actors/autonomous_actor.cc
index 8f281d4..1166524 100644
--- a/y2014_bot3/actors/autonomous_actor.cc
+++ b/y2014_bot3/actors/autonomous_actor.cc
@@ -9,8 +9,7 @@
 #include "aos/util/phased_loop.h"
 #include "y2014_bot3/control_loops/drivetrain/drivetrain_base.h"
 
-namespace y2014_bot3 {
-namespace actors {
+namespace y2014_bot3::actors {
 using ::frc971::ProfileParametersT;
 
 using ::aos::monotonic_clock;
@@ -58,5 +57,4 @@
   return true;
 }
 
-}  // namespace actors
-}  // namespace y2014_bot3
+}  // namespace y2014_bot3::actors
diff --git a/y2014_bot3/control_loops/drivetrain/drivetrain_base.cc b/y2014_bot3/control_loops/drivetrain/drivetrain_base.cc
index 6a6ed31..ea6806f 100644
--- a/y2014_bot3/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2014_bot3/control_loops/drivetrain/drivetrain_base.cc
@@ -13,9 +13,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2014_bot3 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2014_bot3::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -57,6 +55,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2014_bot3
+}  // namespace y2014_bot3::control_loops::drivetrain
diff --git a/y2014_bot3/control_loops/rollers/rollers.cc b/y2014_bot3/control_loops/rollers/rollers.cc
index 8cf7ba6..ea77357 100644
--- a/y2014_bot3/control_loops/rollers/rollers.cc
+++ b/y2014_bot3/control_loops/rollers/rollers.cc
@@ -6,9 +6,7 @@
 #include "y2014_bot3/control_loops/rollers/rollers_position_generated.h"
 #include "y2014_bot3/control_loops/rollers/rollers_status_generated.h"
 
-namespace y2014_bot3 {
-namespace control_loops {
-namespace rollers {
+namespace y2014_bot3::control_loops::rollers {
 
 Rollers::Rollers(::aos::EventLoop *event_loop, const ::std::string &name)
     : frc971::controls::ControlLoop<Goal, Position, Status, Output>(event_loop,
@@ -83,6 +81,4 @@
   output->CheckOk(output->Send(Output::Pack(*output->fbb(), &output_struct)));
 }
 
-}  //  namespace rollers
-}  //  namespace control_loops
-}  //  namespace y2014_bot3
+}  // namespace y2014_bot3::control_loops::rollers
diff --git a/y2014_bot3/joystick_reader.cc b/y2014_bot3/joystick_reader.cc
index 0c48552..98ade64 100644
--- a/y2014_bot3/joystick_reader.cc
+++ b/y2014_bot3/joystick_reader.cc
@@ -22,9 +22,7 @@
 using ::frc971::input::driver_station::JoystickAxis;
 using ::frc971::input::driver_station::POVLocation;
 
-namespace y2014_bot3 {
-namespace input {
-namespace joysticks {
+namespace y2014_bot3::input::joysticks {
 
 // Joystick & button addresses.
 const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
@@ -133,9 +131,7 @@
   ::frc971::autonomous::BaseAutonomousActor::Factory autonomous_action_factory_;
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2014_bot3
+}  // namespace y2014_bot3::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2014_bot3/output/motor_writer.cc b/y2014_bot3/output/motor_writer.cc
index 0b0e17b..87b41dc 100644
--- a/y2014_bot3/output/motor_writer.cc
+++ b/y2014_bot3/output/motor_writer.cc
@@ -15,8 +15,7 @@
 
 using ::aos::util::SimpleLogInterval;
 
-namespace bot3 {
-namespace output {
+namespace bot3::output {
 
 class MotorWriter : public ::aos::MotorOutput {
   // Maximum age of an output packet before the motors get zeroed instead.
@@ -111,8 +110,7 @@
 
 constexpr chrono::milliseconds MotorWriter::kOldLogInterval;
 
-}  // namespace output
-}  // namespace bot3
+}  // namespace bot3::output
 
 int main() {
   ::aos::Init();
diff --git a/y2014_bot3/shifter_hall_effect.h b/y2014_bot3/shifter_hall_effect.h
index a4bdeb8..0a65360 100644
--- a/y2014_bot3/shifter_hall_effect.h
+++ b/y2014_bot3/shifter_hall_effect.h
@@ -1,8 +1,7 @@
 #ifndef BOT3_SHIFTER_HALL_EFFECT_H_
 #define BOT3_SHIFTER_HALL_EFFECT_H_
 
-namespace bot3 {
-namespace constants {
+namespace bot3::constants {
 
 // Contains the voltages for an analog hall effect sensor on a shifter.
 struct ShifterHallEffect {
@@ -13,7 +12,6 @@
   double clear_high, clear_low;
 };
 
-}  // namespace constants
-}  // namespace bot3
+}  // namespace bot3::constants
 
 #endif
diff --git a/y2014_bot3/wpilib_interface.cc b/y2014_bot3/wpilib_interface.cc
index 22d372e..5640e50 100644
--- a/y2014_bot3/wpilib_interface.cc
+++ b/y2014_bot3/wpilib_interface.cc
@@ -57,8 +57,7 @@
 using ::frc971::wpilib::LoopOutputHandler;
 using std::make_unique;
 
-namespace y2014_bot3 {
-namespace wpilib {
+namespace y2014_bot3::wpilib {
 
 double drivetrain_translate(int32_t in) {
   return static_cast<double>(in) / (256.0 /*cpr*/ * 4.0 /*4x*/) *
@@ -357,7 +356,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2014_bot3
+}  // namespace y2014_bot3::wpilib
 
 AOS_ROBOT_CLASS(::y2014_bot3::wpilib::WPILibRobot);
diff --git a/y2016/actors/autonomous_actor.cc b/y2016/actors/autonomous_actor.cc
index ffba99b..d784d51 100644
--- a/y2016/actors/autonomous_actor.cc
+++ b/y2016/actors/autonomous_actor.cc
@@ -14,8 +14,7 @@
 #include "y2016/queues/ball_detector_generated.h"
 #include "y2016/vision/vision_generated.h"
 
-namespace y2016 {
-namespace actors {
+namespace y2016::actors {
 using ::aos::monotonic_clock;
 using ::frc971::ProfileParametersT;
 namespace superstructure = y2016::control_loops::superstructure;
@@ -985,5 +984,4 @@
   return true;
 }
 
-}  // namespace actors
-}  // namespace y2016
+}  // namespace y2016::actors
diff --git a/y2016/actors/superstructure_actor.cc b/y2016/actors/superstructure_actor.cc
index d33b125..734512a 100644
--- a/y2016/actors/superstructure_actor.cc
+++ b/y2016/actors/superstructure_actor.cc
@@ -8,8 +8,7 @@
 #include "y2016/control_loops/superstructure/superstructure_goal_generated.h"
 #include "y2016/control_loops/superstructure/superstructure_status_generated.h"
 
-namespace y2016 {
-namespace actors {
+namespace y2016::actors {
 
 namespace chrono = ::std::chrono;
 
@@ -112,5 +111,4 @@
   WaitUntil(::std::bind(&SuperstructureActor::SuperstructureDone, this));
 }
 
-}  // namespace actors
-}  // namespace y2016
+}  // namespace y2016::actors
diff --git a/y2016/actors/vision_align_actor.cc b/y2016/actors/vision_align_actor.cc
index a31ac5d..f636ddf 100644
--- a/y2016/actors/vision_align_actor.cc
+++ b/y2016/actors/vision_align_actor.cc
@@ -16,8 +16,7 @@
 #include "y2016/control_loops/drivetrain/drivetrain_base.h"
 #include "y2016/vision/vision_generated.h"
 
-namespace y2016 {
-namespace actors {
+namespace y2016::actors {
 
 VisionAlignActor::VisionAlignActor(::aos::EventLoop *event_loop)
     : aos::common::actions::ActorBase<vision_align_action::Goal>(
@@ -88,5 +87,4 @@
   return true;
 }
 
-}  // namespace actors
-}  // namespace y2016
+}  // namespace y2016::actors
diff --git a/y2016/constants.cc b/y2016/constants.cc
index 707fa9c..0c65b11 100644
--- a/y2016/constants.cc
+++ b/y2016/constants.cc
@@ -21,8 +21,7 @@
 #define M_PI 3.14159265358979323846
 #endif
 
-namespace y2016 {
-namespace constants {
+namespace y2016::constants {
 
 // ///// Mutual constants between robots. /////
 const int Values::kZeroingSampleSize;
@@ -210,5 +209,4 @@
   return *values[team_number];
 }
 
-}  // namespace constants
-}  // namespace y2016
+}  // namespace y2016::constants
diff --git a/y2016/control_loops/drivetrain/drivetrain_base.cc b/y2016/control_loops/drivetrain/drivetrain_base.cc
index 1be12ca..208c843 100644
--- a/y2016/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2016/control_loops/drivetrain/drivetrain_base.cc
@@ -14,9 +14,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2016 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2016::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -56,6 +54,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2016
+}  // namespace y2016::control_loops::drivetrain
diff --git a/y2016/control_loops/shooter/shooter.cc b/y2016/control_loops/shooter/shooter.cc
index d317d4f..aeac5a4 100644
--- a/y2016/control_loops/shooter/shooter.cc
+++ b/y2016/control_loops/shooter/shooter.cc
@@ -5,9 +5,7 @@
 #include "aos/logging/logging.h"
 #include "y2016/control_loops/shooter/shooter_plant.h"
 
-namespace y2016 {
-namespace control_loops {
-namespace shooter {
+namespace y2016::control_loops::shooter {
 
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
@@ -194,6 +192,4 @@
   (void)status->Send(status_builder.Finish());
 }
 
-}  // namespace shooter
-}  // namespace control_loops
-}  // namespace y2016
+}  // namespace y2016::control_loops::shooter
diff --git a/y2016/control_loops/shooter/shooter_lib_test.cc b/y2016/control_loops/shooter/shooter_lib_test.cc
index 1a82b9b..a984d26 100644
--- a/y2016/control_loops/shooter/shooter_lib_test.cc
+++ b/y2016/control_loops/shooter/shooter_lib_test.cc
@@ -16,10 +16,7 @@
 
 using ::frc971::control_loops::testing::kTeamNumber;
 
-namespace y2016 {
-namespace control_loops {
-namespace shooter {
-namespace testing {
+namespace y2016::control_loops::shooter::testing {
 
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
@@ -282,7 +279,4 @@
   VerifyNearGoal();
 }
 
-}  // namespace testing
-}  // namespace shooter
-}  // namespace control_loops
-}  // namespace y2016
+}  // namespace y2016::control_loops::shooter::testing
diff --git a/y2016/control_loops/superstructure/superstructure.cc b/y2016/control_loops/superstructure/superstructure.cc
index 88dfd93..7b69534 100644
--- a/y2016/control_loops/superstructure/superstructure.cc
+++ b/y2016/control_loops/superstructure/superstructure.cc
@@ -8,9 +8,7 @@
 #include "y2016/control_loops/superstructure/superstructure_controls.h"
 #include "y2016/queues/ball_detector_generated.h"
 
-namespace y2016 {
-namespace control_loops {
-namespace superstructure {
+namespace y2016::control_loops::superstructure {
 
 namespace {
 // The maximum voltage the intake roller will be allowed to use.
@@ -846,6 +844,4 @@
 constexpr double Superstructure::kShoulderWristClearAngle;
 constexpr double Superstructure::kShoulderTransitionToLanded;
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2016
+}  // namespace y2016::control_loops::superstructure
diff --git a/y2016/control_loops/superstructure/superstructure_controls.cc b/y2016/control_loops/superstructure/superstructure_controls.cc
index ee2020e..32c8b17 100644
--- a/y2016/control_loops/superstructure/superstructure_controls.cc
+++ b/y2016/control_loops/superstructure/superstructure_controls.cc
@@ -5,9 +5,7 @@
 #include "y2016/control_loops/superstructure/integral_arm_plant.h"
 #include "y2016/control_loops/superstructure/integral_intake_plant.h"
 
-namespace y2016 {
-namespace control_loops {
-namespace superstructure {
+namespace y2016::control_loops::superstructure {
 
 using ::frc971::PotAndIndexPosition;
 
@@ -254,6 +252,4 @@
   }
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2016
+}  // namespace y2016::control_loops::superstructure
diff --git a/y2016/control_loops/superstructure/superstructure_lib_test.cc b/y2016/control_loops/superstructure/superstructure_lib_test.cc
index 9609cd0..ed2f210 100644
--- a/y2016/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2016/control_loops/superstructure/superstructure_lib_test.cc
@@ -21,10 +21,7 @@
 
 using ::frc971::control_loops::PositionSensorSimulator;
 
-namespace y2016 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2016::control_loops::superstructure::testing {
 
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
@@ -1496,7 +1493,4 @@
   EXPECT_GE(superstructure_plant_.shoulder_angular_velocity(), 0.55);
 }
 
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2016
+}  // namespace y2016::control_loops::superstructure::testing
diff --git a/y2016/dashboard/dashboard.cc b/y2016/dashboard/dashboard.cc
index 0b12b14..319eaa5 100644
--- a/y2016/dashboard/dashboard.cc
+++ b/y2016/dashboard/dashboard.cc
@@ -25,8 +25,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2016 {
-namespace dashboard {
+namespace y2016::dashboard {
 namespace big_indicator {
 constexpr int kBlack = 0;
 constexpr int kBallIntaked = 1;
@@ -275,8 +274,7 @@
   data_collector_thread_.join();
 }
 
-}  // namespace dashboard
-}  // namespace y2016
+}  // namespace y2016::dashboard
 
 int main(int argc, char **argv) {
   // Make sure to reference this to force the linker to include it.
diff --git a/y2016/joystick_reader.cc b/y2016/joystick_reader.cc
index 3daecce..2eb2ed1 100644
--- a/y2016/joystick_reader.cc
+++ b/y2016/joystick_reader.cc
@@ -31,9 +31,7 @@
 using ::frc971::input::driver_station::JoystickAxis;
 using ::frc971::input::driver_station::POVLocation;
 
-namespace y2016 {
-namespace input {
-namespace joysticks {
+namespace y2016::input::joysticks {
 
 namespace {
 
@@ -458,9 +456,7 @@
                                      "no drivetrain status");
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2016
+}  // namespace y2016::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2016/vision/blob_filters.cc b/y2016/vision/blob_filters.cc
index 0193ef6..c9cd04d 100644
--- a/y2016/vision/blob_filters.cc
+++ b/y2016/vision/blob_filters.cc
@@ -2,8 +2,7 @@
 
 #include <unistd.h>
 
-namespace aos {
-namespace vision {
+namespace aos::vision {
 
 double CornerFinder::LineScore(Vector<2> A, Vector<2> B, FittedLine line) {
   Vector<2> st(line.st.x, line.st.y);
@@ -390,5 +389,4 @@
   }
 }
 
-}  // namespace vision
-}  // namespace aos
+}  // namespace aos::vision
diff --git a/y2016/vision/stereo_geometry.cc b/y2016/vision/stereo_geometry.cc
index a58675c..673834c 100644
--- a/y2016/vision/stereo_geometry.cc
+++ b/y2016/vision/stereo_geometry.cc
@@ -1,7 +1,6 @@
 #include "y2016/vision/stereo_geometry.h"
 
-namespace y2016 {
-namespace vision {
+namespace y2016::vision {
 
 Calibration FindCalibrationForRobotOrDie(
     const ::std::string &robot_name, const CalibrationFile &calibration_file) {
@@ -14,5 +13,4 @@
           calibration_file.ShortDebugString().c_str());
 }
 
-}  // namespace vision
-}  // namespace y2016
+}  // namespace y2016::vision
diff --git a/y2016/vision/target_receiver.cc b/y2016/vision/target_receiver.cc
index 701f7e8..5aa854e 100644
--- a/y2016/vision/target_receiver.cc
+++ b/y2016/vision/target_receiver.cc
@@ -22,8 +22,7 @@
 #include "y2016/vision/vision_data.pb.h"
 #include "y2016/vision/vision_generated.h"
 
-namespace y2016 {
-namespace vision {
+namespace y2016::vision {
 
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
@@ -428,8 +427,7 @@
   }
 }
 
-}  // namespace vision
-}  // namespace y2016
+}  // namespace y2016::vision
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2016/vision/target_sender.cc b/y2016/vision/target_sender.cc
index a0a0dc7..5a842b7 100644
--- a/y2016/vision/target_sender.cc
+++ b/y2016/vision/target_sender.cc
@@ -18,8 +18,7 @@
 #include "y2016/vision/stereo_geometry.h"
 #include "y2016/vision/vision_data.pb.h"
 
-namespace y2016 {
-namespace vision {
+namespace y2016::vision {
 using aos::events::DataSocket;
 using aos::events::TCPServer;
 using aos::events::TXUdpSocket;
@@ -218,8 +217,7 @@
   loop.Run();
 }
 
-}  // namespace vision
-}  // namespace y2016
+}  // namespace y2016::vision
 
 int main(int, char **) {
   using namespace y2016::vision;
diff --git a/y2016/vision/tools/blob_stream_replay.cc b/y2016/vision/tools/blob_stream_replay.cc
index 847f654..1c15259 100644
--- a/y2016/vision/tools/blob_stream_replay.cc
+++ b/y2016/vision/tools/blob_stream_replay.cc
@@ -18,8 +18,7 @@
 #include "y2016/vision/blob_filters.h"
 // #include "y2016/vision/process_targets.h"
 
-namespace y2016 {
-namespace vision {
+namespace y2016::vision {
 using namespace aos::vision;
 
 ::aos::vision::Vector<2> CreateCenterFromTarget(double lx, double ly, double rx,
@@ -573,8 +572,7 @@
   // count how many frames we miss in a row.
   int missed_count_ = 16;
 };
-}  // namespace vision
-}  // namespace y2016
+}  // namespace y2016::vision
 
 int main(int argc, char *argv[]) {
   using namespace y2016::vision;
diff --git a/y2016/wpilib_interface.cc b/y2016/wpilib_interface.cc
index 0e98085..3466b82 100644
--- a/y2016/wpilib_interface.cc
+++ b/y2016/wpilib_interface.cc
@@ -58,8 +58,7 @@
 namespace shooter = ::y2016::control_loops::shooter;
 namespace superstructure = ::y2016::control_loops::superstructure;
 
-namespace y2016 {
-namespace wpilib {
+namespace y2016::wpilib {
 namespace {
 constexpr double kMaxBringupPower = 12.0;
 }  // namespace
@@ -698,7 +697,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2016
+}  // namespace y2016::wpilib
 
 AOS_ROBOT_CLASS(::y2016::wpilib::WPILibRobot);
diff --git a/y2017/actors/autonomous_actor.cc b/y2017/actors/autonomous_actor.cc
index 19aa329..f67f0d7 100644
--- a/y2017/actors/autonomous_actor.cc
+++ b/y2017/actors/autonomous_actor.cc
@@ -8,8 +8,7 @@
 #include "aos/util/phased_loop.h"
 #include "y2017/control_loops/drivetrain/drivetrain_base.h"
 
-namespace y2017 {
-namespace actors {
+namespace y2017::actors {
 using ::aos::monotonic_clock;
 using ::frc971::ProfileParametersT;
 namespace chrono = ::std::chrono;
@@ -321,5 +320,4 @@
   return true;
 }
 
-}  // namespace actors
-}  // namespace y2017
+}  // namespace y2017::actors
diff --git a/y2017/constants.cc b/y2017/constants.cc
index b27c3b7..d599772 100644
--- a/y2017/constants.cc
+++ b/y2017/constants.cc
@@ -21,8 +21,7 @@
 #define M_PI 3.14159265358979323846
 #endif
 
-namespace y2017 {
-namespace constants {
+namespace y2017::constants {
 
 const int Values::kZeroingSampleSize;
 
@@ -194,5 +193,4 @@
       Blend(coefficient, a1.indexer_velocity, a2.indexer_velocity)};
 }
 
-}  // namespace constants
-}  // namespace y2017
+}  // namespace y2017::constants
diff --git a/y2017/control_loops/drivetrain/drivetrain_base.cc b/y2017/control_loops/drivetrain/drivetrain_base.cc
index ea985d7..1569e34 100644
--- a/y2017/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2017/control_loops/drivetrain/drivetrain_base.cc
@@ -14,9 +14,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2017 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2017::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -56,6 +54,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::drivetrain
diff --git a/y2017/control_loops/superstructure/column/column.cc b/y2017/control_loops/superstructure/column/column.cc
index b8a12f7..6583357 100644
--- a/y2017/control_loops/superstructure/column/column.cc
+++ b/y2017/control_loops/superstructure/column/column.cc
@@ -15,10 +15,7 @@
 #include "y2017/control_loops/superstructure/column/column_integral_plant.h"
 #include "y2017/control_loops/superstructure/column/stuck_column_integral_plant.h"
 
-namespace y2017 {
-namespace control_loops {
-namespace superstructure {
-namespace column {
+namespace y2017::control_loops::superstructure::column {
 
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
@@ -692,7 +689,4 @@
   return std::make_pair(indexer_status_offset, turret_status_offset);
 }
 
-}  // namespace column
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::superstructure::column
diff --git a/y2017/control_loops/superstructure/column/column_zeroing.cc b/y2017/control_loops/superstructure/column/column_zeroing.cc
index 53bec5f..68cdd61 100644
--- a/y2017/control_loops/superstructure/column/column_zeroing.cc
+++ b/y2017/control_loops/superstructure/column/column_zeroing.cc
@@ -2,10 +2,7 @@
 
 #include "frc971/zeroing/wrap.h"
 
-namespace y2017 {
-namespace control_loops {
-namespace superstructure {
-namespace column {
+namespace y2017::control_loops::superstructure::column {
 
 ColumnZeroingEstimator::ColumnZeroingEstimator(
     const ZeroingConstants &column_constants)
@@ -82,7 +79,4 @@
   return state_builder.Finish();
 }
 
-}  // namespace column
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::superstructure::column
diff --git a/y2017/control_loops/superstructure/column/column_zeroing_test.cc b/y2017/control_loops/superstructure/column/column_zeroing_test.cc
index ef32beb..2edcab2 100644
--- a/y2017/control_loops/superstructure/column/column_zeroing_test.cc
+++ b/y2017/control_loops/superstructure/column/column_zeroing_test.cc
@@ -16,10 +16,7 @@
 #include "frc971/zeroing/zeroing.h"
 #include "y2017/constants.h"
 
-namespace y2017 {
-namespace control_loops {
-namespace superstructure {
-namespace column {
+namespace y2017::control_loops::superstructure::column {
 
 using ::frc971::HallEffectAndPosition;
 using ::frc971::control_loops::PositionSensorSimulator;
@@ -136,7 +133,4 @@
   EXPECT_TRUE(column_zeroing_estimator_.zeroed());
 }
 
-}  // namespace column
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::superstructure::column
diff --git a/y2017/control_loops/superstructure/hood/hood.cc b/y2017/control_loops/superstructure/hood/hood.cc
index 4f1a4eb..a8c1aa6 100644
--- a/y2017/control_loops/superstructure/hood/hood.cc
+++ b/y2017/control_loops/superstructure/hood/hood.cc
@@ -3,10 +3,7 @@
 #include "y2017/constants.h"
 #include "y2017/control_loops/superstructure/hood/hood_integral_plant.h"
 
-namespace y2017 {
-namespace control_loops {
-namespace superstructure {
-namespace hood {
+namespace y2017::control_loops::superstructure::hood {
 
 namespace chrono = ::std::chrono;
 
@@ -215,7 +212,4 @@
   return status_builder.Finish();
 }
 
-}  // namespace hood
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::superstructure::hood
diff --git a/y2017/control_loops/superstructure/intake/intake.cc b/y2017/control_loops/superstructure/intake/intake.cc
index ee631d7..dfcaf31 100644
--- a/y2017/control_loops/superstructure/intake/intake.cc
+++ b/y2017/control_loops/superstructure/intake/intake.cc
@@ -3,10 +3,7 @@
 #include "y2017/constants.h"
 #include "y2017/control_loops/superstructure/intake/intake_integral_plant.h"
 
-namespace y2017 {
-namespace control_loops {
-namespace superstructure {
-namespace intake {
+namespace y2017::control_loops::superstructure::intake {
 
 constexpr double Intake::kZeroingVoltage;
 constexpr double Intake::kOperatingVoltage;
@@ -146,7 +143,4 @@
   return status_builder.Finish();
 }
 
-}  // namespace intake
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::superstructure::intake
diff --git a/y2017/control_loops/superstructure/shooter/shooter.cc b/y2017/control_loops/superstructure/shooter/shooter.cc
index 8a2dcb9..135b089 100644
--- a/y2017/control_loops/superstructure/shooter/shooter.cc
+++ b/y2017/control_loops/superstructure/shooter/shooter.cc
@@ -4,10 +4,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace y2017 {
-namespace control_loops {
-namespace superstructure {
-namespace shooter {
+namespace y2017::control_loops::superstructure::shooter {
 
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
@@ -156,7 +153,4 @@
   return status_offset;
 }
 
-}  // namespace shooter
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::superstructure::shooter
diff --git a/y2017/control_loops/superstructure/superstructure.cc b/y2017/control_loops/superstructure/superstructure.cc
index 84da59c..5cf3f9f 100644
--- a/y2017/control_loops/superstructure/superstructure.cc
+++ b/y2017/control_loops/superstructure/superstructure.cc
@@ -9,9 +9,7 @@
 #include "y2017/control_loops/superstructure/shooter/shooter.h"
 #include "y2017/vision/vision_generated.h"
 
-namespace y2017 {
-namespace control_loops {
-namespace superstructure {
+namespace y2017::control_loops::superstructure {
 
 namespace {
 // The maximum voltage the intake roller will be allowed to use.
@@ -266,6 +264,4 @@
   (void)status->Send(status_builder.Finish());
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::superstructure
diff --git a/y2017/control_loops/superstructure/superstructure_lib_test.cc b/y2017/control_loops/superstructure/superstructure_lib_test.cc
index e7fd0ff..60f4612 100644
--- a/y2017/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2017/control_loops/superstructure/superstructure_lib_test.cc
@@ -17,10 +17,7 @@
 
 using ::frc971::control_loops::PositionSensorSimulator;
 
-namespace y2017 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2017::control_loops::superstructure::testing {
 namespace {
 constexpr double kNoiseScalar = 0.01;
 }  // namespace
@@ -1738,7 +1735,4 @@
 // TODO(austin): Indexer zeroing error detection.
 // TODO(austin): Detect detached turret encoder
 
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::superstructure::testing
diff --git a/y2017/control_loops/superstructure/vision_distance_average_test.cc b/y2017/control_loops/superstructure/vision_distance_average_test.cc
index e1a406b..93c1063 100644
--- a/y2017/control_loops/superstructure/vision_distance_average_test.cc
+++ b/y2017/control_loops/superstructure/vision_distance_average_test.cc
@@ -4,9 +4,7 @@
 
 #include "aos/flatbuffers.h"
 
-namespace y2017 {
-namespace control_loops {
-namespace superstructure {
+namespace y2017::control_loops::superstructure {
 
 class VisionDistanceAverageTest : public ::testing::Test {
  public:
@@ -73,6 +71,4 @@
   EXPECT_FALSE(average()->Valid());
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::superstructure
diff --git a/y2017/control_loops/superstructure/vision_time_adjuster.cc b/y2017/control_loops/superstructure/vision_time_adjuster.cc
index 6684546..2fb646c 100644
--- a/y2017/control_loops/superstructure/vision_time_adjuster.cc
+++ b/y2017/control_loops/superstructure/vision_time_adjuster.cc
@@ -5,9 +5,7 @@
 #include "frc971/control_loops/drivetrain/drivetrain_status_generated.h"
 #include "y2017/control_loops/drivetrain/drivetrain_dog_motor_plant.h"
 
-namespace y2017 {
-namespace control_loops {
-namespace superstructure {
+namespace y2017::control_loops::superstructure {
 
 using ::aos::monotonic_clock;
 namespace chrono = ::std::chrono;
@@ -162,6 +160,4 @@
   }
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::superstructure
diff --git a/y2017/control_loops/superstructure/vision_time_adjuster_test.cc b/y2017/control_loops/superstructure/vision_time_adjuster_test.cc
index 125a960..4811c97 100644
--- a/y2017/control_loops/superstructure/vision_time_adjuster_test.cc
+++ b/y2017/control_loops/superstructure/vision_time_adjuster_test.cc
@@ -10,9 +10,7 @@
 #include "y2017/control_loops/drivetrain/drivetrain_dog_motor_plant.h"
 #include "y2017/vision/vision_generated.h"
 
-namespace y2017 {
-namespace control_loops {
-namespace superstructure {
+namespace y2017::control_loops::superstructure {
 
 class VisionTimeAdjusterTest : public ::testing::Test {
  public:
@@ -223,6 +221,4 @@
   }
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2017
+}  // namespace y2017::control_loops::superstructure
diff --git a/y2017/joystick_reader.cc b/y2017/joystick_reader.cc
index 7cd2aaf..78f81c7 100644
--- a/y2017/joystick_reader.cc
+++ b/y2017/joystick_reader.cc
@@ -24,9 +24,7 @@
 using ::frc971::input::driver_station::JoystickAxis;
 using ::frc971::input::driver_station::POVLocation;
 
-namespace y2017 {
-namespace input {
-namespace joysticks {
+namespace y2017::input::joysticks {
 
 namespace superstructure = control_loops::superstructure;
 
@@ -317,9 +315,7 @@
   bool fire_ = false;
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2017
+}  // namespace y2017::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2017/vision/debug_viewer.cc b/y2017/vision/debug_viewer.cc
index 79b9800..073f8e5 100644
--- a/y2017/vision/debug_viewer.cc
+++ b/y2017/vision/debug_viewer.cc
@@ -14,8 +14,7 @@
 using aos::vision::ImageRange;
 using aos::vision::RangeImage;
 
-namespace y2017 {
-namespace vision {
+namespace y2017::vision {
 
 BlobList RenderTargetListShifted(const std::vector<TargetComponent> &list) {
   BlobList out;
@@ -120,8 +119,7 @@
   std::vector<aos::vision::OverlayBase *> overlays_;
 };
 
-}  // namespace vision
-}  // namespace y2017
+}  // namespace y2017::vision
 
 int main(int argc, char **argv) {
   y2017::vision::FilterHarnessExample filter_harness;
diff --git a/y2017/vision/target_finder.cc b/y2017/vision/target_finder.cc
index e917b2e..640c7fe 100644
--- a/y2017/vision/target_finder.cc
+++ b/y2017/vision/target_finder.cc
@@ -2,8 +2,7 @@
 
 #include <cmath>
 
-namespace y2017 {
-namespace vision {
+namespace y2017::vision {
 
 // Blobs now come in three types:
 //  0) normal blob.
@@ -276,5 +275,4 @@
   *angle = -std::atan2(px, pz);
 }
 
-}  // namespace vision
-}  // namespace y2017
+}  // namespace y2017::vision
diff --git a/y2017/vision/target_receiver.cc b/y2017/vision/target_receiver.cc
index f21fe4e..fd9f7d8 100644
--- a/y2017/vision/target_receiver.cc
+++ b/y2017/vision/target_receiver.cc
@@ -9,8 +9,7 @@
 #include "y2017/vision/vision_generated.h"
 #include "y2017/vision/vision_result.pb.h"
 
-namespace y2017 {
-namespace vision {
+namespace y2017::vision {
 
 using aos::monotonic_clock;
 
@@ -70,8 +69,7 @@
   }
 }
 
-}  // namespace vision
-}  // namespace y2017
+}  // namespace y2017::vision
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2017/vision/target_sender.cc b/y2017/vision/target_sender.cc
index a198cd2..1e6e049 100644
--- a/y2017/vision/target_sender.cc
+++ b/y2017/vision/target_sender.cc
@@ -27,8 +27,7 @@
 #include "y2017/vision/vision_config.pb.h"
 #include "y2017/vision/vision_result.pb.h"
 
-namespace y2017 {
-namespace vision {
+namespace y2017::vision {
 
 using aos::events::DataSocket;
 using aos::events::TCPServer;
@@ -215,8 +214,7 @@
   return true;
 }
 
-}  // namespace vision
-}  // namespace y2017
+}  // namespace y2017::vision
 
 int main(int, char **) {
   using namespace y2017::vision;
diff --git a/y2017/wpilib_interface.cc b/y2017/wpilib_interface.cc
index 822c3f4..f1205f3 100644
--- a/y2017/wpilib_interface.cc
+++ b/y2017/wpilib_interface.cc
@@ -67,8 +67,7 @@
 using namespace frc;
 using std::make_unique;
 
-namespace y2017 {
-namespace wpilib {
+namespace y2017::wpilib {
 namespace {
 
 constexpr double kMaxBringupPower = 12.0;
@@ -549,7 +548,6 @@
 };
 
 }  // namespace
-}  // namespace wpilib
-}  // namespace y2017
+}  // namespace y2017::wpilib
 
 AOS_ROBOT_CLASS(::y2017::wpilib::WPILibRobot);
diff --git a/y2018/actors/autonomous_actor.cc b/y2018/actors/autonomous_actor.cc
index ea9daab..ae017b5 100644
--- a/y2018/actors/autonomous_actor.cc
+++ b/y2018/actors/autonomous_actor.cc
@@ -8,8 +8,7 @@
 #include "aos/util/phased_loop.h"
 #include "y2018/control_loops/drivetrain/drivetrain_base.h"
 
-namespace y2018 {
-namespace actors {
+namespace y2018::actors {
 using ::frc971::ProfileParametersT;
 
 using ::aos::monotonic_clock;
@@ -599,5 +598,4 @@
   return false;
 }
 
-}  // namespace actors
-}  // namespace y2018
+}  // namespace y2018::actors
diff --git a/y2018/constants.cc b/y2018/constants.cc
index 189ea5b..41c8f3a 100644
--- a/y2018/constants.cc
+++ b/y2018/constants.cc
@@ -20,8 +20,7 @@
 #define M_PI 3.14159265358979323846
 #endif
 
-namespace y2018 {
-namespace constants {
+namespace y2018::constants {
 namespace {
 
 const uint16_t kCompTeamNumber = 971;
@@ -163,5 +162,4 @@
   return *values[team_number];
 }
 
-}  // namespace constants
-}  // namespace y2018
+}  // namespace y2018::constants
diff --git a/y2018/control_loops/drivetrain/drivetrain_base.cc b/y2018/control_loops/drivetrain/drivetrain_base.cc
index 9168b4b..92f460d 100644
--- a/y2018/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2018/control_loops/drivetrain/drivetrain_base.cc
@@ -13,9 +13,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2018 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2018::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -57,6 +55,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2018
+}  // namespace y2018::control_loops::drivetrain
diff --git a/y2018/control_loops/python/arm_bounds.cc b/y2018/control_loops/python/arm_bounds.cc
index 1515192..5338993 100644
--- a/y2018/control_loops/python/arm_bounds.cc
+++ b/y2018/control_loops/python/arm_bounds.cc
@@ -7,8 +7,7 @@
 #include <cmath>
 #include <iostream>
 
-namespace y2018 {
-namespace control_loops {
+namespace y2018::control_loops {
 
 static BoundsCheck MakeArbitraryArmSpace(::std::vector<Point> points) {
   for (Point &point : points) {
@@ -534,5 +533,4 @@
                                 {1.8577014383575772, -1.7353804562372057}});
 }
 
-}  // namespace control_loops
-}  // namespace y2018
+}  // namespace y2018::control_loops
diff --git a/y2018/control_loops/superstructure/arm/arm.cc b/y2018/control_loops/superstructure/arm/arm.cc
index 0749e3f..4e70022 100644
--- a/y2018/control_loops/superstructure/arm/arm.cc
+++ b/y2018/control_loops/superstructure/arm/arm.cc
@@ -10,10 +10,7 @@
 #include "y2018/control_loops/superstructure/arm/arm_constants.h"
 #include "y2018/control_loops/superstructure/arm/generated_graph.h"
 
-namespace y2018 {
-namespace control_loops {
-namespace superstructure {
-namespace arm {
+namespace y2018::control_loops::superstructure::arm {
 
 namespace {
 
@@ -432,7 +429,4 @@
   return status_builder.Finish();
 }
 
-}  // namespace arm
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2018
+}  // namespace y2018::control_loops::superstructure::arm
diff --git a/y2018/control_loops/superstructure/arm/trajectory_plot.cc b/y2018/control_loops/superstructure/arm/trajectory_plot.cc
index 7fdde3f..6739b07 100644
--- a/y2018/control_loops/superstructure/arm/trajectory_plot.cc
+++ b/y2018/control_loops/superstructure/arm/trajectory_plot.cc
@@ -12,10 +12,7 @@
 DEFINE_bool(plot, true, "If true, plot");
 DEFINE_bool(plot_thetas, true, "If true, plot the angles");
 
-namespace y2018 {
-namespace control_loops {
-namespace superstructure {
-namespace arm {
+namespace y2018::control_loops::superstructure::arm {
 
 void Main() {
   frc971::control_loops::arm::Dynamics dynamics(kArmConstants);
@@ -355,10 +352,7 @@
   }
 }
 
-}  // namespace arm
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2018
+}  // namespace y2018::control_loops::superstructure::arm
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2018/control_loops/superstructure/debouncer.cc b/y2018/control_loops/superstructure/debouncer.cc
index 40b730d..98e80f3 100644
--- a/y2018/control_loops/superstructure/debouncer.cc
+++ b/y2018/control_loops/superstructure/debouncer.cc
@@ -1,8 +1,6 @@
 #include "y2018/control_loops/superstructure/debouncer.h"
 
-namespace y2018 {
-namespace control_loops {
-namespace superstructure {
+namespace y2018::control_loops::superstructure {
 
 void Debouncer::Update(bool new_state) {
   // If the incoming state is different from the one we have stored, increment
@@ -20,6 +18,4 @@
   }
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2018
+}  // namespace y2018::control_loops::superstructure
diff --git a/y2018/control_loops/superstructure/debouncer.h b/y2018/control_loops/superstructure/debouncer.h
index ad46b51..381f2f2 100644
--- a/y2018/control_loops/superstructure/debouncer.h
+++ b/y2018/control_loops/superstructure/debouncer.h
@@ -1,12 +1,10 @@
 #ifndef Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_DEBOUNCER_H_
 #define Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_DEBOUNCER_H_
 
-namespace y2018 {
-namespace control_loops {
-namespace superstructure {
+namespace y2018::control_loops::superstructure {
 
-// Ensures that a certain number of states of a certain type are recieved before
-// the actual state is changed.
+// Ensures that a certain number of states of a certain type are recieved
+// before the actual state is changed.
 class Debouncer {
  public:
   // Parameters:
@@ -37,8 +35,6 @@
   int consistent_count_ = 0;
 };
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2018
+}  // namespace y2018::control_loops::superstructure
 
 #endif  // Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_DEBOUNCER_H_
diff --git a/y2018/control_loops/superstructure/debouncer_test.cc b/y2018/control_loops/superstructure/debouncer_test.cc
index 2f56d56..ba3bd87 100644
--- a/y2018/control_loops/superstructure/debouncer_test.cc
+++ b/y2018/control_loops/superstructure/debouncer_test.cc
@@ -2,10 +2,7 @@
 
 #include "gtest/gtest.h"
 
-namespace y2018 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2018::control_loops::superstructure::testing {
 
 // Tests that the debouncer behaves as it should. This tests the following:
 // - The debouncer changes its internal state after the desired number of
@@ -53,7 +50,4 @@
 
   EXPECT_EQ(true, bouncer.current_state());
 }
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2018
+}  // namespace y2018::control_loops::superstructure::testing
diff --git a/y2018/control_loops/superstructure/intake/intake.cc b/y2018/control_loops/superstructure/intake/intake.cc
index edefca4..4c96de0 100644
--- a/y2018/control_loops/superstructure/intake/intake.cc
+++ b/y2018/control_loops/superstructure/intake/intake.cc
@@ -8,10 +8,7 @@
 #include "y2018/control_loops/superstructure/intake/intake_delayed_plant.h"
 #include "y2018/control_loops/superstructure/intake/intake_plant.h"
 
-namespace y2018 {
-namespace control_loops {
-namespace superstructure {
-namespace intake {
+namespace y2018::control_loops::superstructure::intake {
 
 namespace chrono = ::std::chrono;
 using ::aos::monotonic_clock;
@@ -179,7 +176,4 @@
   return status_builder.Finish();
 }
 
-}  // namespace intake
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2018
+}  // namespace y2018::control_loops::superstructure::intake
diff --git a/y2018/control_loops/superstructure/superstructure.cc b/y2018/control_loops/superstructure/superstructure.cc
index fc08280..f0748fa 100644
--- a/y2018/control_loops/superstructure/superstructure.cc
+++ b/y2018/control_loops/superstructure/superstructure.cc
@@ -10,9 +10,7 @@
 #include "y2018/status_light_generated.h"
 #include "y2018/vision/vision_generated.h"
 
-namespace y2018 {
-namespace control_loops {
-namespace superstructure {
+namespace y2018::control_loops::superstructure {
 
 using ::aos::monotonic_clock;
 
@@ -350,6 +348,4 @@
   }
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2018
+}  // namespace y2018::control_loops::superstructure
diff --git a/y2018/control_loops/superstructure/superstructure_lib_test.cc b/y2018/control_loops/superstructure/superstructure_lib_test.cc
index b142420..fdd467b 100644
--- a/y2018/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2018/control_loops/superstructure/superstructure_lib_test.cc
@@ -19,10 +19,7 @@
 
 using ::frc971::control_loops::PositionSensorSimulator;
 
-namespace y2018 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2018::control_loops::superstructure::testing {
 namespace {
 constexpr double kNoiseScalar = 0.01;
 }  // namespace
@@ -786,7 +783,4 @@
 // TODO(austin): Test multiple path segments.
 // TODO(austin): Disable in the middle and test recovery.
 
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2018
+}  // namespace y2018::control_loops::superstructure::testing
diff --git a/y2018/joystick_reader.cc b/y2018/joystick_reader.cc
index 7e25bb3..351d1f5 100644
--- a/y2018/joystick_reader.cc
+++ b/y2018/joystick_reader.cc
@@ -38,9 +38,7 @@
 using ::y2018::control_loops::superstructure::arm::BackPoints;
 using ::y2018::control_loops::superstructure::arm::FrontPoints;
 
-namespace y2018 {
-namespace input {
-namespace joysticks {
+namespace y2018::input::joysticks {
 
 namespace arm = ::y2018::control_loops::superstructure::arm;
 
@@ -386,9 +384,7 @@
   ::std::unique_ptr<ProtoTXUdpSocket<VisionControl>> video_tx_;
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2018
+}  // namespace y2018::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2018/vision/vision_status.cc b/y2018/vision/vision_status.cc
index ef3fd5a..ec5ea55 100644
--- a/y2018/vision/vision_status.cc
+++ b/y2018/vision/vision_status.cc
@@ -8,8 +8,7 @@
 #include "y2018/vision.pb.h"
 #include "y2018/vision/vision_generated.h"
 
-namespace y2018 {
-namespace vision {
+namespace y2018::vision {
 
 using aos::monotonic_clock;
 
@@ -43,8 +42,7 @@
   }
 }
 
-}  // namespace vision
-}  // namespace y2018
+}  // namespace y2018::vision
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2018/wpilib_interface.cc b/y2018/wpilib_interface.cc
index cf71bdd..32ef7a9 100644
--- a/y2018/wpilib_interface.cc
+++ b/y2018/wpilib_interface.cc
@@ -63,8 +63,7 @@
 namespace chrono = ::std::chrono;
 namespace superstructure = ::y2018::control_loops::superstructure;
 
-namespace y2018 {
-namespace wpilib {
+namespace y2018::wpilib {
 namespace {
 
 constexpr double kMaxBringupPower = 12.0;
@@ -779,7 +778,6 @@
 };
 
 }  // namespace
-}  // namespace wpilib
-}  // namespace y2018
+}  // namespace y2018::wpilib
 
 AOS_ROBOT_CLASS(::y2018::wpilib::WPILibRobot);
diff --git a/y2019/actors/auto_splines.cc b/y2019/actors/auto_splines.cc
index 67f9e85..02fc3d0 100644
--- a/y2019/actors/auto_splines.cc
+++ b/y2019/actors/auto_splines.cc
@@ -2,8 +2,7 @@
 
 #include "frc971/control_loops/control_loops_generated.h"
 
-namespace y2019 {
-namespace actors {
+namespace y2019::actors {
 
 void MaybeFlipSpline(
     aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
@@ -806,5 +805,4 @@
   return multispline_builder.Finish();
 }
 
-}  // namespace actors
-}  // namespace y2019
+}  // namespace y2019::actors
diff --git a/y2019/actors/autonomous_actor.cc b/y2019/actors/autonomous_actor.cc
index b8024ec..5200fed 100644
--- a/y2019/actors/autonomous_actor.cc
+++ b/y2019/actors/autonomous_actor.cc
@@ -10,8 +10,7 @@
 #include "y2019/actors/auto_splines.h"
 #include "y2019/control_loops/drivetrain/drivetrain_base.h"
 
-namespace y2019 {
-namespace actors {
+namespace y2019::actors {
 
 using ::aos::monotonic_clock;
 using ::frc971::ProfileParametersT;
@@ -392,5 +391,4 @@
   return true;
 }
 
-}  // namespace actors
-}  // namespace y2019
+}  // namespace y2019::actors
diff --git a/y2019/constants.cc b/y2019/constants.cc
index 0332252..26188de 100644
--- a/y2019/constants.cc
+++ b/y2019/constants.cc
@@ -20,8 +20,7 @@
 #include "y2019/control_loops/superstructure/wrist/integral_wrist_plant.h"
 #include "y2019/vision/constants.h"
 
-namespace y2019 {
-namespace constants {
+namespace y2019::constants {
 
 using ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator;
 
@@ -428,5 +427,4 @@
   }
 }
 
-}  // namespace constants
-}  // namespace y2019
+}  // namespace y2019::constants
diff --git a/y2019/control_loops/drivetrain/drivetrain_base.cc b/y2019/control_loops/drivetrain/drivetrain_base.cc
index 089bdf0..77085a6 100644
--- a/y2019/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2019/control_loops/drivetrain/drivetrain_base.cc
@@ -13,9 +13,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2019 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2019::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -58,6 +56,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops::drivetrain
diff --git a/y2019/control_loops/drivetrain/event_loop_localizer.cc b/y2019/control_loops/drivetrain/event_loop_localizer.cc
index 634cedb..a916914 100644
--- a/y2019/control_loops/drivetrain/event_loop_localizer.cc
+++ b/y2019/control_loops/drivetrain/event_loop_localizer.cc
@@ -2,9 +2,7 @@
 
 #include <functional>
 
-namespace y2019 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2019::control_loops::drivetrain {
 constexpr size_t EventLoopLocalizer::kMaxTargetsPerFrame;
 
 ::std::array<EventLoopLocalizer::Camera, constants::Values::kNumCameras>
@@ -110,6 +108,4 @@
   localizer_.UpdateTargets(cameras_[camera], views, t);
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops::drivetrain
diff --git a/y2019/control_loops/drivetrain/localized_drivetrain_test.cc b/y2019/control_loops/drivetrain/localized_drivetrain_test.cc
index 016e3b7..5aaafd7 100644
--- a/y2019/control_loops/drivetrain/localized_drivetrain_test.cc
+++ b/y2019/control_loops/drivetrain/localized_drivetrain_test.cc
@@ -15,10 +15,7 @@
 // drivetrain, will behave properly. The purpose of this test is to make sure
 // that all the pieces fit together, not to test the algorithms themselves.
 
-namespace y2019 {
-namespace control_loops {
-namespace drivetrain {
-namespace testing {
+namespace y2019::control_loops::drivetrain::testing {
 
 using frc971::control_loops::drivetrain::DrivetrainConfig;
 using frc971::control_loops::drivetrain::Goal;
@@ -399,7 +396,4 @@
   EXPECT_NEAR(HPSlotLeft().abs_pos().y(), drivetrain_plant_.state().y(), 0.2);
 }
 
-}  // namespace testing
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops::drivetrain::testing
diff --git a/y2019/control_loops/drivetrain/localizer_test.cc b/y2019/control_loops/drivetrain/localizer_test.cc
index 28f0235..7f0b13d 100644
--- a/y2019/control_loops/drivetrain/localizer_test.cc
+++ b/y2019/control_loops/drivetrain/localizer_test.cc
@@ -19,9 +19,7 @@
 
 DEFINE_bool(plot, false, "If true, plot");
 
-namespace y2019 {
-namespace control_loops {
-namespace testing {
+namespace y2019::control_loops::testing {
 
 using ::y2019::constants::Field;
 
@@ -694,6 +692,4 @@
             /*goal_tolerance=*/0.7,
         })));
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops::testing
diff --git a/y2019/control_loops/drivetrain/replay_localizer.cc b/y2019/control_loops/drivetrain/replay_localizer.cc
index b7d269b..80cf221 100644
--- a/y2019/control_loops/drivetrain/replay_localizer.cc
+++ b/y2019/control_loops/drivetrain/replay_localizer.cc
@@ -25,9 +25,7 @@
 DEFINE_int32(start_offset, 0,
              "Time, in seconds, to start replay plot after the first enable.");
 
-namespace y2019 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2019::control_loops::drivetrain {
 using ::y2019::constants::Field;
 
 typedef TypedLocalizer<constants::Values::kNumCameras, Field::kNumTargets,
@@ -386,9 +384,7 @@
   ::std::vector<double> long_accel_;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops::drivetrain
 
 int main(int argc, char *argv[]) {
   gflags::ParseCommandLineFlags(&argc, &argv, false);
diff --git a/y2019/control_loops/drivetrain/target_selector.cc b/y2019/control_loops/drivetrain/target_selector.cc
index 87115ae..b078dba 100644
--- a/y2019/control_loops/drivetrain/target_selector.cc
+++ b/y2019/control_loops/drivetrain/target_selector.cc
@@ -2,8 +2,7 @@
 
 #include "aos/json_to_flatbuffer.h"
 
-namespace y2019 {
-namespace control_loops {
+namespace y2019::control_loops {
 
 constexpr double TargetSelector::kFakeFov;
 
@@ -100,5 +99,4 @@
   return true;
 }
 
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops
diff --git a/y2019/control_loops/drivetrain/target_selector_test.cc b/y2019/control_loops/drivetrain/target_selector_test.cc
index d4ef6da..b0767e5 100644
--- a/y2019/control_loops/drivetrain/target_selector_test.cc
+++ b/y2019/control_loops/drivetrain/target_selector_test.cc
@@ -5,9 +5,7 @@
 #include "aos/events/simulated_event_loop.h"
 #include "y2019/control_loops/superstructure/superstructure_goal_generated.h"
 
-namespace y2019 {
-namespace control_loops {
-namespace testing {
+namespace y2019::control_loops::testing {
 
 typedef ::frc971::control_loops::TypedPose<double> Pose;
 typedef ::Eigen::Matrix<double, 5, 1> State;
@@ -190,6 +188,4 @@
                    true, CargoNearLeft(),
                    /*expected_radius=*/0.0}));
 
-}  // namespace testing
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops::testing
diff --git a/y2019/control_loops/superstructure/collision_avoidance.cc b/y2019/control_loops/superstructure/collision_avoidance.cc
index 9c2bf93..c52141b 100644
--- a/y2019/control_loops/superstructure/collision_avoidance.cc
+++ b/y2019/control_loops/superstructure/collision_avoidance.cc
@@ -7,9 +7,7 @@
 #include "y2019/control_loops/superstructure/superstructure_goal_generated.h"
 #include "y2019/control_loops/superstructure/superstructure_status_generated.h"
 
-namespace y2019 {
-namespace control_loops {
-namespace superstructure {
+namespace y2019::control_loops::superstructure {
 
 constexpr double CollisionAvoidance::kElevatorClearHeight;
 constexpr double CollisionAvoidance::kElevatorClearWristDownHeight;
@@ -188,6 +186,4 @@
   }
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops::superstructure
diff --git a/y2019/control_loops/superstructure/collision_avoidance_tests.cc b/y2019/control_loops/superstructure/collision_avoidance_tests.cc
index 68449d6..f22e9ba 100644
--- a/y2019/control_loops/superstructure/collision_avoidance_tests.cc
+++ b/y2019/control_loops/superstructure/collision_avoidance_tests.cc
@@ -6,10 +6,7 @@
 #include "y2019/control_loops/superstructure/superstructure_goal_generated.h"
 #include "y2019/control_loops/superstructure/superstructure_status_generated.h"
 
-namespace y2019 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2019::control_loops::superstructure::testing {
 
 using aos::FlatbufferDetachedBuffer;
 using frc971::control_loops::AbsoluteEncoderProfiledJointStatus;
@@ -484,7 +481,4 @@
 INSTANTIATE_TEST_SUITE_P(CollisionAvoidancePieceTest, CollisionAvoidanceTests,
                          ::testing::Bool());
 
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops::superstructure::testing
diff --git a/y2019/control_loops/superstructure/superstructure.cc b/y2019/control_loops/superstructure/superstructure.cc
index e796f0b..8a38e7a 100644
--- a/y2019/control_loops/superstructure/superstructure.cc
+++ b/y2019/control_loops/superstructure/superstructure.cc
@@ -6,9 +6,7 @@
 #include "frc971/control_loops/static_zeroing_single_dof_profiled_subsystem.h"
 #include "y2019/status_light_generated.h"
 
-namespace y2019 {
-namespace control_loops {
-namespace superstructure {
+namespace y2019::control_loops::superstructure {
 
 using frc971::control_loops::AbsoluteEncoderProfiledJointStatus;
 using frc971::control_loops::PotAndAbsoluteEncoderProfiledJointStatus;
@@ -214,6 +212,4 @@
   }
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops::superstructure
diff --git a/y2019/control_loops/superstructure/superstructure_lib_test.cc b/y2019/control_loops/superstructure/superstructure_lib_test.cc
index a09913b..c2bf988 100644
--- a/y2019/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2019/control_loops/superstructure/superstructure_lib_test.cc
@@ -17,10 +17,7 @@
 #include "y2019/control_loops/superstructure/superstructure.h"
 #include "y2019/control_loops/superstructure/wrist/wrist_plant.h"
 
-namespace y2019 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2019::control_loops::superstructure::testing {
 
 namespace {
 constexpr double kNoiseScalar = 0.01;
@@ -1010,7 +1007,4 @@
   RunFor(chrono::seconds(2));
 }
 
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops::superstructure::testing
diff --git a/y2019/control_loops/superstructure/vacuum.cc b/y2019/control_loops/superstructure/vacuum.cc
index fda123e..a9fbd8c 100644
--- a/y2019/control_loops/superstructure/vacuum.cc
+++ b/y2019/control_loops/superstructure/vacuum.cc
@@ -7,9 +7,7 @@
 #include "y2019/control_loops/superstructure/superstructure_goal_generated.h"
 #include "y2019/control_loops/superstructure/superstructure_output_generated.h"
 
-namespace y2019 {
-namespace control_loops {
-namespace superstructure {
+namespace y2019::control_loops::superstructure {
 
 namespace chrono = ::std::chrono;
 
@@ -86,6 +84,4 @@
       monotonic_now < last_disable_has_piece_time_ + chrono::milliseconds(250);
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2019
+}  // namespace y2019::control_loops::superstructure
diff --git a/y2019/jevois/camera/image_stream.cc b/y2019/jevois/camera/image_stream.cc
index 44fd8e5..3268a67 100644
--- a/y2019/jevois/camera/image_stream.cc
+++ b/y2019/jevois/camera/image_stream.cc
@@ -2,8 +2,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace y2019 {
-namespace camera {
+namespace y2019::camera {
 
 void ImageStreamEvent::ProcessHelper(
     aos::vision::DataRef data, aos::monotonic_clock::time_point timestamp) {
@@ -14,5 +13,4 @@
   ProcessImage(data, timestamp);
 }
 
-}  // namespace camera
-}  // namespace y2019
+}  // namespace y2019::camera
diff --git a/y2019/jevois/camera/reader.cc b/y2019/jevois/camera/reader.cc
index 84bf7fe..09e07db 100644
--- a/y2019/jevois/camera/reader.cc
+++ b/y2019/jevois/camera/reader.cc
@@ -19,8 +19,7 @@
 
 #define CLEAR(x) memset(&(x), 0, sizeof(x))
 
-namespace y2019 {
-namespace camera {
+namespace y2019::camera {
 
 using ::camera::xioctl;
 
@@ -296,5 +295,4 @@
   }
 }
 
-}  // namespace camera
-}  // namespace y2019
+}  // namespace y2019::camera
diff --git a/y2019/jevois/cobs_test.cc b/y2019/jevois/cobs_test.cc
index 303c4d3..61604ad 100644
--- a/y2019/jevois/cobs_test.cc
+++ b/y2019/jevois/cobs_test.cc
@@ -5,8 +5,7 @@
 
 #include "aos/testing/test_logging.h"
 
-namespace frc971 {
-namespace jevois {
+namespace frc971::jevois {
 
 // Tests the size conversions for some known, simple values.
 TEST(CobsMaxEncodedSizeTest, Simple) {
@@ -289,5 +288,4 @@
             packetizer.received_packet());
 }
 
-}  // namespace jevois
-}  // namespace frc971
+}  // namespace frc971::jevois
diff --git a/y2019/jevois/serial.cc b/y2019/jevois/serial.cc
index cd0bb99..3bcc87e 100644
--- a/y2019/jevois/serial.cc
+++ b/y2019/jevois/serial.cc
@@ -8,8 +8,7 @@
 
 #include "aos/logging/logging.h"
 
-namespace y2019 {
-namespace jevois {
+namespace y2019::jevois {
 
 int open_via_terminos(const char *tty_name) {
   int itsDev = ::open(tty_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
@@ -75,5 +74,4 @@
   return itsDev;
 }
 
-}  // namespace jevois
-}  // namespace y2019
+}  // namespace y2019::jevois
diff --git a/y2019/jevois/serial.h b/y2019/jevois/serial.h
index 14e2f98..04114cc 100644
--- a/y2019/jevois/serial.h
+++ b/y2019/jevois/serial.h
@@ -1,12 +1,10 @@
 #ifndef Y2019_JEVOIS_SERIAL_H_
 #define Y2019_JEVOIS_SERIAL_H_
 
-namespace y2019 {
-namespace jevois {
+namespace y2019::jevois {
 
 int open_via_terminos(const char *tty_name);
 
-}  // namespace jevois
-}  // namespace y2019
+}  // namespace y2019::jevois
 
 #endif  // Y2019_JEVOIS_SERIAL_H_
diff --git a/y2019/jevois/spi.cc b/y2019/jevois/spi.cc
index b3b6550..85ad988 100644
--- a/y2019/jevois/spi.cc
+++ b/y2019/jevois/spi.cc
@@ -39,8 +39,7 @@
 //   Note that empty frames are still sent to indicate that the camera is
 //   still working even though it doesn't see any targets.
 
-namespace frc971 {
-namespace jevois {
+namespace frc971::jevois {
 namespace {
 
 constexpr float heading_min() { return -3; }
@@ -312,5 +311,4 @@
   return message;
 }
 
-}  // namespace jevois
-}  // namespace frc971
+}  // namespace frc971::jevois
diff --git a/y2019/jevois/spi_test.cc b/y2019/jevois/spi_test.cc
index c600869..3c69993 100644
--- a/y2019/jevois/spi_test.cc
+++ b/y2019/jevois/spi_test.cc
@@ -4,9 +4,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace jevois {
-namespace testing {
+namespace frc971::jevois::testing {
 
 // Tests packing and then unpacking an empty message.
 TEST(SpiToRoborioPackTest, Empty) {
@@ -228,6 +226,4 @@
   EXPECT_EQ(input_message, output_message.value());
 }
 
-}  // namespace testing
-}  // namespace jevois
-}  // namespace frc971
+}  // namespace frc971::jevois::testing
diff --git a/y2019/jevois/teensy.cc b/y2019/jevois/teensy.cc
index 7c71ae8..9d755a3 100644
--- a/y2019/jevois/teensy.cc
+++ b/y2019/jevois/teensy.cc
@@ -22,8 +22,7 @@
 
 // All indices here refer to the ports as numbered on the PCB.
 
-namespace frc971 {
-namespace jevois {
+namespace frc971::jevois {
 namespace {
 
 // Holds all of our hardware UARTs. There is exactly one global instance for
@@ -1022,5 +1021,4 @@
 }  // extern "C"
 
 }  // namespace
-}  // namespace jevois
-}  // namespace frc971
+}  // namespace frc971::jevois
diff --git a/y2019/jevois/uart.cc b/y2019/jevois/uart.cc
index 0fc25c9..93e0072 100644
--- a/y2019/jevois/uart.cc
+++ b/y2019/jevois/uart.cc
@@ -13,8 +13,7 @@
 #define AOS_CHECK_GE(...)
 #endif
 
-namespace frc971 {
-namespace jevois {
+namespace frc971::jevois {
 
 UartToTeensyBuffer UartPackToTeensy(const CameraFrame &message) {
   std::array<char, uart_to_teensy_size()> buffer;
@@ -197,5 +196,4 @@
   return message;
 }
 
-}  // namespace jevois
-}  // namespace frc971
+}  // namespace frc971::jevois
diff --git a/y2019/jevois/uart_test.cc b/y2019/jevois/uart_test.cc
index 5a3a330..621412d 100644
--- a/y2019/jevois/uart_test.cc
+++ b/y2019/jevois/uart_test.cc
@@ -4,9 +4,7 @@
 
 #include "gtest/gtest.h"
 
-namespace frc971 {
-namespace jevois {
-namespace testing {
+namespace frc971::jevois::testing {
 
 // Tests packing and then unpacking a message with arbitrary values.
 TEST(UartToTeensyTest, Basic) {
@@ -123,6 +121,4 @@
   }
 }
 
-}  // namespace testing
-}  // namespace jevois
-}  // namespace frc971
+}  // namespace frc971::jevois::testing
diff --git a/y2019/joystick_angle.cc b/y2019/joystick_angle.cc
index 986a3fa..9baf9ed 100644
--- a/y2019/joystick_angle.cc
+++ b/y2019/joystick_angle.cc
@@ -4,9 +4,7 @@
 
 #include "frc971/zeroing/wrap.h"
 
-namespace y2019 {
-namespace input {
-namespace joysticks {
+namespace y2019::input::joysticks {
 
 using ::frc971::zeroing::Wrap;
 
@@ -47,6 +45,4 @@
 
   return JoystickAngle::kDefault;
 }
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2019
+}  // namespace y2019::input::joysticks
diff --git a/y2019/joystick_reader.cc b/y2019/joystick_reader.cc
index 12f590f..b44d084 100644
--- a/y2019/joystick_reader.cc
+++ b/y2019/joystick_reader.cc
@@ -41,9 +41,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2019 {
-namespace input {
-namespace joysticks {
+namespace y2019::input::joysticks {
 
 namespace superstructure = y2019::control_loops::superstructure;
 
@@ -669,9 +667,7 @@
       ::aos::monotonic_clock::time_point::min();
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2019
+}  // namespace y2019::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2019/vision/constants.cc b/y2019/vision/constants.cc
index 3fa99a7..504af1e 100644
--- a/y2019/vision/constants.cc
+++ b/y2019/vision/constants.cc
@@ -1,7 +1,6 @@
 #include "y2019/vision/constants.h"
 
-namespace y2019 {
-namespace vision {
+namespace y2019::vision {
 
 static constexpr double kInchesToMeters = 0.0254;
 
@@ -320,5 +319,4 @@
   }
 }
 
-}  // namespace vision
-}  // namespace y2019
+}  // namespace y2019::vision
diff --git a/y2019/vision/constants_formatting.cc b/y2019/vision/constants_formatting.cc
index ebda53f..52db9d5 100644
--- a/y2019/vision/constants_formatting.cc
+++ b/y2019/vision/constants_formatting.cc
@@ -3,8 +3,7 @@
 
 #include "y2019/vision/constants.h"
 
-namespace y2019 {
-namespace vision {
+namespace y2019::vision {
 
 namespace {
 // 64 should be enough for any mortal.
@@ -57,8 +56,7 @@
   std::ofstream o(fname);
   o << R"(#include "y2019/vision/constants.h"
 
-namespace y2019 {
-namespace vision {
+namespace y2019::vision {
 
 static constexpr double kInchesToMeters = 0.0254;
 )";
@@ -90,11 +88,9 @@
   }
 }
 
-}  // namespace vision
-}  // namespace y2019
+}  // namespace y2019::vision
 )";
   o.close();
 }
 
-}  // namespace vision
-}  // namespace y2019
+}  // namespace y2019::vision
diff --git a/y2019/vision/debug_serial.cc b/y2019/vision/debug_serial.cc
index 9b88260..79849b9 100644
--- a/y2019/vision/debug_serial.cc
+++ b/y2019/vision/debug_serial.cc
@@ -13,8 +13,7 @@
 #include "y2019/jevois/structures.h"
 #include "y2019/jevois/uart.h"
 
-namespace y2019 {
-namespace vision {
+namespace y2019::vision {
 
 void main(int argc, char **argv) {
   (void)argc;
@@ -85,7 +84,6 @@
   }
 }
 
-}  // namespace vision
-}  // namespace y2019
+}  // namespace y2019::vision
 
 int main(int argc, char **argv) { y2019::vision::main(argc, argv); }
diff --git a/y2019/vision/debug_viewer.cc b/y2019/vision/debug_viewer.cc
index b2ad1be..1a93f87 100644
--- a/y2019/vision/debug_viewer.cc
+++ b/y2019/vision/debug_viewer.cc
@@ -21,8 +21,7 @@
 
 DEFINE_int32(camera, 10, "The camera to use the intrinsics for");
 
-namespace y2019 {
-namespace vision {
+namespace y2019::vision {
 
 std::vector<PixelRef> GetNColors(size_t num_colors) {
   std::vector<PixelRef> colors;
@@ -358,8 +357,7 @@
   bool draw_results_ = true;
 };
 
-}  // namespace vision
-}  // namespace y2019
+}  // namespace y2019::vision
 
 int main(int argc, char **argv) {
   ::gflags::ParseCommandLineFlags(&argc, &argv, true);
diff --git a/y2019/vision/global_calibration.cc b/y2019/vision/global_calibration.cc
index b8f5b3c..bb3259e 100644
--- a/y2019/vision/global_calibration.cc
+++ b/y2019/vision/global_calibration.cc
@@ -52,8 +52,7 @@
 using ceres::Solve;
 using ceres::Solver;
 
-namespace y2019 {
-namespace vision {
+namespace y2019::vision {
 namespace {
 
 constexpr double kInchesToMeters = 0.0254;
@@ -293,7 +292,6 @@
   DumpCameraConstants(FLAGS_constants.c_str(), info.camera_id, results);
 }
 
-}  // namespace vision
-}  // namespace y2019
+}  // namespace y2019::vision
 
 int main(int argc, char **argv) { y2019::vision::main(argc, argv); }
diff --git a/y2019/vision/image_writer.cc b/y2019/vision/image_writer.cc
index 4ca9b96..9b73a81 100644
--- a/y2019/vision/image_writer.cc
+++ b/y2019/vision/image_writer.cc
@@ -6,8 +6,7 @@
 
 #include "glog/logging.h"
 
-namespace y2019 {
-namespace vision {
+namespace y2019::vision {
 
 ImageWriter::ImageWriter() {
   LOG(INFO) << "Initializing image writer";
@@ -38,5 +37,4 @@
   }
 }
 
-}  // namespace vision
-}  // namespace y2019
+}  // namespace y2019::vision
diff --git a/y2019/vision/server/server.cc b/y2019/vision/server/server.cc
index c9e7091..309a90c 100644
--- a/y2019/vision/server/server.cc
+++ b/y2019/vision/server/server.cc
@@ -28,8 +28,7 @@
 #include "y2019/control_loops/superstructure/superstructure_status_generated.h"
 #include "y2019/vision/server/server_data.pb.h"
 
-namespace y2019 {
-namespace vision {
+namespace y2019::vision {
 
 namespace chrono = ::std::chrono;
 
@@ -279,8 +278,7 @@
   event_loop.Run();
 }
 
-}  // namespace vision
-}  // namespace y2019
+}  // namespace y2019::vision
 
 int main(int argc, char **argv) {
   // Make sure to reference this to force the linker to include it.
diff --git a/y2019/vision/server/www/generate_camera.cc b/y2019/vision/server/www/generate_camera.cc
index 455b0a9..c673aec 100644
--- a/y2019/vision/server/www/generate_camera.cc
+++ b/y2019/vision/server/www/generate_camera.cc
@@ -4,8 +4,7 @@
 #include "y2019/constants.h"
 #include "y2019/vision/constants.h"
 
-namespace y2019 {
-namespace vision {
+namespace y2019::vision {
 void DumpPose(std::basic_ostream<char> *o, const vision::CameraGeometry &pose) {
   *o << "{x: " << pose.location[0] << ", y: " << pose.location[1]
      << ", theta: " << pose.heading << "}";
@@ -23,8 +22,7 @@
   }
   out_file << "];\n";
 }
-}  // namespace vision
-}  // namespace y2019
+}  // namespace y2019::vision
 
 int main(int argc, char *argv[]) {
   if (argc != 2) {
diff --git a/y2019/vision/target_finder.cc b/y2019/vision/target_finder.cc
index b59792c..7efc38a 100644
--- a/y2019/vision/target_finder.cc
+++ b/y2019/vision/target_finder.cc
@@ -6,8 +6,7 @@
 
 using namespace aos::vision;
 
-namespace y2019 {
-namespace vision {
+namespace y2019::vision {
 
 TargetFinder::TargetFinder()
     : target_template_(Target::MakeTemplate()),
@@ -632,5 +631,4 @@
   return needs_update;
 }
 
-}  // namespace vision
-}  // namespace y2019
+}  // namespace y2019::vision
diff --git a/y2019/vision/target_geometry.cc b/y2019/vision/target_geometry.cc
index e562f49..52d9b8d 100644
--- a/y2019/vision/target_geometry.cc
+++ b/y2019/vision/target_geometry.cc
@@ -11,8 +11,7 @@
 using ceres::Solve;
 using ceres::Solver;
 
-namespace y2019 {
-namespace vision {
+namespace y2019::vision {
 
 static constexpr double kInchesToMeters = 0.0254;
 
@@ -349,5 +348,4 @@
   return IR;
 }
 
-}  // namespace vision
-}  // namespace y2019
+}  // namespace y2019::vision
diff --git a/y2019/wpilib_interface.cc b/y2019/wpilib_interface.cc
index b3a5953..16102f4 100644
--- a/y2019/wpilib_interface.cc
+++ b/y2019/wpilib_interface.cc
@@ -66,8 +66,7 @@
 namespace chrono = ::std::chrono;
 using std::make_unique;
 
-namespace y2019 {
-namespace wpilib {
+namespace y2019::wpilib {
 namespace {
 
 constexpr double kMaxBringupPower = 12.0;
@@ -821,7 +820,6 @@
 };
 
 }  // namespace
-}  // namespace wpilib
-}  // namespace y2019
+}  // namespace y2019::wpilib
 
 AOS_ROBOT_CLASS(::y2019::wpilib::WPILibRobot);
diff --git a/y2020/actors/auto_splines.cc b/y2020/actors/auto_splines.cc
index 3ad292d..28aa996 100644
--- a/y2020/actors/auto_splines.cc
+++ b/y2020/actors/auto_splines.cc
@@ -2,8 +2,7 @@
 
 #include "frc971/control_loops/control_loops_generated.h"
 
-namespace y2020 {
-namespace actors {
+namespace y2020::actors {
 
 constexpr double kFieldLength = 16.4592;
 constexpr double kFieldWidth = 8.2296;
@@ -186,5 +185,4 @@
   return multispline_builder.Finish();
 }
 
-}  // namespace actors
-}  // namespace y2020
+}  // namespace y2020::actors
diff --git a/y2020/actors/autonomous_actor.cc b/y2020/actors/autonomous_actor.cc
index 160d36a..13b7d69 100644
--- a/y2020/actors/autonomous_actor.cc
+++ b/y2020/actors/autonomous_actor.cc
@@ -16,8 +16,7 @@
 DEFINE_bool(just_shoot, false,
             "If true, run the autonomous that just shoots balls.");
 
-namespace y2020 {
-namespace actors {
+namespace y2020::actors {
 
 using ::aos::monotonic_clock;
 using ::frc971::ProfileParametersT;
@@ -462,5 +461,4 @@
   return WaitUntilAbsoluteBallsShot(Balls() + num_wanted);
 }
 
-}  // namespace actors
-}  // namespace y2020
+}  // namespace y2020::actors
diff --git a/y2020/constants.cc b/y2020/constants.cc
index e30ef0e..b5456b4 100644
--- a/y2020/constants.cc
+++ b/y2020/constants.cc
@@ -20,8 +20,7 @@
 #include "y2020/control_loops/superstructure/intake/integral_intake_plant.h"
 #include "y2020/control_loops/superstructure/turret/integral_turret_plant.h"
 
-namespace y2020 {
-namespace constants {
+namespace y2020::constants {
 
 const int Values::kZeroingSampleSize;
 
@@ -200,5 +199,4 @@
   return *values;
 }
 
-}  // namespace constants
-}  // namespace y2020
+}  // namespace y2020::constants
diff --git a/y2020/control_loops/drivetrain/drivetrain_base.cc b/y2020/control_loops/drivetrain/drivetrain_base.cc
index 7b42df5..3e05020 100644
--- a/y2020/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2020/control_loops/drivetrain/drivetrain_base.cc
@@ -15,9 +15,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2020 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2020::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -77,6 +75,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2020
+}  // namespace y2020::control_loops::drivetrain
diff --git a/y2020/control_loops/drivetrain/drivetrain_replay_test.cc b/y2020/control_loops/drivetrain/drivetrain_replay_test.cc
index 0baf34b..731f02c 100644
--- a/y2020/control_loops/drivetrain/drivetrain_replay_test.cc
+++ b/y2020/control_loops/drivetrain/drivetrain_replay_test.cc
@@ -27,10 +27,7 @@
 DEFINE_string(config, "y2020/aos_config.json",
               "Name of the config file to replay using.");
 
-namespace y2020 {
-namespace control_loops {
-namespace drivetrain {
-namespace testing {
+namespace y2020::control_loops::drivetrain::testing {
 
 class DrivetrainReplayTest : public ::testing::Test {
  public:
@@ -135,7 +132,4 @@
   EXPECT_LT(std::abs(status_fetcher_->theta()), 0.02);
 }
 
-}  // namespace testing
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2020
+}  // namespace y2020::control_loops::drivetrain::testing
diff --git a/y2020/control_loops/drivetrain/localizer.cc b/y2020/control_loops/drivetrain/localizer.cc
index 8f8bf87..fabbb8e 100644
--- a/y2020/control_loops/drivetrain/localizer.cc
+++ b/y2020/control_loops/drivetrain/localizer.cc
@@ -6,9 +6,7 @@
             "If true, send LocalizerDebug messages on every tick, even if "
             "they would be empty.");
 
-namespace y2020 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2020::control_loops::drivetrain {
 
 namespace {
 // Converts a flatbuffer TransformationMatrix to an Eigen matrix. Technically,
@@ -499,6 +497,4 @@
   return Zhat;
 }
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2020
+}  // namespace y2020::control_loops::drivetrain
diff --git a/y2020/control_loops/drivetrain/localizer_test.cc b/y2020/control_loops/drivetrain/localizer_test.cc
index 3e2cf6b..90076c0 100644
--- a/y2020/control_loops/drivetrain/localizer_test.cc
+++ b/y2020/control_loops/drivetrain/localizer_test.cc
@@ -19,10 +19,7 @@
 
 // This file tests that the full 2020 localizer behaves sanely.
 
-namespace y2020 {
-namespace control_loops {
-namespace drivetrain {
-namespace testing {
+namespace y2020::control_loops::drivetrain::testing {
 
 using aos::logger::BootTimestamp;
 using frc971::control_loops::drivetrain::DrivetrainConfig;
@@ -622,7 +619,4 @@
   RunFor(chrono::seconds(20));
 }
 
-}  // namespace testing
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2020
+}  // namespace y2020::control_loops::drivetrain::testing
diff --git a/y2020/control_loops/superstructure/shooter/shooter.cc b/y2020/control_loops/superstructure/shooter/shooter.cc
index c400e34..2792205 100644
--- a/y2020/control_loops/superstructure/shooter/shooter.cc
+++ b/y2020/control_loops/superstructure/shooter/shooter.cc
@@ -9,10 +9,7 @@
 #include "y2020/control_loops/superstructure/finisher/finisher_plant.h"
 #include "y2020/control_loops/superstructure/finisher/integral_finisher_plant.h"
 
-namespace y2020 {
-namespace control_loops {
-namespace superstructure {
-namespace shooter {
+namespace y2020::control_loops::superstructure::shooter {
 
 Shooter::Shooter()
     : finisher_(
@@ -141,7 +138,4 @@
   return status_builder.Finish();
 }
 
-}  // namespace shooter
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2020
+}  // namespace y2020::control_loops::superstructure::shooter
diff --git a/y2020/control_loops/superstructure/superstructure.cc b/y2020/control_loops/superstructure/superstructure.cc
index b7d57b4..f951791 100644
--- a/y2020/control_loops/superstructure/superstructure.cc
+++ b/y2020/control_loops/superstructure/superstructure.cc
@@ -4,9 +4,7 @@
 #include "aos/events/event_loop.h"
 #include "aos/network/team_number.h"
 
-namespace y2020 {
-namespace control_loops {
-namespace superstructure {
+namespace y2020::control_loops::superstructure {
 
 using frc971::control_loops::AbsoluteAndAbsoluteEncoderProfiledJointStatus;
 using frc971::control_loops::AbsoluteEncoderProfiledJointStatus;
@@ -313,6 +311,4 @@
   }
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2020
+}  // namespace y2020::control_loops::superstructure
diff --git a/y2020/control_loops/superstructure/superstructure_lib_test.cc b/y2020/control_loops/superstructure/superstructure_lib_test.cc
index 8b34fc9..950593e 100644
--- a/y2020/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2020/control_loops/superstructure/superstructure_lib_test.cc
@@ -28,10 +28,7 @@
 DEFINE_string(config, "y2020/aos_config.json",
               "Name of the config file to replay using.");
 
-namespace y2020 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2020::control_loops::superstructure::testing {
 
 namespace {
 constexpr double kNoiseScalar = 0.01;
@@ -1473,7 +1470,4 @@
                                            aos::Alliance::kBlue,
                                            aos::Alliance::kInvalid));
 
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2020
+}  // namespace y2020::control_loops::superstructure::testing
diff --git a/y2020/control_loops/superstructure/turret/aiming.cc b/y2020/control_loops/superstructure/turret/aiming.cc
index 0b2c5f3..238beda 100644
--- a/y2020/control_loops/superstructure/turret/aiming.cc
+++ b/y2020/control_loops/superstructure/turret/aiming.cc
@@ -3,10 +3,7 @@
 #include "y2020/constants.h"
 #include "y2020/control_loops/drivetrain/drivetrain_base.h"
 
-namespace y2020 {
-namespace control_loops {
-namespace superstructure {
-namespace turret {
+namespace y2020::control_loops::superstructure::turret {
 
 using frc971::control_loops::Pose;
 using frc971::control_loops::aiming::RobotState;
@@ -197,7 +194,4 @@
   return builder.Finish();
 }
 
-}  // namespace turret
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2020
+}  // namespace y2020::control_loops::superstructure::turret
diff --git a/y2020/control_loops/superstructure/turret/aiming_test.cc b/y2020/control_loops/superstructure/turret/aiming_test.cc
index b63d705..855f66a 100644
--- a/y2020/control_loops/superstructure/turret/aiming_test.cc
+++ b/y2020/control_loops/superstructure/turret/aiming_test.cc
@@ -7,11 +7,7 @@
 #include "y2020/constants.h"
 #include "y2020/control_loops/drivetrain/drivetrain_base.h"
 
-namespace y2020 {
-namespace control_loops {
-namespace superstructure {
-namespace turret {
-namespace testing {
+namespace y2020::control_loops::superstructure::turret::testing {
 
 class TeamNumberEnvironment : public ::testing::Environment {
  public:
@@ -259,8 +255,4 @@
   EXPECT_EQ(0.0, goal->goal_velocity());
 }
 
-}  // namespace testing
-}  // namespace turret
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2020
+}  // namespace y2020::control_loops::superstructure::turret::testing
diff --git a/y2020/joystick_reader.cc b/y2020/joystick_reader.cc
index 951c5a7..2aa263e 100644
--- a/y2020/joystick_reader.cc
+++ b/y2020/joystick_reader.cc
@@ -31,9 +31,7 @@
 using frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal;
 using frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal;
 
-namespace y2020 {
-namespace input {
-namespace joysticks {
+namespace y2020::input::joysticks {
 
 namespace superstructure = y2020::control_loops::superstructure;
 
@@ -332,9 +330,7 @@
   size_t unwinch_counter_ = 0;
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2020
+}  // namespace y2020::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2020/vision/camera_reader.cc b/y2020/vision/camera_reader.cc
index a63becd..251f988 100644
--- a/y2020/vision/camera_reader.cc
+++ b/y2020/vision/camera_reader.cc
@@ -23,8 +23,7 @@
 DEFINE_bool(use_prev_pose, true,
             "If true, use previous pose estimate as seed for next estimate.");
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 
 const sift::CameraCalibration *CameraReader::FindCameraCalibration() const {
   const std::string_view node_name = event_loop_->node()->name()->string_view();
@@ -541,5 +540,4 @@
   return fbb->CreateVector(features_vector);
 }
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
diff --git a/y2020/vision/camera_reader_main.cc b/y2020/vision/camera_reader_main.cc
index b54cf4e..1995151 100644
--- a/y2020/vision/camera_reader_main.cc
+++ b/y2020/vision/camera_reader_main.cc
@@ -6,8 +6,8 @@
 // bazel run //y2020/vision:camera_reader -- --config y2020/aos_config.json
 //   --override_hostname pi-7971-1  --ignore_timestamps true
 DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
-namespace frc971 {
-namespace vision {
+
+namespace frc971::vision {
 namespace {
 
 void CameraReaderMain() {
@@ -43,8 +43,7 @@
 }
 
 }  // namespace
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2020/vision/extrinsics_calibration.cc b/y2020/vision/extrinsics_calibration.cc
index 334de0b..deda8c3 100644
--- a/y2020/vision/extrinsics_calibration.cc
+++ b/y2020/vision/extrinsics_calibration.cc
@@ -21,8 +21,7 @@
 DEFINE_string(base_intrinsics, "",
               "Intrinsics to use for extrinsics calibration.");
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace chrono = std::chrono;
 using aos::distributed_clock;
 using aos::monotonic_clock;
@@ -146,8 +145,7 @@
   }
 }
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2020/vision/sift/fast_gaussian.cc b/y2020/vision/sift/fast_gaussian.cc
index 22549ac..69432b4 100644
--- a/y2020/vision/sift/fast_gaussian.cc
+++ b/y2020/vision/sift/fast_gaussian.cc
@@ -6,8 +6,7 @@
 
 #include "y2020/vision/sift/fast_gaussian_all.h"
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace {
 
 void CheckNonOverlapping(const cv::Mat &a, const cv::Mat &b) {
@@ -122,5 +121,4 @@
   cv::subtract(*blurred, source, *difference);
 }
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
diff --git a/y2020/vision/sift/fast_gaussian_generator.cc b/y2020/vision/sift/fast_gaussian_generator.cc
index aefb3d9..9b3ca9a 100644
--- a/y2020/vision/sift/fast_gaussian_generator.cc
+++ b/y2020/vision/sift/fast_gaussian_generator.cc
@@ -15,8 +15,7 @@
 // https://halide-lang.org/tutorials/tutorial_lesson_15_generators.html has an
 // introduction to much of the magic in this file.
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace {
 
 // Returns a function implementating a 1-dimensional gaussian blur convolution.
@@ -206,8 +205,7 @@
   }
 };
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
 
 HALIDE_REGISTER_GENERATOR(frc971::vision::GaussianGenerator, gaussian_generator)
 HALIDE_REGISTER_GENERATOR(frc971::vision::SubtractGenerator, subtract_generator)
diff --git a/y2020/vision/sift/fast_gaussian_test.cc b/y2020/vision/sift/fast_gaussian_test.cc
index 0ed9e20..27bab54 100644
--- a/y2020/vision/sift/fast_gaussian_test.cc
+++ b/y2020/vision/sift/fast_gaussian_test.cc
@@ -5,9 +5,7 @@
 
 #include "y2020/vision/sift/fast_gaussian_all.h"
 
-namespace frc971 {
-namespace vision {
-namespace testing {
+namespace frc971::vision::testing {
 
 class FastGaussianTest : public ::testing::Test {
  public:
@@ -70,6 +68,4 @@
   ExpectEqual(fast, fast_direct, 0);
 }
 
-}  // namespace testing
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision::testing
diff --git a/y2020/vision/sift/get_gaussian_kernel_test.cc b/y2020/vision/sift/get_gaussian_kernel_test.cc
index e35f06e..3d2674f 100644
--- a/y2020/vision/sift/get_gaussian_kernel_test.cc
+++ b/y2020/vision/sift/get_gaussian_kernel_test.cc
@@ -8,9 +8,7 @@
 #include <opencv2/core/mat.hpp>
 #include <opencv2/imgproc.hpp>
 
-namespace frc971 {
-namespace vision {
-namespace testing {
+namespace frc971::vision::testing {
 
 class GetGaussianKernelTest
     : public ::testing::TestWithParam<std::tuple<int, double>> {
@@ -33,6 +31,4 @@
                                             ::testing::Values(0.01f, 0.1f,
                                                               0.9f)));
 
-}  // namespace testing
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision::testing
diff --git a/y2020/vision/sift/sift971.cc b/y2020/vision/sift/sift971.cc
index afab9b4..21f9a97 100644
--- a/y2020/vision/sift/sift971.cc
+++ b/y2020/vision/sift/sift971.cc
@@ -118,8 +118,7 @@
 
 using namespace cv;
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace {
 
 #define USE_AVX2 0
@@ -1288,5 +1287,4 @@
   }
 }
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
diff --git a/y2020/vision/tools/python_code/camera_param_test.cc b/y2020/vision/tools/python_code/camera_param_test.cc
index 30616b0..f47c327 100644
--- a/y2020/vision/tools/python_code/camera_param_test.cc
+++ b/y2020/vision/tools/python_code/camera_param_test.cc
@@ -16,8 +16,7 @@
 #include "y2020/vision/sift/sift_generated.h"
 #include "y2020/vision/sift/sift_training_generated.h"
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace {
 
 class Feature {
@@ -275,5 +274,4 @@
 }
 
 }  // namespace
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
diff --git a/y2020/vision/viewer.cc b/y2020/vision/viewer.cc
index ff08f01..8ba2955 100644
--- a/y2020/vision/viewer.cc
+++ b/y2020/vision/viewer.cc
@@ -20,8 +20,7 @@
 DEFINE_string(capture, "",
               "If set, capture a single image and save it to this filename.");
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace {
 
 aos::Fetcher<CameraImage> image_fetcher;
@@ -170,8 +169,7 @@
 }
 
 }  // namespace
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
 
 // Quick and lightweight grayscale viewer for images
 int main(int argc, char **argv) {
diff --git a/y2020/vision/viewer_replay.cc b/y2020/vision/viewer_replay.cc
index 03777bc..ee1c8d5 100644
--- a/y2020/vision/viewer_replay.cc
+++ b/y2020/vision/viewer_replay.cc
@@ -12,8 +12,7 @@
 DEFINE_string(image_save_prefix, "/tmp/img",
               "Prefix to use for saving images from the logfile.");
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace {
 
 void ViewerMain(int argc, char *argv[]) {
@@ -50,8 +49,7 @@
 }
 
 }  // namespace
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
 
 // Quick and lightweight grayscale viewer for images
 int main(int argc, char **argv) {
diff --git a/y2020/wpilib_interface.cc b/y2020/wpilib_interface.cc
index c9cec8a..f3ff00f 100644
--- a/y2020/wpilib_interface.cc
+++ b/y2020/wpilib_interface.cc
@@ -65,8 +65,7 @@
 namespace chrono = ::std::chrono;
 using std::make_unique;
 
-namespace y2020 {
-namespace wpilib {
+namespace y2020::wpilib {
 namespace {
 
 constexpr double kMaxBringupPower = 12.0;
@@ -685,7 +684,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2020
+}  // namespace y2020::wpilib
 
 AOS_ROBOT_CLASS(::y2020::wpilib::WPILibRobot);
diff --git a/y2021_bot3/actors/auto_splines.cc b/y2021_bot3/actors/auto_splines.cc
index c6a5fd3..8546391 100644
--- a/y2021_bot3/actors/auto_splines.cc
+++ b/y2021_bot3/actors/auto_splines.cc
@@ -2,8 +2,7 @@
 
 #include "frc971/control_loops/control_loops_generated.h"
 
-namespace y2021_bot3 {
-namespace actors {
+namespace y2021_bot3::actors {
 
 void MaybeFlipSpline(
     aos::Sender<frc971::control_loops::drivetrain::Goal>::Builder *builder,
@@ -99,5 +98,4 @@
   return multispline_builder.Finish();
 }
 
-}  // namespace actors
-}  // namespace y2021_bot3
+}  // namespace y2021_bot3::actors
diff --git a/y2021_bot3/actors/autonomous_actor.cc b/y2021_bot3/actors/autonomous_actor.cc
index c6ea7c5..e5db3fa 100644
--- a/y2021_bot3/actors/autonomous_actor.cc
+++ b/y2021_bot3/actors/autonomous_actor.cc
@@ -8,8 +8,7 @@
 #include "frc971/control_loops/drivetrain/localizer_generated.h"
 #include "y2021_bot3/control_loops/drivetrain/drivetrain_base.h"
 
-namespace y2021_bot3 {
-namespace actors {
+namespace y2021_bot3::actors {
 
 using ::aos::monotonic_clock;
 using ::frc971::ProfileParametersT;
@@ -33,5 +32,4 @@
   return true;
 }
 
-}  // namespace actors
-}  // namespace y2021_bot3
+}  // namespace y2021_bot3::actors
diff --git a/y2021_bot3/constants.cc b/y2021_bot3/constants.cc
index facd1a0..63ebf7a 100644
--- a/y2021_bot3/constants.cc
+++ b/y2021_bot3/constants.cc
@@ -13,8 +13,7 @@
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
 
-namespace y2021_bot3 {
-namespace constants {
+namespace y2021_bot3::constants {
 
 const int Values::kZeroingSampleSize;
 
@@ -80,5 +79,4 @@
   return *values[team_number];
 }
 
-}  // namespace constants
-}  // namespace y2021_bot3
+}  // namespace y2021_bot3::constants
diff --git a/y2021_bot3/control_loops/drivetrain/drivetrain_base.cc b/y2021_bot3/control_loops/drivetrain/drivetrain_base.cc
index 5b4c120..42f0535 100644
--- a/y2021_bot3/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2021_bot3/control_loops/drivetrain/drivetrain_base.cc
@@ -13,9 +13,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2021_bot3 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2021_bot3::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -58,6 +56,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2021_bot3
+}  // namespace y2021_bot3::control_loops::drivetrain
diff --git a/y2021_bot3/control_loops/superstructure/superstructure.cc b/y2021_bot3/control_loops/superstructure/superstructure.cc
index 1b4b611..16fa3d0 100644
--- a/y2021_bot3/control_loops/superstructure/superstructure.cc
+++ b/y2021_bot3/control_loops/superstructure/superstructure.cc
@@ -2,9 +2,7 @@
 
 #include "aos/events/event_loop.h"
 
-namespace y2021_bot3 {
-namespace control_loops {
-namespace superstructure {
+namespace y2021_bot3::control_loops::superstructure {
 
 using frc971::control_loops::AbsoluteEncoderProfiledJointStatus;
 using frc971::control_loops::PotAndAbsoluteEncoderProfiledJointStatus;
@@ -50,6 +48,4 @@
   (void)status->Send(status_builder.Finish());
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2021_bot3
+}  // namespace y2021_bot3::control_loops::superstructure
diff --git a/y2021_bot3/control_loops/superstructure/superstructure_lib_test.cc b/y2021_bot3/control_loops/superstructure/superstructure_lib_test.cc
index a47cd57..089250b 100644
--- a/y2021_bot3/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2021_bot3/control_loops/superstructure/superstructure_lib_test.cc
@@ -13,10 +13,7 @@
 DEFINE_string(output_folder, "",
               "If set, logs all channels to the provided logfile.");
 
-namespace y2021_bot3 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2021_bot3::control_loops::superstructure::testing {
 
 class SuperstructureTest : public ::frc971::testing::ControlLoopTest {
  public:
@@ -202,7 +199,4 @@
   RunFor(std::chrono::seconds(10));
 }
 
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2021_bot3
+}  // namespace y2021_bot3::control_loops::superstructure::testing
diff --git a/y2021_bot3/joystick_reader.cc b/y2021_bot3/joystick_reader.cc
index 0e5076a..dc60c6e 100644
--- a/y2021_bot3/joystick_reader.cc
+++ b/y2021_bot3/joystick_reader.cc
@@ -23,9 +23,7 @@
 using frc971::input::driver_station::JoystickAxis;
 using frc971::input::driver_station::POVLocation;
 
-namespace y2021_bot3 {
-namespace input {
-namespace joysticks {
+namespace y2021_bot3::input::joysticks {
 
 namespace superstructure = y2021_bot3::control_loops::superstructure;
 
@@ -59,9 +57,7 @@
   ::aos::Fetcher<superstructure::Status> superstructure_status_fetcher_;
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2021_bot3
+}  // namespace y2021_bot3::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2021_bot3/wpilib_interface.cc b/y2021_bot3/wpilib_interface.cc
index 6f5908c..4006736 100644
--- a/y2021_bot3/wpilib_interface.cc
+++ b/y2021_bot3/wpilib_interface.cc
@@ -59,8 +59,7 @@
 namespace chrono = ::std::chrono;
 using std::make_unique;
 
-namespace y2021_bot3 {
-namespace wpilib {
+namespace y2021_bot3::wpilib {
 namespace {
 
 constexpr double kMaxBringupPower = 12.0;
@@ -354,7 +353,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2021_bot3
+}  // namespace y2021_bot3::wpilib
 
 AOS_ROBOT_CLASS(::y2021_bot3::wpilib::WPILibRobot);
diff --git a/y2022/actors/auto_splines.cc b/y2022/actors/auto_splines.cc
index e674dc4..b0915d5 100644
--- a/y2022/actors/auto_splines.cc
+++ b/y2022/actors/auto_splines.cc
@@ -2,8 +2,7 @@
 
 #include "frc971/control_loops/control_loops_generated.h"
 
-namespace y2022 {
-namespace actors {
+namespace y2022::actors {
 
 void MaybeFlipSpline(
     aos::Sender<frc971::control_loops::drivetrain::Goal>::Builder *builder,
@@ -100,5 +99,4 @@
       alliance);
 }
 
-}  // namespace actors
-}  // namespace y2022
+}  // namespace y2022::actors
diff --git a/y2022/actors/autonomous_actor.cc b/y2022/actors/autonomous_actor.cc
index 19e9edf..41f7e04 100644
--- a/y2022/actors/autonomous_actor.cc
+++ b/y2022/actors/autonomous_actor.cc
@@ -18,8 +18,7 @@
 DEFINE_bool(rapid_react_two, false,
             "If true, run the two ball rapid react autonomous mode");
 
-namespace y2022 {
-namespace actors {
+namespace y2022::actors {
 namespace {
 constexpr double kExtendIntakeGoal = -0.10;
 constexpr double kRetractIntakeGoal = 1.47;
@@ -491,5 +490,4 @@
   }
 }
 
-}  // namespace actors
-}  // namespace y2022
+}  // namespace y2022::actors
diff --git a/y2022/constants.cc b/y2022/constants.cc
index 04ca14c..7ad6213 100644
--- a/y2022/constants.cc
+++ b/y2022/constants.cc
@@ -19,8 +19,7 @@
 #include "y2022/control_loops/superstructure/intake/integral_intake_plant.h"
 #include "y2022/control_loops/superstructure/turret/integral_turret_plant.h"
 
-namespace y2022 {
-namespace constants {
+namespace y2022::constants {
 
 const int Values::kZeroingSampleSize;
 
@@ -412,5 +411,4 @@
 
 Values MakeValues() { return MakeValues(aos::network::GetTeamNumber()); }
 
-}  // namespace constants
-}  // namespace y2022
+}  // namespace y2022::constants
diff --git a/y2022/control_loops/drivetrain/drivetrain_base.cc b/y2022/control_loops/drivetrain/drivetrain_base.cc
index c58353e..551a5d5 100644
--- a/y2022/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2022/control_loops/drivetrain/drivetrain_base.cc
@@ -14,9 +14,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2022 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2022::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -66,6 +64,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2022
+}  // namespace y2022::control_loops::drivetrain
diff --git a/y2022/control_loops/superstructure/catapult/catapult.cc b/y2022/control_loops/superstructure/catapult/catapult.cc
index b0ec6fd..493bb46 100644
--- a/y2022/control_loops/superstructure/catapult/catapult.cc
+++ b/y2022/control_loops/superstructure/catapult/catapult.cc
@@ -10,10 +10,7 @@
 #include "osqp.h"
 #include "y2022/control_loops/superstructure/catapult/catapult_plant.h"
 
-namespace y2022 {
-namespace control_loops {
-namespace superstructure {
-namespace catapult {
+namespace y2022::control_loops::superstructure::catapult {
 namespace chrono = std::chrono;
 
 namespace {
@@ -453,7 +450,4 @@
   return catapult_.MakeStatus(fbb);
 }
 
-}  // namespace catapult
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2022
+}  // namespace y2022::control_loops::superstructure::catapult
diff --git a/y2022/control_loops/superstructure/catapult/catapult_main.cc b/y2022/control_loops/superstructure/catapult/catapult_main.cc
index 53d357a..e3f897c 100644
--- a/y2022/control_loops/superstructure/catapult/catapult_main.cc
+++ b/y2022/control_loops/superstructure/catapult/catapult_main.cc
@@ -4,10 +4,7 @@
 #include "y2022/control_loops/superstructure/catapult/catapult.h"
 #include "y2022/control_loops/superstructure/catapult/catapult_plant.h"
 
-namespace y2022 {
-namespace control_loops {
-namespace superstructure {
-namespace catapult {
+namespace y2022::control_loops::superstructure::catapult {
 namespace chrono = std::chrono;
 
 void OSQPSolve() {
@@ -114,10 +111,7 @@
   return 0;
 }
 
-}  // namespace catapult
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2022
+}  // namespace y2022::control_loops::superstructure::catapult
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2022/control_loops/superstructure/catapult/catapult_test.cc b/y2022/control_loops/superstructure/catapult/catapult_test.cc
index 7361bcd..b2cd180 100644
--- a/y2022/control_loops/superstructure/catapult/catapult_test.cc
+++ b/y2022/control_loops/superstructure/catapult/catapult_test.cc
@@ -5,11 +5,7 @@
 
 #include "y2022/control_loops/superstructure/catapult/catapult_plant.h"
 
-namespace y2022 {
-namespace control_loops {
-namespace superstructure {
-namespace catapult {
-namespace testing {
+namespace y2022::control_loops::superstructure::catapult::testing {
 
 // Tests that computing P and q with 2 different horizons comes out the same.
 TEST(MPCTest, HorizonTest) {
@@ -56,8 +52,4 @@
   EXPECT_NEAR(X_final.y(), X.y(), 1e-2);
 }
 
-}  // namespace testing
-}  // namespace catapult
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2022
+}  // namespace y2022::control_loops::superstructure::catapult::testing
diff --git a/y2022/control_loops/superstructure/collision_avoidance.cc b/y2022/control_loops/superstructure/collision_avoidance.cc
index 0c13295..33e4d6e 100644
--- a/y2022/control_loops/superstructure/collision_avoidance.cc
+++ b/y2022/control_loops/superstructure/collision_avoidance.cc
@@ -5,9 +5,7 @@
 #include "absl/functional/bind_front.h"
 #include "glog/logging.h"
 
-namespace y2022 {
-namespace control_loops {
-namespace superstructure {
+namespace y2022::control_loops::superstructure {
 
 CollisionAvoidance::CollisionAvoidance() {
   clear_min_intake_front_goal();
@@ -213,6 +211,4 @@
   }
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2022
+}  // namespace y2022::control_loops::superstructure
diff --git a/y2022/control_loops/superstructure/superstructure.cc b/y2022/control_loops/superstructure/superstructure.cc
index 5abe995..fc6aeee 100644
--- a/y2022/control_loops/superstructure/superstructure.cc
+++ b/y2022/control_loops/superstructure/superstructure.cc
@@ -9,9 +9,7 @@
 DEFINE_bool(ignore_distance, false,
             "If true, ignore distance when shooting and obay joystick_reader");
 
-namespace y2022 {
-namespace control_loops {
-namespace superstructure {
+namespace y2022::control_loops::superstructure {
 
 using frc971::control_loops::AbsoluteEncoderProfiledJointStatus;
 using frc971::control_loops::PotAndAbsoluteEncoderProfiledJointStatus;
@@ -653,6 +651,4 @@
               : 0.0);
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2022
+}  // namespace y2022::control_loops::superstructure
diff --git a/y2022/control_loops/superstructure/superstructure_lib_test.cc b/y2022/control_loops/superstructure/superstructure_lib_test.cc
index c85d5d0..cbe3c97 100644
--- a/y2022/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2022/control_loops/superstructure/superstructure_lib_test.cc
@@ -19,10 +19,7 @@
 DEFINE_string(output_folder, "",
               "If set, logs all channels to the provided logfile.");
 
-namespace y2022 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2022::control_loops::superstructure::testing {
 namespace chrono = std::chrono;
 
 using ::aos::monotonic_clock;
@@ -1300,7 +1297,4 @@
               superstructure_status_fetcher_->turret()->position(), 5e-4);
 }
 
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2022
+}  // namespace y2022::control_loops::superstructure::testing
diff --git a/y2022/control_loops/superstructure/turret/aiming.cc b/y2022/control_loops/superstructure/turret/aiming.cc
index c570856..18ebafa 100644
--- a/y2022/control_loops/superstructure/turret/aiming.cc
+++ b/y2022/control_loops/superstructure/turret/aiming.cc
@@ -2,10 +2,7 @@
 
 #include "y2022/control_loops/drivetrain/drivetrain_base.h"
 
-namespace y2022 {
-namespace control_loops {
-namespace superstructure {
-namespace turret {
+namespace y2022::control_loops::superstructure::turret {
 
 using frc971::control_loops::Pose;
 using frc971::control_loops::aiming::RobotState;
@@ -80,7 +77,4 @@
   return builder.Finish();
 }
 
-}  // namespace turret
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2022
+}  // namespace y2022::control_loops::superstructure::turret
diff --git a/y2022/joystick_reader.cc b/y2022/joystick_reader.cc
index 910e16d..9993e8f 100644
--- a/y2022/joystick_reader.cc
+++ b/y2022/joystick_reader.cc
@@ -31,9 +31,7 @@
 using frc971::input::driver_station::JoystickAxis;
 using frc971::input::driver_station::POVLocation;
 
-namespace y2022 {
-namespace input {
-namespace joysticks {
+namespace y2022::input::joysticks {
 
 namespace superstructure = y2022::control_loops::superstructure;
 
@@ -376,9 +374,7 @@
   bool last_back_intake_has_ball_ = false;
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2022
+}  // namespace y2022::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2022/vision/ball_color.cc b/y2022/vision/ball_color.cc
index b1ebd85..930142f 100644
--- a/y2022/vision/ball_color.cc
+++ b/y2022/vision/ball_color.cc
@@ -13,8 +13,7 @@
 #include "frc971/input/joystick_state_generated.h"
 #include "frc971/vision/vision_generated.h"
 
-namespace y2022 {
-namespace vision {
+namespace y2022::vision {
 
 namespace {
 cv::Rect ArrayToRect(const std::array<int, 4> &values) {
@@ -144,5 +143,4 @@
   return sum / num_pixels_selected;
 }
 
-}  // namespace vision
-}  // namespace y2022
+}  // namespace y2022::vision
diff --git a/y2022/vision/ball_color_main.cc b/y2022/vision/ball_color_main.cc
index 03e3033..5f05b34 100644
--- a/y2022/vision/ball_color_main.cc
+++ b/y2022/vision/ball_color_main.cc
@@ -9,8 +9,7 @@
 //   --override_hostname pi-7971-1  --ignore_timestamps true
 DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
 
-namespace y2022 {
-namespace vision {
+namespace y2022::vision {
 namespace {
 
 using namespace frc971::vision;
@@ -28,8 +27,7 @@
 }
 
 }  // namespace
-}  // namespace vision
-}  // namespace y2022
+}  // namespace y2022::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2022/vision/blob_detector.cc b/y2022/vision/blob_detector.cc
index 2c6ff44..70ff1b2 100644
--- a/y2022/vision/blob_detector.cc
+++ b/y2022/vision/blob_detector.cc
@@ -25,8 +25,7 @@
              "Required difference between green pixels vs. blue when using "
              "--use_outdoors");
 
-namespace y2022 {
-namespace vision {
+namespace y2022::vision {
 
 cv::Mat BlobDetector::ThresholdImage(cv::Mat bgr_image) {
   cv::Mat binarized_image(cv::Size(bgr_image.cols, bgr_image.rows), CV_8UC1);
@@ -266,5 +265,4 @@
           << " ms";
 }
 
-}  // namespace vision
-}  // namespace y2022
+}  // namespace y2022::vision
diff --git a/y2022/vision/calibrate_extrinsics.cc b/y2022/vision/calibrate_extrinsics.cc
index d8b57dc..0a950ab 100644
--- a/y2022/vision/calibrate_extrinsics.cc
+++ b/y2022/vision/calibrate_extrinsics.cc
@@ -25,8 +25,7 @@
 DEFINE_string(base_intrinsics, "",
               "Intrinsics to use for extrinsics calibration.");
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace chrono = std::chrono;
 using aos::distributed_clock;
 using aos::monotonic_clock;
@@ -263,8 +262,7 @@
   }
 }  // namespace vision
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2022/vision/camera_reader.cc b/y2022/vision/camera_reader.cc
index 012a2db..a077d09 100644
--- a/y2022/vision/camera_reader.cc
+++ b/y2022/vision/camera_reader.cc
@@ -17,8 +17,7 @@
 
 DEFINE_string(image_png, "", "A set of PNG images");
 
-namespace y2022 {
-namespace vision {
+namespace y2022::vision {
 
 using namespace frc971::vision;
 
@@ -235,5 +234,4 @@
   }
 }
 
-}  // namespace vision
-}  // namespace y2022
+}  // namespace y2022::vision
diff --git a/y2022/vision/camera_reader_main.cc b/y2022/vision/camera_reader_main.cc
index 5f19d64..278f14b 100644
--- a/y2022/vision/camera_reader_main.cc
+++ b/y2022/vision/camera_reader_main.cc
@@ -14,8 +14,7 @@
               "Exposure time when using --use_outdoors, in 100us increments; 0 "
               "implies auto exposure");
 
-namespace y2022 {
-namespace vision {
+namespace y2022::vision {
 namespace {
 
 using namespace frc971::vision;
@@ -59,8 +58,7 @@
 }
 
 }  // namespace
-}  // namespace vision
-}  // namespace y2022
+}  // namespace y2022::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2022/vision/viewer.cc b/y2022/vision/viewer.cc
index 58db722..b0bcdac 100644
--- a/y2022/vision/viewer.cc
+++ b/y2022/vision/viewer.cc
@@ -36,8 +36,7 @@
             "If true, display the target estimation graphically");
 DEFINE_bool(sort_by_time, true, "If true, sort the images by time");
 
-namespace y2022 {
-namespace vision {
+namespace y2022::vision {
 namespace {
 
 using namespace frc971::vision;
@@ -273,8 +272,7 @@
   }
 }
 }  // namespace
-}  // namespace vision
-}  // namespace y2022
+}  // namespace y2022::vision
 
 // Quick and lightweight viewer for images
 int main(int argc, char **argv) {
diff --git a/y2022/vision/viewer_replay.cc b/y2022/vision/viewer_replay.cc
index 7e8c800..15427e4 100644
--- a/y2022/vision/viewer_replay.cc
+++ b/y2022/vision/viewer_replay.cc
@@ -26,8 +26,7 @@
 DEFINE_string(logger_pi_log, "/tmp/logger_pi/", "Path to logger pi log");
 DEFINE_string(roborio_log, "/tmp/roborio/", "Path to roborio log");
 
-namespace y2022 {
-namespace vision {
+namespace y2022::vision {
 namespace {
 
 using aos::monotonic_clock;
@@ -257,8 +256,7 @@
 }
 
 }  // namespace
-}  // namespace vision
-}  // namespace y2022
+}  // namespace y2022::vision
 
 // Quick and lightweight viewer for image logs
 int main(int argc, char **argv) {
diff --git a/y2022/wpilib_interface.cc b/y2022/wpilib_interface.cc
index 55cf510..dd2224c 100644
--- a/y2022/wpilib_interface.cc
+++ b/y2022/wpilib_interface.cc
@@ -65,8 +65,7 @@
 
 DEFINE_bool(can_catapult, false, "If true, use CAN to control the catapult.");
 
-namespace y2022 {
-namespace wpilib {
+namespace y2022::wpilib {
 namespace {
 
 constexpr double kMaxBringupPower = 12.0;
@@ -828,7 +827,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2022
+}  // namespace y2022::wpilib
 
 AOS_ROBOT_CLASS(::y2022::wpilib::WPILibRobot);
diff --git a/y2022_bot3/actors/auto_splines.cc b/y2022_bot3/actors/auto_splines.cc
index 047eac8..ced429a 100644
--- a/y2022_bot3/actors/auto_splines.cc
+++ b/y2022_bot3/actors/auto_splines.cc
@@ -2,8 +2,7 @@
 
 #include "frc971/control_loops/control_loops_generated.h"
 
-namespace y2022_bot3 {
-namespace actors {
+namespace y2022_bot3::actors {
 
 void MaybeFlipSpline(
     aos::Sender<frc971::control_loops::drivetrain::Goal>::Builder *builder,
@@ -50,5 +49,4 @@
       alliance);
 }
 
-}  // namespace actors
-}  // namespace y2022_bot3
+}  // namespace y2022_bot3::actors
diff --git a/y2022_bot3/actors/autonomous_actor.cc b/y2022_bot3/actors/autonomous_actor.cc
index a4667ce..6c5c244 100644
--- a/y2022_bot3/actors/autonomous_actor.cc
+++ b/y2022_bot3/actors/autonomous_actor.cc
@@ -14,8 +14,7 @@
 
 DEFINE_bool(spline_auto, false, "If true, define a spline autonomous mode");
 
-namespace y2022_bot3 {
-namespace actors {
+namespace y2022_bot3::actors {
 
 using ::aos::monotonic_clock;
 using frc971::CreateProfileParameters;
@@ -183,5 +182,4 @@
   }
 }
 
-}  // namespace actors
-}  // namespace y2022_bot3
+}  // namespace y2022_bot3::actors
diff --git a/y2022_bot3/constants.cc b/y2022_bot3/constants.cc
index ef5ad32..8defbc6 100644
--- a/y2022_bot3/constants.cc
+++ b/y2022_bot3/constants.cc
@@ -16,8 +16,7 @@
 #include "y2022_bot3/control_loops/superstructure/climber/integral_climber_plant.h"
 #include "y2022_bot3/control_loops/superstructure/intake/integral_intake_plant.h"
 
-namespace y2022_bot3 {
-namespace constants {
+namespace y2022_bot3::constants {
 
 const int Values::kZeroingSampleSize;
 
@@ -143,5 +142,4 @@
 
 Values MakeValues() { return MakeValues(aos::network::GetTeamNumber()); }
 
-}  // namespace constants
-}  // namespace y2022_bot3
+}  // namespace y2022_bot3::constants
diff --git a/y2022_bot3/control_loops/drivetrain/drivetrain_base.cc b/y2022_bot3/control_loops/drivetrain/drivetrain_base.cc
index a97e0dd..dc89588 100644
--- a/y2022_bot3/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2022_bot3/control_loops/drivetrain/drivetrain_base.cc
@@ -14,9 +14,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2022_bot3 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2022_bot3::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -66,6 +64,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2022_bot3
+}  // namespace y2022_bot3::control_loops::drivetrain
diff --git a/y2022_bot3/control_loops/superstructure/superstructure.cc b/y2022_bot3/control_loops/superstructure/superstructure.cc
index f701907..3dfa74c 100644
--- a/y2022_bot3/control_loops/superstructure/superstructure.cc
+++ b/y2022_bot3/control_loops/superstructure/superstructure.cc
@@ -4,9 +4,7 @@
 #include "aos/flatbuffer_merge.h"
 #include "frc971/zeroing/wrap.h"
 
-namespace y2022_bot3 {
-namespace control_loops {
-namespace superstructure {
+namespace y2022_bot3::control_loops::superstructure {
 
 using frc971::control_loops::AbsoluteEncoderProfiledJointStatus;
 using frc971::control_loops::PotAndAbsoluteEncoderProfiledJointStatus;
@@ -89,6 +87,4 @@
   (void)status->Send(status_builder.Finish());
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2022_bot3
+}  // namespace y2022_bot3::control_loops::superstructure
diff --git a/y2022_bot3/control_loops/superstructure/superstructure_lib_test.cc b/y2022_bot3/control_loops/superstructure/superstructure_lib_test.cc
index 614bc08..493d2f5 100644
--- a/y2022_bot3/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2022_bot3/control_loops/superstructure/superstructure_lib_test.cc
@@ -15,10 +15,7 @@
 DEFINE_string(output_folder, "",
               "If set, logs all channels to the provided logfile.");
 
-namespace y2022_bot3 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2022_bot3::control_loops::superstructure::testing {
 namespace chrono = std::chrono;
 
 using ::aos::monotonic_clock;
@@ -472,7 +469,4 @@
   TestRoller(0.0);
 }
 
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2022_bot3
\ No newline at end of file
+}  // namespace y2022_bot3::control_loops::superstructure::testing
diff --git a/y2022_bot3/joystick_reader.cc b/y2022_bot3/joystick_reader.cc
index 00a28be..67f8957 100644
--- a/y2022_bot3/joystick_reader.cc
+++ b/y2022_bot3/joystick_reader.cc
@@ -26,9 +26,7 @@
 using frc971::input::driver_station::JoystickAxis;
 using frc971::input::driver_station::POVLocation;
 
-namespace y2022_bot3 {
-namespace input {
-namespace joysticks {
+namespace y2022_bot3::input::joysticks {
 
 namespace superstructure = y2022_bot3::control_loops::superstructure;
 
@@ -101,9 +99,7 @@
   ::aos::Fetcher<superstructure::Status> superstructure_status_fetcher_;
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2022_bot3
+}  // namespace y2022_bot3::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2022_bot3/wpilib_interface.cc b/y2022_bot3/wpilib_interface.cc
index c441f6e..278e869 100644
--- a/y2022_bot3/wpilib_interface.cc
+++ b/y2022_bot3/wpilib_interface.cc
@@ -59,8 +59,7 @@
 namespace chrono = ::std::chrono;
 using std::make_unique;
 
-namespace y2022_bot3 {
-namespace wpilib {
+namespace y2022_bot3::wpilib {
 namespace {
 
 constexpr double kMaxBringupPower = 12.0;
@@ -390,7 +389,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2022_bot3
+}  // namespace y2022_bot3::wpilib
 
 AOS_ROBOT_CLASS(::y2022_bot3::wpilib::WPILibRobot);
diff --git a/y2023/autonomous/auto_splines.cc b/y2023/autonomous/auto_splines.cc
index aa6497c..3607627 100644
--- a/y2023/autonomous/auto_splines.cc
+++ b/y2023/autonomous/auto_splines.cc
@@ -3,8 +3,7 @@
 #include "aos/flatbuffer_merge.h"
 #include "frc971/control_loops/control_loops_generated.h"
 
-namespace y2023 {
-namespace autonomous {
+namespace y2023::autonomous {
 
 namespace {
 flatbuffers::Offset<frc971::MultiSpline> FixSpline(
@@ -202,5 +201,4 @@
   return FixSpline(builder, multispline_builder.Finish(), alliance);
 }
 
-}  // namespace autonomous
-}  // namespace y2023
+}  // namespace y2023::autonomous
diff --git a/y2023/autonomous/autonomous_actor.cc b/y2023/autonomous/autonomous_actor.cc
index e452d21..652fe66 100644
--- a/y2023/autonomous/autonomous_actor.cc
+++ b/y2023/autonomous/autonomous_actor.cc
@@ -17,8 +17,7 @@
 DEFINE_bool(charged_up_cable, false, "If true run cable side autonomous mode");
 DEFINE_bool(do_balance, true, "If true run the balance.");
 
-namespace y2023 {
-namespace autonomous {
+namespace y2023::autonomous {
 
 using ::frc971::ProfileParametersT;
 
@@ -629,5 +628,4 @@
   return true;
 }
 
-}  // namespace autonomous
-}  // namespace y2023
+}  // namespace y2023::autonomous
diff --git a/y2023/constants.cc b/y2023/constants.cc
index 6b63cda..0154453 100644
--- a/y2023/constants.cc
+++ b/y2023/constants.cc
@@ -15,8 +15,7 @@
 #include "y2023/control_loops/superstructure/roll/integral_roll_plant.h"
 #include "y2023/control_loops/superstructure/wrist/integral_wrist_plant.h"
 
-namespace y2023 {
-namespace constants {
+namespace y2023::constants {
 
 Values MakeValues(uint16_t team) {
   LOG(INFO) << "creating a Constants for team: " << team;
@@ -179,5 +178,4 @@
 
 Values MakeValues() { return MakeValues(aos::network::GetTeamNumber()); }
 
-}  // namespace constants
-}  // namespace y2023
+}  // namespace y2023::constants
diff --git a/y2023/control_loops/drivetrain/drivetrain_base.cc b/y2023/control_loops/drivetrain/drivetrain_base.cc
index a11a896..63e7904 100644
--- a/y2023/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2023/control_loops/drivetrain/drivetrain_base.cc
@@ -15,9 +15,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2023 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2023::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -85,6 +83,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2023
+}  // namespace y2023::control_loops::drivetrain
diff --git a/y2023/control_loops/superstructure/arm/arm.cc b/y2023/control_loops/superstructure/arm/arm.cc
index 7144e57..51efc55 100644
--- a/y2023/control_loops/superstructure/arm/arm.cc
+++ b/y2023/control_loops/superstructure/arm/arm.cc
@@ -3,10 +3,7 @@
 #include "y2023/control_loops/superstructure/roll/integral_hybrid_roll_plant.h"
 #include "y2023/control_loops/superstructure/roll/integral_roll_plant.h"
 
-namespace y2023 {
-namespace control_loops {
-namespace superstructure {
-namespace arm {
+namespace y2023::control_loops::superstructure::arm {
 namespace {
 
 namespace chrono = ::std::chrono;
@@ -359,7 +356,4 @@
   return status_builder.Finish();
 }
 
-}  // namespace arm
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2023
+}  // namespace y2023::control_loops::superstructure::arm
diff --git a/y2023/control_loops/superstructure/arm/arm_design.cc b/y2023/control_loops/superstructure/arm/arm_design.cc
index 99ffa2c..e918746 100644
--- a/y2023/control_loops/superstructure/arm/arm_design.cc
+++ b/y2023/control_loops/superstructure/arm/arm_design.cc
@@ -17,10 +17,7 @@
 DEFINE_double(goal0, 0.0, "goal position on proximal");
 DEFINE_double(goal1, 0.0, "goal position on distal");
 
-namespace y2023 {
-namespace control_loops {
-namespace superstructure {
-namespace arm {
+namespace y2023::control_loops::superstructure::arm {
 
 int Main() {
   frc971::analysis::Plotter plotter;
@@ -182,10 +179,7 @@
   return 0;
 }
 
-}  // namespace arm
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2023
+}  // namespace y2023::control_loops::superstructure::arm
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2023/control_loops/superstructure/arm/trajectory.cc b/y2023/control_loops/superstructure/arm/trajectory.cc
index cbdfee8..be339e4 100644
--- a/y2023/control_loops/superstructure/arm/trajectory.cc
+++ b/y2023/control_loops/superstructure/arm/trajectory.cc
@@ -15,10 +15,7 @@
 DEFINE_double(lqr_distal_pos, 0.5, "Position LQR gain");
 DEFINE_double(lqr_distal_vel, 5, "Velocity LQR gain");
 
-namespace y2023 {
-namespace control_loops {
-namespace superstructure {
-namespace arm {
+namespace y2023::control_loops::superstructure::arm {
 
 ::Eigen::Matrix<double, 3, 1> CosSpline::Theta(double alpha) const {
   ::Eigen::Matrix<double, 3, 1> result;
@@ -1005,7 +1002,4 @@
   omega_ = trajectory_->OmegaT(goal_(0), goal_(1));
 }
 
-}  // namespace arm
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2023
+}  // namespace y2023::control_loops::superstructure::arm
diff --git a/y2023/control_loops/superstructure/arm/trajectory_plot.cc b/y2023/control_loops/superstructure/arm/trajectory_plot.cc
index 16c8771..4db5080 100644
--- a/y2023/control_loops/superstructure/arm/trajectory_plot.cc
+++ b/y2023/control_loops/superstructure/arm/trajectory_plot.cc
@@ -23,10 +23,7 @@
 DEFINE_double(vmax_battery, 12.0, "Max battery voltage.");
 DEFINE_double(time, 2.0, "Simulation time.");
 
-namespace y2023 {
-namespace control_loops {
-namespace superstructure {
-namespace arm {
+namespace y2023::control_loops::superstructure::arm {
 using frc971::control_loops::MatrixGaussianQuadrature5;
 
 void Main() {
@@ -545,10 +542,7 @@
   }
 }
 
-}  // namespace arm
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2023
+}  // namespace y2023::control_loops::superstructure::arm
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2023/control_loops/superstructure/arm/trajectory_test.cc b/y2023/control_loops/superstructure/arm/trajectory_test.cc
index 8af7ba7..666a702 100644
--- a/y2023/control_loops/superstructure/arm/trajectory_test.cc
+++ b/y2023/control_loops/superstructure/arm/trajectory_test.cc
@@ -8,11 +8,7 @@
 #include "y2023/control_loops/superstructure/roll/integral_hybrid_roll_plant.h"
 #include "y2023/control_loops/superstructure/roll/integral_roll_plant.h"
 
-namespace y2023 {
-namespace control_loops {
-namespace superstructure {
-namespace arm {
-namespace testing {
+namespace y2023::control_loops::superstructure::arm::testing {
 
 using frc971::control_loops::MatrixGaussianQuadrature5;
 using frc971::control_loops::arm::Dynamics;
@@ -226,8 +222,4 @@
       final_theta_t.isApprox(trajectory.path().Theta(follower.goal(0))));
 }
 
-}  // namespace testing
-}  // namespace arm
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2023
+}  // namespace y2023::control_loops::superstructure::arm::testing
diff --git a/y2023/control_loops/superstructure/end_effector.cc b/y2023/control_loops/superstructure/end_effector.cc
index 43f3d24..2f01128 100644
--- a/y2023/control_loops/superstructure/end_effector.cc
+++ b/y2023/control_loops/superstructure/end_effector.cc
@@ -5,9 +5,7 @@
 #include "frc971/control_loops/control_loop.h"
 #include "y2023/vision/game_pieces_generated.h"
 
-namespace y2023 {
-namespace control_loops {
-namespace superstructure {
+namespace y2023::control_loops::superstructure {
 
 using ::aos::monotonic_clock;
 
@@ -147,6 +145,4 @@
 
 void EndEffector::Reset() { state_ = EndEffectorState::IDLE; }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2023
+}  // namespace y2023::control_loops::superstructure
diff --git a/y2023/control_loops/superstructure/superstructure.cc b/y2023/control_loops/superstructure/superstructure.cc
index 4919cd6..e11092a 100644
--- a/y2023/control_loops/superstructure/superstructure.cc
+++ b/y2023/control_loops/superstructure/superstructure.cc
@@ -10,9 +10,7 @@
 DEFINE_bool(ignore_distance, false,
             "If true, ignore distance when shooting and obay joystick_reader");
 
-namespace y2023 {
-namespace control_loops {
-namespace superstructure {
+namespace y2023::control_loops::superstructure {
 
 using ::aos::monotonic_clock;
 
@@ -148,6 +146,4 @@
                                               y2);
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2023
+}  // namespace y2023::control_loops::superstructure
diff --git a/y2023/control_loops/superstructure/superstructure_lib_test.cc b/y2023/control_loops/superstructure/superstructure_lib_test.cc
index 926846e..d4fa653 100644
--- a/y2023/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2023/control_loops/superstructure/superstructure_lib_test.cc
@@ -18,10 +18,7 @@
 DEFINE_string(output_folder, "",
               "If set, logs all channels to the provided logfile.");
 
-namespace y2023 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2023::control_loops::superstructure::testing {
 namespace {
 constexpr double kNoiseScalar = 0.01;
 }  // namespace
@@ -926,7 +923,4 @@
 INSTANTIATE_TEST_SUITE_P(EndEffectorGoal, SuperstructureBeambreakTest,
                          ::testing::Values(vision::Class::CUBE));
 
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2023
+}  // namespace y2023::control_loops::superstructure::testing
diff --git a/y2023/joystick_reader.cc b/y2023/joystick_reader.cc
index f4d9ea6..45418bc 100644
--- a/y2023/joystick_reader.cc
+++ b/y2023/joystick_reader.cc
@@ -39,9 +39,7 @@
 using y2023::control_loops::superstructure::RollerGoal;
 using Side = frc971::control_loops::drivetrain::RobotSide;
 
-namespace y2023 {
-namespace input {
-namespace joysticks {
+namespace y2023::input::joysticks {
 
 constexpr double kConeWrist = 0.4;
 constexpr double kCubeWrist = 1.0;
@@ -562,9 +560,7 @@
   const ArmSetpoint *current_setpoint_ = nullptr;
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2023
+}  // namespace y2023::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2023/tof_controller/tof_controller.cc b/y2023/tof_controller/tof_controller.cc
index f8e8fb9..80102ae 100644
--- a/y2023/tof_controller/tof_controller.cc
+++ b/y2023/tof_controller/tof_controller.cc
@@ -13,8 +13,7 @@
 #include "pico/bootrom.h"
 #include "pico/stdlib.h"
 
-namespace y2023 {
-namespace tof_controller {
+namespace y2023::tof_controller {
 
 static constexpr uint kI2CBaudrate = 100000;
 static constexpr uint16_t kExpectedSensorId = 0xEBAA;
@@ -500,7 +499,6 @@
   }
 }
 
-}  // namespace tof_controller
-}  // namespace y2023
+}  // namespace y2023::tof_controller
 
 int main() { y2023::tof_controller::main(); }
diff --git a/y2023/vision/april_generator.cc b/y2023/vision/april_generator.cc
index 4ac389a..3746474 100644
--- a/y2023/vision/april_generator.cc
+++ b/y2023/vision/april_generator.cc
@@ -14,8 +14,7 @@
 // https://halide-lang.org/tutorials/tutorial_lesson_15_generators.html has an
 // introduction to much of the magic in this file.
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace {
 
 // Returns a function implementating a 1-dimensional gaussian blur convolution.
@@ -147,8 +146,7 @@
   }
 };
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
 
 // TODO(austin): Combine the functions and optimize for device/host and all that
 // jazz.
diff --git a/y2023/vision/aprilrobotics.cc b/y2023/vision/aprilrobotics.cc
index f2e2592..0605eb2 100644
--- a/y2023/vision/aprilrobotics.cc
+++ b/y2023/vision/aprilrobotics.cc
@@ -20,8 +20,7 @@
 DEFINE_uint64(pose_estimation_iterations, 50,
               "Number of iterations for apriltag pose estimation.");
 
-namespace y2023 {
-namespace vision {
+namespace y2023::vision {
 
 namespace chrono = std::chrono;
 
@@ -374,5 +373,4 @@
   return {.detections = results, .rejections = rejections_};
 }
 
-}  // namespace vision
-}  // namespace y2023
+}  // namespace y2023::vision
diff --git a/y2023/vision/calibrate_extrinsics.cc b/y2023/vision/calibrate_extrinsics.cc
index 91bdefd..f0a0d71 100644
--- a/y2023/vision/calibrate_extrinsics.cc
+++ b/y2023/vision/calibrate_extrinsics.cc
@@ -31,8 +31,7 @@
               "Output json file to use for the resulting calibration "
               "(intrinsics and extrinsics).");
 
-namespace frc971 {
-namespace vision {
+namespace frc971::vision {
 namespace chrono = std::chrono;
 using aos::distributed_clock;
 using aos::monotonic_clock;
@@ -306,8 +305,7 @@
   }
 }  // namespace vision
 
-}  // namespace vision
-}  // namespace frc971
+}  // namespace frc971::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2023/vision/calibrate_multi_cameras.cc b/y2023/vision/calibrate_multi_cameras.cc
index d3cfa6f..48dffb9 100644
--- a/y2023/vision/calibrate_multi_cameras.cc
+++ b/y2023/vision/calibrate_multi_cameras.cc
@@ -67,8 +67,7 @@
 // estimation, and probably also include camera->imu extrinsics from all
 // cameras, not just pi1
 
-namespace y2023 {
-namespace vision {
+namespace y2023::vision {
 using frc971::vision::DataAdapter;
 using frc971::vision::ImageCallback;
 using frc971::vision::PoseUtils;
@@ -699,8 +698,7 @@
     delete image_callbacks[i];
   }
 }
-}  // namespace vision
-}  // namespace y2023
+}  // namespace y2023::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2023/vision/camera_reader.cc b/y2023/vision/camera_reader.cc
index d5f39a0..abffac0 100644
--- a/y2023/vision/camera_reader.cc
+++ b/y2023/vision/camera_reader.cc
@@ -22,8 +22,7 @@
 DEFINE_bool(send_downsized_images, false,
             "Whether to send downsized image for driver cam streaming.");
 
-namespace y2023 {
-namespace vision {
+namespace y2023::vision {
 namespace {
 
 using namespace frc971::vision;
@@ -202,8 +201,7 @@
 }
 
 }  // namespace
-}  // namespace vision
-}  // namespace y2023
+}  // namespace y2023::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2023/vision/ccm.cc b/y2023/vision/ccm.cc
index 7f35ae5..d32cc2f 100644
--- a/y2023/vision/ccm.cc
+++ b/y2023/vision/ccm.cc
@@ -8,8 +8,7 @@
 #include "aos/init.h"
 #include "aos/time/time.h"
 
-namespace y2023 {
-namespace vision {
+namespace y2023::vision {
 namespace {
 
 // Adapted from the opencv example code for color calibration.
@@ -73,8 +72,7 @@
 }
 
 }  // namespace
-}  // namespace vision
-}  // namespace y2023
+}  // namespace y2023::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2023/vision/game_pieces.cc b/y2023/vision/game_pieces.cc
index 8a0621d..68ff160 100644
--- a/y2023/vision/game_pieces.cc
+++ b/y2023/vision/game_pieces.cc
@@ -7,8 +7,7 @@
 #include "frc971/vision/vision_generated.h"
 #include "y2023/vision/yolov5.h"
 
-namespace y2023 {
-namespace vision {
+namespace y2023::vision {
 using aos::monotonic_clock;
 GamePiecesDetector::GamePiecesDetector(aos::EventLoop *event_loop)
     : game_pieces_sender_(event_loop->MakeSender<GamePieces>("/camera")) {
@@ -73,5 +72,4 @@
   builder.CheckOk(builder.Send(game_pieces_builder.Finish()));
 }
 
-}  // namespace vision
-}  // namespace y2023
+}  // namespace y2023::vision
diff --git a/y2023/vision/game_pieces_main.cc b/y2023/vision/game_pieces_main.cc
index 97940b6..b4ceff5 100644
--- a/y2023/vision/game_pieces_main.cc
+++ b/y2023/vision/game_pieces_main.cc
@@ -4,8 +4,7 @@
 
 DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
 
-namespace y2023 {
-namespace vision {
+namespace y2023::vision {
 namespace {
 
 void GamePiecesDetectorMain() {
@@ -16,8 +15,7 @@
   event_loop.Run();
 }
 }  // namespace
-}  // namespace vision
-}  // namespace y2023
+}  // namespace y2023::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2023/vision/target_mapping.cc b/y2023/vision/target_mapping.cc
index 83705b9..af4c36c 100644
--- a/y2023/vision/target_mapping.cc
+++ b/y2023/vision/target_mapping.cc
@@ -58,8 +58,7 @@
 DECLARE_int32(max_target_id);
 DECLARE_bool(visualize_solver);
 
-namespace y2023 {
-namespace vision {
+namespace y2023::vision {
 using frc971::vision::DataAdapter;
 using frc971::vision::ImageCallback;
 using frc971::vision::PoseUtils;
@@ -430,8 +429,7 @@
   mapper_replay.MaybeSolve();
 }
 
-}  // namespace vision
-}  // namespace y2023
+}  // namespace y2023::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2023/vision/viewer.cc b/y2023/vision/viewer.cc
index e03680c..78731e5 100644
--- a/y2023/vision/viewer.cc
+++ b/y2023/vision/viewer.cc
@@ -18,8 +18,7 @@
 DEFINE_int32(rate, 100, "Time in milliseconds to wait between images");
 DEFINE_double(scale, 1.0, "Scale factor for images being displayed");
 
-namespace y2023 {
-namespace vision {
+namespace y2023::vision {
 namespace {
 
 using frc971::vision::CameraImage;
@@ -108,8 +107,7 @@
 }
 
 }  // namespace
-}  // namespace vision
-}  // namespace y2023
+}  // namespace y2023::vision
 
 int main(int argc, char **argv) {
   aos::InitGoogle(&argc, &argv);
diff --git a/y2023/vision/yolov5.cc b/y2023/vision/yolov5.cc
index ba2a9f7..e62b106 100644
--- a/y2023/vision/yolov5.cc
+++ b/y2023/vision/yolov5.cc
@@ -30,8 +30,7 @@
 
 DEFINE_bool(visualize_detections, false, "Display inference output");
 
-namespace y2023 {
-namespace vision {
+namespace y2023::vision {
 
 class YOLOV5Impl : public YOLOV5 {
  public:
@@ -303,5 +302,4 @@
   return filtered_detections;
 };
 
-}  // namespace vision
-}  // namespace y2023
+}  // namespace y2023::vision
diff --git a/y2023/wpilib_interface.cc b/y2023/wpilib_interface.cc
index 3bf6027..8438281 100644
--- a/y2023/wpilib_interface.cc
+++ b/y2023/wpilib_interface.cc
@@ -72,8 +72,7 @@
 namespace chrono = ::std::chrono;
 using std::make_unique;
 
-namespace y2023 {
-namespace wpilib {
+namespace y2023::wpilib {
 namespace {
 
 constexpr double kMaxBringupPower = 12.0;
@@ -1058,7 +1057,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2023
+}  // namespace y2023::wpilib
 
 AOS_ROBOT_CLASS(::y2023::wpilib::WPILibRobot);
diff --git a/y2023_bot3/autonomous/auto_splines.cc b/y2023_bot3/autonomous/auto_splines.cc
index 25277e9..b0577bf 100644
--- a/y2023_bot3/autonomous/auto_splines.cc
+++ b/y2023_bot3/autonomous/auto_splines.cc
@@ -3,8 +3,7 @@
 #include "aos/flatbuffer_merge.h"
 #include "frc971/control_loops/control_loops_generated.h"
 
-namespace y2023_bot3 {
-namespace autonomous {
+namespace y2023_bot3::autonomous {
 
 namespace {
 flatbuffers::Offset<frc971::MultiSpline> FixSpline(
@@ -172,5 +171,4 @@
   return FixSpline(builder, multispline_builder.Finish(), alliance);
 }
 
-}  // namespace autonomous
-}  // namespace y2023_bot3
+}  // namespace y2023_bot3::autonomous
diff --git a/y2023_bot3/autonomous/autonomous_actor.cc b/y2023_bot3/autonomous/autonomous_actor.cc
index 7c722be..61811d7 100644
--- a/y2023_bot3/autonomous/autonomous_actor.cc
+++ b/y2023_bot3/autonomous/autonomous_actor.cc
@@ -20,8 +20,7 @@
 DEFINE_bool(one_piece, false,
             "End charged_up autonomous after first cube is placed.");
 
-namespace y2023_bot3 {
-namespace autonomous {
+namespace y2023_bot3::autonomous {
 
 using ::frc971::ProfileParametersT;
 
@@ -287,5 +286,4 @@
   }
 }
 
-}  // namespace autonomous
-}  // namespace y2023_bot3
+}  // namespace y2023_bot3::autonomous
diff --git a/y2023_bot3/constants.cc b/y2023_bot3/constants.cc
index 7f77d4d..be9ddbf 100644
--- a/y2023_bot3/constants.cc
+++ b/y2023_bot3/constants.cc
@@ -13,8 +13,7 @@
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
 
-namespace y2023_bot3 {
-namespace constants {
+namespace y2023_bot3::constants {
 
 Values MakeValues(uint16_t team) {
   LOG(INFO) << "creating a Constants for team: " << team;
@@ -38,5 +37,4 @@
 
 Values MakeValues() { return MakeValues(aos::network::GetTeamNumber()); }
 
-}  // namespace constants
-}  // namespace y2023_bot3
+}  // namespace y2023_bot3::constants
diff --git a/y2023_bot3/control_loops/drivetrain/drivetrain_base.cc b/y2023_bot3/control_loops/drivetrain/drivetrain_base.cc
index 5b30097..481cab0 100644
--- a/y2023_bot3/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2023_bot3/control_loops/drivetrain/drivetrain_base.cc
@@ -15,9 +15,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2023_bot3 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2023_bot3::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -85,6 +83,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2023_bot3
+}  // namespace y2023_bot3::control_loops::drivetrain
diff --git a/y2023_bot3/control_loops/superstructure/superstructure.cc b/y2023_bot3/control_loops/superstructure/superstructure.cc
index e77245e..b730ffa 100644
--- a/y2023_bot3/control_loops/superstructure/superstructure.cc
+++ b/y2023_bot3/control_loops/superstructure/superstructure.cc
@@ -9,9 +9,7 @@
 DEFINE_bool(ignore_distance, false,
             "If true, ignore distance when shooting and obay joystick_reader");
 
-namespace y2023_bot3 {
-namespace control_loops {
-namespace superstructure {
+namespace y2023_bot3::control_loops::superstructure {
 
 using ::aos::monotonic_clock;
 
@@ -51,6 +49,4 @@
   (void)status->Send(status_builder.Finish());
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2023_bot3
+}  // namespace y2023_bot3::control_loops::superstructure
diff --git a/y2023_bot3/control_loops/superstructure/superstructure_lib_test.cc b/y2023_bot3/control_loops/superstructure/superstructure_lib_test.cc
index 370ec17..d9c9d15 100644
--- a/y2023_bot3/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2023_bot3/control_loops/superstructure/superstructure_lib_test.cc
@@ -16,10 +16,7 @@
 DEFINE_string(output_folder, "",
               "If set, logs all channels to the provided logfile.");
 
-namespace y2023_bot3 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2023_bot3::control_loops::superstructure::testing {
 namespace {}  // namespace
 namespace chrono = std::chrono;
 
@@ -260,7 +257,4 @@
   VerifyNearGoal();
 }
 
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2023_bot3
+}  // namespace y2023_bot3::control_loops::superstructure::testing
diff --git a/y2023_bot3/joystick_reader.cc b/y2023_bot3/joystick_reader.cc
index 4c42bdc..9516d70 100644
--- a/y2023_bot3/joystick_reader.cc
+++ b/y2023_bot3/joystick_reader.cc
@@ -32,9 +32,7 @@
 using frc971::input::driver_station::POVLocation;
 using Side = frc971::control_loops::drivetrain::RobotSide;
 
-namespace y2023_bot3 {
-namespace input {
-namespace joysticks {
+namespace y2023_bot3::input::joysticks {
 
 namespace superstructure = y2023_bot3::control_loops::superstructure;
 
@@ -101,9 +99,7 @@
   ::aos::Fetcher<superstructure::Status> superstructure_status_fetcher_;
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2023_bot3
+}  // namespace y2023_bot3::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2023_bot3/wpilib_interface.cc b/y2023_bot3/wpilib_interface.cc
index 231f2c6..443fabd 100644
--- a/y2023_bot3/wpilib_interface.cc
+++ b/y2023_bot3/wpilib_interface.cc
@@ -71,8 +71,7 @@
 namespace chrono = ::std::chrono;
 using std::make_unique;
 
-namespace y2023_bot3 {
-namespace wpilib {
+namespace y2023_bot3::wpilib {
 namespace {
 
 constexpr double kMaxBringupPower = 12.0;
@@ -674,7 +673,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2023_bot3
+}  // namespace y2023_bot3::wpilib
 
 AOS_ROBOT_CLASS(::y2023_bot3::wpilib::WPILibRobot);
diff --git a/y2023_bot4/constants.cc b/y2023_bot4/constants.cc
index aab1935..701308d 100644
--- a/y2023_bot4/constants.cc
+++ b/y2023_bot4/constants.cc
@@ -6,8 +6,7 @@
 
 #include "aos/network/team_number.h"
 
-namespace y2023_bot4 {
-namespace constants {
+namespace y2023_bot4::constants {
 Values MakeValues(uint16_t team) {
   LOG(INFO) << "creating a Constants for team: " << team;
   Values r;
@@ -48,5 +47,4 @@
 }
 
 Values MakeValues() { return MakeValues(aos::network::GetTeamNumber()); }
-}  // namespace constants
-}  // namespace y2023_bot4
+}  // namespace y2023_bot4::constants
diff --git a/y2023_bot4/swerve_publisher_lib_test.cc b/y2023_bot4/swerve_publisher_lib_test.cc
index 817f295..e834659 100644
--- a/y2023_bot4/swerve_publisher_lib_test.cc
+++ b/y2023_bot4/swerve_publisher_lib_test.cc
@@ -4,8 +4,7 @@
 
 #include "aos/events/simulated_event_loop.h"
 
-namespace y2023_bot4 {
-namespace testing {
+namespace y2023_bot4::testing {
 class SwervePublisherTest : public ::testing::Test {
  public:
   SwervePublisherTest()
@@ -50,5 +49,4 @@
   SendOutput();
   CheckOutput();
 }
-}  // namespace testing
-}  // namespace y2023_bot4
+}  // namespace y2023_bot4::testing
diff --git a/y2023_bot4/wpilib_interface.cc b/y2023_bot4/wpilib_interface.cc
index 9dd3604..e5b5a6f 100644
--- a/y2023_bot4/wpilib_interface.cc
+++ b/y2023_bot4/wpilib_interface.cc
@@ -24,8 +24,7 @@
 
 namespace drivetrain = frc971::control_loops::drivetrain;
 
-namespace y2023_bot4 {
-namespace wpilib {
+namespace y2023_bot4::wpilib {
 namespace {
 
 template <class T>
@@ -304,7 +303,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2023_bot4
+}  // namespace y2023_bot4::wpilib
 
 AOS_ROBOT_CLASS(::y2023_bot4::wpilib::WPILibRobot)
diff --git a/y2024/autonomous/auto_splines.cc b/y2024/autonomous/auto_splines.cc
index d2bd3a1..5d2c10f 100644
--- a/y2024/autonomous/auto_splines.cc
+++ b/y2024/autonomous/auto_splines.cc
@@ -3,8 +3,7 @@
 #include "aos/flatbuffer_merge.h"
 #include "frc971/control_loops/control_loops_generated.h"
 
-namespace y2024 {
-namespace autonomous {
+namespace y2024::autonomous {
 
 namespace {
 flatbuffers::Offset<frc971::MultiSpline> FixSpline(
@@ -122,5 +121,4 @@
   return FixSpline(builder, multispline_builder.Finish(), alliance);
 }
 
-}  // namespace autonomous
-}  // namespace y2024
+}  // namespace y2024::autonomous
diff --git a/y2024/autonomous/autonomous_actor.cc b/y2024/autonomous/autonomous_actor.cc
index fd42a56..a7c656d 100644
--- a/y2024/autonomous/autonomous_actor.cc
+++ b/y2024/autonomous/autonomous_actor.cc
@@ -13,8 +13,7 @@
 
 DEFINE_bool(spline_auto, false, "Run simple test S-spline auto mode.");
 
-namespace y2024 {
-namespace autonomous {
+namespace y2024::autonomous {
 
 using ::frc971::ProfileParametersT;
 
@@ -192,5 +191,4 @@
     AOS_LOG(ERROR, "Failed to reset localizer.\n");
   }
 }
-}  // namespace autonomous
-}  // namespace y2024
+}  // namespace y2024::autonomous
diff --git a/y2024/constants.cc b/y2024/constants.cc
index cdaf28c..a347353 100644
--- a/y2024/constants.cc
+++ b/y2024/constants.cc
@@ -13,8 +13,7 @@
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
 
-namespace y2024 {
-namespace constants {
+namespace y2024::constants {
 
 Values MakeValues(uint16_t team) {
   LOG(INFO) << "creating a Constants for team: " << team;
@@ -46,5 +45,4 @@
 
 Values MakeValues() { return MakeValues(aos::network::GetTeamNumber()); }
 
-}  // namespace constants
-}  // namespace y2024
+}  // namespace y2024::constants
diff --git a/y2024/control_loops/drivetrain/drivetrain_base.cc b/y2024/control_loops/drivetrain/drivetrain_base.cc
index 88b74f9..325dae8 100644
--- a/y2024/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2024/control_loops/drivetrain/drivetrain_base.cc
@@ -15,9 +15,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2024 {
-namespace control_loops {
-namespace drivetrain {
+namespace y2024::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -85,6 +83,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2024
+}  // namespace y2024::control_loops::drivetrain
diff --git a/y2024/control_loops/superstructure/superstructure.cc b/y2024/control_loops/superstructure/superstructure.cc
index abb5536..bb89021 100644
--- a/y2024/control_loops/superstructure/superstructure.cc
+++ b/y2024/control_loops/superstructure/superstructure.cc
@@ -9,9 +9,7 @@
 DEFINE_bool(ignore_distance, false,
             "If true, ignore distance when shooting and obay joystick_reader");
 
-namespace y2024 {
-namespace control_loops {
-namespace superstructure {
+namespace y2024::control_loops::superstructure {
 
 using ::aos::monotonic_clock;
 
@@ -73,6 +71,4 @@
               : 0.0);
 }
 
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2024
\ No newline at end of file
+}  // namespace y2024::control_loops::superstructure
diff --git a/y2024/control_loops/superstructure/superstructure_lib_test.cc b/y2024/control_loops/superstructure/superstructure_lib_test.cc
index 85e16b2..bcda3ae 100644
--- a/y2024/control_loops/superstructure/superstructure_lib_test.cc
+++ b/y2024/control_loops/superstructure/superstructure_lib_test.cc
@@ -17,10 +17,7 @@
 DEFINE_string(output_folder, "",
               "If set, logs all channels to the provided logfile.");
 
-namespace y2024 {
-namespace control_loops {
-namespace superstructure {
-namespace testing {
+namespace y2024::control_loops::superstructure::testing {
 
 namespace chrono = std::chrono;
 
@@ -281,7 +278,4 @@
   RunFor(chrono::seconds(2));
   CheckIfZeroed();
 }
-}  // namespace testing
-}  // namespace superstructure
-}  // namespace control_loops
-}  // namespace y2024
+}  // namespace y2024::control_loops::superstructure::testing
diff --git a/y2024/joystick_reader.cc b/y2024/joystick_reader.cc
index ebc2485..d30e1f5 100644
--- a/y2024/joystick_reader.cc
+++ b/y2024/joystick_reader.cc
@@ -30,9 +30,7 @@
 using frc971::input::driver_station::POVLocation;
 using Side = frc971::control_loops::drivetrain::RobotSide;
 
-namespace y2024 {
-namespace input {
-namespace joysticks {
+namespace y2024::input::joysticks {
 
 class Reader : public ::frc971::input::ActionJoystickInput {
  public:
@@ -68,9 +66,7 @@
       superstructure_status_fetcher_;
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2024
+}  // namespace y2024::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2024/wpilib_interface.cc b/y2024/wpilib_interface.cc
index 8c1cfd3..94d62ce 100644
--- a/y2024/wpilib_interface.cc
+++ b/y2024/wpilib_interface.cc
@@ -71,8 +71,7 @@
 namespace chrono = ::std::chrono;
 using std::make_unique;
 
-namespace y2024 {
-namespace wpilib {
+namespace y2024::wpilib {
 namespace {
 
 constexpr double kMaxBringupPower = 12.0;
@@ -286,7 +285,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2024
+}  // namespace y2024::wpilib
 
 AOS_ROBOT_CLASS(::y2024::wpilib::WPILibRobot);
diff --git a/y2024_defense/constants.cc b/y2024_defense/constants.cc
index fa7a14c..31b3ae3 100644
--- a/y2024_defense/constants.cc
+++ b/y2024_defense/constants.cc
@@ -13,8 +13,7 @@
 #include "aos/mutex/mutex.h"
 #include "aos/network/team_number.h"
 
-namespace y2024_defense {
-namespace constants {
+namespace y2024_defense::constants {
 
 Values MakeValues(uint16_t team) {
   LOG(INFO) << "creating a Constants for team: " << team;
@@ -26,5 +25,4 @@
 
 Values MakeValues() { return MakeValues(aos::network::GetTeamNumber()); }
 
-}  // namespace constants
-}  // namespace y2024_defense
+}  // namespace y2024_defense::constants
diff --git a/y2024_defense/control_loops/drivetrain/drivetrain_base.cc b/y2024_defense/control_loops/drivetrain/drivetrain_base.cc
index 5d14833..2f33e35 100644
--- a/y2024_defense/control_loops/drivetrain/drivetrain_base.cc
+++ b/y2024_defense/control_loops/drivetrain/drivetrain_base.cc
@@ -15,9 +15,7 @@
 
 namespace chrono = ::std::chrono;
 
-namespace y2024_defense {
-namespace control_loops {
-namespace drivetrain {
+namespace y2024_defense::control_loops::drivetrain {
 
 using ::frc971::constants::ShifterHallEffect;
 
@@ -85,6 +83,4 @@
   return kDrivetrainConfig;
 };
 
-}  // namespace drivetrain
-}  // namespace control_loops
-}  // namespace y2024_defense
+}  // namespace y2024_defense::control_loops::drivetrain
diff --git a/y2024_defense/joystick_reader.cc b/y2024_defense/joystick_reader.cc
index 8c3115b..5eeb864 100644
--- a/y2024_defense/joystick_reader.cc
+++ b/y2024_defense/joystick_reader.cc
@@ -23,9 +23,7 @@
 
 using Side = frc971::control_loops::drivetrain::RobotSide;
 
-namespace y2024_defense {
-namespace input {
-namespace joysticks {
+namespace y2024_defense::input::joysticks {
 
 class Reader : public ::frc971::input::ActionJoystickInput {
  public:
@@ -46,9 +44,7 @@
   }
 };
 
-}  // namespace joysticks
-}  // namespace input
-}  // namespace y2024_defense
+}  // namespace y2024_defense::input::joysticks
 
 int main(int argc, char **argv) {
   ::aos::InitGoogle(&argc, &argv);
diff --git a/y2024_defense/wpilib_interface.cc b/y2024_defense/wpilib_interface.cc
index d599813..1584dbd 100644
--- a/y2024_defense/wpilib_interface.cc
+++ b/y2024_defense/wpilib_interface.cc
@@ -74,8 +74,7 @@
 
 using std::make_unique;
 
-namespace y2024_defense {
-namespace wpilib {
+namespace y2024_defense::wpilib {
 namespace {
 
 constexpr double kMaxBringupPower = 12.0;
@@ -361,7 +360,6 @@
   }
 };
 
-}  // namespace wpilib
-}  // namespace y2024_defense
+}  // namespace y2024_defense::wpilib
 
 AOS_ROBOT_CLASS(::y2024_defense::wpilib::WPILibRobot);