Merge "Add aos_dump autocomplete script"
diff --git a/aos/BUILD b/aos/BUILD
index 0129187..243e7f3 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -483,6 +483,21 @@
],
)
+cc_binary(
+ name = "aos_graph_nodes",
+ srcs = [
+ "aos_graph_nodes.cc",
+ ],
+ visibility = ["//visibility:public"],
+ deps = [
+ ":configuration",
+ ":json_to_flatbuffer",
+ "//aos:init",
+ "//aos/events:shm_event_loop",
+ "@com_github_google_glog//:glog",
+ ],
+)
+
cc_library(
name = "ftrace",
srcs = [
diff --git a/aos/aos_graph_nodes.cc b/aos/aos_graph_nodes.cc
new file mode 100644
index 0000000..952c6b5
--- /dev/null
+++ b/aos/aos_graph_nodes.cc
@@ -0,0 +1,108 @@
+#include <iostream>
+#include <map>
+
+#include "aos/configuration.h"
+#include "aos/events/shm_event_loop.h"
+#include "aos/init.h"
+#include "aos/json_to_flatbuffer.h"
+#include "gflags/gflags.h"
+
+DEFINE_bool(all, false,
+ "If true, print out the channels for all nodes in the config file, "
+ "not just the channels which are visible on this node.");
+DEFINE_string(config, "./config.json", "File path of aos configuration");
+DEFINE_bool(short_types, true,
+ "Whether to show a shortened version of the type name");
+
+int main(int argc, char **argv) {
+ gflags::SetUsageMessage(
+ "\nCreates graph of nodes and message channels based on the robot config "
+ "file. \n\n"
+ "To save to file, run as: \n"
+ "\t aos_graph_nodes > /tmp/graph.dot\n\n"
+ "To display graph, run as: \n"
+ "\t aos_graph_nodes | dot -Tx11");
+ aos::InitGoogle(&argc, &argv);
+
+ // Cycle through this list of colors-- here's some defaults.
+ // Can use color names or Hex values of RGB, e.g., red = "#FF0000"
+ std::vector<std::string> color_list = {"red", "blue", "orange", "green",
+ "violet", "gold3", "magenta"};
+ int color_index = 0;
+
+ std::string channel_name;
+ std::string message_type;
+
+ // Map from source nodes to color for them
+ std::map<std::string, std::string> color_map;
+
+ if (argc > 1) {
+ LOG(ERROR) << "ERROR: Got unexpected arguments\n\n";
+ gflags::ShowUsageWithFlagsRestrict(argv[0], "aos/aos_graph_nodes.cc");
+ return -1;
+ }
+
+ aos::FlatbufferDetachedBuffer<aos::Configuration> config =
+ aos::configuration::ReadConfig(FLAGS_config);
+
+ const aos::Configuration *config_msg = &config.message();
+ aos::ShmEventLoop event_loop(config_msg);
+ event_loop.SkipTimingReport();
+ event_loop.SkipAosLog();
+
+ // Open output file and print header
+ std::stringstream graph_out;
+ graph_out << "digraph g {" << std::endl;
+
+ for (const aos::Channel *channel : *config_msg->channels()) {
+ VLOG(1) << "Found channel " << channel->type()->string_view();
+ if (FLAGS_all || aos::configuration::ChannelIsReadableOnNode(
+ channel, event_loop.node())) {
+ flatbuffers::string_view type_name = channel->type()->string_view();
+ if (FLAGS_short_types) {
+ // Strip down to just the top level of the message type
+ type_name = channel->type()->string_view().substr(
+ channel->type()->string_view().rfind(".") + 1, std::string::npos);
+ }
+
+ VLOG(1) << "Found: " << channel->name()->string_view() << ' '
+ << channel->type()->string_view();
+
+ CHECK(channel->has_source_node())
+ << ": Could not find source node for channel "
+ << channel->type()->string_view();
+ std::string source_node_name = channel->source_node()->c_str();
+ VLOG(1) << "Source node name:" << channel->source_node()->c_str();
+
+ // If we haven't seen this node yet, add to our list, with new color
+ if (color_map.count(source_node_name) == 0) {
+ color_map[source_node_name] = color_list[color_index];
+ color_index = (color_index + 1) % color_list.size();
+ }
+
+ if (channel->has_destination_nodes()) {
+ for (const aos::Connection *connection :
+ *channel->destination_nodes()) {
+ VLOG(1) << "Destination Node: " << connection->name()->string_view();
+ graph_out << "\t" << source_node_name << " -> "
+ << connection->name()->c_str() << " [label=\""
+ << channel->name()->c_str() << "\\n"
+ << type_name << "\" color=\"" << color_map[source_node_name]
+ << "\"];" << std::endl;
+ }
+ }
+ }
+ }
+
+ // Write out all the nodes at the end, with their respective colors
+ for (const auto node_color : color_map) {
+ graph_out << "\t" << node_color.first << " [color=\"" << node_color.second
+ << "\"];" << std::endl;
+ }
+
+ // Close out the file
+ graph_out << "}" << std::endl;
+
+ std::cout << graph_out.str();
+ return 0;
+}
diff --git a/aos/dump_rtprio.cc b/aos/dump_rtprio.cc
index 5f4397f..006b348 100644
--- a/aos/dump_rtprio.cc
+++ b/aos/dump_rtprio.cc
@@ -247,8 +247,6 @@
} // namespace
int main() {
- ::aos::logging::Init();
-
const int pid_max = find_pid_max();
const cpu_set_t all_cpus = find_all_cpus();
diff --git a/aos/events/event_loop.cc b/aos/events/event_loop.cc
index 639e337..5c0b628 100644
--- a/aos/events/event_loop.cc
+++ b/aos/events/event_loop.cc
@@ -81,9 +81,7 @@
EventLoop::EventLoop(const Configuration *configuration)
: timing_report_(flatbuffers::DetachedBuffer()),
- configuration_(configuration) {
- logging::Init();
-}
+ configuration_(configuration) {}
EventLoop::~EventLoop() {
CHECK_EQ(senders_.size(), 0u) << ": Not all senders destroyed";
diff --git a/aos/events/logging/log_cat.cc b/aos/events/logging/log_cat.cc
index 0afdc03..79ea1e3 100644
--- a/aos/events/logging/log_cat.cc
+++ b/aos/events/logging/log_cat.cc
@@ -5,6 +5,7 @@
#include <string>
#include <string_view>
#include <vector>
+#include "dirent.h"
#include "aos/configuration.h"
#include "aos/events/logging/logger.h"
@@ -58,6 +59,31 @@
}
}
+void SearchDirectory(std::vector<std::string> *files, std::string filename) {
+ DIR *directory = opendir(filename.c_str());
+
+ if (directory == nullptr) {
+ // its not a directory
+ // it could be a file
+ // or it could not exist
+ files->emplace_back(filename);
+ return;
+ }
+
+ struct dirent *directory_entry;
+ while ((directory_entry = readdir(directory)) != nullptr) {
+ std::string next_filename = directory_entry->d_name;
+ if (next_filename == "." || next_filename == "..") {
+ continue;
+ }
+
+ std::string path = filename + "/" + next_filename;
+ SearchDirectory(files, path);
+ }
+
+ closedir(directory);
+}
+
int main(int argc, char **argv) {
gflags::SetUsageMessage(
"Usage:\n"
@@ -124,7 +150,7 @@
std::vector<std::string> unsorted_logfiles;
for (int i = 1; i < argc; ++i) {
- unsorted_logfiles.emplace_back(std::string(argv[i]));
+ SearchDirectory(&unsorted_logfiles, argv[i]);
}
const std::vector<aos::logger::LogFile> logfiles =
diff --git a/aos/init.cc b/aos/init.cc
index 163f5dd..51e22cf 100644
--- a/aos/init.cc
+++ b/aos/init.cc
@@ -39,7 +39,6 @@
// Common stuff that needs to happen at the beginning of both the realtime and
// non-realtime initialization sequences. May be called twice.
void InitStart() {
- ::aos::logging::Init();
if (FLAGS_coredump) {
WriteCoreDumps();
}
diff --git a/aos/ipc_lib/eventfd_latency.cc b/aos/ipc_lib/eventfd_latency.cc
index 9229f1a..d146c13 100644
--- a/aos/ipc_lib/eventfd_latency.cc
+++ b/aos/ipc_lib/eventfd_latency.cc
@@ -160,7 +160,5 @@
int main(int argc, char **argv) {
::gflags::ParseCommandLineFlags(&argc, &argv, true);
- ::aos::logging::Init();
-
return ::aos::Main(argc, argv);
}
diff --git a/aos/ipc_lib/futex_latency.cc b/aos/ipc_lib/futex_latency.cc
index 59fa860..ef27e29 100644
--- a/aos/ipc_lib/futex_latency.cc
+++ b/aos/ipc_lib/futex_latency.cc
@@ -164,7 +164,5 @@
int main(int argc, char **argv) {
::gflags::ParseCommandLineFlags(&argc, &argv, true);
- ::aos::logging::Init();
-
return ::aos::Main(argc, argv);
}
diff --git a/aos/ipc_lib/ipc_comparison.cc b/aos/ipc_lib/ipc_comparison.cc
index 9191eae..6435ee7 100644
--- a/aos/ipc_lib/ipc_comparison.cc
+++ b/aos/ipc_lib/ipc_comparison.cc
@@ -902,7 +902,6 @@
::gflags::ParseCommandLineFlags(&argc, &argv, true);
::aos::InitNRT();
- ::aos::logging::Init();
return ::aos::Main(argc, argv);
}
diff --git a/aos/ipc_lib/named_pipe_latency.cc b/aos/ipc_lib/named_pipe_latency.cc
index c3f5c5c..2bd24f3 100644
--- a/aos/ipc_lib/named_pipe_latency.cc
+++ b/aos/ipc_lib/named_pipe_latency.cc
@@ -168,7 +168,5 @@
int main(int argc, char **argv) {
::gflags::ParseCommandLineFlags(&argc, &argv, true);
- ::aos::logging::Init();
-
return ::aos::Main(argc, argv);
}
diff --git a/aos/ipc_lib/signal_stress.cc b/aos/ipc_lib/signal_stress.cc
index ea9537f..60243fd 100644
--- a/aos/ipc_lib/signal_stress.cc
+++ b/aos/ipc_lib/signal_stress.cc
@@ -191,7 +191,5 @@
int main(int argc, char **argv) {
::gflags::ParseCommandLineFlags(&argc, &argv, true);
- ::aos::logging::Init();
-
return ::aos::Main(argc, argv);
}
diff --git a/aos/logging/context.cc b/aos/logging/context.cc
index 446e0df..0628e0e 100644
--- a/aos/logging/context.cc
+++ b/aos/logging/context.cc
@@ -42,7 +42,7 @@
char thread_name_array[kThreadNameLength + 1];
if (prctl(PR_GET_NAME, thread_name_array) != 0) {
- PDie("prctl(PR_GET_NAME, %p) failed", thread_name_array);
+ PLOG(FATAL) << "prctl(PR_GET_NAME, " << thread_name_array << ") failed";
}
#if __has_feature(memory_sanitizer)
// msan doesn't understand PR_GET_NAME, so help it along.
@@ -73,7 +73,7 @@
} // namespace
-Context::Context() : implementation(GetImplementation()), sequence(0) {}
+Context::Context() : sequence(0) {}
// Used in aos/linux_code/init.cc when a thread's name is changed.
void ReloadThreadName() {
diff --git a/aos/logging/context.h b/aos/logging/context.h
index 43ac54f..cc770ba 100644
--- a/aos/logging/context.h
+++ b/aos/logging/context.h
@@ -45,7 +45,8 @@
static void DeleteNow();
// Which one to log to right now.
- // Will be NULL if there is no logging implementation to use right now.
+ // Will be NULL if there is no logging implementation to use right now and we
+ // should use stderr instead.
std::shared_ptr<LogImplementation> implementation;
// A name representing this task/(process and thread).
diff --git a/aos/logging/implementations.cc b/aos/logging/implementations.cc
index 096127a..be54eec 100644
--- a/aos/logging/implementations.cc
+++ b/aos/logging/implementations.cc
@@ -5,33 +5,17 @@
#include <algorithm>
#include <chrono>
-#include <mutex>
-#include "absl/base/call_once.h"
-#include "aos/die.h"
#include "aos/logging/printf_formats.h"
-#include "aos/stl_mutex/stl_mutex.h"
#include "aos/time/time.h"
namespace aos {
namespace logging {
+namespace internal {
namespace {
namespace chrono = ::std::chrono;
-struct GlobalState {
- std::shared_ptr<LogImplementation> implementation;
- aos::stl_mutex lock;
- static GlobalState *Get() {
- static GlobalState r;
- return &r;
- }
-};
-
-} // namespace
-namespace internal {
-namespace {
-
void FillInMessageBase(log_level level,
monotonic_clock::time_point monotonic_now,
LogMessage *message) {
@@ -61,21 +45,15 @@
message->message_length =
ExecuteFormat(message->message, sizeof(message->message), format, ap);
- message->type = LogMessage::Type::kString;
}
void PrintMessage(FILE *output, const LogMessage &message) {
-#define BASE_ARGS \
- AOS_LOGGING_BASE_ARGS( \
- message.name_length, message.name, static_cast<int32_t>(message.source), \
- message.sequence, message.level, message.seconds, message.nseconds)
- switch (message.type) {
- case LogMessage::Type::kString:
- fprintf(output, AOS_LOGGING_BASE_FORMAT "%.*s", BASE_ARGS,
- static_cast<int>(message.message_length), message.message);
- break;
- }
-#undef BASE_ARGS
+ fprintf(output, AOS_LOGGING_BASE_FORMAT "%.*s",
+ AOS_LOGGING_BASE_ARGS(message.name_length, message.name,
+ static_cast<int32_t>(message.source),
+ message.sequence, message.level,
+ message.seconds, message.nseconds),
+ static_cast<int>(message.message_length), message.message);
}
} // namespace internal
@@ -95,55 +73,13 @@
}
void SetImplementation(std::shared_ptr<LogImplementation> implementation) {
- Init();
- GlobalState *const global = GlobalState::Get();
- std::unique_lock<aos::stl_mutex> locker(global->lock);
- global->implementation = std::move(implementation);
-}
-
-std::shared_ptr<LogImplementation> SwapImplementation(
- std::shared_ptr<LogImplementation> implementation) {
- std::shared_ptr<LogImplementation> result;
- {
- GlobalState *const global = GlobalState::Get();
- std::unique_lock<aos::stl_mutex> locker(global->lock);
- result = std::move(global->implementation);
- global->implementation = std::move(implementation);
- }
- Cleanup();
- return result;
+ internal::Context *context = internal::Context::Get();
+ context->implementation = std::move(implementation);
}
std::shared_ptr<LogImplementation> GetImplementation() {
- GlobalState *const global = GlobalState::Get();
- std::unique_lock<aos::stl_mutex> locker(global->lock);
- CHECK(global->implementation);
- return global->implementation;
-}
-
-namespace {
-
-struct DoInit {
- DoInit() {
- GlobalState *const global = GlobalState::Get();
- std::unique_lock<aos::stl_mutex> locker(global->lock);
- CHECK(!global->implementation);
- global->implementation = std::make_shared<StreamLogImplementation>(stdout);
- }
-};
-
-} // namespace
-
-void Init() { static DoInit do_init; }
-
-void Load() { internal::Context::Get(); }
-
-void Cleanup() { internal::Context::Delete(); }
-
-void RegisterCallbackImplementation(
- const ::std::function<void(const LogMessage &)> &callback) {
- Init();
- SetImplementation(std::make_shared<CallbackLogImplementation>(callback));
+ internal::Context *context = internal::Context::Get();
+ return context->implementation;
}
} // namespace logging
diff --git a/aos/logging/implementations.h b/aos/logging/implementations.h
index 962982b..6395c37 100644
--- a/aos/logging/implementations.h
+++ b/aos/logging/implementations.h
@@ -35,8 +35,6 @@
// Contains all of the information about a given logging call.
struct LogMessage {
- enum class Type : uint8_t { kString };
-
int32_t seconds, nseconds;
// message_length is just the length of the actual data (which member depends
// on the type).
@@ -45,26 +43,9 @@
static_assert(sizeof(source) == 4, "that's how they get printed");
// Per task/thread.
uint16_t sequence;
- Type type;
log_level level;
char name[LOG_MESSAGE_NAME_LEN];
- union {
- char message[LOG_MESSAGE_LEN];
- struct {
- uint32_t type_id;
- size_t string_length;
- // The message string and then the serialized structure.
- char serialized[LOG_MESSAGE_LEN - sizeof(type) - sizeof(string_length)];
- } structure;
- struct {
- // The type ID of the element type.
- uint32_t type;
- int rows, cols;
- size_t string_length;
- // The message string and then the serialized matrix.
- char data[LOG_MESSAGE_LEN - sizeof(type) - sizeof(rows) - sizeof(cols)];
- } matrix;
- };
+ char message[LOG_MESSAGE_LEN];
};
static_assert(shm_ok<LogMessage>::value, "it's going in a queue");
@@ -118,20 +99,13 @@
FILE *const stream_;
};
+// Returns the current implementation.
std::shared_ptr<LogImplementation> GetImplementation();
// Sets the current implementation.
void SetImplementation(std::shared_ptr<LogImplementation> implementation);
-// Updates the log implementation, returning the current implementation.
-std::shared_ptr<LogImplementation> SwapImplementation(
- std::shared_ptr<LogImplementation> implementation);
-
-// Must be called at least once per process/load before anything else is
-// called. This function is safe to call multiple times from multiple
-// tasks/threads.
-void Init();
-
+// A logging implementation which just uses a callback.
class CallbackLogImplementation : public HandleMessageLogImplementation {
public:
CallbackLogImplementation(
@@ -144,27 +118,13 @@
::std::function<void(const LogMessage &)> callback_;
};
-// Resets all information in this task/thread to its initial state.
-// NOTE: This is not the opposite of Init(). The state that this deletes is
-// lazily created when needed. It is actually the opposite of Load().
-void Cleanup();
-
-void RegisterCallbackImplementation(
- const ::std::function<void(const LogMessage &)> &callback);
-
class ScopedLogRestorer {
public:
- ScopedLogRestorer() = default;
-
- ~ScopedLogRestorer() {
- if (prev_impl_) {
- SetImplementation(std::move(prev_impl_));
- }
- Cleanup();
- }
+ ScopedLogRestorer() : prev_impl_(GetImplementation()) {}
+ ~ScopedLogRestorer() { SetImplementation(std::move(prev_impl_)); }
void Swap(std::shared_ptr<LogImplementation> new_impl) {
- prev_impl_ = SwapImplementation(std::move(new_impl));
+ SetImplementation(std::move(new_impl));
}
private:
diff --git a/aos/logging/implementations_test.cc b/aos/logging/implementations_test.cc
index f6cdc6f..058baab 100644
--- a/aos/logging/implementations_test.cc
+++ b/aos/logging/implementations_test.cc
@@ -92,7 +92,6 @@
}
void TearDown() override {
SetImplementation(nullptr);
- Cleanup();
internal::Context::DeleteNow();
CHECK_EQ(log_implementation.use_count(), 1);
log_implementation.reset();
diff --git a/aos/logging/interface.cc b/aos/logging/interface.cc
index b2f7b75..0cb0cd8 100644
--- a/aos/logging/interface.cc
+++ b/aos/logging/interface.cc
@@ -9,6 +9,8 @@
#include "aos/die.h"
#include "aos/logging/context.h"
+#include "aos/logging/implementations.h"
+#include "glog/logging.h"
namespace aos {
namespace logging {
@@ -21,8 +23,8 @@
const int ret = vsnprintf(output, size, format, ap);
typedef ::std::common_type<int, size_t>::type RetType;
if (ret < 0) {
- AOS_PLOG(FATAL, "vsnprintf(%p, %zd, %s, args) failed", output, size,
- format);
+ PLOG(FATAL) << "vsnprintf(" << output << ", " << size << ", " << format
+ << ", args) failed";
} else if (static_cast<RetType>(ret) >= static_cast<RetType>(size)) {
// Overwrite the '\0' at the end of the existing data and
// copy in the one on the end of continued.
@@ -31,39 +33,32 @@
return ::std::min<RetType>(ret, size);
}
-void RunWithCurrentImplementation(
- ::std::function<void(LogImplementation *)> function) {
- Context *context = Context::Get();
-
- const std::shared_ptr<LogImplementation> implementation =
- context->implementation;
- if (implementation == NULL) {
- Die("no logging implementation to use\n");
- }
- function(implementation.get());
-}
-
} // namespace internal
using internal::Context;
-void LogImplementation::DoVLog(log_level level, const char *format,
- va_list ap) {
- auto log_impl = [&](LogImplementation *implementation) {
- va_list ap1;
- va_copy(ap1, ap);
- implementation->DoLog(level, format, ap1);
- va_end(ap1);
-
- if (level == FATAL) {
- VDie(format, ap);
- }
- };
- internal::RunWithCurrentImplementation(::std::ref(log_impl));
-}
-
void VLog(log_level level, const char *format, va_list ap) {
- LogImplementation::DoVLog(level, format, ap);
+ va_list ap1;
+ va_copy(ap1, ap);
+
+ Context *context = Context::Get();
+
+ const std::shared_ptr<LogImplementation> implementation =
+ context->implementation;
+ // Log to the implementation if we have it, and stderr as a backup.
+ if (implementation) {
+ implementation->DoLog(level, format, ap1);
+ } else {
+ aos::logging::LogMessage message;
+ aos::logging::internal::FillInMessage(level, aos::monotonic_clock::now(),
+ format, ap, &message);
+ aos::logging::internal::PrintMessage(stderr, message);
+ }
+ va_end(ap1);
+
+ if (level == FATAL) {
+ VDie(format, ap);
+ }
}
} // namespace logging
diff --git a/aos/logging/interface.h b/aos/logging/interface.h
index 3695e40..387e55d 100644
--- a/aos/logging/interface.h
+++ b/aos/logging/interface.h
@@ -21,30 +21,15 @@
// for the current LogImplementation.
void VLog(log_level level, const char *format, va_list ap)
__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 2, 0)));
-// Adds to the saved up message.
-void VCork(int line, const char *function, const char *format, va_list ap)
- __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)));
-// Actually logs the saved up message.
-void VUnCork(int line, const char *function, log_level level, const char *file,
- const char *format, va_list ap)
- __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 5, 0)));
// Represents a system that can actually take log messages and do something
// useful with them.
-// All of the code (transitively too!) in the DoLog here can make
-// normal LOG and LOG_DYNAMIC calls but can NOT call LOG_CORK/LOG_UNCORK. These
-// calls will not result in DoLog recursing. However, implementations must be
-// safe to call from multiple threads/tasks at the same time. Also, any other
-// overriden methods may end up logging through a given implementation's DoLog.
class LogImplementation {
public:
LogImplementation() {}
virtual ~LogImplementation() {}
- virtual bool fill_type_cache() { return true; }
-
- protected:
// Actually logs the given message. Implementations should somehow create a
// LogMessage and then call internal::FillInMessage.
__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0))) virtual void DoLog(
@@ -56,15 +41,6 @@
DoLog(level, format, ap);
va_end(ap);
}
-
- private:
- // These functions call similar methods on the "current" LogImplementation or
- // Die if they can't find one.
- // levels is how many LogImplementations to not use off the stack.
- static void DoVLog(log_level, const char *format, va_list ap)
- __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 2, 0)));
-
- friend void VLog(log_level, const char *, va_list);
};
namespace internal {
@@ -75,12 +51,6 @@
va_list ap)
__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)));
-// Runs the given function with the current LogImplementation (handles switching
-// it out while running function etc).
-// levels is how many LogImplementations to not use off the stack.
-void RunWithCurrentImplementation(
- int levels, ::std::function<void(LogImplementation *)> function);
-
} // namespace internal
} // namespace logging
} // namespace aos
diff --git a/aos/mutex/mutex_test.cc b/aos/mutex/mutex_test.cc
index 07de9dc..c0ec66e 100644
--- a/aos/mutex/mutex_test.cc
+++ b/aos/mutex/mutex_test.cc
@@ -66,7 +66,6 @@
// Sees what happens with multiple unlocks.
TEST_F(MutexDeathTest, RepeatUnlock) {
- logging::Init();
ASSERT_FALSE(test_mutex_.Lock());
test_mutex_.Unlock();
EXPECT_DEATH(
@@ -80,7 +79,6 @@
// Sees what happens if you unlock without ever locking (or unlocking) it.
TEST_F(MutexDeathTest, NeverLock) {
- logging::Init();
EXPECT_DEATH(
{
logging::SetImplementation(
diff --git a/aos/starter/starter.cc b/aos/starter/starter.cc
index 4bfb3d2..6431a25 100644
--- a/aos/starter/starter.cc
+++ b/aos/starter/starter.cc
@@ -714,8 +714,6 @@
void Run();
void Main() {
- logging::Init();
-
// Set UID to 0 so we can run things as root down below. Since the starter
// program on the roborio runs starter.sh under "lvuser", it will continuously
// fail due to lack of permissions if we do not manually set the UID to admin.
diff --git a/aos/testing/test_logging.cc b/aos/testing/test_logging.cc
index 77bc4e9..b5b71ff 100644
--- a/aos/testing/test_logging.cc
+++ b/aos/testing/test_logging.cc
@@ -22,19 +22,7 @@
public:
const ::std::vector<LogMessage> &messages() { return messages_; }
- // Sets the current thread's time to be monotonic_now for logging.
- void MockTime(::aos::monotonic_clock::time_point monotonic_now) {
- mock_time_ = true;
- monotonic_now_ = monotonic_now;
- }
-
- // Clears any mock time for the current thread.
- void UnMockTime() { mock_time_ = false; }
-
::aos::monotonic_clock::time_point monotonic_now() const override {
- if (mock_time_) {
- return monotonic_now_;
- }
return ::aos::monotonic_clock::now();
}
@@ -70,8 +58,6 @@
}
}
- bool fill_type_cache() override { return false; }
-
void PrintMessagesAsTheyComeIn() { print_as_messages_come_in_ = true; }
// Don't call these from outside this class.
@@ -95,18 +81,8 @@
bool print_as_messages_come_in_ = false;
FILE *output_file_ = stdout;
::aos::Mutex messages_mutex_;
-
- // Thread local storage for mock time. This is thread local because if
- // someone spawns a thread and goes to town in parallel with a simulated event
- // loop, we want to just print the actual monotonic clock out.
- static AOS_THREAD_LOCAL bool mock_time_;
- static AOS_THREAD_LOCAL ::aos::monotonic_clock::time_point monotonic_now_;
};
-AOS_THREAD_LOCAL bool TestLogImplementation::mock_time_ = false;
-AOS_THREAD_LOCAL ::aos::monotonic_clock::time_point
- TestLogImplementation::monotonic_now_ = ::aos::monotonic_clock::min_time;
-
class MyTestEventListener : public ::testing::EmptyTestEventListener {
virtual void OnTestStart(const ::testing::TestInfo & /*test_info*/) {
TestLogImplementation::GetInstance()->ClearMessages();
@@ -138,7 +114,6 @@
};
void *DoEnableTestLogging() {
- logging::Init();
logging::SetImplementation(TestLogImplementation::GetInstance());
::testing::UnitTest::GetInstance()->listeners().Append(
@@ -163,10 +138,5 @@
TestLogImplementation::GetInstance()->PrintMessagesAsTheyComeIn();
}
-void MockTime(::aos::monotonic_clock::time_point monotonic_now) {
- TestLogImplementation::GetInstance()->MockTime(monotonic_now);
-}
-void UnMockTime() { TestLogImplementation::GetInstance()->UnMockTime(); }
-
} // namespace testing
} // namespace aos
diff --git a/aos/testing/test_logging.h b/aos/testing/test_logging.h
index e7059d1..0a26b07 100644
--- a/aos/testing/test_logging.h
+++ b/aos/testing/test_logging.h
@@ -23,13 +23,6 @@
// we want to use graphing tools to verify what's happening.
void ForcePrintLogsDuringTests();
-// Sets the current mock logging time to monotonic_now. This only applies to
-// the current thread.
-void MockTime(::aos::monotonic_clock::time_point monotonic_now);
-// Clears the mock logging time for the current thread and goes back to using
-// monotonic_clock::now().
-void UnMockTime();
-
} // namespace testing
} // namespace aos
diff --git a/aos/transaction/BUILD b/aos/transaction/BUILD
deleted file mode 100644
index 81dc8a0..0000000
--- a/aos/transaction/BUILD
+++ /dev/null
@@ -1,25 +0,0 @@
-package(default_visibility = ["//visibility:public"])
-
-cc_library(
- name = "transaction",
- hdrs = [
- "transaction.h",
- ],
- deps = [
- "//aos/logging",
- "//aos/util:compiler_memory_barrier",
- ],
-)
-
-cc_test(
- name = "transaction_test",
- srcs = [
- "transaction_test.cc",
- ],
- deps = [
- ":transaction",
- "//aos/logging",
- "//aos/testing:googletest",
- "//aos/util:death_test_log_implementation",
- ],
-)
diff --git a/aos/transaction/transaction.h b/aos/transaction/transaction.h
deleted file mode 100644
index e0266f9..0000000
--- a/aos/transaction/transaction.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef AOS_TRANSACTION_H_
-#define AOS_TRANSACTION_H_
-
-#include <stdint.h>
-
-#include <array>
-
-#include "aos/util/compiler_memory_barrier.h"
-#include "aos/logging/logging.h"
-
-namespace aos {
-namespace transaction {
-
-// Manages a LIFO stack of Work objects. Designed to help implement transactions
-// by providing a safe way to undo things etc.
-//
-// number_works Work objects are created statically and then Create is called on
-// each as it is added to the stack. When the work should do whatever it does,
-// DoWork() will be called. The work objects get no notification when they are
-// dropped off of the stack.
-//
-// Work::DoWork() must be idempotent because it may get called multiple times if
-// CompleteWork() is interrupted part of the way through.
-//
-// This class handles compiler memory barriers etc to make sure only fully
-// created works are ever invoked, and each work will be fully created by the
-// time AddWork returns. This does not mean it's safe for multiple threads to
-// interact with an instance of this class at the same time.
-template <class Work, int number_works>
-class WorkStack {
- public:
- // Calls DoWork() on all the works that have been added and then removes them
- // all from the stack.
- void CompleteWork() {
- int current = stack_index_;
- while (current > 0) {
- stack_.at(--current).DoWork();
- }
- aos_compiler_memory_barrier();
- stack_index_ = 0;
- aos_compiler_memory_barrier();
- }
-
- // Drops all works that have been added.
- void DropWork() {
- stack_index_ = 0;
- aos_compiler_memory_barrier();
- }
-
- // Returns true if we have any works to complete right now.
- bool HasWork() const { return stack_index_ != 0; }
-
- // Forwards all of its arguments to Work::Create, which it calls on the next
- // work to be added.
- template <class... A>
- void AddWork(A &&... a) {
- if (stack_index_ >= number_works) {
- AOS_LOG(FATAL, "too many works\n");
- }
- stack_.at(stack_index_).Create(::std::forward<A>(a)...);
- aos_compiler_memory_barrier();
- ++stack_index_;
- aos_compiler_memory_barrier();
- }
-
- private:
- // The next index into stack_ for a new work to be added.
- int stack_index_ = 0;
- ::std::array<Work, number_works> stack_;
-};
-
-// When invoked, sets *pointer to the value it had when this work was Created.
-template <class T>
-class RestoreValueWork {
- public:
- void Create(T *pointer) {
- pointer_ = pointer;
- value_ = *pointer;
- }
- void DoWork() {
- *pointer_ = value_;
- }
-
- private:
- T *pointer_;
- T value_;
-};
-
-// Handles the casting necessary to restore any kind of pointer.
-class RestorePointerWork : public RestoreValueWork<void *> {
- public:
- template <class T>
- void Create(T **pointer) {
- static_assert(sizeof(T *) == sizeof(void *),
- "that's a weird pointer");
- RestoreValueWork<void *>::Create(reinterpret_cast<void **>(pointer));
- }
-};
-
-} // namespace transaction
-} // namespace aos
-
-#endif // AOS_TRANSACTION_H_
diff --git a/aos/transaction/transaction_test.cc b/aos/transaction/transaction_test.cc
deleted file mode 100644
index 52b297e..0000000
--- a/aos/transaction/transaction_test.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "aos/transaction/transaction.h"
-
-#include <vector>
-
-#include "gtest/gtest.h"
-
-#include "aos/util/death_test_log_implementation.h"
-
-namespace aos {
-namespace transaction {
-namespace testing {
-
-class WorkStackTest : public ::testing::Test {
- public:
- // Contains an index which it adds to the created_works and invoked_works
- // vectors of its containing WorkStackTest.
- class TestWork {
- public:
- void Create(WorkStackTest *test, int i) {
- test->created_works()->push_back(i);
- i_ = i;
- test_ = test;
- }
- void DoWork() { test_->invoked_works()->push_back(i_); }
-
- int i() const { return i_; }
-
- private:
- int i_;
- WorkStackTest *test_;
- };
-
- ::std::vector<int> *created_works() { return &created_works_; }
- ::std::vector<int> *invoked_works() { return &invoked_works_; }
- WorkStack<TestWork, 20> *work_stack() { return &work_stack_; }
-
- // Creates a TestWork with index i and adds it to work_stack().
- void CreateWork(int i) { work_stack_.AddWork(this, i); }
-
- private:
- ::std::vector<int> created_works_, invoked_works_;
- WorkStack<TestWork, 20> work_stack_;
-};
-
-typedef WorkStackTest WorkStackDeathTest;
-
-TEST_F(WorkStackTest, Basic) {
- EXPECT_FALSE(work_stack()->HasWork());
- EXPECT_EQ(0u, created_works()->size());
- EXPECT_EQ(0u, invoked_works()->size());
-
- CreateWork(971);
- EXPECT_TRUE(work_stack()->HasWork());
- EXPECT_EQ(1u, created_works()->size());
- EXPECT_EQ(0u, invoked_works()->size());
- EXPECT_EQ(971, created_works()->at(0));
-
- work_stack()->CompleteWork();
- EXPECT_FALSE(work_stack()->HasWork());
- EXPECT_EQ(1u, created_works()->size());
- EXPECT_EQ(1u, invoked_works()->size());
- EXPECT_EQ(971, invoked_works()->at(0));
-}
-
-TEST_F(WorkStackTest, DropWork) {
- CreateWork(971);
- CreateWork(254);
- EXPECT_EQ(2u, created_works()->size());
-
- work_stack()->DropWork();
- EXPECT_FALSE(work_stack()->HasWork());
- work_stack()->CompleteWork();
- EXPECT_EQ(0u, invoked_works()->size());
-}
-
-// Tests that the works get run in the correct order.
-TEST_F(WorkStackTest, InvocationOrder) {
- CreateWork(971);
- CreateWork(254);
- CreateWork(1678);
-
- work_stack()->CompleteWork();
- EXPECT_EQ((::std::vector<int>{971, 254, 1678}), *created_works());
- EXPECT_EQ((::std::vector<int>{1678, 254, 971}), *invoked_works());
-}
-
-// Tests that it handles adding too many works intelligently.
-TEST_F(WorkStackDeathTest, TooManyWorks) {
- logging::Init();
- EXPECT_DEATH(
- {
- logging::SetImplementation(
- std::make_shared<util::DeathTestLogImplementation>());
- for (int i = 0; i < 1000; ++i) {
- CreateWork(i);
- }
- },
- ".*too many works.*");
-}
-
-} // namespace testing
-} // namespace transaction
-} // namespace aos
diff --git a/aos/util/BUILD b/aos/util/BUILD
index b23b720..01be701 100644
--- a/aos/util/BUILD
+++ b/aos/util/BUILD
@@ -237,28 +237,6 @@
],
)
-cc_library(
- name = "linked_list",
- hdrs = [
- "linked_list.h",
- ],
- deps = [
- "//aos/transaction",
- ],
-)
-
-cc_test(
- name = "linked_list_test",
- srcs = [
- "linked_list_test.cc",
- ],
- deps = [
- ":linked_list",
- "//aos/logging",
- "//aos/testing:googletest",
- ],
-)
-
cc_test(
name = "phased_loop_test",
srcs = [
diff --git a/aos/util/linked_list.h b/aos/util/linked_list.h
deleted file mode 100644
index 14f1788..0000000
--- a/aos/util/linked_list.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef AOS_UTIL_LINKED_LIST_H_
-#define AOS_UTIL_LINKED_LIST_H_
-
-#include <functional>
-
-#include "aos/transaction/transaction.h"
-
-namespace aos {
-namespace util {
-
-// Handles manipulating an intrusive linked list. T must look like the
-// following:
-// struct T {
-// ...
-// T *next;
-// ...
-// };
-// This class doesn't deal with creating or destroying them, so
-// constructors/destructors/other members variables/member functions are all
-// fine, but the next pointer must be there for this class to work.
-// This class will handle all manipulations of next. It does not need to be
-// initialized before calling Add and should not be changed afterwards.
-// next can (and probably should) be private if the appropriate instantiation of
-// this class is friended.
-template <class T>
-class LinkedList {
- public:
- T *head() const { return head_; }
-
- bool Empty() const { return head() == nullptr; }
-
- void Add(T *t) {
- Add<0>(t, nullptr);
- }
-
- // restore_points (if non-null) will be used so the operation can be safely
- // reverted at any point.
- template <int number_works>
- void Add(T *t, transaction::WorkStack<transaction::RestorePointerWork,
- number_works> *restore_pointers) {
- if (restore_pointers != nullptr) restore_pointers->AddWork(&t->next);
- t->next = head();
- if (restore_pointers != nullptr) restore_pointers->AddWork(&head_);
- head_ = t;
- }
-
- void Remove(T *t) {
- Remove<0>(t, nullptr);
- }
-
- // restore_points (if non-null) will be used so the operation can be safely
- // reverted at any point.
- template <int number_works>
- void Remove(T *t, transaction::WorkStack<transaction::RestorePointerWork,
- number_works> *restore_pointers) {
- T **pointer = &head_;
- while (*pointer != nullptr) {
- if (*pointer == t) {
- if (restore_pointers != nullptr) {
- restore_pointers->AddWork(pointer);
- }
- *pointer = t->next;
- return;
- }
- pointer = &(*pointer)->next;
- }
- AOS_LOG(FATAL, "%p is not in the list\n", t);
- }
-
- // Calls function for each element of the list.
- // function can modify these elements in any way except touching the next
- // pointer (including by calling other methods of this object).
- void Each(::std::function<void(T *)> function) const {
- T *c = head();
- while (c != nullptr) {
- T *const next = c->next;
- function(c);
- c = next;
- }
- }
-
- // Returns the first element of the list where function returns true or
- // nullptr if it returns false for all.
- T *Find(::std::function<bool(const T *)> function) const {
- T *c = head();
- while (c != nullptr) {
- if (function(c)) return c;
- c = c->next;
- }
- return nullptr;
- }
-
- private:
- T *head_ = nullptr;
-};
-
-// Keeps track of something along with a next pointer. Useful for things that
-// either have types without next pointers or for storing pointers to things
-// that belong in multiple lists.
-template <class V>
-struct LinkedListReference {
- V item;
-
- private:
- friend class LinkedList<LinkedListReference>;
-
- LinkedListReference *next;
-};
-
-} // namespace util
-} // namespace aos
-
-#endif // AOS_UTIL_LINKED_LIST_H_
diff --git a/aos/util/linked_list_test.cc b/aos/util/linked_list_test.cc
deleted file mode 100644
index 6959628..0000000
--- a/aos/util/linked_list_test.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-#include "aos/util/linked_list.h"
-
-#include <vector>
-
-#include "gtest/gtest.h"
-
-namespace aos {
-namespace util {
-namespace testing {
-
-class LinkedListTest : public ::testing::Test {
- public:
- virtual ~LinkedListTest() {
- while (list.head() != nullptr) {
- RemoveElement(list.head());
- }
- }
-
- struct Member {
- Member(int i) : i(i) {}
-
- int i;
- Member *next = nullptr;
- };
- LinkedList<Member> list;
-
- Member *AddElement(int i) {
- Member *member = new Member(i);
- list.Add(member);
- return member;
- }
-
- void RemoveElement(Member *member) {
- list.Remove(member);
- delete member;
- }
-
- Member *GetMember(int i) const {
- return list.Find([i](const Member *member) { return member->i == i; });
- }
-
- bool HasMember(int i) const { return GetMember(i) != nullptr; }
-
- ::std::vector<int> GetMembers() {
- ::std::vector<int> r;
- list.Each([&r](Member *member) { r.push_back(member->i); });
- return r;
- }
-};
-
-// Tests that adding and removing elements works correctly.
-TEST_F(LinkedListTest, Basic) {
- EXPECT_TRUE(list.Empty());
- AddElement(971);
- EXPECT_FALSE(list.Empty());
- AddElement(254);
- EXPECT_FALSE(list.Empty());
- AddElement(1678);
- EXPECT_FALSE(list.Empty());
-
- EXPECT_EQ((::std::vector<int>{1678, 254, 971}), GetMembers());
-
- EXPECT_EQ(1678, list.head()->i);
- RemoveElement(list.head());
- EXPECT_EQ(254, list.head()->i);
- EXPECT_FALSE(list.Empty());
- RemoveElement(list.head());
- EXPECT_EQ(971, list.head()->i);
- EXPECT_FALSE(list.Empty());
- RemoveElement(list.head());
- EXPECT_TRUE(list.Empty());
-}
-
-TEST_F(LinkedListTest, Each) {
- ::std::vector<int> found;
- auto add_to_found = [&found](Member *member) {
- found.push_back(member->i);
- };
-
- AddElement(971);
- found.clear();
- list.Each(add_to_found);
- EXPECT_EQ((::std::vector<int>{971}), found);
-
- AddElement(254);
- found.clear();
- list.Each(add_to_found);
- EXPECT_EQ((::std::vector<int>{254, 971}), found);
-
- AddElement(1678);
- found.clear();
- list.Each(add_to_found);
- EXPECT_EQ((::std::vector<int>{1678, 254, 971}), found);
-}
-
-TEST_F(LinkedListTest, Find) {
- auto find_254 = [](const Member *member) { return member->i == 254; };
-
- AddElement(971);
- EXPECT_EQ(nullptr, list.Find(find_254));
- Member *member = AddElement(254);
- EXPECT_EQ(member, list.Find(find_254));
- AddElement(1678);
- EXPECT_EQ(member, list.Find(find_254));
-}
-
-// Removing an element from the middle of the list used to break it.
-TEST_F(LinkedListTest, RemoveFromMiddle) {
- AddElement(971);
- auto in_middle = AddElement(254);
- AddElement(1678);
- RemoveElement(in_middle);
-
- EXPECT_EQ((::std::vector<int>{1678, 971}), GetMembers());
-}
-
-} // namespace testing
-} // namespace util
-} // namespace aos
diff --git a/aos/vision/tools/camera_primer.cc b/aos/vision/tools/camera_primer.cc
index 027f9dc..fcd7d0b 100644
--- a/aos/vision/tools/camera_primer.cc
+++ b/aos/vision/tools/camera_primer.cc
@@ -26,8 +26,6 @@
// camera_primer
// target_sender
int main(int argc, char **argv) {
- ::aos::logging::Init();
-
aos::vision::CameraParams params;
if (argc != 2) {
diff --git a/frc971/control_loops/drivetrain/drivetrain.cc b/frc971/control_loops/drivetrain/drivetrain.cc
index 8c0599f..88e7a02 100644
--- a/frc971/control_loops/drivetrain/drivetrain.cc
+++ b/frc971/control_loops/drivetrain/drivetrain.cc
@@ -297,9 +297,16 @@
localizer_->right_velocity())
.finished();
- dt_spline_.Update(
- output != nullptr && controller_type == ControllerType::SPLINE_FOLLOWER,
- trajectory_state, kf_.X_hat().block<2, 1>(4, 0));
+ {
+ // TODO(james): The regular Kalman Filter's voltage error terms are
+ // currently unusable--either don't use voltage error at all for the spline
+ // following code, or use the EKF's voltage error estimates.
+ const Eigen::Matrix<double, 2, 1> voltage_error =
+ 0 * kf_.X_hat().block<2, 1>(4, 0);
+ dt_spline_.Update(
+ output != nullptr && controller_type == ControllerType::SPLINE_FOLLOWER,
+ trajectory_state, voltage_error);
+ }
dt_line_follow_.Update(monotonic_now, trajectory_state);
diff --git a/frc971/control_loops/drivetrain/drivetrain_lib_test.cc b/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
index 9857196..bfa3d26 100644
--- a/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
+++ b/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
@@ -901,6 +901,8 @@
// Tests that simple spline converges when we introduce a straight voltage
// error.
+// TODO(james): Reenable this once we decide what to do with the voltage error
+// terms.
TEST_F(DrivetrainTest, SplineVoltageError) {
SetEnabled(true);
drivetrain_plant_.set_left_voltage_offset(1.0);
@@ -947,7 +949,21 @@
WaitForTrajectoryPlan();
RunFor(chrono::milliseconds(5000));
- VerifyNearSplineGoal();
+ // Since the voltage error compensation is disabled, expect that we will have
+ // *failed* to reach our goal.
+ drivetrain_status_fetcher_.Fetch();
+ const double expected_x =
+ CHECK_NOTNULL(drivetrain_status_fetcher_->trajectory_logging())->x();
+ const double expected_y =
+ CHECK_NOTNULL(drivetrain_status_fetcher_->trajectory_logging())->y();
+ const double estimated_x = drivetrain_status_fetcher_->x();
+ const double estimated_y = drivetrain_status_fetcher_->y();
+ const ::Eigen::Vector2d actual = drivetrain_plant_.GetPosition();
+ // Expect the x position comparison to fail; everything else to succeed.
+ EXPECT_GT(std::abs(estimated_x - expected_x), spline_control_tolerance_);
+ EXPECT_NEAR(estimated_y, expected_y, spline_control_tolerance_);
+ EXPECT_NEAR(actual(0), estimated_x, spline_estimate_tolerance_);
+ EXPECT_NEAR(actual(1), estimated_y, spline_estimate_tolerance_);
}
// Tests that a multispline converges on a goal.
diff --git a/frc971/control_loops/drivetrain/libspline.cc b/frc971/control_loops/drivetrain/libspline.cc
index a9820f7..280171f 100644
--- a/frc971/control_loops/drivetrain/libspline.cc
+++ b/frc971/control_loops/drivetrain/libspline.cc
@@ -205,7 +205,6 @@
// Util
void SetUpLogging() {
- ::aos::logging::Init();
::aos::network::OverrideTeamNumber(971);
}
}
diff --git a/frc971/control_loops/drivetrain/trajectory_plot.cc b/frc971/control_loops/drivetrain/trajectory_plot.cc
index 60bd21f..6aff128 100644
--- a/frc971/control_loops/drivetrain/trajectory_plot.cc
+++ b/frc971/control_loops/drivetrain/trajectory_plot.cc
@@ -247,7 +247,6 @@
int main(int argc, char **argv) {
::gflags::ParseCommandLineFlags(&argc, &argv, false);
- ::aos::logging::Init();
::aos::network::OverrideTeamNumber(971);
::frc971::control_loops::drivetrain::Main();
return 0;
diff --git a/third_party/diff-from-upstream.sh b/third_party/diff-from-upstream.sh
new file mode 100755
index 0000000..373cc00
--- /dev/null
+++ b/third_party/diff-from-upstream.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+# This script will run `git diff` from the latest upstream to HEAD on the
+# git-subtreed directory given as its first argument, passing all of the
+# other arguments on.
+#
+# This will not work on non-squashed git-subtree directories.
+
+# Copied from
+# https://github.com/git/git/blob/master/contrib/subtree/git-subtree.sh.
+find_latest_squash()
+{
+ dir="$1"
+ sq=
+ main=
+ sub=
+ git log --grep="^git-subtree-dir: $dir/*\$" \
+ --pretty=format:'START %H%n%s%n%n%b%nEND%n' HEAD |
+ while read a b junk; do
+ case "$a" in
+ START) sq="$b" ;;
+ git-subtree-mainline:) main="$b" ;;
+ git-subtree-split:) sub="$b" ;;
+ END)
+ if [ -n "$sub" ]; then
+ if [ -n "$main" ]; then
+ # a rejoin commit?
+ # Pretend its sub was a squash.
+ sq="$sub"
+ fi
+ echo "$sq" "$sub"
+ break
+ fi
+ sq=
+ main=
+ sub=
+ ;;
+ esac
+ done
+}
+
+DIR="${1%/}"
+shift
+DIFF_ARGS="$@"
+
+SPLIT="$(find_latest_squash "${DIR}")"
+if [ -z "${SPLIT}" ]; then
+ echo "${DIR} does not appear to be git-subtreed in."
+ exit 1
+fi
+
+set ${SPLIT}
+SQUASHED_UPSTREAM=$1
+
+git diff ${DIFF_ARGS} ${SQUASHED_UPSTREAM}..HEAD:${DIR}
diff --git a/y2016/vision/target_sender.cc b/y2016/vision/target_sender.cc
index 3783e9f..bc2a695 100644
--- a/y2016/vision/target_sender.cc
+++ b/y2016/vision/target_sender.cc
@@ -7,8 +7,6 @@
#include <thread>
#include <vector>
-#include "aos/logging/implementations.h"
-#include "aos/logging/logging.h"
#include "aos/time/time.h"
#include "aos/vision/events/socket_types.h"
#include "aos/vision/events/udp.h"
@@ -225,7 +223,6 @@
int main(int, char **) {
using namespace y2016::vision;
StereoGeometry stereo("./stereo_rig.calib");
- ::aos::logging::Init();
std::thread cam0([stereo]() {
RunCamera(0, GetCameraParams(stereo.calibration()),
stereo.calibration().right_camera_name(),
diff --git a/y2017/vision/target_sender.cc b/y2017/vision/target_sender.cc
index 1c5f3f7..7a24d37 100644
--- a/y2017/vision/target_sender.cc
+++ b/y2017/vision/target_sender.cc
@@ -219,7 +219,6 @@
int main(int, char **) {
using namespace y2017::vision;
- ::aos::logging::Init();
VisionConfig cfg;
if (ReadConfiguration("ConfigFile.pb.ascii", &cfg)) {
if (cfg.robot_configs().count("Laptop") != 1) {
diff --git a/y2018/vision/image_streamer.cc b/y2018/vision/image_streamer.cc
index 06a74c4..fb60f1d 100644
--- a/y2018/vision/image_streamer.cc
+++ b/y2018/vision/image_streamer.cc
@@ -288,9 +288,6 @@
int main(int argc, char ** argv) {
gflags::ParseCommandLineFlags(&argc, &argv, false);
- ::aos::logging::Init();
- ::aos::logging::SetImplementation(
- std::make_shared<::aos::logging::StreamLogImplementation>(stderr));
TCPServer<MjpegDataSocket> tcp_server_(80);
aos::vision::CameraParams params0;
diff --git a/y2019/image_streamer/image_streamer.cc b/y2019/image_streamer/image_streamer.cc
index 1252627..6640df0 100644
--- a/y2019/image_streamer/image_streamer.cc
+++ b/y2019/image_streamer/image_streamer.cc
@@ -307,9 +307,6 @@
int main(int argc, char **argv) {
gflags::ParseCommandLineFlags(&argc, &argv, false);
- ::aos::logging::Init();
- ::aos::logging::SetImplementation(
- std::make_shared<::aos::logging::StreamLogImplementation>(stderr));
TCPServer<MjpegDataSocket> tcp_server_(80);
aos::vision::CameraParams params0;
params0.set_exposure(FLAGS_camera0_exposure);
diff --git a/y2019/vision/debug_serial.cc b/y2019/vision/debug_serial.cc
index 18670c0..d1c70c2 100644
--- a/y2019/vision/debug_serial.cc
+++ b/y2019/vision/debug_serial.cc
@@ -23,9 +23,6 @@
using namespace y2019::vision;
using namespace frc971::jevois;
// gflags::ParseCommandLineFlags(&argc, &argv, false);
- ::aos::logging::Init();
- ::aos::logging::SetImplementation(
- std::make_shared<::aos::logging::StreamLogImplementation>(stderr));
int flags = fcntl(0, F_GETFL, 0);
fcntl(0, F_SETFL, flags | O_NONBLOCK);
diff --git a/y2019/vision/global_calibration.cc b/y2019/vision/global_calibration.cc
index af2ad54..e1e5ca8 100644
--- a/y2019/vision/global_calibration.cc
+++ b/y2019/vision/global_calibration.cc
@@ -102,10 +102,6 @@
FLAGS_image_count,
};
- ::aos::logging::Init();
- ::aos::logging::SetImplementation(
- std::make_shared<::aos::logging::StreamLogImplementation>(stderr));
-
TargetFinder target_finder;
ceres::Problem problem;