Merge changes I6bbe5d56,I943faba4
* changes:
Merge commit '6dccd64de51ea960cb6f0d975768c874814b4c75' into HEAD
Squashed 'third_party/flatbuffers/' changes from bc44fad35..8aa8b9139
diff --git a/BUILD b/BUILD
index 9368a1f..4a4baa5 100644
--- a/BUILD
+++ b/BUILD
@@ -32,6 +32,8 @@
# gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_shift_schedule_response //scouting/webserver/requests/messages:request_shift_schedule_response_go_fbs
# gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_shift_schedule //scouting/webserver/requests/messages:submit_shift_schedule_go_fbs
# gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_shift_schedule_response //scouting/webserver/requests/messages:submit_shift_schedule_response_go_fbs
+# gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_driver_ranking //scouting/webserver/requests/messages:submit_driver_ranking_go_fbs
+# gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_driver_ranking_response //scouting/webserver/requests/messages:submit_driver_ranking_response_go_fbs
gazelle(
name = "gazelle",
diff --git a/WORKSPACE b/WORKSPACE
index 172e7bb..d402c98 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -56,6 +56,10 @@
python_gtk_debs = "files",
)
load(
+ "//debian:gtk_runtime.bzl",
+ gtk_runtime_debs = "files",
+)
+load(
"//debian:opencv_arm64.bzl",
opencv_arm64_debs = "files",
)
@@ -127,6 +131,8 @@
generate_repositories_for_debs(python_gtk_debs)
+generate_repositories_for_debs(gtk_runtime_debs)
+
generate_repositories_for_debs(opencv_arm64_debs)
generate_repositories_for_debs(opencv_armhf_debs)
@@ -683,6 +689,13 @@
url = "https://www.frc971.org/Build-Dependencies/python_gtk-4.tar.gz",
)
+http_archive(
+ name = "gtk_runtime",
+ build_file = "@//debian:gtk_runtime.BUILD",
+ sha256 = "934693e64bfe63f0c55cdf432fe183eb077d6875d4d6a3dce4e47dbe7e20f5a9",
+ url = "https://www.frc971.org/Build-Dependencies/gtk_runtime-3.tar.gz",
+)
+
# Downloaded from
# https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2018q2/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2?revision=bc2c96c0-14b5-4bb4-9f18-bceb4050fee7?product=GNU%20Arm%20Embedded%20Toolchain,64-bit,,Linux,7-2018-q2-update
http_archive(
@@ -1315,3 +1328,36 @@
load("//third_party/cargo:crates.bzl", "raze_fetch_remote_crates")
raze_fetch_remote_crates()
+
+http_archive(
+ name = "com_github_zaphoyd_websocketpp",
+ build_file = "//third_party/websocketpp:websocketpp.BUILD",
+ sha256 = "6ce889d85ecdc2d8fa07408d6787e7352510750daa66b5ad44aacb47bea76755",
+ strip_prefix = "websocketpp-0.8.2",
+ url = "https://github.com/zaphoyd/websocketpp/archive/refs/tags/0.8.2.tar.gz",
+)
+
+http_archive(
+ name = "com_github_foxglove_ws-protocol",
+ build_file = "//third_party/foxglove_ws_protocol:foxglove_ws_protocol.BUILD",
+ patch_args = ["-p1"],
+ patches = ["//third_party/foxglove_ws_protocol:foxglove_ws_protocol.patch"],
+ sha256 = "3256f09a67419f6556778c443d332f1a4bf53ba0e7a464179bf838abffa366ab",
+ strip_prefix = "ws-protocol-releases-typescript-ws-protocol-examples-v0.0.6",
+ url = "https://github.com/foxglove/ws-protocol/archive/refs/tags/releases/typescript/ws-protocol-examples/v0.0.6.tar.gz",
+)
+
+http_archive(
+ name = "asio",
+ build_file_content = """
+cc_library(
+ name = "asio",
+ hdrs = glob(["include/asio/**/*.hpp", "include/asio/**/*.ipp", "include/asio.hpp"]),
+ visibility = ["//visibility:public"],
+ defines = ["ASIO_STANDALONE"],
+ includes = ["include/"],
+)""",
+ sha256 = "8976812c24a118600f6fcf071a20606630a69afe4c0abee3b0dea528e682c585",
+ strip_prefix = "asio-1.24.0",
+ url = "https://downloads.sourceforge.net/project/asio/asio/1.24.0%2520%2528Stable%2529/asio-1.24.0.tar.bz2",
+)
diff --git a/aos/BUILD b/aos/BUILD
index 596996b..164f40b 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -514,6 +514,7 @@
"configuration_test.cc",
],
data = [
+ "//aos/events:ping_fbs_reflection_out",
"//aos/events:pingpong_config",
"//aos/events:pong_fbs_reflection_out",
"//aos/testdata:test_configs",
@@ -521,6 +522,7 @@
target_compatible_with = ["@platforms//os:linux"],
deps = [
":configuration",
+ "//aos/events:ping_fbs",
"//aos/testing:flatbuffer_eq",
"//aos/testing:googletest",
"//aos/testing:path",
diff --git a/aos/configuration.cc b/aos/configuration.cc
index d5ac2a1..ad6fb54 100644
--- a/aos/configuration.cc
+++ b/aos/configuration.cc
@@ -68,7 +68,6 @@
}
} // namespace
-
// Define the compare and equal operators for Channel and Application so we can
// insert them in the btree below.
bool operator<(const FlatbufferDetachedBuffer<Channel> &lhs,
@@ -1594,5 +1593,30 @@
return channel->num_readers() + channel->num_senders();
}
+// Searches through configurations for schemas that include a certain type
+const reflection::Schema *GetSchema(const Configuration *config,
+ std::string_view schema_type) {
+ if (config->has_channels()) {
+ std::vector<flatbuffers::Offset<Channel>> channel_offsets;
+ for (const Channel *c : *config->channels()) {
+ if (schema_type == c->type()->string_view()) {
+ return c->schema();
+ }
+ }
+ }
+ return nullptr;
+}
+
+// Copy schema reflection into detached flatbuffer
+std::optional<FlatbufferDetachedBuffer<reflection::Schema>>
+GetSchemaDetachedBuffer(const Configuration *config,
+ std::string_view schema_type) {
+ const reflection::Schema *found_schema = GetSchema(config, schema_type);
+ if (found_schema == nullptr) {
+ return std::nullopt;
+ }
+ return RecursiveCopyFlatBuffer(found_schema);
+}
+
} // namespace configuration
} // namespace aos
diff --git a/aos/configuration.h b/aos/configuration.h
index 8515b18..4d84b23 100644
--- a/aos/configuration.h
+++ b/aos/configuration.h
@@ -212,7 +212,20 @@
// Returns the number of scratch buffers in the queue.
int QueueScratchBufferSize(const Channel *channel);
-// TODO(austin): GetSchema<T>(const Flatbuffer<Configuration> &config);
+// Searches through configurations for schemas that include a certain type.
+const reflection::Schema *GetSchema(const Configuration *config,
+ std::string_view schema_type);
+
+// GetSchema template
+template <typename T>
+const reflection::Schema *GetSchema(const Configuration *config) {
+ return GetSchema(config, T::GetFullyQualifiedName());
+}
+
+// Copy schema reflection into detached flatbuffer
+std::optional<FlatbufferDetachedBuffer<reflection::Schema>>
+GetSchemaDetachedBuffer(const Configuration *config,
+ std::string_view schema_type);
} // namespace configuration
@@ -222,6 +235,7 @@
const FlatbufferDetachedBuffer<Channel> &rhs);
bool operator==(const FlatbufferDetachedBuffer<Channel> &lhs,
const FlatbufferDetachedBuffer<Channel> &rhs);
+
} // namespace aos
#endif // AOS_CONFIGURATION_H_
diff --git a/aos/configuration_test.cc b/aos/configuration_test.cc
index fa74e20..fc45d88 100644
--- a/aos/configuration_test.cc
+++ b/aos/configuration_test.cc
@@ -1,6 +1,7 @@
#include "aos/configuration.h"
#include "absl/strings/strip.h"
+#include "aos/events/ping_generated.h"
#include "aos/json_to_flatbuffer.h"
#include "aos/testing/flatbuffer_eq.h"
#include "aos/testing/path.h"
@@ -1007,10 +1008,47 @@
JsonToFlatbuffer<Channel>(
"{ \"name\": \"/foo\", \"type\": \".aos.bar\", \"num_readers\": 5, "
"\"num_senders\": 10 }");
-
EXPECT_EQ(QueueScratchBufferSize(&channel.message()), 15);
}
+// Tests that GetSchema returns schema of specified type
+TEST_F(ConfigurationTest, GetSchema) {
+ FlatbufferDetachedBuffer<Configuration> config =
+ ReadConfig(ArtifactPath("aos/events/pingpong_config.json"));
+ FlatbufferVector<reflection::Schema> expected_schema =
+ FileToFlatbuffer<reflection::Schema>(
+ ArtifactPath("aos/events/ping.bfbs"));
+ EXPECT_EQ(FlatbufferToJson(GetSchema(&config.message(), "aos.examples.Ping")),
+ FlatbufferToJson(expected_schema));
+ EXPECT_EQ(GetSchema(&config.message(), "invalid_name"), nullptr);
+}
+
+// Tests that GetSchema template returns schema of specified type
+TEST_F(ConfigurationTest, GetSchemaTemplate) {
+ FlatbufferDetachedBuffer<Configuration> config =
+ ReadConfig(ArtifactPath("aos/events/pingpong_config.json"));
+ FlatbufferVector<reflection::Schema> expected_schema =
+ FileToFlatbuffer<reflection::Schema>(
+ ArtifactPath("aos/events/ping.bfbs"));
+ EXPECT_EQ(FlatbufferToJson(GetSchema<aos::examples::Ping>(&config.message())),
+ FlatbufferToJson(expected_schema));
+}
+
+// Tests that GetSchemaDetachedBuffer returns detached buffer of specified type
+TEST_F(ConfigurationTest, GetSchemaDetachedBuffer) {
+ FlatbufferDetachedBuffer<Configuration> config =
+ ReadConfig(ArtifactPath("aos/events/pingpong_config.json"));
+ FlatbufferVector<reflection::Schema> expected_schema =
+ FileToFlatbuffer<reflection::Schema>(
+ ArtifactPath("aos/events/ping.bfbs"));
+ EXPECT_EQ(FlatbufferToJson(
+ GetSchemaDetachedBuffer(&config.message(), "aos.examples.Ping")
+ .value()),
+ FlatbufferToJson(expected_schema));
+ EXPECT_EQ(GetSchemaDetachedBuffer(&config.message(), "invalid_name"),
+ std::nullopt);
+}
+
} // namespace testing
} // namespace configuration
} // namespace aos
diff --git a/aos/events/event_loop_runtime.rs b/aos/events/event_loop_runtime.rs
index 360c931..023cfb6 100644
--- a/aos/events/event_loop_runtime.rs
+++ b/aos/events/event_loop_runtime.rs
@@ -370,6 +370,9 @@
MonotonicInstant(self.0.monotonic_now())
}
+ pub fn realtime_now(&self) -> RealtimeInstant {
+ RealtimeInstant(self.0.realtime_now())
+ }
/// Note that the `'event_loop` input lifetime is intentional. The C++ API requires that it is
/// part of `self.configuration()`, which will always have this lifetime.
///
@@ -711,7 +714,6 @@
where
T: Follow<'a> + 'a;
-// TODO(Brian): Add the realtime timestamps here.
impl<'a, T> TypedContext<'a, T>
where
T: Follow<'a> + 'a,
@@ -730,6 +732,12 @@
pub fn monotonic_remote_time(&self) -> MonotonicInstant {
self.0.monotonic_remote_time()
}
+ pub fn realtime_event_time(&self) -> RealtimeInstant {
+ self.0.realtime_event_time()
+ }
+ pub fn realtime_remote_time(&self) -> RealtimeInstant {
+ self.0.realtime_remote_time()
+ }
pub fn queue_index(&self) -> u32 {
self.0.queue_index()
}
@@ -750,10 +758,11 @@
T::Inner: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- // TODO(Brian): Add the realtime timestamps here.
f.debug_struct("TypedContext")
.field("monotonic_event_time", &self.monotonic_event_time())
.field("monotonic_remote_time", &self.monotonic_remote_time())
+ .field("realtime_event_time", &self.realtime_event_time())
+ .field("realtime_remote_time", &self.realtime_remote_time())
.field("queue_index", &self.queue_index())
.field("remote_queue_index", &self.remote_queue_index())
.field("message", &self.message())
@@ -1020,10 +1029,11 @@
impl fmt::Debug for Context<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- // TODO(Brian): Add the realtime timestamps here.
f.debug_struct("Context")
.field("monotonic_event_time", &self.monotonic_event_time())
.field("monotonic_remote_time", &self.monotonic_remote_time())
+ .field("realtime_event_time", &self.realtime_event_time())
+ .field("realtime_remote_time", &self.realtime_remote_time())
.field("queue_index", &self.queue_index())
.field("remote_queue_index", &self.remote_queue_index())
.field("size", &self.data().map(|data| data.len()))
@@ -1033,7 +1043,6 @@
}
}
-// TODO(Brian): Add the realtime timestamps here.
impl<'context> Context<'context> {
pub fn monotonic_event_time(self) -> MonotonicInstant {
MonotonicInstant(self.0.monotonic_event_time)
@@ -1043,6 +1052,14 @@
MonotonicInstant(self.0.monotonic_remote_time)
}
+ pub fn realtime_event_time(self) -> RealtimeInstant {
+ RealtimeInstant(self.0.realtime_event_time)
+ }
+
+ pub fn realtime_remote_time(self) -> RealtimeInstant {
+ RealtimeInstant(self.0.realtime_remote_time)
+ }
+
pub fn queue_index(self) -> u32 {
self.0.queue_index
}
@@ -1093,9 +1110,6 @@
/// Represents a `aos::monotonic_clock::time_point` in a natural Rust way. This
/// is intended to have the same API as [`std::time::Instant`], any missing
/// functionality can be added if useful.
-///
-/// TODO(Brian): Do RealtimeInstant too. Use a macro? Integer as a generic
-/// parameter to distinguish them? Or just copy/paste?
#[repr(transparent)]
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct MonotonicInstant(i64);
@@ -1125,6 +1139,34 @@
}
}
+#[repr(transparent)]
+#[derive(Clone, Copy, Eq, PartialEq)]
+pub struct RealtimeInstant(i64);
+
+impl RealtimeInstant {
+ pub const MIN_TIME: Self = Self(i64::MIN);
+
+ pub fn is_min_time(self) -> bool {
+ self == Self::MIN_TIME
+ }
+
+ pub fn duration_since_epoch(self) -> Option<Duration> {
+ if self.is_min_time() {
+ None
+ } else {
+ Some(Duration::from_nanos(self.0.try_into().expect(
+ "monotonic_clock::time_point should always be after the epoch",
+ )))
+ }
+ }
+}
+
+impl fmt::Debug for RealtimeInstant {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.duration_since_epoch().fmt(f)
+ }
+}
+
mod panic_waker {
use std::task::{RawWaker, RawWakerVTable, Waker};
diff --git a/aos/events/logging/logfile_utils.cc b/aos/events/logging/logfile_utils.cc
index a76c1a8..342cf8b 100644
--- a/aos/events/logging/logfile_utils.cc
+++ b/aos/events/logging/logfile_utils.cc
@@ -987,7 +987,13 @@
return std::nullopt;
}
- if (FLAGS_workaround_double_headers) {
+ // We only know of busted headers in the versions of the log file header
+ // *before* the logger_sha1 field was added. At some point before that point,
+ // the logic to track when a header has been written was rewritten in such a
+ // way that it can't happen anymore. We've seen some logs where the body
+ // parses as a header recently, so the simple solution of always looking is
+ // failing us.
+ if (FLAGS_workaround_double_headers && !result.message().has_logger_sha1()) {
while (true) {
absl::Span<const uint8_t> maybe_header_data = span_reader->PeekMessage();
if (maybe_header_data == absl::Span<const uint8_t>()) {
diff --git a/aos/util/BUILD b/aos/util/BUILD
index f8eb09f..bd1dbab 100644
--- a/aos/util/BUILD
+++ b/aos/util/BUILD
@@ -437,6 +437,17 @@
],
)
+cc_library(
+ name = "foxglove_websocket_lib",
+ srcs = ["foxglove_websocket_lib.cc"],
+ hdrs = ["foxglove_websocket_lib.h"],
+ deps = [
+ ":mcap_logger",
+ "//aos/events:event_loop",
+ "@com_github_foxglove_ws-protocol",
+ ],
+)
+
cc_binary(
name = "config_validator",
testonly = True,
@@ -454,3 +465,15 @@
"@com_google_googletest//:gtest",
],
)
+
+cc_binary(
+ name = "foxglove_websocket",
+ srcs = ["foxglove_websocket.cc"],
+ visibility = ["//visibility:public"],
+ deps = [
+ ":foxglove_websocket_lib",
+ "//aos:init",
+ "//aos/events:shm_event_loop",
+ "@com_github_gflags_gflags//:gflags",
+ ],
+)
diff --git a/aos/util/file.cc b/aos/util/file.cc
index 317206e..cdf0061 100644
--- a/aos/util/file.cc
+++ b/aos/util/file.cc
@@ -36,7 +36,6 @@
void WriteStringToFileOrDie(const std::string_view filename,
const std::string_view contents,
mode_t permissions) {
- ::std::string r;
ScopedFD fd(open(::std::string(filename).c_str(),
O_CREAT | O_WRONLY | O_TRUNC, permissions));
PCHECK(fd.get() != -1) << ": opening " << filename;
diff --git a/aos/util/foxglove_websocket.cc b/aos/util/foxglove_websocket.cc
new file mode 100644
index 0000000..26092bc
--- /dev/null
+++ b/aos/util/foxglove_websocket.cc
@@ -0,0 +1,46 @@
+#include "aos/events/shm_event_loop.h"
+#include "aos/init.h"
+#include "aos/util/foxglove_websocket_lib.h"
+#include "gflags/gflags.h"
+
+DEFINE_string(config, "/app/aos_config.json", "Path to the config.");
+DEFINE_uint32(port, 8765, "Port to use for foxglove websocket server.");
+
+int main(int argc, char *argv[]) {
+ gflags::SetUsageMessage(
+ "Runs a websocket server that a foxglove instance can connect to in "
+ "order to view live data on a device.\n\n"
+ "Typical Usage: foxglove_websocket [--port 8765]\n"
+ "If the default port is not exposed directly, you can port-forward with "
+ "SSH by doing\n"
+ "$ ssh -L 8765:localhost:8765 ssh_target\n\n"
+ "When accessing this in foxglove:\n"
+ "1) Open a data source (this window may be open by default).\n"
+ "2) Select \"Open Connection\"\n"
+ "3) Select \"Foxglove WebSocket\" (do NOT select the rosbridge option)\n"
+ "4) Fill out the URL for the machine. If port forwarding, the default\n"
+ " ws://localhost:8765 should work.\n\n"
+ "Note that this does not start up a foxglove instance itself. You must "
+ "either have one locally on your laptop, or go to "
+ "https://studio.foxglove.dev, or use another application to serve the "
+ "foxglove HTML pages.\n"
+ "If you want to use the studio.foxglove.dev page to view data (which "
+ "won't send any of your data to foxglove.dev--it's just needed to load "
+ "the HTML files), you can also go directly to:\n"
+ "https://studio.foxglove.dev/?ds=foxglove-websocket&ds.url=ws://"
+ "localhost:8765\n"
+ "where localhost:8765 must be updated if you aren't port-forwarding "
+ "and/or are using a different port number. Similarly, if you are serving "
+ "the static foxglove files locally, you can update the "
+ "studio.foxglove.dev to point at your local webserver.\n");
+ aos::InitGoogle(&argc, &argv);
+
+ aos::FlatbufferDetachedBuffer<aos::Configuration> config =
+ aos::configuration::ReadConfig(FLAGS_config);
+
+ aos::ShmEventLoop event_loop(&config.message());
+
+ aos::FoxgloveWebsocketServer server(&event_loop, FLAGS_port);
+
+ event_loop.Run();
+}
diff --git a/aos/util/foxglove_websocket_lib.cc b/aos/util/foxglove_websocket_lib.cc
new file mode 100644
index 0000000..b4d262a
--- /dev/null
+++ b/aos/util/foxglove_websocket_lib.cc
@@ -0,0 +1,126 @@
+#include "aos/util/foxglove_websocket_lib.h"
+
+#include "aos/util/mcap_logger.h"
+#include "gflags/gflags.h"
+
+DEFINE_uint32(sorting_buffer_ms, 100,
+ "Amount of time to buffer messages to sort them before sending "
+ "them to foxglove.");
+DEFINE_bool(fetch_pinned_channels, false,
+ "Set this to allow foxglove_websocket to make fetchers on channels "
+ "with a read_method of PIN (see aos/configuration.fbs; PIN is an "
+ "enum value). By default, we don't make fetchers for "
+ "these channels since using up a fetcher slot on PIN'd channels "
+ "can have side-effects.");
+
+namespace {
+// Period at which to poll the fetchers for all the channels.
+constexpr std::chrono::milliseconds kPollPeriod{50};
+} // namespace
+
+namespace aos {
+FoxgloveWebsocketServer::FoxgloveWebsocketServer(aos::EventLoop *event_loop,
+ uint32_t port)
+ : event_loop_(event_loop), server_(port, "aos_foxglove") {
+ for (const aos::Channel *channel :
+ *event_loop_->configuration()->channels()) {
+ const bool is_pinned = (channel->read_method() == ReadMethod::PIN);
+ if (aos::configuration::ChannelIsReadableOnNode(channel,
+ event_loop_->node()) &&
+ (!is_pinned || FLAGS_fetch_pinned_channels)) {
+ const ChannelId id =
+ server_.addChannel(foxglove::websocket::ChannelWithoutId{
+ .topic = channel->name()->str() + " " + channel->type()->str(),
+ .encoding = "json",
+ .schemaName = channel->type()->str(),
+ .schema = JsonSchemaForFlatbuffer({channel->schema()}).dump()});
+ CHECK(fetchers_.count(id) == 0);
+ fetchers_[id] =
+ FetcherState{.fetcher = event_loop_->MakeRawFetcher(channel)};
+ }
+ }
+
+ server_.setSubscribeHandler([this](ChannelId channel) {
+ if (fetchers_.count(channel) == 0) {
+ return;
+ }
+ if (active_channels_.count(channel) == 0) {
+ // Catch up to the latest message on the requested channel, then subscribe
+ // to it.
+ fetchers_[channel].fetcher->Fetch();
+ active_channels_.insert(channel);
+ }
+ });
+ server_.setUnsubscribeHandler(
+ [this](ChannelId channel) { active_channels_.erase(channel); });
+ aos::TimerHandler *timer = event_loop_->AddTimer([this]() {
+ // In order to run the websocket server, we just let it spin every cycle for
+ // a bit. This isn't great for integration, but lets us stay in control and
+ // until we either have (a) a chance to locate a file descriptor to hand
+ // epoll; or (b) rewrite the foxglove websocket server to use seasocks
+ // (which we know how to integrate), we'll just function with this.
+ // TODO(james): Tighter integration into our event loop structure.
+ server_.run_for(kPollPeriod / 2);
+
+ // Unfortunately, we can't just push out all the messages as they come in.
+ // Foxglove expects that the timestamps associated with each message to be
+ // monotonic, and if you send things out of order then it will clear the
+ // state of the visualization entirely, which makes viewing plots
+ // impossible. If the user only accesses a single channel, that is fine, but
+ // as soon as they try to use multiple channels, you encounter interleaving.
+ // To resolve this, we specify a buffer (--sorting_buffer_ms), and only send
+ // out messages older than that time, sorting everything before we send it
+ // out.
+ const aos::monotonic_clock::time_point sort_until =
+ event_loop_->monotonic_now() -
+ std::chrono::milliseconds(FLAGS_sorting_buffer_ms);
+
+ // Pair of <send_time, channel id>.
+ absl::btree_set<std::pair<aos::monotonic_clock::time_point, ChannelId>>
+ fetcher_times;
+
+ // Go through and seed fetcher_times with the first message on each channel.
+ for (const ChannelId channel : active_channels_) {
+ FetcherState *fetcher = &fetchers_[channel];
+ if (fetcher->sent_current_message) {
+ if (fetcher->fetcher->FetchNext()) {
+ fetcher->sent_current_message = false;
+ }
+ }
+ if (!fetcher->sent_current_message) {
+ const aos::monotonic_clock::time_point send_time =
+ fetcher->fetcher->context().monotonic_event_time;
+ if (send_time <= sort_until) {
+ fetcher_times.insert(std::make_pair(send_time, channel));
+ }
+ }
+ }
+
+ // Send the oldest message continually until we run out of messages to send.
+ while (!fetcher_times.empty()) {
+ const ChannelId channel = fetcher_times.begin()->second;
+ FetcherState *fetcher = &fetchers_[channel];
+ server_.sendMessage(
+ channel, fetcher_times.begin()->first.time_since_epoch().count(),
+ aos::FlatbufferToJson(
+ fetcher->fetcher->channel()->schema(),
+ static_cast<const uint8_t *>(fetcher->fetcher->context().data)));
+ fetcher_times.erase(fetcher_times.begin());
+ fetcher->sent_current_message = true;
+ if (fetcher->fetcher->FetchNext()) {
+ fetcher->sent_current_message = false;
+ const aos::monotonic_clock::time_point send_time =
+ fetcher->fetcher->context().monotonic_event_time;
+ if (send_time <= sort_until) {
+ fetcher_times.insert(std::make_pair(send_time, channel));
+ }
+ }
+ }
+ });
+
+ event_loop_->OnRun([timer, this]() {
+ timer->Setup(event_loop_->monotonic_now(), kPollPeriod);
+ });
+}
+FoxgloveWebsocketServer::~FoxgloveWebsocketServer() { server_.stop(); }
+} // namespace aos
diff --git a/aos/util/foxglove_websocket_lib.h b/aos/util/foxglove_websocket_lib.h
new file mode 100644
index 0000000..8160653
--- /dev/null
+++ b/aos/util/foxglove_websocket_lib.h
@@ -0,0 +1,43 @@
+#ifndef AOS_UTIL_FOXGLOVE_WEBSOCKET_LIB_H_
+#define AOS_UTIL_FOXGLOVE_WEBSOCKET_LIB_H_
+#include <map>
+#include <set>
+
+#include "aos/events/event_loop.h"
+#include "foxglove/websocket/server.hpp"
+
+namespace aos {
+// This class implements a live AOS -> Foxglove Websocket Protocol connection,
+// making use of the implementation at
+// https://github.com/foxglove/ws-protocol/tree/main/cpp to send JSON messages
+// to a foxglove studio client.
+// See foxglove_websocket.cc for some usage notes.
+class FoxgloveWebsocketServer {
+ public:
+ FoxgloveWebsocketServer(aos::EventLoop *event_loop, uint32_t port);
+ ~FoxgloveWebsocketServer();
+
+ private:
+ typedef foxglove::websocket::ChannelId ChannelId;
+
+ struct FetcherState {
+ std::unique_ptr<aos::RawFetcher> fetcher;
+ // Whether the current message in the fetcher has been sent to the client.
+ // Starts as true because the fetcher starts with no data.
+ // This is necessary because we have to send all of our messages out
+ // in order, which we can only do once we know the timestamp of each
+ // message. And we can only know the timestamp after having called Fetch()
+ // on the fetcher. Once we get around to actually sending the data, we can
+ // set this to true so that we know it is safe to call FetchNext() again.
+ bool sent_current_message = true;
+ };
+
+ aos::EventLoop *event_loop_;
+ foxglove::websocket::Server server_;
+ // A map of fetchers for every single channel that could be subscribed to.
+ std::map<ChannelId, FetcherState> fetchers_;
+ // The set of channels that we have clients actively subscribed to.
+ std::set<ChannelId> active_channels_;
+};
+} // namespace aos
+#endif // AOS_UTIL_FOXGLOVE_WEBSOCKET_LIB_H_
diff --git a/debian/BUILD b/debian/BUILD
index de5144d..f14db44 100644
--- a/debian/BUILD
+++ b/debian/BUILD
@@ -51,6 +51,10 @@
python_gtk_debs = "files",
)
load(
+ ":gtk_runtime.bzl",
+ gtk_runtime_debs = "files",
+)
+load(
":opencv_arm64.bzl",
opencv_arm64_debs = "files",
)
@@ -156,6 +160,33 @@
)
download_packages(
+ name = "download_gtk_runtime",
+ excludes = [
+ "libstdc++6",
+ "lsb-base",
+ "libglib2.0-dev-bin",
+ "fonts-freefont",
+ "gsettings-backend",
+ "libpng-dev",
+ "libz-dev",
+ "libstdc++-dev",
+ "libc6-dev",
+ ],
+ # Since "libglib2.0-0" pulls in glibc, we need to forcibly remove it again.
+ force_excludes = [
+ "libc6",
+ "libgcc-s1",
+ ],
+ force_includes = [
+ "libglib2.0-0",
+ ],
+ packages = [
+ "gir1.2-gtk-3.0",
+ "libgtk-3-dev",
+ ],
+)
+
+download_packages(
name = "download_python_deps",
excludes = [
"libblas.so.3",
@@ -390,6 +421,12 @@
target_compatible_with = ["@platforms//os:linux"],
)
+generate_deb_tarball(
+ name = "gtk_runtime",
+ files = gtk_runtime_debs,
+ target_compatible_with = ["@platforms//os:linux"],
+)
+
download_packages(
name = "download_opencv",
packages = [
diff --git a/debian/download_packages.py b/debian/download_packages.py
index 6d548b5..d012ff6 100755
--- a/debian/download_packages.py
+++ b/debian/download_packages.py
@@ -105,12 +105,15 @@
yield package
-def download_deps(apt_args, packages, excludes, force_includes):
+def download_deps(apt_args, packages, excludes, force_includes,
+ force_excludes):
deps = get_all_deps(apt_args, packages)
exclude_deps = get_all_deps(apt_args, excludes)
deps -= exclude_deps
force_include_deps = get_all_deps(apt_args, force_includes)
deps |= force_include_deps
+ force_exclude_deps = get_all_deps(apt_args, force_excludes)
+ deps -= force_exclude_deps
env = dict(os.environ)
del env['LD_LIBRARY_PATH']
subprocess.check_call([b"apt-get"] + [a.encode('utf-8')
@@ -173,6 +176,13 @@
action="append",
help=
"Force include this and its dependencies. Even if listed in excludes.")
+ parser.add_argument(
+ "--force-exclude",
+ type=str,
+ action="append",
+ help=
+ "Force exclude this and its dependencies. Even if listed via --force-include."
+ )
parser.add_argument("--arch",
type=str,
default="amd64",
@@ -214,7 +224,8 @@
# Exclude common packages that don't make sense to include in everything all
# the time.
excludes += _ALWAYS_EXCLUDE
- download_deps(apt_args, args.package, excludes, args.force_include)
+ download_deps(apt_args, args.package, excludes, args.force_include,
+ args.force_exclude)
fixup_files()
print_file_list()
print("Your packages are all in %s" % folder)
diff --git a/debian/gtk_runtime.BUILD b/debian/gtk_runtime.BUILD
new file mode 100644
index 0000000..e529782
--- /dev/null
+++ b/debian/gtk_runtime.BUILD
@@ -0,0 +1,12 @@
+filegroup(
+ name = "gtk_runtime",
+ srcs = glob([
+ "etc/**",
+ "lib/x86_64-linux-gnu/**/*.so*",
+ "usr/lib/**/*.so*",
+ "usr/lib/x86_64-linux-gnu/**/*",
+ "usr/share/font*/**",
+ "usr/share/gir-1.0/**",
+ ]),
+ visibility = ["//visibility:public"],
+)
diff --git a/debian/gtk_runtime.bzl b/debian/gtk_runtime.bzl
new file mode 100644
index 0000000..029419c
--- /dev/null
+++ b/debian/gtk_runtime.bzl
@@ -0,0 +1,267 @@
+files = {
+ "adwaita-icon-theme_3.38.0-1_all.deb": "2046876c82fc1c342b38ace9aa0661bcb3e167837c984b4bdc89702bc78df5ac",
+ "coreutils_8.32-4+b1_amd64.deb": "3558a412ab51eee4b60641327cb145bb91415f127769823b68f9335585b308d4",
+ "dconf-gsettings-backend_0.38.0-2_amd64.deb": "194991ed5f4ab1ca25413858cb99c910391cfd6d3b1b6a3d3e56a4b3a706a37d",
+ "dconf-service_0.38.0-2_amd64.deb": "639125f7a44d11f96661c61a07abbb58da0e5636ed406ac186adcef8651775c2",
+ "fontconfig-config_2.13.1-4.2_all.deb": "48afb6ad7d15e6104a343b789f73697301ad8bff77b69927bc998f5a409d8e90",
+ "fontconfig_2.13.1-4.2_amd64.deb": "c594a100759ef7c94149359cf4d2da5fb59ef30474c7a2dde1e049d32b9c478a",
+ "fonts-croscore_20201225-1_all.deb": "64904820b729ff40038f85683004e3b94b328d969bc0fbba263c58d635452923",
+ "fonts-dejavu-core_2.37-2_all.deb": "1f67421437b6eb18669d2868e3e02cb88668683d635198142f48aacc5b397118",
+ "fonts-freefont-otf_20120503-10_all.deb": "0b63996c80c6c660424af6d3832818e647960d6f65a51de010bb57dd0762faa7",
+ "fonts-freefont-ttf_20120503-10_all.deb": "4ca1c21ebc479198a3a5879d236c8317d6f7b2f1c403f7890e24c02eead05615",
+ "fonts-liberation2_2.1.3-1_all.deb": "e0805f0085132f5e6dd30f88c0d7260caf1e5450832fe2e3988a20fa9fa2150e",
+ "fonts-liberation_1.07.4-11_all.deb": "efd381517f958b01969343634ffcbdd60056be7779af84c6f53a005090430204",
+ "fonts-texgyre_20180621-3.1_all.deb": "cb7e9a4b2471cfdd57194c16364f9102f0639816a2662fed4b30d2a158747076",
+ "fonts-urw-base35_20200910-1_all.deb": "f95a139adb7f1b60626e76d4d45d1b35aad1bc2c2597394c291ef5f84b5dcb43",
+ "gir1.2-atk-1.0_2.36.0-2_amd64.deb": "36154c1e50e8e8013a14ce4ecfa1cf7527250beb49a2c60ac02ab2c8a40a5357",
+ "gir1.2-atspi-2.0_2.38.0-4_amd64.deb": "2b6f6d4c3de060e4f52cb7edba4c6ed9ab8d3601c4be617feac12e042df873ca",
+ "gir1.2-freedesktop_1.66.1-1+b1_amd64.deb": "60d8f35f0d67548088525543e3ff9e00934ebb5bfe7639afa45e5740e024f991",
+ "gir1.2-gdkpixbuf-2.0_2.42.2+dfsg-1+deb11u1_amd64.deb": "ba2552eb10b14b6f8ab44e28b7d638dd28de5b7e9a593e08b6f69395382a5c7b",
+ "gir1.2-glib-2.0_1.66.1-1+b1_amd64.deb": "1163a4e7eb095e37752739c0065bad50fa2177c13a87e7c1b0d44ed517fe8c91",
+ "gir1.2-gtk-3.0_3.24.24-4+deb11u2_amd64.deb": "a2a5c8e5aa3d8f7f5244464afce826485c96a0a3f2af8380fb33d8f2b2eb550d",
+ "gir1.2-harfbuzz-0.0_2.7.4-1_amd64.deb": "057b61d69437910e0350076cc0dd46d3ddb01ba181a434802aa328e81bc440d1",
+ "gir1.2-pango-1.0_1.46.2-3_amd64.deb": "0859356937e4b269201341ce410c77761fb68537ed3c317c223e7e67105ab0bb",
+ "glib-networking-common_2.66.0-2_all.deb": "a07370151ce5169e48ee7799b9bd9a7a035467a21f5cf3373b2aff090968609c",
+ "glib-networking-services_2.66.0-2_amd64.deb": "19131c7c31bc3fae604df30d2f73c3e8338ffeb2988fe167bb8b2b1c8913c9ab",
+ "glib-networking_2.66.0-2_amd64.deb": "b2cd50a8c3b30c16fd1a19c5244f681c6c0d1f426c385d44900477b052f70024",
+ "gsettings-desktop-schemas_3.38.0-2_all.deb": "3758968491a770e50cd85122c00d141944ffb43cb7a5c886a37290fef848cee3",
+ "gtk-update-icon-cache_3.24.24-4+deb11u2_amd64.deb": "b877617f382240663be1010510511a5f9fe10853a3f97088cc01be277ff184d6",
+ "hicolor-icon-theme_0.17-2_all.deb": "20304d34b85a734ec1e4830badf3a3a70a5dc5f9c1afc0b2230ecd760c81b5e0",
+ "icu-devtools_67.1-7_amd64.deb": "0a89d6f360d9c686c08d0156a0c8244715c9aaeffca079cf1716f12cffece82e",
+ "libatk-bridge2.0-0_2.38.0-1_amd64.deb": "65b063b4b45c5fd60d91e374d01bb73eacdb30c545a6ef0873d07d6da97765d1",
+ "libatk-bridge2.0-dev_2.38.0-1_amd64.deb": "04be11ea79e542a4eea20977e23557c5cc21427e93c354d69b86586f81d248c7",
+ "libatk1.0-0_2.36.0-2_amd64.deb": "572cd62f92ec25c75b98617321373d46a6717cbcc93d2025ebd6d550f1abf901",
+ "libatk1.0-data_2.36.0-2_all.deb": "86c1acae473977f8a78b905090847df654306996324493f9a39d9f27807778b2",
+ "libatk1.0-dev_2.36.0-2_amd64.deb": "8a107ce46427f5cf68076eb0ab7e9b09f0237cb2674499da582c5a29cfc94d72",
+ "libatspi2.0-0_2.38.0-4_amd64.deb": "53435278eb8815aafbb41db29a691a43a9de16fa58d9bc7908a1f6f2a07f0b67",
+ "libatspi2.0-dev_2.38.0-4_amd64.deb": "fbbb10ba97dbfc79c5c1edc223e606c792332a47d242b21b1dea5c9bae5dbc2c",
+ "libattr1_2.4.48-6_amd64.deb": "af3c3562eb2802481a2b9558df1b389f3c6d9b1bf3b4219e000e05131372ebaf",
+ "libavahi-client3_0.8-5+deb11u1_amd64.deb": "44104ae278d853f9d20b90a6192257497d430f3ff4af093af1c504effb9caf4f",
+ "libavahi-common-data_0.8-5+deb11u1_amd64.deb": "847c7050a234915514a967e2edbf8b1a02fe5451bb910f9bdeffda0688280fce",
+ "libavahi-common3_0.8-5+deb11u1_amd64.deb": "d5d97f84a894e6ef0e535a17d1dcc1ed64933d6e04a350306e989d05b37de00c",
+ "libblkid-dev_2.36.1-8+deb11u1_amd64.deb": "3f224b3dc4d094367b45b31c4bc367dd9528f45eba22af77229a7f9be7e6005d",
+ "libblkid1_2.36.1-8+deb11u1_amd64.deb": "9026ddd9f211008531ce6024d5ce042c723e237ecadfbf1f9343cb44aff492b9",
+ "libbrotli-dev_1.0.9-2+b2_amd64.deb": "520ef8f3af1a190ac2ce5954c0e42c8e6b80a593124f97e813be33e9e068ffc3",
+ "libbrotli1_1.0.9-2+b2_amd64.deb": "65ca7d8b03e9dac09c5d544a89dd52d1aeb74f6a19583d32e4ff5f0c77624c24",
+ "libbsd0_0.11.3-1_amd64.deb": "284a7b8dcfcad74770f57360721365317448b38ab773db542bf630e94e60c13e",
+ "libcairo-gobject2_1.16.0-5_amd64.deb": "a046d3ca805d4151029941fae736bfdf1c6f3dbcf1bd581102bd5ad844ea013e",
+ "libcairo-script-interpreter2_1.16.0-5_amd64.deb": "c1c47955283d36ccadbdfd88eef515063d28fdc20c751d70c863b18ca190ec8a",
+ "libcairo2-dev_1.16.0-5_amd64.deb": "a8ba01e9d19a1a4f512e7fa1ba1c089e2ace1a5b08733e167b9bea3fe86766de",
+ "libcairo2_1.16.0-5_amd64.deb": "b27210c0cf7757120e871abeba7de12a5cf94727a2360ecca5eb8e50ca809d12",
+ "libcolord2_1.4.5-3_amd64.deb": "b7f0b90535a04f25f4fe8a838b548eed87447b3225414bd4f30755ee917698dd",
+ "libcups2_2.3.3op2-3+deb11u2_amd64.deb": "67c6cf6ba6259468660da16676fcb7ac77cf4a14ca812a60375ca26263a7b273",
+ "libdatrie-dev_0.2.13-1_amd64.deb": "0885c9b6c0a448b1faaa5fa51f3b751b986f33e48ca98ae901413c22a4a6e5a3",
+ "libdatrie1_0.2.13-1_amd64.deb": "3544f2cf26039fade9c7e7297dde1458b8386442c3b0fc26fdf10127433341c1",
+ "libdbus-1-3_1.12.20-2_amd64.deb": "7256dfeda88461e6fccbf98372d3ec29487b3b2d0ae5d145a3332ab35274f0da",
+ "libdbus-1-dev_1.12.20-2_amd64.deb": "0bf0161cb23cf6d3adb3b7d5b701b982a65ad1ecff21e6267e69d803b1d88108",
+ "libdconf1_0.38.0-2_amd64.deb": "ff3b1d05466782acd6e335b001460b7af4ea76f49bbbbd5447535d2b702fa97e",
+ "libdeflate0_1.7-1_amd64.deb": "dadaf0d28360f6eb21ad389b2e0f12f8709c9de539b28de9c11d7ec7043dec95",
+ "libdpkg-perl_1.20.12_all.deb": "62b6da489682a684c8224a2cca0fc83d239846696cca5f67d5699c1df14b56ea",
+ "libdrm-amdgpu1_2.4.104-1_amd64.deb": "0005f21e342925bd26a25185289ae035aa931ced8f6fd9e3d4deade36d272ecd",
+ "libdrm-common_2.4.104-1_all.deb": "60c69026fb8e4cfdf8d80a4a86ee30516c611dcc4de4aa1c8ccbf06dff563e2b",
+ "libdrm-intel1_2.4.104-1_amd64.deb": "7d376adc7b5d4d83ec8414ff67dbc18765c6d420de9a6e1045fead7f1f82331d",
+ "libdrm-nouveau2_2.4.104-1_amd64.deb": "dbf4a3be55c609b1a2ea89d6782ae5c9a5b991844917dcd42c01666b73a96ceb",
+ "libdrm-radeon1_2.4.104-1_amd64.deb": "c33cd14e8ed7e2dfc02696ed51d4795c5797b0821666667e0a889bba705862b0",
+ "libdrm2_2.4.104-1_amd64.deb": "113396b3a33000f7f3347cd711ad9bcfe9945927331cc6cee63c751a889a967b",
+ "libedit2_3.1-20191231-2+b1_amd64.deb": "ac545f6ad10ba791aca24b09255ad1d6d943e6bc7c5511d5998e104aee51c943",
+ "libegl-dev_1.3.2-1_amd64.deb": "2847662b23487d5b1e467bca8cc8753baa880f794744a9b492c978bd5514b286",
+ "libegl-mesa0_20.3.5-1_amd64.deb": "a0c36a3665af89cbc96f865bd1b64c6c07b93096e91ba5b470d375d02dfa6d82",
+ "libegl1-mesa-dev_20.3.5-1_amd64.deb": "7b8139acb2e43a50fd952d54b41449baf13b404f65dccf187ae7852f028104f9",
+ "libegl1_1.3.2-1_amd64.deb": "3a5583ebd7a9d8ad102484db9637c409561428d21345037b310c4ef2ca8e8837",
+ "libelf1_0.183-1_amd64.deb": "e1ad132d502b255023c222d0cae1d02ca941f6b68fd0e9b908c6004cc326592c",
+ "libepoxy-dev_1.5.5-1_amd64.deb": "3979a7f81ffe10efcb1dcc3bd6e3ced5a88d1fe0ed68b12fb4cc4133b3e3d1b1",
+ "libepoxy0_1.5.5-1_amd64.deb": "3d050c9b138872c83b5b3521c97ab89f8a885b1391fdd0477cf8168ae54728a3",
+ "libexpat1-dev_2.2.10-2+deb11u4_amd64.deb": "fcf045732259c7303b8a2da0b2047e6823898cf3b0d7a40ece5dc6ad099a226a",
+ "libexpat1_2.2.10-2+deb11u4_amd64.deb": "d482f5d15353291e3a9e58c382d2ad3a412f028d3e553695a12f002c70b5a256",
+ "libffi-dev_3.3-6_amd64.deb": "ca2c71d9c68b1944b689606f12acf8023bad1b5083e8413894fd41ad0b977d20",
+ "libffi7_3.3-6_amd64.deb": "30ca89bfddae5fa6e0a2a044f22b6e50cd17c4bc6bc850c579819aeab7101f0f",
+ "libfontconfig-dev_2.13.1-4.2_amd64.deb": "7655d4238ee7e6ced13501006d20986cbf9ff08454a4e502d5aa399f83e28876",
+ "libfontconfig1-dev_2.13.1-4.2_amd64.deb": "a19502912fb57c1e9c87efbd7b7adad7f1c1b793164580ddf02168f0cfec59fb",
+ "libfontconfig1_2.13.1-4.2_amd64.deb": "b92861827627a76e74d6f447a5577d039ef2f95da18af1f29aa98fb96baea4c1",
+ "libfreetype-dev_2.10.4+dfsg-1+deb11u1_amd64.deb": "f0f5ece4c70fad68c8bdbe3cd09a5c9fb7d6112766f0d96439a45a9ae1aaf363",
+ "libfreetype6-dev_2.10.4+dfsg-1+deb11u1_amd64.deb": "ca1305fc7e3668f591ffc0e793569c7076dcf6d4765d8cf5cde7485fc7110beb",
+ "libfreetype6_2.10.4+dfsg-1+deb11u1_amd64.deb": "b21cfdd12adf6cac4af320c2485fb62a8a5edc6f9768bc2288fd686f4fa6dfdf",
+ "libfribidi-dev_1.0.8-2+deb11u1_amd64.deb": "b52de25f728d81b45440d5ad2458ca9809de700e8ee364320703d279e0ed4358",
+ "libfribidi0_1.0.8-2+deb11u1_amd64.deb": "690a889adfbe4e656e33b512dc1099cf29328632d684527dcfd4862810c5ee56",
+ "libgbm1_20.3.5-1_amd64.deb": "2d9b07282e46e3c9398613b6d4fe86c3259e4326b158be7e1f4f58cab541156c",
+ "libgcrypt20_1.8.7-6_amd64.deb": "7a2e0eef8e0c37f03f3a5fcf7102a2e3dc70ba987f696ab71949f9abf36f35ef",
+ "libgdk-pixbuf-2.0-0_2.42.2+dfsg-1+deb11u1_amd64.deb": "c593621089e9f8a8b5012de2cec9c835fdd64d0c42344423fc0a904c82e4967b",
+ "libgdk-pixbuf-2.0-dev_2.42.2+dfsg-1+deb11u1_amd64.deb": "9a0b3467e24b4369cffe154b55996d74270426b621748ae28044579c3a96e14b",
+ "libgdk-pixbuf-xlib-2.0-0_2.40.2-2_amd64.deb": "c11e9c92534e1e8036ad33a7ee1962b120834a02c41594cdf90ce01855ba84a4",
+ "libgdk-pixbuf-xlib-2.0-dev_2.40.2-2_amd64.deb": "5769f16c81c72ce50bd2aa8a7724b511d84ab411f9f23d5ef79b40fbd59c57e9",
+ "libgdk-pixbuf2.0-bin_2.42.2+dfsg-1+deb11u1_amd64.deb": "90ed931ec0abee05a6c8141ed6de98550f04c51a09500488fd5db1064437aac7",
+ "libgdk-pixbuf2.0-common_2.42.2+dfsg-1+deb11u1_all.deb": "e99738118ad4a63a4cfd7e34006fd379dd850b9527ec464a104b178a5038b5be",
+ "libgdk-pixbuf2.0-dev_2.40.2-2_amd64.deb": "98d1fe8b2fc224569a04d18f4a0efd6d5482feb47f85b1f4f3e149972a44a93e",
+ "libgirepository-1.0-1_1.66.1-1+b1_amd64.deb": "787e913bf56f19bc54720c3463ab8afe1cc9442536fde31e2a36afc3939f28c9",
+ "libgl-dev_1.3.2-1_amd64.deb": "a6487873f2706bbabf9346cdb190f47f23a1464f31cecf92c363bac37c342f2f",
+ "libgl1-mesa-dri_20.3.5-1_amd64.deb": "08e8bc20077e188da7061f77d23a336782d8463c0cc112fabbfa9c8b45923fd2",
+ "libgl1_1.3.2-1_amd64.deb": "f300f9610b5f05f1ce566c4095f1bf2170e512ac5d201c40d895b8fce29dec98",
+ "libglapi-mesa_20.3.5-1_amd64.deb": "aa8f8eaf13224cbb8729416be79350460f7f2230193b2da5d5e24f3dc7e9985f",
+ "libgles-dev_1.3.2-1_amd64.deb": "969e9197d8b8a36780f9b5d86f7c3066cdfef9dd7cdc3aee59a1870415c53578",
+ "libgles1_1.3.2-1_amd64.deb": "18425a2558be1de779c7c71ce780b133381f0db594a901839c6ae3d8e3f3c966",
+ "libgles2_1.3.2-1_amd64.deb": "367116f5e3b3a003a80203848b5ce1401451a67c2b2b9d6a383efc91badb0724",
+ "libglib2.0-0_2.66.8-1_amd64.deb": "995469490dcc8f667df8051a39dd5abd7149d849456c28af4e58cbfd6d6dc4f8",
+ "libglib2.0-bin_2.66.8-1_amd64.deb": "5adf4c916832ad4203fed68faacd4552361cbccc22f66f4504a7ad6fc955bddd",
+ "libglib2.0-data_2.66.8-1_all.deb": "be41a674336cefd00e2a468fe19c8bbf9f3fac86f39379e1b7acbad41f6af644",
+ "libglib2.0-dev_2.66.8-1_amd64.deb": "782fcfd549266048309b8da556377c16445bafe9f0aec31d9f246ac9b736d2aa",
+ "libglvnd-dev_1.3.2-1_amd64.deb": "e330ccbe6338789fd63212b55009dcce733265799395ad55b300cd1427234e7f",
+ "libglvnd0_1.3.2-1_amd64.deb": "52a4464d181949f5ed8f7e55cca67ba2739f019e93fcfa9d14e8d65efe98fffc",
+ "libglx-dev_1.3.2-1_amd64.deb": "5a50549948bc4363eab32b1083dad2165402c3628f2ee85e9a32563228cc61c1",
+ "libglx-mesa0_20.3.5-1_amd64.deb": "2d19e2addfbea965220e62f512318351f12bdfe7e180f265f00d0f2834a77833",
+ "libglx0_1.3.2-1_amd64.deb": "cb642200f7e28e6dbb4075110a0b441880eeec35c8a00a2198c59c53309e5e17",
+ "libgmp10_6.2.1+dfsg-1+deb11u1_amd64.deb": "fc117ccb084a98d25021f7e01e4dfedd414fa2118fdd1e27d2d801d7248aebbc",
+ "libgnutls30_3.7.1-5+deb11u2_amd64.deb": "ca2dbeb934a985f3ee1204f7a58001535ce49e8f8575d3fea08efbd4640773f1",
+ "libgpg-error0_1.38-2_amd64.deb": "16a507fb20cc58b5a524a0dc254a9cb1df02e1ce758a2d8abde0bc4a3c9b7c26",
+ "libgraphite2-3_1.3.14-1_amd64.deb": "31113b9e20c89d3b923da0540d6f30535b8d14f32e5904de89e34537fa87d59a",
+ "libgraphite2-dev_1.3.14-1_amd64.deb": "aa0437ff7c38b6e68a0bbcc3f18163677372e99fe3ec9673a552d8a8521aba64",
+ "libgtk-3-0_3.24.24-4+deb11u2_amd64.deb": "f58fcba87f2b7cb03a0f9f174817cc2ef18cd5dcfe41129b618ec3b7d5e0f8a0",
+ "libgtk-3-common_3.24.24-4+deb11u2_all.deb": "172d01f359af8f13cee93dba183e282ea5f059f2a418dfe66d35abf9dd60ddd7",
+ "libgtk-3-dev_3.24.24-4+deb11u2_amd64.deb": "24e7547f68a920c7d85ec38a102ba625e7f73d38ee2e7a494ba8b25eaf608062",
+ "libharfbuzz-dev_2.7.4-1_amd64.deb": "e2b5b9331990dc71da22fe05529cc72220e5449bcb98b08338c00e2f697cca65",
+ "libharfbuzz-gobject0_2.7.4-1_amd64.deb": "3c3cbf4150275173e7b4cdb0b12b8670867e70c27c0a31fd6559f4ce68a7dd84",
+ "libharfbuzz-icu0_2.7.4-1_amd64.deb": "43b41efde4c41c04b067f1d2917f33cb2d6a56b8e5d770e53ee71d7debdd241b",
+ "libharfbuzz0b_2.7.4-1_amd64.deb": "c76825341b5877240ff2511a376844a50ffda19d9d019ae65a5b3a97f9a1a183",
+ "libhogweed6_3.7.3-1_amd64.deb": "6aab2e892cdb2dfba45707601bc6c3b19aa228f70ae5841017f14c3b0ca3d22f",
+ "libice-dev_1.0.10-1_amd64.deb": "9d111d7e07104f7b9cc284d32e811ab01f376613f163b0580fbd7b61440ff669",
+ "libice6_1.0.10-1_amd64.deb": "452796e565c9d42386bd59990000ae9c37d85e142e00ee2b14df0787e2bbf970",
+ "libicu-dev_67.1-7_amd64.deb": "7932a6acfbfd76e1dbedcf171dafda9e549b8dc179a666043dbb3d5b733c4a29",
+ "libicu67_67.1-7_amd64.deb": "2bf5c46254f527865bfd6368e1120908755fa57d83634bd7d316c9b3cfd57303",
+ "libidn2-0_2.3.0-5_amd64.deb": "cb80cd769171537bafbb4a16c12ec427065795946b3415781bc9792e92d60b59",
+ "libjbig0_2.1-3.1+b2_amd64.deb": "9646d69eefce505407bf0437ea12fb7c2d47a3fd4434720ba46b642b6dcfd80f",
+ "libjpeg62-turbo_2.0.6-4_amd64.deb": "28de780a1605cf501c3a4ebf3e588f5110e814b208548748ab064100c32202ea",
+ "libjson-glib-1.0-0_1.6.2-1_amd64.deb": "c2db69dda6ceda43065d694c5ebd515900dd38d7231a74016f10a2d2a870f01d",
+ "libjson-glib-1.0-common_1.6.2-1_all.deb": "a938ec35a20dca2e5878a8750fb44683b67a5f7c2d23d383963803a9fcfac1a3",
+ "liblcms2-2_2.12~rc1-2_amd64.deb": "0608ecb6ed258814e390b52b3fb50f2a6d3239b5ecb1086292ae08be00a67b0f",
+ "libllvm11_11.0.1-2_amd64.deb": "eaff3c8dd6039af90b8b6bdbf33433e35d8c808a7aa195d0e3800ef5e61affff",
+ "liblz4-1_1.9.3-2_amd64.deb": "79ac6e9ca19c483f2e8effcc3401d723dd9dbb3a4ae324714de802adb21a8117",
+ "liblzo2-2_2.10-2_amd64.deb": "4f08e092c76e425295a498cd547dc9b8f6a595473f3020ab8c96309b29872636",
+ "libmd0_1.0.3-3_amd64.deb": "9e425b3c128b69126d95e61998e1b5ef74e862dd1fc953d91eebcc315aea62ea",
+ "libmount-dev_2.36.1-8+deb11u1_amd64.deb": "e2ab59f02398ff5f50d58ba5702a3dc27d47b6b028fccab03d0e8060e317f328",
+ "libmount1_2.36.1-8+deb11u1_amd64.deb": "a3d8673804f32e9716e33111714e250b6f1092770a52e21fab99d0ab4b48c5d9",
+ "libnettle8_3.7.3-1_amd64.deb": "e4f8ec31ed14518b241eb7b423ad5ed3f4a4e8ac50aae72c9fd475c569582764",
+ "libopengl-dev_1.3.2-1_amd64.deb": "7e598e73830ffb5d6fae58ebd1c769b6f7806dc92bd5649893b74f1302b47e82",
+ "libopengl0_1.3.2-1_amd64.deb": "4327a9f20b88e7bcb07af3b196121096877331b61eeed64467854eb0b525fc43",
+ "libp11-kit0_0.23.22-1_amd64.deb": "bfef5f31ee1c730e56e16bb62cc5ff8372185106c75bf1ed1756c96703019457",
+ "libpango-1.0-0_1.46.2-3_amd64.deb": "cfb3079a7397cc7d50eabe28ea70ce15ba371c84efafd8f8529ee047e667f523",
+ "libpango1.0-dev_1.46.2-3_amd64.deb": "5da5a8009ab6275b12193e277bf6d091b29203f058d246d5b8a184d1c7f0cde6",
+ "libpangocairo-1.0-0_1.46.2-3_amd64.deb": "f0489372e4bcb153d750934eb3cddd9104bc3a46d564aa10bef320ba89681d37",
+ "libpangoft2-1.0-0_1.46.2-3_amd64.deb": "78067d7222459902e22da6b4c1ab8ee84940752d25a5f3dea1a43f846a8562e3",
+ "libpangoxft-1.0-0_1.46.2-3_amd64.deb": "621545808843e84288039a55df16023ff872f48b3a155788dba7a1cea25c7a9b",
+ "libpciaccess0_0.16-1_amd64.deb": "f581ced157bd475477337860e7e7fcabeeb091444bc5a189c5c97adc8fcabda5",
+ "libpcre16-3_8.39-13_amd64.deb": "04ef146b0119a8a5ab1df09d990bd61a45bf99d2989aa248ebc7f72dbb99544e",
+ "libpcre2-16-0_10.36-2+deb11u1_amd64.deb": "386fc5684d0339469f0910aefc96f12d2b058dc22d096605f483a56475a37d39",
+ "libpcre2-32-0_10.36-2+deb11u1_amd64.deb": "b6d6b388adb390aae0690c0398b813222b0ed16a1705b8fb2acd1d190c03936a",
+ "libpcre2-8-0_10.36-2+deb11u1_amd64.deb": "ee192c8d22624eb9d0a2ae95056bad7fb371e5abc17e23e16b1de3ddb17a1064",
+ "libpcre2-dev_10.36-2+deb11u1_amd64.deb": "bd4bf9a13dc86c14b6ed8d822d5c8eb66b80418fe8a0484fe1cd6836a8381c49",
+ "libpcre2-posix2_10.36-2+deb11u1_amd64.deb": "f19dc0b4145836eb0c5ce462e16f546fb5298b9186d760d829cd0c171d0a2afd",
+ "libpcre3-dev_8.39-13_amd64.deb": "e588a2bd07e2770ad2fa9e3b02e359d3ff3c6f0c17a809365d3e97da7b0e64e0",
+ "libpcre32-3_8.39-13_amd64.deb": "961135f3ff2d00c2e46640b9730d9ddef80ae9d9037e2ec882ee8f6ce5dd48c9",
+ "libpcre3_8.39-13_amd64.deb": "48efcf2348967c211cd9408539edf7ec3fa9d800b33041f6511ccaecc1ffa9d0",
+ "libpcrecpp0v5_8.39-13_amd64.deb": "79e15b8d31f8561ad1c19f8c280d0a9fe280f7872701ef53c9bdfce6b3015a18",
+ "libpixman-1-0_0.40.0-1_amd64.deb": "55236a7d4b9db107eb480ac56b3aa786572ea577ba34323baf46aceb7ba6d012",
+ "libpixman-1-dev_0.40.0-1_amd64.deb": "bcde62aee0fe759798e8a4d3a3d9b0666ba5ab15d1cb9e69fa000ff23ba305cb",
+ "libproxy1v5_0.4.17-1_amd64.deb": "b21c1524b972dd72387ecb8b12c0a860738ce0832ed18fe7ffb9da6adc9b9e41",
+ "libpsl5_0.21.0-1.2_amd64.deb": "d716f5b4346ec85bb728f4530abeb1da4a79f696c72d7f774c59ba127c202fa7",
+ "libpthread-stubs0-dev_0.4-1_amd64.deb": "54632f160e1e8a43656a87195a547391038c4ca0f53291b849cd4457ba5dfde9",
+ "librest-0.7-0_0.8.1-1.1_amd64.deb": "5cd57a96145a362bf60428315ab3fc6c2f528ab38a06a905da2568575c23bdc8",
+ "libselinux1-dev_3.1-3_amd64.deb": "16b14d7e8ed88b9b07d1b52d84d04ab2fcdfcdc4b8cecc9dd34df06f3ce7d3fb",
+ "libselinux1_3.1-3_amd64.deb": "339f5ede10500c16dd7192d73169c31c4b27ab12130347275f23044ec8c7d897",
+ "libsensors-config_3.6.0-7_all.deb": "4265811140a591d27c99d026b63707d8235d98c73d7543c66ab9ec73c28523fc",
+ "libsensors5_3.6.0-7_amd64.deb": "b9cb9a081ea3c9b68ef047d7e51f3b84bccde1a2467d5657df4c5d54775b187e",
+ "libsepol1-dev_3.1-1_amd64.deb": "1bec586de489db87c8746a6eeed27982915fc578c91e9e78ef39773ab824e023",
+ "libsepol1_3.1-1_amd64.deb": "b6057dc6806a6dfaef74b09d84d1f18716d7a6d2f1da30520cef555210c6af62",
+ "libsm-dev_1.2.3-1_amd64.deb": "2ff8641d3217dc1a0f26514f5d8de2009669423a4aa0db46b3df564a8b367026",
+ "libsm6_1.2.3-1_amd64.deb": "22a420890489023346f30fecef14ea900a0788e7bf959ef826aabb83944fccfb",
+ "libsoup-gnome2.4-1_2.72.0-2_amd64.deb": "7fdc774b567e3a5e0881aa01fcfcac637fdeeb8ea6233b710571e1f5b3a994b6",
+ "libsoup2.4-1_2.72.0-2_amd64.deb": "32dad5305be0faa619df36688a20d187ba915f02e9e184cc5c3c6e3d98259e9c",
+ "libsqlite3-0_3.34.1-3_amd64.deb": "a0b8d3acf4a0483048637637d269be93af48d5c16f6f139f53edd13384ad4686",
+ "libsystemd0_247.3-7+deb11u1_amd64.deb": "0bce44fd32e9fa18b68cb89f4010939b9984b9782db2d1985b041fc96e9a02b8",
+ "libtasn1-6_4.16.0-2_amd64.deb": "fd7a200100298c2556e67bdc1a5faf5cf21c3136fa47f381d7e9769233ee88a1",
+ "libthai-data_0.1.28-3_all.deb": "64750cb822e54627a25b5a00cde06e233b5dea28571690215f672af97937f01b",
+ "libthai-dev_0.1.28-3_amd64.deb": "b633b5fbe6220f69fe78019817a3176124e64c5e402cf1142bac14ec93bfbb4b",
+ "libthai0_0.1.28-3_amd64.deb": "446e2b6e8e8a0f5f6c0de0a40c2aa4e1c2cf806efc450c37f5358c7ff1092d6a",
+ "libtiff5_4.2.0-1+deb11u1_amd64.deb": "b22d25e14421a36c4c3b721c04c6312d79ccd91c9a0e2291f58e36b8d4a07fbb",
+ "libtinfo6_6.2+20201114-2_amd64.deb": "aeaf942c71ecc0ed081efdead1a1de304dcd513a9fc06791f26992e76986597b",
+ "libudev1_247.3-7+deb11u1_amd64.deb": "6c654be062de0fd8696808cbc0bfd5ff81e7163c14f0136a132090eda2363831",
+ "libunistring2_0.9.10-4_amd64.deb": "654433ad02d3a8b05c1683c6c29a224500bf343039c34dcec4e5e9515345e3d4",
+ "libuuid1_2.36.1-8+deb11u1_amd64.deb": "31250af4dd3b7d1519326a9a6764d1466a93d8f498cf6545058761ebc38b2823",
+ "libvulkan1_1.2.162.0-1_amd64.deb": "8b3a6e5db7d8bdc369a0d276bfae1551ffc0fa31dbd193d56655c8f553868361",
+ "libwayland-bin_1.18.0-2~exp1.1_amd64.deb": "774e97053d524549044b332469d13eec70c989b4bc00a592019512c17a92978e",
+ "libwayland-client0_1.18.0-2~exp1.1_amd64.deb": "4baf16bb3a35823251453368ee078b6be6a14f97b05c19783b5acd4232a608ea",
+ "libwayland-cursor0_1.18.0-2~exp1.1_amd64.deb": "1b48d1d8e17a95b28a2876c7f2a95667ee1618a5f586d4dff05aeb09488172cb",
+ "libwayland-dev_1.18.0-2~exp1.1_amd64.deb": "3265bf05c0cea760d0e8f5fb5fc68b0f154911de23503e02232dfa59f6b6490c",
+ "libwayland-egl1_1.18.0-2~exp1.1_amd64.deb": "b98e636f08eca9e818e326fc8cd75810dbb50b1ed4e3586c2394e11248e29275",
+ "libwayland-server0_1.18.0-2~exp1.1_amd64.deb": "1df9a6e304bdaebdd53e1044c6eadcda95c914119e9426c2866eaa619a49c85b",
+ "libwebp6_0.6.1-2.1_amd64.deb": "52bfd0f8d3a1bbd2c25fcd72fab857d0f24aea35874af68e057dde869ae3902c",
+ "libx11-6_1.7.2-1_amd64.deb": "086bd667fc07369472a923da015d182bb0c15a72228a5c0e6ddbcbeaab70acd2",
+ "libx11-data_1.7.2-1_all.deb": "049b7eabced516acfdf44a5e81c26d108b16e4987e5d7604ea53eaade74027fb",
+ "libx11-dev_1.7.2-1_amd64.deb": "11e5f9dcded1a1226b3ee02847b86edce525240367b3989274a891a43dc49f5f",
+ "libx11-xcb1_1.7.2-1_amd64.deb": "1f9f2dbe7744a2bb7f855d819f43167df095fe7d5291546bec12865aed045e0c",
+ "libxau-dev_1.0.9-1_amd64.deb": "d1a7f5d484e0879b3b2e8d512894744505e53d078712ce65903fef2ecfd824bb",
+ "libxau6_1.0.9-1_amd64.deb": "679db1c4579ec7c61079adeaae8528adeb2e4bf5465baa6c56233b995d714750",
+ "libxcb-dri2-0_1.14-3_amd64.deb": "fbfc7d55fa00ab7068d015c185363370215c857ac9484d7020c2d9c38c8401b2",
+ "libxcb-dri3-0_1.14-3_amd64.deb": "4dd503b321253f210fe546aae8fe5061fc7d30015cf5580d7843432a71ebc772",
+ "libxcb-glx0_1.14-3_amd64.deb": "61ae35a71148038aad04b021b3adfa0dee4fc06d98e045ec9edfd9e850324876",
+ "libxcb-present0_1.14-3_amd64.deb": "7937af87426de2ed382ba0d6204fee58f4028b332625e2727ebb7ca9a1b32028",
+ "libxcb-render0-dev_1.14-3_amd64.deb": "f3335e206e938c760df5f933e35f370e850050e5c2c9ce0568f190970a6cac41",
+ "libxcb-render0_1.14-3_amd64.deb": "3d653df34e5cd35a78a9aff1d90c18ec0200e5574e27bc779315b855bea2ecc0",
+ "libxcb-shm0-dev_1.14-3_amd64.deb": "283d20ecde030b6905e7042f427a434a6334556a6475b11422278919f4c0c840",
+ "libxcb-shm0_1.14-3_amd64.deb": "0751b48b1c637b5b0cb080159c29b8dd83af8ec771a21c8cc26d180aaab0d351",
+ "libxcb-sync1_1.14-3_amd64.deb": "53e7f18c8a95b2be2024537a753b6bd914af5f4c7aeed175f61155a5a3c8fe88",
+ "libxcb-xfixes0_1.14-3_amd64.deb": "939b29a4eaad5972ba379c2b5f29cf51d7d947b10e68cc2fe96238efcd3d63c2",
+ "libxcb1-dev_1.14-3_amd64.deb": "b75544f334c8963b8b7b0e8a88f8a7cde95a714dddbcda076d4beb669a961b58",
+ "libxcb1_1.14-3_amd64.deb": "d5e0f047ed766f45eb7473947b70f9e8fddbe45ef22ecfd92ab712c0671a93ac",
+ "libxcomposite-dev_0.4.5-1_amd64.deb": "6aecea058e55f46341be898d6e21b933fee5a314e3133ec33b4b88441e7d52b4",
+ "libxcomposite1_0.4.5-1_amd64.deb": "4c26ebf519d2ebc22fc1416dee45e12c4c4ef68aa9b2ed890356830df42b652a",
+ "libxcursor-dev_1.2.0-2_amd64.deb": "c84c43ad4d596bd673288f6035ced4755468b873149181936a0c1fc99cff78aa",
+ "libxcursor1_1.2.0-2_amd64.deb": "d9fee761e4c50572c3ce3c3965b70fcfecd277d0d7d598e102134d12757a3d11",
+ "libxdamage-dev_1.1.5-2_amd64.deb": "34a580b62466411b34a0be2bb0d00c3ec268da96e80d0adc40b379c97e9bac37",
+ "libxdamage1_1.1.5-2_amd64.deb": "1acf6d6117929a7df346d355caeb579798d75feb7e3b3aae58a2d1af735b444f",
+ "libxdmcp-dev_1.1.2-3_amd64.deb": "c6733e5f6463afd261998e408be6eb37f24ce0a64b63bed50a87ddb18ebc1699",
+ "libxdmcp6_1.1.2-3_amd64.deb": "ecb8536f5fb34543b55bb9dc5f5b14c9dbb4150a7bddb3f2287b7cab6e9d25ef",
+ "libxext-dev_1.3.3-1.1_amd64.deb": "0aa17565287ca8a37914e043789ee33c6e1f987acf346dac7175165009c5db7c",
+ "libxext6_1.3.3-1.1_amd64.deb": "dc1ff8a2b60c7dd3c8917ffb9aa65ee6cda52648d9150608683c47319d1c0c8c",
+ "libxfixes-dev_5.0.3-2_amd64.deb": "bacfcd67ca931839a2e2ae87922ecb40e2870470afa86d0c7245288825da2340",
+ "libxfixes3_5.0.3-2_amd64.deb": "58622d0d65c3535bd724c4da62ae7acb71e0e8f527bcbd65daf8c97e6f0ef843",
+ "libxft-dev_2.3.2-2_amd64.deb": "c6919b13423d4e3b41b7650b2d9bb6f6deac2906b3d51d047b5898a169ebc13c",
+ "libxft2_2.3.2-2_amd64.deb": "cd71384b4d511cba69bcee29af326943c7ca12450765f44c40d246608c779aad",
+ "libxi-dev_1.7.10-1_amd64.deb": "736309ff476f0e1594f855cf44e2fb20bf1e594518ce2259eb9b2dd93917f2db",
+ "libxi6_1.7.10-1_amd64.deb": "4d583f43b5396ca5434100a7274613e9983357d80875a47b29a4f3218fe0bec0",
+ "libxinerama-dev_1.1.4-2_amd64.deb": "18047f52c3a1294d61bc2642d22d05bd879c15393c4e8b4ac2ee6a5061585b9b",
+ "libxinerama1_1.1.4-2_amd64.deb": "f692c854935571ee44fe313541d8a9f678a4f11dc513bc43b9d0a501c6dff0bd",
+ "libxkbcommon-dev_1.0.3-2_amd64.deb": "1202d8c64e670876b58f5b3d3f797b1848ec462f7caeef8b1e597ecea18570b6",
+ "libxkbcommon0_1.0.3-2_amd64.deb": "d74d0b9f0a6641b44c279644c7ac627fa7a9b92350b7c6ff37da94352885bcfc",
+ "libxml2_2.9.10+dfsg-6.7+deb11u2_amd64.deb": "4e0fe50fee6c42eeb8a77c55f08baca4f7ebc7d443760ffaaf5f437274f25800",
+ "libxrandr-dev_1.5.1-1_amd64.deb": "67d40174015e8b4e3e2fe3b6fb2990943321a168e0fbb2d12082f637914a0a2e",
+ "libxrandr2_1.5.1-1_amd64.deb": "8fdd8ba4a8ad819731d6bbd903b52851a2ec2f9ef4139d880e9be421ea61338c",
+ "libxrender-dev_0.9.10-1_amd64.deb": "135ed7c8a589e17d21718a91b5a7da48159f33c85e0b337aae9b9f484d3a4954",
+ "libxrender1_0.9.10-1_amd64.deb": "3ea17d07b5aa89012130e2acd92f0fc0ea67314e2f5eab6e33930ef688f48294",
+ "libxshmfence1_1.3-1_amd64.deb": "1a38142e40e3d32dc4f9a326bf5617363b7d9b4bb762fdcdd262f2192092024d",
+ "libxtst-dev_1.2.3-1_amd64.deb": "9ed56e0fd5807afe20cfee8fad16c657c6d7410d7934d8726584794bd77ea989",
+ "libxtst6_1.2.3-1_amd64.deb": "7072f9be17abdb9c5af7d052b19c84d1a6c1c13c30c120a98d284ba73d2da73f",
+ "libxxf86vm1_1.1.4-1+b2_amd64.deb": "6f4ca916aaec26d7000fa7f58de3f71119309ab7590ce1f517abfe1825a676c7",
+ "libz3-4_4.8.10-1_amd64.deb": "7a38c2dd985eb9315857588ee06ff297e2b16de159dec85bd2777a43ebe9f458",
+ "libzstd1_1.4.8+dfsg-2.1_amd64.deb": "5dcadfbb743bfa1c1c773bff91c018f835e8e8c821d423d3836f3ab84773507b",
+ "pango1.0-tools_1.46.2-3_amd64.deb": "e622e68a9451c9d15fd2a5c4c4a95884f33bdfece63f9c0d6cd3953c5d202e74",
+ "perl_5.32.1-4+deb11u2_amd64.deb": "1cebc4516ed7c240b812c7bdd7e6ea0810f513152717ca17ce139ee0dfbc7b0d",
+ "pkg-config_0.29.2-1_amd64.deb": "09a05a23c5fd5baacd488255a6b0114909210691b830fb951acd276e9bcd632a",
+ "sensible-utils_0.0.14_all.deb": "b9a447dc4ec8714196b037e20a2209e62cd669f5450222952f259bda4416b71f",
+ "shared-mime-info_2.0-1_amd64.deb": "de0a814e186af5a941e1fcd3044da62eb155638fcf9616d6005bcfc6696bbe67",
+ "ttf-bitstream-vera_1.10-8.1_all.deb": "ba622edf73744b2951bbd20bfc113a1a875a9b0c6fed1ac9e9c7f4b54dd8a048",
+ "ucf_3.0043_all.deb": "ebef6bcd777b5c0cc2699926f2159db08433aed07c50cb321fd828b28c5e8d53",
+ "uuid-dev_2.36.1-8+deb11u1_amd64.deb": "90a533bbb3b82f5c9bedc5da28965ca8223913099f8ac67213e4f8828bfdd2a1",
+ "wayland-protocols_1.20-1_all.deb": "09bcb6b1d7735a0190ec85f73680dfd53cfa91ff139c8b3d4e18377f94bb6599",
+ "x11-common_7.7+22_all.deb": "5d1c3287826f60c3a82158b803b9c0489b8aad845ca23a53a982eba3dbb82aa3",
+ "x11proto-core-dev_2020.1-1_all.deb": "92941b1b2a7889a67e952a9301339202b6b390b77af939a26ee15c94ef4fad7e",
+ "x11proto-dev_2020.1-1_all.deb": "d5568d587d9ad2664c34c14b0ac538ccb3c567e126ee5291085a8de704a565f5",
+ "x11proto-input-dev_2020.1-1_all.deb": "f2b5dbb98ddafb56b3a6d4d5545812b98e272c146f79adb41e49533eeaa97d3f",
+ "x11proto-randr-dev_2020.1-1_all.deb": "ca63b15ebe65d1e45868d72eb87cd447be3adeb5cc25787db09f65ef05e30c66",
+ "x11proto-record-dev_2020.1-1_all.deb": "dc0ceb54206b03107d31d0ce8665d47ce7c7debac5c3e072e041cdc37f176d3f",
+ "x11proto-render-dev_2020.1-1_all.deb": "f622a9bdd90d51305cd92ee3c5d30ca82f1a20aea3632514965afed6e85589c7",
+ "x11proto-xext-dev_2020.1-1_all.deb": "61e858b8758b8ff63dfc8206d3b00bfbe3ad36ef133dea41b3c5b73dc427d41b",
+ "x11proto-xinerama-dev_2020.1-1_all.deb": "0183efc631edb1308b2bc38ae08f3dc27db735f8d1e84d87bde6416fa023c70d",
+ "xkb-data_2.29-2_all.deb": "9122cccc67e6b3c3aef2fa9c50ef9d793a12f951c76698a02b1f4ceb9e3634e5",
+ "xorg-sgml-doctools_1.11-1.1_all.deb": "168345058319094e475a87ace66f5fb6ae802109650ea8434d672117982b5d0a",
+ "xtrans-dev_1.4.0-1_all.deb": "9ce1af9464faee0c679348dd11cdf63934c12e734a64e0903692b0cb5af38e06",
+ "zlib1g_1.2.11.dfsg-2+deb11u2_amd64.deb": "03d2ab2174af76df6f517b854b77460fbdafc3dac0dca979317da67538159a3e",
+}
diff --git a/debian/packages.bzl b/debian/packages.bzl
index 0f2784a..dfb4ed8 100644
--- a/debian/packages.bzl
+++ b/debian/packages.bzl
@@ -24,7 +24,7 @@
# 6. Add a new "new_http_archive" entry to the WORKSPACE file for the tarball
# you just uploaded.
-def download_packages(name, packages, excludes = [], force_includes = [], target_compatible_with = None):
+def download_packages(name, packages, excludes = [], force_includes = [], force_excludes = [], target_compatible_with = None):
"""Downloads a set of packages as well as their dependencies.
You can also specify excludes in case some of the dependencies are meta
@@ -34,10 +34,17 @@
list to use in a .bzl file. Once you have the packages on
https://www.frc971.org/Build-Dependencies/ you can add them to a to
combine_packages rule.
+
+ force_includes lets you include packages that are excluded by default. The
+ dependencies of these force-included packages are also force-included. To
+ counter-act that, you can use "force_excludes". The force-excluded packages
+ are excluded even if they're pulled in as a dependency from a
+ "force_includes" package.
"""
package_list = " ".join(packages)
excludes_list = " ".join(["--exclude=%s" % e for e in excludes])
force_includes = " ".join(["--force-include=%s" % i for i in force_includes])
+ force_excludes = " ".join(["--force-exclude=%s" % e for e in force_excludes])
native.genrule(
name = name + "_gen",
outs = ["%s.sh" % name],
@@ -58,8 +65,8 @@
# --- end runfiles.bash initialization v2 ---
-exec "$$(rlocation org_frc971/debian/download_packages)" %s %s %s "$$@"
-END""" % (force_includes, excludes_list, package_list),
+exec "$$(rlocation org_frc971/debian/download_packages)" %s %s %s %s "$$@"
+END""" % (force_includes, force_excludes, excludes_list, package_list),
target_compatible_with = target_compatible_with,
)
native.sh_binary(
diff --git a/frc971/control_loops/python/path_edit.py b/frc971/control_loops/python/path_edit.py
index 7c742c8..437b242 100755
--- a/frc971/control_loops/python/path_edit.py
+++ b/frc971/control_loops/python/path_edit.py
@@ -48,7 +48,10 @@
# init editing / viewing modes and pointer location
self.mode = Mode.kPlacing
self.mousex = 0
+ self.lastx = 0
self.mousey = 0
+ self.lasty = 0
+ self.drag_start = None
self.module_path = os.path.dirname(os.path.realpath(sys.argv[0]))
self.path_to_export = os.path.join(self.module_path,
'points_for_pathedit.json')
@@ -406,6 +409,8 @@
self.queue_draw()
def do_button_release_event(self, event):
+ self.drag_start = None
+
self.attempt_append_multisplines()
self.mousex, self.mousey = self.input_transform.transform_point(
event.x, event.y)
@@ -430,6 +435,9 @@
self.mousex, self.mousey = self.input_transform.transform_point(
event.x, event.y)
+ self.lastx = event.x
+ self.lasty = event.y
+
if self.mode == Mode.kPlacing:
if self.active_multispline.addPoint(self.mousex, self.mousey):
self.mode = Mode.kEditing
@@ -462,6 +470,9 @@
index_multisplines, index_splines,
index_points)
+ if self.control_point_index == None:
+ self.drag_start = (event.x, event.y)
+
multispline, result = Multispline.nearest_distance(
self.multisplines, cur_p)
if result and result.fun < 0.1:
@@ -484,6 +495,14 @@
multispline.update_lib_spline()
self.graph.schedule_recalculate(self.multisplines)
+
+ if self.mode == Mode.kEditing and self.drag_start != None and self.control_point_index == None:
+
+ self.zoom_transform.translate(event.x - self.lastx,
+ event.y - self.lasty)
+ self.lastx = event.x
+ self.lasty = event.y
+
self.queue_draw()
def do_scroll_event(self, event):
@@ -505,9 +524,9 @@
scale = (self.field.width + scale_by) / self.field.width
# This restricts the amount it can be scaled.
- if self.zoom_transform.xx <= 0.5:
+ if self.zoom_transform.xx <= 0.05:
scale = max(scale, 1)
- elif self.zoom_transform.xx >= 16:
+ elif self.zoom_transform.xx >= 32:
scale = min(scale, 1)
# undo the scaled translation that the old zoom transform did
diff --git a/frc971/rockpi/.config b/frc971/rockpi/.config
new file mode 100644
index 0000000..18a33b7
--- /dev/null
+++ b/frc971/rockpi/.config
@@ -0,0 +1,6584 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm64 6.0.8 Kernel Configuration
+#
+CONFIG_CC_VERSION_TEXT="aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110"
+CONFIG_CC_IS_GCC=y
+CONFIG_GCC_VERSION=100201
+CONFIG_CLANG_VERSION=0
+CONFIG_AS_IS_GNU=y
+CONFIG_AS_VERSION=23502
+CONFIG_LD_IS_BFD=y
+CONFIG_LD_VERSION=23502
+CONFIG_LLD_VERSION=0
+CONFIG_CC_CAN_LINK=y
+CONFIG_CC_CAN_LINK_STATIC=y
+CONFIG_CC_HAS_ASM_INLINE=y
+CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
+CONFIG_PAHOLE_VERSION=0
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_TABLE_SORT=y
+CONFIG_THREAD_INFO_IN_TASK=y
+
+#
+# General setup
+#
+CONFIG_INIT_ENV_ARG_LIMIT=32
+# CONFIG_COMPILE_TEST is not set
+# CONFIG_WERROR is not set
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_BUILD_SALT=""
+CONFIG_DEFAULT_INIT=""
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_WATCH_QUEUE is not set
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_USELIB is not set
+CONFIG_AUDIT=y
+CONFIG_HAVE_ARCH_AUDITSYSCALL=y
+CONFIG_AUDITSYSCALL=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_GENERIC_IRQ_IPI=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
+CONFIG_IRQ_MSI_IOMMU=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_SPARSE_IRQ=y
+# CONFIG_GENERIC_IRQ_DEBUGFS is not set
+# end of IRQ subsystem
+
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_HZ_PERIODIC=y
+# CONFIG_NO_HZ_IDLE is not set
+# CONFIG_NO_HZ_FULL is not set
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+# end of Timers subsystem
+
+CONFIG_BPF=y
+CONFIG_HAVE_EBPF_JIT=y
+CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y
+
+#
+# BPF subsystem
+#
+CONFIG_BPF_SYSCALL=y
+CONFIG_BPF_JIT=y
+# CONFIG_BPF_JIT_ALWAYS_ON is not set
+CONFIG_BPF_JIT_DEFAULT_ON=y
+CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
+CONFIG_USERMODE_DRIVER=y
+# CONFIG_BPF_PRELOAD is not set
+# CONFIG_BPF_LSM is not set
+# end of BPF subsystem
+
+CONFIG_HAVE_PREEMPT_LAZY=y
+CONFIG_PREEMPT_LAZY=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_RT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_PREEMPTION=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_SCHED_AVG_IRQ=y
+CONFIG_SCHED_THERMAL_PRESSURE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+# CONFIG_PSI is not set
+# end of CPU/Task time and stats accounting
+
+CONFIG_CPU_ISOLATION=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_EXPERT is not set
+CONFIG_SRCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_TASKS_RCU_GENERIC=y
+CONFIG_TASKS_RCU=y
+CONFIG_TASKS_TRACE_RCU=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_RCU_NEED_SEGCBLIST=y
+CONFIG_RCU_BOOST=y
+CONFIG_RCU_BOOST_DELAY=500
+# end of RCU Subsystem
+
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_IKHEADERS is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
+# CONFIG_PRINTK_INDEX is not set
+CONFIG_GENERIC_SCHED_CLOCK=y
+
+#
+# Scheduler features
+#
+# end of Scheduler features
+
+CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
+CONFIG_CC_HAS_INT128=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_GCC12_NO_ARRAY_BOUNDS=y
+CONFIG_ARCH_SUPPORTS_INT128=y
+CONFIG_CGROUPS=y
+CONFIG_PAGE_COUNTER=y
+# CONFIG_CGROUP_FAVOR_DYNMODS is not set
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_MEMCG_KMEM=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CGROUP_WRITEBACK=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_CFS_BANDWIDTH is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_CGROUP_PIDS=y
+# CONFIG_CGROUP_RDMA is not set
+# CONFIG_CGROUP_FREEZER is not set
+CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+# CONFIG_CGROUP_BPF is not set
+# CONFIG_CGROUP_MISC is not set
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_TIME_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_SCHED_AUTOGROUP=y
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+CONFIG_RD_LZ4=y
+CONFIG_RD_ZSTD=y
+CONFIG_BOOT_CONFIG=y
+# CONFIG_BOOT_CONFIG_EMBED is not set
+CONFIG_INITRAMFS_PRESERVE_MTIME=y
+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_LD_ORPHAN_WARN=y
+CONFIG_SYSCTL=y
+CONFIG_HAVE_UID16=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_MULTIUSER=y
+# CONFIG_SGETMASK_SYSCALL is not set
+CONFIG_SYSFS_SYSCALL=y
+CONFIG_FHANDLE=y
+CONFIG_POSIX_TIMERS=y
+CONFIG_PRINTK=y
+CONFIG_HAVE_ATOMIC_CONSOLE=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_FUTEX_PI=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_IO_URING=y
+CONFIG_ADVISE_SYSCALLS=y
+CONFIG_MEMBARRIER=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_BASE_RELATIVE=y
+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
+CONFIG_KCMP=y
+CONFIG_RSEQ=y
+# CONFIG_DEBUG_RSEQ is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+# CONFIG_PC104 is not set
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+# end of Kernel Performance Events And Counters
+
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+# end of General setup
+
+CONFIG_ARM64=y
+CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y
+CONFIG_64BIT=y
+CONFIG_MMU=y
+CONFIG_ARM64_PAGE_SHIFT=12
+CONFIG_ARM64_CONT_PTE_SHIFT=4
+CONFIG_ARM64_CONT_PMD_SHIFT=4
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+CONFIG_ARCH_MMAP_RND_BITS_MAX=33
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
+CONFIG_SMP=y
+CONFIG_KERNEL_MODE_NEON=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_PGTABLE_LEVELS=4
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_ARCH_PROC_KCORE_TEXT=y
+
+#
+# Platform selection
+#
+# CONFIG_ARCH_ACTIONS is not set
+# CONFIG_ARCH_SUNXI is not set
+# CONFIG_ARCH_ALPINE is not set
+# CONFIG_ARCH_APPLE is not set
+# CONFIG_ARCH_BCM2835 is not set
+# CONFIG_ARCH_BCM4908 is not set
+# CONFIG_ARCH_BCM_IPROC is not set
+# CONFIG_ARCH_BCMBCA is not set
+# CONFIG_ARCH_BERLIN is not set
+# CONFIG_ARCH_BITMAIN is not set
+# CONFIG_ARCH_BRCMSTB is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SPARX5 is not set
+# CONFIG_ARCH_K3 is not set
+# CONFIG_ARCH_LAYERSCAPE is not set
+# CONFIG_ARCH_LG1K is not set
+# CONFIG_ARCH_HISI is not set
+# CONFIG_ARCH_KEEMBAY is not set
+# CONFIG_ARCH_MEDIATEK is not set
+# CONFIG_ARCH_MESON is not set
+# CONFIG_ARCH_MVEBU is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_NPCM is not set
+# CONFIG_ARCH_QCOM is not set
+# CONFIG_ARCH_REALTEK is not set
+# CONFIG_ARCH_RENESAS is not set
+CONFIG_ARCH_ROCKCHIP=y
+# CONFIG_ARCH_S32 is not set
+# CONFIG_ARCH_SEATTLE is not set
+# CONFIG_ARCH_INTEL_SOCFPGA is not set
+# CONFIG_ARCH_SYNQUACER is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_SPRD is not set
+# CONFIG_ARCH_THUNDER is not set
+# CONFIG_ARCH_THUNDER2 is not set
+# CONFIG_ARCH_UNIPHIER is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_VISCONTI is not set
+# CONFIG_ARCH_XGENE is not set
+# CONFIG_ARCH_ZYNQMP is not set
+# end of Platform selection
+
+#
+# Kernel Features
+#
+
+#
+# ARM errata workarounds via the alternatives framework
+#
+CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y
+CONFIG_ARM64_ERRATUM_826319=y
+CONFIG_ARM64_ERRATUM_827319=y
+CONFIG_ARM64_ERRATUM_824069=y
+CONFIG_ARM64_ERRATUM_819472=y
+CONFIG_ARM64_ERRATUM_832075=y
+CONFIG_ARM64_ERRATUM_1742098=y
+CONFIG_ARM64_ERRATUM_845719=y
+CONFIG_ARM64_ERRATUM_843419=y
+CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
+CONFIG_ARM64_ERRATUM_1024718=y
+CONFIG_ARM64_ERRATUM_1418040=y
+CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
+CONFIG_ARM64_ERRATUM_1165522=y
+CONFIG_ARM64_ERRATUM_1319367=y
+CONFIG_ARM64_ERRATUM_1530923=y
+CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
+CONFIG_ARM64_ERRATUM_2441007=y
+CONFIG_ARM64_ERRATUM_1286807=y
+CONFIG_ARM64_ERRATUM_1463225=y
+CONFIG_ARM64_ERRATUM_1542419=y
+CONFIG_ARM64_ERRATUM_1508412=y
+CONFIG_ARM64_ERRATUM_2051678=y
+CONFIG_ARM64_ERRATUM_2077057=y
+CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y
+CONFIG_ARM64_ERRATUM_2054223=y
+CONFIG_ARM64_ERRATUM_2067961=y
+CONFIG_ARM64_ERRATUM_2441009=y
+CONFIG_ARM64_ERRATUM_2457168=y
+CONFIG_CAVIUM_ERRATUM_22375=y
+CONFIG_CAVIUM_ERRATUM_23144=y
+CONFIG_CAVIUM_ERRATUM_23154=y
+CONFIG_CAVIUM_ERRATUM_27456=y
+CONFIG_CAVIUM_ERRATUM_30115=y
+CONFIG_CAVIUM_TX2_ERRATUM_219=y
+CONFIG_FUJITSU_ERRATUM_010001=y
+CONFIG_HISILICON_ERRATUM_161600802=y
+CONFIG_QCOM_FALKOR_ERRATUM_1003=y
+CONFIG_QCOM_FALKOR_ERRATUM_1009=y
+CONFIG_QCOM_QDF2400_ERRATUM_0065=y
+CONFIG_QCOM_FALKOR_ERRATUM_E1041=y
+CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y
+CONFIG_SOCIONEXT_SYNQUACER_PREITS=y
+# end of ARM errata workarounds via the alternatives framework
+
+CONFIG_ARM64_4K_PAGES=y
+# CONFIG_ARM64_16K_PAGES is not set
+# CONFIG_ARM64_64K_PAGES is not set
+# CONFIG_ARM64_VA_BITS_39 is not set
+CONFIG_ARM64_VA_BITS_48=y
+CONFIG_ARM64_VA_BITS=48
+CONFIG_ARM64_PA_BITS_48=y
+CONFIG_ARM64_PA_BITS=48
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SCHED_MC=y
+# CONFIG_SCHED_CLUSTER is not set
+# CONFIG_SCHED_SMT is not set
+CONFIG_NR_CPUS=256
+CONFIG_HOTPLUG_CPU=y
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=2
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_HW_PERF_EVENTS=y
+CONFIG_PARAVIRT=y
+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
+CONFIG_KEXEC=y
+# CONFIG_KEXEC_FILE is not set
+CONFIG_CRASH_DUMP=y
+CONFIG_TRANS_TABLE=y
+CONFIG_XEN_DOM0=y
+CONFIG_XEN=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_UNMAP_KERNEL_AT_EL0=y
+CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y
+CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
+# CONFIG_ARM64_SW_TTBR0_PAN is not set
+CONFIG_ARM64_TAGGED_ADDR_ABI=y
+CONFIG_COMPAT=y
+CONFIG_KUSER_HELPERS=y
+# CONFIG_ARMV8_DEPRECATED is not set
+
+#
+# ARMv8.1 architectural features
+#
+CONFIG_ARM64_HW_AFDBM=y
+CONFIG_ARM64_PAN=y
+CONFIG_AS_HAS_LDAPR=y
+CONFIG_AS_HAS_LSE_ATOMICS=y
+CONFIG_ARM64_LSE_ATOMICS=y
+CONFIG_ARM64_USE_LSE_ATOMICS=y
+# end of ARMv8.1 architectural features
+
+#
+# ARMv8.2 architectural features
+#
+CONFIG_AS_HAS_ARMV8_2=y
+CONFIG_AS_HAS_SHA3=y
+# CONFIG_ARM64_PMEM is not set
+CONFIG_ARM64_RAS_EXTN=y
+CONFIG_ARM64_CNP=y
+# end of ARMv8.2 architectural features
+
+#
+# ARMv8.3 architectural features
+#
+CONFIG_ARM64_PTR_AUTH=y
+CONFIG_ARM64_PTR_AUTH_KERNEL=y
+CONFIG_CC_HAS_BRANCH_PROT_PAC_RET=y
+CONFIG_CC_HAS_SIGN_RETURN_ADDRESS=y
+CONFIG_AS_HAS_PAC=y
+CONFIG_AS_HAS_CFI_NEGATE_RA_STATE=y
+# end of ARMv8.3 architectural features
+
+#
+# ARMv8.4 architectural features
+#
+CONFIG_ARM64_AMU_EXTN=y
+CONFIG_AS_HAS_ARMV8_4=y
+CONFIG_ARM64_TLB_RANGE=y
+# end of ARMv8.4 architectural features
+
+#
+# ARMv8.5 architectural features
+#
+CONFIG_AS_HAS_ARMV8_5=y
+CONFIG_ARM64_BTI=y
+CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI=y
+CONFIG_ARM64_E0PD=y
+CONFIG_ARM64_AS_HAS_MTE=y
+CONFIG_ARM64_MTE=y
+# end of ARMv8.5 architectural features
+
+#
+# ARMv8.7 architectural features
+#
+CONFIG_ARM64_EPAN=y
+# end of ARMv8.7 architectural features
+
+CONFIG_ARM64_SVE=y
+CONFIG_ARM64_SME=y
+CONFIG_ARM64_MODULE_PLTS=y
+# CONFIG_ARM64_PSEUDO_NMI is not set
+CONFIG_RELOCATABLE=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_RANDOMIZE_MODULE_REGION_FULL=y
+CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
+CONFIG_STACKPROTECTOR_PER_TASK=y
+CONFIG_ARCH_NR_GPIO=0
+# end of Kernel Features
+
+#
+# Boot options
+#
+CONFIG_CMDLINE=""
+CONFIG_EFI_STUB=y
+CONFIG_EFI=y
+CONFIG_DMI=y
+# end of Boot options
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_SUSPEND_SKIP_SYNC is not set
+CONFIG_HIBERNATE_CALLBACKS=y
+CONFIG_HIBERNATION=y
+CONFIG_HIBERNATION_SNAPSHOT_DEV=y
+CONFIG_PM_STD_PARTITION=""
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_USERSPACE_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_CLK=y
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
+CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
+CONFIG_PM_GENERIC_DOMAINS_OF=y
+CONFIG_CPU_PM=y
+# CONFIG_ENERGY_MODEL is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_HEADER=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# end of Power management options
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Idle
+#
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+# CONFIG_CPU_IDLE_GOV_MENU is not set
+# CONFIG_CPU_IDLE_GOV_TEO is not set
+CONFIG_DT_IDLE_STATES=y
+CONFIG_DT_IDLE_GENPD=y
+
+#
+# ARM CPU Idle Drivers
+#
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y
+# end of ARM CPU Idle Drivers
+# end of CPU Idle
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set
+
+#
+# CPU frequency scaling drivers
+#
+CONFIG_CPUFREQ_DT=m
+CONFIG_CPUFREQ_DT_PLATDEV=y
+# CONFIG_ARM_SCPI_CPUFREQ is not set
+# end of CPU Frequency scaling
+# end of CPU Power Management
+
+CONFIG_ARCH_SUPPORTS_ACPI=y
+# CONFIG_ACPI is not set
+CONFIG_HAVE_KVM=y
+# CONFIG_VIRTUALIZATION is not set
+CONFIG_ARM64_CRYPTO=y
+CONFIG_CRYPTO_SHA256_ARM64=y
+CONFIG_CRYPTO_SHA512_ARM64=m
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_SHA512_ARM64_CE=m
+CONFIG_CRYPTO_SHA3_ARM64=m
+CONFIG_CRYPTO_SM3_ARM64_CE=m
+# CONFIG_CRYPTO_SM4_ARM64_CE is not set
+# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set
+# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+# CONFIG_CRYPTO_POLYVAL_ARM64_CE is not set
+CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m
+CONFIG_CRYPTO_AES_ARM64=y
+CONFIG_CRYPTO_AES_ARM64_CE=y
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_NEON_BLK=m
+CONFIG_CRYPTO_CHACHA20_NEON=m
+CONFIG_CRYPTO_POLY1305_NEON=m
+# CONFIG_CRYPTO_NHPOLY1305_NEON is not set
+CONFIG_CRYPTO_AES_ARM64_BS=m
+
+#
+# General architecture-dependent options
+#
+CONFIG_CRASH_CORE=y
+CONFIG_KEXEC_CORE=y
+CONFIG_ARCH_HAS_SUBPAGE_FAULTS=y
+# CONFIG_KPROBES is not set
+CONFIG_JUMP_LABEL=y
+# CONFIG_STATIC_KEYS_SELFTEST is not set
+CONFIG_UPROBES=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
+CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y
+CONFIG_HAVE_NMI=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
+CONFIG_ARCH_HAS_KEEPINITRD=y
+CONFIG_ARCH_HAS_SET_MEMORY=y
+CONFIG_ARCH_HAS_SET_DIRECT_MAP=y
+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
+CONFIG_ARCH_WANTS_NO_INSTR=y
+CONFIG_HAVE_ASM_MODVERSIONS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_RSEQ=y
+CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y
+CONFIG_MMU_GATHER_TABLE_FREE=y
+CONFIG_MMU_GATHER_RCU_TABLE_FREE=y
+CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
+CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
+CONFIG_HAVE_CMPXCHG_LOCAL=y
+CONFIG_HAVE_CMPXCHG_DOUBLE=y
+CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_SECCOMP=y
+CONFIG_SECCOMP_FILTER=y
+# CONFIG_SECCOMP_CACHE_DEBUG is not set
+CONFIG_HAVE_ARCH_STACKLEAK=y
+CONFIG_HAVE_STACKPROTECTOR=y
+CONFIG_STACKPROTECTOR=y
+CONFIG_STACKPROTECTOR_STRONG=y
+CONFIG_ARCH_SUPPORTS_LTO_CLANG=y
+CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y
+CONFIG_LTO_NONE=y
+CONFIG_ARCH_SUPPORTS_CFI_CLANG=y
+CONFIG_HAVE_CONTEXT_TRACKING_USER=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOVE_PUD=y
+CONFIG_HAVE_MOVE_PMD=y
+CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
+CONFIG_HAVE_ARCH_HUGE_VMAP=y
+CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
+CONFIG_ARCH_MMAP_RND_BITS=18
+CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_COMPAT_OLD_SIGACTION=y
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_ARCH_SUPPORTS_RT=y
+CONFIG_HAVE_ARCH_VMAP_STACK=y
+CONFIG_VMAP_STACK=y
+CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y
+CONFIG_RANDOMIZE_KSTACK_OFFSET=y
+# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set
+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
+CONFIG_STRICT_KERNEL_RWX=y
+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
+CONFIG_STRICT_MODULE_RWX=y
+CONFIG_HAVE_ARCH_COMPILER_H=y
+CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y
+CONFIG_ARCH_USE_MEMREMAP_PROT=y
+# CONFIG_LOCK_EVENT_COUNTS is not set
+CONFIG_ARCH_HAS_RELR=y
+CONFIG_HAVE_PREEMPT_DYNAMIC=y
+CONFIG_HAVE_PREEMPT_DYNAMIC_KEY=y
+CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y
+CONFIG_ARCH_HAVE_TRACE_MMIO_ACCESS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
+# end of GCOV-based kernel profiling
+
+CONFIG_HAVE_GCC_PLUGINS=y
+# end of General architecture-dependent options
+
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG is not set
+CONFIG_MODULE_COMPRESS_NONE=y
+# CONFIG_MODULE_COMPRESS_GZIP is not set
+# CONFIG_MODULE_COMPRESS_XZ is not set
+# CONFIG_MODULE_COMPRESS_ZSTD is not set
+# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set
+CONFIG_MODPROBE_PATH="/sbin/modprobe"
+# CONFIG_TRIM_UNUSED_KSYMS is not set
+CONFIG_MODULES_TREE_LOOKUP=y
+CONFIG_BLOCK=y
+CONFIG_BLOCK_LEGACY_AUTOLOAD=y
+CONFIG_BLK_DEV_BSG_COMMON=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BLK_DEV_INTEGRITY_T10=m
+# CONFIG_BLK_DEV_ZONED is not set
+# CONFIG_BLK_DEV_THROTTLING is not set
+# CONFIG_BLK_WBT is not set
+# CONFIG_BLK_CGROUP_IOLATENCY is not set
+# CONFIG_BLK_CGROUP_IOCOST is not set
+# CONFIG_BLK_CGROUP_IOPRIO is not set
+CONFIG_BLK_DEBUG_FS=y
+# CONFIG_BLK_SED_OPAL is not set
+# CONFIG_BLK_INLINE_ENCRYPTION is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_EFI_PARTITION=y
+# end of Partition Types
+
+CONFIG_BLOCK_COMPAT=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_MQ_VIRTIO=y
+CONFIG_BLK_PM=y
+
+#
+# IO Schedulers
+#
+CONFIG_MQ_IOSCHED_DEADLINE=m
+CONFIG_MQ_IOSCHED_KYBER=y
+# CONFIG_IOSCHED_BFQ is not set
+# end of IO Schedulers
+
+CONFIG_ASN1=y
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
+CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y
+CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y
+CONFIG_FREEZER=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_COMPAT_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_STATE=y
+CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
+CONFIG_ARCH_HAVE_ELF_PROT=y
+CONFIG_ARCH_USE_GNU_PROPERTY=y
+CONFIG_ELFCORE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+# end of Executable file formats
+
+#
+# Memory Management options
+#
+CONFIG_SWAP=y
+# CONFIG_ZSWAP is not set
+
+#
+# SLAB allocator options
+#
+CONFIG_SLUB=y
+CONFIG_SLAB_MERGE_DEFAULT=y
+# CONFIG_SLAB_FREELIST_RANDOM is not set
+# CONFIG_SLAB_FREELIST_HARDENED is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_SLUB_CPU_PARTIAL=y
+# end of SLAB allocator options
+
+# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_HAVE_FAST_GUP=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
+CONFIG_COMPACTION=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=0
+CONFIG_PAGE_REPORTING=y
+CONFIG_MIGRATION=y
+CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y
+CONFIG_CONTIG_ALLOC=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_MMU_NOTIFIER=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
+CONFIG_MEMORY_FAILURE=y
+# CONFIG_HWPOISON_INJECT is not set
+CONFIG_ARCH_WANTS_THP_SWAP=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
+CONFIG_USE_PERCPU_NUMA_NODE_ID=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_CMA=y
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_CMA_DEBUGFS is not set
+# CONFIG_CMA_SYSFS is not set
+CONFIG_CMA_AREAS=7
+CONFIG_GENERIC_EARLY_IOREMAP=y
+# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set
+# CONFIG_IDLE_PAGE_TRACKING is not set
+CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
+CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y
+CONFIG_ARCH_HAS_PTE_DEVMAP=y
+CONFIG_ARCH_HAS_ZONE_DMA_SET=y
+CONFIG_ZONE_DMA=y
+CONFIG_ZONE_DMA32=y
+CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_PERCPU_STATS is not set
+# CONFIG_GUP_TEST is not set
+CONFIG_ARCH_HAS_PTE_SPECIAL=y
+CONFIG_SECRETMEM=y
+# CONFIG_ANON_VMA_NAME is not set
+# CONFIG_USERFAULTFD is not set
+
+#
+# Data Access Monitoring
+#
+# CONFIG_DAMON is not set
+# end of Data Access Monitoring
+# end of Memory Management options
+
+CONFIG_NET=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_EGRESS=y
+CONFIG_SKB_EXTENSIONS=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+CONFIG_UNIX_SCM=y
+CONFIG_AF_UNIX_OOB=y
+# CONFIG_UNIX_DIAG is not set
+# CONFIG_TLS is not set
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+# CONFIG_XDP_SOCKETS is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_NET_IP_TUNNEL=m
+# CONFIG_IP_MROUTE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+CONFIG_NET_UDP_TUNNEL=m
+# CONFIG_NET_FOU is not set
+# CONFIG_NET_FOU_IP_TUNNELS is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_UDP_DIAG is not set
+# CONFIG_INET_RAW_DIAG is not set
+# CONFIG_INET_DIAG_DESTROY is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_IPV6_ILA is not set
+# CONFIG_IPV6_VTI is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_IPV6_SEG6_LWTUNNEL is not set
+# CONFIG_IPV6_SEG6_HMAC is not set
+# CONFIG_IPV6_RPL_LWTUNNEL is not set
+# CONFIG_IPV6_IOAM6_LWTUNNEL is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_MPTCP is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NETWORK_PHY_TIMESTAMPING=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=m
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_INGRESS=y
+CONFIG_NETFILTER_EGRESS=y
+CONFIG_NETFILTER_FAMILY_BRIDGE=y
+# CONFIG_NETFILTER_NETLINK_ACCT is not set
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NETFILTER_NETLINK_OSF is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_LOG_SYSLOG=m
+# CONFIG_NF_CONNTRACK_MARK is not set
+# CONFIG_NF_CONNTRACK_ZONES is not set
+CONFIG_NF_CONNTRACK_PROCFS=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+# CONFIG_NF_CONNTRACK_TIMEOUT is not set
+# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
+# CONFIG_NF_CONNTRACK_LABELS is not set
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+# CONFIG_NF_CONNTRACK_FTP is not set
+# CONFIG_NF_CONNTRACK_H323 is not set
+# CONFIG_NF_CONNTRACK_IRC is not set
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+# CONFIG_NF_CONNTRACK_SNMP is not set
+# CONFIG_NF_CONNTRACK_PPTP is not set
+# CONFIG_NF_CONNTRACK_SANE is not set
+# CONFIG_NF_CONNTRACK_SIP is not set
+# CONFIG_NF_CONNTRACK_TFTP is not set
+# CONFIG_NF_CT_NETLINK is not set
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_MASQUERADE=y
+# CONFIG_NF_TABLES is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XTABLES_COMPAT=y
+
+#
+# Xtables combined modules
+#
+# CONFIG_NETFILTER_XT_MARK is not set
+# CONFIG_NETFILTER_XT_CONNMARK is not set
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_HL is not set
+# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+# CONFIG_NETFILTER_XT_TARGET_LED is not set
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+CONFIG_NETFILTER_XT_NAT=m
+# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set
+CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+
+#
+# Xtables matches
+#
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+# CONFIG_NETFILTER_XT_MATCH_BPF is not set
+# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ECN is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
+# CONFIG_NETFILTER_XT_MATCH_HL is not set
+# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set
+# CONFIG_NETFILTER_XT_MATCH_STATE is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# end of Core Netfilter Configuration
+
+# CONFIG_IP_SET is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+# CONFIG_NF_SOCKET_IPV4 is not set
+# CONFIG_NF_TPROXY_IPV4 is not set
+# CONFIG_NF_DUP_IPV4 is not set
+# CONFIG_NF_LOG_ARP is not set
+CONFIG_NF_LOG_IPV4=m
+CONFIG_NF_REJECT_IPV4=m
+CONFIG_IP_NF_IPTABLES=m
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_RPFILTER is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+# CONFIG_IP_NF_TARGET_SYNPROXY is not set
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+# CONFIG_IP_NF_TARGET_NETMAP is not set
+# CONFIG_IP_NF_TARGET_REDIRECT is not set
+CONFIG_IP_NF_MANGLE=m
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_SECURITY is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# end of IP: Netfilter Configuration
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_NF_SOCKET_IPV6 is not set
+# CONFIG_NF_TPROXY_IPV6 is not set
+# CONFIG_NF_DUP_IPV6 is not set
+CONFIG_NF_REJECT_IPV6=m
+CONFIG_NF_LOG_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+# CONFIG_IP6_NF_MATCH_AH is not set
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
+# CONFIG_IP6_NF_MATCH_FRAG is not set
+# CONFIG_IP6_NF_MATCH_OPTS is not set
+# CONFIG_IP6_NF_MATCH_HL is not set
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
+# CONFIG_IP6_NF_MATCH_MH is not set
+# CONFIG_IP6_NF_MATCH_RPFILTER is not set
+# CONFIG_IP6_NF_MATCH_RT is not set
+# CONFIG_IP6_NF_MATCH_SRH is not set
+# CONFIG_IP6_NF_TARGET_HL is not set
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+# CONFIG_IP6_NF_TARGET_SYNPROXY is not set
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP6_NF_RAW is not set
+# CONFIG_IP6_NF_SECURITY is not set
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+# CONFIG_IP6_NF_TARGET_NPT is not set
+# end of IPv6: Netfilter Configuration
+
+CONFIG_NF_DEFRAG_IPV6=m
+# CONFIG_NF_CONNTRACK_BRIDGE is not set
+# CONFIG_BRIDGE_NF_EBTABLES is not set
+CONFIG_BPFILTER=y
+CONFIG_BPFILTER_UMH=m
+# CONFIG_IP_DCCP is not set
+CONFIG_IP_SCTP=m
+CONFIG_SCTP_DBG_OBJCNT=y
+CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y
+# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set
+# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
+CONFIG_SCTP_COOKIE_HMAC_MD5=y
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_INET_SCTP_DIAG=m
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+# CONFIG_BRIDGE_MRP is not set
+# CONFIG_BRIDGE_CFM is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_6LOWPAN is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+CONFIG_DNS_RESOLVER=y
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_MPLS is not set
+# CONFIG_NET_NSH is not set
+# CONFIG_HSR is not set
+# CONFIG_NET_SWITCHDEV is not set
+# CONFIG_NET_L3_MASTER_DEV is not set
+# CONFIG_QRTR is not set
+# CONFIG_NET_NCSI is not set
+CONFIG_PCPU_DEV_REFCNT=y
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_XPS=y
+# CONFIG_CGROUP_NET_PRIO is not set
+# CONFIG_CGROUP_NET_CLASSID is not set
+CONFIG_BQL=y
+CONFIG_NET_FLOW_LIMIT=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# end of Network testing
+# end of Networking options
+
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+CONFIG_CAN_GW=m
+# CONFIG_CAN_J1939 is not set
+# CONFIG_CAN_ISOTP is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_AF_KCM is not set
+# CONFIG_MCTP is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+# CONFIG_PSAMPLE is not set
+# CONFIG_NET_IFE is not set
+# CONFIG_LWTUNNEL is not set
+CONFIG_DST_CACHE=y
+CONFIG_GRO_CELLS=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SOCK_MSG=y
+CONFIG_PAGE_POOL=y
+# CONFIG_PAGE_POOL_STATS is not set
+CONFIG_FAILOVER=y
+CONFIG_ETHTOOL_NETLINK=y
+
+#
+# Device Drivers
+#
+CONFIG_ARM_AMBA=y
+CONFIG_HAVE_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+CONFIG_PCIEAER=y
+# CONFIG_PCIEAER_INJECT is not set
+# CONFIG_PCIE_ECRC is not set
+CONFIG_PCIEASPM=y
+CONFIG_PCIEASPM_DEFAULT=y
+# CONFIG_PCIEASPM_POWERSAVE is not set
+# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
+# CONFIG_PCIEASPM_PERFORMANCE is not set
+CONFIG_PCIE_PME=y
+# CONFIG_PCIE_DPC is not set
+# CONFIG_PCIE_PTM is not set
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_IRQ_DOMAIN=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_PF_STUB is not set
+CONFIG_PCI_ATS=y
+CONFIG_PCI_ECAM=y
+CONFIG_PCI_IOV=y
+# CONFIG_PCI_PRI is not set
+# CONFIG_PCI_PASID is not set
+CONFIG_PCI_LABEL=y
+# CONFIG_PCIE_BUS_TUNE_OFF is not set
+CONFIG_PCIE_BUS_DEFAULT=y
+# CONFIG_PCIE_BUS_SAFE is not set
+# CONFIG_PCIE_BUS_PERFORMANCE is not set
+# CONFIG_PCIE_BUS_PEER2PEER is not set
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+
+#
+# PCI controller drivers
+#
+# CONFIG_PCI_FTPCI100 is not set
+CONFIG_PCI_HOST_COMMON=y
+CONFIG_PCI_HOST_GENERIC=y
+# CONFIG_PCIE_XILINX is not set
+CONFIG_PCI_XGENE=y
+CONFIG_PCI_XGENE_MSI=y
+CONFIG_PCIE_ALTERA=y
+CONFIG_PCIE_ALTERA_MSI=y
+CONFIG_PCI_HOST_THUNDER_PEM=y
+CONFIG_PCI_HOST_THUNDER_ECAM=y
+CONFIG_PCIE_ROCKCHIP=y
+CONFIG_PCIE_ROCKCHIP_HOST=m
+# CONFIG_PCIE_MICROCHIP_HOST is not set
+
+#
+# DesignWare PCI Core Support
+#
+CONFIG_PCIE_DW=y
+CONFIG_PCIE_DW_HOST=y
+# CONFIG_PCIE_DW_PLAT_HOST is not set
+CONFIG_PCI_HISI=y
+# CONFIG_PCIE_ROCKCHIP_DW_HOST is not set
+CONFIG_PCIE_KIRIN=y
+# CONFIG_PCI_MESON is not set
+# CONFIG_PCIE_AL is not set
+# end of DesignWare PCI Core Support
+
+#
+# Mobiveil PCIe Core Support
+#
+# end of Mobiveil PCIe Core Support
+
+#
+# Cadence PCIe controllers support
+#
+# CONFIG_PCIE_CADENCE_PLAT_HOST is not set
+# CONFIG_PCI_J721E_HOST is not set
+# end of Cadence PCIe controllers support
+# end of PCI controller drivers
+
+#
+# PCI Endpoint
+#
+# CONFIG_PCI_ENDPOINT is not set
+# end of PCI Endpoint
+
+#
+# PCI switch controller drivers
+#
+# CONFIG_PCI_SW_SWITCHTEC is not set
+# end of PCI switch controller drivers
+
+# CONFIG_CXL_BUS is not set
+# CONFIG_PCCARD is not set
+# CONFIG_RAPIDIO is not set
+
+#
+# Generic Driver Options
+#
+# CONFIG_UEVENT_HELPER is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_DEVTMPFS_SAFE is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+
+#
+# Firmware loader
+#
+CONFIG_FW_LOADER=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
+# CONFIG_FW_LOADER_COMPRESS is not set
+CONFIG_FW_CACHE=y
+# CONFIG_FW_UPLOAD is not set
+# end of Firmware loader
+
+CONFIG_WANT_DEV_COREDUMP=y
+CONFIG_ALLOW_DEV_COREDUMP=y
+CONFIG_DEV_COREDUMP=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set
+# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set
+CONFIG_SYS_HYPERVISOR=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_SOC_BUS=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_SPI=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_IRQ=y
+CONFIG_DMA_SHARED_BUFFER=y
+# CONFIG_DMA_FENCE_TRACE is not set
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_ARCH_NUMA=y
+# end of Generic Driver Options
+
+#
+# Bus devices
+#
+CONFIG_BRCMSTB_GISB_ARB=y
+# CONFIG_MOXTET is not set
+CONFIG_VEXPRESS_CONFIG=y
+# CONFIG_MHI_BUS is not set
+# CONFIG_MHI_BUS_EP is not set
+# end of Bus devices
+
+# CONFIG_CONNECTOR is not set
+
+#
+# Firmware Drivers
+#
+
+#
+# ARM System Control and Management Interface Protocol
+#
+# CONFIG_ARM_SCMI_PROTOCOL is not set
+# end of ARM System Control and Management Interface Protocol
+
+CONFIG_ARM_SCPI_PROTOCOL=y
+CONFIG_ARM_SCPI_POWER_DOMAIN=y
+# CONFIG_FIRMWARE_MEMMAP is not set
+CONFIG_DMIID=y
+# CONFIG_DMI_SYSFS is not set
+# CONFIG_FW_CFG_SYSFS is not set
+# CONFIG_SYSFB_SIMPLEFB is not set
+# CONFIG_ARM_FFA_TRANSPORT is not set
+# CONFIG_GOOGLE_FIRMWARE is not set
+
+#
+# EFI (Extensible Firmware Interface) Support
+#
+CONFIG_EFI_ESRT=y
+CONFIG_EFI_VARS_PSTORE=y
+# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set
+CONFIG_EFI_PARAMS_FROM_FDT=y
+CONFIG_EFI_RUNTIME_WRAPPERS=y
+CONFIG_EFI_GENERIC_STUB=y
+CONFIG_EFI_ARMSTUB_DTB_LOADER=y
+# CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER is not set
+# CONFIG_EFI_BOOTLOADER_CONTROL is not set
+CONFIG_EFI_CAPSULE_LOADER=y
+# CONFIG_EFI_TEST is not set
+# CONFIG_RESET_ATTACK_MITIGATION is not set
+# CONFIG_EFI_DISABLE_PCI_DMA is not set
+CONFIG_EFI_EARLYCON=y
+# CONFIG_EFI_DISABLE_RUNTIME is not set
+# CONFIG_EFI_COCO_SECRET is not set
+# end of EFI (Extensible Firmware Interface) Support
+
+CONFIG_ARM_PSCI_FW=y
+# CONFIG_ARM_PSCI_CHECKER is not set
+CONFIG_HAVE_ARM_SMCCC=y
+CONFIG_HAVE_ARM_SMCCC_DISCOVERY=y
+CONFIG_ARM_SMCCC_SOC_ID=y
+
+#
+# Tegra firmware driver
+#
+# end of Tegra firmware driver
+# end of Firmware Drivers
+
+# CONFIG_GNSS is not set
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+
+#
+# Partition parsers
+#
+# CONFIG_MTD_AR7_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# end of Partition parsers
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+
+#
+# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK.
+#
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+# CONFIG_MTD_PARTITIONED_MASTER is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# end of RAM/ROM/Flash chip drivers
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+# end of Mapping drivers for chip access
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_MCHP23K256 is not set
+# CONFIG_MTD_MCHP48L640 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+# end of Self-contained MTD device drivers
+
+#
+# NAND
+#
+CONFIG_MTD_NAND_CORE=y
+# CONFIG_MTD_ONENAND is not set
+CONFIG_MTD_RAW_NAND=y
+
+#
+# Raw/parallel NAND flash controllers
+#
+CONFIG_MTD_NAND_DENALI=y
+# CONFIG_MTD_NAND_DENALI_PCI is not set
+CONFIG_MTD_NAND_DENALI_DT=y
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_BRCMNAND is not set
+# CONFIG_MTD_NAND_MXIC is not set
+# CONFIG_MTD_NAND_GPIO is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_NAND_CADENCE is not set
+# CONFIG_MTD_NAND_ARASAN is not set
+# CONFIG_MTD_NAND_INTEL_LGM is not set
+# CONFIG_MTD_NAND_ROCKCHIP is not set
+
+#
+# Misc
+#
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_RICOH is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_SPI_NAND is not set
+
+#
+# ECC engine support
+#
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_ECC_SW_HAMMING=y
+# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set
+# CONFIG_MTD_NAND_ECC_SW_BCH is not set
+# CONFIG_MTD_NAND_ECC_MXIC is not set
+# end of ECC engine support
+# end of NAND
+
+#
+# LPDDR & LPDDR2 PCM memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# end of LPDDR & LPDDR2 PCM memory drivers
+
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set
+CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y
+# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set
+# CONFIG_MTD_UBI is not set
+# CONFIG_MTD_HYPERBUS is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+# CONFIG_OF_UNITTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_RESERVED_MEM=y
+# CONFIG_OF_OVERLAY is not set
+CONFIG_OF_NUMA=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_NULL_BLK is not set
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_XEN_BLKDEV_FRONTEND is not set
+# CONFIG_XEN_BLKDEV_BACKEND is not set
+# CONFIG_VIRTIO_BLK is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_BLK_DEV_UBLK is not set
+
+#
+# NVME Support
+#
+CONFIG_NVME_CORE=m
+CONFIG_BLK_DEV_NVME=m
+# CONFIG_NVME_MULTIPATH is not set
+# CONFIG_NVME_VERBOSE_ERRORS is not set
+# CONFIG_NVME_HWMON is not set
+# CONFIG_NVME_FC is not set
+# CONFIG_NVME_TCP is not set
+# CONFIG_NVME_AUTH is not set
+# CONFIG_NVME_TARGET is not set
+# end of NVME Support
+
+#
+# Misc devices
+#
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HI6421V600_IRQ is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+CONFIG_SRAM=y
+# CONFIG_DW_XDATA_PCIE is not set
+# CONFIG_PCI_ENDPOINT_TEST is not set
+# CONFIG_XILINX_SDFEC is not set
+# CONFIG_HISI_HIKEY_USB is not set
+# CONFIG_OPEN_DICE is not set
+# CONFIG_VCPU_STALL_DETECTOR is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_AT25=m
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+# CONFIG_EEPROM_IDT_89HPESX is not set
+# CONFIG_EEPROM_EE1004 is not set
+# end of EEPROM support
+
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# end of Texas Instruments shared transport line discipline
+
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+# CONFIG_ALTERA_STAPL is not set
+# CONFIG_VMWARE_VMCI is not set
+# CONFIG_GENWQE is not set
+# CONFIG_ECHO is not set
+# CONFIG_BCM_VK is not set
+# CONFIG_MISC_ALCOR_PCI is not set
+# CONFIG_MISC_RTSX_PCI is not set
+# CONFIG_MISC_RTSX_USB is not set
+# CONFIG_HABANA_AI is not set
+# CONFIG_UACCE is not set
+# CONFIG_PVPANIC is not set
+# end of Misc devices
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI_COMMON=y
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+# CONFIG_BLK_DEV_SD is not set
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=y
+CONFIG_SCSI_SAS_LIBSAS=y
+CONFIG_SCSI_SAS_ATA=y
+CONFIG_SCSI_SAS_HOST_SMP=y
+# CONFIG_SCSI_SRP_ATTRS is not set
+# end of SCSI Transports
+
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# end of SCSI device support
+
+CONFIG_HAVE_PATA_PLATFORM=y
+CONFIG_ATA=y
+CONFIG_SATA_HOST=y
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_ATA_FORCE=y
+CONFIG_SATA_PMP=y
+
+#
+# Controllers with non-SFF native interface
+#
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_MOBILE_LPM_POLICY=0
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_CEVA=y
+CONFIG_AHCI_XGENE=y
+CONFIG_AHCI_QORIQ=y
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_SATA_ACARD_AHCI is not set
+CONFIG_SATA_SIL24=y
+CONFIG_ATA_SFF=y
+
+#
+# SFF controllers with custom DMA interface
+#
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_ATA_BMDMA=y
+
+#
+# SATA SFF controllers with BMDMA
+#
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_DWC is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+
+#
+# PATA SFF controllers with BMDMA
+#
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_ATP867X is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
+# CONFIG_PATA_SCH is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+
+#
+# PIO-only SFF controllers
+#
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+CONFIG_PATA_PLATFORM=y
+CONFIG_PATA_OF_PLATFORM=y
+# CONFIG_PATA_RZ1000 is not set
+
+#
+# Generic fallback / legacy drivers
+#
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_LEGACY is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# end of IEEE 1394 (FireWire) support
+
+CONFIG_NETDEVICES=y
+CONFIG_MII=m
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_WIREGUARD is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_IPVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_GENEVE is not set
+# CONFIG_BAREUDP is not set
+# CONFIG_GTP is not set
+# CONFIG_AMT is not set
+# CONFIG_MACSEC is not set
+# CONFIG_NETCONSOLE is not set
+CONFIG_TUN=y
+# CONFIG_TUN_VNET_CROSS_LE is not set
+# CONFIG_VETH is not set
+# CONFIG_VIRTIO_NET is not set
+# CONFIG_NLMON is not set
+# CONFIG_ARCNET is not set
+CONFIG_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_AGERE is not set
+# CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_ALTERA_TSE is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_ASIX is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_DAVICOM is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_ENGLEDER is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_FUNGIBLE is not set
+# CONFIG_NET_VENDOR_GOOGLE is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_HUAWEI is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_WANGXUN is not set
+# CONFIG_JME is not set
+# CONFIG_NET_VENDOR_LITEX is not set
+CONFIG_NET_VENDOR_MARVELL=y
+CONFIG_MVMDIO=y
+# CONFIG_SKGE is not set
+CONFIG_SKY2=y
+# CONFIG_SKY2_DEBUG is not set
+# CONFIG_OCTEONTX2_AF is not set
+# CONFIG_OCTEONTX2_PF is not set
+# CONFIG_OCTEON_EP is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MICROSEMI is not set
+# CONFIG_NET_VENDOR_MICROSOFT is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETERION is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_PACKET_ENGINES is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SOLARFLARE is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
+CONFIG_NET_VENDOR_STMICRO=y
+CONFIG_STMMAC_ETH=m
+# CONFIG_STMMAC_SELFTESTS is not set
+CONFIG_STMMAC_PLATFORM=m
+# CONFIG_DWMAC_DWC_QOS_ETH is not set
+CONFIG_DWMAC_GENERIC=m
+CONFIG_DWMAC_ROCKCHIP=m
+# CONFIG_DWMAC_INTEL_PLAT is not set
+# CONFIG_DWMAC_LOONGSON is not set
+# CONFIG_STMMAC_PCI is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VERTEXCOM is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_NET_VENDOR_XILINX is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PHYLINK=m
+CONFIG_PHYLIB=y
+CONFIG_SWPHY=y
+# CONFIG_LED_TRIGGER_PHY is not set
+CONFIG_FIXED_PHY=y
+# CONFIG_SFP is not set
+
+#
+# MII PHY device drivers
+#
+# CONFIG_AMD_PHY is not set
+# CONFIG_ADIN_PHY is not set
+# CONFIG_ADIN1100_PHY is not set
+# CONFIG_AQUANTIA_PHY is not set
+CONFIG_AX88796B_PHY=m
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM54140_PHY is not set
+# CONFIG_BCM7XXX_PHY is not set
+# CONFIG_BCM84881_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_CORTINA_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_INTEL_XWAY_PHY is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+CONFIG_MARVELL_PHY=m
+CONFIG_MARVELL_10G_PHY=m
+# CONFIG_MARVELL_88X2222_PHY is not set
+# CONFIG_MAXLINEAR_GPHY is not set
+# CONFIG_MEDIATEK_GE_PHY is not set
+CONFIG_MICREL_PHY=y
+CONFIG_MICROCHIP_PHY=m
+# CONFIG_MICROCHIP_T1_PHY is not set
+# CONFIG_MICROSEMI_PHY is not set
+# CONFIG_MOTORCOMM_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_NXP_C45_TJA11XX_PHY is not set
+# CONFIG_NXP_TJA11XX_PHY is not set
+CONFIG_AT803X_PHY=m
+# CONFIG_QSEMI_PHY is not set
+CONFIG_REALTEK_PHY=m
+# CONFIG_RENESAS_PHY is not set
+CONFIG_ROCKCHIP_PHY=y
+CONFIG_SMSC_PHY=m
+# CONFIG_STE10XP is not set
+# CONFIG_TERANETICS_PHY is not set
+# CONFIG_DP83822_PHY is not set
+# CONFIG_DP83TC811_PHY is not set
+# CONFIG_DP83848_PHY is not set
+# CONFIG_DP83867_PHY is not set
+# CONFIG_DP83869_PHY is not set
+# CONFIG_DP83TD510_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_XILINX_GMII2RGMII is not set
+# CONFIG_MICREL_KS8995MA is not set
+CONFIG_CAN_DEV=m
+CONFIG_CAN_VCAN=m
+# CONFIG_CAN_VXCAN is not set
+CONFIG_CAN_NETLINK=y
+CONFIG_CAN_CALC_BITTIMING=y
+# CONFIG_CAN_CAN327 is not set
+# CONFIG_CAN_FLEXCAN is not set
+# CONFIG_CAN_GRCAN is not set
+# CONFIG_CAN_KVASER_PCIEFD is not set
+# CONFIG_CAN_SLCAN is not set
+# CONFIG_CAN_XILINXCAN is not set
+# CONFIG_CAN_C_CAN is not set
+# CONFIG_CAN_CC770 is not set
+# CONFIG_CAN_CTUCANFD_PCI is not set
+# CONFIG_CAN_CTUCANFD_PLATFORM is not set
+# CONFIG_CAN_IFI_CANFD is not set
+# CONFIG_CAN_M_CAN is not set
+# CONFIG_CAN_PEAK_PCIEFD is not set
+# CONFIG_CAN_SJA1000 is not set
+# CONFIG_CAN_SOFTING is not set
+
+#
+# CAN SPI interfaces
+#
+# CONFIG_CAN_HI311X is not set
+# CONFIG_CAN_MCP251X is not set
+# CONFIG_CAN_MCP251XFD is not set
+# end of CAN SPI interfaces
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_8DEV_USB is not set
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_ESD_USB is not set
+# CONFIG_CAN_ETAS_ES58X is not set
+# CONFIG_CAN_GS_USB is not set
+# CONFIG_CAN_KVASER_USB is not set
+# CONFIG_CAN_MCBA_USB is not set
+# CONFIG_CAN_PEAK_USB is not set
+# CONFIG_CAN_UCAN is not set
+# end of CAN USB interfaces
+
+# CONFIG_CAN_DEBUG_DEVICES is not set
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_BUS=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_OF_MDIO=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MDIO_BITBANG=y
+# CONFIG_MDIO_BCM_UNIMAC is not set
+CONFIG_MDIO_CAVIUM=y
+# CONFIG_MDIO_GPIO is not set
+# CONFIG_MDIO_HISI_FEMAC is not set
+# CONFIG_MDIO_MVUSB is not set
+# CONFIG_MDIO_MSCC_MIIM is not set
+# CONFIG_MDIO_OCTEON is not set
+# CONFIG_MDIO_IPQ4019 is not set
+# CONFIG_MDIO_IPQ8064 is not set
+CONFIG_MDIO_THUNDER=y
+
+#
+# MDIO Multiplexers
+#
+CONFIG_MDIO_BUS_MUX=y
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set
+CONFIG_MDIO_BUS_MUX_MMIOREG=y
+
+#
+# PCS device drivers
+#
+CONFIG_PCS_XPCS=m
+# end of PCS device drivers
+
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_USB_NET_DRIVERS is not set
+# CONFIG_WLAN is not set
+# CONFIG_WAN is not set
+
+#
+# Wireless WAN
+#
+# CONFIG_WWAN is not set
+# end of Wireless WAN
+
+# CONFIG_XEN_NETDEV_FRONTEND is not set
+# CONFIG_XEN_NETDEV_BACKEND is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_NETDEVSIM is not set
+# CONFIG_NET_FAILOVER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_LEDS=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_SPARSEKMAP is not set
+CONFIG_INPUT_MATRIXKMAP=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+# CONFIG_RMI4_CORE is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_SERIO_ARC_PS2 is not set
+# CONFIG_SERIO_APBPS2 is not set
+# CONFIG_SERIO_GPIO_PS2 is not set
+# CONFIG_USERIO is not set
+# CONFIG_GAMEPORT is not set
+# end of Hardware I/O ports
+# end of Input device support
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_LDISC_AUTOLOAD=y
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_EARLYCON=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_16550A_VARIANTS=y
+# CONFIG_SERIAL_8250_FINTEK is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_DMA=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_EXAR=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_DW=y
+# CONFIG_SERIAL_8250_RT288X is not set
+CONFIG_SERIAL_8250_PERICOM=y
+CONFIG_SERIAL_OF_PLATFORM=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_SIFIVE is not set
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_SC16IS7XX is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_SERIAL_RP2 is not set
+# CONFIG_SERIAL_FSL_LPUART is not set
+# CONFIG_SERIAL_FSL_LINFLEXUART is not set
+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set
+# CONFIG_SERIAL_SPRD is not set
+# end of Serial drivers
+
+CONFIG_SERIAL_MCTRL_GPIO=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_NULL_TTY is not set
+# CONFIG_HVC_XEN is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_RPMSG_TTY is not set
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_VIRTIO_CONSOLE is not set
+CONFIG_IPMI_HANDLER=m
+CONFIG_IPMI_DMI_DECODE=y
+CONFIG_IPMI_PLAT_DATA=y
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+# CONFIG_IPMI_SSIF is not set
+# CONFIG_IPMI_IPMB is not set
+# CONFIG_IPMI_WATCHDOG is not set
+# CONFIG_IPMI_POWEROFF is not set
+# CONFIG_IPMB_DEVICE_INTERFACE is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_HW_RANDOM_BA431 is not set
+# CONFIG_HW_RANDOM_VIRTIO is not set
+CONFIG_HW_RANDOM_OPTEE=m
+# CONFIG_HW_RANDOM_CCTRNG is not set
+# CONFIG_HW_RANDOM_XIPHERA is not set
+CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=m
+CONFIG_HW_RANDOM_CN10K=m
+# CONFIG_APPLICOM is not set
+CONFIG_DEVMEM=y
+CONFIG_DEVPORT=y
+# CONFIG_TCG_TPM is not set
+# CONFIG_XILLYBUS is not set
+# CONFIG_XILLYUSB is not set
+CONFIG_RANDOM_TRUST_CPU=y
+# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
+# end of Character devices
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+
+#
+# Multiplexer I2C Chip support
+#
+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
+# CONFIG_I2C_MUX_GPIO is not set
+# CONFIG_I2C_MUX_GPMUX is not set
+# CONFIG_I2C_MUX_LTC4306 is not set
+# CONFIG_I2C_MUX_PCA9541 is not set
+CONFIG_I2C_MUX_PCA954x=y
+# CONFIG_I2C_MUX_PINCTRL is not set
+# CONFIG_I2C_MUX_REG is not set
+# CONFIG_I2C_DEMUX_PINCTRL is not set
+# CONFIG_I2C_MUX_MLXCPLD is not set
+# end of Multiplexer I2C Chip support
+
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_NVIDIA_GPU is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_CADENCE is not set
+# CONFIG_I2C_CBUS_GPIO is not set
+CONFIG_I2C_DESIGNWARE_CORE=y
+# CONFIG_I2C_DESIGNWARE_SLAVE is not set
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+# CONFIG_I2C_DESIGNWARE_PCI is not set
+# CONFIG_I2C_EMEV2 is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_NOMADIK is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+CONFIG_I2C_RK3X=y
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_THUNDERX is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_CP2615 is not set
+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_VIRTIO is not set
+# end of I2C Hardware Bus support
+
+# CONFIG_I2C_STUB is not set
+CONFIG_I2C_SLAVE=y
+# CONFIG_I2C_SLAVE_EEPROM is not set
+# CONFIG_I2C_SLAVE_TESTUNIT is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# end of I2C support
+
+# CONFIG_I3C is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+# CONFIG_SPI_AXI_SPI_ENGINE is not set
+CONFIG_SPI_BITBANG=m
+# CONFIG_SPI_CADENCE is not set
+# CONFIG_SPI_CADENCE_QUADSPI is not set
+# CONFIG_SPI_CADENCE_XSPI is not set
+# CONFIG_SPI_DESIGNWARE is not set
+CONFIG_SPI_NXP_FLEXSPI=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_FSL_SPI is not set
+# CONFIG_SPI_MICROCHIP_CORE is not set
+# CONFIG_SPI_OC_TINY is not set
+CONFIG_SPI_PL022=y
+# CONFIG_SPI_PXA2XX is not set
+CONFIG_SPI_ROCKCHIP=y
+# CONFIG_SPI_ROCKCHIP_SFC is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_SIFIVE is not set
+# CONFIG_SPI_MXIC is not set
+# CONFIG_SPI_THUNDERX is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_ZYNQMP_GQSPI is not set
+# CONFIG_SPI_AMD is not set
+
+#
+# SPI Multiplexer support
+#
+# CONFIG_SPI_MUX is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_LOOPBACK_TEST is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_SPI_SLAVE is not set
+CONFIG_SPMI=y
+# CONFIG_SPMI_HISI3670 is not set
+# CONFIG_HSI is not set
+CONFIG_PPS=y
+# CONFIG_PPS_DEBUG is not set
+# CONFIG_NTP_PPS is not set
+
+#
+# PPS clients support
+#
+# CONFIG_PPS_CLIENT_KTIMER is not set
+# CONFIG_PPS_CLIENT_LDISC is not set
+# CONFIG_PPS_CLIENT_GPIO is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+# CONFIG_DP83640_PHY is not set
+# CONFIG_PTP_1588_CLOCK_INES is not set
+CONFIG_PTP_1588_CLOCK_KVM=y
+# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set
+# CONFIG_PTP_1588_CLOCK_IDTCM is not set
+# CONFIG_PTP_1588_CLOCK_OCP is not set
+# end of PTP clock support
+
+CONFIG_PINCTRL=y
+CONFIG_GENERIC_PINCTRL_GROUPS=y
+CONFIG_PINMUX=y
+CONFIG_GENERIC_PINMUX_FUNCTIONS=y
+CONFIG_PINCONF=y
+CONFIG_GENERIC_PINCONF=y
+# CONFIG_DEBUG_PINCTRL is not set
+# CONFIG_PINCTRL_AXP209 is not set
+CONFIG_PINCTRL_MAX77620=y
+# CONFIG_PINCTRL_MCP23S08 is not set
+# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set
+# CONFIG_PINCTRL_OCELOT is not set
+# CONFIG_PINCTRL_RK805 is not set
+CONFIG_PINCTRL_ROCKCHIP=y
+CONFIG_PINCTRL_SINGLE=y
+# CONFIG_PINCTRL_STMFX is not set
+# CONFIG_PINCTRL_SX150X is not set
+
+#
+# Renesas pinctrl drivers
+#
+# end of Renesas pinctrl drivers
+
+CONFIG_GPIOLIB=y
+CONFIG_GPIOLIB_FASTPATH_LIMIT=512
+CONFIG_OF_GPIO=y
+CONFIG_GPIOLIB_IRQCHIP=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_CDEV_V1=y
+CONFIG_GPIO_GENERIC=y
+
+#
+# Memory mapped GPIO drivers
+#
+# CONFIG_GPIO_74XX_MMIO is not set
+# CONFIG_GPIO_ALTERA is not set
+# CONFIG_GPIO_CADENCE is not set
+CONFIG_GPIO_DWAPB=y
+# CONFIG_GPIO_EXAR is not set
+# CONFIG_GPIO_FTGPIO010 is not set
+CONFIG_GPIO_GENERIC_PLATFORM=y
+# CONFIG_GPIO_GRGPIO is not set
+# CONFIG_GPIO_HLWD is not set
+# CONFIG_GPIO_LOGICVC is not set
+CONFIG_GPIO_MB86S7X=y
+CONFIG_GPIO_PL061=y
+CONFIG_GPIO_ROCKCHIP=y
+# CONFIG_GPIO_SIFIVE is not set
+# CONFIG_GPIO_SYSCON is not set
+CONFIG_GPIO_XGENE=y
+# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_AMD_FCH is not set
+# end of Memory mapped GPIO drivers
+
+#
+# I2C GPIO expanders
+#
+# CONFIG_GPIO_ADP5588 is not set
+# CONFIG_GPIO_ADNP is not set
+# CONFIG_GPIO_GW_PLD is not set
+# CONFIG_GPIO_MAX7300 is not set
+CONFIG_GPIO_MAX732X=y
+# CONFIG_GPIO_MAX732X_IRQ is not set
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+# CONFIG_GPIO_PCA9570 is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_TPIC2810 is not set
+# end of I2C GPIO expanders
+
+#
+# MFD GPIO expanders
+#
+# CONFIG_GPIO_BD9571MWV is not set
+CONFIG_GPIO_MAX77620=y
+# end of MFD GPIO expanders
+
+#
+# PCI GPIO expanders
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_PCI_IDIO_16 is not set
+# CONFIG_GPIO_PCIE_IDIO_24 is not set
+# CONFIG_GPIO_RDC321X is not set
+# end of PCI GPIO expanders
+
+#
+# SPI GPIO expanders
+#
+# CONFIG_GPIO_74X164 is not set
+# CONFIG_GPIO_MAX3191X is not set
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_PISOSR is not set
+# CONFIG_GPIO_XRA1403 is not set
+# end of SPI GPIO expanders
+
+#
+# USB GPIO expanders
+#
+# end of USB GPIO expanders
+
+#
+# Virtual GPIO drivers
+#
+# CONFIG_GPIO_AGGREGATOR is not set
+# CONFIG_GPIO_MOCKUP is not set
+# CONFIG_GPIO_VIRTIO is not set
+# CONFIG_GPIO_SIM is not set
+# end of Virtual GPIO drivers
+
+# CONFIG_W1 is not set
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_BRCMSTB=y
+# CONFIG_POWER_RESET_GPIO is not set
+# CONFIG_POWER_RESET_GPIO_RESTART is not set
+# CONFIG_POWER_RESET_LTC2952 is not set
+# CONFIG_POWER_RESET_REGULATOR is not set
+# CONFIG_POWER_RESET_RESTART is not set
+CONFIG_POWER_RESET_VEXPRESS=y
+CONFIG_POWER_RESET_XGENE=y
+CONFIG_POWER_RESET_SYSCON=y
+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set
+CONFIG_REBOOT_MODE=y
+CONFIG_SYSCON_REBOOT_MODE=y
+# CONFIG_NVMEM_REBOOT_MODE is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+CONFIG_POWER_SUPPLY_HWMON=y
+# CONFIG_PDA_POWER is not set
+# CONFIG_GENERIC_ADC_BATTERY is not set
+# CONFIG_IP5XXX_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_CHARGER_ADP5061 is not set
+# CONFIG_BATTERY_CW2015 is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2781 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_SAMSUNG_SDI is not set
+CONFIG_BATTERY_SBS=m
+# CONFIG_CHARGER_SBS is not set
+# CONFIG_MANAGER_SBS is not set
+CONFIG_BATTERY_BQ27XXX=y
+CONFIG_BATTERY_BQ27XXX_I2C=y
+# CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set
+# CONFIG_AXP20X_POWER is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_LP8727 is not set
+# CONFIG_CHARGER_GPIO is not set
+# CONFIG_CHARGER_MANAGER is not set
+# CONFIG_CHARGER_LT3651 is not set
+# CONFIG_CHARGER_LTC4162L is not set
+# CONFIG_CHARGER_DETECTOR_MAX14656 is not set
+# CONFIG_CHARGER_MAX77976 is not set
+# CONFIG_CHARGER_BQ2415X is not set
+# CONFIG_CHARGER_BQ24190 is not set
+# CONFIG_CHARGER_BQ24257 is not set
+# CONFIG_CHARGER_BQ24735 is not set
+# CONFIG_CHARGER_BQ2515X is not set
+# CONFIG_CHARGER_BQ25890 is not set
+# CONFIG_CHARGER_BQ25980 is not set
+# CONFIG_CHARGER_BQ256XX is not set
+# CONFIG_CHARGER_SMB347 is not set
+# CONFIG_BATTERY_GAUGE_LTC2941 is not set
+# CONFIG_BATTERY_GOLDFISH is not set
+# CONFIG_BATTERY_RT5033 is not set
+# CONFIG_CHARGER_RT9455 is not set
+# CONFIG_CHARGER_UCS1002 is not set
+# CONFIG_CHARGER_BD99954 is not set
+# CONFIG_BATTERY_UG3105 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7314 is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM1177 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7310 is not set
+# CONFIG_SENSORS_ADT7410 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_AHT10 is not set
+# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set
+# CONFIG_SENSORS_AS370 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_AXI_FAN_CONTROL is not set
+CONFIG_SENSORS_ARM_SCPI=y
+# CONFIG_SENSORS_ASPEED is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_CORSAIR_CPRO is not set
+# CONFIG_SENSORS_CORSAIR_PSU is not set
+# CONFIG_SENSORS_DRIVETEMP is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_FTSTEUTATES is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_G762 is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_HIH6130 is not set
+# CONFIG_SENSORS_IBMAEM is not set
+# CONFIG_SENSORS_IBMPEX is not set
+# CONFIG_SENSORS_IIO_HWMON is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_POWR1220 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LTC2945 is not set
+# CONFIG_SENSORS_LTC2947_I2C is not set
+# CONFIG_SENSORS_LTC2947_SPI is not set
+# CONFIG_SENSORS_LTC2990 is not set
+# CONFIG_SENSORS_LTC2992 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4222 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4260 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX127 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX1668 is not set
+# CONFIG_SENSORS_MAX197 is not set
+# CONFIG_SENSORS_MAX31722 is not set
+# CONFIG_SENSORS_MAX31730 is not set
+# CONFIG_SENSORS_MAX6620 is not set
+# CONFIG_SENSORS_MAX6621 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_MAX6697 is not set
+# CONFIG_SENSORS_MAX31790 is not set
+# CONFIG_SENSORS_MCP3021 is not set
+# CONFIG_SENSORS_TC654 is not set
+# CONFIG_SENSORS_TPS23861 is not set
+# CONFIG_SENSORS_MR75203 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+CONFIG_SENSORS_LM90=m
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LM95234 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_LM95245 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_NTC_THERMISTOR is not set
+# CONFIG_SENSORS_NCT6683 is not set
+# CONFIG_SENSORS_NCT6775 is not set
+# CONFIG_SENSORS_NCT6775_I2C is not set
+# CONFIG_SENSORS_NCT7802 is not set
+# CONFIG_SENSORS_NCT7904 is not set
+# CONFIG_SENSORS_NPCM7XX is not set
+# CONFIG_SENSORS_NZXT_KRAKEN2 is not set
+# CONFIG_SENSORS_NZXT_SMART2 is not set
+# CONFIG_SENSORS_OCC_P8_I2C is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+CONFIG_SENSORS_PWM_FAN=m
+# CONFIG_SENSORS_SBTSI is not set
+# CONFIG_SENSORS_SBRMI is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SHT3x is not set
+# CONFIG_SENSORS_SHT4x is not set
+# CONFIG_SENSORS_SHTC1 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SY7636A is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_SCH5636 is not set
+# CONFIG_SENSORS_STTS751 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_ADC128D818 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_INA209 is not set
+CONFIG_SENSORS_INA2XX=m
+# CONFIG_SENSORS_INA238 is not set
+CONFIG_SENSORS_INA3221=m
+# CONFIG_SENSORS_TC74 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP103 is not set
+# CONFIG_SENSORS_TMP108 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_TMP464 is not set
+# CONFIG_SENSORS_TMP513 is not set
+# CONFIG_SENSORS_VEXPRESS is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83773G is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_NETLINK is not set
+# CONFIG_THERMAL_STATISTICS is not set
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=y
+# CONFIG_THERMAL_WRITABLE_TRIPS is not set
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
+# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
+# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
+CONFIG_THERMAL_GOV_STEP_WISE=y
+# CONFIG_THERMAL_GOV_BANG_BANG is not set
+# CONFIG_THERMAL_GOV_USER_SPACE is not set
+CONFIG_CPU_THERMAL=y
+CONFIG_CPU_FREQ_THERMAL=y
+# CONFIG_DEVFREQ_THERMAL is not set
+CONFIG_THERMAL_EMULATION=y
+# CONFIG_THERMAL_MMIO is not set
+# CONFIG_MAX77620_THERMAL is not set
+CONFIG_ROCKCHIP_THERMAL=m
+# CONFIG_GENERIC_ADC_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y
+CONFIG_WATCHDOG_OPEN_TIMEOUT=0
+# CONFIG_WATCHDOG_SYSFS is not set
+# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set
+
+#
+# Watchdog Pretimeout Governors
+#
+# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_GPIO_WATCHDOG is not set
+# CONFIG_XILINX_WATCHDOG is not set
+# CONFIG_ZIIRAVE_WATCHDOG is not set
+CONFIG_ARM_SP805_WATCHDOG=y
+# CONFIG_ARM_SBSA_WATCHDOG is not set
+# CONFIG_CADENCE_WATCHDOG is not set
+CONFIG_DW_WATCHDOG=y
+# CONFIG_MAX63XX_WATCHDOG is not set
+# CONFIG_MAX77620_WATCHDOG is not set
+# CONFIG_ARM_SMC_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_I6300ESB_WDT is not set
+# CONFIG_MEN_A21_WDT is not set
+# CONFIG_XEN_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_ACT8945A is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_MFD_AS3722 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_ATMEL_FLEXCOM is not set
+# CONFIG_MFD_ATMEL_HLCDC is not set
+# CONFIG_MFD_BCM590XX is not set
+CONFIG_MFD_BD9571MWV=y
+CONFIG_MFD_AXP20X=y
+CONFIG_MFD_AXP20X_I2C=y
+# CONFIG_MFD_MADERA is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_DA9062 is not set
+# CONFIG_MFD_DA9063 is not set
+# CONFIG_MFD_DA9150 is not set
+# CONFIG_MFD_DLN2 is not set
+# CONFIG_MFD_GATEWORKS_GSC is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_MFD_MP2629 is not set
+CONFIG_MFD_HI6421_PMIC=y
+# CONFIG_MFD_HI6421_SPMI is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_LPC_ICH is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_IQS62X is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_KEMPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX14577 is not set
+CONFIG_MFD_MAX77620=y
+# CONFIG_MFD_MAX77650 is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX77714 is not set
+# CONFIG_MFD_MAX77843 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_MT6360 is not set
+# CONFIG_MFD_MT6397 is not set
+# CONFIG_MFD_MENF21BMC is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_CPCAP is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_NTXEC is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_RT4831 is not set
+# CONFIG_MFD_RT5033 is not set
+# CONFIG_MFD_RC5T583 is not set
+CONFIG_MFD_RK808=y
+# CONFIG_MFD_RN5T618 is not set
+CONFIG_MFD_SEC_CORE=y
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SIMPLE_MFD_I2C is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SKY81452 is not set
+# CONFIG_MFD_STMPE is not set
+CONFIG_MFD_SYSCON=y
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP3943 is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_TI_LMU is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65086 is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TI_LP873X is not set
+# CONFIG_MFD_TI_LP87565 is not set
+# CONFIG_MFD_TPS65218 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TQMX86 is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_MFD_LOCHNAGAR is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+CONFIG_MFD_ROHM_BD718XX=y
+# CONFIG_MFD_ROHM_BD71828 is not set
+# CONFIG_MFD_ROHM_BD957XMUF is not set
+# CONFIG_MFD_STPMIC1 is not set
+# CONFIG_MFD_STMFX is not set
+# CONFIG_MFD_ATC260X_I2C is not set
+# CONFIG_MFD_KHADAS_MCU is not set
+# CONFIG_MFD_QCOM_PM8008 is not set
+CONFIG_MFD_VEXPRESS_SYSREG=y
+# CONFIG_RAVE_SP_CORE is not set
+# CONFIG_MFD_INTEL_M10_BMC is not set
+# CONFIG_MFD_RSMU_I2C is not set
+# CONFIG_MFD_RSMU_SPI is not set
+# end of Multifunction device drivers
+
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_88PG86X is not set
+# CONFIG_REGULATOR_ACT8865 is not set
+# CONFIG_REGULATOR_AD5398 is not set
+CONFIG_REGULATOR_AXP20X=y
+CONFIG_REGULATOR_BD718XX=y
+CONFIG_REGULATOR_BD9571MWV=y
+# CONFIG_REGULATOR_DA9121 is not set
+# CONFIG_REGULATOR_DA9210 is not set
+# CONFIG_REGULATOR_DA9211 is not set
+CONFIG_REGULATOR_FAN53555=y
+# CONFIG_REGULATOR_FAN53880 is not set
+CONFIG_REGULATOR_GPIO=y
+# CONFIG_REGULATOR_HI6421 is not set
+CONFIG_REGULATOR_HI6421V530=y
+# CONFIG_REGULATOR_ISL9305 is not set
+# CONFIG_REGULATOR_ISL6271A is not set
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_LP872X is not set
+# CONFIG_REGULATOR_LP8755 is not set
+# CONFIG_REGULATOR_LTC3589 is not set
+# CONFIG_REGULATOR_LTC3676 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_MAX77620=y
+# CONFIG_REGULATOR_MAX8649 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
+# CONFIG_REGULATOR_MAX8893 is not set
+# CONFIG_REGULATOR_MAX8952 is not set
+CONFIG_REGULATOR_MAX8973=y
+# CONFIG_REGULATOR_MAX20086 is not set
+# CONFIG_REGULATOR_MAX77826 is not set
+# CONFIG_REGULATOR_MCP16502 is not set
+# CONFIG_REGULATOR_MP5416 is not set
+# CONFIG_REGULATOR_MP8859 is not set
+# CONFIG_REGULATOR_MP886X is not set
+# CONFIG_REGULATOR_MPQ7920 is not set
+# CONFIG_REGULATOR_MT6311 is not set
+# CONFIG_REGULATOR_MT6315 is not set
+# CONFIG_REGULATOR_PCA9450 is not set
+# CONFIG_REGULATOR_PF8X00 is not set
+CONFIG_REGULATOR_PFUZE100=y
+# CONFIG_REGULATOR_PV88060 is not set
+# CONFIG_REGULATOR_PV88080 is not set
+# CONFIG_REGULATOR_PV88090 is not set
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_QCOM_SPMI=y
+# CONFIG_REGULATOR_QCOM_USB_VBUS is not set
+# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set
+CONFIG_REGULATOR_RK808=y
+CONFIG_REGULATOR_ROHM=y
+# CONFIG_REGULATOR_RT4801 is not set
+# CONFIG_REGULATOR_RT5190A is not set
+# CONFIG_REGULATOR_RT5759 is not set
+# CONFIG_REGULATOR_RT6160 is not set
+# CONFIG_REGULATOR_RT6245 is not set
+# CONFIG_REGULATOR_RTQ2134 is not set
+# CONFIG_REGULATOR_RTMV20 is not set
+# CONFIG_REGULATOR_RTQ6752 is not set
+# CONFIG_REGULATOR_S2MPA01 is not set
+CONFIG_REGULATOR_S2MPS11=y
+# CONFIG_REGULATOR_S5M8767 is not set
+# CONFIG_REGULATOR_SLG51000 is not set
+# CONFIG_REGULATOR_SY7636A is not set
+# CONFIG_REGULATOR_SY8106A is not set
+# CONFIG_REGULATOR_SY8824X is not set
+# CONFIG_REGULATOR_SY8827N is not set
+# CONFIG_REGULATOR_TPS51632 is not set
+# CONFIG_REGULATOR_TPS62360 is not set
+# CONFIG_REGULATOR_TPS6286X is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_REGULATOR_TPS65132 is not set
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_VCTRL=m
+# CONFIG_REGULATOR_VEXPRESS is not set
+# CONFIG_REGULATOR_QCOM_LABIBB is not set
+CONFIG_RC_CORE=m
+# CONFIG_LIRC is not set
+CONFIG_RC_MAP=m
+CONFIG_RC_DECODERS=y
+# CONFIG_IR_IMON_DECODER is not set
+# CONFIG_IR_JVC_DECODER is not set
+# CONFIG_IR_MCE_KBD_DECODER is not set
+# CONFIG_IR_NEC_DECODER is not set
+# CONFIG_IR_RC5_DECODER is not set
+# CONFIG_IR_RC6_DECODER is not set
+# CONFIG_IR_RCMM_DECODER is not set
+# CONFIG_IR_SANYO_DECODER is not set
+# CONFIG_IR_SHARP_DECODER is not set
+# CONFIG_IR_SONY_DECODER is not set
+# CONFIG_IR_XMP_DECODER is not set
+CONFIG_RC_DEVICES=y
+# CONFIG_IR_GPIO_CIR is not set
+# CONFIG_IR_HIX5HD2 is not set
+# CONFIG_IR_IGORPLUGUSB is not set
+# CONFIG_IR_IGUANA is not set
+# CONFIG_IR_IMON is not set
+# CONFIG_IR_IMON_RAW is not set
+# CONFIG_IR_MCEUSB is not set
+# CONFIG_IR_REDRAT3 is not set
+# CONFIG_IR_SERIAL is not set
+# CONFIG_IR_STREAMZAP is not set
+# CONFIG_IR_TOY is not set
+# CONFIG_IR_TTUSBIR is not set
+# CONFIG_RC_ATI_REMOTE is not set
+# CONFIG_RC_LOOPBACK is not set
+# CONFIG_RC_XBOX_DVD is not set
+CONFIG_CEC_CORE=m
+
+#
+# CEC support
+#
+# CONFIG_MEDIA_CEC_RC is not set
+# CONFIG_MEDIA_CEC_SUPPORT is not set
+# end of CEC support
+
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_SUPPORT_FILTER=y
+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
+
+#
+# Media device types
+#
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+# CONFIG_MEDIA_RADIO_SUPPORT is not set
+# CONFIG_MEDIA_SDR_SUPPORT is not set
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+# CONFIG_MEDIA_TEST_SUPPORT is not set
+# end of Media device types
+
+CONFIG_VIDEO_DEV=m
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_DVB_CORE=m
+
+#
+# Video4Linux options
+#
+CONFIG_VIDEO_V4L2_I2C=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_VIDEO_ADV_DEBUG=y
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_V4L2_H264=m
+CONFIG_V4L2_VP9=m
+CONFIG_V4L2_MEM2MEM_DEV=m
+CONFIG_V4L2_FWNODE=m
+CONFIG_V4L2_ASYNC=m
+# end of Video4Linux options
+
+#
+# Media controller options
+#
+# CONFIG_MEDIA_CONTROLLER_DVB is not set
+CONFIG_MEDIA_CONTROLLER_REQUEST_API=y
+# end of Media controller options
+
+#
+# Digital TV options
+#
+# CONFIG_DVB_MMAP is not set
+# CONFIG_DVB_NET is not set
+CONFIG_DVB_MAX_ADAPTERS=16
+# CONFIG_DVB_DYNAMIC_MINORS is not set
+# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set
+# CONFIG_DVB_ULE_DEBUG is not set
+# end of Digital TV options
+
+#
+# Media drivers
+#
+
+#
+# Drivers filtered as selected at 'Filter media drivers'
+#
+
+#
+# Media drivers
+#
+CONFIG_MEDIA_USB_SUPPORT=y
+
+#
+# Webcam devices
+#
+# CONFIG_VIDEO_CPIA2 is not set
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_GSPCA_BENQ is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_CPIA1 is not set
+# CONFIG_USB_GSPCA_DTCS033 is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_JEILINJ is not set
+# CONFIG_USB_GSPCA_JL2005BCD is not set
+# CONFIG_USB_GSPCA_KINECT is not set
+# CONFIG_USB_GSPCA_KONICA is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
+# CONFIG_USB_GSPCA_NW80X is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_OV534_9 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7302 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SE401 is not set
+# CONFIG_USB_GSPCA_SN9C2028 is not set
+# CONFIG_USB_GSPCA_SN9C20X is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA1528 is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
+# CONFIG_USB_GSPCA_SQ930X is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_STK1135 is not set
+# CONFIG_USB_GSPCA_STV0680 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TOPRO is not set
+# CONFIG_USB_GSPCA_TOUPTEK is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_VICAM is not set
+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# CONFIG_USB_GL860 is not set
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_STV06XX is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_S2255 is not set
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+# CONFIG_USB_ZR364XX is not set
+
+#
+# Analog TV USB devices
+#
+# CONFIG_VIDEO_HDPVR is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_STK1160_COMMON is not set
+
+#
+# Analog/digital TV USB devices
+#
+# CONFIG_VIDEO_AU0828 is not set
+# CONFIG_VIDEO_CX231XX is not set
+# CONFIG_VIDEO_TM6000 is not set
+
+#
+# Digital TV USB devices
+#
+# CONFIG_DVB_AS102 is not set
+# CONFIG_DVB_B2C2_FLEXCOP_USB is not set
+# CONFIG_DVB_USB_V2 is not set
+# CONFIG_DVB_USB is not set
+# CONFIG_SMS_USB_DRV is not set
+# CONFIG_DVB_TTUSB_BUDGET is not set
+# CONFIG_DVB_TTUSB_DEC is not set
+
+#
+# Webcam, TV (analog/digital) USB devices
+#
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_MEDIA_PCI_SUPPORT is not set
+CONFIG_MEDIA_PLATFORM_DRIVERS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+# CONFIG_DVB_PLATFORM_DRIVERS is not set
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_MEM2MEM_DEINTERLACE=m
+# CONFIG_VIDEO_MUX is not set
+
+#
+# Allegro DVT media platform drivers
+#
+
+#
+# Amlogic media platform drivers
+#
+
+#
+# Amphion drivers
+#
+
+#
+# Aspeed media platform drivers
+#
+# CONFIG_VIDEO_ASPEED is not set
+
+#
+# Atmel media platform drivers
+#
+
+#
+# Cadence media platform drivers
+#
+# CONFIG_VIDEO_CADENCE_CSI2RX is not set
+# CONFIG_VIDEO_CADENCE_CSI2TX is not set
+
+#
+# Chips&Media media platform drivers
+#
+
+#
+# Intel media platform drivers
+#
+
+#
+# Marvell media platform drivers
+#
+# CONFIG_VIDEO_CAFE_CCIC is not set
+
+#
+# Mediatek media platform drivers
+#
+
+#
+# NVidia media platform drivers
+#
+
+#
+# NXP media platform drivers
+#
+
+#
+# Qualcomm media platform drivers
+#
+
+#
+# Renesas media platform drivers
+#
+
+#
+# Rockchip media platform drivers
+#
+CONFIG_VIDEO_ROCKCHIP_RGA=m
+CONFIG_VIDEO_ROCKCHIP_ISP1=m
+
+#
+# Samsung media platform drivers
+#
+
+#
+# STMicroelectronics media platform drivers
+#
+
+#
+# Sunxi media platform drivers
+#
+
+#
+# Texas Instruments drivers
+#
+
+#
+# VIA media platform drivers
+#
+
+#
+# Xilinx media platform drivers
+#
+# CONFIG_VIDEO_XILINX is not set
+
+#
+# MMC/SDIO DVB adapters
+#
+# CONFIG_SMS_SDIO_DRV is not set
+CONFIG_VIDEOBUF2_CORE=m
+CONFIG_VIDEOBUF2_V4L2=m
+CONFIG_VIDEOBUF2_MEMOPS=m
+CONFIG_VIDEOBUF2_DMA_CONTIG=m
+CONFIG_VIDEOBUF2_VMALLOC=m
+CONFIG_VIDEOBUF2_DMA_SG=m
+# end of Media drivers
+
+#
+# Media ancillary drivers
+#
+CONFIG_MEDIA_ATTACH=y
+
+#
+# IR I2C driver auto-selected by 'Autoselect ancillary drivers'
+#
+CONFIG_VIDEO_IR_I2C=m
+
+#
+# Camera sensor devices
+#
+# CONFIG_VIDEO_AR0521 is not set
+# CONFIG_VIDEO_HI556 is not set
+# CONFIG_VIDEO_HI846 is not set
+# CONFIG_VIDEO_HI847 is not set
+# CONFIG_VIDEO_IMX208 is not set
+# CONFIG_VIDEO_IMX214 is not set
+CONFIG_VIDEO_IMX219=m
+# CONFIG_VIDEO_IMX258 is not set
+# CONFIG_VIDEO_IMX274 is not set
+# CONFIG_VIDEO_IMX290 is not set
+# CONFIG_VIDEO_IMX319 is not set
+# CONFIG_VIDEO_IMX334 is not set
+# CONFIG_VIDEO_IMX335 is not set
+# CONFIG_VIDEO_IMX355 is not set
+# CONFIG_VIDEO_IMX412 is not set
+# CONFIG_VIDEO_MT9M001 is not set
+# CONFIG_VIDEO_MT9M032 is not set
+# CONFIG_VIDEO_MT9M111 is not set
+# CONFIG_VIDEO_MT9P031 is not set
+# CONFIG_VIDEO_MT9T001 is not set
+# CONFIG_VIDEO_MT9T112 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_MT9V032 is not set
+# CONFIG_VIDEO_MT9V111 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_VIDEO_OG01A1B is not set
+# CONFIG_VIDEO_OV02A10 is not set
+# CONFIG_VIDEO_OV08D10 is not set
+# CONFIG_VIDEO_OV13858 is not set
+# CONFIG_VIDEO_OV13B10 is not set
+# CONFIG_VIDEO_OV2640 is not set
+# CONFIG_VIDEO_OV2659 is not set
+# CONFIG_VIDEO_OV2680 is not set
+# CONFIG_VIDEO_OV2685 is not set
+# CONFIG_VIDEO_OV5640 is not set
+# CONFIG_VIDEO_OV5645 is not set
+CONFIG_VIDEO_OV5647=m
+# CONFIG_VIDEO_OV5648 is not set
+# CONFIG_VIDEO_OV5670 is not set
+# CONFIG_VIDEO_OV5675 is not set
+# CONFIG_VIDEO_OV5693 is not set
+# CONFIG_VIDEO_OV5695 is not set
+# CONFIG_VIDEO_OV6650 is not set
+# CONFIG_VIDEO_OV7251 is not set
+# CONFIG_VIDEO_OV7640 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_OV772X is not set
+# CONFIG_VIDEO_OV7740 is not set
+# CONFIG_VIDEO_OV8856 is not set
+# CONFIG_VIDEO_OV8865 is not set
+# CONFIG_VIDEO_OV9282 is not set
+# CONFIG_VIDEO_OV9640 is not set
+# CONFIG_VIDEO_OV9650 is not set
+# CONFIG_VIDEO_RDACM20 is not set
+# CONFIG_VIDEO_RDACM21 is not set
+# CONFIG_VIDEO_RJ54N1 is not set
+# CONFIG_VIDEO_S5C73M3 is not set
+# CONFIG_VIDEO_S5K4ECGX is not set
+# CONFIG_VIDEO_S5K5BAF is not set
+# CONFIG_VIDEO_S5K6A3 is not set
+# CONFIG_VIDEO_S5K6AA is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_VS6624 is not set
+# CONFIG_VIDEO_CCS is not set
+# CONFIG_VIDEO_ET8EK8 is not set
+# CONFIG_VIDEO_M5MOLS is not set
+# end of Camera sensor devices
+
+#
+# Lens drivers
+#
+# CONFIG_VIDEO_AD5820 is not set
+# CONFIG_VIDEO_AK7375 is not set
+# CONFIG_VIDEO_DW9714 is not set
+# CONFIG_VIDEO_DW9768 is not set
+# CONFIG_VIDEO_DW9807_VCM is not set
+# end of Lens drivers
+
+#
+# Flash devices
+#
+# CONFIG_VIDEO_ADP1653 is not set
+# CONFIG_VIDEO_LM3560 is not set
+# CONFIG_VIDEO_LM3646 is not set
+# end of Flash devices
+
+#
+# Audio decoders, processors and mixers
+#
+# CONFIG_VIDEO_CS3308 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_SONY_BTF_MPX is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_UDA1342 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_WM8775 is not set
+# end of Audio decoders, processors and mixers
+
+#
+# RDS decoders
+#
+# CONFIG_VIDEO_SAA6588 is not set
+# end of RDS decoders
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_ADV7180 is not set
+# CONFIG_VIDEO_ADV7183 is not set
+# CONFIG_VIDEO_ADV748X is not set
+# CONFIG_VIDEO_ADV7604 is not set
+# CONFIG_VIDEO_ADV7842 is not set
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_ISL7998X is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_MAX9286 is not set
+# CONFIG_VIDEO_ML86V7667 is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_TC358743 is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_TVP7002 is not set
+# CONFIG_VIDEO_TW2804 is not set
+# CONFIG_VIDEO_TW9903 is not set
+# CONFIG_VIDEO_TW9906 is not set
+# CONFIG_VIDEO_TW9910 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_CX25840 is not set
+# end of Video decoders
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_AD9389B is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+# CONFIG_VIDEO_ADV7343 is not set
+# CONFIG_VIDEO_ADV7393 is not set
+# CONFIG_VIDEO_AK881X is not set
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_THS8200 is not set
+# end of Video encoders
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# end of Video improvement chips
+
+#
+# Audio/Video compression chips
+#
+# CONFIG_VIDEO_SAA6752HS is not set
+# end of Audio/Video compression chips
+
+#
+# SDR tuner chips
+#
+# end of SDR tuner chips
+
+#
+# Miscellaneous helper chips
+#
+# CONFIG_VIDEO_I2C is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_ST_MIPID02 is not set
+# CONFIG_VIDEO_THS7303 is not set
+# end of Miscellaneous helper chips
+
+#
+# Media SPI Adapters
+#
+# CONFIG_CXD2880_SPI_DRV is not set
+# CONFIG_VIDEO_GS1662 is not set
+# end of Media SPI Adapters
+
+CONFIG_MEDIA_TUNER=m
+
+#
+# Customize TV tuners
+#
+# CONFIG_MEDIA_TUNER_E4000 is not set
+# CONFIG_MEDIA_TUNER_FC0011 is not set
+# CONFIG_MEDIA_TUNER_FC0012 is not set
+# CONFIG_MEDIA_TUNER_FC0013 is not set
+# CONFIG_MEDIA_TUNER_FC2580 is not set
+# CONFIG_MEDIA_TUNER_IT913X is not set
+# CONFIG_MEDIA_TUNER_M88RS6000T is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+CONFIG_MEDIA_TUNER_MC44S803=m
+# CONFIG_MEDIA_TUNER_MSI001 is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2063 is not set
+CONFIG_MEDIA_TUNER_MT20XX=m
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MXL301RF is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set
+# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_R820T is not set
+# CONFIG_MEDIA_TUNER_SI2157 is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_TDA18250 is not set
+CONFIG_MEDIA_TUNER_TDA18271=m
+CONFIG_MEDIA_TUNER_TDA827X=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_TUA9001 is not set
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC4000=m
+CONFIG_MEDIA_TUNER_XC5000=m
+# end of Customize TV tuners
+
+#
+# Customise DVB Frontends
+#
+
+#
+# Multistandard (satellite) frontends
+#
+# CONFIG_DVB_M88DS3103 is not set
+# CONFIG_DVB_MXL5XX is not set
+# CONFIG_DVB_STB0899 is not set
+# CONFIG_DVB_STB6100 is not set
+# CONFIG_DVB_STV090x is not set
+# CONFIG_DVB_STV0910 is not set
+# CONFIG_DVB_STV6110x is not set
+# CONFIG_DVB_STV6111 is not set
+
+#
+# Multistandard (cable + terrestrial) frontends
+#
+# CONFIG_DVB_DRXK is not set
+# CONFIG_DVB_MN88472 is not set
+# CONFIG_DVB_MN88473 is not set
+# CONFIG_DVB_SI2165 is not set
+# CONFIG_DVB_TDA18271C2DD is not set
+
+#
+# DVB-S (satellite) frontends
+#
+# CONFIG_DVB_CX24110 is not set
+# CONFIG_DVB_CX24116 is not set
+# CONFIG_DVB_CX24117 is not set
+# CONFIG_DVB_CX24120 is not set
+# CONFIG_DVB_CX24123 is not set
+# CONFIG_DVB_DS3000 is not set
+# CONFIG_DVB_MB86A16 is not set
+# CONFIG_DVB_MT312 is not set
+# CONFIG_DVB_S5H1420 is not set
+# CONFIG_DVB_SI21XX is not set
+# CONFIG_DVB_STB6000 is not set
+# CONFIG_DVB_STV0288 is not set
+# CONFIG_DVB_STV0299 is not set
+# CONFIG_DVB_STV0900 is not set
+# CONFIG_DVB_STV6110 is not set
+# CONFIG_DVB_TDA10071 is not set
+# CONFIG_DVB_TDA10086 is not set
+# CONFIG_DVB_TDA8083 is not set
+# CONFIG_DVB_TDA8261 is not set
+# CONFIG_DVB_TDA826X is not set
+# CONFIG_DVB_TS2020 is not set
+# CONFIG_DVB_TUA6100 is not set
+# CONFIG_DVB_TUNER_CX24113 is not set
+# CONFIG_DVB_TUNER_ITD1000 is not set
+# CONFIG_DVB_VES1X93 is not set
+# CONFIG_DVB_ZL10036 is not set
+# CONFIG_DVB_ZL10039 is not set
+
+#
+# DVB-T (terrestrial) frontends
+#
+# CONFIG_DVB_AF9013 is not set
+# CONFIG_DVB_CX22700 is not set
+# CONFIG_DVB_CX22702 is not set
+# CONFIG_DVB_CXD2820R is not set
+# CONFIG_DVB_CXD2841ER is not set
+# CONFIG_DVB_DIB3000MB is not set
+# CONFIG_DVB_DIB3000MC is not set
+# CONFIG_DVB_DIB7000M is not set
+# CONFIG_DVB_DIB7000P is not set
+# CONFIG_DVB_DIB9000 is not set
+# CONFIG_DVB_DRXD is not set
+# CONFIG_DVB_EC100 is not set
+# CONFIG_DVB_L64781 is not set
+# CONFIG_DVB_MT352 is not set
+# CONFIG_DVB_NXT6000 is not set
+# CONFIG_DVB_RTL2830 is not set
+# CONFIG_DVB_RTL2832 is not set
+# CONFIG_DVB_S5H1432 is not set
+# CONFIG_DVB_SI2168 is not set
+# CONFIG_DVB_SP887X is not set
+# CONFIG_DVB_STV0367 is not set
+# CONFIG_DVB_TDA10048 is not set
+# CONFIG_DVB_TDA1004X is not set
+# CONFIG_DVB_ZD1301_DEMOD is not set
+# CONFIG_DVB_ZL10353 is not set
+# CONFIG_DVB_CXD2880 is not set
+
+#
+# DVB-C (cable) frontends
+#
+# CONFIG_DVB_STV0297 is not set
+# CONFIG_DVB_TDA10021 is not set
+# CONFIG_DVB_TDA10023 is not set
+# CONFIG_DVB_VES1820 is not set
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+# CONFIG_DVB_AU8522_DTV is not set
+# CONFIG_DVB_AU8522_V4L is not set
+# CONFIG_DVB_BCM3510 is not set
+# CONFIG_DVB_LG2160 is not set
+# CONFIG_DVB_LGDT3305 is not set
+# CONFIG_DVB_LGDT3306A is not set
+# CONFIG_DVB_LGDT330X is not set
+# CONFIG_DVB_MXL692 is not set
+# CONFIG_DVB_NXT200X is not set
+# CONFIG_DVB_OR51132 is not set
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_S5H1409 is not set
+# CONFIG_DVB_S5H1411 is not set
+
+#
+# ISDB-T (terrestrial) frontends
+#
+# CONFIG_DVB_DIB8000 is not set
+# CONFIG_DVB_MB86A20S is not set
+# CONFIG_DVB_S921 is not set
+
+#
+# ISDB-S (satellite) & ISDB-T (terrestrial) frontends
+#
+# CONFIG_DVB_MN88443X is not set
+# CONFIG_DVB_TC90522 is not set
+
+#
+# Digital terrestrial only tuners/PLL
+#
+# CONFIG_DVB_PLL is not set
+# CONFIG_DVB_TUNER_DIB0070 is not set
+# CONFIG_DVB_TUNER_DIB0090 is not set
+
+#
+# SEC control devices for DVB-S
+#
+# CONFIG_DVB_A8293 is not set
+# CONFIG_DVB_AF9033 is not set
+# CONFIG_DVB_ASCOT2E is not set
+# CONFIG_DVB_ATBM8830 is not set
+# CONFIG_DVB_HELENE is not set
+# CONFIG_DVB_HORUS3A is not set
+# CONFIG_DVB_ISL6405 is not set
+# CONFIG_DVB_ISL6421 is not set
+# CONFIG_DVB_ISL6423 is not set
+# CONFIG_DVB_IX2505V is not set
+# CONFIG_DVB_LGS8GL5 is not set
+# CONFIG_DVB_LGS8GXX is not set
+# CONFIG_DVB_LNBH25 is not set
+# CONFIG_DVB_LNBH29 is not set
+# CONFIG_DVB_LNBP21 is not set
+# CONFIG_DVB_LNBP22 is not set
+# CONFIG_DVB_M88RS2000 is not set
+# CONFIG_DVB_TDA665x is not set
+# CONFIG_DVB_DRX39XYJ is not set
+
+#
+# Common Interface (EN50221) controller drivers
+#
+# CONFIG_DVB_CXD2099 is not set
+# CONFIG_DVB_SP2 is not set
+# end of Customise DVB Frontends
+# end of Media ancillary drivers
+
+#
+# Graphics support
+#
+CONFIG_DRM=m
+CONFIG_DRM_MIPI_DSI=y
+# CONFIG_DRM_DEBUG_SELFTEST is not set
+CONFIG_DRM_KMS_HELPER=m
+# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set
+# CONFIG_DRM_DEBUG_MODESET_LOCK is not set
+# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
+CONFIG_DRM_DISPLAY_HELPER=m
+CONFIG_DRM_DISPLAY_DP_HELPER=y
+CONFIG_DRM_DISPLAY_HDMI_HELPER=y
+# CONFIG_DRM_DP_AUX_CHARDEV is not set
+# CONFIG_DRM_DP_CEC is not set
+CONFIG_DRM_GEM_CMA_HELPER=m
+CONFIG_DRM_GEM_SHMEM_HELPER=m
+CONFIG_DRM_SCHED=m
+
+#
+# I2C encoder or helper chips
+#
+CONFIG_DRM_I2C_CH7006=m
+CONFIG_DRM_I2C_SIL164=m
+CONFIG_DRM_I2C_NXP_TDA998X=m
+# CONFIG_DRM_I2C_NXP_TDA9950 is not set
+# end of I2C encoder or helper chips
+
+#
+# ARM devices
+#
+# CONFIG_DRM_HDLCD is not set
+# CONFIG_DRM_MALI_DISPLAY is not set
+# CONFIG_DRM_KOMEDA is not set
+# end of ARM devices
+
+# CONFIG_DRM_RADEON is not set
+# CONFIG_DRM_AMDGPU is not set
+# CONFIG_DRM_NOUVEAU is not set
+# CONFIG_DRM_VGEM is not set
+# CONFIG_DRM_VKMS is not set
+CONFIG_DRM_ROCKCHIP=m
+CONFIG_ROCKCHIP_VOP=y
+# CONFIG_ROCKCHIP_VOP2 is not set
+CONFIG_ROCKCHIP_ANALOGIX_DP=y
+CONFIG_ROCKCHIP_CDN_DP=y
+CONFIG_ROCKCHIP_DW_HDMI=y
+CONFIG_ROCKCHIP_DW_MIPI_DSI=y
+CONFIG_ROCKCHIP_INNO_HDMI=y
+# CONFIG_ROCKCHIP_LVDS is not set
+# CONFIG_ROCKCHIP_RGB is not set
+# CONFIG_ROCKCHIP_RK3066_HDMI is not set
+# CONFIG_DRM_VMWGFX is not set
+# CONFIG_DRM_UDL is not set
+# CONFIG_DRM_AST is not set
+# CONFIG_DRM_MGAG200 is not set
+# CONFIG_DRM_RCAR_DW_HDMI is not set
+# CONFIG_DRM_RCAR_USE_LVDS is not set
+# CONFIG_DRM_RCAR_MIPI_DSI is not set
+# CONFIG_DRM_QXL is not set
+CONFIG_DRM_PANEL=y
+
+#
+# Display Panels
+#
+# CONFIG_DRM_PANEL_ABT_Y030XX067A is not set
+# CONFIG_DRM_PANEL_ARM_VERSATILE is not set
+# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set
+# CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0 is not set
+# CONFIG_DRM_PANEL_BOE_HIMAX8279D is not set
+# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set
+# CONFIG_DRM_PANEL_DSI_CM is not set
+# CONFIG_DRM_PANEL_LVDS is not set
+CONFIG_DRM_PANEL_SIMPLE=m
+# CONFIG_DRM_PANEL_EDP is not set
+# CONFIG_DRM_PANEL_EBBG_FT8719 is not set
+# CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set
+# CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02 is not set
+# CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D is not set
+# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set
+# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set
+# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set
+# CONFIG_DRM_PANEL_INNOLUX_EJ030NA is not set
+# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set
+# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set
+# CONFIG_DRM_PANEL_JDI_R63452 is not set
+# CONFIG_DRM_PANEL_KHADAS_TS050 is not set
+# CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set
+# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set
+# CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829 is not set
+# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set
+# CONFIG_DRM_PANEL_LG_LB035Q02 is not set
+# CONFIG_DRM_PANEL_LG_LG4573 is not set
+# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set
+# CONFIG_DRM_PANEL_NEWVISION_NV3052C is not set
+# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set
+# CONFIG_DRM_PANEL_NOVATEK_NT35560 is not set
+# CONFIG_DRM_PANEL_NOVATEK_NT35950 is not set
+# CONFIG_DRM_PANEL_NOVATEK_NT36672A is not set
+# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set
+# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set
+# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set
+# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set
+# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set
+# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set
+# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set
+# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set
+# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set
+# CONFIG_DRM_PANEL_RONBO_RB070D30 is not set
+# CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 is not set
+# CONFIG_DRM_PANEL_SAMSUNG_DB7430 is not set
+# CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 is not set
+# CONFIG_DRM_PANEL_SAMSUNG_S6D27A1 is not set
+# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set
+# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set
+# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set
+# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set
+# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set
+# CONFIG_DRM_PANEL_SAMSUNG_SOFEF00 is not set
+# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set
+# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set
+# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set
+# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set
+# CONFIG_DRM_PANEL_SHARP_LS060T1SX01 is not set
+# CONFIG_DRM_PANEL_SITRONIX_ST7701 is not set
+# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set
+# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set
+# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set
+# CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521 is not set
+# CONFIG_DRM_PANEL_TDO_TL070WSH30 is not set
+# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set
+# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set
+# CONFIG_DRM_PANEL_TPO_TPG110 is not set
+# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set
+# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set
+# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set
+# CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set
+# end of Display Panels
+
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_PANEL_BRIDGE=y
+
+#
+# Display Interface Bridges
+#
+# CONFIG_DRM_CDNS_DSI is not set
+# CONFIG_DRM_CHIPONE_ICN6211 is not set
+# CONFIG_DRM_CHRONTEL_CH7033 is not set
+# CONFIG_DRM_DISPLAY_CONNECTOR is not set
+# CONFIG_DRM_ITE_IT6505 is not set
+# CONFIG_DRM_LONTIUM_LT8912B is not set
+# CONFIG_DRM_LONTIUM_LT9211 is not set
+# CONFIG_DRM_LONTIUM_LT9611 is not set
+# CONFIG_DRM_LONTIUM_LT9611UXC is not set
+# CONFIG_DRM_ITE_IT66121 is not set
+# CONFIG_DRM_LVDS_CODEC is not set
+# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set
+# CONFIG_DRM_NWL_MIPI_DSI is not set
+# CONFIG_DRM_NXP_PTN3460 is not set
+# CONFIG_DRM_PARADE_PS8622 is not set
+# CONFIG_DRM_PARADE_PS8640 is not set
+# CONFIG_DRM_SIL_SII8620 is not set
+CONFIG_DRM_SII902X=m
+# CONFIG_DRM_SII9234 is not set
+# CONFIG_DRM_SIMPLE_BRIDGE is not set
+# CONFIG_DRM_THINE_THC63LVD1024 is not set
+# CONFIG_DRM_TOSHIBA_TC358762 is not set
+# CONFIG_DRM_TOSHIBA_TC358764 is not set
+# CONFIG_DRM_TOSHIBA_TC358767 is not set
+# CONFIG_DRM_TOSHIBA_TC358768 is not set
+# CONFIG_DRM_TOSHIBA_TC358775 is not set
+# CONFIG_DRM_TI_DLPC3433 is not set
+# CONFIG_DRM_TI_TFP410 is not set
+# CONFIG_DRM_TI_SN65DSI83 is not set
+# CONFIG_DRM_TI_SN65DSI86 is not set
+# CONFIG_DRM_TI_TPD12S015 is not set
+# CONFIG_DRM_ANALOGIX_ANX6345 is not set
+# CONFIG_DRM_ANALOGIX_ANX78XX is not set
+CONFIG_DRM_ANALOGIX_DP=m
+# CONFIG_DRM_ANALOGIX_ANX7625 is not set
+CONFIG_DRM_I2C_ADV7511=m
+CONFIG_DRM_I2C_ADV7511_CEC=y
+# CONFIG_DRM_CDNS_MHDP8546 is not set
+CONFIG_DRM_DW_HDMI=m
+# CONFIG_DRM_DW_HDMI_CEC is not set
+CONFIG_DRM_DW_MIPI_DSI=m
+# end of Display Interface Bridges
+
+CONFIG_DRM_ETNAVIV=m
+CONFIG_DRM_ETNAVIV_THERMAL=y
+# CONFIG_DRM_HISI_HIBMC is not set
+# CONFIG_DRM_HISI_KIRIN is not set
+# CONFIG_DRM_LOGICVC is not set
+# CONFIG_DRM_MXSFB is not set
+# CONFIG_DRM_IMX_LCDIF is not set
+# CONFIG_DRM_ARCPGU is not set
+# CONFIG_DRM_BOCHS is not set
+# CONFIG_DRM_CIRRUS_QEMU is not set
+# CONFIG_DRM_GM12U320 is not set
+# CONFIG_DRM_PANEL_MIPI_DBI is not set
+# CONFIG_DRM_SIMPLEDRM is not set
+# CONFIG_TINYDRM_HX8357D is not set
+# CONFIG_TINYDRM_ILI9163 is not set
+# CONFIG_TINYDRM_ILI9225 is not set
+# CONFIG_TINYDRM_ILI9341 is not set
+# CONFIG_TINYDRM_ILI9486 is not set
+# CONFIG_TINYDRM_MI0283QT is not set
+# CONFIG_TINYDRM_REPAPER is not set
+# CONFIG_TINYDRM_ST7586 is not set
+# CONFIG_TINYDRM_ST7735R is not set
+# CONFIG_DRM_PL111 is not set
+# CONFIG_DRM_XEN_FRONTEND is not set
+CONFIG_DRM_LIMA=m
+CONFIG_DRM_PANFROST=m
+# CONFIG_DRM_TIDSS is not set
+# CONFIG_DRM_GUD is not set
+# CONFIG_DRM_SSD130X is not set
+# CONFIG_DRM_LEGACY is not set
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=m
+CONFIG_DRM_NOMODESET=y
+
+#
+# Frame buffer Devices
+#
+CONFIG_FB_CMDLINE=y
+# CONFIG_FB is not set
+# end of Frame buffer Devices
+
+#
+# Backlight & LCD device support
+#
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_KTD253 is not set
+CONFIG_BACKLIGHT_PWM=m
+# CONFIG_BACKLIGHT_QCOM_WLED is not set
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630A is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
+CONFIG_BACKLIGHT_LP855X=m
+# CONFIG_BACKLIGHT_GPIO is not set
+# CONFIG_BACKLIGHT_LV5207LP is not set
+# CONFIG_BACKLIGHT_BD6107 is not set
+# CONFIG_BACKLIGHT_ARCXCNN is not set
+# CONFIG_BACKLIGHT_LED is not set
+# end of Backlight & LCD device support
+
+CONFIG_VIDEOMODE_HELPERS=y
+CONFIG_HDMI=y
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_DUMMY_CONSOLE_COLUMNS=80
+CONFIG_DUMMY_CONSOLE_ROWS=25
+# end of Console display driver support
+# end of Graphics support
+
+# CONFIG_SOUND is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HID_BATTERY_STRENGTH is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+# CONFIG_HID_ACCUTOUCH is not set
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=y
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_ASUS is not set
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=y
+# CONFIG_HID_BETOP_FF is not set
+# CONFIG_HID_BIGBEN_FF is not set
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+# CONFIG_HID_CORSAIR is not set
+# CONFIG_HID_COUGAR is not set
+# CONFIG_HID_MACALLY is not set
+# CONFIG_HID_CMEDIA is not set
+# CONFIG_HID_CREATIVE_SB0540 is not set
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELAN is not set
+# CONFIG_HID_ELECOM is not set
+# CONFIG_HID_ELO is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_GEMBIRD is not set
+# CONFIG_HID_GFRM is not set
+# CONFIG_HID_GLORIOUS is not set
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_VIVALDI is not set
+# CONFIG_HID_GT683R is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_VIEWSONIC is not set
+# CONFIG_HID_XIAOMI is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+CONFIG_HID_ITE=y
+# CONFIG_HID_JABRA is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=y
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LED is not set
+# CONFIG_HID_LENOVO is not set
+# CONFIG_HID_LETSKETCH is not set
+CONFIG_HID_LOGITECH=y
+# CONFIG_HID_LOGITECH_HIDPP is not set
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+# CONFIG_HID_MALTRON is not set
+# CONFIG_HID_MAYFLASH is not set
+# CONFIG_HID_MEGAWORLD_FF is not set
+CONFIG_HID_REDRAGON=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NINTENDO is not set
+# CONFIG_HID_NTI is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PENMOUNT is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PLANTRONICS is not set
+# CONFIG_HID_RAZER is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_RETRODE is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SEMITEK is not set
+# CONFIG_HID_SIGMAMICRO is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEAM is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_RMI is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_TOPRE is not set
+# CONFIG_HID_THINGM is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_UDRAW_PS3 is not set
+# CONFIG_HID_U2FZERO is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_WIIMOTE is not set
+# CONFIG_HID_XINMO is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+# CONFIG_HID_ALPS is not set
+# CONFIG_HID_MCP2221 is not set
+# end of Special HID drivers
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+# end of USB HID support
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID_OF is not set
+# CONFIG_I2C_HID_OF_ELAN is not set
+# CONFIG_I2C_HID_OF_GOODIX is not set
+# end of I2C HID support
+# end of HID support
+
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+# CONFIG_USB_LED_TRIG is not set
+CONFIG_USB_ULPI_BUS=y
+# CONFIG_USB_CONN_GPIO is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+CONFIG_USB_PCI=y
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEFAULT_PERSIST=y
+# CONFIG_USB_FEW_INIT_RETRIES is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_PRODUCTLIST is not set
+# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set
+# CONFIG_USB_OTG_FSM is not set
+# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set
+CONFIG_USB_AUTOSUSPEND_DELAY=2
+# CONFIG_USB_MON is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_XHCI_HCD=y
+# CONFIG_USB_XHCI_DBGCAP is not set
+CONFIG_USB_XHCI_PCI=y
+# CONFIG_USB_XHCI_PCI_RENESAS is not set
+CONFIG_USB_XHCI_PLATFORM=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_PCI=y
+# CONFIG_USB_EHCI_FSL is not set
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_FOTG210_HCD is not set
+# CONFIG_USB_MAX3421_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PCI=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HCD_TEST_MODE is not set
+# CONFIG_USB_XEN_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+# CONFIG_USB_UAS is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USBIP_CORE is not set
+# CONFIG_USB_CDNS_SUPPORT is not set
+CONFIG_USB_MUSB_HDRC=y
+# CONFIG_USB_MUSB_HOST is not set
+# CONFIG_USB_MUSB_GADGET is not set
+CONFIG_USB_MUSB_DUAL_ROLE=y
+
+#
+# Platform Glue Layer
+#
+
+#
+# MUSB DMA mode
+#
+# CONFIG_MUSB_PIO_ONLY is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_DWC2 is not set
+# CONFIG_USB_CHIPIDEA is not set
+# CONFIG_USB_ISP1760 is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_APPLE_MFI_FASTCHARGE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_EZUSB_FX2 is not set
+# CONFIG_USB_HUB_USB251XB is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+# CONFIG_USB_HSIC_USB4604 is not set
+# CONFIG_USB_LINK_LAYER_TEST is not set
+# CONFIG_USB_CHAOSKEY is not set
+# CONFIG_USB_ONBOARD_HUB is not set
+
+#
+# USB Physical Layer drivers
+#
+CONFIG_USB_PHY=y
+CONFIG_NOP_USB_XCEIV=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+CONFIG_USB_ULPI=y
+CONFIG_USB_ULPI_VIEWPORT=y
+# end of USB Physical Layer drivers
+
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+
+#
+# USB Peripheral Controller
+#
+# CONFIG_USB_FOTG210_UDC is not set
+# CONFIG_USB_GR_UDC is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_PXA27X is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_MV_U3D is not set
+CONFIG_USB_SNP_CORE=y
+CONFIG_USB_SNP_UDC_PLAT=y
+# CONFIG_USB_M66592 is not set
+CONFIG_USB_BDC_UDC=y
+# CONFIG_USB_AMD5536UDC is not set
+# CONFIG_USB_NET2272 is not set
+# CONFIG_USB_NET2280 is not set
+# CONFIG_USB_GOKU is not set
+# CONFIG_USB_EG20T is not set
+# CONFIG_USB_GADGET_XILINX is not set
+# CONFIG_USB_MAX3420_UDC is not set
+# CONFIG_USB_DUMMY_HCD is not set
+# end of USB Peripheral Controller
+
+# CONFIG_USB_CONFIGFS is not set
+
+#
+# USB Gadget precomposed configurations
+#
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_ACM_MS is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+# CONFIG_USB_G_WEBCAM is not set
+# CONFIG_USB_RAW_GADGET is not set
+# end of USB Gadget precomposed configurations
+
+CONFIG_TYPEC=m
+# CONFIG_TYPEC_TCPM is not set
+# CONFIG_TYPEC_UCSI is not set
+# CONFIG_TYPEC_TPS6598X is not set
+# CONFIG_TYPEC_ANX7411 is not set
+# CONFIG_TYPEC_RT1719 is not set
+# CONFIG_TYPEC_HD3SS3220 is not set
+# CONFIG_TYPEC_STUSB160X is not set
+# CONFIG_TYPEC_WUSB3801 is not set
+
+#
+# USB Type-C Multiplexer/DeMultiplexer Switch support
+#
+# CONFIG_TYPEC_MUX_FSA4480 is not set
+# CONFIG_TYPEC_MUX_PI3USB30532 is not set
+# end of USB Type-C Multiplexer/DeMultiplexer Switch support
+
+#
+# USB Type-C Alternate Mode drivers
+#
+# CONFIG_TYPEC_DP_ALTMODE is not set
+# end of USB Type-C Alternate Mode drivers
+
+CONFIG_USB_ROLE_SWITCH=y
+CONFIG_MMC=y
+CONFIG_PWRSEQ_EMMC=y
+CONFIG_PWRSEQ_SIMPLE=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_STM32_SDMMC=y
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+# CONFIG_MMC_SDHCI_OF_ASPEED is not set
+# CONFIG_MMC_SDHCI_OF_AT91 is not set
+# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set
+CONFIG_MMC_SDHCI_CADENCE=y
+CONFIG_MMC_SDHCI_F_SDH30=y
+# CONFIG_MMC_SDHCI_MILBEAUT is not set
+# CONFIG_MMC_TIFM_SD is not set
+CONFIG_MMC_SPI=y
+# CONFIG_MMC_CB710 is not set
+# CONFIG_MMC_VIA_SDMMC is not set
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_PLTFM=y
+# CONFIG_MMC_DW_BLUEFIELD is not set
+CONFIG_MMC_DW_EXYNOS=y
+CONFIG_MMC_DW_HI3798CV200=y
+CONFIG_MMC_DW_K3=y
+# CONFIG_MMC_DW_PCI is not set
+CONFIG_MMC_DW_ROCKCHIP=y
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MMC_USDHI6ROL0 is not set
+CONFIG_MMC_CQHCI=y
+# CONFIG_MMC_HSQ is not set
+# CONFIG_MMC_TOSHIBA_PCI is not set
+# CONFIG_MMC_MTK is not set
+CONFIG_MMC_SDHCI_XENON=y
+# CONFIG_MMC_SDHCI_OMAP is not set
+# CONFIG_MMC_SDHCI_AM654 is not set
+CONFIG_SCSI_UFSHCD=y
+# CONFIG_SCSI_UFS_BSG is not set
+# CONFIG_SCSI_UFS_HPB is not set
+# CONFIG_SCSI_UFS_HWMON is not set
+# CONFIG_SCSI_UFSHCD_PCI is not set
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+# CONFIG_SCSI_UFS_CDNS_PLATFORM is not set
+# CONFIG_SCSI_UFS_DWC_TC_PLATFORM is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+# CONFIG_LEDS_CLASS_FLASH is not set
+# CONFIG_LEDS_CLASS_MULTICOLOR is not set
+# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_AN30259A is not set
+# CONFIG_LEDS_AW2013 is not set
+# CONFIG_LEDS_BCM6328 is not set
+# CONFIG_LEDS_BCM6358 is not set
+# CONFIG_LEDS_CR0014114 is not set
+# CONFIG_LEDS_EL15203000 is not set
+# CONFIG_LEDS_LM3530 is not set
+# CONFIG_LEDS_LM3532 is not set
+# CONFIG_LEDS_LM3642 is not set
+# CONFIG_LEDS_LM3692X is not set
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_LP3952 is not set
+# CONFIG_LEDS_LP50XX is not set
+# CONFIG_LEDS_LP55XX_COMMON is not set
+# CONFIG_LEDS_LP8860 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_PCA963X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+CONFIG_LEDS_PWM=y
+# CONFIG_LEDS_REGULATOR is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+# CONFIG_LEDS_TCA6507 is not set
+# CONFIG_LEDS_TLC591XX is not set
+# CONFIG_LEDS_LM355x is not set
+# CONFIG_LEDS_IS31FL319X is not set
+# CONFIG_LEDS_IS31FL32XX is not set
+
+#
+# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)
+#
+# CONFIG_LEDS_BLINKM is not set
+CONFIG_LEDS_SYSCON=y
+# CONFIG_LEDS_MLXREG is not set
+# CONFIG_LEDS_USER is not set
+# CONFIG_LEDS_SPI_BYTE is not set
+# CONFIG_LEDS_TI_LMU_COMMON is not set
+
+#
+# Flash and Torch LED drivers
+#
+
+#
+# RGB LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_ONESHOT is not set
+CONFIG_LEDS_TRIGGER_DISK=y
+CONFIG_LEDS_TRIGGER_MTD=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_ACTIVITY=y
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_LEDS_TRIGGER_TRANSIENT is not set
+# CONFIG_LEDS_TRIGGER_CAMERA is not set
+CONFIG_LEDS_TRIGGER_PANIC=y
+CONFIG_LEDS_TRIGGER_NETDEV=y
+CONFIG_LEDS_TRIGGER_PATTERN=y
+# CONFIG_LEDS_TRIGGER_AUDIO is not set
+CONFIG_LEDS_TRIGGER_TTY=y
+
+#
+# Simple LED drivers
+#
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EDAC=y
+CONFIG_EDAC_LEGACY_SYSFS=y
+# CONFIG_EDAC_DEBUG is not set
+# CONFIG_EDAC_THUNDERX is not set
+# CONFIG_EDAC_XGENE is not set
+# CONFIG_EDAC_DMC520 is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+CONFIG_RTC_SYSTOHC=y
+CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+CONFIG_RTC_NVMEM=y
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_ABB5ZES3 is not set
+# CONFIG_RTC_DRV_ABEOZ9 is not set
+# CONFIG_RTC_DRV_ABX80X is not set
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_HYM8563 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+CONFIG_RTC_DRV_MAX77686=y
+# CONFIG_RTC_DRV_NCT3018Y is not set
+CONFIG_RTC_DRV_RK808=m
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_ISL12022 is not set
+# CONFIG_RTC_DRV_ISL12026 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8523 is not set
+# CONFIG_RTC_DRV_PCF85063 is not set
+# CONFIG_RTC_DRV_PCF85363 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8010 is not set
+CONFIG_RTC_DRV_RX8581=m
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3028 is not set
+# CONFIG_RTC_DRV_RV3032 is not set
+# CONFIG_RTC_DRV_RV8803 is not set
+CONFIG_RTC_DRV_S5M=y
+# CONFIG_RTC_DRV_SD3078 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1302 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1343 is not set
+# CONFIG_RTC_DRV_DS1347 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6916 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RX4581 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_MCP795 is not set
+CONFIG_RTC_I2C_AND_SPI=y
+
+#
+# SPI and I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS3232=y
+CONFIG_RTC_DRV_DS3232_HWMON=y
+# CONFIG_RTC_DRV_PCF2127 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+# CONFIG_RTC_DRV_RX6110 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1685_FAMILY is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_DS2404 is not set
+CONFIG_RTC_DRV_EFI=y
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_OPTEE is not set
+# CONFIG_RTC_DRV_ZYNQMP is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+CONFIG_RTC_DRV_PL031=y
+# CONFIG_RTC_DRV_CADENCE is not set
+# CONFIG_RTC_DRV_FTRTC010 is not set
+# CONFIG_RTC_DRV_R7301 is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_GOLDFISH is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DMA_OF=y
+# CONFIG_ALTERA_MSGDMA is not set
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_DW_AXI_DMAC is not set
+CONFIG_FSL_EDMA=y
+# CONFIG_FSL_QDMA is not set
+# CONFIG_HISI_DMA is not set
+# CONFIG_INTEL_IDMA64 is not set
+CONFIG_MV_XOR_V2=y
+CONFIG_PL330_DMA=y
+# CONFIG_PLX_DMA is not set
+# CONFIG_XILINX_DMA is not set
+# CONFIG_XILINX_ZYNQMP_DMA is not set
+# CONFIG_XILINX_ZYNQMP_DPDMA is not set
+CONFIG_QCOM_HIDMA_MGMT=y
+CONFIG_QCOM_HIDMA=y
+# CONFIG_DW_DMAC is not set
+# CONFIG_DW_DMAC_PCI is not set
+# CONFIG_DW_EDMA is not set
+# CONFIG_DW_EDMA_PCIE is not set
+# CONFIG_SF_PDMA is not set
+
+#
+# DMA Clients
+#
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+CONFIG_DMA_ENGINE_RAID=y
+
+#
+# DMABUF options
+#
+CONFIG_SYNC_FILE=y
+# CONFIG_SW_SYNC is not set
+# CONFIG_UDMABUF is not set
+# CONFIG_DMABUF_MOVE_NOTIFY is not set
+# CONFIG_DMABUF_DEBUG is not set
+# CONFIG_DMABUF_SELFTESTS is not set
+# CONFIG_DMABUF_HEAPS is not set
+# CONFIG_DMABUF_SYSFS_STATS is not set
+# end of DMABUF options
+
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VFIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+CONFIG_VIRTIO_ANCHOR=y
+CONFIG_VIRTIO=y
+# CONFIG_VIRTIO_MENU is not set
+# CONFIG_VDPA is not set
+# CONFIG_VHOST_MENU is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# end of Microsoft Hyper-V guest support
+
+#
+# Xen driver support
+#
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_SCRUB_PAGES_DEFAULT=y
+CONFIG_XEN_DEV_EVTCHN=y
+CONFIG_XEN_BACKEND=y
+CONFIG_XENFS=y
+CONFIG_XEN_COMPAT_XENFS=y
+CONFIG_XEN_SYS_HYPERVISOR=y
+CONFIG_XEN_GNTDEV=y
+CONFIG_XEN_GRANT_DEV_ALLOC=y
+# CONFIG_XEN_GRANT_DMA_ALLOC is not set
+CONFIG_SWIOTLB_XEN=y
+CONFIG_XEN_PCI_STUB=y
+CONFIG_XEN_PCIDEV_STUB=m
+# CONFIG_XEN_PVCALLS_FRONTEND is not set
+# CONFIG_XEN_PVCALLS_BACKEND is not set
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_EFI=y
+CONFIG_XEN_AUTO_XLATE=y
+# CONFIG_XEN_VIRTIO is not set
+# end of Xen driver support
+
+# CONFIG_GREYBUS is not set
+# CONFIG_COMEDI is not set
+CONFIG_STAGING=y
+# CONFIG_RTS5208 is not set
+
+#
+# IIO staging drivers
+#
+
+#
+# Accelerometers
+#
+# CONFIG_ADIS16203 is not set
+# CONFIG_ADIS16240 is not set
+# end of Accelerometers
+
+#
+# Analog to digital converters
+#
+# CONFIG_AD7816 is not set
+# end of Analog to digital converters
+
+#
+# Analog digital bi-direction converters
+#
+# CONFIG_ADT7316 is not set
+# end of Analog digital bi-direction converters
+
+#
+# Capacitance to digital converters
+#
+# CONFIG_AD7746 is not set
+# end of Capacitance to digital converters
+
+#
+# Direct Digital Synthesis
+#
+# CONFIG_AD9832 is not set
+# CONFIG_AD9834 is not set
+# end of Direct Digital Synthesis
+
+#
+# Network Analyzer, Impedance Converters
+#
+# CONFIG_AD5933 is not set
+# end of Network Analyzer, Impedance Converters
+
+#
+# Active energy metering IC
+#
+# CONFIG_ADE7854 is not set
+# end of Active energy metering IC
+
+#
+# Resolver to digital converters
+#
+# CONFIG_AD2S1210 is not set
+# end of Resolver to digital converters
+# end of IIO staging drivers
+
+CONFIG_STAGING_MEDIA=y
+# CONFIG_DVB_AV7110 is not set
+CONFIG_VIDEO_HANTRO=m
+CONFIG_VIDEO_HANTRO_ROCKCHIP=y
+# CONFIG_VIDEO_MAX96712 is not set
+CONFIG_VIDEO_ROCKCHIP_VDEC=m
+# CONFIG_VIDEO_STKWEBCAM is not set
+# CONFIG_VIDEO_ZORAN is not set
+CONFIG_STAGING_BOARD=y
+# CONFIG_LTE_GDM724X is not set
+# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set
+# CONFIG_KS7010 is not set
+# CONFIG_PI433 is not set
+# CONFIG_XIL_AXIS_FIFO is not set
+# CONFIG_FIELDBUS_DEV is not set
+# CONFIG_QLGE is not set
+# CONFIG_VME_BUS is not set
+# CONFIG_GOLDFISH is not set
+# CONFIG_CHROME_PLATFORMS is not set
+# CONFIG_MELLANOX_PLATFORM is not set
+# CONFIG_SURFACE_PLATFORMS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_COMMON_CLK=y
+
+#
+# Clock driver for ARM Reference designs
+#
+# CONFIG_CLK_ICST is not set
+CONFIG_CLK_SP810=y
+CONFIG_CLK_VEXPRESS_OSC=y
+# end of Clock driver for ARM Reference designs
+
+# CONFIG_LMK04832 is not set
+# CONFIG_COMMON_CLK_MAX77686 is not set
+# CONFIG_COMMON_CLK_MAX9485 is not set
+CONFIG_COMMON_CLK_RK808=y
+CONFIG_COMMON_CLK_SCPI=y
+# CONFIG_COMMON_CLK_SI5341 is not set
+# CONFIG_COMMON_CLK_SI5351 is not set
+# CONFIG_COMMON_CLK_SI514 is not set
+# CONFIG_COMMON_CLK_SI544 is not set
+# CONFIG_COMMON_CLK_SI570 is not set
+# CONFIG_COMMON_CLK_CDCE706 is not set
+# CONFIG_COMMON_CLK_CDCE925 is not set
+CONFIG_COMMON_CLK_CS2000_CP=y
+CONFIG_COMMON_CLK_S2MPS11=y
+# CONFIG_COMMON_CLK_AXI_CLKGEN is not set
+CONFIG_COMMON_CLK_XGENE=y
+CONFIG_COMMON_CLK_PWM=y
+# CONFIG_COMMON_CLK_RS9_PCIE is not set
+# CONFIG_COMMON_CLK_VC5 is not set
+# CONFIG_COMMON_CLK_BD718XX is not set
+# CONFIG_COMMON_CLK_FIXED_MMIO is not set
+CONFIG_COMMON_CLK_ROCKCHIP=y
+CONFIG_CLK_PX30=y
+CONFIG_CLK_RK3308=y
+CONFIG_CLK_RK3328=y
+CONFIG_CLK_RK3368=y
+CONFIG_CLK_RK3399=y
+CONFIG_CLK_RK3568=y
+# CONFIG_XILINX_VCU is not set
+CONFIG_HWSPINLOCK=y
+
+#
+# Clock Source drivers
+#
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_ROCKCHIP_TIMER=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
+CONFIG_FSL_ERRATUM_A008585=y
+CONFIG_HISILICON_ERRATUM_161010101=y
+CONFIG_ARM64_ERRATUM_858921=y
+# CONFIG_MICROCHIP_PIT64B is not set
+# end of Clock Source drivers
+
+CONFIG_MAILBOX=y
+CONFIG_ARM_MHU=y
+# CONFIG_ARM_MHU_V2 is not set
+CONFIG_PLATFORM_MHU=y
+# CONFIG_PL320_MBOX is not set
+# CONFIG_ROCKCHIP_MBOX is not set
+# CONFIG_ALTERA_MBOX is not set
+# CONFIG_MAILBOX_TEST is not set
+CONFIG_IOMMU_IOVA=y
+CONFIG_IOMMU_API=y
+CONFIG_IOMMU_SUPPORT=y
+
+#
+# Generic IOMMU Pagetable Support
+#
+CONFIG_IOMMU_IO_PGTABLE=y
+CONFIG_IOMMU_IO_PGTABLE_LPAE=y
+# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set
+# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
+# end of Generic IOMMU Pagetable Support
+
+# CONFIG_IOMMU_DEBUGFS is not set
+CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
+# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
+# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
+CONFIG_OF_IOMMU=y
+CONFIG_IOMMU_DMA=y
+CONFIG_ROCKCHIP_IOMMU=y
+CONFIG_ARM_SMMU=y
+# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set
+CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y
+CONFIG_ARM_SMMU_V3=y
+# CONFIG_ARM_SMMU_V3_SVA is not set
+# CONFIG_VIRTIO_IOMMU is not set
+
+#
+# Remoteproc drivers
+#
+CONFIG_REMOTEPROC=y
+# CONFIG_REMOTEPROC_CDEV is not set
+# end of Remoteproc drivers
+
+#
+# Rpmsg drivers
+#
+CONFIG_RPMSG=y
+# CONFIG_RPMSG_CHAR is not set
+# CONFIG_RPMSG_CTRL is not set
+# CONFIG_RPMSG_NS is not set
+CONFIG_RPMSG_QCOM_GLINK=y
+CONFIG_RPMSG_QCOM_GLINK_RPM=y
+# CONFIG_RPMSG_VIRTIO is not set
+# end of Rpmsg drivers
+
+# CONFIG_SOUNDWIRE is not set
+
+#
+# SOC (System On Chip) specific Drivers
+#
+
+#
+# Amlogic SoC drivers
+#
+# end of Amlogic SoC drivers
+
+#
+# Broadcom SoC drivers
+#
+CONFIG_SOC_BRCMSTB=y
+# end of Broadcom SoC drivers
+
+#
+# NXP/Freescale QorIQ SoC drivers
+#
+# CONFIG_QUICC_ENGINE is not set
+# CONFIG_FSL_RCPM is not set
+# end of NXP/Freescale QorIQ SoC drivers
+
+#
+# fujitsu SoC drivers
+#
+# end of fujitsu SoC drivers
+
+#
+# i.MX SoC drivers
+#
+# end of i.MX SoC drivers
+
+#
+# Enable LiteX SoC Builder specific drivers
+#
+# CONFIG_LITEX_SOC_CONTROLLER is not set
+# end of Enable LiteX SoC Builder specific drivers
+
+#
+# Qualcomm SoC drivers
+#
+# end of Qualcomm SoC drivers
+
+CONFIG_ROCKCHIP_GRF=y
+CONFIG_ROCKCHIP_IODOMAIN=y
+CONFIG_ROCKCHIP_PM_DOMAINS=y
+CONFIG_SOC_TI=y
+
+#
+# Xilinx SoC drivers
+#
+# end of Xilinx SoC drivers
+# end of SOC (System On Chip) specific Drivers
+
+CONFIG_PM_DEVFREQ=y
+
+#
+# DEVFREQ Governors
+#
+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
+# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
+# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
+# CONFIG_DEVFREQ_GOV_USERSPACE is not set
+# CONFIG_DEVFREQ_GOV_PASSIVE is not set
+
+#
+# DEVFREQ Drivers
+#
+# CONFIG_ARM_RK3399_DMC_DEVFREQ is not set
+# CONFIG_PM_DEVFREQ_EVENT is not set
+CONFIG_EXTCON=y
+
+#
+# Extcon Device Drivers
+#
+# CONFIG_EXTCON_ADC_JACK is not set
+# CONFIG_EXTCON_FSA9480 is not set
+# CONFIG_EXTCON_GPIO is not set
+# CONFIG_EXTCON_MAX3355 is not set
+# CONFIG_EXTCON_PTN5150 is not set
+# CONFIG_EXTCON_RT8973A is not set
+# CONFIG_EXTCON_SM5502 is not set
+CONFIG_EXTCON_USB_GPIO=y
+# CONFIG_EXTCON_USBC_TUSB320 is not set
+CONFIG_MEMORY=y
+# CONFIG_ARM_PL172_MPMC is not set
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+# CONFIG_IIO_BUFFER_CB is not set
+# CONFIG_IIO_BUFFER_DMA is not set
+# CONFIG_IIO_BUFFER_DMAENGINE is not set
+# CONFIG_IIO_BUFFER_HW_CONSUMER is not set
+CONFIG_IIO_KFIFO_BUF=m
+CONFIG_IIO_TRIGGERED_BUFFER=m
+# CONFIG_IIO_CONFIGFS is not set
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
+# CONFIG_IIO_SW_DEVICE is not set
+# CONFIG_IIO_SW_TRIGGER is not set
+# CONFIG_IIO_TRIGGERED_EVENT is not set
+
+#
+# Accelerometers
+#
+# CONFIG_ADIS16201 is not set
+# CONFIG_ADIS16209 is not set
+# CONFIG_ADXL313_I2C is not set
+# CONFIG_ADXL313_SPI is not set
+# CONFIG_ADXL345_I2C is not set
+# CONFIG_ADXL345_SPI is not set
+# CONFIG_ADXL355_I2C is not set
+# CONFIG_ADXL355_SPI is not set
+# CONFIG_ADXL367_SPI is not set
+# CONFIG_ADXL367_I2C is not set
+# CONFIG_ADXL372_SPI is not set
+# CONFIG_ADXL372_I2C is not set
+# CONFIG_BMA180 is not set
+# CONFIG_BMA220 is not set
+# CONFIG_BMA400 is not set
+# CONFIG_BMC150_ACCEL is not set
+# CONFIG_BMI088_ACCEL is not set
+# CONFIG_DA280 is not set
+# CONFIG_DA311 is not set
+# CONFIG_DMARD06 is not set
+# CONFIG_DMARD09 is not set
+# CONFIG_DMARD10 is not set
+# CONFIG_FXLS8962AF_I2C is not set
+# CONFIG_FXLS8962AF_SPI is not set
+# CONFIG_IIO_ST_ACCEL_3AXIS is not set
+# CONFIG_KXSD9 is not set
+# CONFIG_KXCJK1013 is not set
+# CONFIG_MC3230 is not set
+# CONFIG_MMA7455_I2C is not set
+# CONFIG_MMA7455_SPI is not set
+# CONFIG_MMA7660 is not set
+# CONFIG_MMA8452 is not set
+# CONFIG_MMA9551 is not set
+# CONFIG_MMA9553 is not set
+# CONFIG_MXC4005 is not set
+# CONFIG_MXC6255 is not set
+# CONFIG_SCA3000 is not set
+# CONFIG_SCA3300 is not set
+# CONFIG_STK8312 is not set
+# CONFIG_STK8BA50 is not set
+# end of Accelerometers
+
+#
+# Analog to digital converters
+#
+# CONFIG_AD7091R5 is not set
+# CONFIG_AD7124 is not set
+# CONFIG_AD7192 is not set
+# CONFIG_AD7266 is not set
+# CONFIG_AD7280 is not set
+# CONFIG_AD7291 is not set
+# CONFIG_AD7292 is not set
+# CONFIG_AD7298 is not set
+# CONFIG_AD7476 is not set
+# CONFIG_AD7606_IFACE_PARALLEL is not set
+# CONFIG_AD7606_IFACE_SPI is not set
+# CONFIG_AD7766 is not set
+# CONFIG_AD7768_1 is not set
+# CONFIG_AD7780 is not set
+# CONFIG_AD7791 is not set
+# CONFIG_AD7793 is not set
+# CONFIG_AD7887 is not set
+# CONFIG_AD7923 is not set
+# CONFIG_AD7949 is not set
+# CONFIG_AD799X is not set
+# CONFIG_ADI_AXI_ADC is not set
+# CONFIG_AXP20X_ADC is not set
+# CONFIG_AXP288_ADC is not set
+# CONFIG_CC10001_ADC is not set
+# CONFIG_ENVELOPE_DETECTOR is not set
+# CONFIG_HI8435 is not set
+# CONFIG_HX711 is not set
+# CONFIG_INA2XX_ADC is not set
+# CONFIG_LTC2471 is not set
+# CONFIG_LTC2485 is not set
+# CONFIG_LTC2496 is not set
+# CONFIG_LTC2497 is not set
+# CONFIG_MAX1027 is not set
+# CONFIG_MAX11100 is not set
+# CONFIG_MAX1118 is not set
+# CONFIG_MAX1241 is not set
+# CONFIG_MAX1363 is not set
+# CONFIG_MAX9611 is not set
+# CONFIG_MCP320X is not set
+# CONFIG_MCP3422 is not set
+# CONFIG_MCP3911 is not set
+# CONFIG_NAU7802 is not set
+# CONFIG_QCOM_SPMI_IADC is not set
+# CONFIG_QCOM_SPMI_VADC is not set
+# CONFIG_QCOM_SPMI_ADC5 is not set
+CONFIG_ROCKCHIP_SARADC=m
+# CONFIG_SD_ADC_MODULATOR is not set
+# CONFIG_TI_ADC081C is not set
+# CONFIG_TI_ADC0832 is not set
+# CONFIG_TI_ADC084S021 is not set
+# CONFIG_TI_ADC12138 is not set
+# CONFIG_TI_ADC108S102 is not set
+# CONFIG_TI_ADC128S052 is not set
+# CONFIG_TI_ADC161S626 is not set
+# CONFIG_TI_ADS1015 is not set
+# CONFIG_TI_ADS7950 is not set
+# CONFIG_TI_ADS8344 is not set
+# CONFIG_TI_ADS8688 is not set
+# CONFIG_TI_ADS124S08 is not set
+# CONFIG_TI_ADS131E08 is not set
+# CONFIG_TI_TLC4541 is not set
+# CONFIG_TI_TSC2046 is not set
+# CONFIG_VF610_ADC is not set
+# CONFIG_XILINX_XADC is not set
+# end of Analog to digital converters
+
+#
+# Analog to digital and digital to analog converters
+#
+# CONFIG_AD74413R is not set
+# end of Analog to digital and digital to analog converters
+
+#
+# Analog Front Ends
+#
+# CONFIG_IIO_RESCALE is not set
+# end of Analog Front Ends
+
+#
+# Amplifiers
+#
+# CONFIG_AD8366 is not set
+# CONFIG_ADA4250 is not set
+# CONFIG_HMC425 is not set
+# end of Amplifiers
+
+#
+# Capacitance to digital converters
+#
+# CONFIG_AD7150 is not set
+# end of Capacitance to digital converters
+
+#
+# Chemical Sensors
+#
+# CONFIG_ATLAS_PH_SENSOR is not set
+# CONFIG_ATLAS_EZO_SENSOR is not set
+# CONFIG_BME680 is not set
+# CONFIG_CCS811 is not set
+# CONFIG_IAQCORE is not set
+# CONFIG_PMS7003 is not set
+# CONFIG_SCD30_CORE is not set
+# CONFIG_SCD4X is not set
+# CONFIG_SENSIRION_SGP30 is not set
+# CONFIG_SENSIRION_SGP40 is not set
+# CONFIG_SPS30_I2C is not set
+# CONFIG_SPS30_SERIAL is not set
+# CONFIG_SENSEAIR_SUNRISE_CO2 is not set
+# CONFIG_VZ89X is not set
+# end of Chemical Sensors
+
+#
+# Hid Sensor IIO Common
+#
+# end of Hid Sensor IIO Common
+
+#
+# IIO SCMI Sensors
+#
+# end of IIO SCMI Sensors
+
+#
+# SSP Sensor Common
+#
+# CONFIG_IIO_SSP_SENSORHUB is not set
+# end of SSP Sensor Common
+
+#
+# Digital to analog converters
+#
+# CONFIG_AD3552R is not set
+# CONFIG_AD5064 is not set
+# CONFIG_AD5360 is not set
+# CONFIG_AD5380 is not set
+# CONFIG_AD5421 is not set
+# CONFIG_AD5446 is not set
+# CONFIG_AD5449 is not set
+# CONFIG_AD5592R is not set
+# CONFIG_AD5593R is not set
+# CONFIG_AD5504 is not set
+# CONFIG_AD5624R_SPI is not set
+# CONFIG_LTC2688 is not set
+# CONFIG_AD5686_SPI is not set
+# CONFIG_AD5696_I2C is not set
+# CONFIG_AD5755 is not set
+# CONFIG_AD5758 is not set
+# CONFIG_AD5761 is not set
+# CONFIG_AD5764 is not set
+# CONFIG_AD5766 is not set
+# CONFIG_AD5770R is not set
+# CONFIG_AD5791 is not set
+# CONFIG_AD7293 is not set
+# CONFIG_AD7303 is not set
+# CONFIG_AD8801 is not set
+# CONFIG_DPOT_DAC is not set
+# CONFIG_DS4424 is not set
+# CONFIG_LTC1660 is not set
+# CONFIG_LTC2632 is not set
+# CONFIG_M62332 is not set
+# CONFIG_MAX517 is not set
+# CONFIG_MAX5821 is not set
+# CONFIG_MCP4725 is not set
+# CONFIG_MCP4922 is not set
+# CONFIG_TI_DAC082S085 is not set
+# CONFIG_TI_DAC5571 is not set
+# CONFIG_TI_DAC7311 is not set
+# CONFIG_TI_DAC7612 is not set
+# CONFIG_VF610_DAC is not set
+# end of Digital to analog converters
+
+#
+# IIO dummy driver
+#
+# end of IIO dummy driver
+
+#
+# Filters
+#
+# CONFIG_ADMV8818 is not set
+# end of Filters
+
+#
+# Frequency Synthesizers DDS/PLL
+#
+
+#
+# Clock Generator/Distribution
+#
+# CONFIG_AD9523 is not set
+# end of Clock Generator/Distribution
+
+#
+# Phase-Locked Loop (PLL) frequency synthesizers
+#
+# CONFIG_ADF4350 is not set
+# CONFIG_ADF4371 is not set
+# CONFIG_ADMV1013 is not set
+# CONFIG_ADMV1014 is not set
+# CONFIG_ADMV4420 is not set
+# CONFIG_ADRF6780 is not set
+# end of Phase-Locked Loop (PLL) frequency synthesizers
+# end of Frequency Synthesizers DDS/PLL
+
+#
+# Digital gyroscope sensors
+#
+# CONFIG_ADIS16080 is not set
+# CONFIG_ADIS16130 is not set
+# CONFIG_ADIS16136 is not set
+# CONFIG_ADIS16260 is not set
+# CONFIG_ADXRS290 is not set
+# CONFIG_ADXRS450 is not set
+# CONFIG_BMG160 is not set
+# CONFIG_FXAS21002C is not set
+# CONFIG_MPU3050_I2C is not set
+# CONFIG_IIO_ST_GYRO_3AXIS is not set
+# CONFIG_ITG3200 is not set
+# end of Digital gyroscope sensors
+
+#
+# Health Sensors
+#
+
+#
+# Heart Rate Monitors
+#
+# CONFIG_AFE4403 is not set
+# CONFIG_AFE4404 is not set
+# CONFIG_MAX30100 is not set
+# CONFIG_MAX30102 is not set
+# end of Heart Rate Monitors
+# end of Health Sensors
+
+#
+# Humidity sensors
+#
+# CONFIG_AM2315 is not set
+# CONFIG_DHT11 is not set
+# CONFIG_HDC100X is not set
+# CONFIG_HDC2010 is not set
+# CONFIG_HTS221 is not set
+# CONFIG_HTU21 is not set
+# CONFIG_SI7005 is not set
+# CONFIG_SI7020 is not set
+# end of Humidity sensors
+
+#
+# Inertial measurement units
+#
+# CONFIG_ADIS16400 is not set
+# CONFIG_ADIS16460 is not set
+# CONFIG_ADIS16475 is not set
+# CONFIG_ADIS16480 is not set
+# CONFIG_BMI160_I2C is not set
+# CONFIG_BMI160_SPI is not set
+# CONFIG_FXOS8700_I2C is not set
+# CONFIG_FXOS8700_SPI is not set
+# CONFIG_KMX61 is not set
+# CONFIG_INV_ICM42600_I2C is not set
+# CONFIG_INV_ICM42600_SPI is not set
+# CONFIG_INV_MPU6050_I2C is not set
+# CONFIG_INV_MPU6050_SPI is not set
+# CONFIG_IIO_ST_LSM6DSX is not set
+# CONFIG_IIO_ST_LSM9DS0 is not set
+# end of Inertial measurement units
+
+#
+# Light sensors
+#
+# CONFIG_ADJD_S311 is not set
+# CONFIG_ADUX1020 is not set
+# CONFIG_AL3010 is not set
+# CONFIG_AL3320A is not set
+# CONFIG_APDS9300 is not set
+# CONFIG_APDS9960 is not set
+# CONFIG_AS73211 is not set
+# CONFIG_BH1750 is not set
+# CONFIG_BH1780 is not set
+# CONFIG_CM32181 is not set
+# CONFIG_CM3232 is not set
+# CONFIG_CM3323 is not set
+# CONFIG_CM3605 is not set
+# CONFIG_CM36651 is not set
+# CONFIG_GP2AP002 is not set
+# CONFIG_GP2AP020A00F is not set
+CONFIG_SENSORS_ISL29018=m
+# CONFIG_SENSORS_ISL29028 is not set
+# CONFIG_ISL29125 is not set
+# CONFIG_JSA1212 is not set
+# CONFIG_RPR0521 is not set
+# CONFIG_LTR501 is not set
+# CONFIG_LV0104CS is not set
+# CONFIG_MAX44000 is not set
+# CONFIG_MAX44009 is not set
+# CONFIG_NOA1305 is not set
+# CONFIG_OPT3001 is not set
+# CONFIG_PA12203001 is not set
+# CONFIG_SI1133 is not set
+# CONFIG_SI1145 is not set
+# CONFIG_STK3310 is not set
+# CONFIG_ST_UVIS25 is not set
+# CONFIG_TCS3414 is not set
+# CONFIG_TCS3472 is not set
+# CONFIG_SENSORS_TSL2563 is not set
+# CONFIG_TSL2583 is not set
+# CONFIG_TSL2591 is not set
+# CONFIG_TSL2772 is not set
+# CONFIG_TSL4531 is not set
+# CONFIG_US5182D is not set
+# CONFIG_VCNL4000 is not set
+# CONFIG_VCNL4035 is not set
+# CONFIG_VEML6030 is not set
+# CONFIG_VEML6070 is not set
+# CONFIG_VL6180 is not set
+# CONFIG_ZOPT2201 is not set
+# end of Light sensors
+
+#
+# Magnetometer sensors
+#
+# CONFIG_AK8974 is not set
+# CONFIG_AK8975 is not set
+# CONFIG_AK09911 is not set
+# CONFIG_BMC150_MAGN_I2C is not set
+# CONFIG_BMC150_MAGN_SPI is not set
+# CONFIG_MAG3110 is not set
+# CONFIG_MMC35240 is not set
+# CONFIG_IIO_ST_MAGN_3AXIS is not set
+# CONFIG_SENSORS_HMC5843_I2C is not set
+# CONFIG_SENSORS_HMC5843_SPI is not set
+# CONFIG_SENSORS_RM3100_I2C is not set
+# CONFIG_SENSORS_RM3100_SPI is not set
+# CONFIG_YAMAHA_YAS530 is not set
+# end of Magnetometer sensors
+
+#
+# Multiplexers
+#
+# CONFIG_IIO_MUX is not set
+# end of Multiplexers
+
+#
+# Inclinometer sensors
+#
+# end of Inclinometer sensors
+
+#
+# Triggers - standalone
+#
+# CONFIG_IIO_INTERRUPT_TRIGGER is not set
+# CONFIG_IIO_SYSFS_TRIGGER is not set
+# end of Triggers - standalone
+
+#
+# Linear and angular position sensors
+#
+# end of Linear and angular position sensors
+
+#
+# Digital potentiometers
+#
+# CONFIG_AD5110 is not set
+# CONFIG_AD5272 is not set
+# CONFIG_DS1803 is not set
+# CONFIG_MAX5432 is not set
+# CONFIG_MAX5481 is not set
+# CONFIG_MAX5487 is not set
+# CONFIG_MCP4018 is not set
+# CONFIG_MCP4131 is not set
+# CONFIG_MCP4531 is not set
+# CONFIG_MCP41010 is not set
+# CONFIG_TPL0102 is not set
+# end of Digital potentiometers
+
+#
+# Digital potentiostats
+#
+# CONFIG_LMP91000 is not set
+# end of Digital potentiostats
+
+#
+# Pressure sensors
+#
+# CONFIG_ABP060MG is not set
+# CONFIG_BMP280 is not set
+# CONFIG_DLHL60D is not set
+# CONFIG_DPS310 is not set
+# CONFIG_HP03 is not set
+# CONFIG_ICP10100 is not set
+# CONFIG_MPL115_I2C is not set
+# CONFIG_MPL115_SPI is not set
+CONFIG_MPL3115=m
+# CONFIG_MS5611 is not set
+# CONFIG_MS5637 is not set
+# CONFIG_IIO_ST_PRESS is not set
+# CONFIG_T5403 is not set
+# CONFIG_HP206C is not set
+# CONFIG_ZPA2326 is not set
+# end of Pressure sensors
+
+#
+# Lightning sensors
+#
+# CONFIG_AS3935 is not set
+# end of Lightning sensors
+
+#
+# Proximity and distance sensors
+#
+# CONFIG_ISL29501 is not set
+# CONFIG_LIDAR_LITE_V2 is not set
+# CONFIG_MB1232 is not set
+# CONFIG_PING is not set
+# CONFIG_RFD77402 is not set
+# CONFIG_SRF04 is not set
+# CONFIG_SX9310 is not set
+# CONFIG_SX9324 is not set
+# CONFIG_SX9360 is not set
+# CONFIG_SX9500 is not set
+# CONFIG_SRF08 is not set
+# CONFIG_VCNL3020 is not set
+# CONFIG_VL53L0X_I2C is not set
+# end of Proximity and distance sensors
+
+#
+# Resolver to digital converters
+#
+# CONFIG_AD2S90 is not set
+# CONFIG_AD2S1200 is not set
+# end of Resolver to digital converters
+
+#
+# Temperature sensors
+#
+# CONFIG_LTC2983 is not set
+# CONFIG_MAXIM_THERMOCOUPLE is not set
+# CONFIG_MLX90614 is not set
+# CONFIG_MLX90632 is not set
+# CONFIG_TMP006 is not set
+# CONFIG_TMP007 is not set
+# CONFIG_TMP117 is not set
+# CONFIG_TSYS01 is not set
+# CONFIG_TSYS02D is not set
+# CONFIG_MAX31856 is not set
+# CONFIG_MAX31865 is not set
+# end of Temperature sensors
+
+# CONFIG_NTB is not set
+CONFIG_PWM=y
+CONFIG_PWM_SYSFS=y
+# CONFIG_PWM_DEBUG is not set
+# CONFIG_PWM_ATMEL_TCB is not set
+# CONFIG_PWM_CLK is not set
+# CONFIG_PWM_DWC is not set
+# CONFIG_PWM_FSL_FTM is not set
+# CONFIG_PWM_PCA9685 is not set
+CONFIG_PWM_ROCKCHIP=y
+# CONFIG_PWM_XILINX is not set
+
+#
+# IRQ chip support
+#
+CONFIG_IRQCHIP=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_GIC_MAX_NR=1
+CONFIG_ARM_GIC_V2M=y
+CONFIG_ARM_GIC_V3=y
+CONFIG_ARM_GIC_V3_ITS=y
+CONFIG_ARM_GIC_V3_ITS_PCI=y
+# CONFIG_AL_FIC is not set
+# CONFIG_XILINX_INTC is not set
+CONFIG_PARTITION_PERCPU=y
+# end of IRQ chip support
+
+# CONFIG_IPACK_BUS is not set
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_RESET_CONTROLLER=y
+# CONFIG_RESET_SIMPLE is not set
+# CONFIG_RESET_TI_SYSCON is not set
+# CONFIG_RESET_TI_TPS380X is not set
+
+#
+# PHY Subsystem
+#
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PHY_MIPI_DPHY=y
+CONFIG_PHY_XGENE=y
+# CONFIG_PHY_CAN_TRANSCEIVER is not set
+
+#
+# PHY drivers for Broadcom platforms
+#
+# CONFIG_BCM_KONA_USB2_PHY is not set
+# end of PHY drivers for Broadcom platforms
+
+# CONFIG_PHY_CADENCE_TORRENT is not set
+# CONFIG_PHY_CADENCE_DPHY is not set
+# CONFIG_PHY_CADENCE_DPHY_RX is not set
+# CONFIG_PHY_CADENCE_SIERRA is not set
+# CONFIG_PHY_CADENCE_SALVO is not set
+# CONFIG_PHY_PXA_28NM_HSIC is not set
+# CONFIG_PHY_PXA_28NM_USB2 is not set
+# CONFIG_PHY_LAN966X_SERDES is not set
+# CONFIG_PHY_CPCAP_USB is not set
+# CONFIG_PHY_MAPPHONE_MDM6600 is not set
+# CONFIG_PHY_OCELOT_SERDES is not set
+CONFIG_PHY_QCOM_USB_HS=y
+# CONFIG_PHY_QCOM_USB_HSIC is not set
+CONFIG_PHY_ROCKCHIP_DP=m
+CONFIG_PHY_ROCKCHIP_DPHY_RX0=m
+CONFIG_PHY_ROCKCHIP_EMMC=y
+CONFIG_PHY_ROCKCHIP_INNO_HDMI=m
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY=m
+CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=m
+CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=m
+CONFIG_PHY_ROCKCHIP_PCIE=m
+CONFIG_PHY_ROCKCHIP_TYPEC=y
+CONFIG_PHY_ROCKCHIP_USB=m
+# CONFIG_PHY_TUSB1210 is not set
+# end of PHY Subsystem
+
+# CONFIG_POWERCAP is not set
+# CONFIG_MCB is not set
+
+#
+# Performance monitor support
+#
+# CONFIG_ARM_CCI_PMU is not set
+# CONFIG_ARM_CCN is not set
+# CONFIG_ARM_CMN is not set
+CONFIG_ARM_PMU=y
+# CONFIG_ARM_DSU_PMU is not set
+# CONFIG_ARM_SPE_PMU is not set
+# CONFIG_HISI_PCIE_PMU is not set
+# CONFIG_HNS3_PMU is not set
+# end of Performance monitor support
+
+CONFIG_RAS=y
+# CONFIG_USB4 is not set
+
+#
+# Android
+#
+# CONFIG_ANDROID_BINDER_IPC is not set
+# end of Android
+
+# CONFIG_LIBNVDIMM is not set
+# CONFIG_DAX is not set
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SYSFS=y
+# CONFIG_NVMEM_SPMI_SDAM is not set
+CONFIG_ROCKCHIP_EFUSE=y
+# CONFIG_ROCKCHIP_OTP is not set
+# CONFIG_NVMEM_RMEM is not set
+
+#
+# HW tracing support
+#
+# CONFIG_STM is not set
+# CONFIG_INTEL_TH is not set
+# end of HW tracing support
+
+# CONFIG_FPGA is not set
+# CONFIG_FSI is not set
+CONFIG_TEE=y
+CONFIG_OPTEE=y
+CONFIG_PM_OPP=y
+# CONFIG_SIOX is not set
+# CONFIG_SLIMBUS is not set
+# CONFIG_INTERCONNECT is not set
+# CONFIG_COUNTER is not set
+# CONFIG_MOST is not set
+# CONFIG_PECI is not set
+CONFIG_HTE=y
+# end of Device Drivers
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_VALIDATE_FS_PARSER is not set
+CONFIG_FS_IOMAP=y
+# CONFIG_EXT2_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_USE_FOR_EXT2=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_XFS_FS=m
+CONFIG_XFS_SUPPORT_V4=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_ONLINE_SCRUB is not set
+CONFIG_XFS_DEBUG=y
+CONFIG_XFS_ASSERT_FATAL=y
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+# CONFIG_EXPORTFS_BLOCK_OPS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_FS_ENCRYPTION is not set
+# CONFIG_FS_VERITY is not set
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QUOTA_DEBUG is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_AUTOFS_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+# CONFIG_VIRTIO_FS is not set
+CONFIG_OVERLAY_FS=m
+# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set
+CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
+# CONFIG_OVERLAY_FS_INDEX is not set
+# CONFIG_OVERLAY_FS_XINO_AUTO is not set
+# CONFIG_OVERLAY_FS_METACOPY is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+# end of Caches
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+# end of CD-ROM/DVD Filesystems
+
+#
+# DOS/FAT/EXFAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_FAT_DEFAULT_UTF8 is not set
+# CONFIG_EXFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS3_FS is not set
+# end of DOS/FAT/EXFAT/NT Filesystems
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_VMCORE=y
+# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_PROC_CHILDREN is not set
+CONFIG_KERNFS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_INODE64 is not set
+CONFIG_ARCH_SUPPORTS_HUGETLBFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
+CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
+# CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON is not set
+CONFIG_MEMFD_CREATE=y
+CONFIG_ARCH_HAS_GIGANTIC_PAGE=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_EFIVAR_FS=y
+# end of Pseudo filesystems
+
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ORANGEFS_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_PSTORE=y
+CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240
+CONFIG_PSTORE_DEFLATE_COMPRESS=y
+# CONFIG_PSTORE_LZO_COMPRESS is not set
+# CONFIG_PSTORE_LZ4_COMPRESS is not set
+# CONFIG_PSTORE_LZ4HC_COMPRESS is not set
+# CONFIG_PSTORE_842_COMPRESS is not set
+# CONFIG_PSTORE_ZSTD_COMPRESS is not set
+CONFIG_PSTORE_COMPRESS=y
+CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y
+CONFIG_PSTORE_COMPRESS_DEFAULT="deflate"
+# CONFIG_PSTORE_CONSOLE is not set
+# CONFIG_PSTORE_PMSG is not set
+# CONFIG_PSTORE_RAM is not set
+# CONFIG_PSTORE_BLK is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_EROFS_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+# CONFIG_UNICODE is not set
+CONFIG_IO_WQ=y
+# end of File systems
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_KEYS_REQUEST_CACHE is not set
+# CONFIG_PERSISTENT_KEYRINGS is not set
+# CONFIG_TRUSTED_KEYS is not set
+# CONFIG_ENCRYPTED_KEYS is not set
+# CONFIG_KEY_DH_OPERATIONS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+CONFIG_SECURITY=y
+CONFIG_SECURITYFS=y
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
+# CONFIG_HARDENED_USERCOPY is not set
+# CONFIG_FORTIFY_SOURCE is not set
+# CONFIG_STATIC_USERMODEHELPER is not set
+# CONFIG_SECURITY_SMACK is not set
+# CONFIG_SECURITY_TOMOYO is not set
+# CONFIG_SECURITY_APPARMOR is not set
+# CONFIG_SECURITY_LOADPIN is not set
+# CONFIG_SECURITY_YAMA is not set
+# CONFIG_SECURITY_SAFESETID is not set
+# CONFIG_SECURITY_LOCKDOWN_LSM is not set
+# CONFIG_SECURITY_LANDLOCK is not set
+CONFIG_INTEGRITY=y
+# CONFIG_INTEGRITY_SIGNATURE is not set
+CONFIG_INTEGRITY_AUDIT=y
+# CONFIG_IMA is not set
+# CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set
+# CONFIG_EVM is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity"
+
+#
+# Kernel hardening options
+#
+
+#
+# Memory initialization
+#
+CONFIG_INIT_STACK_NONE=y
+# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
+# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
+# end of Memory initialization
+
+CONFIG_RANDSTRUCT_NONE=y
+# end of Kernel hardening options
+# end of Security options
+
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_SKCIPHER=y
+CONFIG_CRYPTO_SKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_AKCIPHER2=y
+CONFIG_CRYPTO_AKCIPHER=y
+CONFIG_CRYPTO_KPP2=y
+CONFIG_CRYPTO_KPP=m
+CONFIG_CRYPTO_ACOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_NULL2=y
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_ENGINE=m
+
+#
+# Public-key cryptography
+#
+CONFIG_CRYPTO_RSA=y
+# CONFIG_CRYPTO_DH is not set
+CONFIG_CRYPTO_ECC=m
+CONFIG_CRYPTO_ECDH=m
+# CONFIG_CRYPTO_ECDSA is not set
+# CONFIG_CRYPTO_ECRDSA is not set
+# CONFIG_CRYPTO_SM2 is not set
+# CONFIG_CRYPTO_CURVE25519 is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set
+# CONFIG_CRYPTO_AEGIS128 is not set
+CONFIG_CRYPTO_SEQIV=m
+CONFIG_CRYPTO_ECHAINIV=y
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CFB is not set
+CONFIG_CRYPTO_CTR=m
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_OFB is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_KEYWRAP is not set
+# CONFIG_CRYPTO_ADIANTUM is not set
+# CONFIG_CRYPTO_HCTR2 is not set
+# CONFIG_CRYPTO_ESSIV is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_CMAC=m
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_XXHASH is not set
+# CONFIG_CRYPTO_BLAKE2B is not set
+CONFIG_CRYPTO_CRCT10DIF=y
+CONFIG_CRYPTO_CRC64_ROCKSOFT=y
+CONFIG_CRYPTO_GHASH=m
+# CONFIG_CRYPTO_POLY1305 is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD160 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SHA3=m
+CONFIG_CRYPTO_SM3=m
+# CONFIG_CRYPTO_SM3_GENERIC is not set
+# CONFIG_CRYPTO_STREEBOG is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_TI is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+CONFIG_CRYPTO_CHACHA20=m
+# CONFIG_CRYPTO_ARIA is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_SM4_GENERIC is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_LZO is not set
+# CONFIG_CRYPTO_842 is not set
+# CONFIG_CRYPTO_LZ4 is not set
+# CONFIG_CRYPTO_LZ4HC is not set
+# CONFIG_CRYPTO_ZSTD is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+# CONFIG_CRYPTO_DRBG_HASH is not set
+# CONFIG_CRYPTO_DRBG_CTR is not set
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+# CONFIG_CRYPTO_USER_API_RNG is not set
+# CONFIG_CRYPTO_USER_API_AEAD is not set
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set
+# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set
+# CONFIG_CRYPTO_DEV_CCP is not set
+# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set
+# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set
+# CONFIG_CRYPTO_DEV_QAT_C62X is not set
+# CONFIG_CRYPTO_DEV_QAT_4XXX is not set
+# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set
+# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set
+# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set
+# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set
+# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set
+# CONFIG_CRYPTO_DEV_ROCKCHIP is not set
+CONFIG_CRYPTO_DEV_VIRTIO=m
+# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
+# CONFIG_CRYPTO_DEV_CCREE is not set
+# CONFIG_CRYPTO_DEV_HISI_SEC is not set
+# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set
+CONFIG_ASYMMETRIC_KEY_TYPE=y
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
+CONFIG_X509_CERTIFICATE_PARSER=y
+# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set
+CONFIG_PKCS7_MESSAGE_PARSER=y
+# CONFIG_FIPS_SIGNATURE_SELFTEST is not set
+
+#
+# Certificates for signature checking
+#
+CONFIG_SYSTEM_TRUSTED_KEYRING=y
+CONFIG_SYSTEM_TRUSTED_KEYS=""
+# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set
+# CONFIG_SECONDARY_TRUSTED_KEYRING is not set
+# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
+# end of Certificates for signature checking
+
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_LINEAR_RANGES=y
+# CONFIG_PACKING is not set
+CONFIG_BITREVERSE=y
+CONFIG_HAVE_ARCH_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_NET_UTILS=y
+# CONFIG_CORDIC is not set
+# CONFIG_PRIME_NUMBERS is not set
+CONFIG_RATIONAL=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_HAS_FAST_MULTIPLIER=y
+CONFIG_ARCH_USE_SYM_ANNOTATIONS=y
+CONFIG_INDIRECT_PIO=y
+# CONFIG_TRACE_MMIO_ACCESS is not set
+
+#
+# Crypto library routines
+#
+CONFIG_CRYPTO_LIB_AES=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m
+CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m
+CONFIG_CRYPTO_LIB_CHACHA=m
+CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m
+CONFIG_CRYPTO_LIB_CURVE25519=m
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9
+CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m
+CONFIG_CRYPTO_LIB_POLY1305=m
+CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+# end of Crypto library routines
+
+CONFIG_LIB_MEMNEQ=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC64_ROCKSOFT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+CONFIG_CRC64=y
+# CONFIG_CRC4 is not set
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=m
+# CONFIG_CRC8 is not set
+CONFIG_XXHASH=y
+CONFIG_AUDIT_GENERIC=y
+CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
+CONFIG_AUDIT_COMPAT_GENERIC=y
+# CONFIG_RANDOM32_SELFTEST is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_LZ4_DECOMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+# CONFIG_XZ_DEC_SPARC is not set
+# CONFIG_XZ_DEC_MICROLZMA is not set
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_DECOMPRESS_LZ4=y
+CONFIG_DECOMPRESS_ZSTD=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_INTERVAL_TREE=y
+CONFIG_ASSOCIATIVE_ARRAY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAS_DMA=y
+CONFIG_DMA_OPS=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_DMA_DECLARE_COHERENT=y
+CONFIG_ARCH_HAS_SETUP_DMA_OPS=y
+CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y
+CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
+CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y
+CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
+CONFIG_SWIOTLB=y
+# CONFIG_DMA_RESTRICTED_POOL is not set
+CONFIG_DMA_NONCOHERENT_MMAP=y
+CONFIG_DMA_COHERENT_POOL=y
+CONFIG_DMA_DIRECT_REMAP=y
+CONFIG_DMA_CMA=y
+CONFIG_DMA_PERNUMA_CMA=y
+
+#
+# Default contiguous memory area size:
+#
+CONFIG_CMA_SIZE_MBYTES=32
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_ALIGNMENT=8
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_DMA_MAP_BENCHMARK is not set
+CONFIG_SGL_ALLOC=y
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_GLOB=y
+# CONFIG_GLOB_SELFTEST is not set
+CONFIG_NLATTR=y
+CONFIG_CLZ_TAB=y
+CONFIG_IRQ_POLL=y
+CONFIG_MPILIB=y
+CONFIG_LIBFDT=y
+CONFIG_OID_REGISTRY=y
+CONFIG_UCS2_STRING=y
+CONFIG_HAVE_GENERIC_VDSO=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_VDSO_TIME_NS=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_AUTOSELECT=y
+CONFIG_SG_POOL=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_STACKDEPOT=y
+CONFIG_SBITMAP=y
+# end of Library routines
+
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+
+#
+# Kernel hacking
+#
+
+#
+# printk and dmesg options
+#
+CONFIG_PRINTK_TIME=y
+# CONFIG_PRINTK_CALLER is not set
+# CONFIG_STACKTRACE_BUILD_ID is not set
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
+CONFIG_CONSOLE_LOGLEVEL_QUIET=4
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
+# CONFIG_BOOT_PRINTK_DELAY is not set
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DYNAMIC_DEBUG_CORE=y
+CONFIG_SYMBOLIC_ERRNAME=y
+CONFIG_DEBUG_BUGVERBOSE=y
+# end of printk and dmesg options
+
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MISC=y
+
+#
+# Compile-time checks and compiler options
+#
+CONFIG_AS_HAS_NON_CONST_LEB128=y
+CONFIG_DEBUG_INFO_NONE=y
+# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
+# CONFIG_DEBUG_INFO_DWARF4 is not set
+# CONFIG_DEBUG_INFO_DWARF5 is not set
+CONFIG_FRAME_WARN=2048
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_HEADERS_INSTALL is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_SECTION_MISMATCH_WARN_ONLY=y
+# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set
+CONFIG_ARCH_WANT_FRAME_POINTERS=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_VMLINUX_MAP is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# end of Compile-time checks and compiler options
+
+#
+# Generic Kernel Debugging Instruments
+#
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
+CONFIG_MAGIC_SYSRQ_SERIAL=y
+CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE=""
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_FS_ALLOW_ALL=y
+# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set
+# CONFIG_DEBUG_FS_ALLOW_NONE is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y
+# CONFIG_UBSAN is not set
+CONFIG_HAVE_ARCH_KCSAN=y
+# end of Generic Kernel Debugging Instruments
+
+#
+# Networking Debugging
+#
+# CONFIG_NET_DEV_REFCNT_TRACKER is not set
+# CONFIG_NET_NS_REFCNT_TRACKER is not set
+# CONFIG_DEBUG_NET is not set
+# end of Networking Debugging
+
+#
+# Memory Debugging
+#
+# CONFIG_PAGE_EXTENSION is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_PAGE_OWNER is not set
+# CONFIG_PAGE_TABLE_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+# CONFIG_DEBUG_PAGE_REF is not set
+# CONFIG_DEBUG_RODATA_TEST is not set
+CONFIG_ARCH_HAS_DEBUG_WX=y
+# CONFIG_DEBUG_WX is not set
+CONFIG_GENERIC_PTDUMP=y
+# CONFIG_PTDUMP_DEBUGFS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SHRINKER_DEBUG is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_SCHED_STACK_END_CHECK is not set
+CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_VM_PGTABLE is not set
+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
+# CONFIG_DEBUG_VIRTUAL is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+CONFIG_HAVE_ARCH_KASAN=y
+CONFIG_HAVE_ARCH_KASAN_SW_TAGS=y
+CONFIG_HAVE_ARCH_KASAN_HW_TAGS=y
+CONFIG_HAVE_ARCH_KASAN_VMALLOC=y
+CONFIG_CC_HAS_KASAN_GENERIC=y
+CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y
+# CONFIG_KASAN is not set
+CONFIG_HAVE_ARCH_KFENCE=y
+# CONFIG_KFENCE is not set
+# end of Memory Debugging
+
+# CONFIG_DEBUG_SHIRQ is not set
+
+#
+# Debug Oops, Lockups and Hangs
+#
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_WQ_WATCHDOG=y
+# CONFIG_TEST_LOCKUP is not set
+# end of Debug Oops, Lockups and Hangs
+
+#
+# Scheduler Debugging
+#
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_SCHED_INFO=y
+# CONFIG_SCHEDSTATS is not set
+# end of Scheduler Debugging
+
+# CONFIG_DEBUG_TIMEKEEPING is not set
+# CONFIG_DEBUG_PREEMPT is not set
+
+#
+# Lock Debugging (spinlocks, mutexes, etc...)
+#
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_LOCK_TORTURE_TEST is not set
+# CONFIG_WW_MUTEX_SELFTEST is not set
+# CONFIG_SCF_TORTURE_TEST is not set
+# CONFIG_CSD_LOCK_WAIT_DEBUG is not set
+# end of Lock Debugging (spinlocks, mutexes, etc...)
+
+CONFIG_TRACE_IRQFLAGS=y
+CONFIG_TRACE_IRQFLAGS_NMI=y
+# CONFIG_DEBUG_IRQFLAGS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
+# CONFIG_DEBUG_KOBJECT is not set
+
+#
+# Debug kernel data structures
+#
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_PLIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BUG_ON_DATA_CORRUPTION is not set
+# end of Debug kernel data structures
+
+# CONFIG_DEBUG_CREDENTIALS is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_RCU_SCALE_TEST is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_REF_SCALE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=21
+CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0
+# CONFIG_RCU_TRACE is not set
+# CONFIG_RCU_EQS_DEBUG is not set
+# end of RCU Debugging
+
+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
+# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACER_MAX_TRACE=y
+CONFIG_TRACE_CLOCK=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_PREEMPTIRQ_TRACEPOINTS=y
+CONFIG_TRACING=y
+CONFIG_GENERIC_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+CONFIG_BOOTTIME_TRACING=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+CONFIG_TRACE_PREEMPT_TOGGLE=y
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_PREEMPT_TRACER=y
+CONFIG_SCHED_TRACER=y
+# CONFIG_HWLAT_TRACER is not set
+CONFIG_OSNOISE_TRACER=y
+CONFIG_TIMERLAT_TRACER=y
+CONFIG_FTRACE_SYSCALLS=y
+CONFIG_TRACER_SNAPSHOT=y
+CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_UPROBE_EVENTS=y
+CONFIG_BPF_EVENTS=y
+CONFIG_DYNAMIC_EVENTS=y
+CONFIG_PROBE_EVENTS=y
+CONFIG_SYNTH_EVENTS=y
+# CONFIG_HIST_TRIGGERS is not set
+CONFIG_TRACE_EVENT_INJECT=y
+# CONFIG_TRACEPOINT_BENCHMARK is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_TRACE_EVAL_MAP_FILE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_RING_BUFFER_STARTUP_TEST is not set
+# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set
+# CONFIG_PREEMPTIRQ_DELAY_TEST is not set
+# CONFIG_SYNTH_EVENT_GEN_TEST is not set
+# CONFIG_RV is not set
+# CONFIG_SAMPLES is not set
+CONFIG_STRICT_DEVMEM=y
+# CONFIG_IO_STRICT_DEVMEM is not set
+
+#
+# arm64 Debugging
+#
+# CONFIG_PID_IN_CONTEXTIDR is not set
+# CONFIG_ARM64_RELOC_TEST is not set
+# CONFIG_CORESIGHT is not set
+# end of arm64 Debugging
+
+#
+# Kernel Testing and Coverage
+#
+# CONFIG_KUNIT is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_ARCH_HAS_KCOV=y
+CONFIG_CC_HAS_SANCOV_TRACE_PC=y
+CONFIG_RUNTIME_TESTING_MENU=y
+# CONFIG_LKDTM is not set
+# CONFIG_TEST_MIN_HEAP is not set
+# CONFIG_TEST_DIV64 is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_TEST_REF_TRACKER is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_REED_SOLOMON_TEST is not set
+# CONFIG_INTERVAL_TREE_TEST is not set
+# CONFIG_PERCPU_TEST is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_TEST_HEXDUMP is not set
+# CONFIG_STRING_SELFTEST is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_STRSCPY is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_TEST_PRINTF is not set
+# CONFIG_TEST_SCANF is not set
+# CONFIG_TEST_BITMAP is not set
+# CONFIG_TEST_UUID is not set
+# CONFIG_TEST_XARRAY is not set
+# CONFIG_TEST_RHASHTABLE is not set
+# CONFIG_TEST_SIPHASH is not set
+# CONFIG_TEST_IDA is not set
+# CONFIG_TEST_LKM is not set
+# CONFIG_TEST_BITOPS is not set
+# CONFIG_TEST_VMALLOC is not set
+# CONFIG_TEST_USER_COPY is not set
+# CONFIG_TEST_BPF is not set
+# CONFIG_TEST_BLACKHOLE_DEV is not set
+# CONFIG_FIND_BIT_BENCHMARK is not set
+# CONFIG_TEST_FIRMWARE is not set
+# CONFIG_TEST_SYSCTL is not set
+# CONFIG_TEST_UDELAY is not set
+# CONFIG_TEST_STATIC_KEYS is not set
+# CONFIG_TEST_KMOD is not set
+# CONFIG_TEST_MEMCAT_P is not set
+# CONFIG_TEST_MEMINIT is not set
+# CONFIG_TEST_FREE_PAGES is not set
+CONFIG_ARCH_USE_MEMTEST=y
+CONFIG_MEMTEST=y
+# end of Kernel Testing and Coverage
+# end of Kernel hacking
diff --git a/frc971/rockpi/README.md b/frc971/rockpi/README.md
new file mode 100644
index 0000000..c71ee08
--- /dev/null
+++ b/frc971/rockpi/README.md
@@ -0,0 +1,108 @@
+# Building a root filesystem image
+
+To start with, you need to build the kernel.
+`build_rootfs.sh` has a list of dependencies you will need to build everything
+in a comment. Start by installing those.
+
+Then, run `./build_kernel.sh`. This will make a .tar.xz with the kernel and
+device tree in it.
+
+Then, build the rootfs with `./build_rootfs.sh`. This will make an image
+named `arm64_bullseye_debian.img`.
+
+The script is set up to reinstall the kernel, add any missing packages, and
+add/update the files added. This isn't perfect, but will incrementally update
+a rootfs as we go. When in doubt, a full reinstall is recommended.
+Do that by removing the image.
+
+# Installing
+
+`sudo dd if=arm64_bullseye_debian.img of=/dev/sda status=progress`
+
+The default user is `pi`, and password is `raspberry`.
+
+# State of RK3399 image processing.
+
+Use `media-ctl -p -d /dev/media1` to print out the ISP configuration.
+
+There is configuration in the image sensor driver, ISP, and resizer.
+`media-ctl` can be used for all of that, and everything needs to be setup
+before images will flow. The resizer supports exporting 2 image sizes
+simultaneously, which is incredibly useful to feed both the h264 encoder and
+code with different image sizes. The following captures images:
+
+```
+# set the links
+media-ctl -v -d "platform:rkisp1" -r
+media-ctl -v -d "platform:rkisp1" -l "'ov5647 4-0036':0 -> 'rkisp1_csi':0 [1]"
+
+media-ctl -v -d "platform:rkisp1" -l "'rkisp1_csi':1 -> 'rkisp1_isp':0 [1]"
+media-ctl -v -d "platform:rkisp1" -l "'rkisp1_isp':2 -> 'rkisp1_resizer_selfpath':0 [1]"
+media-ctl -v -d "platform:rkisp1" -l "'rkisp1_isp':2 -> 'rkisp1_resizer_mainpath':0 [1]"
+
+# set format for imx219 4-0010:0
+media-ctl -v -d "platform:rkisp1" --set-v4l2 '"ov5647 4-0036":0 [fmt:SBGGR10_1X10/1296x972]'
+
+# set format for rkisp1_isp pads:
+media-ctl -v -d "platform:rkisp1" --set-v4l2 '"rkisp1_isp":0 [fmt:SBGGR10_1X10/1296x972 crop: (0,0)/1296x972]'
+media-ctl -v -d "platform:rkisp1" --set-v4l2 '"rkisp1_isp":2 [fmt:YUYV8_2X8/1296x972 crop: (0,0)/1296x972]'
+
+# set format for rkisp1_resizer_selfpath pads:
+media-ctl -v -d "platform:rkisp1" --set-v4l2 '"rkisp1_resizer_selfpath":0 [fmt:YUYV8_2X8/1296x972 crop: (0,0)/1296x972]'
+media-ctl -v -d "platform:rkisp1" --set-v4l2 '"rkisp1_resizer_selfpath":1 [fmt:YUYV8_2X8/1296x972]'
+
+media-ctl -v -d "platform:rkisp1" --set-v4l2 '"rkisp1_resizer_mainpath":0 [fmt:YUYV8_2X8/1296x972 crop: (0,0)/1296x972]'
+media-ctl -v -d "platform:rkisp1" --set-v4l2 '"rkisp1_resizer_mainpath":1 [fmt:YUYV8_2X8/648x486]'
+
+# set format for rkisp1_selfpath:
+v4l2-ctl -z "platform:rkisp1" -d "rkisp1_selfpath" -v "width=1296,height=972,"
+v4l2-ctl -z "platform:rkisp1" -d "rkisp1_selfpath" -v "pixelformat=422P"
+
+v4l2-ctl -z "platform:rkisp1" -d "rkisp1_mainpath" -v "width=648,height=486,"
+v4l2-ctl -z "platform:rkisp1" -d "rkisp1_mainpath" -v "pixelformat=422P"
+
+# start streaming:
+echo "Selfpath"
+v4l2-ctl -z "platform:rkisp1" -d "rkisp1_selfpath" --stream-mmap --stream-count 10
+
+echo "Mainpath"
+v4l2-ctl -z "platform:rkisp1" -d "rkisp1_mainpath" --stream-mmap --stream-count 10
+```
+
+There are 2 pieces of hardware in the rockpi for encoding/decoding,
+the Hantro encoder/decoder, and the rkvdec decoder.
+Considering all the robot does is encode, we don't really need to worry about
+rkvdec.
+
+ISP configuration is available
+[here](https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/pixfmt-meta-rkisp1.html#c.rkisp1_params_cfg)
+using the v4l2 API.
+
+[CNX software](https://www.cnx-software.com/2020/11/24/hantro-h1-hardware-accelerated-video-encoding-support-in-mainline-linux/)
+has a decent state of the union from 2020. The names and pointers are still relevant
+
+July 2022 has some patches which suggest they might make h264 encoding work.
+I don't know where this repo comes from though.
+[Potential patches](https://git.pengutronix.de/cgit/mgr/linux/log/?h=v5.19/topic/rk3568-vepu-h264-stateless-bootlin)
+
+[mpp](https://github.com/rockchip-linux/mpp/blob/develop/readme.txt)
+is Rockchip's proposed userspace processing library. I haven't gotten this to
+work with 6.0 yet.
+
+gstreamer only shows codecs in `gst-inspect-1.0 video4linux2` which there are
+encoders for.
+
+https://lwn.net/Articles/776082/ has a reference patch for the vendor driver.
+
+In theory, something like:
+`gst-launch-1.0 -vvvv videotestsrc ! v4l2jpegenc ! fakesink`
+should work for using the m2m kernel implementation of JPEG encoding on the
+hantro encoder, but something isn't happy and doesn't work. I need to do more debugging
+to figure that out, if we care. It feels like a good baby step to a h624 encoder,
+I could be wrong there.
+
+[This](https://lkml.org/lkml/2021/11/16/628) adds support for VP9 decoding, but
+our kernel already has it. It has pointers to the pieces which added decoding.
+
+[This](https://www.netbsd.org/~mrg/rk3399/Rockchip%20RK3399TRM%20V1.1%20Part3%2020160728.pdf)
+is the TRM for the chip.
diff --git a/frc971/rockpi/build_kernel.sh b/frc971/rockpi/build_kernel.sh
new file mode 100755
index 0000000..73c0a51
--- /dev/null
+++ b/frc971/rockpi/build_kernel.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+set -eux
+set -o pipefail
+
+if [[ ! -e linux ]]; then
+ git clone --branch 6.0.8-rt14-rockpi4b https://github.com/frc971/linux
+ ln -s ../.config linux/.config
+fi
+
+(
+cd linux
+
+export CC=aarch64-linux-gnu-
+export CROSS_COMPILE=aarch64-linux-gnu-
+export LOCALVERSION=-rockpi4b
+
+make ARCH=arm64 CROSS_COMPILE="${CROSS_COMPILE}" oldconfig
+make ARCH=arm64 CROSS_COMPILE="${CROSS_COMPILE}" menuconfig
+make -j40 ARCH=arm64 LOCALVERSION="${LOCALVERSION}" \
+ CROSS_COMPILE="${CROSS_COMPILE}" Image modules
+make -j40 ARCH=arm64 LOCALVERSION="${LOCALVERSION}" \
+ CROSS_COMPILE="${CROSS_COMPILE}" dtbs
+
+rm -rf ../kernel-install
+mkdir -p ../kernel-install
+
+VERSION="$(cat include/config/kernel.release)"
+
+make -s ARCH=arm64 LOCALVERSION="${LOCALVERSION}" \
+ CROSS_COMPILE="${CROSS_COMPILE}" \
+ modules_install INSTALL_MOD_PATH="$(realpath ../kernel-install)"
+make -s ARCH=arm64 LOCALVERSION="${LOCALVERSION}" \
+ CROSS_COMPILE="${CROSS_COMPILE}" \
+ dtbs_install INSTALL_DTBS_PATH="$(realpath ../kernel-install)/boot/dtbs/${VERSION}"
+make -s ARCH=arm64 LOCALVERSION="${LOCALVERSION}" CROSS_COMPILE="${CROSS_COMPILE}" \
+ install INSTALL_PATH="$(realpath ../kernel-install)/boot/"
+)
+
+VERSION="$(cat linux/include/config/kernel.release)"
+
+tar -cvf "linux-kernel-${VERSION}.tar.xz" -C kernel-install .
diff --git a/frc971/rockpi/build_rootfs.sh b/frc971/rockpi/build_rootfs.sh
new file mode 100755
index 0000000..b94154d
--- /dev/null
+++ b/frc971/rockpi/build_rootfs.sh
@@ -0,0 +1,221 @@
+#!/bin/bash
+
+set -eux
+set -o pipefail
+
+UBOOT_VERSION=v2022.10
+
+IMAGE="arm64_bullseye_debian.img"
+KERNEL_VERSION=6.0.8-rt14-rockpi4b
+PARTITION="${IMAGE}.partition"
+
+# TODO(austin): Make sure flex, bison, gcc-aarch64-linux-gnu,
+# gcc-arm-none-eabi, device-tree-compiler, swig are installed
+# rather than let the user figure this out on their own the hard way.
+export CC=aarch64-linux-gnu-
+
+# Reset any existing mounts.
+if mount | grep "${PARTITION}/boot" >/dev/null; then
+ sudo umount "${PARTITION}/boot"
+fi
+
+if mount | grep "${PARTITION}" >/dev/null; then
+ sudo umount "${PARTITION}"
+fi
+
+LOOPBACK="$(sudo losetup --list | grep "${IMAGE}" | awk '{print $1}')"
+if [[ -n "${LOOPBACK}" ]]; then
+ echo "Loop still exists..."
+ sudo losetup -d "${LOOPBACK}"
+fi
+
+# Build bl31.elf.
+if [[ ! -e arm-trusted-firmware ]]; then
+ git clone https://github.com/ARM-software/arm-trusted-firmware --depth=1
+fi
+
+pushd arm-trusted-firmware/
+git pull --ff-only
+#make CROSS_COMPILE="${CC}" realclean -j "$(nproc)"
+make CROSS_COMPILE="${CC}" PLAT=rk3399 -j "$(nproc)"
+popd
+
+export BL31="$(pwd)/arm-trusted-firmware/build/rk3399/release/bl31/bl31.elf"
+
+ls -lah "${BL31}"
+
+# Now, build uboot.
+if [[ ! -e u-boot ]]; then
+ git clone -b "${UBOOT_VERSION} https://github.com/u-boot/u-boot" --depth=1
+fi
+
+pushd u-boot/
+git fetch origin "${UBOOT_VERSION}"
+git reset --hard "${UBOOT_VERSION}"
+
+#make ARCH=arm CROSS_COMPILE="${CC}" distclean -j $(nproc)
+make ARCH=arm CROSS_COMPILE="${CC}" rock-pi-4-rk3399_defconfig -j "$(nproc)"
+make ARCH=arm CROSS_COMPILE="${CC}" -j "$(nproc)"
+echo "Made uboot"
+popd
+
+
+# Now build the base set of partitions.
+NEW_IMAGE=0
+if [[ ! -e "${IMAGE}" ]]; then
+ NEW_IMAGE=1
+ dd if=/dev/zero of="${IMAGE}" bs=1 count=0 seek=3G
+ dd if=./u-boot/idbloader.img of="${IMAGE}" seek=64 conv=notrunc
+ dd if=./u-boot/u-boot.itb of="${IMAGE}" seek=16384 conv=notrunc
+
+ sfdisk "${IMAGE}" <<-__EOF__
+16M,64M,L,*
+80M,,L,*
+__EOF__
+
+ sudo losetup -P -f "${IMAGE}"
+ LOOPBACK="$(sudo losetup --list | grep "${IMAGE}" | awk '{print $1}')"
+
+ sudo mkfs.fat "${LOOPBACK}p1"
+ sudo mkfs.ext4 -L rootfs "${LOOPBACK}p2"
+
+ sudo losetup -d "${LOOPBACK}"
+fi
+
+
+# Mount them
+mkdir -p "${PARTITION}"
+
+sudo losetup -P -f "${IMAGE}"
+LOOPBACK="$(sudo losetup --list | grep "${IMAGE}" | awk '{print $1}')"
+sudo mount "${LOOPBACK}p2" "${PARTITION}"
+if [[ ! -e "${PARTITION}/boot" ]]; then
+ sudo mkdir "${PARTITION}/boot"
+fi
+sudo mount "${LOOPBACK}p1" "${PARTITION}/boot"
+
+# Run the string command as root inside the target.
+function target() {
+ sudo chroot --userspec=root.root "${PARTITION}" qemu-aarch64-static \
+ /bin/bash -c "$1"
+}
+
+# Run the string command as the pi user inside the target.
+function pi_target() {
+ sudo chroot --userspec=pi.pi "${PARTITION}" qemu-aarch64-static \
+ /bin/bash -c "$1"
+}
+
+# And, if we made a new image, debootstrap to get things going.
+if (( NEW_IMAGE == 1 )); then
+ sudo debootstrap --arch=arm64 --no-check-gpg --foreign bullseye \
+ "${PARTITION}" http://deb.debian.org/debian/
+ sudo cp /usr/bin/qemu-aarch64-static "${PARTITION}/usr/bin/"
+
+ target "/debootstrap/debootstrap --second-stage"
+
+ target "useradd -m -p '\$y\$j9T\$85lzhdky63CTj.two7Zj20\$pVY53UR0VebErMlm8peyrEjmxeiRw/rfXfx..9.xet1' -s /bin/bash pi"
+
+else
+ sudo cp /usr/bin/qemu-aarch64-static "${PARTITION}/usr/bin/"
+fi
+
+# Install the kernel.
+sudo rm -rf "${PARTITION}/boot/dtbs/${KERNEL_VERSION}/"
+sudo rm -rf "${PARTITION}/lib/modules/${KERNEL_VERSION}/"
+sudo mkdir -p "${PARTITION}/lib/modules/"
+sudo tar --owner=0 --group=0 --no-same-owner --no-same-permissions -xvf \
+ "linux-kernel-${KERNEL_VERSION}.tar.xz" -C "${PARTITION}/boot/" \
+ --strip-components=2 ./boot/
+sudo tar --strip-components=3 -xvf "linux-kernel-${KERNEL_VERSION}.tar.xz" \
+ -C "${PARTITION}/lib/modules/" ./lib/modules
+
+# Now, configure it to start automatically.
+sudo mkdir -p ${PARTITION}/boot/extlinux/
+cat << __EOF__ | sudo tee "${PARTITION}/boot/extlinux/extlinux.conf"
+label Linux ${KERNEL_VERSION}
+ kernel /vmlinuz-${KERNEL_VERSION}
+ append earlycon=uart8250,mmio32,0xff1a0000 earlyprintk console=ttyS2,1500000n8 root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait
+ fdtdir /dtbs/${KERNEL_VERSION}/
+__EOF__
+
+copyfile root.root 644 etc/apt/sources.list.d/bullseye-backports.list
+copyfile root.root 644 etc/apt/sources.list.d/frc971.list
+
+target "apt-get update"
+target "apt-get -y install -t bullseye-backports systemd"
+
+target "apt-get install -y sudo openssh-server python3 bash-completion git v4l-utils cpufrequtils pmount rsync vim-nox chrony libopencv-calib3d4.5 libopencv-contrib4.5 libopencv-core4.5 libopencv-features2d4.5 libopencv-flann4.5 libopencv-highgui4.5 libopencv-imgcodecs4.5 libopencv-imgproc4.5 libopencv-ml4.5 libopencv-objdetect4.5 libopencv-photo4.5 libopencv-shape4.5 libopencv-stitching4.5 libopencv-superres4.5 libopencv-video4.5 libopencv-videoio4.5 libopencv-videostab4.5 libopencv-viz4.5 libnice10 pmount libnice-dev feh libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 libgstreamer-plugins-bad1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-nice usbutils locales"
+
+target "usermod -a -G sudo pi"
+target "usermod -a -G video pi"
+target "localedef -i en_US -f UTF-8 en_US.UTF-8"
+
+function target_mkdir() {
+ target "install -d -m $2 -o $(echo $1 | sed 's/\.[^.]*//') -g $(echo $1 | sed 's/[^.]*\.//') $3"
+}
+
+function copyfile() {
+ sudo cp contents/$3 ${PARTITION}/$3
+ sudo chmod $2 ${PARTITION}/$3
+ target "chown $1 /$3"
+}
+
+copyfile root.root 644 etc/fstab
+copyfile root.root 440 etc/sudoers
+copyfile root.root 444 etc/default/cpufrequtils
+target_mkdir root.root 755 etc/systemd/network
+copyfile root.root 644 etc/systemd/network/eth0.network
+target_mkdir pi.pi 755 home/pi/.ssh
+copyfile pi.pi 600 home/pi/.ssh/authorized_keys
+target_mkdir root.root 700 root/bin
+copyfile root.root 500 root/bin/grow.sh
+copyfile root.root 500 root/bin/change_hostname.sh
+copyfile root.root 500 root/bin/deploy_kernel.sh
+copyfile root.root 644 etc/systemd/system/grow-rootfs.service
+copyfile root.root 644 etc/sysctl.d/sctp.conf
+copyfile root.root 644 etc/systemd/logind.conf
+copyfile root.root 644 etc/security/limits.d/rt.conf
+copyfile root.root 644 etc/systemd/system/frc971.service
+copyfile root.root 644 etc/systemd/system/frc971chrt.service
+copyfile root.root 644 etc/systemd/system/usb-mount@.service
+copyfile root.root 644 etc/udev/rules.d/99-usb-mount.rules
+
+target "apt-get update"
+target "apt-get -y install -t bullseye-backports systemd"
+
+target "systemctl enable systemd-networkd"
+target "systemctl enable systemd-resolved"
+target "systemctl enable grow-rootfs"
+target "systemctl enable frc971"
+target "systemctl enable frc971chrt"
+target "/root/bin/change_hostname.sh pi-971-1"
+
+
+if [[ ! -e "${PARTITION}/home/pi/.dotfiles" ]]; then
+ pi_target "cd /home/pi/ && \
+ git clone --separate-git-dir=/home/pi/.dotfiles https://github.com/AustinSchuh/.dotfiles.git tmpdotfiles && \
+ rsync --recursive --verbose --exclude .git tmpdotfiles/ /home/pi/ && \
+ rm -r tmpdotfiles && \
+ git --git-dir=/home/pi/.dotfiles/ --work-tree=/home/pi/ config --local status.showUntrackedFiles no && \
+ vim -c \":qa!\""
+
+ target "cd /root/ && \
+ git clone --separate-git-dir=/root/.dotfiles https://github.com/AustinSchuh/.dotfiles.git tmpdotfiles && \
+ rsync --recursive --verbose --exclude .git tmpdotfiles/ /root/ && rm -r tmpdotfiles && \
+ git --git-dir=/root/.dotfiles/ --work-tree=/root/ config --local status.showUntrackedFiles no && \
+ vim -c \":qa!\""
+fi
+
+target "apt-get clean"
+
+sudo chroot ${PARTITION} qemu-aarch64-static /bin/bash
+
+# TODO(austin): This appears to not be working... pi_target doesn't apper to be happy
+sudo chroot --userspec=pi.pi ${PARTITION} qemu-aarch64-static /bin/bash
+
+# TODO(austin): everything else we were doing to the pi's.
+sudo rm ${PARTITION}/usr/bin/qemu-aarch64-static
+sudo umount ${PARTITION}/boot
+sudo umount ${PARTITION}
+rmdir ${PARTITION}
diff --git a/frc971/rockpi/contents/etc/apt/sources.list.d/bullseye-backports.list b/frc971/rockpi/contents/etc/apt/sources.list.d/bullseye-backports.list
new file mode 100644
index 0000000..290785a
--- /dev/null
+++ b/frc971/rockpi/contents/etc/apt/sources.list.d/bullseye-backports.list
@@ -0,0 +1 @@
+deb http://deb.debian.org/debian bullseye-backports main
diff --git a/frc971/rockpi/contents/etc/apt/sources.list.d/frc971.list b/frc971/rockpi/contents/etc/apt/sources.list.d/frc971.list
new file mode 100644
index 0000000..2bfe5f9
--- /dev/null
+++ b/frc971/rockpi/contents/etc/apt/sources.list.d/frc971.list
@@ -0,0 +1 @@
+deb [trusted=yes] https://software.frc971.org/Build-Dependencies/gstreamer_bullseye_arm64_deps ./
diff --git a/frc971/rockpi/contents/etc/fstab b/frc971/rockpi/contents/etc/fstab
new file mode 100644
index 0000000..cf62c9f
--- /dev/null
+++ b/frc971/rockpi/contents/etc/fstab
@@ -0,0 +1,2 @@
+/dev/mmcblk0p1 /boot auto defaults 0 2
+/dev/mmcblk0p2 / auto errors=remount-ro 0 0
diff --git a/frc971/rockpi/contents/etc/security/limits.d/rt.conf b/frc971/rockpi/contents/etc/security/limits.d/rt.conf
new file mode 100644
index 0000000..ad2c08b
--- /dev/null
+++ b/frc971/rockpi/contents/etc/security/limits.d/rt.conf
@@ -0,0 +1,3 @@
+pi - nice -20
+pi - rtprio 95
+pi - memlock unlimited
diff --git a/frc971/rockpi/contents/etc/sudoers b/frc971/rockpi/contents/etc/sudoers
new file mode 100644
index 0000000..4ce0b30
--- /dev/null
+++ b/frc971/rockpi/contents/etc/sudoers
@@ -0,0 +1,27 @@
+#
+# This file MUST be edited with the 'visudo' command as root.
+#
+# Please consider adding local content in /etc/sudoers.d/ instead of
+# directly modifying this file.
+#
+# See the man page for details on how to write a sudoers file.
+#
+Defaults env_reset
+Defaults mail_badpass
+Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+
+# Host alias specification
+
+# User alias specification
+
+# Cmnd alias specification
+
+# User privilege specification
+root ALL=(ALL:ALL) ALL
+
+# Allow members of group sudo to execute any command
+%sudo ALL=NOPASSWD: ALL
+
+# See sudoers(5) for more information on "@include" directives:
+
+@includedir /etc/sudoers.d
diff --git a/frc971/rockpi/contents/etc/sysctl.d/sctp.conf b/frc971/rockpi/contents/etc/sysctl.d/sctp.conf
new file mode 100644
index 0000000..1fcf2ca
--- /dev/null
+++ b/frc971/rockpi/contents/etc/sysctl.d/sctp.conf
@@ -0,0 +1,4 @@
+# https://wwwx.cs.unc.edu/~sparkst/howto/network_tuning.php
+# Make the buffers big enough for an image
+net.core.wmem_max=8388608
+net.core.rmem_max=8388608
diff --git a/frc971/rockpi/contents/etc/systemd/logind.conf b/frc971/rockpi/contents/etc/systemd/logind.conf
new file mode 100644
index 0000000..17ced30
--- /dev/null
+++ b/frc971/rockpi/contents/etc/systemd/logind.conf
@@ -0,0 +1,36 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# See logind.conf(5) for details.
+
+[Login]
+#NAutoVTs=6
+#ReserveVT=6
+#KillUserProcesses=no
+#KillOnlyUsers=
+#KillExcludeUsers=root
+#InhibitDelayMaxSec=5
+#HandlePowerKey=poweroff
+#HandleSuspendKey=suspend
+#HandleHibernateKey=hibernate
+#HandleLidSwitch=suspend
+#HandleLidSwitchExternalPower=suspend
+#HandleLidSwitchDocked=ignore
+#PowerKeyIgnoreInhibited=no
+#SuspendKeyIgnoreInhibited=no
+#HibernateKeyIgnoreInhibited=no
+#LidSwitchIgnoreInhibited=yes
+#HoldoffTimeoutSec=30s
+#IdleAction=ignore
+#IdleActionSec=30min
+#RuntimeDirectorySize=10%
+
+# We don't want systemd removing IPC. This makes it so nothing new can talk to
+# existing channels.
+RemoveIPC=no
+#InhibitorsMax=8192
+#SessionsMax=8192
diff --git a/frc971/rockpi/contents/etc/systemd/network/eth0.network b/frc971/rockpi/contents/etc/systemd/network/eth0.network
new file mode 100644
index 0000000..f9e7c2e
--- /dev/null
+++ b/frc971/rockpi/contents/etc/systemd/network/eth0.network
@@ -0,0 +1,7 @@
+[Match]
+Name=eth0
+
+[Network]
+Address=10.9.71.20/24
+Gateway=10.9.71.13
+DNS=8.8.8.8
diff --git a/frc971/rockpi/contents/etc/systemd/system/frc971.service b/frc971/rockpi/contents/etc/systemd/system/frc971.service
new file mode 100644
index 0000000..be6b37f
--- /dev/null
+++ b/frc971/rockpi/contents/etc/systemd/system/frc971.service
@@ -0,0 +1,22 @@
+[Unit]
+Description=Start up 971 robot code
+Requires=network-online.target
+After=network-online.target
+
+[Service]
+User=pi
+Group=pi
+Type=simple
+WorkingDirectory=/home/pi/bin
+ExecStart=/home/pi/bin/starter.sh
+KillMode=mixed
+TimeoutStopSec=10
+LimitRTPRIO=60
+LimitNICE=-20
+LimitMEMLOCK=infinity
+
+Restart=always
+RestartSec=5s
+
+[Install]
+WantedBy=multi-user.target
diff --git a/frc971/rockpi/contents/etc/systemd/system/frc971chrt.service b/frc971/rockpi/contents/etc/systemd/system/frc971chrt.service
new file mode 100644
index 0000000..6086fa0
--- /dev/null
+++ b/frc971/rockpi/contents/etc/systemd/system/frc971chrt.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Configure IRQs
+
+[Service]
+Type=oneshot
+ExecStart=/home/pi/bin/chrt.sh
+
+[Install]
+WantedBy=multi-user.target
diff --git a/frc971/rockpi/contents/etc/systemd/system/grow-rootfs.service b/frc971/rockpi/contents/etc/systemd/system/grow-rootfs.service
new file mode 100644
index 0000000..232b290
--- /dev/null
+++ b/frc971/rockpi/contents/etc/systemd/system/grow-rootfs.service
@@ -0,0 +1,19 @@
+[Unit]
+Description=Grow partition and filesystem to fit disk
+DefaultDependencies=no
+Before=local-fs.target
+Before=shutdown.target
+After=-.mount
+BindsTo=-.mount
+
+# Backport of <https://github.com/systemd/systemd/pull/14618>.
+After=systemd-remount-fs.service
+
+[Service]
+Type=oneshot
+ExecStart=/bin/bash -c "/root/bin/grow.sh && /sbin/resize2fs $(systemctl show --property What --value -- -.mount)"
+TimeoutSec=0
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
diff --git a/frc971/rockpi/contents/etc/systemd/system/usb-mount@.service b/frc971/rockpi/contents/etc/systemd/system/usb-mount@.service
new file mode 100644
index 0000000..934d456
--- /dev/null
+++ b/frc971/rockpi/contents/etc/systemd/system/usb-mount@.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Mount USB Drive on %i
+[Service]
+Type=oneshot
+RemainAfterExit=true
+ExecStart=/usr/bin/pmount --umask 000 /dev/%i /media/%i
+ExecStop=/usr/bin/pumount /dev/%i
diff --git a/frc971/rockpi/contents/etc/udev/rules.d/99-usb-mount.rules b/frc971/rockpi/contents/etc/udev/rules.d/99-usb-mount.rules
new file mode 100644
index 0000000..1884828
--- /dev/null
+++ b/frc971/rockpi/contents/etc/udev/rules.d/99-usb-mount.rules
@@ -0,0 +1,2 @@
+ACTION=="add",KERNEL=="sd[a-z][0-9]*",SUBSYSTEMS=="usb",RUN+="/bin/systemctl start usb-mount@%k.service"
+ACTION=="remove",KERNEL=="sd[a-z][0-9]*",SUBSYSTEMS=="usb",RUN+="/bin/systemctl stop usb-mount@%k.service"
diff --git a/frc971/rockpi/contents/home/pi/.ssh/authorized_keys b/frc971/rockpi/contents/home/pi/.ssh/authorized_keys
new file mode 100644
index 0000000..9fd2597
--- /dev/null
+++ b/frc971/rockpi/contents/home/pi/.ssh/authorized_keys
@@ -0,0 +1,4 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDI002gCm4aRVrIcg2G4/qF4D1oNY74HFFAHjNUIgvrmqSEn+Oy+pxigpJFiZZaJMJpaw4kpd1IEpZxhooZm4DC4/bVV3wAFTw/OJI7D75WgrRrBRHd95TMBwYyNUhoDOcPAoZ69+IL9P0rhmNjgCv6Y+3PG+Rl6IqRPuf3dXX/PT3E/h8B18PRkEnas/3WTW8goov6x10kVAa5I+iQansiyAbPQF7E+Q5mpsnl26V2vpHo1UAk7y+TD7jqifEn13TmLeTkDXmaIOflQeOBMAdErftuqrClPa00VbejP18v02RI/jOIAQ250g0hN3zvKi2eNHUPdAzlMB4cSvZspRrB /home/austin/.ssh/id_rsa
+ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgzaqXNuB589EgR6/ljdYhp5Ca+B8eimCTmmC23oQvNyIAAAADAQABAAABAQDI002gCm4aRVrIcg2G4/qF4D1oNY74HFFAHjNUIgvrmqSEn+Oy+pxigpJFiZZaJMJpaw4kpd1IEpZxhooZm4DC4/bVV3wAFTw/OJI7D75WgrRrBRHd95TMBwYyNUhoDOcPAoZ69+IL9P0rhmNjgCv6Y+3PG+Rl6IqRPuf3dXX/PT3E/h8B18PRkEnas/3WTW8goov6x10kVAa5I+iQansiyAbPQF7E+Q5mpsnl26V2vpHo1UAk7y+TD7jqifEn13TmLeTkDXmaIOflQeOBMAdErftuqrClPa00VbejP18v02RI/jOIAQ250g0hN3zvKi2eNHUPdAzlMB4cSvZspRrBAAAAAAAAAAAAAAABAAAAHmF1c3Rpbi5zY2h1aEBibHVlcml2ZXJ0ZWNoLmNvbQAAAA8AAAADYnJ0AAAABHJvb3QAAAAAWGi3PAAAAABjhSpmAAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAKwAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQAAAIUEANvRmN8fXmKOO6xQPsllgbHxX+hvP4sU8/ayxw1K9C2MlGT3OKPgnjWEmvEPgpPR+/YQ6asQnP+jucdgCM8q7+c4ATwFnMO7yl2LCU1UkCKShzoumXflKC9rWNVT6MY4PTbpQXui5XE0gIZrjKrkcfCGjvRouUasM/C5Zro/aGQFkL6XAAAApwAAABNlY2RzYS1zaGEyLW5pc3RwNTIxAAAAjAAAAEIAswnueuP8iT7Qbzr1yBx6tLbNY9jewA6NEkLnFJtu11VzBFFaLWxeXwKPy3ajT0DCzt6EX6YKBHfYngnzdyjP9KkAAABCAWsxaA9D59ToYmbEKT//85dczH397v6As8WeQMAMzKfJYVSJBceHiwt6EbRKd6m+xUsd/Sr4Bj/Eu2VvwplqCpOq /home/austin/.ssh/id_rsa
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDLyVTxr8s3kjz+PEjEymgwC8o64IZgBRJbtq9HZ16ufEHqxCD6WK21v8XsbAyTo3/vIfiae+SxhZTC9PMA1AQXuXCBTcvH1avHlHNPgnfxOfzNpU5LSZx/hqrx9tJ+ELV6m34XUbAhIhXJSyiPE2Mst8et6XUvXLgQ8hr0vwXZ3jitI0WzdoZE2svQhn/Cw+NnFiIyhVm4VTnw0bo5XVvvCawvZdTWsyXIvYx9P7rJ5Kvr1eJTZB+tDynzEFxJZeC+lnE6kV8NudC/7hLwwn1Uvqon17Z4P8ukxDsaD2Y4a2v0zqqN0FkEAKjhcqRWdyHM2JOeygRJa1sABNzt4gJB austin@ASchuh-T480s
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDDs88Uby+A7k69WSUXp6wmDrsIIFib5bsJ/0oHdjRWSZc4gHVGVF4cFCIJsjvuiQ3LlQ1vVb4ot7kXDNhPWEENRiuMVN3bovTr0fIjSi+YzhidIUZV44LhIkf2XorjpBjfdKE8YyZgYU0wway6myLijoEy6UnLaYerFjUh0k0p+R/axNtD48Glge82pvihosNt4J4592PGbfoTg7hgPizz4Yp39MtYN0OAqHDSrthU/ceA97prMo9tugozHthDasNAb1u/KiOr86dswLiGhwfM0aWAStIu+jie8fKzFtPFFvCyeEaGTYJ/nKiTq2qX2VNLk2zoqXoP6OPHTztejMtRyuRZxx3+mwhDT1lwUQx/ZsFqMTuIOjGQjpzQg3/Q2Y7rnSeQmgc5LglzaH5SRQ7i3nXJvDm1akdHRFFjarBw9Pb2p8DsDaTmJ6gpoEFqZZa1RM5ZCab8bL9z0pHBdpqhIXcPflDQE7Qi8win+LlWBwFyjhu5PvNnAKFEv6uQC1M= austin@aschuh-3950x
diff --git a/frc971/rockpi/contents/root/bin/change_hostname.sh b/frc971/rockpi/contents/root/bin/change_hostname.sh
new file mode 100755
index 0000000..a784bb1
--- /dev/null
+++ b/frc971/rockpi/contents/root/bin/change_hostname.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+set -xeuo pipefail
+
+HOSTNAME="$1"
+
+# TODO<Jim>: Should probably add handling for imu hostname, too
+if [[ ! "${HOSTNAME}" =~ ^pi-[0-9]*-[0-9]$ ]]; then
+ echo "Invalid hostname ${HOSTNAME}, needs to be pi-[team#]-[pi#]"
+ exit 1
+fi
+
+TEAM_NUMBER="$(echo ${HOSTNAME} | sed 's/pi-\(.*\)-.*/\1/')"
+PI_NUMBER="$(echo ${HOSTNAME} | sed 's/pi-.*-\(.*\)/\1/')"
+IP_BASE="$(echo ${TEAM_NUMBER} | sed 's/\(.*\)\(..\)/10.\1.\2/')"
+IP="${IP_BASE}.$(( 100 + ${PI_NUMBER}))"
+
+echo "Changing to team number ${TEAM_NUMBER}, IP ${IP}"
+
+sed -i "s/^Address=.*$/Address=${IP}\/24/" /etc/systemd/network/eth0.network
+sed -i "s/^Gateway=.*$/Gateway=${IP_BASE}.13/" /etc/systemd/network/eth0.network
+
+echo "${HOSTNAME}" > /etc/hostname
+
+# Make sure a 127.0.* entry exists to make things looking up localhost happy.
+if grep '^127.0.1.1' /etc/hosts > /dev/null;
+then
+ sed -i "s/\(127\.0\.1\.1\t\).*$/\1${HOSTNAME}/" /etc/hosts
+else
+ echo -e "127.0.1.1\t${HOSTNAME}" >> /etc/hosts
+fi
+
+# Put corret team number in pi's IP addresses, or add them if needed
+if grep '^10\.[0-9]*\.[0-9]*\.[0-9]*\s*pi-[0-9]*-[0-9] pi[0-9]$' /etc/hosts >/dev/null ;
+then
+ sed -i "s/^10\.[0-9]*\.[0-9]*\(\.[0-9]*\s*pi-\)[0-9]*\(-[0-9] pi[0-9]\)$/${IP_BASE}\1${TEAM_NUMBER}\2/" /etc/hosts
+else
+ for i in {1..6}; do
+ echo -e "${IP_BASE}.$(( i + 100 ))\tpi-${TEAM_NUMBER}-${i} pi${i}" >> /etc/hosts
+ done
+fi
+
+# Put corret team number in roborio's address, or add it if missing
+if grep '^10\.[0-9]*\.[0-9]*\.2\s*roborio$' /etc/hosts >/dev/null;
+then
+ sed -i "s/^10\.[0-9]*\.[0-9]*\(\.2\s*roborio\)$/${IP_BASE}\1/" /etc/hosts
+else
+ echo -e "${IP_BASE}.2\troborio" >> /etc/hosts
+fi
+
+# Put corret team number in imu's address, or add it if missing
+if grep '^10\.[0-9]*\.[0-9]*\.105\s.*\s*imu$' /etc/hosts >/dev/null;
+then
+ sed -i "s/^10\.[0-9]*\.[0-9]*\(\.[0-9]*\s*pi-\)[0-9]*\(-[0-9] pi5 imu\)$/${IP_BASE}\1${TEAM_NUMBER}\2/" /etc/hosts
+else
+ if grep '^10\.[0-9]*\.[0-9]*\.105\s*pi-[0-9]*-[0-9]*\s*pi5$' /etc/hosts
+ then
+ sed -i "s/^10\.[0-9]*\.[0-9]*\(\.[0-9]*\s*pi-\)[0-9]*\(-[0-9] pi5\)$/${IP_BASE}\1${TEAM_NUMBER}\2 imu/" /etc/hosts
+ else
+ echo -e "${IP_BASE}.105\tpi-${TEAM_NUMBER}-5 pi5 imu" >> /etc/hosts
+ fi
+fi
diff --git a/frc971/rockpi/contents/root/bin/deploy_kernel.sh b/frc971/rockpi/contents/root/bin/deploy_kernel.sh
new file mode 100644
index 0000000..69a6297
--- /dev/null
+++ b/frc971/rockpi/contents/root/bin/deploy_kernel.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+set -ex
+
+KERNEL_VERSION=6.0.8-rt14-rockpi4b
+
+rm -rf /boot/dtbs/${KERNEL_VERSION}/
+rm -rf /lib/modules/${KERNEL_VERSION}/
+tar --owner=0 --group=0 --no-same-owner --no-same-permissions -xvf ./linux-kernel-${KERNEL_VERSION}.tar.xz -C /boot/ --strip-components=2 ./boot/
+tar --strip-components=3 -xvf linux-kernel-${KERNEL_VERSION}.tar.xz -C /lib/modules/ ./lib/modules
diff --git a/frc971/rockpi/contents/root/bin/grow.sh b/frc971/rockpi/contents/root/bin/grow.sh
new file mode 100644
index 0000000..e298427
--- /dev/null
+++ b/frc971/rockpi/contents/root/bin/grow.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+set -eux
+set -o pipefail
+
+PARTITION="$(systemctl show --property What --value -- -.mount | sed 's/\/dev\///')"
+PARTITION_NUMBER="$(echo ${PARTITION} | sed 's/^[^p]*p\([0-9]\)/\1/')"
+DEVICE="$(echo ${PARTITION} | sed 's/p[0-9]*$//')"
+
+START=$(cat /sys/block/${DEVICE}/${PARTITION}/start)
+END=$((${START}+$(cat /sys/block/${DEVICE}/${PARTITION}/size)))
+NEWEND=$(($(cat /sys/block/${DEVICE}/size)-8))
+
+if [[ "${NEWEND}" -gt "${END}" ]]; then
+ sfdisk --delete "/dev/${DEVICE}" "${PARTITION_NUMBER}"
+ sfdisk --force "/dev/${DEVICE}" <<-__EOF__
+16M,64M,L,*
+80M,,L,*
+__EOF__
+ partx -u "/dev/${DEVICE}"
+fi
diff --git a/frc971/vision/BUILD b/frc971/vision/BUILD
index b2b815a..f5bb94d 100644
--- a/frc971/vision/BUILD
+++ b/frc971/vision/BUILD
@@ -79,6 +79,7 @@
"//aos/events/logging:log_reader",
"//frc971/analysis:in_process_plotter",
"//frc971/control_loops/drivetrain:improved_down_estimator",
+ "//frc971/vision:visualize_robot",
"//frc971/wpilib:imu_batch_fbs",
"//frc971/wpilib:imu_fbs",
"//third_party:opencv",
@@ -88,6 +89,46 @@
],
)
+flatbuffer_cc_library(
+ name = "target_map_fbs",
+ srcs = ["target_map.fbs"],
+ gen_reflections = 1,
+ target_compatible_with = ["@platforms//os:linux"],
+ visibility = ["//visibility:public"],
+)
+
+cc_library(
+ name = "target_mapper",
+ srcs = ["target_mapper.cc"],
+ hdrs = ["target_mapper.h"],
+ target_compatible_with = ["@platforms//os:linux"],
+ visibility = ["//visibility:public"],
+ deps = [
+ ":geometry_lib",
+ ":target_map_fbs",
+ "//aos/events:simulated_event_loop",
+ "//frc971/control_loops:control_loop",
+ "//frc971/vision/ceres:pose_graph_2d_lib",
+ "//third_party:opencv",
+ "@com_google_ceres_solver//:ceres",
+ "@org_tuxfamily_eigen//:eigen",
+ ],
+)
+
+cc_test(
+ name = "target_mapper_test",
+ srcs = [
+ "target_mapper_test.cc",
+ ],
+ target_compatible_with = ["@platforms//os:linux"],
+ deps = [
+ ":target_mapper",
+ "//aos/events:simulated_event_loop",
+ "//aos/testing:googletest",
+ "//aos/testing:random_seed",
+ ],
+)
+
cc_library(
name = "geometry_lib",
hdrs = [
@@ -112,3 +153,36 @@
"//aos/testing:googletest",
],
)
+
+cc_library(
+ name = "visualize_robot",
+ srcs = [
+ "visualize_robot.cc",
+ ],
+ hdrs = [
+ "visualize_robot.h",
+ ],
+ deps = [
+ "//aos:init",
+ "//third_party:opencv",
+ "@com_google_absl//absl/strings:str_format",
+ "@org_tuxfamily_eigen//:eigen",
+ ],
+)
+
+cc_binary(
+ name = "visualize_robot_sample",
+ srcs = [
+ "visualize_robot_sample.cc",
+ ],
+ target_compatible_with = ["@platforms//os:linux"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "//aos:init",
+ "//frc971/vision:visualize_robot",
+ "//third_party:opencv",
+ "@com_github_google_glog//:glog",
+ "@com_google_ceres_solver//:ceres",
+ "@org_tuxfamily_eigen//:eigen",
+ ],
+)
diff --git a/frc971/vision/calibration_accumulator.cc b/frc971/vision/calibration_accumulator.cc
index ac1946c..f1ab4fc 100644
--- a/frc971/vision/calibration_accumulator.cc
+++ b/frc971/vision/calibration_accumulator.cc
@@ -1,20 +1,22 @@
#include "frc971/vision/calibration_accumulator.h"
-#include <opencv2/aruco/charuco.hpp>
-#include <opencv2/calib3d.hpp>
-#include <opencv2/features2d.hpp>
+#include <algorithm>
+#include <limits>
#include <opencv2/highgui/highgui.hpp>
-#include <opencv2/imgproc.hpp>
#include "Eigen/Dense"
#include "aos/events/simulated_event_loop.h"
+#include "aos/network/team_number.h"
#include "aos/time/time.h"
#include "frc971/control_loops/quaternion_utils.h"
-#include "frc971/wpilib/imu_batch_generated.h"
#include "frc971/vision/charuco_lib.h"
+#include "frc971/wpilib/imu_batch_generated.h"
DEFINE_bool(display_undistorted, false,
"If true, display the undistorted image.");
+DEFINE_string(save_path, "", "Where to store annotated images");
+DEFINE_bool(save_valid_only, false,
+ "If true, only save images with valid pose estimates");
namespace frc971 {
namespace vision {
@@ -27,59 +29,83 @@
void CalibrationData::AddCameraPose(
distributed_clock::time_point distributed_now, Eigen::Vector3d rvec,
Eigen::Vector3d tvec) {
- // Always start with IMU reading...
- if (!imu_points_.empty() && imu_points_[0].first < distributed_now) {
+ // Always start with IMU (or turret) reading...
+ // Note, we may not have a turret, so need to handle that case
+ // If we later get a turret point, then we handle removal of camera points in
+ // AddTurret
+ if ((!imu_points_.empty() && imu_points_[0].first < distributed_now) &&
+ (turret_points_.empty() || turret_points_[0].first < distributed_now)) {
rot_trans_points_.emplace_back(distributed_now, std::make_pair(rvec, tvec));
}
}
void CalibrationData::AddImu(distributed_clock::time_point distributed_now,
Eigen::Vector3d gyro, Eigen::Vector3d accel) {
- imu_points_.emplace_back(distributed_now, std::make_pair(gyro, accel));
+ double zero_threshold = 1e-12;
+ // We seem to be getting 0 readings on IMU, so ignore for now
+ // TODO<Jim>: I think this has been resolved in HandleIMU, but want to leave
+ // this here just in case there are other ways this could happen
+ if ((fabs(accel(0)) < zero_threshold) && (fabs(accel(1)) < zero_threshold) &&
+ (fabs(accel(2)) < zero_threshold)) {
+ LOG(FATAL) << "Ignoring zero value from IMU accelerometer: " << accel
+ << " (gyro is " << gyro << ")";
+ } else {
+ imu_points_.emplace_back(distributed_now, std::make_pair(gyro, accel));
+ }
}
void CalibrationData::AddTurret(
aos::distributed_clock::time_point distributed_now, Eigen::Vector2d state) {
- // We want the turret to be known too when solving. But, we don't know if we
- // are going to have a turret until we get the first reading. In that case,
- // blow away any camera readings from before.
- while (!rot_trans_points_.empty() &&
- rot_trans_points_[0].first < distributed_now) {
- rot_trans_points_.erase(rot_trans_points_.begin());
+ // We want the turret to be known too when solving. But, we don't know if
+ // we are going to have a turret until we get the first reading. In that
+ // case, blow away any camera readings from before.
+ // NOTE: Since the IMU motion is independent of the turret position, we don't
+ // need to remove the IMU readings before the turret
+ if (turret_points_.empty()) {
+ while (!rot_trans_points_.empty() &&
+ rot_trans_points_[0].first < distributed_now) {
+ LOG(INFO) << "Erasing, distributed " << distributed_now;
+ rot_trans_points_.erase(rot_trans_points_.begin());
+ }
}
turret_points_.emplace_back(distributed_now, state);
}
void CalibrationData::ReviewData(CalibrationDataObserver *observer) const {
- size_t next_imu_point = 0;
size_t next_camera_point = 0;
- while (true) {
- if (next_imu_point != imu_points_.size()) {
- // There aren't that many combinations, so just brute force them all
- // rather than being too clever.
- if (next_camera_point != rot_trans_points_.size()) {
- if (imu_points_[next_imu_point].first >
- rot_trans_points_[next_camera_point].first) {
- // Camera!
- observer->UpdateCamera(rot_trans_points_[next_camera_point].first,
- rot_trans_points_[next_camera_point].second);
- ++next_camera_point;
- } else {
- // IMU!
- observer->UpdateIMU(imu_points_[next_imu_point].first,
- imu_points_[next_imu_point].second);
- ++next_imu_point;
- }
+ size_t next_imu_point = 0;
+ size_t next_turret_point = 0;
+
+ // Just go until one of the data streams runs out. We lose a few points, but
+ // it makes the logic much easier
+ while (
+ next_camera_point != rot_trans_points_.size() &&
+ next_imu_point != imu_points_.size() &&
+ (turret_points_.empty() || next_turret_point != turret_points_.size())) {
+ // If camera_point is next, update it
+ if ((rot_trans_points_[next_camera_point].first <=
+ imu_points_[next_imu_point].first) &&
+ (turret_points_.empty() ||
+ (rot_trans_points_[next_camera_point].first <=
+ turret_points_[next_turret_point].first))) {
+ // Camera!
+ observer->UpdateCamera(rot_trans_points_[next_camera_point].first,
+ rot_trans_points_[next_camera_point].second);
+ ++next_camera_point;
+ } else {
+ // If it's not the camera, check if IMU is next
+ if (turret_points_.empty() || (imu_points_[next_imu_point].first <=
+ turret_points_[next_turret_point].first)) {
+ // IMU!
+ observer->UpdateIMU(imu_points_[next_imu_point].first,
+ imu_points_[next_imu_point].second);
+ ++next_imu_point;
} else {
- if (next_camera_point != rot_trans_points_.size()) {
- // Camera!
- observer->UpdateCamera(rot_trans_points_[next_camera_point].first,
- rot_trans_points_[next_camera_point].second);
- ++next_camera_point;
- } else {
- // Nothing left for either list of points, so we are done.
- break;
- }
+ // If it's not IMU or camera, and turret_points is not empty, it must be
+ // the turret!
+ observer->UpdateTurret(turret_points_[next_turret_point].first,
+ turret_points_[next_turret_point].second);
+ ++next_turret_point;
}
}
}
@@ -98,17 +124,42 @@
charuco_extractor_(
image_event_loop_, pi,
[this](cv::Mat rgb_image, monotonic_clock::time_point eof,
- std::vector<int> charuco_ids,
- std::vector<cv::Point2f> charuco_corners, bool valid,
- Eigen::Vector3d rvec_eigen, Eigen::Vector3d tvec_eigen) {
+ std::vector<cv::Vec4i> charuco_ids,
+ std::vector<std::vector<cv::Point2f>> charuco_corners,
+ bool valid, std::vector<Eigen::Vector3d> rvecs_eigen,
+ std::vector<Eigen::Vector3d> tvecs_eigen) {
HandleCharuco(rgb_image, eof, charuco_ids, charuco_corners, valid,
- rvec_eigen, tvec_eigen);
+ rvecs_eigen, tvecs_eigen);
+ }),
+ image_callback_(
+ image_event_loop_,
+ absl::StrCat("/pi",
+ std::to_string(aos::network::ParsePiNumber(pi).value()),
+ "/camera"),
+ [this](cv::Mat rgb_image, const monotonic_clock::time_point eof) {
+ charuco_extractor_.HandleImage(rgb_image, eof);
}),
data_(data) {
imu_factory_->OnShutdown([]() { cv::destroyAllWindows(); });
+ // Check for IMUValuesBatch topic on both /localizer and /drivetrain channels,
+ // since both are valid/possible
+ std::string imu_channel;
+ if (imu_event_loop->HasChannel<frc971::IMUValuesBatch>("/localizer")) {
+ imu_channel = "/localizer";
+ } else if (imu_event_loop->HasChannel<frc971::IMUValuesBatch>(
+ "/drivetrain")) {
+ imu_channel = "/drivetrain";
+ } else {
+ LOG(FATAL) << "Couldn't find channel with IMU data for either localizer or "
+ "drivtrain";
+ }
+
+ VLOG(2) << "Listening for " << frc971::IMUValuesBatch::GetFullyQualifiedName()
+ << " on channel: " << imu_channel;
+
imu_event_loop_->MakeWatcher(
- "/drivetrain", [this](const frc971::IMUValuesBatch &imu) {
+ imu_channel, [this](const frc971::IMUValuesBatch &imu) {
if (!imu.has_readings()) {
return;
}
@@ -118,28 +169,17 @@
});
}
-void Calibration::HandleCharuco(cv::Mat rgb_image,
- const monotonic_clock::time_point eof,
- std::vector<int> /*charuco_ids*/,
- std::vector<cv::Point2f> /*charuco_corners*/,
- bool valid, Eigen::Vector3d rvec_eigen,
- Eigen::Vector3d tvec_eigen) {
+void Calibration::HandleCharuco(
+ cv::Mat rgb_image, const monotonic_clock::time_point eof,
+ std::vector<cv::Vec4i> /*charuco_ids*/,
+ std::vector<std::vector<cv::Point2f>> /*charuco_corners*/, bool valid,
+ std::vector<Eigen::Vector3d> rvecs_eigen,
+ std::vector<Eigen::Vector3d> tvecs_eigen) {
if (valid) {
- data_->AddCameraPose(image_factory_->ToDistributedClock(eof), rvec_eigen,
- tvec_eigen);
-
- // Z -> up
- // Y -> away from cameras 2 and 3
- // X -> left
- Eigen::Vector3d imu(last_value_.accelerometer_x,
- last_value_.accelerometer_y,
- last_value_.accelerometer_z);
-
- Eigen::Quaternion<double> imu_to_camera(
- Eigen::AngleAxisd(-0.5 * M_PI, Eigen::Vector3d::UnitX()));
-
- Eigen::Quaternion<double> board_to_world(
- Eigen::AngleAxisd(0.5 * M_PI, Eigen::Vector3d::UnitX()));
+ CHECK(rvecs_eigen.size() > 0) << "Require at least one target detected";
+ // We only use one (the first) target detected for calibration
+ data_->AddCameraPose(image_factory_->ToDistributedClock(eof),
+ rvecs_eigen[0], tvecs_eigen[0]);
Eigen::IOFormat HeavyFmt(Eigen::FullPrecision, 0, ", ", ",\n", "[", "]",
"[", "]");
@@ -148,26 +188,47 @@
std::chrono::duration_cast<std::chrono::duration<double>>(
image_event_loop_->monotonic_now() - eof)
.count();
- LOG(INFO) << std::fixed << std::setprecision(6) << "Age: " << age_double
- << ", Pose is R:" << rvec_eigen.transpose().format(HeavyFmt)
- << " T:" << tvec_eigen.transpose().format(HeavyFmt);
+ VLOG(1) << std::fixed << std::setprecision(6) << "Age: " << age_double
+ << ", Pose is R:" << rvecs_eigen[0].transpose().format(HeavyFmt)
+ << "\nT:" << tvecs_eigen[0].transpose().format(HeavyFmt);
}
- cv::imshow("Display", rgb_image);
+ if (FLAGS_visualize) {
+ if (FLAGS_display_undistorted) {
+ const cv::Size image_size(rgb_image.cols, rgb_image.rows);
+ cv::Mat undistorted_rgb_image(image_size, CV_8UC3);
+ cv::undistort(rgb_image, undistorted_rgb_image,
+ charuco_extractor_.camera_matrix(),
+ charuco_extractor_.dist_coeffs());
- if (FLAGS_display_undistorted) {
- const cv::Size image_size(rgb_image.cols, rgb_image.rows);
- cv::Mat undistorted_rgb_image(image_size, CV_8UC3);
- cv::undistort(rgb_image, undistorted_rgb_image,
- charuco_extractor_.camera_matrix(),
- charuco_extractor_.dist_coeffs());
+ cv::imshow("Display undist", undistorted_rgb_image);
+ }
- cv::imshow("Display undist", undistorted_rgb_image);
+ cv::imshow("Display", rgb_image);
+ cv::waitKey(1);
+ }
+
+ if (FLAGS_save_path != "") {
+ if (!FLAGS_save_valid_only || valid) {
+ static int img_count = 0;
+ std::string image_name = absl::StrFormat("/img_%06d.png", img_count);
+ std::string path = FLAGS_save_path + image_name;
+ VLOG(2) << "Saving image to " << path;
+ cv::imwrite(path, rgb_image);
+ img_count++;
+ }
}
}
void Calibration::HandleIMU(const frc971::IMUValues *imu) {
- VLOG(1) << "IMU " << imu;
+ // Need to check for valid values, since we sometimes don't get them
+ if (!imu->has_gyro_x() || !imu->has_gyro_y() || !imu->has_gyro_z() ||
+ !imu->has_accelerometer_x() || !imu->has_accelerometer_y() ||
+ !imu->has_accelerometer_z()) {
+ return;
+ }
+
+ VLOG(2) << "IMU " << imu;
imu->UnPackTo(&last_value_);
Eigen::Vector3d gyro(last_value_.gyro_x, last_value_.gyro_y,
last_value_.gyro_z);
diff --git a/frc971/vision/calibration_accumulator.h b/frc971/vision/calibration_accumulator.h
index e4f9c8a..d21f4c6 100644
--- a/frc971/vision/calibration_accumulator.h
+++ b/frc971/vision/calibration_accumulator.h
@@ -56,7 +56,9 @@
size_t camera_samples_size() const { return rot_trans_points_.size(); }
- size_t turret_samples() const { return turret_points_.size(); }
+ size_t imu_samples_size() const { return imu_points_.size(); }
+
+ size_t turret_samples_size() const { return turret_points_.size(); }
private:
std::vector<std::pair<aos::distributed_clock::time_point,
@@ -82,14 +84,18 @@
aos::EventLoop *image_event_loop, aos::EventLoop *imu_event_loop,
std::string_view pi, CalibrationData *data);
- // Processes a charuco detection.
+ // Processes a charuco detection that is returned from charuco_lib.
+ // For a valid detection(s), it stores camera observation
+ // Also optionally displays and saves annotated images based on visualize and
+ // save_path flags, respectively
void HandleCharuco(cv::Mat rgb_image,
const aos::monotonic_clock::time_point eof,
- std::vector<int> /*charuco_ids*/,
- std::vector<cv::Point2f> /*charuco_corners*/, bool valid,
- Eigen::Vector3d rvec_eigen, Eigen::Vector3d tvec_eigen);
+ std::vector<cv::Vec4i> /*charuco_ids*/,
+ std::vector<std::vector<cv::Point2f>> /*charuco_corners*/,
+ bool valid, std::vector<Eigen::Vector3d> rvecs_eigen,
+ std::vector<Eigen::Vector3d> tvecs_eigen);
- // Processes an IMU reading.
+ // Processes an IMU reading by storing for later processing
void HandleIMU(const frc971::IMUValues *imu);
private:
@@ -99,6 +105,7 @@
aos::NodeEventLoopFactory *imu_factory_;
CharucoExtractor charuco_extractor_;
+ ImageCallback image_callback_;
CalibrationData *data_;
diff --git a/frc971/vision/ceres/BUILD b/frc971/vision/ceres/BUILD
new file mode 100644
index 0000000..5622b55
--- /dev/null
+++ b/frc971/vision/ceres/BUILD
@@ -0,0 +1,24 @@
+# Copy of ceres example code from their repo
+cc_library(
+ name = "pose_graph_2d_lib",
+ hdrs = [
+ "angle_local_parameterization.h",
+ "normalize_angle.h",
+ "pose_graph_2d_error_term.h",
+ "read_g2o.h",
+ "types.h",
+ ],
+ copts = [
+ # Needed to silence GFlags complaints.
+ "-Wno-sign-compare",
+ "-Wno-unused-parameter",
+ "-Wno-format-nonliteral",
+ ],
+ target_compatible_with = ["@platforms//os:linux"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "@com_github_gflags_gflags//:gflags",
+ "@com_google_ceres_solver//:ceres",
+ "@org_tuxfamily_eigen//:eigen",
+ ],
+)
diff --git a/frc971/vision/ceres/angle_local_parameterization.h b/frc971/vision/ceres/angle_local_parameterization.h
new file mode 100644
index 0000000..a81637c
--- /dev/null
+++ b/frc971/vision/ceres/angle_local_parameterization.h
@@ -0,0 +1,64 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2016 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: vitus@google.com (Michael Vitus)
+
+#ifndef CERES_EXAMPLES_POSE_GRAPH_2D_ANGLE_LOCAL_PARAMETERIZATION_H_
+#define CERES_EXAMPLES_POSE_GRAPH_2D_ANGLE_LOCAL_PARAMETERIZATION_H_
+
+#include "ceres/local_parameterization.h"
+#include "normalize_angle.h"
+
+namespace ceres {
+namespace examples {
+
+// Defines a local parameterization for updating the angle to be constrained in
+// [-pi to pi).
+class AngleLocalParameterization {
+ public:
+ template <typename T>
+ bool operator()(const T* theta_radians,
+ const T* delta_theta_radians,
+ T* theta_radians_plus_delta) const {
+ *theta_radians_plus_delta =
+ NormalizeAngle(*theta_radians + *delta_theta_radians);
+
+ return true;
+ }
+
+ static ceres::LocalParameterization* Create() {
+ return (new ceres::AutoDiffLocalParameterization<AngleLocalParameterization,
+ 1,
+ 1>);
+ }
+};
+
+} // namespace examples
+} // namespace ceres
+
+#endif // CERES_EXAMPLES_POSE_GRAPH_2D_ANGLE_LOCAL_PARAMETERIZATION_H_
diff --git a/frc971/vision/ceres/normalize_angle.h b/frc971/vision/ceres/normalize_angle.h
new file mode 100644
index 0000000..c215671
--- /dev/null
+++ b/frc971/vision/ceres/normalize_angle.h
@@ -0,0 +1,53 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2016 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: vitus@google.com (Michael Vitus)
+
+#ifndef CERES_EXAMPLES_POSE_GRAPH_2D_NORMALIZE_ANGLE_H_
+#define CERES_EXAMPLES_POSE_GRAPH_2D_NORMALIZE_ANGLE_H_
+
+#include <cmath>
+
+#include "ceres/ceres.h"
+
+namespace ceres {
+namespace examples {
+
+// Normalizes the angle in radians between [-pi and pi).
+template <typename T>
+inline T NormalizeAngle(const T& angle_radians) {
+ // Use ceres::floor because it is specialized for double and Jet types.
+ T two_pi(2.0 * M_PI);
+ return angle_radians -
+ two_pi * ceres::floor((angle_radians + T(M_PI)) / two_pi);
+}
+
+} // namespace examples
+} // namespace ceres
+
+#endif // CERES_EXAMPLES_POSE_GRAPH_2D_NORMALIZE_ANGLE_H_
diff --git a/frc971/vision/ceres/pose_graph_2d_error_term.h b/frc971/vision/ceres/pose_graph_2d_error_term.h
new file mode 100644
index 0000000..2df31f6
--- /dev/null
+++ b/frc971/vision/ceres/pose_graph_2d_error_term.h
@@ -0,0 +1,119 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2016 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: vitus@google.com (Michael Vitus)
+//
+// Cost function for a 2D pose graph formulation.
+
+#ifndef CERES_EXAMPLES_POSE_GRAPH_2D_POSE_GRAPH_2D_ERROR_TERM_H_
+#define CERES_EXAMPLES_POSE_GRAPH_2D_POSE_GRAPH_2D_ERROR_TERM_H_
+
+#include "Eigen/Core"
+
+namespace ceres {
+namespace examples {
+
+template <typename T>
+Eigen::Matrix<T, 2, 2> RotationMatrix2D(T yaw_radians) {
+ const T cos_yaw = ceres::cos(yaw_radians);
+ const T sin_yaw = ceres::sin(yaw_radians);
+
+ Eigen::Matrix<T, 2, 2> rotation;
+ rotation << cos_yaw, -sin_yaw, sin_yaw, cos_yaw;
+ return rotation;
+}
+
+// Computes the error term for two poses that have a relative pose measurement
+// between them. Let the hat variables be the measurement.
+//
+// residual = information^{1/2} * [ r_a^T * (p_b - p_a) - \hat{p_ab} ]
+// [ Normalize(yaw_b - yaw_a - \hat{yaw_ab}) ]
+//
+// where r_a is the rotation matrix that rotates a vector represented in frame A
+// into the global frame, and Normalize(*) ensures the angles are in the range
+// [-pi, pi).
+class PoseGraph2dErrorTerm {
+ public:
+ PoseGraph2dErrorTerm(double x_ab,
+ double y_ab,
+ double yaw_ab_radians,
+ const Eigen::Matrix3d& sqrt_information)
+ : p_ab_(x_ab, y_ab),
+ yaw_ab_radians_(yaw_ab_radians),
+ sqrt_information_(sqrt_information) {}
+
+ template <typename T>
+ bool operator()(const T* const x_a,
+ const T* const y_a,
+ const T* const yaw_a,
+ const T* const x_b,
+ const T* const y_b,
+ const T* const yaw_b,
+ T* residuals_ptr) const {
+ const Eigen::Matrix<T, 2, 1> p_a(*x_a, *y_a);
+ const Eigen::Matrix<T, 2, 1> p_b(*x_b, *y_b);
+
+ Eigen::Map<Eigen::Matrix<T, 3, 1>> residuals_map(residuals_ptr);
+
+ residuals_map.template head<2>() =
+ RotationMatrix2D(*yaw_a).transpose() * (p_b - p_a) - p_ab_.cast<T>();
+ residuals_map(2) = ceres::examples::NormalizeAngle(
+ (*yaw_b - *yaw_a) - static_cast<T>(yaw_ab_radians_));
+
+ // Scale the residuals by the square root information matrix to account for
+ // the measurement uncertainty.
+ residuals_map = sqrt_information_.template cast<T>() * residuals_map;
+
+ return true;
+ }
+
+ static ceres::CostFunction* Create(double x_ab,
+ double y_ab,
+ double yaw_ab_radians,
+ const Eigen::Matrix3d& sqrt_information) {
+ return (new ceres::
+ AutoDiffCostFunction<PoseGraph2dErrorTerm, 3, 1, 1, 1, 1, 1, 1>(
+ new PoseGraph2dErrorTerm(
+ x_ab, y_ab, yaw_ab_radians, sqrt_information)));
+ }
+
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
+ private:
+ // The position of B relative to A in the A frame.
+ const Eigen::Vector2d p_ab_;
+ // The orientation of frame B relative to frame A.
+ const double yaw_ab_radians_;
+ // The inverse square root of the measurement covariance matrix.
+ const Eigen::Matrix3d sqrt_information_;
+};
+
+} // namespace examples
+} // namespace ceres
+
+#endif // CERES_EXAMPLES_POSE_GRAPH_2D_POSE_GRAPH_2D_ERROR_TERM_H_
diff --git a/frc971/vision/ceres/read_g2o.h b/frc971/vision/ceres/read_g2o.h
new file mode 100644
index 0000000..fea32e9
--- /dev/null
+++ b/frc971/vision/ceres/read_g2o.h
@@ -0,0 +1,143 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2016 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: vitus@google.com (Michael Vitus)
+//
+// Reads a file in the g2o filename format that describes a pose graph problem.
+
+#ifndef EXAMPLES_CERES_READ_G2O_H_
+#define EXAMPLES_CERES_READ_G2O_H_
+
+#include <fstream>
+#include <string>
+
+#include "glog/logging.h"
+
+namespace ceres {
+namespace examples {
+
+// Reads a single pose from the input and inserts it into the map. Returns false
+// if there is a duplicate entry.
+template <typename Pose, typename Allocator>
+bool ReadVertex(std::ifstream* infile,
+ std::map<int, Pose, std::less<int>, Allocator>* poses) {
+ int id;
+ Pose pose;
+ *infile >> id >> pose;
+
+ // Ensure we don't have duplicate poses.
+ if (poses->find(id) != poses->end()) {
+ LOG(ERROR) << "Duplicate vertex with ID: " << id;
+ return false;
+ }
+ (*poses)[id] = pose;
+
+ return true;
+}
+
+// Reads the contraints between two vertices in the pose graph
+template <typename Constraint, typename Allocator>
+void ReadConstraint(std::ifstream* infile,
+ std::vector<Constraint, Allocator>* constraints) {
+ Constraint constraint;
+ *infile >> constraint;
+
+ constraints->push_back(constraint);
+}
+
+// Reads a file in the g2o filename format that describes a pose graph
+// problem. The g2o format consists of two entries, vertices and constraints.
+//
+// In 2D, a vertex is defined as follows:
+//
+// VERTEX_SE2 ID x_meters y_meters yaw_radians
+//
+// A constraint is defined as follows:
+//
+// EDGE_SE2 ID_A ID_B A_x_B A_y_B A_yaw_B I_11 I_12 I_13 I_22 I_23 I_33
+//
+// where I_ij is the (i, j)-th entry of the information matrix for the
+// measurement.
+//
+//
+// In 3D, a vertex is defined as follows:
+//
+// VERTEX_SE3:QUAT ID x y z q_x q_y q_z q_w
+//
+// where the quaternion is in Hamilton form.
+// A constraint is defined as follows:
+//
+// EDGE_SE3:QUAT ID_a ID_b x_ab y_ab z_ab q_x_ab q_y_ab q_z_ab q_w_ab I_11 I_12 I_13 ... I_16 I_22 I_23 ... I_26 ... I_66 // NOLINT
+//
+// where I_ij is the (i, j)-th entry of the information matrix for the
+// measurement. Only the upper-triangular part is stored. The measurement order
+// is the delta position followed by the delta orientation.
+template <typename Pose,
+ typename Constraint,
+ typename MapAllocator,
+ typename VectorAllocator>
+bool ReadG2oFile(const std::string& filename,
+ std::map<int, Pose, std::less<int>, MapAllocator>* poses,
+ std::vector<Constraint, VectorAllocator>* constraints) {
+ CHECK(poses != NULL);
+ CHECK(constraints != NULL);
+
+ poses->clear();
+ constraints->clear();
+
+ std::ifstream infile(filename.c_str());
+ if (!infile) {
+ return false;
+ }
+
+ std::string data_type;
+ while (infile.good()) {
+ // Read whether the type is a node or a constraint.
+ infile >> data_type;
+ if (data_type == Pose::name()) {
+ if (!ReadVertex(&infile, poses)) {
+ return false;
+ }
+ } else if (data_type == Constraint::name()) {
+ ReadConstraint(&infile, constraints);
+ } else {
+ LOG(ERROR) << "Unknown data type: " << data_type;
+ return false;
+ }
+
+ // Clear any trailing whitespace from the line.
+ infile >> std::ws;
+ }
+
+ return true;
+}
+
+} // namespace examples
+} // namespace ceres
+
+#endif // EXAMPLES_CERES_READ_G2O_H_
diff --git a/frc971/vision/ceres/types.h b/frc971/vision/ceres/types.h
new file mode 100644
index 0000000..3c13824
--- /dev/null
+++ b/frc971/vision/ceres/types.h
@@ -0,0 +1,101 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2016 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: vitus@google.com (Michael Vitus)
+//
+// Defines the types used in the 2D pose graph SLAM formulation. Each vertex of
+// the graph has a unique integer ID with a position and orientation. There are
+// delta transformation constraints between two vertices.
+
+#ifndef CERES_EXAMPLES_POSE_GRAPH_2D_TYPES_H_
+#define CERES_EXAMPLES_POSE_GRAPH_2D_TYPES_H_
+
+#include <fstream>
+
+#include "Eigen/Core"
+#include "normalize_angle.h"
+
+namespace ceres {
+namespace examples {
+
+// The state for each vertex in the pose graph.
+struct Pose2d {
+ double x;
+ double y;
+ double yaw_radians;
+
+ // The name of the data type in the g2o file format.
+ static std::string name() { return "VERTEX_SE2"; }
+};
+
+inline std::istream& operator>>(std::istream& input, Pose2d& pose) {
+ input >> pose.x >> pose.y >> pose.yaw_radians;
+ // Normalize the angle between -pi to pi.
+ pose.yaw_radians = NormalizeAngle(pose.yaw_radians);
+ return input;
+}
+
+// The constraint between two vertices in the pose graph. The constraint is the
+// transformation from vertex id_begin to vertex id_end.
+struct Constraint2d {
+ int id_begin;
+ int id_end;
+
+ double x;
+ double y;
+ double yaw_radians;
+
+ // The inverse of the covariance matrix for the measurement. The order of the
+ // entries are x, y, and yaw.
+ Eigen::Matrix3d information;
+
+ // The name of the data type in the g2o file format.
+ static std::string name() { return "EDGE_SE2"; }
+};
+
+inline std::istream& operator>>(std::istream& input, Constraint2d& constraint) {
+ input >> constraint.id_begin >> constraint.id_end >> constraint.x >>
+ constraint.y >> constraint.yaw_radians >> constraint.information(0, 0) >>
+ constraint.information(0, 1) >> constraint.information(0, 2) >>
+ constraint.information(1, 1) >> constraint.information(1, 2) >>
+ constraint.information(2, 2);
+
+ // Set the lower triangular part of the information matrix.
+ constraint.information(1, 0) = constraint.information(0, 1);
+ constraint.information(2, 0) = constraint.information(0, 2);
+ constraint.information(2, 1) = constraint.information(1, 2);
+
+ // Normalize the angle between -pi to pi.
+ constraint.yaw_radians = NormalizeAngle(constraint.yaw_radians);
+ return input;
+}
+
+} // namespace examples
+} // namespace ceres
+
+#endif // CERES_EXAMPLES_POSE_GRAPH_2D_TYPES_H_
diff --git a/frc971/vision/charuco_lib.cc b/frc971/vision/charuco_lib.cc
index fde5394..0db571f 100644
--- a/frc971/vision/charuco_lib.cc
+++ b/frc971/vision/charuco_lib.cc
@@ -17,13 +17,17 @@
#include "y2020/vision/sift/sift_training_generated.h"
#include "y2020/vision/tools/python_code/sift_training_data.h"
-DEFINE_uint32(min_targets, 10,
- "The mininum number of targets required to match.");
-DEFINE_bool(large_board, true, "If true, use the large calibration board.");
-DEFINE_bool(coarse_pattern, true, "If true, use coarse arucos; else, use fine");
DEFINE_string(board_template_path, "",
"If specified, write an image to the specified path for the "
"charuco board pattern.");
+DEFINE_bool(coarse_pattern, true, "If true, use coarse arucos; else, use fine");
+DEFINE_bool(large_board, true, "If true, use the large calibration board.");
+DEFINE_uint32(
+ min_charucos, 10,
+ "The mininum number of aruco targets in charuco board required to match.");
+DEFINE_string(target_type, "charuco",
+ "Type of target: april_tag|aruco|charuco|charuco_diamond");
+DEFINE_bool(visualize, false, "Whether to visualize the resulting data.");
namespace frc971 {
namespace vision {
@@ -87,7 +91,8 @@
ImageCallback::ImageCallback(
aos::EventLoop *event_loop, std::string_view channel,
- std::function<void(cv::Mat, monotonic_clock::time_point)> &&fn)
+ std::function<void(cv::Mat, monotonic_clock::time_point)> &&handle_image_fn)
+
: event_loop_(event_loop),
server_fetcher_(
event_loop_->MakeFetcher<aos::message_bridge::ServerStatistics>(
@@ -97,7 +102,7 @@
event_loop_->GetChannel<CameraImage>(channel)
->source_node()
->string_view())),
- handle_image_(std::move(fn)) {
+ handle_image_(std::move(handle_image_fn)) {
event_loop_->MakeWatcher(channel, [this](const CameraImage &image) {
const monotonic_clock::time_point eof_source_node =
monotonic_clock::time_point(
@@ -150,47 +155,142 @@
});
}
+void CharucoExtractor::SetupTargetData() {
+ // TODO(Jim): Put correct values here
+ marker_length_ = 0.15;
+ square_length_ = 0.1651;
+
+ // Only charuco board has a board associated with it
+ board_ = static_cast<cv::Ptr<cv::aruco::CharucoBoard>>(NULL);
+
+ if (FLAGS_target_type == "charuco" || FLAGS_target_type == "aruco") {
+ dictionary_ = cv::aruco::getPredefinedDictionary(
+ FLAGS_large_board ? cv::aruco::DICT_5X5_250 : cv::aruco::DICT_6X6_250);
+
+ if (FLAGS_target_type == "charuco") {
+ LOG(INFO) << "Using " << (FLAGS_large_board ? " large " : " small ")
+ << " charuco board with "
+ << (FLAGS_coarse_pattern ? "coarse" : "fine") << " pattern";
+ board_ =
+ (FLAGS_large_board
+ ? (FLAGS_coarse_pattern ? cv::aruco::CharucoBoard::create(
+ 12, 9, 0.06, 0.04666, dictionary_)
+ : cv::aruco::CharucoBoard::create(
+ 25, 18, 0.03, 0.0233, dictionary_))
+ : (FLAGS_coarse_pattern ? cv::aruco::CharucoBoard::create(
+ 7, 5, 0.04, 0.025, dictionary_)
+ // TODO(jim): Need to figure out what
+ // size is for small board, fine pattern
+ : cv::aruco::CharucoBoard::create(
+ 7, 5, 0.03, 0.0233, dictionary_)));
+ if (!FLAGS_board_template_path.empty()) {
+ cv::Mat board_image;
+ board_->draw(cv::Size(600, 500), board_image, 10, 1);
+ cv::imwrite(FLAGS_board_template_path, board_image);
+ }
+ }
+ } else if (FLAGS_target_type == "charuco_diamond") {
+ // TODO<Jim>: Measure this
+ marker_length_ = 0.15;
+ square_length_ = 0.1651;
+ dictionary_ = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_250);
+ } else if (FLAGS_target_type == "april_tag") {
+ // Current printout is supposed to be 200mm
+ // TODO<Jim>: Verify this
+ square_length_ = 0.2;
+ dictionary_ =
+ cv::aruco::getPredefinedDictionary(cv::aruco::DICT_APRILTAG_36h11);
+ } else {
+ // Bail out if it's not a supported target
+ LOG(FATAL) << "Target type undefined: " << FLAGS_target_type
+ << " vs. april_tag|aruco|charuco|charuco_diamond";
+ }
+}
+
+void CharucoExtractor::DrawTargetPoses(cv::Mat rgb_image,
+ std::vector<cv::Vec3d> rvecs,
+ std::vector<cv::Vec3d> tvecs) {
+ const Eigen::Matrix<double, 3, 4> camera_projection =
+ Eigen::Matrix<double, 3, 4>::Identity();
+
+ int x_coord = 10;
+ int y_coord = 0;
+ // draw axis for each marker
+ for (uint i = 0; i < rvecs.size(); i++) {
+ Eigen::Vector3d rvec_eigen, tvec_eigen;
+ cv::cv2eigen(rvecs[i], rvec_eigen);
+ cv::cv2eigen(tvecs[i], tvec_eigen);
+
+ Eigen::Quaternion<double> rotation(
+ frc971::controls::ToQuaternionFromRotationVector(rvec_eigen));
+ Eigen::Translation3d translation(tvec_eigen);
+
+ const Eigen::Affine3d board_to_camera = translation * rotation;
+
+ Eigen::Vector3d result = eigen_camera_matrix_ * camera_projection *
+ board_to_camera * Eigen::Vector3d::Zero();
+
+ // Found that drawAxis hangs if you try to draw with z values too
+ // small (trying to draw axes at inifinity)
+ // TODO<Jim>: Explore what real thresholds for this should be;
+ // likely Don't need to get rid of negative values
+ if (result.z() < 0.01) {
+ LOG(INFO) << "Skipping, due to z value too small: " << result.z();
+ } else {
+ result /= result.z();
+ if (FLAGS_target_type == "charuco") {
+ cv::aruco::drawAxis(rgb_image, camera_matrix_, dist_coeffs_, rvecs[i],
+ tvecs[i], 0.1);
+ } else {
+ cv::drawFrameAxes(rgb_image, camera_matrix_, dist_coeffs_, rvecs[i],
+ tvecs[i], 0.1);
+ }
+ }
+ std::stringstream ss;
+ ss << "tvec[" << i << "] = " << tvecs[i];
+ y_coord += 25;
+ cv::putText(rgb_image, ss.str(), cv::Point(x_coord, y_coord),
+ cv::FONT_HERSHEY_PLAIN, 1.0, cv::Scalar(255, 255, 255));
+ ss.str("");
+ ss << "rvec[" << i << "] = " << rvecs[i];
+ y_coord += 25;
+ cv::putText(rgb_image, ss.str(), cv::Point(x_coord, y_coord),
+ cv::FONT_HERSHEY_PLAIN, 1.0, cv::Scalar(255, 255, 255));
+ }
+}
+
+void CharucoExtractor::PackPoseResults(
+ std::vector<cv::Vec3d> &rvecs, std::vector<cv::Vec3d> &tvecs,
+ std::vector<Eigen::Vector3d> *rvecs_eigen,
+ std::vector<Eigen::Vector3d> *tvecs_eigen) {
+ for (cv::Vec3d rvec : rvecs) {
+ Eigen::Vector3d rvec_eigen = Eigen::Vector3d::Zero();
+ cv::cv2eigen(rvec, rvec_eigen);
+ rvecs_eigen->emplace_back(rvec_eigen);
+ }
+
+ for (cv::Vec3d tvec : tvecs) {
+ Eigen::Vector3d tvec_eigen = Eigen::Vector3d::Zero();
+ cv::cv2eigen(tvec, tvec_eigen);
+ tvecs_eigen->emplace_back(tvec_eigen);
+ }
+}
+
CharucoExtractor::CharucoExtractor(
aos::EventLoop *event_loop, std::string_view pi,
- std::function<void(cv::Mat, monotonic_clock::time_point, std::vector<int>,
- std::vector<cv::Point2f>, bool, Eigen::Vector3d,
- Eigen::Vector3d)> &&fn)
+ std::function<void(cv::Mat, monotonic_clock::time_point,
+ std::vector<cv::Vec4i>,
+ std::vector<std::vector<cv::Point2f>>, bool,
+ std::vector<Eigen::Vector3d>,
+ std::vector<Eigen::Vector3d>)> &&handle_charuco_fn)
: event_loop_(event_loop),
calibration_(SiftTrainingData(), pi),
- dictionary_(cv::aruco::getPredefinedDictionary(
- FLAGS_large_board ? cv::aruco::DICT_5X5_250
- : cv::aruco::DICT_6X6_250)),
- board_(
- FLAGS_large_board
- ? (FLAGS_coarse_pattern ? cv::aruco::CharucoBoard::create(
- 12, 9, 0.06, 0.04666, dictionary_)
- : cv::aruco::CharucoBoard::create(
- 25, 18, 0.03, 0.0233, dictionary_))
- : (FLAGS_coarse_pattern ? cv::aruco::CharucoBoard::create(
- 7, 5, 0.04, 0.025, dictionary_)
- // TODO(jim): Need to figure out what size
- // is for small board, fine pattern
- : cv::aruco::CharucoBoard::create(
- 7, 5, 0.03, 0.0233, dictionary_))),
camera_matrix_(calibration_.CameraIntrinsics()),
eigen_camera_matrix_(calibration_.CameraIntrinsicsEigen()),
dist_coeffs_(calibration_.CameraDistCoeffs()),
pi_number_(aos::network::ParsePiNumber(pi)),
- image_callback_(
- event_loop,
- absl::StrCat("/pi", std::to_string(pi_number_.value()), "/camera"),
- [this](cv::Mat rgb_image, const monotonic_clock::time_point eof) {
- HandleImage(rgb_image, eof);
- }),
- handle_charuco_(std::move(fn)) {
- LOG(INFO) << "Using " << (FLAGS_large_board ? "large" : "small")
- << " board with " << (FLAGS_coarse_pattern ? "coarse" : "fine")
- << " pattern";
- if (!FLAGS_board_template_path.empty()) {
- cv::Mat board_image;
- board_->draw(cv::Size(600, 500), board_image, 10, 1);
- cv::imwrite(FLAGS_board_template_path, board_image);
- }
+ handle_charuco_(std::move(handle_charuco_fn)) {
+ SetupTargetData();
LOG(INFO) << "Camera matrix " << camera_matrix_;
LOG(INFO) << "Distortion Coefficients " << dist_coeffs_;
@@ -207,91 +307,143 @@
std::chrono::duration_cast<std::chrono::duration<double>>(
event_loop_->monotonic_now() - eof)
.count();
+
+ // Set up the variables we'll use in the callback function
+ bool valid = false;
+ // Return a list of poses; for Charuco Board there will be just one
+ std::vector<Eigen::Vector3d> rvecs_eigen;
+ std::vector<Eigen::Vector3d> tvecs_eigen;
+
+ // ids and corners for initial aruco marker detections
std::vector<int> marker_ids;
std::vector<std::vector<cv::Point2f>> marker_corners;
- cv::aruco::detectMarkers(rgb_image, board_->dictionary, marker_corners,
- marker_ids);
+ // ids and corners for final, refined board / marker detections
+ // Using Vec4i type since it supports Charuco Diamonds
+ // And overloading it using 1st int in Vec4i for others target types
+ std::vector<cv::Vec4i> result_ids;
+ std::vector<std::vector<cv::Point2f>> result_corners;
- std::vector<cv::Point2f> charuco_corners;
- std::vector<int> charuco_ids;
- bool valid = false;
- Eigen::Vector3d rvec_eigen = Eigen::Vector3d::Zero();
- Eigen::Vector3d tvec_eigen = Eigen::Vector3d::Zero();
+ // Do initial marker detection; this is the same for all target types
+ cv::aruco::detectMarkers(rgb_image, dictionary_, marker_corners, marker_ids);
+ cv::aruco::drawDetectedMarkers(rgb_image, marker_corners, marker_ids);
- // If at least one marker detected
- if (marker_ids.size() >= FLAGS_min_targets) {
- // Run everything twice, once with the calibration, and once
- // without. This lets us both calibrate, and also print out the pose
- // real time with the previous calibration.
- cv::aruco::interpolateCornersCharuco(marker_corners, marker_ids, rgb_image,
- board_, charuco_corners, charuco_ids);
+ VLOG(2) << "Handle Image, with target type = " << FLAGS_target_type << " and "
+ << marker_ids.size() << " markers detected initially";
- std::vector<cv::Point2f> charuco_corners_with_calibration;
- std::vector<int> charuco_ids_with_calibration;
+ if (marker_ids.size() == 0) {
+ VLOG(2) << "Didn't find any markers";
+ } else {
+ if (FLAGS_target_type == "charuco") {
+ std::vector<int> charuco_ids;
+ std::vector<cv::Point2f> charuco_corners;
- cv::aruco::interpolateCornersCharuco(
- marker_corners, marker_ids, rgb_image, board_,
- charuco_corners_with_calibration, charuco_ids_with_calibration,
- camera_matrix_, dist_coeffs_);
+ // If enough aruco markers detected for the Charuco board
+ if (marker_ids.size() >= FLAGS_min_charucos) {
+ // Run everything twice, once with the calibration, and once
+ // without. This lets us both collect data to calibrate the
+ // intrinsics of the camera (to determine the intrinsics from
+ // multiple samples), and also to use data from a previous/stored
+ // calibration to determine a more accurate pose in real time (used
+ // for extrinsics calibration)
+ cv::aruco::interpolateCornersCharuco(marker_corners, marker_ids,
+ rgb_image, board_, charuco_corners,
+ charuco_ids);
- cv::aruco::drawDetectedMarkers(rgb_image, marker_corners, marker_ids);
+ std::vector<cv::Point2f> charuco_corners_with_calibration;
+ std::vector<int> charuco_ids_with_calibration;
- if (charuco_ids.size() >= FLAGS_min_targets) {
- cv::aruco::drawDetectedCornersCharuco(rgb_image, charuco_corners,
- charuco_ids, cv::Scalar(255, 0, 0));
+ // This call uses a previous intrinsic calibration to get more
+ // accurate marker locations, for a better pose estimate
+ cv::aruco::interpolateCornersCharuco(
+ marker_corners, marker_ids, rgb_image, board_,
+ charuco_corners_with_calibration, charuco_ids_with_calibration,
+ camera_matrix_, dist_coeffs_);
- cv::Vec3d rvec, tvec;
- valid = cv::aruco::estimatePoseCharucoBoard(
- charuco_corners_with_calibration, charuco_ids_with_calibration,
- board_, camera_matrix_, dist_coeffs_, rvec, tvec);
+ if (charuco_ids.size() >= FLAGS_min_charucos) {
+ cv::aruco::drawDetectedCornersCharuco(
+ rgb_image, charuco_corners, charuco_ids, cv::Scalar(255, 0, 0));
- // if charuco pose is valid
- if (valid) {
- cv::cv2eigen(rvec, rvec_eigen);
- cv::cv2eigen(tvec, tvec_eigen);
+ cv::Vec3d rvec, tvec;
+ valid = cv::aruco::estimatePoseCharucoBoard(
+ charuco_corners_with_calibration, charuco_ids_with_calibration,
+ board_, camera_matrix_, dist_coeffs_, rvec, tvec);
- Eigen::Quaternion<double> rotation(
- frc971::controls::ToQuaternionFromRotationVector(rvec_eigen));
- Eigen::Translation3d translation(tvec_eigen);
+ // if charuco pose is valid, return pose, with ids and corners
+ if (valid) {
+ std::vector<cv::Vec3d> rvecs, tvecs;
+ rvecs.emplace_back(rvec);
+ tvecs.emplace_back(tvec);
+ DrawTargetPoses(rgb_image, rvecs, tvecs);
- const Eigen::Affine3d board_to_camera = translation * rotation;
-
- Eigen::Matrix<double, 3, 4> camera_projection =
- Eigen::Matrix<double, 3, 4>::Identity();
- Eigen::Vector3d result = eigen_camera_matrix_ * camera_projection *
- board_to_camera * Eigen::Vector3d::Zero();
-
- // Found that drawAxis hangs if you try to draw with z values too small
- // (trying to draw axes at inifinity)
- // TODO<Jim>: Explore what real thresholds for this should be; likely
- // Don't need to get rid of negative values
- if (result.z() < 0.01) {
- LOG(INFO) << "Skipping, due to z value too small: " << result.z();
- valid = false;
+ PackPoseResults(rvecs, tvecs, &rvecs_eigen, &tvecs_eigen);
+ // Store the corners without calibration, since we use them to
+ // do calibration
+ result_corners.emplace_back(charuco_corners);
+ for (auto id : charuco_ids) {
+ result_ids.emplace_back(cv::Vec4i{id, 0, 0, 0});
+ }
+ } else {
+ VLOG(2) << "Age: " << age_double << ", invalid charuco board pose";
+ }
} else {
- result /= result.z();
- cv::circle(rgb_image, cv::Point(result.x(), result.y()), 4,
- cv::Scalar(255, 255, 255), 0, cv::LINE_8);
-
- cv::aruco::drawAxis(rgb_image, camera_matrix_, dist_coeffs_, rvec,
- tvec, 0.1);
+ VLOG(2) << "Age: " << age_double << ", not enough charuco IDs, got "
+ << charuco_ids.size() << ", needed " << FLAGS_min_charucos;
}
} else {
- LOG(INFO) << "Age: " << age_double << ", invalid pose";
+ VLOG(2) << "Age: " << age_double
+ << ", not enough marker IDs for charuco board, got "
+ << marker_ids.size() << ", needed " << FLAGS_min_charucos;
+ }
+ } else if (FLAGS_target_type == "april_tag" ||
+ FLAGS_target_type == "aruco") {
+ // estimate pose for april tags doesn't return valid, so marking true
+ valid = true;
+ std::vector<cv::Vec3d> rvecs, tvecs;
+ cv::aruco::estimatePoseSingleMarkers(marker_corners, square_length_,
+ camera_matrix_, dist_coeffs_, rvecs,
+ tvecs);
+ DrawTargetPoses(rgb_image, rvecs, tvecs);
+
+ PackPoseResults(rvecs, tvecs, &rvecs_eigen, &tvecs_eigen);
+ for (uint i = 0; i < marker_ids.size(); i++) {
+ result_ids.emplace_back(cv::Vec4i{marker_ids[i], 0, 0, 0});
+ }
+ result_corners = marker_corners;
+ } else if (FLAGS_target_type == "charuco_diamond") {
+ // Extract the diamonds associated with the markers
+ std::vector<cv::Vec4i> diamond_ids;
+ std::vector<std::vector<cv::Point2f>> diamond_corners;
+ cv::aruco::detectCharucoDiamond(rgb_image, marker_corners, marker_ids,
+ square_length_ / marker_length_,
+ diamond_corners, diamond_ids);
+
+ // Check to see if we found any diamond targets
+ if (diamond_ids.size() > 0) {
+ cv::aruco::drawDetectedDiamonds(rgb_image, diamond_corners,
+ diamond_ids);
+
+ // estimate pose for diamonds doesn't return valid, so marking true
+ valid = true;
+ std::vector<cv::Vec3d> rvecs, tvecs;
+ cv::aruco::estimatePoseSingleMarkers(diamond_corners, square_length_,
+ camera_matrix_, dist_coeffs_,
+ rvecs, tvecs);
+ DrawTargetPoses(rgb_image, rvecs, tvecs);
+
+ PackPoseResults(rvecs, tvecs, &rvecs_eigen, &tvecs_eigen);
+ result_ids = diamond_ids;
+ result_corners = diamond_corners;
+ } else {
+ VLOG(2) << "Found aruco markers, but no charuco diamond targets";
}
} else {
- VLOG(2) << "Age: " << age_double << ", not enough charuco IDs, got "
- << charuco_ids.size() << ", needed " << FLAGS_min_targets;
+ LOG(FATAL) << "Unknown target type: " << FLAGS_target_type;
}
- } else {
- VLOG(2) << "Age: " << age_double << ", not enough marker IDs, got "
- << marker_ids.size() << ", needed " << FLAGS_min_targets;
- cv::aruco::drawDetectedMarkers(rgb_image, marker_corners, marker_ids);
}
- handle_charuco_(rgb_image, eof, charuco_ids, charuco_corners, valid,
- rvec_eigen, tvec_eigen);
+ handle_charuco_(rgb_image, eof, result_ids, result_corners, valid,
+ rvecs_eigen, tvecs_eigen);
}
} // namespace vision
diff --git a/frc971/vision/charuco_lib.h b/frc971/vision/charuco_lib.h
index a54bfca..362bb7d 100644
--- a/frc971/vision/charuco_lib.h
+++ b/frc971/vision/charuco_lib.h
@@ -15,6 +15,9 @@
#include "y2020/vision/sift/sift_generated.h"
#include "y2020/vision/sift/sift_training_generated.h"
+DECLARE_bool(visualize);
+DECLARE_string(target_type);
+
namespace frc971 {
namespace vision {
@@ -41,14 +44,16 @@
const sift::CameraCalibration *camera_calibration_;
};
-// Class to call a function with a cv::Mat and age when an image shows up on the
-// provided channel. This hides all the conversions and wrangling needed to
-// view the image.
+// Helper class to call a function with a cv::Mat and age when an image shows up
+// on the provided channel. This hides all the conversions and wrangling needed
+// to view the image.
+// Can connect this with HandleImage function from CharucoExtrator for
+// full-service callback functionality
class ImageCallback {
public:
- ImageCallback(
- aos::EventLoop *event_loop, std::string_view channel,
- std::function<void(cv::Mat, aos::monotonic_clock::time_point)> &&fn);
+ ImageCallback(aos::EventLoop *event_loop, std::string_view channel,
+ std::function<void(cv::Mat, aos::monotonic_clock::time_point)>
+ &&handle_image_fn);
private:
aos::EventLoop *event_loop_;
@@ -65,16 +70,25 @@
// cv::Mat -> image with overlays drawn on it.
// monotonic_clock::time_point -> Time on this node when this image was
// captured.
- // std::vector<int> -> charuco_ids
- // std::vector<cv::Point2f> -> charuco_corners
+ // std::vector<Vec4i> -> target ids (aruco/april in first slot of Vec4i)
+ // NOTE: We use Vec4i since that stores the ids for the charuco diamond target
+ // std::vector<std::vector<cv::Point2f>> -> charuco_corners
// bool -> true if rvec/tvec is valid.
- // Eigen::Vector3d -> rvec
- // Eigen::Vector3d -> tvec
+ // std::vector<Eigen::Vector3d> -> rvec
+ // std::vector<Eigen::Vector3d> -> tvec
+ // NOTE: we return as a vector since all but charuco boards could have
+ // multiple targets in an image; for charuco boards, there should be just one
+ // element
CharucoExtractor(
aos::EventLoop *event_loop, std::string_view pi,
std::function<void(cv::Mat, aos::monotonic_clock::time_point,
- std::vector<int>, std::vector<cv::Point2f>, bool,
- Eigen::Vector3d, Eigen::Vector3d)> &&fn);
+ std::vector<cv::Vec4i>,
+ std::vector<std::vector<cv::Point2f>>, bool,
+ std::vector<Eigen::Vector3d>,
+ std::vector<Eigen::Vector3d>)> &&handle_charuco_fn);
+
+ // Handles the image by detecting the charuco board in it.
+ void HandleImage(cv::Mat rgb_image, aos::monotonic_clock::time_point eof);
// Returns the aruco dictionary in use.
cv::Ptr<cv::aruco::Dictionary> dictionary() const { return dictionary_; }
@@ -87,8 +101,20 @@
const cv::Mat dist_coeffs() const { return dist_coeffs_; }
private:
- // Handles the image by detecting the charuco board in it.
- void HandleImage(cv::Mat rgb_image, aos::monotonic_clock::time_point eof);
+ // Creates the dictionary, board, and other parameters for the appropriate
+ // (ch)aruco target
+ void SetupTargetData();
+
+ // Draw the axes from the pose(s) on the image
+ void DrawTargetPoses(cv::Mat rgb_image, std::vector<cv::Vec3d> rvecs,
+ std::vector<cv::Vec3d> tvecs);
+
+ // Helper function to convert rotation (rvecs) and translation (tvecs) vectors
+ // into Eigen vectors and store in corresponding vectors
+ void PackPoseResults(std::vector<cv::Vec3d> &rvecs,
+ std::vector<cv::Vec3d> &tvecs,
+ std::vector<Eigen::Vector3d> *rvecs_eigen,
+ std::vector<Eigen::Vector3d> *tvecs_eigen);
aos::EventLoop *event_loop_;
CameraCalibration calibration_;
@@ -96,18 +122,26 @@
cv::Ptr<cv::aruco::Dictionary> dictionary_;
cv::Ptr<cv::aruco::CharucoBoard> board_;
+ // Length of a side of the aruco marker
+ double marker_length_;
+ // Length of a side of the checkerboard squares (around the marker)
+ double square_length_;
+
+ // Intrinsic calibration matrix
const cv::Mat camera_matrix_;
+ // Intrinsic calibration matrix as Eigen::Matrix3d
const Eigen::Matrix3d eigen_camera_matrix_;
+ // Intrinsic distortion coefficients
const cv::Mat dist_coeffs_;
+ // Index number of the raspberry pi
const std::optional<uint16_t> pi_number_;
- ImageCallback image_callback_;
-
// Function to call.
- std::function<void(cv::Mat, aos::monotonic_clock::time_point,
- std::vector<int>, std::vector<cv::Point2f>, bool,
- Eigen::Vector3d, Eigen::Vector3d)>
+ std::function<void(
+ cv::Mat, aos::monotonic_clock::time_point, std::vector<cv::Vec4i>,
+ std::vector<std::vector<cv::Point2f>>, bool, std::vector<Eigen::Vector3d>,
+ std::vector<Eigen::Vector3d>)>
handle_charuco_;
};
diff --git a/frc971/vision/extrinsics_calibration.cc b/frc971/vision/extrinsics_calibration.cc
index a71f14d..cd6d183 100644
--- a/frc971/vision/extrinsics_calibration.cc
+++ b/frc971/vision/extrinsics_calibration.cc
@@ -6,6 +6,13 @@
#include "frc971/control_loops/runge_kutta.h"
#include "frc971/vision/calibration_accumulator.h"
#include "frc971/vision/charuco_lib.h"
+#include "frc971/vision/visualize_robot.h"
+
+#include <opencv2/core.hpp>
+#include <opencv2/core/eigen.hpp>
+#include <opencv2/highgui.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <opencv2/imgproc.hpp>
namespace frc971 {
namespace vision {
@@ -79,17 +86,9 @@
virtual void ObserveCameraUpdate(
distributed_clock::time_point /*t*/,
Eigen::Vector3d /*board_to_camera_rotation*/,
+ Eigen::Vector3d /*board_to_camera_translation*/,
Eigen::Quaternion<Scalar> /*imu_to_world_rotation*/,
- Affine3s /*imu_to_world*/) {}
-
- void UpdateTurret(distributed_clock::time_point t,
- Eigen::Vector2d state) override {
- state_ = state;
- state_time_ = t;
- }
-
- Eigen::Vector2d state_ = Eigen::Vector2d::Zero();
- distributed_clock::time_point state_time_ = distributed_clock::min_time;
+ Affine3s /*imu_to_world*/, double /*turret_angle*/) {}
// Observes a camera measurement by applying a kalman filter correction and
// accumulating up the error associated with the step.
@@ -100,8 +99,9 @@
const double pivot_angle =
state_time_ == distributed_clock::min_time
? 0.0
- : state_(0) +
- state_(1) * chrono::duration<double>(t - state_time_).count();
+ : turret_state_(0) +
+ turret_state_(1) *
+ chrono::duration<double>(t - state_time_).count();
const Eigen::Quaternion<Scalar> board_to_camera_rotation(
frc971::controls::ToQuaternionFromRotationVector(rt.first)
@@ -143,9 +143,12 @@
H(2, 2) = static_cast<Scalar>(1.0);
const Eigen::Matrix<Scalar, 3, 1> y = z - H * x_hat_;
+ // TODO<Jim>: Need to understand dependence on this-- solutions vary by 20cm
+ // when changing from 0.01 -> 0.1
+ double obs_noise_var = ::std::pow(0.01, 2);
const Eigen::Matrix<double, 3, 3> R =
- (::Eigen::DiagonalMatrix<double, 3>().diagonal() << ::std::pow(0.01, 2),
- ::std::pow(0.01, 2), ::std::pow(0.01, 2))
+ (::Eigen::DiagonalMatrix<double, 3>().diagonal() << obs_noise_var,
+ obs_noise_var, obs_noise_var)
.finished()
.asDiagonal();
@@ -163,7 +166,8 @@
Eigen::Matrix<Scalar, 3, 1>(error.x(), error.y(), error.z()));
position_errors_.emplace_back(y);
- ObserveCameraUpdate(t, rt.first, imu_to_world_rotation, imu_to_world);
+ ObserveCameraUpdate(t, rt.first, rt.second, imu_to_world_rotation,
+ imu_to_world, pivot_angle);
}
virtual void ObserveIMUUpdate(
@@ -179,7 +183,22 @@
ObserveIMUUpdate(t, wa);
}
+ virtual void ObserveTurretUpdate(distributed_clock::time_point /*t*/,
+ Eigen::Vector2d /*turret_state*/) {}
+
+ void UpdateTurret(distributed_clock::time_point t,
+ Eigen::Vector2d state) override {
+ turret_state_ = state;
+ state_time_ = t;
+
+ ObserveTurretUpdate(t, state);
+ }
+
+ Eigen::Vector2d turret_state_ = Eigen::Vector2d::Zero();
+ distributed_clock::time_point state_time_ = distributed_clock::min_time;
+
const Eigen::Quaternion<Scalar> &orientation() const { return orientation_; }
+ const Eigen::Matrix<Scalar, 6, 1> &get_x_hat() const { return x_hat_; }
size_t num_errors() const { return errors_.size(); }
Scalar errorx(size_t i) const { return errors_[i].x(); }
@@ -373,73 +392,253 @@
vz.emplace_back(x_hat(5));
}
+ // TODO<Jim>: Could probably still do a bit more work on naming
+ // conventions and what is being shown here
frc971::analysis::Plotter plotter;
- plotter.AddFigure("position");
- plotter.AddLine(times_, rx, "x_hat(0)");
- plotter.AddLine(times_, ry, "x_hat(1)");
- plotter.AddLine(times_, rz, "x_hat(2)");
- plotter.AddLine(camera_times_, camera_x_, "Camera x");
- plotter.AddLine(camera_times_, camera_y_, "Camera y");
- plotter.AddLine(camera_times_, camera_z_, "Camera z");
- plotter.AddLine(camera_times_, camera_error_x_, "Camera error x");
- plotter.AddLine(camera_times_, camera_error_y_, "Camera error y");
- plotter.AddLine(camera_times_, camera_error_z_, "Camera error z");
+ plotter.AddFigure("bot (imu) position");
+ plotter.AddLine(times_, x, "x_hat(0)");
+ plotter.AddLine(times_, y, "x_hat(1)");
+ plotter.AddLine(times_, z, "x_hat(2)");
plotter.Publish();
- plotter.AddFigure("error");
- plotter.AddLine(times_, rx, "x_hat(0)");
- plotter.AddLine(times_, ry, "x_hat(1)");
- plotter.AddLine(times_, rz, "x_hat(2)");
- plotter.AddLine(camera_times_, camera_error_x_, "Camera error x");
- plotter.AddLine(camera_times_, camera_error_y_, "Camera error y");
- plotter.AddLine(camera_times_, camera_error_z_, "Camera error z");
+ plotter.AddFigure("bot (imu) rotation");
+ plotter.AddLine(camera_times_, imu_rot_x_, "bot (imu) rot x");
+ plotter.AddLine(camera_times_, imu_rot_y_, "bot (imu) rot y");
+ plotter.AddLine(camera_times_, imu_rot_z_, "bot (imu) rot z");
+ plotter.Publish();
+
+ plotter.AddFigure("rotation error");
+ plotter.AddLine(camera_times_, rotation_error_x_, "Error x");
+ plotter.AddLine(camera_times_, rotation_error_y_, "Error y");
+ plotter.AddLine(camera_times_, rotation_error_z_, "Error z");
+ plotter.Publish();
+
+ plotter.AddFigure("translation error");
+ plotter.AddLine(camera_times_, translation_error_x_, "Error x");
+ plotter.AddLine(camera_times_, translation_error_y_, "Error y");
+ plotter.AddLine(camera_times_, translation_error_z_, "Error z");
plotter.Publish();
plotter.AddFigure("imu");
- plotter.AddLine(camera_times_, world_gravity_x_, "world_gravity(0)");
- plotter.AddLine(camera_times_, world_gravity_y_, "world_gravity(1)");
- plotter.AddLine(camera_times_, world_gravity_z_, "world_gravity(2)");
- plotter.AddLine(imu_times_, imu_x_, "imu x");
- plotter.AddLine(imu_times_, imu_y_, "imu y");
- plotter.AddLine(imu_times_, imu_z_, "imu z");
- plotter.AddLine(times_, rx, "rotation x");
- plotter.AddLine(times_, ry, "rotation y");
- plotter.AddLine(times_, rz, "rotation z");
+ plotter.AddLine(imu_times_, imu_rate_x_, "imu gyro x");
+ plotter.AddLine(imu_times_, imu_rate_y_, "imu gyro y");
+ plotter.AddLine(imu_times_, imu_rate_z_, "imu gyro z");
+ plotter.AddLine(imu_times_, imu_accel_x_, "imu accel x");
+ plotter.AddLine(imu_times_, imu_accel_y_, "imu accel y");
+ plotter.AddLine(imu_times_, imu_accel_z_, "imu accel z");
+ plotter.AddLine(camera_times_, accel_minus_gravity_x_,
+ "accel_minus_gravity(0)");
+ plotter.AddLine(camera_times_, accel_minus_gravity_y_,
+ "accel_minus_gravity(1)");
+ plotter.AddLine(camera_times_, accel_minus_gravity_z_,
+ "accel_minus_gravity(2)");
plotter.Publish();
- plotter.AddFigure("raw");
- plotter.AddLine(imu_times_, imu_x_, "imu x");
- plotter.AddLine(imu_times_, imu_y_, "imu y");
- plotter.AddLine(imu_times_, imu_z_, "imu z");
- plotter.AddLine(imu_times_, imu_ratex_, "omega x");
- plotter.AddLine(imu_times_, imu_ratey_, "omega y");
- plotter.AddLine(imu_times_, imu_ratez_, "omega z");
- plotter.AddLine(camera_times_, raw_camera_x_, "Camera x");
- plotter.AddLine(camera_times_, raw_camera_y_, "Camera y");
- plotter.AddLine(camera_times_, raw_camera_z_, "Camera z");
+ plotter.AddFigure("raw camera observations");
+ plotter.AddLine(camera_times_, raw_camera_rot_x_, "Camera rot x");
+ plotter.AddLine(camera_times_, raw_camera_rot_y_, "Camera rot y");
+ plotter.AddLine(camera_times_, raw_camera_rot_z_, "Camera rot z");
+ plotter.AddLine(camera_times_, raw_camera_trans_x_, "Camera trans x");
+ plotter.AddLine(camera_times_, raw_camera_trans_y_, "Camera trans y");
+ plotter.AddLine(camera_times_, raw_camera_trans_z_, "Camera trans z");
plotter.Publish();
- plotter.AddFigure("xyz vel");
- plotter.AddLine(times_, x, "x");
- plotter.AddLine(times_, y, "y");
- plotter.AddLine(times_, z, "z");
+ plotter.AddFigure("xyz pos, vel estimates");
+ plotter.AddLine(times_, x, "x (x_hat(0))");
+ plotter.AddLine(times_, y, "y (x_hat(1))");
+ plotter.AddLine(times_, z, "z (x_hat(2))");
plotter.AddLine(times_, vx, "vx");
plotter.AddLine(times_, vy, "vy");
plotter.AddLine(times_, vz, "vz");
- plotter.AddLine(camera_times_, camera_position_x_, "Camera x");
- plotter.AddLine(camera_times_, camera_position_y_, "Camera y");
- plotter.AddLine(camera_times_, camera_position_z_, "Camera z");
+ plotter.AddLine(camera_times_, imu_position_x_, "x pos from board");
+ plotter.AddLine(camera_times_, imu_position_y_, "y pos from board");
+ plotter.AddLine(camera_times_, imu_position_z_, "z pos from board");
plotter.Publish();
+ // If we've got 'em, plot 'em
+ if (turret_times_.size() > 0) {
+ plotter.AddFigure("Turret angle");
+ plotter.AddLine(turret_times_, turret_angles_, "turret angle");
+ plotter.Publish();
+ }
+
plotter.Spin();
}
+ void Visualize(const CalibrationParameters &calibration_parameters) {
+ // Set up virtual camera for visualization
+ VisualizeRobot vis_robot;
+
+ // Set virtual viewing point 10 meters above the origin, rotated so the
+ // camera faces straight down
+ Eigen::Translation3d camera_trans(0, 0, 10.0);
+ Eigen::AngleAxisd camera_rot(M_PI, Eigen::Vector3d::UnitX());
+ Eigen::Affine3d camera_viewpoint = camera_trans * camera_rot;
+ vis_robot.SetViewpoint(camera_viewpoint);
+
+ // Create camera with origin in center, and focal length suitable to fit
+ // robot visualization fully in view
+ int image_width = 500;
+ double focal_length = 1000.0;
+ double intr[] = {focal_length, 0.0, image_width / 2.0,
+ 0.0, focal_length, image_width / 2.0,
+ 0.0, 0.0, 1.0};
+ cv::Mat camera_mat = cv::Mat(3, 3, CV_64FC1, intr);
+ cv::Mat dist_coeffs = cv::Mat(1, 5, CV_64F, 0.0);
+ vis_robot.SetCameraParameters(camera_mat);
+ vis_robot.SetDistortionCoefficients(dist_coeffs);
+
+ /*
+ // Draw an initial visualization
+ Eigen::Vector3d T_world_imu_vec =
+ calibration_parameters.initial_state.block<3, 1>(0, 0);
+ Eigen::Translation3d T_world_imu(T_world_imu_vec);
+ Eigen::Affine3d H_world_imu =
+ T_world_imu * calibration_parameters.initial_orientation;
+
+ vis_robot.DrawFrameAxes(H_world_imu, "imu");
+
+ Eigen::Quaterniond R_imu_pivot(calibration_parameters.pivot_to_imu);
+ Eigen::Translation3d T_imu_pivot(
+ calibration_parameters.pivot_to_imu_translation);
+ Eigen::Affine3d H_imu_pivot = T_imu_pivot * R_imu_pivot;
+ Eigen::Affine3d H_world_pivot = H_world_imu * H_imu_pivot;
+ vis_robot.DrawFrameAxes(H_world_pivot, "pivot");
+
+ Eigen::Affine3d H_imupivot_camerapivot(
+ Eigen::AngleAxisd(1.5, Eigen::Vector3d::UnitZ()));
+ Eigen::Quaterniond R_camera_pivot(calibration_parameters.pivot_to_camera);
+ Eigen::Translation3d T_camera_pivot(
+ calibration_parameters.pivot_to_camera_translation);
+ Eigen::Affine3d H_camera_pivot = T_camera_pivot * R_camera_pivot;
+ Eigen::Affine3d H_world_camera = H_world_imu * H_imu_pivot *
+ H_imupivot_camerapivot *
+ H_camera_pivot.inverse();
+ vis_robot.DrawFrameAxes(H_world_camera, "camera");
+
+ cv::imshow("Original poses", image_mat);
+ cv::waitKey();
+ */
+
+ uint current_state_index = 0;
+ uint current_turret_index = 0;
+ for (uint i = 0; i < camera_times_.size() - 1; i++) {
+ // reset image each frame
+ cv::Mat image_mat =
+ cv::Mat::zeros(cv::Size(image_width, image_width), CV_8UC3);
+ vis_robot.SetImage(image_mat);
+
+ // Jump to state closest to current camera_time
+ while (camera_times_[i] > times_[current_state_index] &&
+ current_state_index < times_.size()) {
+ current_state_index++;
+ }
+
+ // H_world_imu: map from world origin to imu (robot) frame
+ Eigen::Vector3d T_world_imu_vec =
+ x_hats_[current_state_index].block<3, 1>(0, 0);
+ Eigen::Translation3d T_world_imu(T_world_imu_vec);
+ Eigen::Affine3d H_world_imu =
+ T_world_imu * orientations_[current_state_index];
+
+ vis_robot.DrawFrameAxes(H_world_imu, "imu_kf");
+
+ // H_world_pivot: map from world origin to pivot point
+ // Do this via the imu (using H_world_pivot = H_world_imu * H_imu_pivot)
+ Eigen::Quaterniond R_imu_pivot(calibration_parameters.pivot_to_imu);
+ Eigen::Translation3d T_imu_pivot(
+ calibration_parameters.pivot_to_imu_translation);
+ Eigen::Affine3d H_imu_pivot = T_imu_pivot * R_imu_pivot;
+ Eigen::Affine3d H_world_pivot = H_world_imu * H_imu_pivot;
+ vis_robot.DrawFrameAxes(H_world_pivot, "pivot");
+
+ // Jump to turret sample closest to current camera_time
+ while (turret_times_.size() > 0 &&
+ camera_times_[i] > turret_times_[current_turret_index] &&
+ current_turret_index < turret_times_.size()) {
+ current_turret_index++;
+ }
+
+ // Draw the camera frame
+
+ Eigen::Affine3d H_imupivot_camerapivot(Eigen::Matrix4d::Identity());
+ if (turret_angles_.size() > 0) {
+ // Need to rotate by the turret angle in the middle of all this
+ H_imupivot_camerapivot = Eigen::Affine3d(Eigen::AngleAxisd(
+ turret_angles_[current_turret_index], Eigen::Vector3d::UnitZ()));
+ }
+
+ // H_world_camera: map from world origin to camera frame
+ // Via imu->pivot->pivot rotation
+ Eigen::Quaterniond R_camera_pivot(calibration_parameters.pivot_to_camera);
+ Eigen::Translation3d T_camera_pivot(
+ calibration_parameters.pivot_to_camera_translation);
+ Eigen::Affine3d H_camera_pivot = T_camera_pivot * R_camera_pivot;
+ Eigen::Affine3d H_world_camera = H_world_imu * H_imu_pivot *
+ H_imupivot_camerapivot *
+ H_camera_pivot.inverse();
+ vis_robot.DrawFrameAxes(H_world_camera, "camera");
+
+ // H_world_board: board location from world reference frame
+ // Uses the estimate from camera-> board, on top of H_world_camera
+ Eigen::Quaterniond R_camera_board(
+ frc971::controls::ToQuaternionFromRotationVector(
+ board_to_camera_rotations_[i]));
+ Eigen::Translation3d T_camera_board(board_to_camera_translations_[i]);
+ Eigen::Affine3d H_camera_board = T_camera_board * R_camera_board;
+ Eigen::Affine3d H_world_board = H_world_camera * H_camera_board;
+
+ vis_robot.DrawFrameAxes(H_world_board, "board est");
+
+ // H_world_board_solve: board in world frame based on solver
+ // Find world -> board via solved parameter of H_world_board
+ // (parameter "board_to_world" and assuming origin of board frame is
+ // coincident with origin of world frame, i.e., T_world_board == 0)
+ Eigen::Quaterniond R_world_board_solve(
+ calibration_parameters.board_to_world);
+ Eigen::Translation3d T_world_board_solve(Eigen::Vector3d(0, 0, 0));
+ Eigen::Affine3d H_world_board_solve =
+ T_world_board_solve * R_world_board_solve;
+
+ vis_robot.DrawFrameAxes(H_world_board_solve, "board_solve");
+
+ // H_world_imu_from_board: imu location in world frame, via the board
+ // Determine the imu location via the board_to_world solved
+ // transformation
+ Eigen::Affine3d H_world_imu_from_board =
+ H_world_board_solve * H_camera_board.inverse() * H_camera_pivot *
+ H_imupivot_camerapivot.inverse() * H_imu_pivot.inverse();
+
+ vis_robot.DrawFrameAxes(H_world_imu_from_board, "imu_board");
+
+ // These errors should match up with the residuals in the optimizer
+ // (Note: rotation seems to differ by sign, but that's OK in residual)
+ Eigen::Affine3d error = H_world_imu_from_board.inverse() * H_world_imu;
+ Eigen::Vector3d trans_error =
+ H_world_imu_from_board.translation() - H_world_imu.translation();
+ Eigen::Quaterniond error_rot(error.rotation());
+ VLOG(1) << "Error: \n"
+ << "Rotation: " << error_rot.coeffs().transpose() << "\n"
+ << "Translation: " << trans_error.transpose();
+
+ cv::imshow("Live", image_mat);
+ cv::waitKey(50);
+
+ if (i % 200 == 0) {
+ LOG(INFO) << "Pausing at step " << i;
+ cv::waitKey();
+ }
+ }
+ LOG(INFO) << "Finished visualizing robot. Press any key to continue";
+ cv::waitKey();
+ }
+
void ObserveIntegrated(distributed_clock::time_point t,
Eigen::Matrix<double, 6, 1> x_hat,
Eigen::Quaternion<double> orientation,
Eigen::Matrix<double, 6, 6> p) override {
- VLOG(1) << t << " -> " << p;
- VLOG(1) << t << " xhat -> " << x_hat.transpose();
+ VLOG(2) << t << " -> " << p;
+ VLOG(2) << t << " xhat -> " << x_hat.transpose();
times_.emplace_back(chrono::duration<double>(t.time_since_epoch()).count());
x_hats_.emplace_back(x_hat);
orientations_.emplace_back(orientation);
@@ -448,83 +647,126 @@
void ObserveIMUUpdate(
distributed_clock::time_point t,
std::pair<Eigen::Vector3d, Eigen::Vector3d> wa) override {
- imu_times_.emplace_back(chrono::duration<double>(t.time_since_epoch()).count());
- imu_ratex_.emplace_back(wa.first.x());
- imu_ratey_.emplace_back(wa.first.y());
- imu_ratez_.emplace_back(wa.first.z());
- imu_x_.emplace_back(wa.second.x());
- imu_y_.emplace_back(wa.second.y());
- imu_z_.emplace_back(wa.second.z());
+ imu_times_.emplace_back(
+ chrono::duration<double>(t.time_since_epoch()).count());
+ imu_rate_x_.emplace_back(wa.first.x());
+ imu_rate_y_.emplace_back(wa.first.y());
+ imu_rate_z_.emplace_back(wa.first.z());
+ imu_accel_x_.emplace_back(wa.second.x());
+ imu_accel_y_.emplace_back(wa.second.y());
+ imu_accel_z_.emplace_back(wa.second.z());
last_accel_ = wa.second;
}
void ObserveCameraUpdate(distributed_clock::time_point t,
Eigen::Vector3d board_to_camera_rotation,
+ Eigen::Vector3d board_to_camera_translation,
Eigen::Quaternion<double> imu_to_world_rotation,
- Eigen::Affine3d imu_to_world) override {
- raw_camera_x_.emplace_back(board_to_camera_rotation(0, 0));
- raw_camera_y_.emplace_back(board_to_camera_rotation(1, 0));
- raw_camera_z_.emplace_back(board_to_camera_rotation(2, 0));
+ Eigen::Affine3d imu_to_world,
+ double turret_angle) override {
+ board_to_camera_rotations_.emplace_back(board_to_camera_rotation);
+ board_to_camera_translations_.emplace_back(board_to_camera_translation);
- Eigen::Matrix<double, 3, 1> rotation_vector =
- frc971::controls::ToRotationVectorFromQuaternion(imu_to_world_rotation);
camera_times_.emplace_back(
chrono::duration<double>(t.time_since_epoch()).count());
- Eigen::Matrix<double, 3, 1> camera_error =
+ raw_camera_rot_x_.emplace_back(board_to_camera_rotation(0, 0));
+ raw_camera_rot_y_.emplace_back(board_to_camera_rotation(1, 0));
+ raw_camera_rot_z_.emplace_back(board_to_camera_rotation(2, 0));
+
+ raw_camera_trans_x_.emplace_back(board_to_camera_translation(0, 0));
+ raw_camera_trans_y_.emplace_back(board_to_camera_translation(1, 0));
+ raw_camera_trans_z_.emplace_back(board_to_camera_translation(2, 0));
+
+ Eigen::Matrix<double, 3, 1> rotation_vector =
+ frc971::controls::ToRotationVectorFromQuaternion(imu_to_world_rotation);
+ imu_rot_x_.emplace_back(rotation_vector(0, 0));
+ imu_rot_y_.emplace_back(rotation_vector(1, 0));
+ imu_rot_z_.emplace_back(rotation_vector(2, 0));
+
+ Eigen::Matrix<double, 3, 1> rotation_error =
frc971::controls::ToRotationVectorFromQuaternion(
imu_to_world_rotation.inverse() * orientation());
- camera_x_.emplace_back(rotation_vector(0, 0));
- camera_y_.emplace_back(rotation_vector(1, 0));
- camera_z_.emplace_back(rotation_vector(2, 0));
+ rotation_error_x_.emplace_back(rotation_error(0, 0));
+ rotation_error_y_.emplace_back(rotation_error(1, 0));
+ rotation_error_z_.emplace_back(rotation_error(2, 0));
- camera_error_x_.emplace_back(camera_error(0, 0));
- camera_error_y_.emplace_back(camera_error(1, 0));
- camera_error_z_.emplace_back(camera_error(2, 0));
+ Eigen::Matrix<double, 3, 1> imu_pos = get_x_hat().block<3, 1>(0, 0);
+ Eigen::Translation3d T_world_imu(imu_pos);
+ Eigen::Affine3d H_world_imu = T_world_imu * orientation();
+ Eigen::Affine3d H_error = imu_to_world.inverse() * H_world_imu;
- const Eigen::Vector3d world_gravity =
+ Eigen::Matrix<double, 3, 1> translation_error = H_error.translation();
+ translation_error_x_.emplace_back(translation_error(0, 0));
+ translation_error_y_.emplace_back(translation_error(1, 0));
+ translation_error_z_.emplace_back(translation_error(2, 0));
+
+ const Eigen::Vector3d accel_minus_gravity =
imu_to_world_rotation * last_accel_ -
Eigen::Vector3d(0, 0, kGravity) * gravity_scalar();
- const Eigen::Vector3d camera_position =
- imu_to_world * Eigen::Vector3d::Zero();
+ accel_minus_gravity_x_.emplace_back(accel_minus_gravity.x());
+ accel_minus_gravity_y_.emplace_back(accel_minus_gravity.y());
+ accel_minus_gravity_z_.emplace_back(accel_minus_gravity.z());
- world_gravity_x_.emplace_back(world_gravity.x());
- world_gravity_y_.emplace_back(world_gravity.y());
- world_gravity_z_.emplace_back(world_gravity.z());
+ const Eigen::Vector3d imu_position = imu_to_world * Eigen::Vector3d::Zero();
- camera_position_x_.emplace_back(camera_position.x());
- camera_position_y_.emplace_back(camera_position.y());
- camera_position_z_.emplace_back(camera_position.z());
+ imu_position_x_.emplace_back(imu_position.x());
+ imu_position_y_.emplace_back(imu_position.y());
+ imu_position_z_.emplace_back(imu_position.z());
+
+ turret_angles_from_camera_.emplace_back(turret_angle);
+ imu_to_world_save_.emplace_back(imu_to_world);
+ }
+
+ void ObserveTurretUpdate(distributed_clock::time_point t,
+ Eigen::Vector2d turret_state) override {
+ turret_times_.emplace_back(
+ chrono::duration<double>(t.time_since_epoch()).count());
+ turret_angles_.emplace_back(turret_state(0));
}
std::vector<double> camera_times_;
- std::vector<double> camera_x_;
- std::vector<double> camera_y_;
- std::vector<double> camera_z_;
- std::vector<double> raw_camera_x_;
- std::vector<double> raw_camera_y_;
- std::vector<double> raw_camera_z_;
- std::vector<double> camera_error_x_;
- std::vector<double> camera_error_y_;
- std::vector<double> camera_error_z_;
+ std::vector<double> imu_rot_x_;
+ std::vector<double> imu_rot_y_;
+ std::vector<double> imu_rot_z_;
+ std::vector<double> raw_camera_rot_x_;
+ std::vector<double> raw_camera_rot_y_;
+ std::vector<double> raw_camera_rot_z_;
+ std::vector<double> raw_camera_trans_x_;
+ std::vector<double> raw_camera_trans_y_;
+ std::vector<double> raw_camera_trans_z_;
+ std::vector<double> rotation_error_x_;
+ std::vector<double> rotation_error_y_;
+ std::vector<double> rotation_error_z_;
+ std::vector<double> translation_error_x_;
+ std::vector<double> translation_error_y_;
+ std::vector<double> translation_error_z_;
+ std::vector<Eigen::Vector3d> board_to_camera_rotations_;
+ std::vector<Eigen::Vector3d> board_to_camera_translations_;
- std::vector<double> world_gravity_x_;
- std::vector<double> world_gravity_y_;
- std::vector<double> world_gravity_z_;
- std::vector<double> imu_x_;
- std::vector<double> imu_y_;
- std::vector<double> imu_z_;
- std::vector<double> camera_position_x_;
- std::vector<double> camera_position_y_;
- std::vector<double> camera_position_z_;
+ std::vector<double> turret_angles_from_camera_;
+ std::vector<Eigen::Affine3d> imu_to_world_save_;
+
+ std::vector<double> imu_position_x_;
+ std::vector<double> imu_position_y_;
+ std::vector<double> imu_position_z_;
std::vector<double> imu_times_;
- std::vector<double> imu_ratex_;
- std::vector<double> imu_ratey_;
- std::vector<double> imu_ratez_;
+ std::vector<double> imu_rate_x_;
+ std::vector<double> imu_rate_y_;
+ std::vector<double> imu_rate_z_;
+ std::vector<double> accel_minus_gravity_x_;
+ std::vector<double> accel_minus_gravity_y_;
+ std::vector<double> accel_minus_gravity_z_;
+ std::vector<double> imu_accel_x_;
+ std::vector<double> imu_accel_y_;
+ std::vector<double> imu_accel_z_;
+
+ std::vector<double> turret_times_;
+ std::vector<double> turret_angles_;
std::vector<double> times_;
std::vector<Eigen::Matrix<double, 6, 1>> x_hats_;
@@ -549,6 +791,8 @@
const S *const pivot_to_imu_translation_ptr,
const S *const gravity_scalar_ptr,
const S *const accelerometer_bias_ptr, S *residual) const {
+ const aos::monotonic_clock::time_point start_time =
+ aos::monotonic_clock::now();
Eigen::Quaternion<S> initial_orientation(
initial_orientation_ptr[3], initial_orientation_ptr[0],
initial_orientation_ptr[1], initial_orientation_ptr[2]);
@@ -585,18 +829,32 @@
pivot_to_imu_translation, *gravity_scalar_ptr, accelerometer_bias);
data->ReviewData(&filter);
+ // Since the angular error scale is bounded by 1 (quaternion, so unit
+ // vector, scaled by sin(alpha)), I found it necessary to scale the
+ // angular error to have it properly balance with the translational error
+ double ang_error_scale = 5.0;
for (size_t i = 0; i < filter.num_errors(); ++i) {
- residual[3 * i + 0] = filter.errorx(i);
- residual[3 * i + 1] = filter.errory(i);
- residual[3 * i + 2] = filter.errorz(i);
+ residual[3 * i + 0] = ang_error_scale * filter.errorx(i);
+ residual[3 * i + 1] = ang_error_scale * filter.errory(i);
+ residual[3 * i + 2] = ang_error_scale * filter.errorz(i);
}
+ double trans_error_scale = 1.0;
for (size_t i = 0; i < filter.num_perrors(); ++i) {
- residual[3 * filter.num_errors() + 3 * i + 0] = filter.errorpx(i);
- residual[3 * filter.num_errors() + 3 * i + 1] = filter.errorpy(i);
- residual[3 * filter.num_errors() + 3 * i + 2] = filter.errorpz(i);
+ residual[3 * filter.num_errors() + 3 * i + 0] =
+ trans_error_scale * filter.errorpx(i);
+ residual[3 * filter.num_errors() + 3 * i + 1] =
+ trans_error_scale * filter.errorpy(i);
+ residual[3 * filter.num_errors() + 3 * i + 2] =
+ trans_error_scale * filter.errorpz(i);
}
+ LOG(INFO) << "Cost function calc took "
+ << chrono::duration<double>(aos::monotonic_clock::now() -
+ start_time)
+ .count()
+ << " seconds";
+
return true;
}
};
@@ -630,6 +888,8 @@
}
{
+ // The turret's Z rotation is redundant with the camera's mounting z
+ // rotation since it's along the rotation axis.
ceres::CostFunction *turret_z_cost_function =
new ceres::AutoDiffCostFunction<PenalizeQuaternionZ, 1, 4>(
new PenalizeQuaternionZ());
@@ -639,7 +899,8 @@
}
if (calibration_parameters->has_pivot) {
- // Constrain Z.
+ // Constrain Z since it's along the rotation axis and therefore
+ // redundant.
problem.SetParameterization(
calibration_parameters->pivot_to_imu_translation.data(),
new ceres::SubsetParameterization(3, {2}));
@@ -657,6 +918,9 @@
calibration_parameters->pivot_to_camera.coeffs().data(),
quaternion_local_parameterization);
problem.SetParameterization(
+ calibration_parameters->pivot_to_imu.coeffs().data(),
+ quaternion_local_parameterization);
+ problem.SetParameterization(
calibration_parameters->board_to_world.coeffs().data(),
quaternion_local_parameterization);
for (int i = 0; i < 3; ++i) {
@@ -678,40 +942,13 @@
ceres::Solver::Options options;
options.minimizer_progress_to_stdout = true;
options.gradient_tolerance = 1e-12;
- options.function_tolerance = 1e-16;
+ options.function_tolerance = 1e-6;
options.parameter_tolerance = 1e-12;
ceres::Solver::Summary summary;
Solve(options, &problem, &summary);
LOG(INFO) << summary.FullReport();
-
- LOG(INFO) << "initial_orientation "
- << calibration_parameters->initial_orientation.coeffs().transpose();
- LOG(INFO) << "pivot_to_imu "
- << calibration_parameters->pivot_to_imu.coeffs().transpose();
- LOG(INFO) << "pivot_to_imu(rotation) "
- << frc971::controls::ToRotationVectorFromQuaternion(
- calibration_parameters->pivot_to_imu)
- .transpose();
- LOG(INFO) << "pivot_to_camera "
- << calibration_parameters->pivot_to_camera.coeffs().transpose();
- LOG(INFO) << "pivot_to_camera(rotation) "
- << frc971::controls::ToRotationVectorFromQuaternion(
- calibration_parameters->pivot_to_camera)
- .transpose();
- LOG(INFO) << "gyro_bias " << calibration_parameters->gyro_bias.transpose();
- LOG(INFO) << "board_to_world "
- << calibration_parameters->board_to_world.coeffs().transpose();
- LOG(INFO) << "board_to_world(rotation) "
- << frc971::controls::ToRotationVectorFromQuaternion(
- calibration_parameters->board_to_world)
- .transpose();
- LOG(INFO) << "pivot_to_imu_translation "
- << calibration_parameters->pivot_to_imu_translation.transpose();
- LOG(INFO) << "pivot_to_camera_translation "
- << calibration_parameters->pivot_to_camera_translation.transpose();
- LOG(INFO) << "gravity " << kGravity * calibration_parameters->gravity_scalar;
- LOG(INFO) << "accelerometer bias "
- << calibration_parameters->accelerometer_bias.transpose();
+ LOG(INFO) << "Solution is " << (summary.IsSolutionUsable() ? "" : "NOT ")
+ << "usable";
}
void Plot(const CalibrationData &data,
@@ -730,5 +967,21 @@
filter.Plot();
}
+void Visualize(const CalibrationData &data,
+ const CalibrationParameters &calibration_parameters) {
+ PoseFilter filter(calibration_parameters.initial_orientation,
+ calibration_parameters.pivot_to_camera,
+ calibration_parameters.pivot_to_imu,
+ calibration_parameters.gyro_bias,
+ calibration_parameters.initial_state,
+ calibration_parameters.board_to_world,
+ calibration_parameters.pivot_to_camera_translation,
+ calibration_parameters.pivot_to_imu_translation,
+ calibration_parameters.gravity_scalar,
+ calibration_parameters.accelerometer_bias);
+ data.ReviewData(&filter);
+ filter.Visualize(calibration_parameters);
+}
+
} // namespace vision
} // namespace frc971
diff --git a/frc971/vision/extrinsics_calibration.h b/frc971/vision/extrinsics_calibration.h
index b24f13f..eb35482 100644
--- a/frc971/vision/extrinsics_calibration.h
+++ b/frc971/vision/extrinsics_calibration.h
@@ -42,6 +42,11 @@
void Plot(const CalibrationData &data,
const CalibrationParameters &calibration_parameters);
+// Shows the evolution of the calibration over time by visualizing relevant
+// coordinate frames in a virtual camera view
+void Visualize(const CalibrationData &data,
+ const CalibrationParameters &calibration_parameters);
+
} // namespace vision
} // namespace frc971
diff --git a/frc971/vision/target_map.fbs b/frc971/vision/target_map.fbs
new file mode 100644
index 0000000..50a9d7d
--- /dev/null
+++ b/frc971/vision/target_map.fbs
@@ -0,0 +1,27 @@
+namespace frc971.vision;
+
+// Represents 3d pose of an april tag on the field.
+table TargetPoseFbs {
+ // AprilTag ID of this target
+ id:uint64 (id: 0);
+
+ // Pose of target relative to field origin.
+ // NOTE: As of now, we only solve for the 2d pose (x, y, yaw)
+ // and all other values will be 0.
+ x:double (id: 1);
+ y:double (id: 2);
+ z:double (id: 3);
+
+ roll:double (id: 4);
+ pitch:double (id: 5);
+ yaw:double (id: 6);
+}
+
+// Map of all target poses on a field.
+// This would be solved for by TargetMapper
+table TargetMap {
+ target_poses:[TargetPoseFbs] (id: 0);
+
+ // Unique name of the field
+ field_name:string (id: 1);
+}
\ No newline at end of file
diff --git a/frc971/vision/target_mapper.cc b/frc971/vision/target_mapper.cc
new file mode 100644
index 0000000..ccaa805
--- /dev/null
+++ b/frc971/vision/target_mapper.cc
@@ -0,0 +1,362 @@
+#include "frc971/vision/target_mapper.h"
+
+#include "frc971/control_loops/control_loop.h"
+#include "frc971/vision/ceres/angle_local_parameterization.h"
+#include "frc971/vision/ceres/normalize_angle.h"
+#include "frc971/vision/ceres/pose_graph_2d_error_term.h"
+#include "frc971/vision/geometry.h"
+
+DEFINE_uint64(max_num_iterations, 100,
+ "Maximum number of iterations for the ceres solver");
+
+namespace frc971::vision {
+
+Eigen::Affine3d PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d pose2d) {
+ Eigen::Affine3d H_world_pose =
+ Eigen::Translation3d(pose2d.x, pose2d.y, 0.0) *
+ Eigen::AngleAxisd(pose2d.yaw_radians, Eigen::Vector3d::UnitZ());
+ return H_world_pose;
+}
+
+ceres::examples::Pose2d PoseUtils::Affine3dToPose2d(Eigen::Affine3d H) {
+ Eigen::Vector3d T = H.translation();
+ double heading = std::atan2(H.rotation()(1, 0), H.rotation()(0, 0));
+ return ceres::examples::Pose2d{T[0], T[1],
+ ceres::examples::NormalizeAngle(heading)};
+}
+
+ceres::examples::Pose2d PoseUtils::ComputeRelativePose(
+ ceres::examples::Pose2d pose_1, ceres::examples::Pose2d pose_2) {
+ Eigen::Affine3d H_world_1 = Pose2dToAffine3d(pose_1);
+ Eigen::Affine3d H_world_2 = Pose2dToAffine3d(pose_2);
+
+ // Get the location of 2 in the 1 frame
+ Eigen::Affine3d H_1_2 = H_world_1.inverse() * H_world_2;
+ return Affine3dToPose2d(H_1_2);
+}
+
+ceres::examples::Pose2d PoseUtils::ComputeOffsetPose(
+ ceres::examples::Pose2d pose_1, ceres::examples::Pose2d pose_2_relative) {
+ auto H_world_1 = Pose2dToAffine3d(pose_1);
+ auto H_1_2 = Pose2dToAffine3d(pose_2_relative);
+ auto H_world_2 = H_world_1 * H_1_2;
+
+ return Affine3dToPose2d(H_world_2);
+}
+
+namespace {
+double ExponentiatedSinTerm(double theta) {
+ return (theta == 0.0 ? 1.0 : std::sin(theta) / theta);
+}
+
+double ExponentiatedCosTerm(double theta) {
+ return (theta == 0.0 ? 0.0 : (1 - std::cos(theta)) / theta);
+}
+} // namespace
+
+ceres::examples::Pose2d DataAdapter::InterpolatePose(
+ const TimestampedPose &pose_start, const TimestampedPose &pose_end,
+ aos::distributed_clock::time_point time) {
+ auto delta_pose =
+ PoseUtils::ComputeRelativePose(pose_start.pose, pose_end.pose);
+ // Time from start of period, on the scale 0-1 where 1 is the end.
+ double interpolation_scalar =
+ static_cast<double>((time - pose_start.time).count()) /
+ static_cast<double>((pose_end.time - pose_start.time).count());
+
+ double theta = delta_pose.yaw_radians;
+ // Take the log of the transformation matrix:
+ // https://mathoverflow.net/questions/118533/how-to-compute-se2-group-exponential-and-logarithm
+ StdFormLine dx_line = {.a = ExponentiatedSinTerm(theta),
+ .b = -ExponentiatedCosTerm(theta),
+ .c = delta_pose.x};
+ StdFormLine dy_line = {.a = ExponentiatedCosTerm(theta),
+ .b = ExponentiatedSinTerm(theta),
+ .c = delta_pose.y};
+
+ std::optional<cv::Point2d> solution = dx_line.Intersection(dy_line);
+ CHECK(solution.has_value());
+
+ // Re-exponentiate with the new values scaled by the interpolation scalar to
+ // get an interpolated tranformation matrix
+ double a = solution->x * interpolation_scalar;
+ double b = solution->y * interpolation_scalar;
+ double alpha = theta * interpolation_scalar;
+
+ ceres::examples::Pose2d interpolated_pose = {
+ .x = a * ExponentiatedSinTerm(theta) - b * ExponentiatedCosTerm(theta),
+ .y = a * ExponentiatedCosTerm(theta) + b * ExponentiatedSinTerm(theta),
+ .yaw_radians = alpha};
+
+ return PoseUtils::ComputeOffsetPose(pose_start.pose, interpolated_pose);
+} // namespace frc971::vision
+
+std::pair<std::vector<ceres::examples::Constraint2d>,
+ std::vector<ceres::examples::Pose2d>>
+DataAdapter::MatchTargetDetections(
+ const std::vector<TimestampedPose> ×tamped_robot_poses,
+ const std::vector<TimestampedDetection> ×tamped_target_detections) {
+ // Interpolate robot poses
+ std::map<aos::distributed_clock::time_point, ceres::examples::Pose2d>
+ interpolated_poses;
+
+ CHECK_GT(timestamped_robot_poses.size(), 1ul)
+ << "Need more than 1 robot pose";
+ auto robot_pose_it = timestamped_robot_poses.begin();
+ for (const auto ×tamped_detection : timestamped_target_detections) {
+ aos::distributed_clock::time_point target_time = timestamped_detection.time;
+ // Find the robot point right before this localization
+ while (robot_pose_it->time > target_time ||
+ (robot_pose_it + 1)->time <= target_time) {
+ robot_pose_it++;
+ CHECK(robot_pose_it < timestamped_robot_poses.end() - 1)
+ << "Need a robot pose before and after every target detection";
+ }
+
+ auto start = robot_pose_it;
+ auto end = robot_pose_it + 1;
+ interpolated_poses.emplace(target_time,
+ InterpolatePose(*start, *end, target_time));
+ }
+
+ // Match consecutive detections
+ std::vector<ceres::examples::Constraint2d> target_constraints;
+ std::vector<ceres::examples::Pose2d> robot_delta_poses;
+
+ auto last_detection = timestamped_target_detections[0];
+ auto last_robot_pose =
+ interpolated_poses[timestamped_target_detections[0].time];
+
+ for (auto it = timestamped_target_detections.begin() + 1;
+ it < timestamped_target_detections.end(); it++) {
+ // Skip two consecutive detections of the same target, because the solver
+ // doesn't allow this
+ if (it->id == last_detection.id) {
+ continue;
+ }
+
+ auto robot_pose = interpolated_poses[it->time];
+ auto robot_delta_pose =
+ PoseUtils::ComputeRelativePose(last_robot_pose, robot_pose);
+ auto confidence = ComputeConfidence(last_detection.time, it->time);
+
+ target_constraints.emplace_back(ComputeTargetConstraint(
+ last_detection, PoseUtils::Pose2dToAffine3d(robot_delta_pose), *it,
+ confidence));
+ robot_delta_poses.emplace_back(robot_delta_pose);
+
+ last_detection = *it;
+ last_robot_pose = robot_pose;
+ }
+
+ return {target_constraints, robot_delta_poses};
+}
+
+Eigen::Matrix3d DataAdapter::ComputeConfidence(
+ aos::distributed_clock::time_point start,
+ aos::distributed_clock::time_point end) {
+ constexpr size_t kX = 0;
+ constexpr size_t kY = 1;
+ constexpr size_t kTheta = 2;
+
+ // Uncertainty matrix between start and end
+ Eigen::Matrix3d P = Eigen::Matrix3d::Zero();
+
+ {
+ // Noise for odometry-based robot position measurements
+ Eigen::Matrix3d Q_odometry = Eigen::Matrix3d::Zero();
+ Q_odometry(kX, kX) = std::pow(0.045, 2);
+ Q_odometry(kY, kY) = std::pow(0.045, 2);
+ Q_odometry(kTheta, kTheta) = std::pow(0.01, 2);
+
+ // Add uncertainty for robot position measurements from start to end
+ int iterations = (end - start) / frc971::controls::kLoopFrequency;
+ P += static_cast<double>(iterations) * Q_odometry;
+ }
+
+ {
+ // Noise for vision-based target localizations
+ Eigen::Matrix3d Q_vision = Eigen::Matrix3d::Zero();
+ Q_vision(kX, kX) = std::pow(0.09, 2);
+ Q_vision(kY, kY) = std::pow(0.09, 2);
+ Q_vision(kTheta, kTheta) = std::pow(0.02, 2);
+
+ // Add uncertainty for the 2 vision measurements (1 at start and 1 at end)
+ P += 2.0 * Q_vision;
+ }
+
+ return P.inverse();
+}
+
+ceres::examples::Constraint2d DataAdapter::ComputeTargetConstraint(
+ const TimestampedDetection &target_detection_start,
+ const Eigen::Affine3d &H_robotstart_robotend,
+ const TimestampedDetection &target_detection_end,
+ const Eigen::Matrix3d &confidence) {
+ // Compute the relative pose (constraint) between the two targets
+ Eigen::Affine3d H_targetstart_targetend =
+ target_detection_start.H_robot_target.inverse() * H_robotstart_robotend *
+ target_detection_end.H_robot_target;
+ ceres::examples::Pose2d target_constraint =
+ PoseUtils::Affine3dToPose2d(H_targetstart_targetend);
+
+ return ceres::examples::Constraint2d{
+ target_detection_start.id, target_detection_end.id,
+ target_constraint.x, target_constraint.y,
+ target_constraint.yaw_radians, confidence};
+}
+
+TargetMapper::TargetMapper(
+ std::string_view target_poses_path,
+ std::vector<ceres::examples::Constraint2d> target_constraints)
+ : target_constraints_(target_constraints) {
+ aos::FlatbufferDetachedBuffer<TargetMap> target_map =
+ aos::JsonFileToFlatbuffer<TargetMap>(target_poses_path);
+ for (const auto *target_pose_fbs : *target_map.message().target_poses()) {
+ target_poses_[target_pose_fbs->id()] = ceres::examples::Pose2d{
+ target_pose_fbs->x(), target_pose_fbs->y(), target_pose_fbs->yaw()};
+ }
+}
+
+TargetMapper::TargetMapper(
+ std::map<TargetId, ceres::examples::Pose2d> target_poses,
+ std::vector<ceres::examples::Constraint2d> target_constraints)
+ : target_poses_(target_poses), target_constraints_(target_constraints) {}
+
+std::optional<TargetMapper::TargetPose> TargetMapper::GetTargetPoseById(
+ std::vector<TargetMapper::TargetPose> target_poses, TargetId target_id) {
+ for (auto target_pose : target_poses) {
+ if (target_pose.id == target_id) {
+ return target_pose;
+ }
+ }
+
+ return std::nullopt;
+}
+
+// Taken from ceres/examples/slam/pose_graph_2d/pose_graph_2d.cc
+void TargetMapper::BuildOptimizationProblem(
+ std::map<int, ceres::examples::Pose2d> *poses,
+ const std::vector<ceres::examples::Constraint2d> &constraints,
+ ceres::Problem *problem) {
+ CHECK_NOTNULL(poses);
+ CHECK_NOTNULL(problem);
+ if (constraints.empty()) {
+ LOG(WARNING) << "No constraints, no problem to optimize.";
+ return;
+ }
+
+ ceres::LossFunction *loss_function = new ceres::HuberLoss(2.0);
+ ceres::LocalParameterization *angle_local_parameterization =
+ ceres::examples::AngleLocalParameterization::Create();
+
+ for (std::vector<ceres::examples::Constraint2d>::const_iterator
+ constraints_iter = constraints.begin();
+ constraints_iter != constraints.end(); ++constraints_iter) {
+ const ceres::examples::Constraint2d &constraint = *constraints_iter;
+
+ std::map<int, ceres::examples::Pose2d>::iterator pose_begin_iter =
+ poses->find(constraint.id_begin);
+ CHECK(pose_begin_iter != poses->end())
+ << "Pose with ID: " << constraint.id_begin << " not found.";
+ std::map<int, ceres::examples::Pose2d>::iterator pose_end_iter =
+ poses->find(constraint.id_end);
+ CHECK(pose_end_iter != poses->end())
+ << "Pose with ID: " << constraint.id_end << " not found.";
+
+ const Eigen::Matrix3d sqrt_information =
+ constraint.information.llt().matrixL();
+ // Ceres will take ownership of the pointer.
+ ceres::CostFunction *cost_function =
+ ceres::examples::PoseGraph2dErrorTerm::Create(
+ constraint.x, constraint.y, constraint.yaw_radians,
+ sqrt_information);
+ problem->AddResidualBlock(
+ cost_function, loss_function, &pose_begin_iter->second.x,
+ &pose_begin_iter->second.y, &pose_begin_iter->second.yaw_radians,
+ &pose_end_iter->second.x, &pose_end_iter->second.y,
+ &pose_end_iter->second.yaw_radians);
+
+ problem->SetParameterization(&pose_begin_iter->second.yaw_radians,
+ angle_local_parameterization);
+ problem->SetParameterization(&pose_end_iter->second.yaw_radians,
+ angle_local_parameterization);
+ }
+
+ // The pose graph optimization problem has three DOFs that are not fully
+ // constrained. This is typically referred to as gauge freedom. You can apply
+ // a rigid body transformation to all the nodes and the optimization problem
+ // will still have the exact same cost. The Levenberg-Marquardt algorithm has
+ // internal damping which mitigates this issue, but it is better to properly
+ // constrain the gauge freedom. This can be done by setting one of the poses
+ // as constant so the optimizer cannot change it.
+ std::map<int, ceres::examples::Pose2d>::iterator pose_start_iter =
+ poses->begin();
+ CHECK(pose_start_iter != poses->end()) << "There are no poses.";
+ problem->SetParameterBlockConstant(&pose_start_iter->second.x);
+ problem->SetParameterBlockConstant(&pose_start_iter->second.y);
+ problem->SetParameterBlockConstant(&pose_start_iter->second.yaw_radians);
+}
+
+// Taken from ceres/examples/slam/pose_graph_2d/pose_graph_2d.cc
+bool TargetMapper::SolveOptimizationProblem(ceres::Problem *problem) {
+ CHECK_NOTNULL(problem);
+
+ ceres::Solver::Options options;
+ options.max_num_iterations = FLAGS_max_num_iterations;
+ options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY;
+
+ ceres::Solver::Summary summary;
+ ceres::Solve(options, problem, &summary);
+
+ LOG(INFO) << summary.FullReport() << '\n';
+
+ return summary.IsSolutionUsable();
+}
+
+void TargetMapper::Solve(std::string_view field_name,
+ std::optional<std::string_view> output_dir) {
+ ceres::Problem problem;
+ BuildOptimizationProblem(&target_poses_, target_constraints_, &problem);
+
+ CHECK(SolveOptimizationProblem(&problem))
+ << "The solve was not successful, exiting.";
+
+ // TODO(milind): add origin to first target offset to all poses
+
+ auto map_json = MapToJson(field_name);
+ VLOG(1) << "Solved target poses: " << map_json;
+
+ if (output_dir.has_value()) {
+ std::string output_path =
+ absl::StrCat(output_dir.value(), "/", field_name, ".json");
+ LOG(INFO) << "Writing map to file: " << output_path;
+ aos::util::WriteStringToFileOrDie(output_path, map_json);
+ }
+}
+
+std::string TargetMapper::MapToJson(std::string_view field_name) const {
+ flatbuffers::FlatBufferBuilder fbb;
+
+ // Convert poses to flatbuffers
+ std::vector<flatbuffers::Offset<TargetPoseFbs>> target_poses_fbs;
+ for (const auto &[id, pose] : target_poses_) {
+ TargetPoseFbs::Builder target_pose_builder(fbb);
+ target_pose_builder.add_id(id);
+ target_pose_builder.add_x(id);
+ target_pose_builder.add_y(id);
+ target_pose_builder.add_yaw(id);
+
+ target_poses_fbs.emplace_back(target_pose_builder.Finish());
+ }
+
+ const auto field_name_offset = fbb.CreateString(field_name);
+ flatbuffers::Offset<TargetMap> target_map_offset = CreateTargetMap(
+ fbb, fbb.CreateVector(target_poses_fbs), field_name_offset);
+
+ return aos::FlatbufferToJson(
+ flatbuffers::GetMutableTemporaryPointer(fbb, target_map_offset),
+ {.multi_line = true});
+}
+
+} // namespace frc971::vision
diff --git a/frc971/vision/target_mapper.h b/frc971/vision/target_mapper.h
new file mode 100644
index 0000000..4dbe52b
--- /dev/null
+++ b/frc971/vision/target_mapper.h
@@ -0,0 +1,144 @@
+#ifndef FRC971_VISION_TARGET_MAPPER_H_
+#define FRC971_VISION_TARGET_MAPPER_H_
+
+#include <unordered_map>
+
+#include "aos/events/simulated_event_loop.h"
+#include "frc971/vision/ceres/types.h"
+#include "frc971/vision/target_map_generated.h"
+
+namespace frc971::vision {
+
+// Estimates positions of vision targets (ex. April Tags) using
+// target detections relative to a robot (which were computed using robot
+// positions at the time of those detections). Solves SLAM problem to estimate
+// target locations using deltas between consecutive target detections.
+class TargetMapper {
+ public:
+ using TargetId = int;
+
+ struct TargetPose {
+ TargetId id;
+ // TOOD(milind): switch everything to 3d once we're more confident in 2d
+ // solving
+ ceres::examples::Pose2d pose;
+ };
+
+ // target_poses_path is the path to a TargetMap json with initial guesses for
+ // the actual locations of the targets on the field.
+ // target_constraints are the deltas between consecutive target detections,
+ // and are usually prepared by the DataAdapter class below.
+ TargetMapper(std::string_view target_poses_path,
+ std::vector<ceres::examples::Constraint2d> target_constraints);
+ // Alternate constructor for tests.
+ // Takes in the actual intial guesses instead of a file containing them
+ TargetMapper(std::map<TargetId, ceres::examples::Pose2d> target_poses,
+ std::vector<ceres::examples::Constraint2d> target_constraints);
+
+ // Solves for the target map. If output_dir is set, the map will be saved to
+ // output_dir/field_name.json
+ void Solve(std::string_view field_name,
+ std::optional<std::string_view> output_dir = std::nullopt);
+
+ // Prints target poses into a TargetMap flatbuffer json
+ std::string MapToJson(std::string_view field_name) const;
+
+ static std::optional<TargetPose> GetTargetPoseById(
+ std::vector<TargetPose> target_poses, TargetId target_id);
+
+ std::map<TargetId, ceres::examples::Pose2d> target_poses() {
+ return target_poses_;
+ }
+
+ private:
+ // Constructs the nonlinear least squares optimization problem from the
+ // pose graph constraints.
+ void BuildOptimizationProblem(
+ std::map<TargetId, ceres::examples::Pose2d> *target_poses,
+ const std::vector<ceres::examples::Constraint2d> &constraints,
+ ceres::Problem *problem);
+
+ // Returns true if the solve was successful.
+ bool SolveOptimizationProblem(ceres::Problem *problem);
+
+ std::map<TargetId, ceres::examples::Pose2d> target_poses_;
+ std::vector<ceres::examples::Constraint2d> target_constraints_;
+};
+
+// Utility functions for dealing with ceres::examples::Pose2d structs
+class PoseUtils {
+ public:
+ // Embeds a 2d pose into a 3d affine transformation to be used in 3d
+ // computation
+ static Eigen::Affine3d Pose2dToAffine3d(ceres::examples::Pose2d pose2d);
+ // Assumes only x and y translation, and only z rotation (yaw)
+ static ceres::examples::Pose2d Affine3dToPose2d(Eigen::Affine3d H);
+
+ // Computes pose_2 relative to pose_1. This is equivalent to (pose_1^-1 *
+ // pose_2)
+ static ceres::examples::Pose2d ComputeRelativePose(
+ ceres::examples::Pose2d pose_1, ceres::examples::Pose2d pose_2);
+
+ // Computes pose_2 given a pose_1 and pose_2 relative to pose_1. This is
+ // equivalent to (pose_1 * pose_2_relative)
+ static ceres::examples::Pose2d ComputeOffsetPose(
+ ceres::examples::Pose2d pose_1, ceres::examples::Pose2d pose_2_relative);
+};
+
+// Transforms robot position and target detection data into target constraints
+// to be used for mapping. Interpolates continous-time data, converting it to
+// discrete detection time steps.
+class DataAdapter {
+ public:
+ // Pairs pose with a time point
+ struct TimestampedPose {
+ aos::distributed_clock::time_point time;
+ ceres::examples::Pose2d pose;
+ };
+
+ // Pairs target detection with a time point
+ struct TimestampedDetection {
+ aos::distributed_clock::time_point time;
+ // Pose of target relative to robot
+ Eigen::Affine3d H_robot_target;
+ TargetMapper::TargetId id;
+ };
+
+ // Pairs consecutive target detections into constraints, and interpolates
+ // robot poses based on time points to compute motion between detections. This
+ // prepares data to be used by TargetMapper. Also returns vector of delta
+ // robot poses corresponding to each constraint, to be used for testing.
+ //
+ // Assumes both inputs are in chronological order.
+ static std::pair<std::vector<ceres::examples::Constraint2d>,
+ std::vector<ceres::examples::Pose2d>>
+ MatchTargetDetections(
+ const std::vector<TimestampedPose> ×tamped_robot_poses,
+ const std::vector<TimestampedDetection> ×tamped_target_detections);
+
+ // Computes inverse of covariance matrix, assuming there was a target
+ // detection between robot movement over the given time period. Ceres calls
+ // this matrix the "information"
+ static Eigen::Matrix3d ComputeConfidence(
+ aos::distributed_clock::time_point start,
+ aos::distributed_clock::time_point end);
+
+ private:
+ static ceres::examples::Pose2d InterpolatePose(
+ const TimestampedPose &pose_start, const TimestampedPose &pose_end,
+ aos::distributed_clock::time_point time);
+
+ // Computes the constraint between the start and end pose of the targets: the
+ // relative pose between the start and end target locations in the frame of
+ // the start target. Takes into account the robot motion in the time between
+ // the two detections.
+ static ceres::examples::Constraint2d ComputeTargetConstraint(
+ const TimestampedDetection &target_detection_start,
+ const Eigen::Affine3d &H_robotstart_robotend,
+ const TimestampedDetection &target_detection_end,
+ const Eigen::Matrix3d &confidence);
+};
+
+} // namespace frc971::vision
+
+#endif // FRC971_VISION_TARGET_MAPPER_H_
diff --git a/frc971/vision/target_mapper_test.cc b/frc971/vision/target_mapper_test.cc
new file mode 100644
index 0000000..f56cd8d
--- /dev/null
+++ b/frc971/vision/target_mapper_test.cc
@@ -0,0 +1,414 @@
+#include "frc971/vision/target_mapper.h"
+
+#include <random>
+
+#include "aos/events/simulated_event_loop.h"
+#include "aos/testing/random_seed.h"
+#include "glog/logging.h"
+#include "gtest/gtest.h"
+
+namespace frc971::vision {
+
+namespace {
+constexpr double kToleranceMeters = 0.05;
+constexpr double kToleranceRadians = 0.05;
+constexpr std::string_view kFieldName = "test";
+} // namespace
+
+#define EXPECT_POSE_NEAR(pose1, pose2) \
+ EXPECT_NEAR(pose1.x, pose2.x, kToleranceMeters); \
+ EXPECT_NEAR(pose1.y, pose2.y, kToleranceMeters); \
+ EXPECT_NEAR(pose1.yaw_radians, pose2.yaw_radians, kToleranceRadians);
+
+#define EXPECT_POSE_EQ(pose1, pose2) \
+ EXPECT_DOUBLE_EQ(pose1.x, pose2.x); \
+ EXPECT_DOUBLE_EQ(pose1.y, pose2.y); \
+ EXPECT_DOUBLE_EQ(pose1.yaw_radians, pose2.yaw_radians);
+
+#define EXPECT_BETWEEN_EXCLUSIVE(value, a, b) \
+ { \
+ auto low = std::min(a, b); \
+ auto high = std::max(a, b); \
+ EXPECT_GT(value, low); \
+ EXPECT_LT(value, high); \
+ }
+
+namespace {
+// Expects angles to be normalized
+double DeltaAngle(double a, double b) {
+ double delta = std::abs(a - b);
+ return std::min(delta, (2.0 * M_PI) - delta);
+}
+} // namespace
+
+// Expects angles to be normalized
+#define EXPECT_ANGLE_BETWEEN_EXCLUSIVE(theta, a, b) \
+ EXPECT_LT(DeltaAngle(a, theta), DeltaAngle(a, b)); \
+ EXPECT_LT(DeltaAngle(b, theta), DeltaAngle(a, b));
+
+#define EXPECT_POSE_IN_RANGE(interpolated_pose, pose_start, pose_end) \
+ EXPECT_BETWEEN_EXCLUSIVE(interpolated_pose.x, pose_start.x, pose_end.x); \
+ EXPECT_BETWEEN_EXCLUSIVE(interpolated_pose.y, pose_start.y, pose_end.y); \
+ EXPECT_ANGLE_BETWEEN_EXCLUSIVE(interpolated_pose.yaw_radians, \
+ pose_start.yaw_radians, \
+ pose_end.yaw_radians);
+
+// Both confidence matrixes should have the same dimensions and be square
+#define EXPECT_CONFIDENCE_GT(confidence1, confidence2) \
+ { \
+ ASSERT_EQ(confidence1.rows(), confidence2.rows()); \
+ ASSERT_EQ(confidence1.rows(), confidence1.cols()); \
+ ASSERT_EQ(confidence2.rows(), confidence2.cols()); \
+ for (size_t i = 0; i < confidence1.rows(); i++) { \
+ EXPECT_GT(confidence1(i, i), confidence2(i, i)); \
+ } \
+ }
+
+namespace {
+ceres::examples::Pose2d MakePose(double x, double y, double yaw_radians) {
+ return ceres::examples::Pose2d{x, y, yaw_radians};
+}
+
+bool TargetIsInView(TargetMapper::TargetPose target_detection) {
+ // And check if it is within the fov of the robot /
+ // camera, assuming camera is pointing in the
+ // positive x-direction of the robot
+ double angle_to_target =
+ atan2(target_detection.pose.y, target_detection.pose.x);
+
+ // Simulated camera field of view, in radians
+ constexpr double kCameraFov = M_PI_2;
+ if (fabs(angle_to_target) <= kCameraFov / 2.0) {
+ VLOG(2) << "Found target in view, based on T = " << target_detection.pose.x
+ << ", " << target_detection.pose.y << " with angle "
+ << angle_to_target;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+aos::distributed_clock::time_point TimeInMs(size_t ms) {
+ return aos::distributed_clock::time_point(std::chrono::milliseconds(ms));
+}
+
+} // namespace
+
+TEST(DataAdapterTest, Interpolation) {
+ std::vector<DataAdapter::TimestampedPose> timestamped_robot_poses = {
+ {TimeInMs(0), ceres::examples::Pose2d{1.0, 2.0, 0.0}},
+ {TimeInMs(5), ceres::examples::Pose2d{1.0, 2.0, 0.0}},
+ {TimeInMs(10), ceres::examples::Pose2d{3.0, 1.0, M_PI_2}},
+ {TimeInMs(15), ceres::examples::Pose2d{5.0, -2.0, -M_PI}},
+ {TimeInMs(20), ceres::examples::Pose2d{5.0, -2.0, -M_PI}},
+ {TimeInMs(25), ceres::examples::Pose2d{10.0, -32.0, M_PI_2}},
+ {TimeInMs(30), ceres::examples::Pose2d{-15.0, 12.0, 0.0}},
+ {TimeInMs(35), ceres::examples::Pose2d{-15.0, 12.0, 0.0}}};
+ std::vector<DataAdapter::TimestampedDetection> timestamped_target_detections =
+ {{TimeInMs(5),
+ PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d{5.0, -4.0, 0.0}),
+ 0},
+ {TimeInMs(9),
+ PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d{5.0, -4.0, 0.0}),
+ 1},
+ {TimeInMs(9),
+ PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d{5.0, -4.0, 0.0}),
+ 2},
+ {TimeInMs(15),
+ PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d{5.0, -4.0, 0.0}),
+ 0},
+ {TimeInMs(16),
+ PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d{5.0, -4.0, 0.0}),
+ 2},
+ {TimeInMs(27),
+ PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d{5.0, -4.0, 0.0}),
+ 1}};
+ auto [target_constraints, robot_delta_poses] =
+ DataAdapter::MatchTargetDetections(timestamped_robot_poses,
+ timestamped_target_detections);
+
+ // Check that target constraints got inserted in the
+ // correct spots
+ EXPECT_EQ(target_constraints.size(),
+ timestamped_target_detections.size() - 1);
+ for (auto it = target_constraints.begin(); it < target_constraints.end();
+ it++) {
+ auto timestamped_it = timestamped_target_detections.begin() +
+ (it - target_constraints.begin());
+ EXPECT_EQ(it->id_begin, timestamped_it->id);
+ EXPECT_EQ(it->id_end, (timestamped_it + 1)->id);
+ }
+
+ // Check that poses were interpolated correctly.
+ // Keep track of the computed robot pose by adding the delta poses
+ auto computed_robot_pose = timestamped_robot_poses[1].pose;
+
+ computed_robot_pose =
+ PoseUtils::ComputeOffsetPose(computed_robot_pose, robot_delta_poses[0]);
+ EXPECT_POSE_IN_RANGE(computed_robot_pose, timestamped_robot_poses[1].pose,
+ timestamped_robot_poses[2].pose);
+
+ computed_robot_pose =
+ PoseUtils::ComputeOffsetPose(computed_robot_pose, robot_delta_poses[1]);
+ EXPECT_POSE_IN_RANGE(computed_robot_pose, timestamped_robot_poses[1].pose,
+ timestamped_robot_poses[2].pose);
+ EXPECT_POSE_EQ(robot_delta_poses[1], MakePose(0.0, 0.0, 0.0));
+
+ computed_robot_pose =
+ PoseUtils::ComputeOffsetPose(computed_robot_pose, robot_delta_poses[2]);
+ EXPECT_POSE_EQ(computed_robot_pose, timestamped_robot_poses[3].pose);
+
+ computed_robot_pose =
+ PoseUtils::ComputeOffsetPose(computed_robot_pose, robot_delta_poses[3]);
+ EXPECT_POSE_EQ(computed_robot_pose, timestamped_robot_poses[4].pose);
+
+ computed_robot_pose =
+ PoseUtils::ComputeOffsetPose(computed_robot_pose, robot_delta_poses[4]);
+ EXPECT_POSE_IN_RANGE(computed_robot_pose, timestamped_robot_poses[5].pose,
+ timestamped_robot_poses[6].pose);
+
+ // Check the confidence matrices. Don't check the actual values
+ // in case the constants change, just check the confidence of contraints
+ // relative to each other, as constraints over longer time periods should have
+ // lower confidence.
+ const auto confidence_0ms =
+ DataAdapter::ComputeConfidence(TimeInMs(0), TimeInMs(0));
+ const auto confidence_1ms =
+ DataAdapter::ComputeConfidence(TimeInMs(0), TimeInMs(1));
+ const auto confidence_4ms =
+ DataAdapter::ComputeConfidence(TimeInMs(0), TimeInMs(4));
+ const auto confidence_6ms =
+ DataAdapter::ComputeConfidence(TimeInMs(0), TimeInMs(6));
+ const auto confidence_11ms =
+ DataAdapter::ComputeConfidence(TimeInMs(0), TimeInMs(11));
+
+ // Check relative magnitude of different confidences.
+ // Confidences for 0-5ms, 5-10ms, and 10-15ms periods are equal
+ // because they fit within one control loop iteration.
+ EXPECT_EQ(confidence_0ms, confidence_1ms);
+ EXPECT_EQ(confidence_1ms, confidence_4ms);
+ EXPECT_CONFIDENCE_GT(confidence_4ms, confidence_6ms);
+ EXPECT_CONFIDENCE_GT(confidence_6ms, confidence_11ms);
+
+ // Check that confidences (information) of actual constraints are correct
+ EXPECT_EQ(target_constraints[0].information, confidence_4ms);
+ EXPECT_EQ(target_constraints[1].information, confidence_0ms);
+ EXPECT_EQ(target_constraints[2].information, confidence_6ms);
+ EXPECT_EQ(target_constraints[3].information, confidence_1ms);
+ EXPECT_EQ(target_constraints[4].information, confidence_11ms);
+}
+
+TEST(TargetMapperTest, TwoTargetsOneConstraint) {
+ std::map<TargetMapper::TargetId, ceres::examples::Pose2d> target_poses;
+ target_poses[0] = ceres::examples::Pose2d{5.0, 0.0, M_PI};
+ target_poses[1] = ceres::examples::Pose2d{-5.0, 0.0, 0.0};
+
+ std::vector<DataAdapter::TimestampedPose> timestamped_robot_poses = {
+ {TimeInMs(5), ceres::examples::Pose2d{2.0, 0.0, 0.0}},
+ {TimeInMs(10), ceres::examples::Pose2d{-1.0, 0.0, 0.0}},
+ {TimeInMs(15), ceres::examples::Pose2d{-1.0, 0.0, 0.0}}};
+ std::vector<DataAdapter::TimestampedDetection> timestamped_target_detections =
+ {{TimeInMs(5),
+ PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d{3.0, 0.0, M_PI}),
+ 0},
+ {TimeInMs(10),
+ PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d{-4.0, 0.0, 0.0}),
+ 1}};
+ auto target_constraints =
+ DataAdapter::MatchTargetDetections(timestamped_robot_poses,
+ timestamped_target_detections)
+ .first;
+
+ frc971::vision::TargetMapper mapper(target_poses, target_constraints);
+ mapper.Solve(kFieldName);
+
+ ASSERT_EQ(mapper.target_poses().size(), 2);
+ EXPECT_POSE_NEAR(mapper.target_poses()[0], MakePose(5.0, 0.0, M_PI));
+ EXPECT_POSE_NEAR(mapper.target_poses()[1], MakePose(-5.0, 0.0, 0.0));
+}
+
+TEST(TargetMapperTest, TwoTargetsTwoConstraints) {
+ std::map<TargetMapper::TargetId, ceres::examples::Pose2d> target_poses;
+ target_poses[0] = ceres::examples::Pose2d{5.0, 0.0, M_PI};
+ target_poses[1] = ceres::examples::Pose2d{-5.0, 0.0, -M_PI_2};
+
+ std::vector<DataAdapter::TimestampedPose> timestamped_robot_poses = {
+ {TimeInMs(5), ceres::examples::Pose2d{-1.0, 0.0, 0.0}},
+ {TimeInMs(10), ceres::examples::Pose2d{3.0, 0.0, 0.0}},
+ {TimeInMs(15), ceres::examples::Pose2d{4.0, 0.0, 0.0}},
+ {TimeInMs(20), ceres::examples::Pose2d{-1.0, 0.0, 0.0}}};
+ std::vector<DataAdapter::TimestampedDetection> timestamped_target_detections =
+ {{TimeInMs(5),
+ PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d{6.0, 0.0, M_PI}),
+ 0},
+ {TimeInMs(10),
+ PoseUtils::Pose2dToAffine3d(
+ ceres::examples::Pose2d{-8.0, 0.0, -M_PI_2}),
+ 1},
+ {TimeInMs(15),
+ PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d{1.0, 0.0, M_PI}),
+ 0}};
+ auto target_constraints =
+ DataAdapter::MatchTargetDetections(timestamped_robot_poses,
+ timestamped_target_detections)
+ .first;
+
+ frc971::vision::TargetMapper mapper(target_poses, target_constraints);
+ mapper.Solve(kFieldName);
+
+ ASSERT_EQ(mapper.target_poses().size(), 2);
+ EXPECT_POSE_NEAR(mapper.target_poses()[0], MakePose(5.0, 0.0, M_PI));
+ EXPECT_POSE_NEAR(mapper.target_poses()[1], MakePose(-5.0, 0.0, -M_PI_2));
+}
+
+TEST(TargetMapperTest, TwoTargetsOneNoisyConstraint) {
+ std::map<TargetMapper::TargetId, ceres::examples::Pose2d> target_poses;
+ target_poses[0] = ceres::examples::Pose2d{5.0, 0.0, M_PI};
+ target_poses[1] = ceres::examples::Pose2d{-5.0, 0.0, 0.0};
+
+ std::vector<DataAdapter::TimestampedPose> timestamped_robot_poses = {
+ {TimeInMs(5), ceres::examples::Pose2d{1.99, 0.0, 0.0}},
+ {TimeInMs(10), ceres::examples::Pose2d{-1.0, 0.0, 0.0}},
+ {TimeInMs(15), ceres::examples::Pose2d{-1.01, -0.01, 0.004}}};
+ std::vector<DataAdapter::TimestampedDetection> timestamped_target_detections =
+ {{TimeInMs(5),
+ PoseUtils::Pose2dToAffine3d(
+ ceres::examples::Pose2d{3.01, 0.001, M_PI - 0.001}),
+ 0},
+ {TimeInMs(10),
+ PoseUtils::Pose2dToAffine3d(ceres::examples::Pose2d{-4.01, 0.0, 0.0}),
+ 1}};
+
+ auto target_constraints =
+ DataAdapter::MatchTargetDetections(timestamped_robot_poses,
+ timestamped_target_detections)
+ .first;
+
+ frc971::vision::TargetMapper mapper(target_poses, target_constraints);
+ mapper.Solve(kFieldName);
+
+ ASSERT_EQ(mapper.target_poses().size(), 2);
+ EXPECT_POSE_NEAR(mapper.target_poses()[0], MakePose(5.0, 0.0, M_PI));
+ EXPECT_POSE_NEAR(mapper.target_poses()[1], MakePose(-5.0, 0.0, 0.0));
+}
+
+TEST(TargetMapperTest, MultiTargetCircleMotion) {
+ // Build set of target locations wrt global origin
+ // For simplicity, do this on a grid of the field
+ double field_half_length = 7.5; // half length of the field
+ double field_half_width = 5.0; // half width of the field
+ std::map<TargetMapper::TargetId, ceres::examples::Pose2d> target_poses;
+ std::vector<TargetMapper::TargetPose> actual_target_poses;
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ TargetMapper::TargetId target_id = i * 3 + j;
+ TargetMapper::TargetPose target_pose{
+ target_id, ceres::examples::Pose2d{field_half_length * (1 - i),
+ field_half_width * (1 - j), 0.0}};
+ actual_target_poses.emplace_back(target_pose);
+ target_poses[target_id] = target_pose.pose;
+ VLOG(2) << "VERTEX_SE2 " << target_id << " " << target_pose.pose.x << " "
+ << target_pose.pose.y << " " << target_pose.pose.yaw_radians;
+ }
+ }
+
+ // Now, create a bunch of robot poses and target
+ // observations
+ size_t dt = 1;
+
+ std::vector<DataAdapter::TimestampedPose> timestamped_robot_poses;
+ std::vector<DataAdapter::TimestampedDetection> timestamped_target_detections;
+
+ constexpr size_t kTotalSteps = 100;
+ for (size_t step_count = 0; step_count < kTotalSteps; step_count++) {
+ size_t t = dt * step_count;
+ // Circle clockwise around the center of the field
+ double robot_theta = t;
+ double robot_x = (field_half_length / 2.0) * cos(robot_theta);
+ double robot_y = (-field_half_width / 2.0) * sin(robot_theta);
+
+ ceres::examples::Pose2d robot_pose{robot_x, robot_y, robot_theta};
+ for (TargetMapper::TargetPose target_pose : actual_target_poses) {
+ TargetMapper::TargetPose target_detection = {
+ .id = target_pose.id,
+ .pose = PoseUtils::ComputeRelativePose(robot_pose, target_pose.pose)};
+ if (TargetIsInView(target_detection)) {
+ // Define random generator with Gaussian
+ // distribution
+ const double mean = 0.0;
+ const double stddev = 1.0;
+ // Can play with this to see how it impacts
+ // randomness
+ constexpr double kNoiseScale = 0.01;
+ std::default_random_engine generator(aos::testing::RandomSeed());
+ std::normal_distribution<double> dist(mean, stddev);
+
+ target_detection.pose.x += dist(generator) * kNoiseScale;
+ target_detection.pose.y += dist(generator) * kNoiseScale;
+ robot_pose.x += dist(generator) * kNoiseScale;
+ robot_pose.y += dist(generator) * kNoiseScale;
+
+ auto time_point =
+ aos::distributed_clock::time_point(std::chrono::milliseconds(t));
+ timestamped_robot_poses.emplace_back(DataAdapter::TimestampedPose{
+ .time = time_point, .pose = robot_pose});
+ timestamped_target_detections.emplace_back(
+ DataAdapter::TimestampedDetection{
+ .time = time_point,
+ .H_robot_target =
+ PoseUtils::Pose2dToAffine3d(target_detection.pose),
+ .id = target_detection.id});
+ }
+ }
+ }
+
+ {
+ // Add in a robot pose after all target poses
+ auto final_robot_pose =
+ timestamped_robot_poses[timestamped_robot_poses.size() - 1];
+ timestamped_robot_poses.emplace_back(DataAdapter::TimestampedPose{
+ .time = final_robot_pose.time + std::chrono::milliseconds(dt),
+ .pose = final_robot_pose.pose});
+ }
+
+ auto target_constraints =
+ DataAdapter::MatchTargetDetections(timestamped_robot_poses,
+ timestamped_target_detections)
+ .first;
+ frc971::vision::TargetMapper mapper(target_poses, target_constraints);
+ mapper.Solve(kFieldName);
+
+ for (auto [target_pose_id, mapper_target_pose] : mapper.target_poses()) {
+ TargetMapper::TargetPose actual_target_pose =
+ TargetMapper::GetTargetPoseById(actual_target_poses, target_pose_id)
+ .value();
+ EXPECT_POSE_NEAR(mapper_target_pose, actual_target_pose.pose);
+ }
+
+ //
+ // See what happens when we don't start with the
+ // correct values
+ //
+ for (auto [target_id, target_pose] : target_poses) {
+ // Skip first pose, since that needs to be correct
+ // and is fixed in the solver
+ if (target_id != 0) {
+ ceres::examples::Pose2d bad_pose{0.0, 0.0, M_PI / 2.0};
+ target_poses[target_id] = bad_pose;
+ }
+ }
+
+ frc971::vision::TargetMapper mapper_bad_poses(target_poses,
+ target_constraints);
+ mapper_bad_poses.Solve(kFieldName);
+
+ for (auto [target_pose_id, mapper_target_pose] :
+ mapper_bad_poses.target_poses()) {
+ TargetMapper::TargetPose actual_target_pose =
+ TargetMapper::GetTargetPoseById(actual_target_poses, target_pose_id)
+ .value();
+ EXPECT_POSE_NEAR(mapper_target_pose, actual_target_pose.pose);
+ }
+}
+
+} // namespace frc971::vision
diff --git a/frc971/vision/visualize_robot.cc b/frc971/vision/visualize_robot.cc
new file mode 100644
index 0000000..0bbe507
--- /dev/null
+++ b/frc971/vision/visualize_robot.cc
@@ -0,0 +1,74 @@
+#include "frc971/vision/visualize_robot.h"
+#include "glog/logging.h"
+
+#include <opencv2/calib3d.hpp>
+#include <opencv2/core/eigen.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <opencv2/imgproc.hpp>
+
+namespace frc971 {
+namespace vision {
+
+cv::Point VisualizeRobot::ProjectPoint(Eigen::Vector3d T_world_point) {
+ // Map 3D point in world coordinates to camera frame
+ Eigen::Vector3d T_camera_point = H_world_viewpoint_.inverse() * T_world_point;
+
+ cv::Vec3d T_camera_point_cv;
+ cv::eigen2cv(T_camera_point, T_camera_point_cv);
+
+ // Project 3d point in camera frame via camera intrinsics
+ cv::Mat proj_point = camera_mat_ * cv::Mat(T_camera_point_cv);
+ cv::Point projected_point(
+ proj_point.at<double>(0, 0) / proj_point.at<double>(0, 2),
+ proj_point.at<double>(0, 1) / proj_point.at<double>(0, 2));
+ return projected_point;
+}
+
+void VisualizeRobot::DrawLine(Eigen::Vector3d start3d, Eigen::Vector3d end3d) {
+ cv::Point start2d = ProjectPoint(start3d);
+ cv::Point end2d = ProjectPoint(end3d);
+
+ cv::line(image_, start2d, end2d, cv::Scalar(0, 0, 255));
+}
+
+void VisualizeRobot::DrawFrameAxes(Eigen::Affine3d H_world_target,
+ std::string label, double axis_scale) {
+ // Map origin to display from global (world) frame to camera frame
+ Eigen::Affine3d H_viewpoint_target =
+ H_world_viewpoint_.inverse() * H_world_target;
+
+ // Extract into OpenCV vectors
+ cv::Mat H_viewpoint_target_mat;
+ cv::eigen2cv(H_viewpoint_target.matrix(), H_viewpoint_target_mat);
+
+ // Convert to opencv R, T for using drawFrameAxes
+ cv::Vec3d rvec, tvec;
+ tvec = H_viewpoint_target_mat(cv::Rect(3, 0, 1, 3));
+ cv::Mat r_mat = H_viewpoint_target_mat(cv::Rect(0, 0, 3, 3));
+ cv::Rodrigues(r_mat, rvec);
+
+ cv::drawFrameAxes(image_, camera_mat_, dist_coeffs_, rvec, tvec, axis_scale);
+
+ if (label != "") {
+ // Grab x axis direction
+ cv::Vec3d label_offset = r_mat.col(0);
+
+ // Find 3D coordinate of point at the end of the x-axis, and project it
+ cv::Mat label_coord_res =
+ camera_mat_ * cv::Mat(tvec + label_offset * axis_scale);
+ cv::Vec3d label_coord = label_coord_res.col(0);
+ label_coord[0] = label_coord[0] / label_coord[2];
+ label_coord[1] = label_coord[1] / label_coord[2];
+ cv::putText(image_, label, cv::Point(label_coord[0], label_coord[1]),
+ cv::FONT_HERSHEY_PLAIN, 1.0, cv::Scalar(0, 0, 255));
+ }
+}
+
+void VisualizeRobot::DrawBoardOutline(Eigen::Affine3d H_world_board,
+ std::string label) {
+ LOG(INFO) << "Not yet implemented; drawing axes only";
+ DrawFrameAxes(H_world_board, label);
+}
+
+} // namespace vision
+} // namespace frc971
diff --git a/frc971/vision/visualize_robot.h b/frc971/vision/visualize_robot.h
new file mode 100644
index 0000000..391a030
--- /dev/null
+++ b/frc971/vision/visualize_robot.h
@@ -0,0 +1,65 @@
+#ifndef FRC971_VISION_VISUALIZE_ROBOT_H_
+#define FRC971_VISION_VISUALIZE_ROBOT_H_
+
+#include <opencv2/core.hpp>
+#include <opencv2/highgui.hpp>
+#include <opencv2/imgproc.hpp>
+
+#include "Eigen/Dense"
+#include "Eigen/Geometry"
+
+namespace frc971 {
+namespace vision {
+
+// Helper class to visualize the coordinate frames associated with
+// the robot Based on a virtual camera viewpoint, and camera model,
+// this class can be used to draw 3D coordinate frames in a virtual
+// camera view.
+//
+// Mostly useful just for doing all the projection calculations
+// Leverages Eigen for transforms and opencv for drawing axes
+
+class VisualizeRobot {
+ public:
+ // Set image on which to draw
+ void SetImage(cv::Mat image) { image_ = image; }
+
+ // Set the viewpoint of the camera relative to a global origin
+ void SetViewpoint(Eigen::Affine3d view_origin) {
+ H_world_viewpoint_ = view_origin;
+ }
+
+ // Set camera parameters (for projection into a virtual view)
+ void SetCameraParameters(cv::Mat camera_intrinsics) {
+ camera_mat_ = camera_intrinsics;
+ }
+
+ // Set distortion coefficients (defaults to 0)
+ void SetDistortionCoefficients(cv::Mat dist_coeffs) {
+ dist_coeffs_ = dist_coeffs;
+ }
+
+ // Helper function to project a point in 3D to the virtual image coordinates
+ cv::Point ProjectPoint(Eigen::Vector3d point3d);
+
+ // Draw a line connecting two 3D points
+ void DrawLine(Eigen::Vector3d start, Eigen::Vector3d end);
+
+ // Draw coordinate frame for a target frame relative to the world frame
+ // Axes are drawn (x,y,z) -> (red, green, blue)
+ void DrawFrameAxes(Eigen::Affine3d H_world_target, std::string label = "",
+ double axis_scale = 0.25);
+
+ // TODO<Jim>: Need to implement this, and maybe DrawRobotOutline
+ void DrawBoardOutline(Eigen::Affine3d H_world_board, std::string label = "");
+
+ Eigen::Affine3d H_world_viewpoint_; // Where to view the world from
+ cv::Mat image_; // Image to draw on
+ cv::Mat camera_mat_; // Virtual camera intrinsics (defines fov, center)
+ cv::Mat dist_coeffs_; // Distortion coefficients, if desired (only used in
+ // DrawFrameAxes
+};
+} // namespace vision
+} // namespace frc971
+
+#endif // FRC971_VISION_VISUALIZE_ROBOT_H_
diff --git a/frc971/vision/visualize_robot_sample.cc b/frc971/vision/visualize_robot_sample.cc
new file mode 100644
index 0000000..dc38352
--- /dev/null
+++ b/frc971/vision/visualize_robot_sample.cc
@@ -0,0 +1,72 @@
+#include "frc971/vision/visualize_robot.h"
+
+#include "aos/init.h"
+#include "aos/logging/logging.h"
+#include "glog/logging.h"
+
+#include "Eigen/Dense"
+
+#include <math.h>
+#include <opencv2/aruco.hpp>
+#include <opencv2/aruco/charuco.hpp>
+#include <opencv2/calib3d.hpp>
+#include <opencv2/core/eigen.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <opencv2/imgproc.hpp>
+#include "aos/time/time.h"
+
+namespace frc971 {
+namespace vision {
+
+// Show / test the basics of visualizing the robot frames
+void Main(int /*argc*/, char ** /* argv */) {
+ VisualizeRobot vis_robot;
+
+ int image_width = 500;
+ cv::Mat image_mat =
+ cv::Mat::zeros(cv::Size(image_width, image_width), CV_8UC3);
+ vis_robot.SetImage(image_mat);
+
+ // 10 meters above the origin, rotated so the camera faces straight down
+ Eigen::Translation3d camera_trans(0, 0, 10.0);
+ Eigen::AngleAxisd camera_rot(M_PI, Eigen::Vector3d::UnitX());
+ Eigen::Affine3d camera_viewpoint = camera_trans * camera_rot;
+ vis_robot.SetViewpoint(camera_viewpoint);
+
+ cv::Mat camera_mat;
+ double focal_length = 1000.0;
+ double intr[] = {focal_length, 0.0, image_width / 2.0,
+ 0.0, focal_length, image_width / 2.0,
+ 0.0, 0.0, 1.0};
+ camera_mat = cv::Mat(3, 3, CV_64FC1, intr);
+ vis_robot.SetCameraParameters(camera_mat);
+
+ Eigen::Affine3d offset_rotate_origin(Eigen::Affine3d::Identity());
+
+ cv::Mat dist_coeffs = cv::Mat(1, 5, CV_64F, 0.0);
+ vis_robot.SetDistortionCoefficients(dist_coeffs);
+
+ // Go around the clock and plot the coordinate frame at different rotations
+ for (int i = 0; i < 12; i++) {
+ double angle = M_PI * double(i) / 6.0;
+ Eigen::Vector3d trans;
+ trans << 1.0 * cos(angle), 1.0 * sin(angle), 0.0;
+
+ offset_rotate_origin = Eigen::Translation3d(trans) *
+ Eigen::AngleAxisd(angle, Eigen::Vector3d::UnitX());
+
+ vis_robot.DrawFrameAxes(offset_rotate_origin, std::to_string(i));
+ }
+
+ // Display the result
+ cv::imshow("Display", image_mat);
+ cv::waitKey();
+}
+} // namespace vision
+} // namespace frc971
+
+int main(int argc, char **argv) {
+ aos::InitGoogle(&argc, &argv);
+
+ frc971::vision::Main(argc, argv);
+}
diff --git a/go.mod b/go.mod
index 09c71f4..b1720c2 100644
--- a/go.mod
+++ b/go.mod
@@ -7,27 +7,32 @@
github.com/golang/protobuf v1.5.2
github.com/google/flatbuffers v2.0.5+incompatible
google.golang.org/grpc v1.43.0
+ gorm.io/driver/postgres v1.3.7
+ gorm.io/gorm v1.23.5
)
require (
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/davecgh/go-spew v1.1.1
github.com/google/go-querystring v1.1.0 // indirect
- github.com/jackc/pgx v3.6.2+incompatible
github.com/phst/runfiles v0.0.0-20220125203201-388095b3a22d
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
- golang.org/x/text v0.3.6 // indirect
+ golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
google.golang.org/protobuf v1.26.0 // indirect
)
require (
- github.com/cockroachdb/apd v1.1.0 // indirect
- github.com/gofrs/uuid v4.0.0+incompatible // indirect
- github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
- github.com/lib/pq v1.10.2 // indirect
- github.com/pkg/errors v0.8.1 // indirect
- github.com/shopspring/decimal v1.2.0 // indirect
- golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
+ github.com/jackc/chunkreader/v2 v2.0.1 // indirect
+ github.com/jackc/pgconn v1.12.1 // indirect
+ github.com/jackc/pgio v1.0.0 // indirect
+ github.com/jackc/pgpassfile v1.0.0 // indirect
+ github.com/jackc/pgproto3/v2 v2.3.0 // indirect
+ github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
+ github.com/jackc/pgtype v1.11.0 // indirect
+ github.com/jackc/pgx/v4 v4.16.1 // indirect
+ github.com/jinzhu/inflection v1.0.0 // indirect
+ github.com/jinzhu/now v1.1.4 // indirect
+ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
)
diff --git a/go.sum b/go.sum
index 7c08101..3082bdc 100644
--- a/go.sum
+++ b/go.sum
@@ -1,6 +1,8 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/buildkite/go-buildkite v2.2.0+incompatible h1:yEjSu1axFC88x4dbufhgMDsEnJztPWlLiZzEvzJggXc=
github.com/buildkite/go-buildkite v2.2.0+incompatible/go.mod h1:WTV0aX5KnQ9ofsKMg2CLUBLJNsQ0RwOEKPhrXXZWPcE=
@@ -17,6 +19,9 @@
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -27,6 +32,9 @@
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -57,41 +65,145 @@
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
-github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
-github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
-github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
+github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
+github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
+github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
+github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
+github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
+github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
+github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
+github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
+github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
+github.com/jackc/pgconn v1.12.1 h1:rsDFzIpRk7xT4B8FufgpCCeyjdNpKyghZeSefViE5W8=
+github.com/jackc/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono=
+github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
+github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
+github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
+github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
+github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=
+github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
+github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.3.0 h1:brH0pCGBDkBW07HWlN/oSBXrmo3WB0UvZd1pIuDcL8Y=
+github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
+github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
+github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
+github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
+github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
+github.com/jackc/pgtype v1.11.0 h1:u4uiGPz/1hryuXzyaBhSk6dnIyyG2683olG2OV+UUgs=
+github.com/jackc/pgtype v1.11.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
+github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
+github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
+github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
+github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
+github.com/jackc/pgx/v4 v4.16.1 h1:JzTglcal01DrghUqt+PmzWsZx/Yh7SC/CTQmSBMTd0Y=
+github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ=
+github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
+github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
+github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/phst/runfiles v0.0.0-20220125203201-388095b3a22d h1:N5aMcF9W9AjW4ed+PJhA7+FjdgPa9gJ+St3mNu2tq1Q=
github.com/phst/runfiles v0.0.0-20220125203201-388095b3a22d/go.mod h1:+oijTyzCf6Qe7sczsCOuoeX11IxZ+UkXXlhLrfyHlzg=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
+github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
+golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
@@ -102,22 +214,44 @@
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -149,8 +283,18 @@
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gorm.io/driver/postgres v1.3.7 h1:FKF6sIMDHDEvvMF/XJvbnCl0nu6KSKUaPXevJ4r+VYQ=
+gorm.io/driver/postgres v1.3.7/go.mod h1:f02ympjIcgtHEGFMZvdgTxODZ9snAHDb4hXfigBVuNI=
+gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
+gorm.io/gorm v1.23.5 h1:TnlF26wScKSvknUC/Rn8t0NLLM22fypYBlvj1+aH6dM=
+gorm.io/gorm v1.23.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
diff --git a/go_deps.bzl b/go_deps.bzl
index 9d37e42..2869b5e 100644
--- a/go_deps.bzl
+++ b/go_deps.bzl
@@ -5,8 +5,8 @@
maybe_override_go_dep(
name = "co_honnef_go_tools",
importpath = "honnef.co/go/tools",
- sum = "h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=",
- version = "v0.0.0-20190523083050-ea95bdfd59fc",
+ sum = "h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=",
+ version = "v0.0.1-2019.2.3",
)
maybe_override_go_dep(
name = "com_github_antihax_optional",
@@ -69,6 +69,18 @@
version = "v1.1.0",
)
maybe_override_go_dep(
+ name = "com_github_coreos_go_systemd",
+ importpath = "github.com/coreos/go-systemd",
+ sum = "h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=",
+ version = "v0.0.0-20190719114852-fd7a80b32e1f",
+ )
+ maybe_override_go_dep(
+ name = "com_github_creack_pty",
+ importpath = "github.com/creack/pty",
+ sum = "h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A=",
+ version = "v1.1.7",
+ )
+ maybe_override_go_dep(
name = "com_github_davecgh_go_spew",
importpath = "github.com/davecgh/go-spew",
sum = "h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=",
@@ -93,6 +105,24 @@
version = "v1.0.0",
)
maybe_override_go_dep(
+ name = "com_github_go_kit_log",
+ importpath = "github.com/go-kit/log",
+ sum = "h1:DGJh0Sm43HbOeYDNnVZFl8BvcYVvjD5bqYJvp0REbwQ=",
+ version = "v0.1.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_go_logfmt_logfmt",
+ importpath = "github.com/go-logfmt/logfmt",
+ sum = "h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=",
+ version = "v0.5.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_go_stack_stack",
+ importpath = "github.com/go-stack/stack",
+ sum = "h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=",
+ version = "v1.8.0",
+ )
+ maybe_override_go_dep(
name = "com_github_gofrs_uuid",
importpath = "github.com/gofrs/uuid",
sum = "h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=",
@@ -129,6 +159,12 @@
version = "v1.1.0",
)
maybe_override_go_dep(
+ name = "com_github_google_renameio",
+ importpath = "github.com/google/renameio",
+ sum = "h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=",
+ version = "v0.1.0",
+ )
+ maybe_override_go_dep(
name = "com_github_google_uuid",
importpath = "github.com/google/uuid",
sum = "h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=",
@@ -141,16 +177,118 @@
version = "v1.16.0",
)
maybe_override_go_dep(
- name = "com_github_jackc_fake",
- importpath = "github.com/jackc/fake",
- sum = "h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=",
- version = "v0.0.0-20150926172116-812a484cc733",
+ name = "com_github_jackc_chunkreader",
+ importpath = "github.com/jackc/chunkreader",
+ sum = "h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=",
+ version = "v1.0.0",
)
maybe_override_go_dep(
- name = "com_github_jackc_pgx",
- importpath = "github.com/jackc/pgx",
- sum = "h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=",
- version = "v3.6.2+incompatible",
+ name = "com_github_jackc_chunkreader_v2",
+ importpath = "github.com/jackc/chunkreader/v2",
+ sum = "h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=",
+ version = "v2.0.1",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jackc_pgconn",
+ importpath = "github.com/jackc/pgconn",
+ sum = "h1:rsDFzIpRk7xT4B8FufgpCCeyjdNpKyghZeSefViE5W8=",
+ version = "v1.12.1",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jackc_pgio",
+ importpath = "github.com/jackc/pgio",
+ sum = "h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=",
+ version = "v1.0.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jackc_pgmock",
+ importpath = "github.com/jackc/pgmock",
+ sum = "h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=",
+ version = "v0.0.0-20210724152146-4ad1a8207f65",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jackc_pgpassfile",
+ importpath = "github.com/jackc/pgpassfile",
+ sum = "h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=",
+ version = "v1.0.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jackc_pgproto3",
+ importpath = "github.com/jackc/pgproto3",
+ sum = "h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=",
+ version = "v1.1.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jackc_pgproto3_v2",
+ importpath = "github.com/jackc/pgproto3/v2",
+ sum = "h1:brH0pCGBDkBW07HWlN/oSBXrmo3WB0UvZd1pIuDcL8Y=",
+ version = "v2.3.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jackc_pgservicefile",
+ importpath = "github.com/jackc/pgservicefile",
+ sum = "h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=",
+ version = "v0.0.0-20200714003250-2b9c44734f2b",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jackc_pgtype",
+ importpath = "github.com/jackc/pgtype",
+ sum = "h1:u4uiGPz/1hryuXzyaBhSk6dnIyyG2683olG2OV+UUgs=",
+ version = "v1.11.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jackc_pgx_v4",
+ importpath = "github.com/jackc/pgx/v4",
+ sum = "h1:JzTglcal01DrghUqt+PmzWsZx/Yh7SC/CTQmSBMTd0Y=",
+ version = "v4.16.1",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jackc_puddle",
+ importpath = "github.com/jackc/puddle",
+ sum = "h1:gI8os0wpRXFd4FiAY2dWiqRK037tjj3t7rKFeO4X5iw=",
+ version = "v1.2.1",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jinzhu_inflection",
+ importpath = "github.com/jinzhu/inflection",
+ sum = "h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=",
+ version = "v1.0.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_jinzhu_now",
+ importpath = "github.com/jinzhu/now",
+ sum = "h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=",
+ version = "v1.1.4",
+ )
+ maybe_override_go_dep(
+ name = "com_github_kisielk_gotool",
+ importpath = "github.com/kisielk/gotool",
+ sum = "h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=",
+ version = "v1.0.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_konsorten_go_windows_terminal_sequences",
+ importpath = "github.com/konsorten/go-windows-terminal-sequences",
+ sum = "h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=",
+ version = "v1.0.2",
+ )
+ maybe_override_go_dep(
+ name = "com_github_kr_pretty",
+ importpath = "github.com/kr/pretty",
+ sum = "h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=",
+ version = "v0.1.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_kr_pty",
+ importpath = "github.com/kr/pty",
+ sum = "h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=",
+ version = "v1.1.8",
+ )
+ maybe_override_go_dep(
+ name = "com_github_kr_text",
+ importpath = "github.com/kr/text",
+ sum = "h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=",
+ version = "v0.1.0",
)
maybe_override_go_dep(
name = "com_github_lib_pq",
@@ -159,6 +297,24 @@
version = "v1.10.2",
)
maybe_override_go_dep(
+ name = "com_github_masterminds_semver_v3",
+ importpath = "github.com/Masterminds/semver/v3",
+ sum = "h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=",
+ version = "v3.1.1",
+ )
+ maybe_override_go_dep(
+ name = "com_github_mattn_go_colorable",
+ importpath = "github.com/mattn/go-colorable",
+ sum = "h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=",
+ version = "v0.1.6",
+ )
+ maybe_override_go_dep(
+ name = "com_github_mattn_go_isatty",
+ importpath = "github.com/mattn/go-isatty",
+ sum = "h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=",
+ version = "v0.0.12",
+ )
+ maybe_override_go_dep(
name = "com_github_phst_runfiles",
importpath = "github.com/phst/runfiles",
sum = "h1:N5aMcF9W9AjW4ed+PJhA7+FjdgPa9gJ+St3mNu2tq1Q=",
@@ -189,16 +345,46 @@
version = "v1.2.0",
)
maybe_override_go_dep(
+ name = "com_github_rogpeppe_go_internal",
+ importpath = "github.com/rogpeppe/go-internal",
+ sum = "h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=",
+ version = "v1.3.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_rs_xid",
+ importpath = "github.com/rs/xid",
+ sum = "h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=",
+ version = "v1.2.1",
+ )
+ maybe_override_go_dep(
+ name = "com_github_rs_zerolog",
+ importpath = "github.com/rs/zerolog",
+ sum = "h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY=",
+ version = "v1.15.0",
+ )
+ maybe_override_go_dep(
+ name = "com_github_satori_go_uuid",
+ importpath = "github.com/satori/go.uuid",
+ sum = "h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=",
+ version = "v1.2.0",
+ )
+ maybe_override_go_dep(
name = "com_github_shopspring_decimal",
importpath = "github.com/shopspring/decimal",
sum = "h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=",
version = "v1.2.0",
)
maybe_override_go_dep(
+ name = "com_github_sirupsen_logrus",
+ importpath = "github.com/sirupsen/logrus",
+ sum = "h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=",
+ version = "v1.4.2",
+ )
+ maybe_override_go_dep(
name = "com_github_stretchr_objx",
importpath = "github.com/stretchr/objx",
- sum = "h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=",
- version = "v0.1.0",
+ sum = "h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=",
+ version = "v0.2.0",
)
maybe_override_go_dep(
name = "com_github_stretchr_testify",
@@ -207,6 +393,12 @@
version = "v1.7.0",
)
maybe_override_go_dep(
+ name = "com_github_zenazn_goji",
+ importpath = "github.com/zenazn/goji",
+ sum = "h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ=",
+ version = "v0.9.0",
+ )
+ maybe_override_go_dep(
name = "com_google_cloud_go",
importpath = "cloud.google.com/go",
sum = "h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=",
@@ -215,8 +407,20 @@
maybe_override_go_dep(
name = "in_gopkg_check_v1",
importpath = "gopkg.in/check.v1",
- sum = "h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=",
- version = "v0.0.0-20161208181325-20d25e280405",
+ sum = "h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=",
+ version = "v1.0.0-20180628173108-788fd7840127",
+ )
+ maybe_override_go_dep(
+ name = "in_gopkg_errgo_v2",
+ importpath = "gopkg.in/errgo.v2",
+ sum = "h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=",
+ version = "v2.1.0",
+ )
+ maybe_override_go_dep(
+ name = "in_gopkg_inconshreveable_log15_v2",
+ importpath = "gopkg.in/inconshreveable/log15.v2",
+ sum = "h1:RlWgLqCMMIYYEVcAR5MDsuHlVkaIPDAF+5Dehzg8L5A=",
+ version = "v2.0.0-20180818164646-67afb5ed74ec",
)
maybe_override_go_dep(
name = "in_gopkg_yaml_v2",
@@ -231,6 +435,18 @@
version = "v3.0.0-20200313102051-9f266ea9e77c",
)
maybe_override_go_dep(
+ name = "io_gorm_driver_postgres",
+ importpath = "gorm.io/driver/postgres",
+ sum = "h1:FKF6sIMDHDEvvMF/XJvbnCl0nu6KSKUaPXevJ4r+VYQ=",
+ version = "v1.3.7",
+ )
+ maybe_override_go_dep(
+ name = "io_gorm_gorm",
+ importpath = "gorm.io/gorm",
+ sum = "h1:TnlF26wScKSvknUC/Rn8t0NLLM22fypYBlvj1+aH6dM=",
+ version = "v1.23.5",
+ )
+ maybe_override_go_dep(
name = "io_opentelemetry_go_proto_otlp",
importpath = "go.opentelemetry.io/proto/otlp",
sum = "h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8=",
@@ -263,8 +479,8 @@
maybe_override_go_dep(
name = "org_golang_x_crypto",
importpath = "golang.org/x/crypto",
- sum = "h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=",
- version = "v0.0.0-20210711020723-a769d52b0f97",
+ sum = "h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=",
+ version = "v0.0.0-20210921155107-089bfa567519",
)
maybe_override_go_dep(
name = "org_golang_x_exp",
@@ -275,8 +491,14 @@
maybe_override_go_dep(
name = "org_golang_x_lint",
importpath = "golang.org/x/lint",
- sum = "h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=",
- version = "v0.0.0-20190313153728-d0100b6bd8b3",
+ sum = "h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=",
+ version = "v0.0.0-20190930215403-16217165b5de",
+ )
+ maybe_override_go_dep(
+ name = "org_golang_x_mod",
+ importpath = "golang.org/x/mod",
+ sum = "h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=",
+ version = "v0.1.1-0.20191105210325-c90efee705ee",
)
maybe_override_go_dep(
name = "org_golang_x_net",
@@ -311,14 +533,14 @@
maybe_override_go_dep(
name = "org_golang_x_text",
importpath = "golang.org/x/text",
- sum = "h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=",
- version = "v0.3.6",
+ sum = "h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=",
+ version = "v0.3.7",
)
maybe_override_go_dep(
name = "org_golang_x_tools",
importpath = "golang.org/x/tools",
- sum = "h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A=",
- version = "v0.0.0-20190524140312-2c0ae7006135",
+ sum = "h1:DnSr2mCsxyCE6ZgIkmcWUQY2R5cH/6wL7eIxEmQOMSE=",
+ version = "v0.0.0-20200103221440-774c71fcf114",
)
maybe_override_go_dep(
name = "org_golang_x_xerrors",
@@ -326,3 +548,27 @@
sum = "h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=",
version = "v0.0.0-20200804184101-5ec99f83aff1",
)
+ maybe_override_go_dep(
+ name = "org_uber_go_atomic",
+ importpath = "go.uber.org/atomic",
+ sum = "h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=",
+ version = "v1.6.0",
+ )
+ maybe_override_go_dep(
+ name = "org_uber_go_multierr",
+ importpath = "go.uber.org/multierr",
+ sum = "h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=",
+ version = "v1.5.0",
+ )
+ maybe_override_go_dep(
+ name = "org_uber_go_tools",
+ importpath = "go.uber.org/tools",
+ sum = "h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=",
+ version = "v0.0.0-20190618225709-2cfd321de3ee",
+ )
+ maybe_override_go_dep(
+ name = "org_uber_go_zap",
+ importpath = "go.uber.org/zap",
+ sum = "h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=",
+ version = "v1.13.0",
+ )
diff --git a/scouting/db/BUILD b/scouting/db/BUILD
index 7fbd2e2..154cab6 100644
--- a/scouting/db/BUILD
+++ b/scouting/db/BUILD
@@ -6,7 +6,12 @@
importpath = "github.com/frc971/971-Robot-Code/scouting/db",
target_compatible_with = ["@platforms//cpu:x86_64"],
visibility = ["//visibility:public"],
- deps = ["@com_github_jackc_pgx//stdlib"],
+ deps = [
+ "@io_gorm_driver_postgres//:postgres",
+ "@io_gorm_gorm//:gorm",
+ "@io_gorm_gorm//clause",
+ "@io_gorm_gorm//logger",
+ ],
)
go_test(
@@ -18,4 +23,5 @@
],
embed = [":db"],
target_compatible_with = ["@platforms//cpu:x86_64"],
+ deps = ["@com_github_davecgh_go_spew//spew"],
)
diff --git a/scouting/db/db.go b/scouting/db/db.go
index 3d514e3..55f2310 100644
--- a/scouting/db/db.go
+++ b/scouting/db/db.go
@@ -1,33 +1,50 @@
package db
import (
- "database/sql"
"errors"
"fmt"
- _ "github.com/jackc/pgx/stdlib"
+ "gorm.io/driver/postgres"
+ "gorm.io/gorm"
+ "gorm.io/gorm/clause"
+ "gorm.io/gorm/logger"
)
type Database struct {
- *sql.DB
+ *gorm.DB
}
type Match struct {
- MatchNumber, SetNumber int32
- CompLevel string
+ // TODO(phil): Rework this be be one team per row.
+ // Makes queries much simpler.
+ MatchNumber int32 `gorm:"primaryKey"`
+ SetNumber int32 `gorm:"primaryKey"`
+ CompLevel string `gorm:"primaryKey"`
R1, R2, R3, B1, B2, B3 int32
}
type Shift struct {
- MatchNumber int32
+ MatchNumber int32 `gorm:"primaryKey"`
R1scouter, R2scouter, R3scouter, B1scouter, B2scouter, B3scouter string
}
type Stats struct {
- TeamNumber, MatchNumber, SetNumber int32
- CompLevel string
- StartingQuadrant int32
- AutoBallPickedUp [5]bool
+ TeamNumber int32 `gorm:"primaryKey"`
+ MatchNumber int32 `gorm:"primaryKey"`
+ SetNumber int32 `gorm:"primaryKey"`
+ CompLevel string `gorm:"primaryKey"`
+ StartingQuadrant int32
+ // This field is for the balls picked up during auto. Use this field
+ // when using this library. Ignore the AutoBallPickedUpX fields below.
+ AutoBallPickedUp [5]bool `gorm:"-:all"`
+ // These fields are internal implementation details. Do not use these.
+ // TODO(phil): Figure out how to use the JSON gorm serializer instead
+ // of manually serializing/deserializing these.
+ AutoBallPickedUp1 bool
+ AutoBallPickedUp2 bool
+ AutoBallPickedUp3 bool
+ AutoBallPickedUp4 bool
+ AutoBallPickedUp5 bool
// TODO(phil): Re-order auto and teleop fields so auto comes first.
ShotsMissed, UpperGoalShots, LowerGoalShots int32
ShotsMissedAuto, UpperGoalAuto, LowerGoalAuto int32
@@ -50,233 +67,85 @@
}
type NotesData struct {
- TeamNumber int32
- Notes []string
+ ID uint `gorm:"primaryKey"`
+ TeamNumber int32
+ Notes string
+ GoodDriving bool
+ BadDriving bool
+ SketchyClimb bool
+ SolidClimb bool
+ GoodDefense bool
+ BadDefense bool
}
type Ranking struct {
- TeamNumber int
+ TeamNumber int `gorm:"primaryKey"`
Losses, Wins, Ties int32
Rank, Dq int32
}
+type DriverRankingData struct {
+ // Each entry in the table is a single scout's ranking.
+ // Multiple scouts can submit a driver ranking for the same
+ // teams in the same match.
+ // The teams being ranked are stored in Rank1, Rank2, Rank3,
+ // Rank1 being the best driving and Rank3 being the worst driving.
+
+ ID uint `gorm:"primaryKey"`
+ MatchNumber int32
+ Rank1 int32
+ Rank2 int32
+ Rank3 int32
+}
+
// Opens a database at the specified port on localhost. We currently don't
// support connecting to databases on other hosts.
func NewDatabase(user string, password string, port int) (*Database, error) {
var err error
database := new(Database)
- psqlInfo := fmt.Sprintf("postgres://%s:%s@localhost:%d/postgres", user, password, port)
- database.DB, err = sql.Open("pgx", psqlInfo)
+ dsn := fmt.Sprintf("host=localhost user=%s password=%s dbname=postgres port=%d sslmode=disable", user, password, port)
+ database.DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
+ Logger: logger.Default.LogMode(logger.Silent),
+ })
if err != nil {
+ database.Delete()
return nil, errors.New(fmt.Sprint("Failed to connect to postgres: ", err))
}
- statement, err := database.Prepare("CREATE TABLE IF NOT EXISTS matches (" +
- "MatchNumber INTEGER, " +
- "SetNumber INTEGER, " +
- "CompLevel VARCHAR, " +
- "R1 INTEGER, " +
- "R2 INTEGER, " +
- "R3 INTEGER, " +
- "B1 INTEGER, " +
- "B2 INTEGER, " +
- "B3 INTEGER, " +
- "PRIMARY KEY (MatchNumber, SetNumber, CompLevel))")
+ err = database.AutoMigrate(&Match{}, &Shift{}, &Stats{}, &NotesData{}, &Ranking{}, &DriverRankingData{})
if err != nil {
- database.Close()
- return nil, errors.New(fmt.Sprint("Failed to prepare matches table creation: ", err))
- }
- defer statement.Close()
-
- _, err = statement.Exec()
- if err != nil {
- database.Close()
- return nil, errors.New(fmt.Sprint("Failed to create matches table: ", err))
- }
-
- statement, err = database.Prepare("CREATE TABLE IF NOT EXISTS shift_schedule (" +
- "id SERIAL PRIMARY KEY, " +
- "MatchNumber INTEGER, " +
- "R1Scouter VARCHAR, " +
- "R2Scouter VARCHAR, " +
- "R3Scouter VARCHAR, " +
- "B1Scouter VARCHAR, " +
- "B2Scouter VARCHAR, " +
- "B3scouter VARCHAR)")
- if err != nil {
- database.Close()
- return nil, errors.New(fmt.Sprint("Failed to prepare shift schedule table creation: ", err))
- }
- defer statement.Close()
-
- _, err = statement.Exec()
- if err != nil {
- database.Close()
- return nil, errors.New(fmt.Sprint("Failed to create shift schedule table: ", err))
- }
-
- statement, err = database.Prepare("CREATE TABLE IF NOT EXISTS team_match_stats (" +
- "TeamNumber INTEGER, " +
- "MatchNumber INTEGER, " +
- "SetNumber INTEGER, " +
- "CompLevel VARCHAR, " +
- "StartingQuadrant INTEGER, " +
- "AutoBall1PickedUp BOOLEAN, " +
- "AutoBall2PickedUp BOOLEAN, " +
- "AutoBall3PickedUp BOOLEAN, " +
- "AutoBall4PickedUp BOOLEAN, " +
- "AutoBall5PickedUp BOOLEAN, " +
- "ShotsMissed INTEGER, " +
- "UpperGoalShots INTEGER, " +
- "LowerGoalShots INTEGER, " +
- "ShotsMissedAuto INTEGER, " +
- "UpperGoalAuto INTEGER, " +
- "LowerGoalAuto INTEGER, " +
- "PlayedDefense INTEGER, " +
- "DefenseReceivedScore INTEGER, " +
- "Climbing INTEGER, " +
- "Comment VARCHAR, " +
- "CollectedBy VARCHAR, " +
- "PRIMARY KEY (TeamNumber, MatchNumber, SetNumber, CompLevel))")
- if err != nil {
- database.Close()
- return nil, errors.New(fmt.Sprint("Failed to prepare stats table creation: ", err))
- }
- defer statement.Close()
-
- _, err = statement.Exec()
- if err != nil {
- database.Close()
- return nil, errors.New(fmt.Sprint("Failed to create team_match_stats table: ", err))
- }
-
- statement, err = database.Prepare("CREATE TABLE IF NOT EXISTS team_notes (" +
- "id SERIAL PRIMARY KEY, " +
- "TeamNumber INTEGER, " +
- "Notes TEXT)")
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to prepare notes table creation: ", err))
- }
- defer statement.Close()
-
- _, err = statement.Exec()
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to create notes table: ", err))
- }
-
- statement, err = database.Prepare("CREATE TABLE IF NOT EXISTS rankings (" +
- "id SERIAL PRIMARY KEY, " +
- "Losses INTEGER, " +
- "Wins INTEGER, " +
- "Ties INTEGER, " +
- "Rank INTEGER, " +
- "Dq INTEGER, " +
- "TeamNumber INTEGER)")
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to prepare rankings table creation: ", err))
- }
- defer statement.Close()
-
- _, err = statement.Exec()
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to create rankings table: ", err))
+ database.Delete()
+ return nil, errors.New(fmt.Sprint("Failed to create/migrate tables: ", err))
}
return database, nil
}
func (database *Database) Delete() error {
- statement, err := database.Prepare("DROP TABLE IF EXISTS matches")
+ sql, err := database.DB.DB()
if err != nil {
- return errors.New(fmt.Sprint("Failed to prepare dropping matches table: ", err))
+ return err
}
- _, err = statement.Exec()
- if err != nil {
- return errors.New(fmt.Sprint("Failed to drop matches table: ", err))
- }
-
- statement, err = database.Prepare("DROP TABLE IF EXISTS shift_schedule")
- if err != nil {
- return errors.New(fmt.Sprint("Failed to prepare dropping shifts table: ", err))
- }
- _, err = statement.Exec()
- if err != nil {
- return errors.New(fmt.Sprint("Failed to drop shifts table: ", err))
- }
-
- statement, err = database.Prepare("DROP TABLE IF EXISTS team_match_stats")
- if err != nil {
- return errors.New(fmt.Sprint("Failed to prepare dropping stats table: ", err))
- }
- _, err = statement.Exec()
- if err != nil {
- return errors.New(fmt.Sprint("Failed to drop stats table: ", err))
- }
-
- statement, err = database.Prepare("DROP TABLE IF EXISTS team_notes")
- if err != nil {
- return errors.New(fmt.Sprint("Failed to prepare dropping notes table: ", err))
- }
- _, err = statement.Exec()
- if err != nil {
- return errors.New(fmt.Sprint("Failed to drop notes table: ", err))
- }
- return nil
-
- statement, err = database.Prepare("DROP TABLE IF EXISTS rankings")
- if err != nil {
- return errors.New(fmt.Sprint("Failed to prepare dropping rankings table: ", err))
- }
- _, err = statement.Exec()
- if err != nil {
- return errors.New(fmt.Sprint("Failed to drop rankings table: ", err))
- }
- return nil
+ return sql.Close()
}
-// This function will also populate the Stats table with six empty rows every time a match is added
-func (database *Database) AddToMatch(m Match) error {
- statement, err := database.Prepare("INSERT INTO matches(" +
- "MatchNumber, SetNumber, CompLevel, " +
- "R1, R2, R3, B1, B2, B3) " +
- "VALUES (" +
- "$1, $2, $3, " +
- "$4, $5, $6, $7, $8, $9) " +
- "ON CONFLICT (MatchNumber, SetNumber, CompLevel) DO UPDATE SET " +
- "R1 = EXCLUDED.R1, R2 = EXCLUDED.R2, R3 = EXCLUDED.R3, " +
- "B1 = EXCLUDED.B1, B2 = EXCLUDED.B2, B3 = EXCLUDED.B3")
- if err != nil {
- return errors.New(fmt.Sprint("Failed to prepare insertion into match database: ", err))
- }
- defer statement.Close()
+func (database *Database) SetDebugLogLevel() {
+ database.DB.Logger = database.DB.Logger.LogMode(logger.Info)
+}
- _, err = statement.Exec(m.MatchNumber, m.SetNumber, m.CompLevel,
- m.R1, m.R2, m.R3, m.B1, m.B2, m.B3)
- if err != nil {
- return errors.New(fmt.Sprint("Failed to insert into match database: ", err))
- }
- return nil
+func (database *Database) AddToMatch(m Match) error {
+ result := database.Clauses(clause.OnConflict{
+ UpdateAll: true,
+ }).Create(&m)
+ return result.Error
}
func (database *Database) AddToShift(sh Shift) error {
- statement, err := database.Prepare("INSERT INTO shift_schedule(" +
- "MatchNumber, " +
- "R1scouter, R2scouter, R3scouter, B1scouter, B2scouter, B3scouter) " +
- "VALUES (" +
- "$1, " +
- "$2, $3, $4, $5, $6, $7)")
- if err != nil {
- return errors.New(fmt.Sprint("Failed to prepare insertion into shift database: ", err))
- }
- defer statement.Close()
-
- _, err = statement.Exec(sh.MatchNumber,
- sh.R1scouter, sh.R2scouter, sh.R3scouter, sh.B1scouter, sh.B2scouter, sh.B3scouter)
- if err != nil {
- return errors.New(fmt.Sprint("Failed to insert into shift database: ", err))
- }
- return nil
+ result := database.Clauses(clause.OnConflict{
+ UpdateAll: true,
+ }).Create(&sh)
+ return result.Error
}
func (database *Database) AddToStats(s Stats) error {
@@ -297,304 +166,139 @@
" in match ", s.MatchNumber, " in the schedule."))
}
- statement, err := database.Prepare("INSERT INTO team_match_stats(" +
- "TeamNumber, MatchNumber, SetNumber, CompLevel, " +
- "StartingQuadrant, " +
- "AutoBall1PickedUp, AutoBall2PickedUp, AutoBall3PickedUp, " +
- "AutoBall4PickedUp, AutoBall5PickedUp, " +
- "ShotsMissed, UpperGoalShots, LowerGoalShots, " +
- "ShotsMissedAuto, UpperGoalAuto, LowerGoalAuto, " +
- "PlayedDefense, DefenseReceivedScore, Climbing, " +
- "Comment, CollectedBy) " +
- "VALUES (" +
- "$1, $2, $3, $4, " +
- "$5, " +
- "$6, $7, $8, " +
- "$9, $10, " +
- "$11, $12, $13, " +
- "$14, $15, $16, " +
- "$17, $18, $19, " +
- "$20, $21)")
- if err != nil {
- return errors.New(fmt.Sprint("Failed to prepare stats update statement: ", err))
- }
- defer statement.Close()
-
- _, err = statement.Exec(
- s.TeamNumber, s.MatchNumber, s.SetNumber, s.CompLevel,
- s.StartingQuadrant,
- s.AutoBallPickedUp[0], s.AutoBallPickedUp[1], s.AutoBallPickedUp[2],
- s.AutoBallPickedUp[3], s.AutoBallPickedUp[4],
- s.ShotsMissed, s.UpperGoalShots, s.LowerGoalShots,
- s.ShotsMissedAuto, s.UpperGoalAuto, s.LowerGoalAuto,
- s.PlayedDefense, s.DefenseReceivedScore, s.Climbing,
- s.Comment, s.CollectedBy)
- if err != nil {
- return errors.New(fmt.Sprint("Failed to update stats database: ", err))
- }
-
- return nil
+ // Unpack the auto balls array.
+ s.AutoBallPickedUp1 = s.AutoBallPickedUp[0]
+ s.AutoBallPickedUp2 = s.AutoBallPickedUp[1]
+ s.AutoBallPickedUp3 = s.AutoBallPickedUp[2]
+ s.AutoBallPickedUp4 = s.AutoBallPickedUp[3]
+ s.AutoBallPickedUp5 = s.AutoBallPickedUp[4]
+ result := database.Create(&s)
+ return result.Error
}
func (database *Database) AddOrUpdateRankings(r Ranking) error {
- statement, err := database.Prepare("UPDATE rankings SET " +
- "Losses = $1, Wins = $2, Ties = $3, " +
- "Rank = $4, Dq = $5, TeamNumber = $6 " +
- "WHERE TeamNumber = $6")
- if err != nil {
- return errors.New(fmt.Sprint("Failed to prepare rankings database update: ", err))
- }
- defer statement.Close()
-
- result, err := statement.Exec(r.Losses, r.Wins, r.Ties,
- r.Rank, r.Dq, r.TeamNumber)
- if err != nil {
- return errors.New(fmt.Sprint("Failed to update rankings database: ", err))
- }
-
- numRowsAffected, err := result.RowsAffected()
- if err != nil {
- return errors.New(fmt.Sprint("Failed to query rows affected: ", err))
- }
- if numRowsAffected == 0 {
- statement, err := database.Prepare("INSERT INTO rankings(" +
- "Losses, Wins, Ties, " +
- "Rank, Dq, TeamNumber) " +
- "VALUES (" +
- "$1, $2, $3, " +
- "$4, $5, $6)")
- if err != nil {
- return errors.New(fmt.Sprint("Failed to prepare insertion into rankings database: ", err))
- }
- defer statement.Close()
-
- _, err = statement.Exec(r.Losses, r.Wins, r.Ties,
- r.Rank, r.Dq, r.TeamNumber)
- if err != nil {
- return errors.New(fmt.Sprint("Failed to insert into rankings database: ", err))
- }
- }
-
- return nil
+ result := database.Clauses(clause.OnConflict{
+ UpdateAll: true,
+ }).Create(&r)
+ return result.Error
}
func (database *Database) ReturnMatches() ([]Match, error) {
- rows, err := database.Query("SELECT * FROM matches")
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to select from matches: ", err))
- }
- defer rows.Close()
-
- matches := make([]Match, 0)
- for rows.Next() {
- var match Match
- err := rows.Scan(&match.MatchNumber, &match.SetNumber, &match.CompLevel,
- &match.R1, &match.R2, &match.R3, &match.B1, &match.B2, &match.B3)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to scan from matches: ", err))
- }
- matches = append(matches, match)
- }
- return matches, nil
+ var matches []Match
+ result := database.Find(&matches)
+ return matches, result.Error
}
func (database *Database) ReturnAllShifts() ([]Shift, error) {
- rows, err := database.Query("SELECT * FROM shift_schedule")
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to select from shift: ", err))
- }
- defer rows.Close()
+ var shifts []Shift
+ result := database.Find(&shifts)
+ return shifts, result.Error
+}
- shifts := make([]Shift, 0)
- for rows.Next() {
- var shift Shift
- var id int
- err := rows.Scan(&id, &shift.MatchNumber,
- &shift.R1scouter, &shift.R2scouter, &shift.R3scouter, &shift.B1scouter, &shift.B2scouter, &shift.B3scouter)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to scan from shift: ", err))
- }
- shifts = append(shifts, shift)
+// Packs the stats. This really just consists of taking the individual auto
+// ball booleans and turning them into an array. The individual booleans are
+// cleared so that they don't affect struct comparisons.
+func packStats(stats *Stats) {
+ stats.AutoBallPickedUp = [5]bool{
+ stats.AutoBallPickedUp1,
+ stats.AutoBallPickedUp2,
+ stats.AutoBallPickedUp3,
+ stats.AutoBallPickedUp4,
+ stats.AutoBallPickedUp5,
}
- return shifts, nil
+ stats.AutoBallPickedUp1 = false
+ stats.AutoBallPickedUp2 = false
+ stats.AutoBallPickedUp3 = false
+ stats.AutoBallPickedUp4 = false
+ stats.AutoBallPickedUp5 = false
}
func (database *Database) ReturnStats() ([]Stats, error) {
- rows, err := database.Query("SELECT * FROM team_match_stats")
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to SELECT * FROM team_match_stats: ", err))
+ var stats []Stats
+ result := database.Find(&stats)
+ // Pack the auto balls array.
+ for i := range stats {
+ packStats(&stats[i])
}
- defer rows.Close()
-
- teams := make([]Stats, 0)
- for rows.Next() {
- var team Stats
- err = rows.Scan(
- &team.TeamNumber, &team.MatchNumber, &team.SetNumber, &team.CompLevel,
- &team.StartingQuadrant,
- &team.AutoBallPickedUp[0], &team.AutoBallPickedUp[1], &team.AutoBallPickedUp[2],
- &team.AutoBallPickedUp[3], &team.AutoBallPickedUp[4],
- &team.ShotsMissed, &team.UpperGoalShots, &team.LowerGoalShots,
- &team.ShotsMissedAuto, &team.UpperGoalAuto, &team.LowerGoalAuto,
- &team.PlayedDefense, &team.DefenseReceivedScore, &team.Climbing,
- &team.Comment, &team.CollectedBy)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to scan from stats: ", err))
- }
- teams = append(teams, team)
- }
- return teams, nil
+ return stats, result.Error
}
func (database *Database) ReturnRankings() ([]Ranking, error) {
- rows, err := database.Query("SELECT * FROM rankings")
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to SELECT * FROM rankings: ", err))
- }
- defer rows.Close()
-
- all_rankings := make([]Ranking, 0)
- for rows.Next() {
- var ranking Ranking
- var id int
- err = rows.Scan(&id,
- &ranking.Losses, &ranking.Wins, &ranking.Ties,
- &ranking.Rank, &ranking.Dq, &ranking.TeamNumber)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to scan from rankings: ", err))
- }
- all_rankings = append(all_rankings, ranking)
- }
- return all_rankings, nil
+ var rankins []Ranking
+ result := database.Find(&rankins)
+ return rankins, result.Error
}
func (database *Database) QueryMatches(teamNumber_ int32) ([]Match, error) {
- rows, err := database.Query("SELECT * FROM matches WHERE "+
- "R1 = $1 OR R2 = $2 OR R3 = $3 OR B1 = $4 OR B2 = $5 OR B3 = $6",
- teamNumber_, teamNumber_, teamNumber_, teamNumber_, teamNumber_, teamNumber_)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to select from matches for team: ", err))
- }
- defer rows.Close()
-
var matches []Match
- for rows.Next() {
- var match Match
- err = rows.Scan(&match.MatchNumber, &match.SetNumber, &match.CompLevel,
- &match.R1, &match.R2, &match.R3, &match.B1, &match.B2, &match.B3)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to scan from matches: ", err))
- }
- matches = append(matches, match)
- }
- return matches, nil
+ result := database.
+ Where("r1 = $1 OR r2 = $1 OR r3 = $1 OR b1 = $1 OR b2 = $1 OR b3 = $1", teamNumber_).
+ Find(&matches)
+ return matches, result.Error
}
func (database *Database) QueryAllShifts(matchNumber_ int) ([]Shift, error) {
- rows, err := database.Query("SELECT * FROM shift_schedule WHERE MatchNumber = $1", matchNumber_)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to select from shift for team: ", err))
- }
- defer rows.Close()
-
var shifts []Shift
- for rows.Next() {
- var shift Shift
- var id int
- err = rows.Scan(&id, &shift.MatchNumber,
- &shift.R1scouter, &shift.R2scouter, &shift.R3scouter, &shift.B1scouter, &shift.B2scouter, &shift.B3scouter)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to scan from matches: ", err))
- }
- shifts = append(shifts, shift)
- }
- return shifts, nil
+ result := database.Where("match_number = ?", matchNumber_).Find(&shifts)
+ return shifts, result.Error
}
func (database *Database) QueryStats(teamNumber_ int) ([]Stats, error) {
- rows, err := database.Query("SELECT * FROM team_match_stats WHERE TeamNumber = $1", teamNumber_)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to select from stats: ", err))
+ var stats []Stats
+ result := database.Where("team_number = ?", teamNumber_).Find(&stats)
+ // Pack the auto balls array.
+ for i := range stats {
+ packStats(&stats[i])
}
- defer rows.Close()
-
- var teams []Stats
- for rows.Next() {
- var team Stats
- err = rows.Scan(
- &team.TeamNumber, &team.MatchNumber, &team.SetNumber, &team.CompLevel,
- &team.StartingQuadrant,
- &team.AutoBallPickedUp[0], &team.AutoBallPickedUp[1], &team.AutoBallPickedUp[2],
- &team.AutoBallPickedUp[3], &team.AutoBallPickedUp[4],
- &team.ShotsMissed, &team.UpperGoalShots, &team.LowerGoalShots,
- &team.ShotsMissedAuto, &team.UpperGoalAuto, &team.LowerGoalAuto,
- &team.PlayedDefense, &team.DefenseReceivedScore, &team.Climbing,
- &team.Comment, &team.CollectedBy)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to scan from stats: ", err))
- }
- teams = append(teams, team)
- }
- return teams, nil
+ return stats, result.Error
}
-func (database *Database) QueryNotes(TeamNumber int32) (NotesData, error) {
- rows, err := database.Query("SELECT * FROM team_notes WHERE TeamNumber = $1", TeamNumber)
- if err != nil {
- return NotesData{}, errors.New(fmt.Sprint("Failed to select from notes: ", err))
+func (database *Database) QueryNotes(TeamNumber int32) ([]string, error) {
+ var rawNotes []NotesData
+ result := database.Where("team_number = ?", TeamNumber).Find(&rawNotes)
+ if result.Error != nil {
+ return nil, result.Error
}
- defer rows.Close()
- var notes []string
- for rows.Next() {
- var id int32
- var data string
- err = rows.Scan(&id, &TeamNumber, &data)
- if err != nil {
- return NotesData{}, errors.New(fmt.Sprint("Failed to scan from notes: ", err))
- }
- notes = append(notes, data)
+ notes := make([]string, len(rawNotes))
+ for i := range rawNotes {
+ notes[i] = rawNotes[i].Notes
}
- return NotesData{TeamNumber, notes}, nil
+ return notes, nil
}
func (database *Database) QueryRankings(TeamNumber int) ([]Ranking, error) {
- rows, err := database.Query("SELECT * FROM rankings WHERE TeamNumber = $1", TeamNumber)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to select from rankings: ", err))
- }
- defer rows.Close()
-
- all_rankings := make([]Ranking, 0)
- for rows.Next() {
- var ranking Ranking
- var id int
- err = rows.Scan(&id,
- &ranking.Losses, &ranking.Wins, &ranking.Ties,
- &ranking.Rank, &ranking.Dq, &ranking.TeamNumber)
- if err != nil {
- return nil, errors.New(fmt.Sprint("Failed to scan from rankings: ", err))
- }
- all_rankings = append(all_rankings, ranking)
- }
- return all_rankings, nil
+ var rankins []Ranking
+ result := database.Where("team_number = ?", TeamNumber).Find(&rankins)
+ return rankins, result.Error
}
func (database *Database) AddNotes(data NotesData) error {
- if len(data.Notes) > 1 {
- return errors.New("Can only insert one row of notes at a time")
- }
- statement, err := database.Prepare("INSERT INTO " +
- "team_notes(TeamNumber, Notes)" +
- "VALUES ($1, $2)")
- if err != nil {
- return errors.New(fmt.Sprint("Failed to prepare insertion into notes table: ", err))
- }
- defer statement.Close()
+ result := database.Create(&NotesData{
+ TeamNumber: data.TeamNumber,
+ Notes: data.Notes,
+ GoodDriving: data.GoodDriving,
+ BadDriving: data.BadDriving,
+ SketchyClimb: data.SketchyClimb,
+ SolidClimb: data.SolidClimb,
+ GoodDefense: data.GoodDefense,
+ BadDefense: data.BadDefense,
+ })
+ return result.Error
+}
- _, err = statement.Exec(data.TeamNumber, data.Notes[0])
- if err != nil {
- return errors.New(fmt.Sprint("Failed to insert into Notes database: ", err))
- }
- return nil
+func (database *Database) AddDriverRanking(data DriverRankingData) error {
+ result := database.Create(&DriverRankingData{
+ MatchNumber: data.MatchNumber,
+ Rank1: data.Rank1,
+ Rank2: data.Rank2,
+ Rank3: data.Rank3,
+ })
+ return result.Error
+}
+
+func (database *Database) QueryDriverRanking(MatchNumber int) ([]DriverRankingData, error) {
+ var data []DriverRankingData
+ result := database.Where("match_number = ?", MatchNumber).Find(&data)
+ return data, result.Error
}
diff --git a/scouting/db/db_test.go b/scouting/db/db_test.go
index 438e52e..460b177 100644
--- a/scouting/db/db_test.go
+++ b/scouting/db/db_test.go
@@ -9,6 +9,8 @@
"strings"
"testing"
"time"
+
+ "github.com/davecgh/go-spew/spew"
)
// Shortcut for error checking. If the specified error is non-nil, print the
@@ -26,7 +28,6 @@
func (fixture dbFixture) TearDown() {
fixture.db.Delete()
- fixture.db.Close()
log.Println("Shutting down testdb")
fixture.server.Process.Signal(os.Interrupt)
fixture.server.Process.Wait()
@@ -55,9 +56,17 @@
}
log.Println("Connected to postgres.")
+ fixture.db.SetDebugLogLevel()
+
return fixture
}
+func checkDeepEqual(t *testing.T, expected interface{}, actual interface{}) {
+ if !reflect.DeepEqual(expected, actual) {
+ t.Fatalf(spew.Sprintf("Got %#v,\nbut expected %#v.", actual, expected))
+ }
+}
+
func TestAddToMatchDB(t *testing.T) {
fixture := createDatabase(t)
defer fixture.TearDown()
@@ -77,9 +86,7 @@
got, err := fixture.db.ReturnMatches()
check(t, err, "Failed ReturnMatches()")
- if !reflect.DeepEqual(correct, got) {
- t.Fatalf("Got %#v,\nbut expected %#v.", got, correct)
- }
+ checkDeepEqual(t, correct, got)
}
func TestAddOrUpdateRankingsDB(t *testing.T) {
@@ -198,6 +205,7 @@
stats := Stats{
TeamNumber: 1236, MatchNumber: 7,
+ SetNumber: 1, CompLevel: "qual",
StartingQuadrant: 2,
AutoBallPickedUp: [5]bool{false, false, false, true, false},
ShotsMissed: 9, UpperGoalShots: 5, LowerGoalShots: 4,
@@ -698,25 +706,20 @@
got, err := fixture.db.QueryRankings(125)
check(t, err, "Failed QueryRankings()")
- if !reflect.DeepEqual(correct, got) {
- t.Errorf("Got %#v,\nbut expected %#v.", got, correct)
- }
+ checkDeepEqual(t, correct, got)
}
func TestNotes(t *testing.T) {
fixture := createDatabase(t)
defer fixture.TearDown()
- expected := NotesData{
- TeamNumber: 1234,
- Notes: []string{"Note 1", "Note 3"},
- }
+ expected := []string{"Note 1", "Note 3"}
- err := fixture.db.AddNotes(NotesData{1234, []string{"Note 1"}})
+ err := fixture.db.AddNotes(NotesData{TeamNumber: 1234, Notes: "Note 1", GoodDriving: true, BadDriving: false, SketchyClimb: false, SolidClimb: true, GoodDefense: false, BadDefense: true})
check(t, err, "Failed to add Note")
- err = fixture.db.AddNotes(NotesData{1235, []string{"Note 2"}})
+ err = fixture.db.AddNotes(NotesData{TeamNumber: 1235, Notes: "Note 2", GoodDriving: false, BadDriving: true, SketchyClimb: false, SolidClimb: true, GoodDefense: false, BadDefense: false})
check(t, err, "Failed to add Note")
- err = fixture.db.AddNotes(NotesData{1234, []string{"Note 3"}})
+ err = fixture.db.AddNotes(NotesData{TeamNumber: 1234, Notes: "Note 3", GoodDriving: true, BadDriving: false, SketchyClimb: false, SolidClimb: true, GoodDefense: true, BadDefense: false})
check(t, err, "Failed to add Note")
actual, err := fixture.db.QueryNotes(1234)
@@ -726,3 +729,33 @@
t.Errorf("Got %#v,\nbut expected %#v.", actual, expected)
}
}
+
+func TestDriverRanking(t *testing.T) {
+ fixture := createDatabase(t)
+ defer fixture.TearDown()
+
+ expected := []DriverRankingData{
+ {ID: 1, MatchNumber: 12, Rank1: 1234, Rank2: 1235, Rank3: 1236},
+ {ID: 2, MatchNumber: 12, Rank1: 1236, Rank2: 1235, Rank3: 1234},
+ }
+
+ err := fixture.db.AddDriverRanking(
+ DriverRankingData{MatchNumber: 12, Rank1: 1234, Rank2: 1235, Rank3: 1236},
+ )
+ check(t, err, "Failed to add Driver Ranking")
+ err = fixture.db.AddDriverRanking(
+ DriverRankingData{MatchNumber: 12, Rank1: 1236, Rank2: 1235, Rank3: 1234},
+ )
+ check(t, err, "Failed to add Driver Ranking")
+ err = fixture.db.AddDriverRanking(
+ DriverRankingData{MatchNumber: 13, Rank1: 1235, Rank2: 1234, Rank3: 1236},
+ )
+ check(t, err, "Failed to add Driver Ranking")
+
+ actual, err := fixture.db.QueryDriverRanking(12)
+ check(t, err, "Failed to get Driver Ranking")
+
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("Got %#v,\nbut expected %#v.", actual, expected)
+ }
+}
diff --git a/scouting/scouting_test.ts b/scouting/scouting_test.ts
index a34d98c..8623fa1 100644
--- a/scouting/scouting_test.ts
+++ b/scouting/scouting_test.ts
@@ -241,7 +241,6 @@
expect(await getHeadingText()).toEqual('Climb');
await element(by.id('high')).click();
- await setTextboxByIdTo('comment', 'A very useful comment here.');
await element(by.buttonText('Next')).click();
expect(await getHeadingText()).toEqual('Other');
@@ -249,6 +248,7 @@
await adjustNthSliderBy(1, 1);
await element(by.id('no_show')).click();
await element(by.id('mechanically_broke')).click();
+ await setTextboxByIdTo('comment', 'A very useful comment here.');
await element(by.buttonText('Next')).click();
expect(await getHeadingText()).toEqual('Review and Submit');
@@ -273,7 +273,6 @@
// Validate Climb.
await expectReviewFieldToBe('Climb Level', 'High');
- await expectReviewFieldToBe('Comments', 'A very useful comment here.');
// Validate Other.
await expectReviewFieldToBe('Defense Played On Rating', '3');
@@ -282,6 +281,7 @@
await expectReviewFieldToBe('Never moved', 'false');
await expectReviewFieldToBe('Battery died', 'false');
await expectReviewFieldToBe('Broke (mechanically)', 'true');
+ await expectReviewFieldToBe('Comments', 'A very useful comment here.');
await element(by.buttonText('Submit')).click();
await browser.wait(
@@ -322,4 +322,108 @@
await element(by.buttonText('Flip')).click();
}
});
+
+ it('should: submit note scouting for multiple teams', async () => {
+ // Navigate to Notes Page.
+ await loadPage();
+ await element(by.cssContainingText('.nav-link', 'Notes')).click();
+ expect(await element(by.id('page-title')).getText()).toEqual('Notes');
+
+ // Add first team.
+ await setTextboxByIdTo('team_number_notes', '1234');
+ await element(by.buttonText('Select')).click();
+
+ // Add note and select keyword for first team.
+ expect(await element(by.id('team-key-1')).getText()).toEqual('1234');
+ await element(by.id('text-input-1')).sendKeys('Good Driving');
+ await element(by.id('Good Driving_0')).click();
+
+ // Navigate to add team selection and add another team.
+ await element(by.id('add-team-button')).click();
+ await setTextboxByIdTo('team_number_notes', '1235');
+ await element(by.buttonText('Select')).click();
+
+ // Add note and select keyword for second team.
+ expect(await element(by.id('team-key-2')).getText()).toEqual('1235');
+ await element(by.id('text-input-2')).sendKeys('Bad Driving');
+ await element(by.id('Bad Driving_1')).click();
+
+ // Submit Notes.
+ await element(by.buttonText('Submit')).click();
+ expect(await element(by.id('team_number_label')).getText()).toEqual(
+ 'Team Number'
+ );
+ });
+
+ it('should: switch note text boxes with keyboard shortcuts', async () => {
+ // Navigate to Notes Page.
+ await loadPage();
+ await element(by.cssContainingText('.nav-link', 'Notes')).click();
+ expect(await element(by.id('page-title')).getText()).toEqual('Notes');
+
+ // Add first team.
+ await setTextboxByIdTo('team_number_notes', '1234');
+ await element(by.buttonText('Select')).click();
+
+ // Add second team.
+ await element(by.id('add-team-button')).click();
+ await setTextboxByIdTo('team_number_notes', '1235');
+ await element(by.buttonText('Select')).click();
+
+ // Add third team.
+ await element(by.id('add-team-button')).click();
+ await setTextboxByIdTo('team_number_notes', '1236');
+ await element(by.buttonText('Select')).click();
+
+ for (let i = 1; i <= 3; i++) {
+ // Press Control + i
+ // Keyup Control for future actions.
+ browser
+ .actions()
+ .keyDown(protractor.Key.CONTROL)
+ .sendKeys(i.toString())
+ .keyUp(protractor.Key.CONTROL)
+ .perform();
+
+ // Expect text input to be focused.
+ expect(
+ await browser.driver.switchTo().activeElement().getAttribute('id')
+ ).toEqual('text-input-' + i);
+ }
+ });
+ it('should: submit driver ranking', async () => {
+ // Navigate to Driver Ranking Page.
+ await loadPage();
+ await element(by.cssContainingText('.nav-link', 'Driver Ranking')).click();
+ expect(await element(by.id('page-title')).getText()).toEqual(
+ 'Driver Ranking'
+ );
+
+ // Input match and team numbers.
+ await setTextboxByIdTo('match_number_selection', '11');
+ await setTextboxByIdTo('team_input_0', '123');
+ await setTextboxByIdTo('team_input_1', '456');
+ await setTextboxByIdTo('team_input_2', '789');
+ await element(by.id('select_button')).click();
+
+ // Verify match and team key input.
+ expect(await element(by.id('match_number_heading')).getText()).toEqual(
+ 'Match #11'
+ );
+ expect(await element(by.id('team_key_label_0')).getText()).toEqual('123');
+ expect(await element(by.id('team_key_label_1')).getText()).toEqual('456');
+ expect(await element(by.id('team_key_label_2')).getText()).toEqual('789');
+
+ // Rank teams.
+ await element(by.id('up_button_2')).click();
+ await element(by.id('down_button_0')).click();
+
+ // Verify ranking change.
+ expect(await element(by.id('team_key_label_0')).getText()).toEqual('789');
+ expect(await element(by.id('team_key_label_1')).getText()).toEqual('123');
+ expect(await element(by.id('team_key_label_2')).getText()).toEqual('456');
+
+ // Submit.
+ await element(by.id('submit_button')).click();
+ });
});
diff --git a/scouting/webserver/main.go b/scouting/webserver/main.go
index 5d4ab01..d2fbdfe 100644
--- a/scouting/webserver/main.go
+++ b/scouting/webserver/main.go
@@ -117,7 +117,7 @@
if err != nil {
log.Fatal("Failed to connect to database: ", err)
}
- defer database.Close()
+ defer database.Delete()
scrapeMatchList := func(year int32, eventCode string) ([]scraping.Match, error) {
if *blueAllianceConfigPtr == "" {
diff --git a/scouting/webserver/requests/BUILD b/scouting/webserver/requests/BUILD
index 87575a9..5c9ede4 100644
--- a/scouting/webserver/requests/BUILD
+++ b/scouting/webserver/requests/BUILD
@@ -24,6 +24,8 @@
"//scouting/webserver/requests/messages:request_shift_schedule_response_go_fbs",
"//scouting/webserver/requests/messages:submit_data_scouting_go_fbs",
"//scouting/webserver/requests/messages:submit_data_scouting_response_go_fbs",
+ "//scouting/webserver/requests/messages:submit_driver_ranking_go_fbs",
+ "//scouting/webserver/requests/messages:submit_driver_ranking_response_go_fbs",
"//scouting/webserver/requests/messages:submit_notes_go_fbs",
"//scouting/webserver/requests/messages:submit_notes_response_go_fbs",
"//scouting/webserver/requests/messages:submit_shift_schedule_go_fbs",
@@ -56,6 +58,7 @@
"//scouting/webserver/requests/messages:request_shift_schedule_response_go_fbs",
"//scouting/webserver/requests/messages:submit_data_scouting_go_fbs",
"//scouting/webserver/requests/messages:submit_data_scouting_response_go_fbs",
+ "//scouting/webserver/requests/messages:submit_driver_ranking_go_fbs",
"//scouting/webserver/requests/messages:submit_notes_go_fbs",
"//scouting/webserver/requests/messages:submit_shift_schedule_go_fbs",
"//scouting/webserver/server",
diff --git a/scouting/webserver/requests/debug/BUILD b/scouting/webserver/requests/debug/BUILD
index 04c4ffa..f826831 100644
--- a/scouting/webserver/requests/debug/BUILD
+++ b/scouting/webserver/requests/debug/BUILD
@@ -15,6 +15,7 @@
"//scouting/webserver/requests/messages:request_notes_for_team_response_go_fbs",
"//scouting/webserver/requests/messages:request_shift_schedule_response_go_fbs",
"//scouting/webserver/requests/messages:submit_data_scouting_response_go_fbs",
+ "//scouting/webserver/requests/messages:submit_driver_ranking_response_go_fbs",
"//scouting/webserver/requests/messages:submit_notes_response_go_fbs",
"//scouting/webserver/requests/messages:submit_shift_schedule_response_go_fbs",
"@com_github_google_flatbuffers//go:go_default_library",
diff --git a/scouting/webserver/requests/debug/debug.go b/scouting/webserver/requests/debug/debug.go
index b3df518..fc0896c 100644
--- a/scouting/webserver/requests/debug/debug.go
+++ b/scouting/webserver/requests/debug/debug.go
@@ -17,6 +17,7 @@
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_notes_for_team_response"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_shift_schedule_response"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting_response"
+ "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_driver_ranking_response"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes_response"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_shift_schedule_response"
flatbuffers "github.com/google/flatbuffers/go"
@@ -157,3 +158,9 @@
server+"/requests/submit/shift_schedule", requestBytes,
submit_shift_schedule_response.GetRootAsSubmitShiftScheduleResponse)
}
+
+func SubmitDriverRanking(server string, requestBytes []byte) (*submit_driver_ranking_response.SubmitDriverRankingResponseT, error) {
+ return sendMessage[submit_driver_ranking_response.SubmitDriverRankingResponseT](
+ server+"/requests/submit/submit_driver_ranking", requestBytes,
+ submit_driver_ranking_response.GetRootAsSubmitDriverRankingResponse)
+}
diff --git a/scouting/webserver/requests/messages/BUILD b/scouting/webserver/requests/messages/BUILD
index b2d21a2..c14a857 100644
--- a/scouting/webserver/requests/messages/BUILD
+++ b/scouting/webserver/requests/messages/BUILD
@@ -21,6 +21,8 @@
"request_shift_schedule_response",
"submit_shift_schedule",
"submit_shift_schedule_response",
+ "submit_driver_ranking",
+ "submit_driver_ranking_response",
)
filegroup(
diff --git a/scouting/webserver/requests/messages/submit_driver_ranking.fbs b/scouting/webserver/requests/messages/submit_driver_ranking.fbs
new file mode 100644
index 0000000..ac1e218
--- /dev/null
+++ b/scouting/webserver/requests/messages/submit_driver_ranking.fbs
@@ -0,0 +1,10 @@
+namespace scouting.webserver.requests;
+
+table SubmitDriverRanking {
+ matchNumber:int (id: 0);
+ rank1:int (id: 1);
+ rank2:int (id: 2);
+ rank3:int (id: 3);
+}
+
+root_type SubmitDriverRanking;
diff --git a/scouting/webserver/requests/messages/submit_driver_ranking_response.fbs b/scouting/webserver/requests/messages/submit_driver_ranking_response.fbs
new file mode 100644
index 0000000..78c6445
--- /dev/null
+++ b/scouting/webserver/requests/messages/submit_driver_ranking_response.fbs
@@ -0,0 +1,8 @@
+namespace scouting.webserver.requests;
+
+table SubmitDriverRankingResponse {
+ // empty response
+}
+
+root_type SubmitDriverRankingResponse;
+
diff --git a/scouting/webserver/requests/messages/submit_notes.fbs b/scouting/webserver/requests/messages/submit_notes.fbs
index cf111b3..1498e26 100644
--- a/scouting/webserver/requests/messages/submit_notes.fbs
+++ b/scouting/webserver/requests/messages/submit_notes.fbs
@@ -3,6 +3,12 @@
table SubmitNotes {
team:int (id: 0);
notes:string (id: 1);
+ good_driving:bool (id: 2);
+ bad_driving:bool (id: 3);
+ sketchy_climb:bool (id: 4);
+ solid_climb:bool (id: 5);
+ good_defense:bool (id: 6);
+ bad_defense:bool (id: 7);
}
root_type SubmitNotes;
diff --git a/scouting/webserver/requests/requests.go b/scouting/webserver/requests/requests.go
index 67a1722..12bc3da 100644
--- a/scouting/webserver/requests/requests.go
+++ b/scouting/webserver/requests/requests.go
@@ -27,6 +27,8 @@
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_shift_schedule_response"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting_response"
+ "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_driver_ranking"
+ "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_driver_ranking_response"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes_response"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_shift_schedule"
@@ -53,6 +55,8 @@
type RequestShiftScheduleResponseT = request_shift_schedule_response.RequestShiftScheduleResponseT
type SubmitShiftSchedule = submit_shift_schedule.SubmitShiftSchedule
type SubmitShiftScheduleResponseT = submit_shift_schedule_response.SubmitShiftScheduleResponseT
+type SubmitDriverRanking = submit_driver_ranking.SubmitDriverRanking
+type SubmitDriverRankingResponseT = submit_driver_ranking_response.SubmitDriverRankingResponseT
// The interface we expect the database abstraction to conform to.
// We use an interface here because it makes unit testing easier.
@@ -66,8 +70,9 @@
QueryMatches(int32) ([]db.Match, error)
QueryAllShifts(int) ([]db.Shift, error)
QueryStats(int) ([]db.Stats, error)
- QueryNotes(int32) (db.NotesData, error)
+ QueryNotes(int32) ([]string, error)
AddNotes(db.NotesData) error
+ AddDriverRanking(db.DriverRankingData) error
}
type ScrapeMatchList func(int32, string) ([]scraping.Match, error)
@@ -337,7 +342,33 @@
func parseTeamKey(teamKey string) (int, error) {
// TBA prefixes teams with "frc". Not sure why. Get rid of that.
teamKey = strings.TrimPrefix(teamKey, "frc")
- return strconv.Atoi(teamKey)
+ magnitude := 0
+ if strings.HasSuffix(teamKey, "A") {
+ magnitude = 0
+ teamKey = strings.TrimSuffix(teamKey, "A")
+ } else if strings.HasSuffix(teamKey, "B") {
+ magnitude = 9
+ teamKey = strings.TrimSuffix(teamKey, "B")
+ } else if strings.HasSuffix(teamKey, "C") {
+ magnitude = 8
+ teamKey = strings.TrimSuffix(teamKey, "C")
+ } else if strings.HasSuffix(teamKey, "D") {
+ magnitude = 7
+ teamKey = strings.TrimSuffix(teamKey, "D")
+ } else if strings.HasSuffix(teamKey, "E") {
+ magnitude = 6
+ teamKey = strings.TrimSuffix(teamKey, "E")
+ } else if strings.HasSuffix(teamKey, "F") {
+ magnitude = 5
+ teamKey = strings.TrimSuffix(teamKey, "F")
+ }
+
+ if magnitude != 0 {
+ teamKey = strconv.Itoa(magnitude) + teamKey
+ }
+
+ result, err := strconv.Atoi(teamKey)
+ return result, err
}
// Parses the alliance data from the specified match and returns the three red
@@ -445,8 +476,14 @@
}
err = handler.db.AddNotes(db.NotesData{
- TeamNumber: request.Team(),
- Notes: []string{string(request.Notes())},
+ TeamNumber: request.Team(),
+ Notes: string(request.Notes()),
+ GoodDriving: bool(request.GoodDriving()),
+ BadDriving: bool(request.BadDriving()),
+ SketchyClimb: bool(request.SketchyClimb()),
+ SolidClimb: bool(request.SolidClimb()),
+ GoodDefense: bool(request.GoodDefense()),
+ BadDefense: bool(request.BadDefense()),
})
if err != nil {
respondWithError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to insert notes: %v", err))
@@ -475,14 +512,14 @@
return
}
- notesData, err := handler.db.QueryNotes(request.Team())
+ notes, err := handler.db.QueryNotes(request.Team())
if err != nil {
respondWithError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to query notes: %v", err))
return
}
var response RequestNotesForTeamResponseT
- for _, data := range notesData.Notes {
+ for _, data := range notes {
response.Notes = append(response.Notes, &request_notes_for_team_response.NoteT{data})
}
@@ -576,6 +613,40 @@
w.Write(builder.FinishedBytes())
}
+type SubmitDriverRankingHandler struct {
+ db Database
+}
+
+func (handler SubmitDriverRankingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ requestBytes, err := io.ReadAll(req.Body)
+ if err != nil {
+ respondWithError(w, http.StatusBadRequest, fmt.Sprint("Failed to read request bytes:", err))
+ return
+ }
+
+ request, success := parseRequest(w, requestBytes, "SubmitDriverRanking", submit_driver_ranking.GetRootAsSubmitDriverRanking)
+ if !success {
+ return
+ }
+
+ err = handler.db.AddDriverRanking(db.DriverRankingData{
+ MatchNumber: request.MatchNumber(),
+ Rank1: request.Rank1(),
+ Rank2: request.Rank2(),
+ Rank3: request.Rank3(),
+ })
+
+ if err != nil {
+ respondWithError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to insert driver ranking: %v", err))
+ return
+ }
+
+ var response SubmitDriverRankingResponseT
+ builder := flatbuffers.NewBuilder(10)
+ builder.Finish((&response).Pack(builder))
+ w.Write(builder.FinishedBytes())
+}
+
func HandleRequests(db Database, scrape ScrapeMatchList, scoutingServer server.ScoutingServer) {
scoutingServer.HandleFunc("/requests", unknown)
scoutingServer.Handle("/requests/submit/data_scouting", submitDataScoutingHandler{db})
@@ -587,4 +658,5 @@
scoutingServer.Handle("/requests/request/notes_for_team", requestNotesForTeamHandler{db})
scoutingServer.Handle("/requests/submit/shift_schedule", submitShiftScheduleHandler{db})
scoutingServer.Handle("/requests/request/shift_schedule", requestShiftScheduleHandler{db})
+ scoutingServer.Handle("/requests/submit/submit_driver_ranking", SubmitDriverRankingHandler{db})
}
diff --git a/scouting/webserver/requests/requests_test.go b/scouting/webserver/requests/requests_test.go
index 44fd5db..55b789b 100644
--- a/scouting/webserver/requests/requests_test.go
+++ b/scouting/webserver/requests/requests_test.go
@@ -24,6 +24,7 @@
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_shift_schedule_response"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting_response"
+ "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_driver_ranking"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_shift_schedule"
"github.com/frc971/971-Robot-Code/scouting/webserver/server"
@@ -314,8 +315,14 @@
builder := flatbuffers.NewBuilder(1024)
builder.Finish((&submit_notes.SubmitNotesT{
- Team: 971,
- Notes: "Notes",
+ Team: 971,
+ Notes: "Notes",
+ GoodDriving: true,
+ BadDriving: false,
+ SketchyClimb: true,
+ SolidClimb: false,
+ GoodDefense: true,
+ BadDefense: false,
}).Pack(builder))
_, err := debug.SubmitNotes("http://localhost:8080", builder.FinishedBytes())
@@ -324,7 +331,16 @@
}
expected := []db.NotesData{
- {TeamNumber: 971, Notes: []string{"Notes"}},
+ {
+ TeamNumber: 971,
+ Notes: "Notes",
+ GoodDriving: true,
+ BadDriving: false,
+ SketchyClimb: true,
+ SolidClimb: false,
+ GoodDefense: true,
+ BadDefense: false,
+ },
}
if !reflect.DeepEqual(database.notes, expected) {
@@ -335,8 +351,14 @@
func TestRequestNotes(t *testing.T) {
database := MockDatabase{
notes: []db.NotesData{{
- TeamNumber: 971,
- Notes: []string{"Notes"},
+ TeamNumber: 971,
+ Notes: "Notes",
+ GoodDriving: true,
+ BadDriving: false,
+ SketchyClimb: true,
+ SolidClimb: false,
+ GoodDefense: true,
+ BadDefense: false,
}},
}
scoutingServer := server.NewScoutingServer()
@@ -539,14 +561,44 @@
}
}
+func TestSubmitDriverRanking(t *testing.T) {
+ database := MockDatabase{}
+ scoutingServer := server.NewScoutingServer()
+ HandleRequests(&database, scrapeEmtpyMatchList, scoutingServer)
+ scoutingServer.Start(8080)
+ defer scoutingServer.Stop()
+
+ builder := flatbuffers.NewBuilder(1024)
+ builder.Finish((&submit_driver_ranking.SubmitDriverRankingT{
+ MatchNumber: 36,
+ Rank1: 1234,
+ Rank2: 1235,
+ Rank3: 1236,
+ }).Pack(builder))
+
+ _, err := debug.SubmitDriverRanking("http://localhost:8080", builder.FinishedBytes())
+ if err != nil {
+ t.Fatal("Failed to submit driver ranking: ", err)
+ }
+
+ expected := []db.DriverRankingData{
+ {MatchNumber: 36, Rank1: 1234, Rank2: 1235, Rank3: 1236},
+ }
+
+ if !reflect.DeepEqual(database.driver_ranking, expected) {
+ t.Fatal("Submitted notes did not match", expected, database.notes)
+ }
+}
+
// A mocked database we can use for testing. Add functionality to this as
// needed for your tests.
type MockDatabase struct {
- matches []db.Match
- stats []db.Stats
- notes []db.NotesData
- shiftSchedule []db.Shift
+ matches []db.Match
+ stats []db.Stats
+ notes []db.NotesData
+ shiftSchedule []db.Shift
+ driver_ranking []db.DriverRankingData
}
func (database *MockDatabase) AddToMatch(match db.Match) error {
@@ -584,14 +636,14 @@
return []db.Stats{}, nil
}
-func (database *MockDatabase) QueryNotes(requestedTeam int32) (db.NotesData, error) {
+func (database *MockDatabase) QueryNotes(requestedTeam int32) ([]string, error) {
var results []string
for _, data := range database.notes {
if data.TeamNumber == requestedTeam {
- results = append(results, data.Notes[0])
+ results = append(results, data.Notes)
}
}
- return db.NotesData{TeamNumber: requestedTeam, Notes: results}, nil
+ return results, nil
}
func (database *MockDatabase) AddNotes(data db.NotesData) error {
@@ -612,6 +664,11 @@
return []db.Shift{}, nil
}
+func (database *MockDatabase) AddDriverRanking(data db.DriverRankingData) error {
+ database.driver_ranking = append(database.driver_ranking, data)
+ return nil
+}
+
// Returns an empty match list from the fake The Blue Alliance scraping.
func scrapeEmtpyMatchList(int32, string) ([]scraping.Match, error) {
return nil, nil
diff --git a/scouting/www/BUILD b/scouting/www/BUILD
index 0b7cebb..ee0659b 100644
--- a/scouting/www/BUILD
+++ b/scouting/www/BUILD
@@ -16,6 +16,7 @@
use_angular_plugin = True,
visibility = ["//visibility:public"],
deps = [
+ "//scouting/www/driver_ranking",
"//scouting/www/entry",
"//scouting/www/import_match_list",
"//scouting/www/match_list",
diff --git a/scouting/www/app.ng.html b/scouting/www/app.ng.html
index 297fd39..d9dbead 100644
--- a/scouting/www/app.ng.html
+++ b/scouting/www/app.ng.html
@@ -40,6 +40,15 @@
<li class="nav-item">
<a
class="nav-link"
+ [class.active]="tabIs('DriverRanking')"
+ (click)="switchTabToGuarded('DriverRanking')"
+ >
+ Driver Ranking
+ </a>
+ </li>
+ <li class="nav-item">
+ <a
+ class="nav-link"
[class.active]="tabIs('ImportMatchList')"
(click)="switchTabToGuarded('ImportMatchList')"
>
@@ -80,6 +89,7 @@
*ngSwitchCase="'Entry'"
></app-entry>
<frc971-notes *ngSwitchCase="'Notes'"></frc971-notes>
+ <app-driver-ranking *ngSwitchCase="'DriverRanking'"></app-driver-ranking>
<app-import-match-list
*ngSwitchCase="'ImportMatchList'"
></app-import-match-list>
diff --git a/scouting/www/app.ts b/scouting/www/app.ts
index 4f95c90..b26f815 100644
--- a/scouting/www/app.ts
+++ b/scouting/www/app.ts
@@ -4,6 +4,7 @@
| 'MatchList'
| 'Notes'
| 'Entry'
+ | 'DriverRanking'
| 'ImportMatchList'
| 'ShiftSchedule'
| 'View';
diff --git a/scouting/www/app_module.ts b/scouting/www/app_module.ts
index 8c18f7a..04d72b3 100644
--- a/scouting/www/app_module.ts
+++ b/scouting/www/app_module.ts
@@ -9,6 +9,7 @@
import {NotesModule} from './notes/notes.module';
import {ShiftScheduleModule} from './shift_schedule/shift_schedule.module';
import {ViewModule} from './view/view.module';
+import {DriverRankingModule} from './driver_ranking/driver_ranking.module';
@NgModule({
declarations: [App],
@@ -20,6 +21,7 @@
ImportMatchListModule,
MatchListModule,
ShiftScheduleModule,
+ DriverRankingModule,
ViewModule,
],
exports: [App],
diff --git a/scouting/www/driver_ranking/BUILD b/scouting/www/driver_ranking/BUILD
new file mode 100644
index 0000000..10b6f99
--- /dev/null
+++ b/scouting/www/driver_ranking/BUILD
@@ -0,0 +1,26 @@
+load("@npm//@bazel/typescript:index.bzl", "ts_library")
+
+ts_library(
+ name = "driver_ranking",
+ srcs = [
+ "driver_ranking.component.ts",
+ "driver_ranking.module.ts",
+ ],
+ angular_assets = [
+ "driver_ranking.component.css",
+ "driver_ranking.ng.html",
+ "//scouting/www:common_css",
+ ],
+ compiler = "//tools:tsc_wrapped_with_angular",
+ target_compatible_with = ["@platforms//cpu:x86_64"],
+ use_angular_plugin = True,
+ visibility = ["//visibility:public"],
+ deps = [
+ "//scouting/webserver/requests/messages:error_response_ts_fbs",
+ "//scouting/webserver/requests/messages:submit_driver_ranking_ts_fbs",
+ "@com_github_google_flatbuffers//ts:flatbuffers_ts",
+ "@npm//@angular/common",
+ "@npm//@angular/core",
+ "@npm//@angular/forms",
+ ],
+)
diff --git a/scouting/www/driver_ranking/driver_ranking.component.css b/scouting/www/driver_ranking/driver_ranking.component.css
new file mode 100644
index 0000000..e220645
--- /dev/null
+++ b/scouting/www/driver_ranking/driver_ranking.component.css
@@ -0,0 +1,3 @@
+* {
+ padding: 10px;
+}
diff --git a/scouting/www/driver_ranking/driver_ranking.component.ts b/scouting/www/driver_ranking/driver_ranking.component.ts
new file mode 100644
index 0000000..aadb3b0
--- /dev/null
+++ b/scouting/www/driver_ranking/driver_ranking.component.ts
@@ -0,0 +1,93 @@
+import {Component, OnInit} from '@angular/core';
+import {Builder, ByteBuffer} from 'flatbuffers';
+import {SubmitDriverRanking} from 'org_frc971/scouting/webserver/requests/messages/submit_driver_ranking_generated';
+import {ErrorResponse} from 'org_frc971/scouting/webserver/requests/messages/error_response_generated';
+
+// TeamSelection: Display form to input which
+// teams to rank and the match number.
+// Data: Display the ranking interface where
+// the scout can reorder teams and submit data.
+type Section = 'TeamSelection' | 'Data';
+
+@Component({
+ selector: 'app-driver-ranking',
+ templateUrl: './driver_ranking.ng.html',
+ styleUrls: ['../common.css', './driver_ranking.component.css'],
+})
+export class DriverRankingComponent {
+ section: Section = 'TeamSelection';
+
+ // Stores the team keys and rank (order of the array).
+ team_ranking: number[] = [971, 972, 973];
+
+ match_number: number = 1;
+
+ errorMessage = '';
+
+ setTeamNumbers() {
+ this.section = 'Data';
+ }
+
+ rankUp(index: number) {
+ if (index > 0) {
+ this.changeRank(index, index - 1);
+ }
+ }
+
+ rankDown(index: number) {
+ if (index < 2) {
+ this.changeRank(index, index + 1);
+ }
+ }
+
+ // Change the rank of a team in team_ranking.
+ // Move the the team at index 'fromIndex'
+ // to the index 'toIndex'.
+ // Ex. Moving the rank 2 (index 1) team to rank1 (index 0)
+ // would be changeRank(1, 0)
+
+ changeRank(fromIndex: number, toIndex: number) {
+ var element = this.team_ranking[fromIndex];
+ this.team_ranking.splice(fromIndex, 1);
+ this.team_ranking.splice(toIndex, 0, element);
+ }
+
+ editTeams() {
+ this.section = 'TeamSelection';
+ }
+
+ async submitData() {
+ const builder = new Builder();
+ builder.finish(
+ SubmitDriverRanking.createSubmitDriverRanking(
+ builder,
+ this.match_number,
+ this.team_ranking[0],
+ this.team_ranking[1],
+ this.team_ranking[2]
+ )
+ );
+ const buffer = builder.asUint8Array();
+ const res = await fetch('/requests/submit/submit_driver_ranking', {
+ method: 'POST',
+ body: buffer,
+ });
+
+ if (!res.ok) {
+ const resBuffer = await res.arrayBuffer();
+ const fbBuffer = new ByteBuffer(new Uint8Array(resBuffer));
+ const parsedResponse = ErrorResponse.getRootAsErrorResponse(fbBuffer);
+
+ const errorMessage = parsedResponse.errorMessage();
+ this.errorMessage = `Received ${res.status} ${res.statusText}: "${errorMessage}"`;
+ return;
+ }
+
+ // Increment the match number.
+ this.match_number = this.match_number + 1;
+
+ // Reset Data.
+ this.section = 'TeamSelection';
+ this.team_ranking = [971, 972, 973];
+ }
+}
diff --git a/scouting/www/driver_ranking/driver_ranking.module.ts b/scouting/www/driver_ranking/driver_ranking.module.ts
new file mode 100644
index 0000000..7fe3623
--- /dev/null
+++ b/scouting/www/driver_ranking/driver_ranking.module.ts
@@ -0,0 +1,11 @@
+import {CommonModule} from '@angular/common';
+import {NgModule} from '@angular/core';
+import {FormsModule} from '@angular/forms';
+import {DriverRankingComponent} from './driver_ranking.component';
+
+@NgModule({
+ declarations: [DriverRankingComponent],
+ exports: [DriverRankingComponent],
+ imports: [CommonModule, FormsModule],
+})
+export class DriverRankingModule {}
diff --git a/scouting/www/driver_ranking/driver_ranking.ng.html b/scouting/www/driver_ranking/driver_ranking.ng.html
new file mode 100644
index 0000000..452359c
--- /dev/null
+++ b/scouting/www/driver_ranking/driver_ranking.ng.html
@@ -0,0 +1,80 @@
+<h2 id="page-title">Driver Ranking</h2>
+
+<ng-container [ngSwitch]="section">
+ <div *ngSwitchCase="'TeamSelection'">
+ <label for="match_number_selection">Match Number</label>
+ <input
+ [(ngModel)]="match_number"
+ type="number"
+ id="match_number_selection"
+ min="1"
+ max="9999"
+ />
+ <br />
+ <br />
+ <label>Team Numbers</label>
+ <input
+ *ngFor="let x of [1,2,3]; let i = index;"
+ [(ngModel)]="team_ranking[i]"
+ type="number"
+ min="1"
+ max="9999"
+ id="team_input_{{i}}"
+ />
+ <button
+ class="btn btn-primary"
+ (click)="setTeamNumbers()"
+ id="select_button"
+ >
+ Select
+ </button>
+ </div>
+ <div *ngSwitchCase="'Data'">
+ <h4 id="match_number_heading">Match #{{match_number}}</h4>
+ <div *ngFor="let team_key of team_ranking; let i = index">
+ <div class="d-flex flex-row justify-content-center pt-2">
+ <div class="d-flex flex-row">
+ <h4 class="align-self-center" id="team_rank_label_{{i}}">
+ {{i + 1}}
+ </h4>
+ <h1 class="align-self-center" id="team_key_label_{{i}}">
+ {{team_key}}
+ </h1>
+ </div>
+ <button
+ class="btn btn-success"
+ (click)="rankUp(i)"
+ id="up_button_{{i}}"
+ >
+ ↑
+ </button>
+ <!--↑ is the html code for an up arrow-->
+ <button
+ class="btn btn-danger"
+ (click)="rankDown(i)"
+ id="down_button_{{i}}"
+ >
+ ↓
+ </button>
+ <!--↓ is the html code for a down arrow-->
+ </div>
+ </div>
+ <div class="d-flex flex-row justify-content-center pt-2">
+ <div>
+ <button class="btn btn-secondary" (click)="editTeams()">
+ Edit Teams
+ </button>
+ </div>
+ <div>
+ <button
+ class="btn btn-success"
+ (click)="submitData()"
+ id="submit_button"
+ >
+ Submit
+ </button>
+ </div>
+ </div>
+ </div>
+ <div class="error">{{errorMessage}}</div>
+</ng-container>
diff --git a/scouting/www/entry/entry.component.css b/scouting/www/entry/entry.component.css
index 6d13657..a78a00a 100644
--- a/scouting/www/entry/entry.component.css
+++ b/scouting/www/entry/entry.component.css
@@ -8,8 +8,8 @@
}
textarea {
- width: 300px;
- height: 150px;
+ width: 350px;
+ height: 180px;
}
button {
diff --git a/scouting/www/entry/entry.ng.html b/scouting/www/entry/entry.ng.html
index 9be8db7..e73cfb0 100644
--- a/scouting/www/entry/entry.ng.html
+++ b/scouting/www/entry/entry.ng.html
@@ -254,10 +254,6 @@
</label>
<br />
</form>
- <div class="row">
- <h4>Comments</h4>
- <textarea [(ngModel)]="comment" id="comment"></textarea>
- </div>
<div class="buttons">
<button class="btn btn-primary" (click)="prevSection()">Back</button>
<button class="btn btn-primary" (click)="nextSection()">Next</button>
@@ -360,6 +356,15 @@
</form>
</div>
+ <div class="row">
+ <h4>General Comments About Match</h4>
+ <textarea
+ [(ngModel)]="comment"
+ id="comment"
+ placeholder="optional"
+ ></textarea>
+ </div>
+
<div class="buttons">
<button class="btn btn-primary" (click)="prevSection()">Back</button>
<button class="btn btn-primary" (click)="nextSection()">Next</button>
@@ -398,7 +403,6 @@
<h4>Climb</h4>
<ul>
<li>Climb Level: {{level | levelToString}}</li>
- <li>Comments: {{comment}}</li>
</ul>
<h4>Other</h4>
@@ -410,6 +414,7 @@
<li>Battery died: {{batteryDied}}</li>
<li>Broke (mechanically): {{mechanicallyBroke}}</li>
<li>Lost coms: {{lostComs}}</li>
+ <li>Comments: {{comment}}</li>
</ul>
<span class="error_message">{{ errorMessage }}</span>
diff --git a/scouting/www/notes/notes.component.css b/scouting/www/notes/notes.component.css
index 869bdab..b601507 100644
--- a/scouting/www/notes/notes.component.css
+++ b/scouting/www/notes/notes.component.css
@@ -4,9 +4,9 @@
.text-input {
width: calc(100% - 20px);
+ height: 100px;
}
-.buttons {
- display: flex;
- justify-content: space-between;
+.container-main {
+ padding-left: 20px;
}
diff --git a/scouting/www/notes/notes.component.ts b/scouting/www/notes/notes.component.ts
index 0f0eb82..f503e2d 100644
--- a/scouting/www/notes/notes.component.ts
+++ b/scouting/www/notes/notes.component.ts
@@ -1,4 +1,4 @@
-import {Component} from '@angular/core';
+import {Component, HostListener} from '@angular/core';
import {Builder, ByteBuffer} from 'flatbuffers';
import {ErrorResponse} from 'org_frc971/scouting/webserver/requests/messages/error_response_generated';
import {RequestNotesForTeam} from 'org_frc971/scouting/webserver/requests/messages/request_notes_for_team_generated';
@@ -9,88 +9,170 @@
import {SubmitNotes} from 'org_frc971/scouting/webserver/requests/messages/submit_notes_generated';
import {SubmitNotesResponse} from 'org_frc971/scouting/webserver/requests/messages/submit_notes_response_generated';
+/*
+For new games, the keywords being used will likely need to be updated.
+To update the keywords complete the following:
+ 1) Update the Keywords Interface and KEYWORD_CHECKBOX_LABELS in notes.component.ts
+ The keys of Keywords and KEYWORD_CHECKBOX_LABELS should match.
+ 2) In notes.component.ts, update the setTeamNumber() method with the new keywords.
+ 3) Add/Edit the new keywords in /scouting/webserver/requests/messages/submit_notes.fbs.
+ 4) In notes.component.ts, update the submitData() method with the newKeywords
+ so that it matches the updated flatbuffer
+ 5) In db.go, update the NotesData struct and the
+ AddNotes method with the new keywords
+ 6) In db_test.go update the TestNotes method so the test uses the keywords
+ 7) Update the submitNoteScoutingHandler in requests.go with the new keywords
+ 8) Finally, update the corresponding test in requests_test.go (TestSubmitNotes)
+
+ Note: If you change the number of keywords you might need to
+ update how they are displayed in notes.ng.html
+*/
+
+// TeamSelection: Display form to add a team to the teams being scouted.
+// Data: Display the note textbox and keyword selection form
+// for all the teams being scouted.
type Section = 'TeamSelection' | 'Data';
-interface Note {
- readonly data: string;
+// Every keyword checkbox corresponds to a boolean.
+// If the boolean is True, the checkbox is selected
+// and the note scout saw that the robot being scouted
+// displayed said property (ex. Driving really well -> goodDriving)
+interface Keywords {
+ goodDriving: boolean;
+ badDriving: boolean;
+ sketchyClimb: boolean;
+ solidClimb: boolean;
+ goodDefense: boolean;
+ badDefense: boolean;
}
+interface Input {
+ teamNumber: number;
+ notesData: string;
+ keywordsData: Keywords;
+}
+
+const KEYWORD_CHECKBOX_LABELS = {
+ goodDriving: 'Good Driving',
+ badDriving: 'Bad Driving',
+ solidClimb: 'Solid Climb',
+ sketchyClimb: 'Sketchy Climb',
+ goodDefense: 'Good Defense',
+ badDefense: 'Bad Defense',
+} as const;
+
@Component({
selector: 'frc971-notes',
templateUrl: './notes.ng.html',
styleUrls: ['../common.css', './notes.component.css'],
})
export class Notes {
+ // Re-export KEYWORD_CHECKBOX_LABELS so that we can
+ // use it in the checkbox properties.
+ readonly KEYWORD_CHECKBOX_LABELS = KEYWORD_CHECKBOX_LABELS;
+
+ // Necessary in order to iterate the keys of KEYWORD_CHECKBOX_LABELS.
+ Object = Object;
+
section: Section = 'TeamSelection';
- notes: Note[] = [];
errorMessage = '';
+ teamNumberSelection: number = 971;
- teamNumber: number = 971;
- newData = '';
+ // Data inputted by user is stored in this array.
+ // Includes the team number, notes, and keyword selection.
+ newData: Input[] = [];
- async setTeamNumber() {
- const builder = new Builder();
- RequestNotesForTeam.startRequestNotesForTeam(builder);
- RequestNotesForTeam.addTeam(builder, this.teamNumber);
- builder.finish(RequestNotesForTeam.endRequestNotesForTeam(builder));
+ // Keyboard shortcuts to switch between text areas.
+ // Listens for Ctrl + number and focuses on the
+ // corresponding textbox.
+ // More Info: https://angular.io/api/core/HostListener
- const buffer = builder.asUint8Array();
- const res = await fetch('/requests/request/notes_for_team', {
- method: 'POST',
- body: buffer,
- });
-
- const resBuffer = await res.arrayBuffer();
- const fbBuffer = new ByteBuffer(new Uint8Array(resBuffer));
-
- if (res.ok) {
- this.notes = [];
- const parsedResponse =
- RequestNotesForTeamResponse.getRootAsRequestNotesForTeamResponse(
- fbBuffer
- );
- for (let i = 0; i < parsedResponse.notesLength(); i++) {
- const fbNote = parsedResponse.notes(i);
- this.notes.push({data: fbNote.data()});
+ @HostListener('window:keyup', ['$event'])
+ onEvent(event: KeyboardEvent) {
+ if (event.ctrlKey) {
+ if (event.code.includes('Digit')) {
+ this.handleFocus(event.key);
}
- this.section = 'Data';
- } else {
- const parsedResponse = ErrorResponse.getRootAsErrorResponse(fbBuffer);
-
- const errorMessage = parsedResponse.errorMessage();
- this.errorMessage = `Received ${res.status} ${res.statusText}: "${errorMessage}"`;
}
}
- changeTeam() {
+ handleFocus(digit: string) {
+ let textArea = <HTMLInputElement>(
+ document.getElementById('text-input-' + digit)
+ );
+ if (textArea != null) {
+ textArea.focus();
+ }
+ }
+
+ setTeamNumber() {
+ let data: Input = {
+ teamNumber: this.teamNumberSelection,
+ notesData: 'Auto: \nTeleop: \nEngame: ',
+ keywordsData: {
+ goodDriving: false,
+ badDriving: false,
+ solidClimb: false,
+ sketchyClimb: false,
+ goodDefense: false,
+ badDefense: false,
+ },
+ };
+
+ this.newData.push(data);
+ this.section = 'Data';
+ }
+
+ removeTeam(index: number) {
+ this.newData.splice(index, 1);
+ if (this.newData.length == 0) {
+ this.section = 'TeamSelection';
+ } else {
+ this.section = 'Data';
+ }
+ }
+
+ addTeam() {
this.section = 'TeamSelection';
}
async submitData() {
- const builder = new Builder();
- const dataFb = builder.createString(this.newData);
- builder.finish(
- SubmitNotes.createSubmitNotes(builder, this.teamNumber, dataFb)
- );
+ for (let i = 0; i < this.newData.length; i++) {
+ const builder = new Builder();
+ const dataFb = builder.createString(this.newData[i].notesData);
- const buffer = builder.asUint8Array();
- const res = await fetch('/requests/submit/submit_notes', {
- method: 'POST',
- body: buffer,
- });
+ builder.finish(
+ SubmitNotes.createSubmitNotes(
+ builder,
+ this.newData[i].teamNumber,
+ dataFb,
+ this.newData[i].keywordsData.goodDriving,
+ this.newData[i].keywordsData.badDriving,
+ this.newData[i].keywordsData.sketchyClimb,
+ this.newData[i].keywordsData.solidClimb,
+ this.newData[i].keywordsData.goodDefense,
+ this.newData[i].keywordsData.badDefense
+ )
+ );
- if (res.ok) {
- this.newData = '';
- this.errorMessage = '';
- await this.setTeamNumber();
- } else {
- const resBuffer = await res.arrayBuffer();
- const fbBuffer = new ByteBuffer(new Uint8Array(resBuffer));
- const parsedResponse = ErrorResponse.getRootAsErrorResponse(fbBuffer);
+ const buffer = builder.asUint8Array();
+ const res = await fetch('/requests/submit/submit_notes', {
+ method: 'POST',
+ body: buffer,
+ });
- const errorMessage = parsedResponse.errorMessage();
- this.errorMessage = `Received ${res.status} ${res.statusText}: "${errorMessage}"`;
+ if (!res.ok) {
+ const resBuffer = await res.arrayBuffer();
+ const fbBuffer = new ByteBuffer(new Uint8Array(resBuffer));
+ const parsedResponse = ErrorResponse.getRootAsErrorResponse(fbBuffer);
+ const errorMessage = parsedResponse.errorMessage();
+ this.errorMessage = `Received ${res.status} ${res.statusText}: "${errorMessage}"`;
+ }
}
+
+ this.newData = [];
+ this.errorMessage = '';
+ this.section = 'TeamSelection';
}
}
diff --git a/scouting/www/notes/notes.ng.html b/scouting/www/notes/notes.ng.html
index a69ba88..b51a7ce 100644
--- a/scouting/www/notes/notes.ng.html
+++ b/scouting/www/notes/notes.ng.html
@@ -1,10 +1,12 @@
-<h2>Notes</h2>
+<h2 id="page-title">Notes</h2>
<ng-container [ngSwitch]="section">
<div *ngSwitchCase="'TeamSelection'">
- <label for="team_number_notes">Team Number</label>
+ <label id="team_number_label" class="label" for="team_number_notes">
+ Team Number
+ </label>
<input
- [(ngModel)]="teamNumber"
+ [(ngModel)]="teamNumberSelection"
type="number"
id="team_number_notes"
min="1"
@@ -14,17 +16,107 @@
</div>
<div *ngSwitchCase="'Data'">
- <h3>Scouting team: {{teamNumber}}</h3>
- <ul *ngFor="let note of notes">
- <li class="note">{{ note.data }}</li>
- </ul>
- <textarea class="text-input" [(ngModel)]="newData"></textarea>
- <div class="buttons">
- <button class="btn btn-primary" (click)="changeTeam()">
- Change team
- </button>
- <button class="btn btn-primary" (click)="submitData()">Submit</button>
+ <div class="container-main" *ngFor="let team of newData; let i = index">
+ <div class="pt-2 pb-2">
+ <div class="d-flex flex-row">
+ <div>
+ <button
+ class="btn bg-transparent ml-10 md-5"
+ (click)="removeTeam(i)"
+ >
+ ✖
+ <!--X Symbol-->
+ </button>
+ </div>
+ <div><h3 id="team-key-{{i+1}}">{{team.teamNumber}}</h3></div>
+ </div>
+ <div class="">
+ <!--
+ Note Input Text Areas.
+ ID property is used for keyboard shorcuts to focus
+ on the corresponding text area.
+ The data-toggle and title properties are
+ used for bootstrap tooltips.
+ -->
+ <textarea
+ class="text-input"
+ id="text-input-{{i+1}}"
+ [(ngModel)]="newData[i].notesData"
+ data-toggle="tooltip"
+ title="Ctrl + {{i+1}}"
+ ></textarea>
+ </div>
+ <!--Key Word Checkboxes-->
+ <!--Row 1 (Prevent Overflow on mobile by splitting checkboxes into 2 rows)-->
+ <!--Slice KEYWORD_CHECKBOX_LABELS using https://angular.io/api/common/SlicePipe-->
+ <div class="d-flex flex-row justify-content-around">
+ <div
+ *ngFor="let key of Object.keys(KEYWORD_CHECKBOX_LABELS) | slice:0:((Object.keys(KEYWORD_CHECKBOX_LABELS).length)/2); let k = index"
+ >
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ [(ngModel)]="newData[i]['keywordsData'][key]"
+ type="checkbox"
+ id="{{KEYWORD_CHECKBOX_LABELS[key]}}_{{i}}"
+ name="{{KEYWORD_CHECKBOX_LABELS[key]}}"
+ />
+ <label
+ class="form-check-label"
+ for="{{KEYWORD_CHECKBOX_LABELS[key]}}_{{i}}"
+ >
+ {{KEYWORD_CHECKBOX_LABELS[key]}}
+ </label>
+ <br />
+ </div>
+ </div>
+ </div>
+ <!--Row 2 (Prevent Overflow on mobile by splitting checkboxes into 2 rows)-->
+ <div class="d-flex flex-row justify-content-around">
+ <div
+ *ngFor="let key of Object.keys(KEYWORD_CHECKBOX_LABELS) | slice:3:(Object.keys(KEYWORD_CHECKBOX_LABELS).length); let k = index"
+ >
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ [(ngModel)]="newData[i]['keywordsData'][key]"
+ type="checkbox"
+ id="{{KEYWORD_CHECKBOX_LABELS[key]}}"
+ name="{{KEYWORD_CHECKBOX_LABELS[key]}}"
+ />
+ <label
+ class="form-check-label"
+ for="{{KEYWORD_CHECKBOX_LABELS[key]}}"
+ >
+ {{KEYWORD_CHECKBOX_LABELS[key]}}
+ </label>
+ <br />
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="d-flex flex-row justify-content-center pt-2">
+ <div>
+ <button
+ id="add-team-button"
+ class="btn btn-secondary"
+ (click)="addTeam()"
+ >
+ Add team
+ </button>
+ </div>
+ <div>
+ <button
+ id="submit-button"
+ class="btn btn-success"
+ (click)="submitData()"
+ >
+ Submit
+ </button>
+ </div>
</div>
</div>
+
<div class="error">{{errorMessage}}</div>
</ng-container>
diff --git a/third_party/foxglove_ws_protocol/BUILD b/third_party/foxglove_ws_protocol/BUILD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/foxglove_ws_protocol/BUILD
diff --git a/third_party/foxglove_ws_protocol/foxglove_ws_protocol.BUILD b/third_party/foxglove_ws_protocol/foxglove_ws_protocol.BUILD
new file mode 100644
index 0000000..01d9a90
--- /dev/null
+++ b/third_party/foxglove_ws_protocol/foxglove_ws_protocol.BUILD
@@ -0,0 +1,19 @@
+# MIT License
+licenses(["notice"])
+
+cc_library(
+ name = "com_github_foxglove_ws-protocol",
+ hdrs = ["cpp/foxglove-websocket/include/foxglove/websocket/server.hpp"],
+ includes = ["cpp/foxglove-websocket/include/"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "@com_github_nlohmann_json//:json",
+ "@com_github_zaphoyd_websocketpp",
+ ],
+)
+
+cc_binary(
+ name = "example_server",
+ srcs = ["cpp/examples/example_server.cpp"],
+ deps = [":com_github_foxglove_ws-protocol"],
+)
diff --git a/third_party/foxglove_ws_protocol/foxglove_ws_protocol.patch b/third_party/foxglove_ws_protocol/foxglove_ws_protocol.patch
new file mode 100644
index 0000000..39eb3da
--- /dev/null
+++ b/third_party/foxglove_ws_protocol/foxglove_ws_protocol.patch
@@ -0,0 +1,78 @@
+# Blue River-specific patches to be able to compile the websocket
+# server against boost and with our compilers/compiler flags.
+diff --git a/cpp/examples/example_server.cpp b/cpp/examples/example_server.cpp
+index c731072..e869e8f 100644
+--- a/cpp/examples/example_server.cpp
++++ b/cpp/examples/example_server.cpp
+@@ -44,7 +44,7 @@ int main() {
+ });
+
+ uint64_t i = 0;
+- std::shared_ptr<asio::steady_timer> timer;
++ std::shared_ptr<boost::asio::steady_timer> timer;
+ std::function<void()> setTimer = [&] {
+ timer = server.getEndpoint().set_timer(200, [&](std::error_code const& ec) {
+ if (ec) {
+@@ -59,7 +59,7 @@ int main() {
+
+ setTimer();
+
+- asio::signal_set signals(server.getEndpoint().get_io_service(), SIGINT);
++ boost::asio::signal_set signals(server.getEndpoint().get_io_service(), SIGINT);
+
+ signals.async_wait([&](std::error_code const& ec, int sig) {
+ if (ec) {
+diff --git a/cpp/foxglove-websocket/include/foxglove/websocket/server.hpp b/cpp/foxglove-websocket/include/foxglove/websocket/server.hpp
+index 16a5e83..8845971 100644
+--- a/cpp/foxglove-websocket/include/foxglove/websocket/server.hpp
++++ b/cpp/foxglove-websocket/include/foxglove/websocket/server.hpp
+@@ -1,6 +1,6 @@
+ #pragma once
+
+-#include <nlohmann/json.hpp>
++#include "single_include/nlohmann/json.hpp"
+ #include <websocketpp/config/asio_no_tls.hpp>
+ #include <websocketpp/server.hpp>
+
+@@ -84,6 +84,9 @@ public:
+ Server& operator=(Server&&) = delete;
+
+ void run();
++ size_t run_for(std::chrono::nanoseconds duration) {
++ return _server.get_io_service().run_for(duration);
++ }
+ void stop();
+
+ ChannelId addChannel(ChannelWithoutId channel);
+@@ -105,6 +108,10 @@ private:
+ std::unordered_map<SubscriptionId, ChannelId> subscriptions;
+ std::unordered_map<ChannelId, std::unordered_set<SubscriptionId>> subscriptionsByChannel;
+
++ ClientInfo(const std::string& name_, const ConnHandle& handle_)
++ : name(name_)
++ , handle(handle_) {}
++
+ ClientInfo(const ClientInfo&) = delete;
+ ClientInfo& operator=(const ClientInfo&) = delete;
+
+@@ -147,7 +154,7 @@ inline Server::Server(uint16_t port, std::string name)
+ _server.set_message_handler(std::bind(&Server::handleMessage, this, _1, _2));
+ _server.set_reuse_addr(true);
+ _server.set_listen_backlog(128);
+- _server.listen(_port);
++ _server.listen(websocketpp::lib::asio::ip::tcp::v4(), _port);
+ _server.start_accept();
+ }
+
+@@ -174,10 +181,7 @@ inline void Server::handleConnectionOpened(ConnHandle hdl) {
+ _server.get_alog().write(
+ websocketpp::log::alevel::app,
+ "Client " + con->get_remote_endpoint() + " connected via " + con->get_resource());
+- _clients.emplace(hdl, ClientInfo{
+- .name = con->get_remote_endpoint(),
+- .handle = hdl,
+- });
++ _clients.emplace(hdl, ClientInfo{con->get_remote_endpoint(), hdl});
+
+ con->send(json({
+ {"op", "serverInfo"},
diff --git a/third_party/websocketpp/BUILD b/third_party/websocketpp/BUILD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/websocketpp/BUILD
diff --git a/third_party/websocketpp/websocketpp.BUILD b/third_party/websocketpp/websocketpp.BUILD
new file mode 100644
index 0000000..ecf12cd
--- /dev/null
+++ b/third_party/websocketpp/websocketpp.BUILD
@@ -0,0 +1,11 @@
+# 3 Clause BSD
+licenses(["notice"])
+
+cc_library(
+ name = "com_github_zaphoyd_websocketpp",
+ hdrs = glob(["websocketpp/**/*.hpp"]),
+ defines = ["_WEBSOCKETPP_CPP11_STL_", "ASIO_STANDALONE"],
+ includes = ["."],
+ visibility = ["//visibility:public"],
+ deps = ["@asio"],
+)
diff --git a/tools/dependency_rewrite b/tools/dependency_rewrite
index bf5d271..80e31a3 100644
--- a/tools/dependency_rewrite
+++ b/tools/dependency_rewrite
@@ -11,6 +11,7 @@
rewrite devsite.ctr-electronics.com/(.*) software.frc971.org/Build-Dependencies/devsite.ctr-electronics.com/$1
rewrite www.openssl.org/(.*) software.frc971.org/Build-Dependencies/www.openssl.org/$1
rewrite zlib.net/(.*) software.frc971.org/Build-Dependencies/zlib.net/$1
+rewrite downloads.sourceforge.net/(.*) software.frc971.org/Build-Dependencies/downloads.sourceforge.net/$1
allow crates.io
allow golang.org
diff --git a/tools/go/go_mirrors.bzl b/tools/go/go_mirrors.bzl
index ee8b1b8..338cc95 100644
--- a/tools/go/go_mirrors.bzl
+++ b/tools/go/go_mirrors.bzl
@@ -1,11 +1,11 @@
# This file is auto-generated. Do not edit.
GO_MIRROR_INFO = {
"co_honnef_go_tools": {
- "filename": "co_honnef_go_tools__v0.0.0-20190523083050-ea95bdfd59fc.zip",
+ "filename": "co_honnef_go_tools__v0.0.1-2019.2.3.zip",
"importpath": "honnef.co/go/tools",
- "sha256": "eeaa82700e96ac5e803d7a9c32363332504beff8fbb1202492b4d43d5a5e7360",
- "strip_prefix": "honnef.co/go/tools@v0.0.0-20190523083050-ea95bdfd59fc",
- "version": "v0.0.0-20190523083050-ea95bdfd59fc",
+ "sha256": "539825114c487680f99df80f6107410e1e53bbfd5deb931b84d1faf2d221638e",
+ "strip_prefix": "honnef.co/go/tools@v0.0.1-2019.2.3",
+ "version": "v0.0.1-2019.2.3",
},
"com_github_antihax_optional": {
"filename": "com_github_antihax_optional__v1.0.0.zip",
@@ -77,6 +77,20 @@
"strip_prefix": "github.com/cockroachdb/apd@v1.1.0",
"version": "v1.1.0",
},
+ "com_github_coreos_go_systemd": {
+ "filename": "com_github_coreos_go_systemd__v0.0.0-20190719114852-fd7a80b32e1f.zip",
+ "importpath": "github.com/coreos/go-systemd",
+ "sha256": "22237f0aed3ab6018a1025c65f4f45b4c05f9aa0c0bb9ec880294273b9a15bf2",
+ "strip_prefix": "github.com/coreos/go-systemd@v0.0.0-20190719114852-fd7a80b32e1f",
+ "version": "v0.0.0-20190719114852-fd7a80b32e1f",
+ },
+ "com_github_creack_pty": {
+ "filename": "com_github_creack_pty__v1.1.7.zip",
+ "importpath": "github.com/creack/pty",
+ "sha256": "e7ea3403784d186aefbe84caed958f8cba2e72a04f30cdb291ece19bec39c8f3",
+ "strip_prefix": "github.com/creack/pty@v1.1.7",
+ "version": "v1.1.7",
+ },
"com_github_davecgh_go_spew": {
"filename": "com_github_davecgh_go_spew__v1.1.1.zip",
"importpath": "github.com/davecgh/go-spew",
@@ -105,6 +119,27 @@
"strip_prefix": "github.com/ghodss/yaml@v1.0.0",
"version": "v1.0.0",
},
+ "com_github_go_kit_log": {
+ "filename": "com_github_go_kit_log__v0.1.0.zip",
+ "importpath": "github.com/go-kit/log",
+ "sha256": "e0676df7357654a000008dfad3b6b211cba3595f32d3e220edd63a4c9d0d9254",
+ "strip_prefix": "github.com/go-kit/log@v0.1.0",
+ "version": "v0.1.0",
+ },
+ "com_github_go_logfmt_logfmt": {
+ "filename": "com_github_go_logfmt_logfmt__v0.5.0.zip",
+ "importpath": "github.com/go-logfmt/logfmt",
+ "sha256": "59a6b59ae3da84f7a58373844ca8d298f5007ce0e173437fc85c26d4fc76ca8b",
+ "strip_prefix": "github.com/go-logfmt/logfmt@v0.5.0",
+ "version": "v0.5.0",
+ },
+ "com_github_go_stack_stack": {
+ "filename": "com_github_go_stack_stack__v1.8.0.zip",
+ "importpath": "github.com/go-stack/stack",
+ "sha256": "78c2667c710f811307038634ffa43af442619acfeaf1efb593aa4e0ded9df48f",
+ "strip_prefix": "github.com/go-stack/stack@v1.8.0",
+ "version": "v1.8.0",
+ },
"com_github_gofrs_uuid": {
"filename": "com_github_gofrs_uuid__v4.0.0+incompatible.zip",
"importpath": "github.com/gofrs/uuid",
@@ -147,6 +182,13 @@
"strip_prefix": "github.com/google/go-querystring@v1.1.0",
"version": "v1.1.0",
},
+ "com_github_google_renameio": {
+ "filename": "com_github_google_renameio__v0.1.0.zip",
+ "importpath": "github.com/google/renameio",
+ "sha256": "b8510bb34078691a20b8e4902d371afe0eb171b2daf953f67cb3960d1926ccf3",
+ "strip_prefix": "github.com/google/renameio@v0.1.0",
+ "version": "v0.1.0",
+ },
"com_github_google_uuid": {
"filename": "com_github_google_uuid__v1.1.2.zip",
"importpath": "github.com/google/uuid",
@@ -161,19 +203,138 @@
"strip_prefix": "github.com/grpc-ecosystem/grpc-gateway@v1.16.0",
"version": "v1.16.0",
},
- "com_github_jackc_fake": {
- "filename": "com_github_jackc_fake__v0.0.0-20150926172116-812a484cc733.zip",
- "importpath": "github.com/jackc/fake",
- "sha256": "bf8b5b51ae03f572a70a0582dc663c5733bba9aca785d39bb0367797148e6d64",
- "strip_prefix": "github.com/jackc/fake@v0.0.0-20150926172116-812a484cc733",
- "version": "v0.0.0-20150926172116-812a484cc733",
+ "com_github_jackc_chunkreader": {
+ "filename": "com_github_jackc_chunkreader__v1.0.0.zip",
+ "importpath": "github.com/jackc/chunkreader",
+ "sha256": "e204c917e2652ffe047f5c8b031192757321f568654e3df8408bf04178df1408",
+ "strip_prefix": "github.com/jackc/chunkreader@v1.0.0",
+ "version": "v1.0.0",
},
- "com_github_jackc_pgx": {
- "filename": "com_github_jackc_pgx__v3.6.2+incompatible.zip",
- "importpath": "github.com/jackc/pgx",
- "sha256": "73675895baa0da97b2f0ce6e895c69b7c77ad994e30ce6a1add2abc3bb17e375",
- "strip_prefix": "github.com/jackc/pgx@v3.6.2+incompatible",
- "version": "v3.6.2+incompatible",
+ "com_github_jackc_chunkreader_v2": {
+ "filename": "com_github_jackc_chunkreader_v2__v2.0.1.zip",
+ "importpath": "github.com/jackc/chunkreader/v2",
+ "sha256": "6e3f4b7d9647f31061f6446ae10de71fc1407e64f84cd0949afac0cd231e8dd2",
+ "strip_prefix": "github.com/jackc/chunkreader/v2@v2.0.1",
+ "version": "v2.0.1",
+ },
+ "com_github_jackc_pgconn": {
+ "filename": "com_github_jackc_pgconn__v1.12.1.zip",
+ "importpath": "github.com/jackc/pgconn",
+ "sha256": "48d34064a1facff7766713d9224502e7376a5d90c1506f99a37c57bfceaf9636",
+ "strip_prefix": "github.com/jackc/pgconn@v1.12.1",
+ "version": "v1.12.1",
+ },
+ "com_github_jackc_pgio": {
+ "filename": "com_github_jackc_pgio__v1.0.0.zip",
+ "importpath": "github.com/jackc/pgio",
+ "sha256": "1a83c03d53f6a40339364cafcbbabb44238203c79ca0c9b98bf582d0df0e0468",
+ "strip_prefix": "github.com/jackc/pgio@v1.0.0",
+ "version": "v1.0.0",
+ },
+ "com_github_jackc_pgmock": {
+ "filename": "com_github_jackc_pgmock__v0.0.0-20210724152146-4ad1a8207f65.zip",
+ "importpath": "github.com/jackc/pgmock",
+ "sha256": "0fffd0a7a67dbdfafa04297e51028c6d2d08cd6691f3b6d78d7ae6502d3d4cf2",
+ "strip_prefix": "github.com/jackc/pgmock@v0.0.0-20210724152146-4ad1a8207f65",
+ "version": "v0.0.0-20210724152146-4ad1a8207f65",
+ },
+ "com_github_jackc_pgpassfile": {
+ "filename": "com_github_jackc_pgpassfile__v1.0.0.zip",
+ "importpath": "github.com/jackc/pgpassfile",
+ "sha256": "1cc79fb0b80f54b568afd3f4648dd1c349f746ad7c379df8d7f9e0eb1cac938b",
+ "strip_prefix": "github.com/jackc/pgpassfile@v1.0.0",
+ "version": "v1.0.0",
+ },
+ "com_github_jackc_pgproto3": {
+ "filename": "com_github_jackc_pgproto3__v1.1.0.zip",
+ "importpath": "github.com/jackc/pgproto3",
+ "sha256": "e3766bee50ed74e49a067b2c4797a2c69015cf104bf3f3624cd483a9e940b4ee",
+ "strip_prefix": "github.com/jackc/pgproto3@v1.1.0",
+ "version": "v1.1.0",
+ },
+ "com_github_jackc_pgproto3_v2": {
+ "filename": "com_github_jackc_pgproto3_v2__v2.3.0.zip",
+ "importpath": "github.com/jackc/pgproto3/v2",
+ "sha256": "6b702c372e13520636243d3be58922968f0630b67e23ba77326ef6ee4cada463",
+ "strip_prefix": "github.com/jackc/pgproto3/v2@v2.3.0",
+ "version": "v2.3.0",
+ },
+ "com_github_jackc_pgservicefile": {
+ "filename": "com_github_jackc_pgservicefile__v0.0.0-20200714003250-2b9c44734f2b.zip",
+ "importpath": "github.com/jackc/pgservicefile",
+ "sha256": "8422a25b9d2b0be05c66ee1ccfdbaab144ce98f1ac678bc647064c560d4cd6e2",
+ "strip_prefix": "github.com/jackc/pgservicefile@v0.0.0-20200714003250-2b9c44734f2b",
+ "version": "v0.0.0-20200714003250-2b9c44734f2b",
+ },
+ "com_github_jackc_pgtype": {
+ "filename": "com_github_jackc_pgtype__v1.11.0.zip",
+ "importpath": "github.com/jackc/pgtype",
+ "sha256": "6a257b81c0bd386d6241219a14ebd41d574a02aeaeb3942670c06441b864dcad",
+ "strip_prefix": "github.com/jackc/pgtype@v1.11.0",
+ "version": "v1.11.0",
+ },
+ "com_github_jackc_pgx_v4": {
+ "filename": "com_github_jackc_pgx_v4__v4.16.1.zip",
+ "importpath": "github.com/jackc/pgx/v4",
+ "sha256": "c3a169a68ff0e56f9f81eee4de4d2fd2a5ec7f4d6be159159325f4863c80bd10",
+ "strip_prefix": "github.com/jackc/pgx/v4@v4.16.1",
+ "version": "v4.16.1",
+ },
+ "com_github_jackc_puddle": {
+ "filename": "com_github_jackc_puddle__v1.2.1.zip",
+ "importpath": "github.com/jackc/puddle",
+ "sha256": "40d73550686666eb1f6df02b65008b2a4c98cfed1254dc4866e6ebe95fbc5c95",
+ "strip_prefix": "github.com/jackc/puddle@v1.2.1",
+ "version": "v1.2.1",
+ },
+ "com_github_jinzhu_inflection": {
+ "filename": "com_github_jinzhu_inflection__v1.0.0.zip",
+ "importpath": "github.com/jinzhu/inflection",
+ "sha256": "cf1087a6f6653ed5f366f85cf0110bbbf581d4e9bc8a4d1a9b56765d94b546c3",
+ "strip_prefix": "github.com/jinzhu/inflection@v1.0.0",
+ "version": "v1.0.0",
+ },
+ "com_github_jinzhu_now": {
+ "filename": "com_github_jinzhu_now__v1.1.4.zip",
+ "importpath": "github.com/jinzhu/now",
+ "sha256": "245473b8e50be3897751ec66dd6be93588de261920e0345b500f692924575872",
+ "strip_prefix": "github.com/jinzhu/now@v1.1.4",
+ "version": "v1.1.4",
+ },
+ "com_github_kisielk_gotool": {
+ "filename": "com_github_kisielk_gotool__v1.0.0.zip",
+ "importpath": "github.com/kisielk/gotool",
+ "sha256": "089dbba6e3aa09944fdb40d72acc86694e8bdde01cfc0f40fe0248309eb80a3f",
+ "strip_prefix": "github.com/kisielk/gotool@v1.0.0",
+ "version": "v1.0.0",
+ },
+ "com_github_konsorten_go_windows_terminal_sequences": {
+ "filename": "com_github_konsorten_go_windows_terminal_sequences__v1.0.2.zip",
+ "importpath": "github.com/konsorten/go-windows-terminal-sequences",
+ "sha256": "4d00d71b8de60bcaf454f8f867210ebcd05e75c0a7c2725904f71aa2f20fb08e",
+ "strip_prefix": "github.com/konsorten/go-windows-terminal-sequences@v1.0.2",
+ "version": "v1.0.2",
+ },
+ "com_github_kr_pretty": {
+ "filename": "com_github_kr_pretty__v0.1.0.zip",
+ "importpath": "github.com/kr/pretty",
+ "sha256": "06063d21457e06dc2aba4a5bd09771147ec3d8ab40b224f26e55c5a76089ca43",
+ "strip_prefix": "github.com/kr/pretty@v0.1.0",
+ "version": "v0.1.0",
+ },
+ "com_github_kr_pty": {
+ "filename": "com_github_kr_pty__v1.1.8.zip",
+ "importpath": "github.com/kr/pty",
+ "sha256": "d66e6fbc65e772289a7ff8c58ab2cdfb886253053b0cea11ba3ca1738b2d6bc6",
+ "strip_prefix": "github.com/kr/pty@v1.1.8",
+ "version": "v1.1.8",
+ },
+ "com_github_kr_text": {
+ "filename": "com_github_kr_text__v0.1.0.zip",
+ "importpath": "github.com/kr/text",
+ "sha256": "9363a4c8f1f3387a36014de51b477b831a13981fc59a5665f9d21609bea9e77c",
+ "strip_prefix": "github.com/kr/text@v0.1.0",
+ "version": "v0.1.0",
},
"com_github_lib_pq": {
"filename": "com_github_lib_pq__v1.10.2.zip",
@@ -182,6 +343,27 @@
"strip_prefix": "github.com/lib/pq@v1.10.2",
"version": "v1.10.2",
},
+ "com_github_masterminds_semver_v3": {
+ "filename": "com_github_masterminds_semver_v3__v3.1.1.zip",
+ "importpath": "github.com/Masterminds/semver/v3",
+ "sha256": "0a46c7403dfeda09b0821e851f8e1cec8f1ea4276281e42ea399da5bc5bf0704",
+ "strip_prefix": "github.com/Masterminds/semver/v3@v3.1.1",
+ "version": "v3.1.1",
+ },
+ "com_github_mattn_go_colorable": {
+ "filename": "com_github_mattn_go_colorable__v0.1.6.zip",
+ "importpath": "github.com/mattn/go-colorable",
+ "sha256": "0da5d3779775f6fe5d007e7ec8e0afc136c4bd7b8c9b5cd73254db26773cf4dc",
+ "strip_prefix": "github.com/mattn/go-colorable@v0.1.6",
+ "version": "v0.1.6",
+ },
+ "com_github_mattn_go_isatty": {
+ "filename": "com_github_mattn_go_isatty__v0.0.12.zip",
+ "importpath": "github.com/mattn/go-isatty",
+ "sha256": "07941d24e0894c29dc42bcd29d644815cd7b5ee84e3c14bbe6d51ad13efcbf07",
+ "strip_prefix": "github.com/mattn/go-isatty@v0.0.12",
+ "version": "v0.0.12",
+ },
"com_github_phst_runfiles": {
"filename": "com_github_phst_runfiles__v0.0.0-20220125203201-388095b3a22d.zip",
"importpath": "github.com/phst/runfiles",
@@ -217,6 +399,34 @@
"strip_prefix": "github.com/rogpeppe/fastuuid@v1.2.0",
"version": "v1.2.0",
},
+ "com_github_rogpeppe_go_internal": {
+ "filename": "com_github_rogpeppe_go_internal__v1.3.0.zip",
+ "importpath": "github.com/rogpeppe/go-internal",
+ "sha256": "191b95c35d85a5683cee6e303a08b4d103bf9de9ececdc6904f21ed90c094b0a",
+ "strip_prefix": "github.com/rogpeppe/go-internal@v1.3.0",
+ "version": "v1.3.0",
+ },
+ "com_github_rs_xid": {
+ "filename": "com_github_rs_xid__v1.2.1.zip",
+ "importpath": "github.com/rs/xid",
+ "sha256": "4abdedc4de69adcb9a4575f99c59d8ab542191e1800b6a91e12a4e9ea8da0026",
+ "strip_prefix": "github.com/rs/xid@v1.2.1",
+ "version": "v1.2.1",
+ },
+ "com_github_rs_zerolog": {
+ "filename": "com_github_rs_zerolog__v1.15.0.zip",
+ "importpath": "github.com/rs/zerolog",
+ "sha256": "8e98c48e7fd132aafbf129664e8fd65229d067d772bff4bd712a497b7a2f00c4",
+ "strip_prefix": "github.com/rs/zerolog@v1.15.0",
+ "version": "v1.15.0",
+ },
+ "com_github_satori_go_uuid": {
+ "filename": "com_github_satori_go_uuid__v1.2.0.zip",
+ "importpath": "github.com/satori/go.uuid",
+ "sha256": "4f741306a0cbe97581e34a638531bcafe3c2848150539a2ec2ba12c5e3e6cbdd",
+ "strip_prefix": "github.com/satori/go.uuid@v1.2.0",
+ "version": "v1.2.0",
+ },
"com_github_shopspring_decimal": {
"filename": "com_github_shopspring_decimal__v1.2.0.zip",
"importpath": "github.com/shopspring/decimal",
@@ -224,12 +434,19 @@
"strip_prefix": "github.com/shopspring/decimal@v1.2.0",
"version": "v1.2.0",
},
+ "com_github_sirupsen_logrus": {
+ "filename": "com_github_sirupsen_logrus__v1.4.2.zip",
+ "importpath": "github.com/sirupsen/logrus",
+ "sha256": "9a8e55830261a4b1c9350d7c45db029c8586c0b2d934d1224cde469425031edd",
+ "strip_prefix": "github.com/sirupsen/logrus@v1.4.2",
+ "version": "v1.4.2",
+ },
"com_github_stretchr_objx": {
- "filename": "com_github_stretchr_objx__v0.1.0.zip",
+ "filename": "com_github_stretchr_objx__v0.2.0.zip",
"importpath": "github.com/stretchr/objx",
- "sha256": "1fa10dab404ed7fc8ed2a033f8784187d5df3513ced3841ce39e46d37850eb1d",
- "strip_prefix": "github.com/stretchr/objx@v0.1.0",
- "version": "v0.1.0",
+ "sha256": "5517d43cfb7e628b9c2c64010b934e346cd24726e3d6eaf02b7f86e10752e968",
+ "strip_prefix": "github.com/stretchr/objx@v0.2.0",
+ "version": "v0.2.0",
},
"com_github_stretchr_testify": {
"filename": "com_github_stretchr_testify__v1.7.0.zip",
@@ -238,6 +455,13 @@
"strip_prefix": "github.com/stretchr/testify@v1.7.0",
"version": "v1.7.0",
},
+ "com_github_zenazn_goji": {
+ "filename": "com_github_zenazn_goji__v0.9.0.zip",
+ "importpath": "github.com/zenazn/goji",
+ "sha256": "0807a255d9d715d18427a6eedd8e4f5a22670b09e5f45fddd229c1ae38da25a9",
+ "strip_prefix": "github.com/zenazn/goji@v0.9.0",
+ "version": "v0.9.0",
+ },
"com_google_cloud_go": {
"filename": "com_google_cloud_go__v0.34.0.zip",
"importpath": "cloud.google.com/go",
@@ -246,11 +470,25 @@
"version": "v0.34.0",
},
"in_gopkg_check_v1": {
- "filename": "in_gopkg_check_v1__v0.0.0-20161208181325-20d25e280405.zip",
+ "filename": "in_gopkg_check_v1__v1.0.0-20180628173108-788fd7840127.zip",
"importpath": "gopkg.in/check.v1",
- "sha256": "4e1817f964ca34e545b81afda0325a5e89cf58de2e413d8207c0afddd0fdc15c",
- "strip_prefix": "gopkg.in/check.v1@v0.0.0-20161208181325-20d25e280405",
- "version": "v0.0.0-20161208181325-20d25e280405",
+ "sha256": "4bc535ed2aac48a231af8b6005a0b5f6069dadab9a3d65b1e9f1fe91c74d8e61",
+ "strip_prefix": "gopkg.in/check.v1@v1.0.0-20180628173108-788fd7840127",
+ "version": "v1.0.0-20180628173108-788fd7840127",
+ },
+ "in_gopkg_errgo_v2": {
+ "filename": "in_gopkg_errgo_v2__v2.1.0.zip",
+ "importpath": "gopkg.in/errgo.v2",
+ "sha256": "6b8954819a20ec52982a206fd3eb94629ff53c5790aa77534e6d8daf7de01bee",
+ "strip_prefix": "gopkg.in/errgo.v2@v2.1.0",
+ "version": "v2.1.0",
+ },
+ "in_gopkg_inconshreveable_log15_v2": {
+ "filename": "in_gopkg_inconshreveable_log15_v2__v2.0.0-20180818164646-67afb5ed74ec.zip",
+ "importpath": "gopkg.in/inconshreveable/log15.v2",
+ "sha256": "799307ed46ca30ca0ac2dc0332f3673814b8ff6cc1ee905a462ccfd438e8e695",
+ "strip_prefix": "gopkg.in/inconshreveable/log15.v2@v2.0.0-20180818164646-67afb5ed74ec",
+ "version": "v2.0.0-20180818164646-67afb5ed74ec",
},
"in_gopkg_yaml_v2": {
"filename": "in_gopkg_yaml_v2__v2.2.3.zip",
@@ -266,6 +504,20 @@
"strip_prefix": "gopkg.in/yaml.v3@v3.0.0-20200313102051-9f266ea9e77c",
"version": "v3.0.0-20200313102051-9f266ea9e77c",
},
+ "io_gorm_driver_postgres": {
+ "filename": "io_gorm_driver_postgres__v1.3.7.zip",
+ "importpath": "gorm.io/driver/postgres",
+ "sha256": "b38fed3060ea8ee200d50666a9c6230f2c387d4ab930b70dd859b93f5fac7771",
+ "strip_prefix": "gorm.io/driver/postgres@v1.3.7",
+ "version": "v1.3.7",
+ },
+ "io_gorm_gorm": {
+ "filename": "io_gorm_gorm__v1.23.5.zip",
+ "importpath": "gorm.io/gorm",
+ "sha256": "34219a6d2ac9b9c340f811e5863a98b150db6d1fd5b8f02777299863c1628e0f",
+ "strip_prefix": "gorm.io/gorm@v1.23.5",
+ "version": "v1.23.5",
+ },
"io_opentelemetry_go_proto_otlp": {
"filename": "io_opentelemetry_go_proto_otlp__v0.7.0.zip",
"importpath": "go.opentelemetry.io/proto/otlp",
@@ -302,11 +554,11 @@
"version": "v1.26.0",
},
"org_golang_x_crypto": {
- "filename": "org_golang_x_crypto__v0.0.0-20210711020723-a769d52b0f97.zip",
+ "filename": "org_golang_x_crypto__v0.0.0-20210921155107-089bfa567519.zip",
"importpath": "golang.org/x/crypto",
- "sha256": "b2b28fcf49bf385183f0369851145ddd93989f68d9e675db536a3dd482ca6d76",
- "strip_prefix": "golang.org/x/crypto@v0.0.0-20210711020723-a769d52b0f97",
- "version": "v0.0.0-20210711020723-a769d52b0f97",
+ "sha256": "eb2426a7891915213cc5da1da7b6fc6e9e2cf253d518d8e169e038e287f414e3",
+ "strip_prefix": "golang.org/x/crypto@v0.0.0-20210921155107-089bfa567519",
+ "version": "v0.0.0-20210921155107-089bfa567519",
},
"org_golang_x_exp": {
"filename": "org_golang_x_exp__v0.0.0-20190121172915-509febef88a4.zip",
@@ -316,11 +568,18 @@
"version": "v0.0.0-20190121172915-509febef88a4",
},
"org_golang_x_lint": {
- "filename": "org_golang_x_lint__v0.0.0-20190313153728-d0100b6bd8b3.zip",
+ "filename": "org_golang_x_lint__v0.0.0-20190930215403-16217165b5de.zip",
"importpath": "golang.org/x/lint",
- "sha256": "5c7bb9792bdc4ec4cf1af525cf9998f8a958daf6495852c9a7dbb71738f2f10a",
- "strip_prefix": "golang.org/x/lint@v0.0.0-20190313153728-d0100b6bd8b3",
- "version": "v0.0.0-20190313153728-d0100b6bd8b3",
+ "sha256": "91323fe1a77f13de722a0ce8efc5c5f2da4f26216d858acec64cb23c956fa163",
+ "strip_prefix": "golang.org/x/lint@v0.0.0-20190930215403-16217165b5de",
+ "version": "v0.0.0-20190930215403-16217165b5de",
+ },
+ "org_golang_x_mod": {
+ "filename": "org_golang_x_mod__v0.1.1-0.20191105210325-c90efee705ee.zip",
+ "importpath": "golang.org/x/mod",
+ "sha256": "b1e6cb975c69d29974b4f77fd8a0f2f7e916a1fa971bab60fdd45ffe80a29f32",
+ "strip_prefix": "golang.org/x/mod@v0.1.1-0.20191105210325-c90efee705ee",
+ "version": "v0.1.1-0.20191105210325-c90efee705ee",
},
"org_golang_x_net": {
"filename": "org_golang_x_net__v0.0.0-20210226172049-e18ecbb05110.zip",
@@ -358,18 +617,18 @@
"version": "v0.0.0-20201126162022-7de9c90e9dd1",
},
"org_golang_x_text": {
- "filename": "org_golang_x_text__v0.3.6.zip",
+ "filename": "org_golang_x_text__v0.3.7.zip",
"importpath": "golang.org/x/text",
- "sha256": "2afade648a4cb240afb7b3bf8e3719b615169c90d6281bd6d4ba34629c744579",
- "strip_prefix": "golang.org/x/text@v0.3.6",
- "version": "v0.3.6",
+ "sha256": "e1a9115e61a38da8bdc893d0ba83b65f89cc1114f152a98eb572c5ea6551e8d4",
+ "strip_prefix": "golang.org/x/text@v0.3.7",
+ "version": "v0.3.7",
},
"org_golang_x_tools": {
- "filename": "org_golang_x_tools__v0.0.0-20190524140312-2c0ae7006135.zip",
+ "filename": "org_golang_x_tools__v0.0.0-20200103221440-774c71fcf114.zip",
"importpath": "golang.org/x/tools",
- "sha256": "86687e8cd5adccf8809ba031e59146d0c89047b6267aacc785ffc20b0ce6b735",
- "strip_prefix": "golang.org/x/tools@v0.0.0-20190524140312-2c0ae7006135",
- "version": "v0.0.0-20190524140312-2c0ae7006135",
+ "sha256": "1c26b6b98d945255dfb6112d71135de3919350250e44e552a7089f724d0b7bfc",
+ "strip_prefix": "golang.org/x/tools@v0.0.0-20200103221440-774c71fcf114",
+ "version": "v0.0.0-20200103221440-774c71fcf114",
},
"org_golang_x_xerrors": {
"filename": "org_golang_x_xerrors__v0.0.0-20200804184101-5ec99f83aff1.zip",
@@ -378,4 +637,32 @@
"strip_prefix": "golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1",
"version": "v0.0.0-20200804184101-5ec99f83aff1",
},
+ "org_uber_go_atomic": {
+ "filename": "org_uber_go_atomic__v1.6.0.zip",
+ "importpath": "go.uber.org/atomic",
+ "sha256": "c5e1e9f48017d7c7f7bb4532235e33242a1508bee68abe3cd301b68fe8ecd552",
+ "strip_prefix": "go.uber.org/atomic@v1.6.0",
+ "version": "v1.6.0",
+ },
+ "org_uber_go_multierr": {
+ "filename": "org_uber_go_multierr__v1.5.0.zip",
+ "importpath": "go.uber.org/multierr",
+ "sha256": "64053b7f6129cf2588f9b9ef1e934a26a0381da0002add973ec99f1294c1fc1e",
+ "strip_prefix": "go.uber.org/multierr@v1.5.0",
+ "version": "v1.5.0",
+ },
+ "org_uber_go_tools": {
+ "filename": "org_uber_go_tools__v0.0.0-20190618225709-2cfd321de3ee.zip",
+ "importpath": "go.uber.org/tools",
+ "sha256": "988dba9c5074080240d33d98e8ce511532f728698db7a9a4ac316c02c94030d6",
+ "strip_prefix": "go.uber.org/tools@v0.0.0-20190618225709-2cfd321de3ee",
+ "version": "v0.0.0-20190618225709-2cfd321de3ee",
+ },
+ "org_uber_go_zap": {
+ "filename": "org_uber_go_zap__v1.13.0.zip",
+ "importpath": "go.uber.org/zap",
+ "sha256": "4b4d15be7b4ce8029ab7c90f2fcb4c98e655172ebaa5cdbe234401081000fa26",
+ "strip_prefix": "go.uber.org/zap@v1.13.0",
+ "version": "v1.13.0",
+ },
}
diff --git a/tools/python/generate_pip_packages_in_docker.sh b/tools/python/generate_pip_packages_in_docker.sh
index a3af2ae..13d51b7 100755
--- a/tools/python/generate_pip_packages_in_docker.sh
+++ b/tools/python/generate_pip_packages_in_docker.sh
@@ -101,6 +101,17 @@
"${PIP_BIN[@]}" install auditwheel
for wheel in "${wheels_built_from_source[@]}"; do
wheel_path="${SCRIPT_DIR}/wheelhouse_tmp/${wheel}"
+
+ # Skip the pygobject wheel for now. I have no idea why, but repairing it will
+ # prevent it from finding certain files. Possibly some issue with paths
+ # relative to the .so file.
+ # TODO(phil): Figure out what's wrong with the repaired wheel.
+ if [[ "${wheel}" == PyGObject-*.whl ]]; then
+ echo "Not repairing ${wheel} because of issues."
+ cp "${wheel_path}" "${SCRIPT_DIR}"/wheelhouse/
+ continue
+ fi
+
echo "Repairing wheel ${wheel}"
if ! auditwheel show "${wheel_path}"; then
echo "Assuming ${wheel} is a non-platform wheel. Skipping."
diff --git a/tools/python/requirements.lock.txt b/tools/python/requirements.lock.txt
index a48b2a7..93ac065 100644
--- a/tools/python/requirements.lock.txt
+++ b/tools/python/requirements.lock.txt
@@ -4,9 +4,9 @@
#
# bazel run //tools/python:requirements.update
#
-certifi==2022.9.14 \
- --hash=sha256:36973885b9542e6bd01dea287b2b4b3b21236307c56324fcc3f1160f2d655ed5 \
- --hash=sha256:e232343de1ab72c2aa521b625c80f699e356830fd0e2c620b465b304b17b0516
+certifi==2022.9.24 \
+ --hash=sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14 \
+ --hash=sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382
# via requests
charset-normalizer==2.1.1 \
--hash=sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845 \
@@ -16,13 +16,84 @@
--hash=sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e \
--hash=sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48
# via mkdocs
+contourpy==1.0.6 \
+ --hash=sha256:0236875c5a0784215b49d00ebbe80c5b6b5d5244b3655a36dda88105334dea17 \
+ --hash=sha256:03d1b9c6b44a9e30d554654c72be89af94fab7510b4b9f62356c64c81cec8b7d \
+ --hash=sha256:0537cc1195245bbe24f2913d1f9211b8f04eb203de9044630abd3664c6cc339c \
+ --hash=sha256:06ca79e1efbbe2df795822df2fa173d1a2b38b6e0f047a0ec7903fbca1d1847e \
+ --hash=sha256:08e8d09d96219ace6cb596506fb9b64ea5f270b2fb9121158b976d88871fcfd1 \
+ --hash=sha256:0b1e66346acfb17694d46175a0cea7d9036f12ed0c31dfe86f0f405eedde2bdd \
+ --hash=sha256:0b97454ed5b1368b66ed414c754cba15b9750ce69938fc6153679787402e4cdf \
+ --hash=sha256:0e4854cc02006ad6684ce092bdadab6f0912d131f91c2450ce6dbdea78ee3c0b \
+ --hash=sha256:12a7dc8439544ed05c6553bf026d5e8fa7fad48d63958a95d61698df0e00092b \
+ --hash=sha256:1b1ee48a130da4dd0eb8055bbab34abf3f6262957832fd575e0cab4979a15a41 \
+ --hash=sha256:1c0e1308307a75e07d1f1b5f0f56b5af84538a5e9027109a7bcf6cb47c434e72 \
+ --hash=sha256:1dedf4c64185a216c35eb488e6f433297c660321275734401760dafaeb0ad5c2 \
+ --hash=sha256:208bc904889c910d95aafcf7be9e677726df9ef71e216780170dbb7e37d118fa \
+ --hash=sha256:211dfe2bd43bf5791d23afbe23a7952e8ac8b67591d24be3638cabb648b3a6eb \
+ --hash=sha256:341330ed19074f956cb20877ad8d2ae50e458884bfa6a6df3ae28487cc76c768 \
+ --hash=sha256:344cb3badf6fc7316ad51835f56ac387bdf86c8e1b670904f18f437d70da4183 \
+ --hash=sha256:358f6364e4873f4d73360b35da30066f40387dd3c427a3e5432c6b28dd24a8fa \
+ --hash=sha256:371f6570a81dfdddbb837ba432293a63b4babb942a9eb7aaa699997adfb53278 \
+ --hash=sha256:375d81366afd547b8558c4720337218345148bc2fcffa3a9870cab82b29667f2 \
+ --hash=sha256:3a1917d3941dd58732c449c810fa7ce46cc305ce9325a11261d740118b85e6f3 \
+ --hash=sha256:4081918147fc4c29fad328d5066cfc751da100a1098398742f9f364be63803fc \
+ --hash=sha256:444fb776f58f4906d8d354eb6f6ce59d0a60f7b6a720da6c1ccb839db7c80eb9 \
+ --hash=sha256:46deb310a276cc5c1fd27958e358cce68b1e8a515fa5a574c670a504c3a3fe30 \
+ --hash=sha256:494efed2c761f0f37262815f9e3c4bb9917c5c69806abdee1d1cb6611a7174a0 \
+ --hash=sha256:50627bf76abb6ba291ad08db583161939c2c5fab38c38181b7833423ab9c7de3 \
+ --hash=sha256:5641927cc5ae66155d0c80195dc35726eae060e7defc18b7ab27600f39dd1fe7 \
+ --hash=sha256:5b117d29433fc8393b18a696d794961464e37afb34a6eeb8b2c37b5f4128a83e \
+ --hash=sha256:613c665529899b5d9fade7e5d1760111a0b011231277a0d36c49f0d3d6914bd6 \
+ --hash=sha256:6e459ebb8bb5ee4c22c19cc000174f8059981971a33ce11e17dddf6aca97a142 \
+ --hash=sha256:6f56515e7c6fae4529b731f6c117752247bef9cdad2b12fc5ddf8ca6a50965a5 \
+ --hash=sha256:730c27978a0003b47b359935478b7d63fd8386dbb2dcd36c1e8de88cbfc1e9de \
+ --hash=sha256:75a2e638042118118ab39d337da4c7908c1af74a8464cad59f19fbc5bbafec9b \
+ --hash=sha256:78ced51807ccb2f45d4ea73aca339756d75d021069604c2fccd05390dc3c28eb \
+ --hash=sha256:7ee394502026d68652c2824348a40bf50f31351a668977b51437131a90d777ea \
+ --hash=sha256:8468b40528fa1e15181cccec4198623b55dcd58306f8815a793803f51f6c474a \
+ --hash=sha256:84c593aeff7a0171f639da92cb86d24954bbb61f8a1b530f74eb750a14685832 \
+ --hash=sha256:913bac9d064cff033cf3719e855d4f1db9f1c179e0ecf3ba9fdef21c21c6a16a \
+ --hash=sha256:9447c45df407d3ecb717d837af3b70cfef432138530712263730783b3d016512 \
+ --hash=sha256:9b0e7fe7f949fb719b206548e5cde2518ffb29936afa4303d8a1c4db43dcb675 \
+ --hash=sha256:9bc407a6af672da20da74823443707e38ece8b93a04009dca25856c2d9adadb1 \
+ --hash=sha256:9e8e686a6db92a46111a1ee0ee6f7fbfae4048f0019de207149f43ac1812cf95 \
+ --hash=sha256:9fc4e7973ed0e1fe689435842a6e6b330eb7ccc696080dda9a97b1a1b78e41db \
+ --hash=sha256:a457ee72d9032e86730f62c5eeddf402e732fdf5ca8b13b41772aa8ae13a4563 \
+ --hash=sha256:a628bba09ba72e472bf7b31018b6281fd4cc903f0888049a3724afba13b6e0b8 \
+ --hash=sha256:a79d239fc22c3b8d9d3de492aa0c245533f4f4c7608e5749af866949c0f1b1b9 \
+ --hash=sha256:aa4674cf3fa2bd9c322982644967f01eed0c91bb890f624e0e0daf7a5c3383e9 \
+ --hash=sha256:acd2bd02f1a7adff3a1f33e431eb96ab6d7987b039d2946a9b39fe6fb16a1036 \
+ --hash=sha256:b3b1bd7577c530eaf9d2bc52d1a93fef50ac516a8b1062c3d1b9bcec9ebe329b \
+ --hash=sha256:b48d94386f1994db7c70c76b5808c12e23ed7a4ee13693c2fc5ab109d60243c0 \
+ --hash=sha256:b64f747e92af7da3b85631a55d68c45a2d728b4036b03cdaba4bd94bcc85bd6f \
+ --hash=sha256:b98c820608e2dca6442e786817f646d11057c09a23b68d2b3737e6dcb6e4a49b \
+ --hash=sha256:c1baa49ab9fedbf19d40d93163b7d3e735d9cd8d5efe4cce9907902a6dad391f \
+ --hash=sha256:c38c6536c2d71ca2f7e418acaf5bca30a3af7f2a2fa106083c7d738337848dbe \
+ --hash=sha256:c78bfbc1a7bff053baf7e508449d2765964d67735c909b583204e3240a2aca45 \
+ --hash=sha256:cd2bc0c8f2e8de7dd89a7f1c10b8844e291bca17d359373203ef2e6100819edd \
+ --hash=sha256:d2eff2af97ea0b61381828b1ad6cd249bbd41d280e53aea5cccd7b2b31b8225c \
+ --hash=sha256:d8834c14b8c3dd849005e06703469db9bf96ba2d66a3f88ecc539c9a8982e0ee \
+ --hash=sha256:d912f0154a20a80ea449daada904a7eb6941c83281a9fab95de50529bfc3a1da \
+ --hash=sha256:da1ef35fd79be2926ba80fbb36327463e3656c02526e9b5b4c2b366588b74d9a \
+ --hash=sha256:dbe6fe7a1166b1ddd7b6d887ea6fa8389d3f28b5ed3f73a8f40ece1fc5a3d340 \
+ --hash=sha256:dcd556c8fc37a342dd636d7eef150b1399f823a4462f8c968e11e1ebeabee769 \
+ --hash=sha256:e13b31d1b4b68db60b3b29f8e337908f328c7f05b9add4b1b5c74e0691180109 \
+ --hash=sha256:e1739496c2f0108013629aa095cc32a8c6363444361960c07493818d0dea2da4 \
+ --hash=sha256:e43255a83835a129ef98f75d13d643844d8c646b258bebd11e4a0975203e018f \
+ --hash=sha256:e626cefff8491bce356221c22af5a3ea528b0b41fbabc719c00ae233819ea0bf \
+ --hash=sha256:eadad75bf91897f922e0fb3dca1b322a58b1726a953f98c2e5f0606bd8408621 \
+ --hash=sha256:f33da6b5d19ad1bb5e7ad38bb8ba5c426d2178928bc2b2c44e8823ea0ecb6ff3 \
+ --hash=sha256:f4052a8a4926d4468416fc7d4b2a7b2a3e35f25b39f4061a7e2a3a2748c4fc48 \
+ --hash=sha256:f6ca38dd8d988eca8f07305125dec6f54ac1c518f1aaddcc14d08c01aebb6efc
+ # via matplotlib
cycler==0.11.0 \
--hash=sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3 \
--hash=sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f
# via matplotlib
-fonttools==4.28.5 \
- --hash=sha256:545c05d0f7903a863c2020e07b8f0a57517f2c40d940bded77076397872d14ca \
- --hash=sha256:edf251d5d2cc0580d5f72de4621c338d8c66c5f61abb50cf486640f73c8194d5
+fonttools==4.38.0 \
+ --hash=sha256:2bb244009f9bf3fa100fc3ead6aeb99febe5985fa20afbfbaa2f8946c2fbdaf1 \
+ --hash=sha256:820466f43c8be8c3009aef8b87e785014133508f0de64ec469e4efb643ae54fb
# via matplotlib
ghp-import==2.1.0 \
--hash=sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619 \
@@ -32,9 +103,9 @@
--hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
--hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
# via requests
-importlib-metadata==5.0.0 \
- --hash=sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab \
- --hash=sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43
+importlib-metadata==5.1.0 \
+ --hash=sha256:d5059f9f1e8e41f80e9c56c2ee58811450c31984dfa625329ffd7c0dad88a73b \
+ --hash=sha256:d84d17e21670ec07990e1044a99efe8d615d860fd176fc29ef5c306068fda313
# via
# markdown
# mkdocs
@@ -44,51 +115,75 @@
# via
# -r tools/python/requirements.txt
# mkdocs
-kiwisolver==1.3.2 \
- --hash=sha256:0007840186bacfaa0aba4466d5890334ea5938e0bb7e28078a0eb0e63b5b59d5 \
- --hash=sha256:19554bd8d54cf41139f376753af1a644b63c9ca93f8f72009d50a2080f870f77 \
- --hash=sha256:1d45d1c74f88b9f41062716c727f78f2a59a5476ecbe74956fafb423c5c87a76 \
- --hash=sha256:1d819553730d3c2724582124aee8a03c846ec4362ded1034c16fb3ef309264e6 \
- --hash=sha256:2210f28778c7d2ee13f3c2a20a3a22db889e75f4ec13a21072eabb5693801e84 \
- --hash=sha256:22521219ca739654a296eea6d4367703558fba16f98688bd8ce65abff36eaa84 \
- --hash=sha256:25405f88a37c5f5bcba01c6e350086d65e7465fd1caaf986333d2a045045a223 \
- --hash=sha256:2b65bd35f3e06a47b5c30ea99e0c2b88f72c6476eedaf8cfbc8e66adb5479dcf \
- --hash=sha256:2ddb500a2808c100e72c075cbb00bf32e62763c82b6a882d403f01a119e3f402 \
- --hash=sha256:2f8f6c8f4f1cff93ca5058d6ec5f0efda922ecb3f4c5fb76181f327decff98b8 \
- --hash=sha256:30fa008c172355c7768159983a7270cb23838c4d7db73d6c0f6b60dde0d432c6 \
- --hash=sha256:3dbb3cea20b4af4f49f84cffaf45dd5f88e8594d18568e0225e6ad9dec0e7967 \
- --hash=sha256:4116ba9a58109ed5e4cb315bdcbff9838f3159d099ba5259c7c7fb77f8537492 \
- --hash=sha256:44e6adf67577dbdfa2d9f06db9fbc5639afefdb5bf2b4dfec25c3a7fbc619536 \
- --hash=sha256:5326ddfacbe51abf9469fe668944bc2e399181a2158cb5d45e1d40856b2a0589 \
- --hash=sha256:70adc3658138bc77a36ce769f5f183169bc0a2906a4f61f09673f7181255ac9b \
- --hash=sha256:72be6ebb4e92520b9726d7146bc9c9b277513a57a38efcf66db0620aec0097e0 \
- --hash=sha256:7843b1624d6ccca403a610d1277f7c28ad184c5aa88a1750c1a999754e65b439 \
- --hash=sha256:7ba5a1041480c6e0a8b11a9544d53562abc2d19220bfa14133e0cdd9967e97af \
- --hash=sha256:80efd202108c3a4150e042b269f7c78643420cc232a0a771743bb96b742f838f \
- --hash=sha256:82f49c5a79d3839bc8f38cb5f4bfc87e15f04cbafa5fbd12fb32c941cb529cfb \
- --hash=sha256:83d2c9db5dfc537d0171e32de160461230eb14663299b7e6d18ca6dca21e4977 \
- --hash=sha256:8d93a1095f83e908fc253f2fb569c2711414c0bfd451cab580466465b235b470 \
- --hash=sha256:8dc3d842fa41a33fe83d9f5c66c0cc1f28756530cd89944b63b072281e852031 \
- --hash=sha256:9661a04ca3c950a8ac8c47f53cbc0b530bce1b52f516a1e87b7736fec24bfff0 \
- --hash=sha256:a498bcd005e8a3fedd0022bb30ee0ad92728154a8798b703f394484452550507 \
- --hash=sha256:a7a4cf5bbdc861987a7745aed7a536c6405256853c94abc9f3287c3fa401b174 \
- --hash=sha256:b5074fb09429f2b7bc82b6fb4be8645dcbac14e592128beeff5461dcde0af09f \
- --hash=sha256:b6a5431940f28b6de123de42f0eb47b84a073ee3c3345dc109ad550a3307dd28 \
- --hash=sha256:ba677bcaff9429fd1bf01648ad0901cea56c0d068df383d5f5856d88221fe75b \
- --hash=sha256:bcadb05c3d4794eb9eee1dddf1c24215c92fb7b55a80beae7a60530a91060560 \
- --hash=sha256:bf7eb45d14fc036514c09554bf983f2a72323254912ed0c3c8e697b62c4c158f \
- --hash=sha256:c358721aebd40c243894298f685a19eb0491a5c3e0b923b9f887ef1193ddf829 \
- --hash=sha256:c4550a359c5157aaf8507e6820d98682872b9100ce7607f8aa070b4b8af6c298 \
- --hash=sha256:c6572c2dab23c86a14e82c245473d45b4c515314f1f859e92608dcafbd2f19b8 \
- --hash=sha256:cba430db673c29376135e695c6e2501c44c256a81495da849e85d1793ee975ad \
- --hash=sha256:dedc71c8eb9c5096037766390172c34fb86ef048b8e8958b4e484b9e505d66bc \
- --hash=sha256:e6f5eb2f53fac7d408a45fbcdeda7224b1cfff64919d0f95473420a931347ae9 \
- --hash=sha256:ec2eba188c1906b05b9b49ae55aae4efd8150c61ba450e6721f64620c50b59eb \
- --hash=sha256:ee040a7de8d295dbd261ef2d6d3192f13e2b08ec4a954de34a6fb8ff6422e24c \
- --hash=sha256:eedd3b59190885d1ebdf6c5e0ca56828beb1949b4dfe6e5d0256a461429ac386 \
- --hash=sha256:f441422bb313ab25de7b3dbfd388e790eceb76ce01a18199ec4944b369017009 \
- --hash=sha256:f8eb7b6716f5b50e9c06207a14172cf2de201e41912ebe732846c02c830455b9 \
- --hash=sha256:fc4453705b81d03568d5b808ad8f09c77c47534f6ac2e72e733f9ca4714aa75c
+kiwisolver==1.4.4 \
+ --hash=sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b \
+ --hash=sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166 \
+ --hash=sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c \
+ --hash=sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c \
+ --hash=sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0 \
+ --hash=sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4 \
+ --hash=sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9 \
+ --hash=sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286 \
+ --hash=sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767 \
+ --hash=sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c \
+ --hash=sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6 \
+ --hash=sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b \
+ --hash=sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004 \
+ --hash=sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf \
+ --hash=sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494 \
+ --hash=sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac \
+ --hash=sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626 \
+ --hash=sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766 \
+ --hash=sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514 \
+ --hash=sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6 \
+ --hash=sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f \
+ --hash=sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d \
+ --hash=sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191 \
+ --hash=sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d \
+ --hash=sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51 \
+ --hash=sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f \
+ --hash=sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8 \
+ --hash=sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454 \
+ --hash=sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb \
+ --hash=sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da \
+ --hash=sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8 \
+ --hash=sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de \
+ --hash=sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a \
+ --hash=sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9 \
+ --hash=sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008 \
+ --hash=sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3 \
+ --hash=sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32 \
+ --hash=sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938 \
+ --hash=sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1 \
+ --hash=sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9 \
+ --hash=sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d \
+ --hash=sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824 \
+ --hash=sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b \
+ --hash=sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd \
+ --hash=sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2 \
+ --hash=sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5 \
+ --hash=sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69 \
+ --hash=sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3 \
+ --hash=sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae \
+ --hash=sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597 \
+ --hash=sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e \
+ --hash=sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955 \
+ --hash=sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca \
+ --hash=sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a \
+ --hash=sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea \
+ --hash=sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede \
+ --hash=sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4 \
+ --hash=sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6 \
+ --hash=sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686 \
+ --hash=sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408 \
+ --hash=sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871 \
+ --hash=sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29 \
+ --hash=sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750 \
+ --hash=sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897 \
+ --hash=sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0 \
+ --hash=sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2 \
+ --hash=sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09 \
+ --hash=sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c
# via matplotlib
markdown==3.3.7 \
--hash=sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874 \
@@ -136,84 +231,89 @@
--hash=sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a \
--hash=sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7
# via jinja2
-matplotlib==3.5.1 \
- --hash=sha256:14334b9902ec776461c4b8c6516e26b450f7ebe0b3ef8703bf5cdfbbaecf774a \
- --hash=sha256:2252bfac85cec7af4a67e494bfccf9080bcba8a0299701eab075f48847cca907 \
- --hash=sha256:2e3484d8455af3fdb0424eae1789af61f6a79da0c80079125112fd5c1b604218 \
- --hash=sha256:34a1fc29f8f96e78ec57a5eff5e8d8b53d3298c3be6df61e7aa9efba26929522 \
- --hash=sha256:3e66497cd990b1a130e21919b004da2f1dc112132c01ac78011a90a0f9229778 \
- --hash=sha256:40e0d7df05e8efe60397c69b467fc8f87a2affeb4d562fe92b72ff8937a2b511 \
- --hash=sha256:456cc8334f6d1124e8ff856b42d2cc1c84335375a16448189999496549f7182b \
- --hash=sha256:506b210cc6e66a0d1c2bb765d055f4f6bc2745070fb1129203b67e85bbfa5c18 \
- --hash=sha256:53273c5487d1c19c3bc03b9eb82adaf8456f243b97ed79d09dded747abaf1235 \
- --hash=sha256:577ed20ec9a18d6bdedb4616f5e9e957b4c08563a9f985563a31fd5b10564d2a \
- --hash=sha256:6803299cbf4665eca14428d9e886de62e24f4223ac31ab9c5d6d5339a39782c7 \
- --hash=sha256:68fa30cec89b6139dc559ed6ef226c53fd80396da1919a1b5ef672c911aaa767 \
- --hash=sha256:6c094e4bfecd2fa7f9adffd03d8abceed7157c928c2976899de282f3600f0a3d \
- --hash=sha256:778d398c4866d8e36ee3bf833779c940b5f57192fa0a549b3ad67bc4c822771b \
- --hash=sha256:7a350ca685d9f594123f652ba796ee37219bf72c8e0fc4b471473d87121d6d34 \
- --hash=sha256:87900c67c0f1728e6db17c6809ec05c025c6624dcf96a8020326ea15378fe8e7 \
- --hash=sha256:8a77906dc2ef9b67407cec0bdbf08e3971141e535db888974a915be5e1e3efc6 \
- --hash=sha256:8e70ae6475cfd0fad3816dcbf6cac536dc6f100f7474be58d59fa306e6e768a4 \
- --hash=sha256:abf67e05a1b7f86583f6ebd01f69b693b9c535276f4e943292e444855870a1b8 \
- --hash=sha256:b04fc29bcef04d4e2d626af28d9d892be6aba94856cb46ed52bcb219ceac8943 \
- --hash=sha256:b19a761b948e939a9e20173aaae76070025f0024fc8f7ba08bef22a5c8573afc \
- --hash=sha256:b2e9810e09c3a47b73ce9cab5a72243a1258f61e7900969097a817232246ce1c \
- --hash=sha256:b71f3a7ca935fc759f2aed7cec06cfe10bc3100fadb5dbd9c435b04e557971e1 \
- --hash=sha256:b8a4fb2a0c5afbe9604f8a91d7d0f27b1832c3e0b5e365f95a13015822b4cd65 \
- --hash=sha256:bb1c613908f11bac270bc7494d68b1ef6e7c224b7a4204d5dacf3522a41e2bc3 \
- --hash=sha256:d24e5bb8028541ce25e59390122f5e48c8506b7e35587e5135efcb6471b4ac6c \
- --hash=sha256:d70a32ee1f8b55eed3fd4e892f0286df8cccc7e0475c11d33b5d0a148f5c7599 \
- --hash=sha256:e293b16cf303fe82995e41700d172a58a15efc5331125d08246b520843ef21ee \
- --hash=sha256:e2f28a07b4f82abb40267864ad7b3a4ed76f1b1663e81c7efc84a9b9248f672f \
- --hash=sha256:e3520a274a0e054e919f5b3279ee5dbccf5311833819ccf3399dab7c83e90a25 \
- --hash=sha256:e3b6f3fd0d8ca37861c31e9a7cab71a0ef14c639b4c95654ea1dd153158bf0df \
- --hash=sha256:e486f60db0cd1c8d68464d9484fd2a94011c1ac8593d765d0211f9daba2bd535 \
- --hash=sha256:e8c87cdaf06fd7b2477f68909838ff4176f105064a72ca9d24d3f2a29f73d393 \
- --hash=sha256:edf5e4e1d5fb22c18820e8586fb867455de3b109c309cb4fce3aaed85d9468d1 \
- --hash=sha256:fe8d40c434a8e2c68d64c6d6a04e77f21791a93ff6afe0dce169597c110d3079
+matplotlib==3.6.2 \
+ --hash=sha256:0844523dfaaff566e39dbfa74e6f6dc42e92f7a365ce80929c5030b84caa563a \
+ --hash=sha256:0eda9d1b43f265da91fb9ae10d6922b5a986e2234470a524e6b18f14095b20d2 \
+ --hash=sha256:168093410b99f647ba61361b208f7b0d64dde1172b5b1796d765cd243cadb501 \
+ --hash=sha256:1836f366272b1557a613f8265db220eb8dd883202bbbabe01bad5a4eadfd0c95 \
+ --hash=sha256:19d61ee6414c44a04addbe33005ab1f87539d9f395e25afcbe9a3c50ce77c65c \
+ --hash=sha256:252957e208c23db72ca9918cb33e160c7833faebf295aaedb43f5b083832a267 \
+ --hash=sha256:32d29c8c26362169c80c5718ce367e8c64f4dd068a424e7110df1dd2ed7bd428 \
+ --hash=sha256:380d48c15ec41102a2b70858ab1dedfa33eb77b2c0982cb65a200ae67a48e9cb \
+ --hash=sha256:3964934731fd7a289a91d315919cf757f293969a4244941ab10513d2351b4e83 \
+ --hash=sha256:3cef89888a466228fc4e4b2954e740ce8e9afde7c4315fdd18caa1b8de58ca17 \
+ --hash=sha256:4426c74761790bff46e3d906c14c7aab727543293eed5a924300a952e1a3a3c1 \
+ --hash=sha256:5024b8ed83d7f8809982d095d8ab0b179bebc07616a9713f86d30cf4944acb73 \
+ --hash=sha256:52c2bdd7cd0bf9d5ccdf9c1816568fd4ccd51a4d82419cc5480f548981b47dd0 \
+ --hash=sha256:54fa9fe27f5466b86126ff38123261188bed568c1019e4716af01f97a12fe812 \
+ --hash=sha256:5ba73aa3aca35d2981e0b31230d58abb7b5d7ca104e543ae49709208d8ce706a \
+ --hash=sha256:5e16dcaecffd55b955aa5e2b8a804379789c15987e8ebd2f32f01398a81e975b \
+ --hash=sha256:5ecfc6559132116dedfc482d0ad9df8a89dc5909eebffd22f3deb684132d002f \
+ --hash=sha256:74153008bd24366cf099d1f1e83808d179d618c4e32edb0d489d526523a94d9f \
+ --hash=sha256:78ec3c3412cf277e6252764ee4acbdbec6920cc87ad65862272aaa0e24381eee \
+ --hash=sha256:795ad83940732b45d39b82571f87af0081c120feff2b12e748d96bb191169e33 \
+ --hash=sha256:7f716b6af94dc1b6b97c46401774472f0867e44595990fe80a8ba390f7a0a028 \
+ --hash=sha256:83dc89c5fd728fdb03b76f122f43b4dcee8c61f1489e232d9ad0f58020523e1c \
+ --hash=sha256:8a0ae37576ed444fe853709bdceb2be4c7df6f7acae17b8378765bd28e61b3ae \
+ --hash=sha256:8a8dbe2cb7f33ff54b16bb5c500673502a35f18ac1ed48625e997d40c922f9cc \
+ --hash=sha256:8a9d899953c722b9afd7e88dbefd8fb276c686c3116a43c577cfabf636180558 \
+ --hash=sha256:8d0068e40837c1d0df6e3abf1cdc9a34a6d2611d90e29610fa1d2455aeb4e2e5 \
+ --hash=sha256:9347cc6822f38db2b1d1ce992f375289670e595a2d1c15961aacbe0977407dfc \
+ --hash=sha256:9f335e5625feb90e323d7e3868ec337f7b9ad88b5d633f876e3b778813021dab \
+ --hash=sha256:b03fd10a1709d0101c054883b550f7c4c5e974f751e2680318759af005964990 \
+ --hash=sha256:b0ca2c60d3966dfd6608f5f8c49b8a0fcf76de6654f2eda55fc6ef038d5a6f27 \
+ --hash=sha256:b2604c6450f9dd2c42e223b1f5dca9643a23cfecc9fde4a94bb38e0d2693b136 \
+ --hash=sha256:ca0e7a658fbafcddcaefaa07ba8dae9384be2343468a8e011061791588d839fa \
+ --hash=sha256:d0e9ac04065a814d4cf2c6791a2ad563f739ae3ae830d716d54245c2b96fead6 \
+ --hash=sha256:d50e8c1e571ee39b5dfbc295c11ad65988879f68009dd281a6e1edbc2ff6c18c \
+ --hash=sha256:d840adcad7354be6f2ec28d0706528b0026e4c3934cc6566b84eac18633eab1b \
+ --hash=sha256:e0bbee6c2a5bf2a0017a9b5e397babb88f230e6f07c3cdff4a4c4bc75ed7c617 \
+ --hash=sha256:e5afe0a7ea0e3a7a257907060bee6724a6002b7eec55d0db16fd32409795f3e1 \
+ --hash=sha256:e68be81cd8c22b029924b6d0ee814c337c0e706b8d88495a617319e5dd5441c3 \
+ --hash=sha256:ec9be0f4826cdb3a3a517509dcc5f87f370251b76362051ab59e42b6b765f8c4 \
+ --hash=sha256:f04f97797df35e442ed09f529ad1235d1f1c0f30878e2fe09a2676b71a8801e0 \
+ --hash=sha256:f41e57ad63d336fe50d3a67bb8eaa26c09f6dda6a59f76777a99b8ccd8e26aec
# via -r tools/python/requirements.txt
mergedeep==1.3.4 \
--hash=sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8 \
--hash=sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307
# via mkdocs
-mkdocs==1.4.0 \
- --hash=sha256:ce057e9992f017b8e1496b591b6c242cbd34c2d406e2f9af6a19b97dd6248faa \
- --hash=sha256:e5549a22d59e7cb230d6a791edd2c3d06690908454c0af82edc31b35d57e3069
+mkdocs==1.4.2 \
+ --hash=sha256:8947af423a6d0facf41ea1195b8e1e8c85ad94ac95ae307fe11232e0424b11c5 \
+ --hash=sha256:c8856a832c1e56702577023cd64cc5f84948280c1c0fcc6af4cd39006ea6aa8c
# via -r tools/python/requirements.txt
-numpy==1.21.5 \
- --hash=sha256:00c9fa73a6989895b8815d98300a20ac993c49ac36c8277e8ffeaa3631c0dbbb \
- --hash=sha256:025b497014bc33fc23897859350f284323f32a2fff7654697f5a5fc2a19e9939 \
- --hash=sha256:08de8472d9f7571f9d51b27b75e827f5296295fa78817032e84464be8bb905bc \
- --hash=sha256:1964db2d4a00348b7a60ee9d013c8cb0c566644a589eaa80995126eac3b99ced \
- --hash=sha256:2a9add27d7fc0fdb572abc3b2486eb3b1395da71e0254c5552b2aad2a18b5441 \
- --hash=sha256:2d8adfca843bc46ac199a4645233f13abf2011a0b2f4affc5c37cd552626f27b \
- --hash=sha256:301e408a052fdcda5cdcf03021ebafc3c6ea093021bf9d1aa47c54d48bdad166 \
- --hash=sha256:311283acf880cfcc20369201bd75da907909afc4666966c7895cbed6f9d2c640 \
- --hash=sha256:341dddcfe3b7b6427a28a27baa59af5ad51baa59bfec3264f1ab287aa3b30b13 \
- --hash=sha256:3a5098df115340fb17fc93867317a947e1dcd978c3888c5ddb118366095851f8 \
- --hash=sha256:3c978544be9e04ed12016dd295a74283773149b48f507d69b36f91aa90a643e5 \
- --hash=sha256:3d893b0871322eaa2f8c7072cdb552d8e2b27645b7875a70833c31e9274d4611 \
- --hash=sha256:4fe6a006557b87b352c04596a6e3f12a57d6e5f401d804947bd3188e6b0e0e76 \
- --hash=sha256:507c05c7a37b3683eb08a3ff993bd1ee1e6c752f77c2f275260533b265ecdb6c \
- --hash=sha256:58ca1d7c8aef6e996112d0ce873ac9dfa1eaf4a1196b4ff7ff73880a09923ba7 \
- --hash=sha256:61bada43d494515d5b122f4532af226fdb5ee08fe5b5918b111279843dc6836a \
- --hash=sha256:69a5a8d71c308d7ef33ef72371c2388a90e3495dbb7993430e674006f94797d5 \
- --hash=sha256:6a5928bc6241264dce5ed509e66f33676fc97f464e7a919edc672fb5532221ee \
- --hash=sha256:7b9d6b14fc9a4864b08d1ba57d732b248f0e482c7b2ff55c313137e3ed4d8449 \
- --hash=sha256:a7c4b701ca418cd39e28ec3b496e6388fe06de83f5f0cb74794fa31cfa384c02 \
- --hash=sha256:a7e8f6216f180f3fd4efb73de5d1eaefb5f5a1ee5b645c67333033e39440e63a \
- --hash=sha256:b545ebadaa2b878c8630e5bcdb97fc4096e779f335fc0f943547c1c91540c815 \
- --hash=sha256:c293d3c0321996cd8ffe84215ffe5d269fd9d1d12c6f4ffe2b597a7c30d3e593 \
- --hash=sha256:c5562bcc1a9b61960fc8950ade44d00e3de28f891af0acc96307c73613d18f6e \
- --hash=sha256:ca9c23848292c6fe0a19d212790e62f398fd9609aaa838859be8459bfbe558aa \
- --hash=sha256:cc1b30205d138d1005adb52087ff45708febbef0e420386f58664f984ef56954 \
- --hash=sha256:dbce7adeb66b895c6aaa1fad796aaefc299ced597f6fbd9ceddb0dd735245354 \
- --hash=sha256:dc4b2fb01f1b4ddbe2453468ea0719f4dbb1f5caa712c8b21bb3dd1480cd30d9 \
- --hash=sha256:eed2afaa97ec33b4411995be12f8bdb95c87984eaa28d76cf628970c8a2d689a \
- --hash=sha256:fc7a7d7b0ed72589fd8b8486b9b42a564f10b8762be8bd4d9df94b807af4a089
+numpy==1.23.5 \
+ --hash=sha256:01dd17cbb340bf0fc23981e52e1d18a9d4050792e8fb8363cecbf066a84b827d \
+ --hash=sha256:06005a2ef6014e9956c09ba07654f9837d9e26696a0470e42beedadb78c11b07 \
+ --hash=sha256:09b7847f7e83ca37c6e627682f145856de331049013853f344f37b0c9690e3df \
+ --hash=sha256:0aaee12d8883552fadfc41e96b4c82ee7d794949e2a7c3b3a7201e968c7ecab9 \
+ --hash=sha256:0cbe9848fad08baf71de1a39e12d1b6310f1d5b2d0ea4de051058e6e1076852d \
+ --hash=sha256:1b1766d6f397c18153d40015ddfc79ddb715cabadc04d2d228d4e5a8bc4ded1a \
+ --hash=sha256:33161613d2269025873025b33e879825ec7b1d831317e68f4f2f0f84ed14c719 \
+ --hash=sha256:5039f55555e1eab31124a5768898c9e22c25a65c1e0037f4d7c495a45778c9f2 \
+ --hash=sha256:522e26bbf6377e4d76403826ed689c295b0b238f46c28a7251ab94716da0b280 \
+ --hash=sha256:56e454c7833e94ec9769fa0f86e6ff8e42ee38ce0ce1fa4cbb747ea7e06d56aa \
+ --hash=sha256:58f545efd1108e647604a1b5aa809591ccd2540f468a880bedb97247e72db387 \
+ --hash=sha256:5e05b1c973a9f858c74367553e236f287e749465f773328c8ef31abe18f691e1 \
+ --hash=sha256:7903ba8ab592b82014713c491f6c5d3a1cde5b4a3bf116404e08f5b52f6daf43 \
+ --hash=sha256:8969bfd28e85c81f3f94eb4a66bc2cf1dbdc5c18efc320af34bffc54d6b1e38f \
+ --hash=sha256:92c8c1e89a1f5028a4c6d9e3ccbe311b6ba53694811269b992c0b224269e2398 \
+ --hash=sha256:9c88793f78fca17da0145455f0d7826bcb9f37da4764af27ac945488116efe63 \
+ --hash=sha256:a7ac231a08bb37f852849bbb387a20a57574a97cfc7b6cabb488a4fc8be176de \
+ --hash=sha256:abdde9f795cf292fb9651ed48185503a2ff29be87770c3b8e2a14b0cd7aa16f8 \
+ --hash=sha256:af1da88f6bc3d2338ebbf0e22fe487821ea4d8e89053e25fa59d1d79786e7481 \
+ --hash=sha256:b2a9ab7c279c91974f756c84c365a669a887efa287365a8e2c418f8b3ba73fb0 \
+ --hash=sha256:bf837dc63ba5c06dc8797c398db1e223a466c7ece27a1f7b5232ba3466aafe3d \
+ --hash=sha256:ca51fcfcc5f9354c45f400059e88bc09215fb71a48d3768fb80e357f3b457e1e \
+ --hash=sha256:ce571367b6dfe60af04e04a1834ca2dc5f46004ac1cc756fb95319f64c095a96 \
+ --hash=sha256:d208a0f8729f3fb790ed18a003f3a57895b989b40ea4dce4717e9cf4af62c6bb \
+ --hash=sha256:dbee87b469018961d1ad79b1a5d50c0ae850000b639bcb1b694e9981083243b6 \
+ --hash=sha256:e9f4c4e51567b616be64e05d517c79a8a22f3606499941d97bb76f2ca59f982d \
+ --hash=sha256:f063b69b090c9d918f9df0a12116029e274daf0181df392839661c4c7ec9018a \
+ --hash=sha256:f9a909a8bae284d46bbfdefbdd4a262ba19d3bc9921b1e76126b1d21c3c34135
# via
# -r tools/python/requirements.txt
+ # contourpy
# matplotlib
# opencv-python
# osqp
@@ -228,23 +328,32 @@
--hash=sha256:e6e448b62afc95c5b58f97e87ef84699e6607fe5c58730a03301c52496005cae \
--hash=sha256:f482e78de6e7b0b060ff994ffd859bddc3f7f382bb2019ef157b0ea8ca8712f5
# via -r tools/python/requirements.txt
-osqp==0.6.2.post5 \
- --hash=sha256:26664bd4238f0f92642f532b23e61efba810a6debba0b3117300749f801e9c25 \
- --hash=sha256:4ca601c5008600b3e0a408339be21f9d626c497b0b0c4dbe4ffe6d6dbbed1b9f \
- --hash=sha256:51a315e02a4cb42e1911047ec6b2a44b67a269d4b5d37d7ee737654206915c82 \
- --hash=sha256:648cb4e34caf0ee948b34a1d0b184f5233e30009090884e0d75503f868bf7b1f \
- --hash=sha256:73a307a93fa7ab68b610e08637c95940070a27f11fda5a2e7a7095cfaff3f0ef \
- --hash=sha256:77408f93ed261581fe498505c69480fb8584c8c0da2a2cd0710bb4bae0c872f5 \
- --hash=sha256:8003fc363f707daa46fef3af548e6a580372154d6cd49a7bf2f569ba5f807d15 \
- --hash=sha256:8c2e40e6788b860887d584a9929ad1c0e436aab8f82bb24da7b165034cb04017 \
- --hash=sha256:908d42fb5d1d9cb36d74a8f3db69384ed1813f1a3e755367557395ce7cf05e16 \
- --hash=sha256:b1e30d6fa10ed11a95023d7308ec1588de3f5b049d09a4d0cc49e057f8e9ce47 \
- --hash=sha256:b2fa17aae42a7ed498ec261b33f262bb4b3605e7e8464062159d9fae817f0d61 \
- --hash=sha256:c07602c8747ce7a177d091bb6d47ce8f214997a86b7577ddee4adae43e9ac92f \
- --hash=sha256:c23bb95e6f72c6b253737edb9e4ef47ceccc3d891c287041ed5fe5f173d317bb \
- --hash=sha256:c7b3ae95221ad6f607dc4a69f36b7a0c71ca434ce85dcbf5cfa084770be5b249 \
- --hash=sha256:c9470c5d58535d31080cb693568916a3e837f09dfa94819a85284b36b3626738 \
- --hash=sha256:ff71646bc9d55c5b3a72cc9b4197e51c36d25d8b2bb81f975d3ce7772ff188ec
+osqp==0.6.2.post8 \
+ --hash=sha256:02175818a0b1715ae0aab88a23678a44b269587af0ef655457042ca69a45eddd \
+ --hash=sha256:0a6e36151d088a9196b24fffc6b1d3a8bf79dcf9e7a5bd5f9c76c9ee1e019edf \
+ --hash=sha256:1d635a321686d15aaf2d91b05f41f736333d6adb0639bc14fc1c22b2cfce9c80 \
+ --hash=sha256:1ecbd173c21805b64a0b736d051312241a84327759526505578f83f7dcc81c66 \
+ --hash=sha256:22724b3ac4eaf17582e3ff35cb6660c026e71138f27fc21dbae4f1dc60904c64 \
+ --hash=sha256:23d6bae4a3612f60d5f652d0e5fa4b2ead507cabfff5d930d822057ae6ed6677 \
+ --hash=sha256:2cc3a966afc4c6ef29dbeb92c59aec7479451149bb77f5c318767433da2c1863 \
+ --hash=sha256:2d39020616c8b4fd9b3ec11f96bd3d68f366ab161323ecb9c1f9c7024eda2d28 \
+ --hash=sha256:2f8647e63bba38f57161d80dda251c06c290bb99e4767cc58a37727ee3c8b912 \
+ --hash=sha256:470c07e7dd06588576155133ae9aea62077dbaa4310aa8e387e879403de42369 \
+ --hash=sha256:497a2fb0d14d20185eaa32aa5f98374fe9a57df09ed0aedb2c27c37d0aa54afa \
+ --hash=sha256:52daa25502056aa1643e2d23ee230a7fe1c399e1a8b35a7b5dd2b77c7b356007 \
+ --hash=sha256:58b38557b0a6181dff8f557244758b955ff27384a1f67b83d75e51fd34c9e842 \
+ --hash=sha256:6a009c100eaaf93e9b2b790af61e209090d2a60b629893e21052d7216e572bbe \
+ --hash=sha256:7f888eaa54bac0261cadb145b3bcf8b2da9109cbf53fc4fdbdc6c6f6c04e2bb9 \
+ --hash=sha256:866f1bc2386b15393a68d379447808bbf3c8b2a126b0fc0669b27fcf3985b86c \
+ --hash=sha256:8d4920fb588d861d0d92874cb5b4435db16fe1e36a986d30638106afe374c1a8 \
+ --hash=sha256:ac9c6aaebe56eae33d7545564148a8fab1d71117cbbe0eedbd2c658bc3455df9 \
+ --hash=sha256:b30e7a2f49103622fdad9ed9c127c47afae01f5a8a6994d04803d3d5deadab4e \
+ --hash=sha256:bd956b7af9d524aed60ab41ec47b20519aede28538dea8f3188ad9056c4c0b01 \
+ --hash=sha256:c9705647d7e6171b3baaa68b0c159c43ea69cba22fbdbd8f79f86ae404a3d96f \
+ --hash=sha256:dd4b2ee44ec08253bcafb4d8a45c7d8278caa0bc13ac7ed24aa35249da7f1d2a \
+ --hash=sha256:dea8085760268971985bb3366bf4d5fb2e8291d7013c47e6178abb964cf05b86 \
+ --hash=sha256:e2475e1417e0ff86b5cd363d9dc2796d54f2a42f67a95fc527eb2ed15df6a1ac \
+ --hash=sha256:f30b405ec0e6a2acf52f59e04f1c258480be172f64c2d37c24adcbf2ac400548
# via -r tools/python/requirements.txt
packaging==21.3 \
--hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
@@ -252,70 +361,92 @@
# via
# matplotlib
# mkdocs
-pillow==8.4.0 \
- --hash=sha256:066f3999cb3b070a95c3652712cffa1a748cd02d60ad7b4e485c3748a04d9d76 \
- --hash=sha256:0a0956fdc5defc34462bb1c765ee88d933239f9a94bc37d132004775241a7585 \
- --hash=sha256:0b052a619a8bfcf26bd8b3f48f45283f9e977890263e4571f2393ed8898d331b \
- --hash=sha256:1394a6ad5abc838c5cd8a92c5a07535648cdf6d09e8e2d6df916dfa9ea86ead8 \
- --hash=sha256:1bc723b434fbc4ab50bb68e11e93ce5fb69866ad621e3c2c9bdb0cd70e345f55 \
- --hash=sha256:244cf3b97802c34c41905d22810846802a3329ddcb93ccc432870243211c79fc \
- --hash=sha256:25a49dc2e2f74e65efaa32b153527fc5ac98508d502fa46e74fa4fd678ed6645 \
- --hash=sha256:2e4440b8f00f504ee4b53fe30f4e381aae30b0568193be305256b1462216feff \
- --hash=sha256:3862b7256046fcd950618ed22d1d60b842e3a40a48236a5498746f21189afbbc \
- --hash=sha256:3eb1ce5f65908556c2d8685a8f0a6e989d887ec4057326f6c22b24e8a172c66b \
- --hash=sha256:3f97cfb1e5a392d75dd8b9fd274d205404729923840ca94ca45a0af57e13dbe6 \
- --hash=sha256:493cb4e415f44cd601fcec11c99836f707bb714ab03f5ed46ac25713baf0ff20 \
- --hash=sha256:4acc0985ddf39d1bc969a9220b51d94ed51695d455c228d8ac29fcdb25810e6e \
- --hash=sha256:5503c86916d27c2e101b7f71c2ae2cddba01a2cf55b8395b0255fd33fa4d1f1a \
- --hash=sha256:5b7bb9de00197fb4261825c15551adf7605cf14a80badf1761d61e59da347779 \
- --hash=sha256:5e9ac5f66616b87d4da618a20ab0a38324dbe88d8a39b55be8964eb520021e02 \
- --hash=sha256:620582db2a85b2df5f8a82ddeb52116560d7e5e6b055095f04ad828d1b0baa39 \
- --hash=sha256:62cc1afda735a8d109007164714e73771b499768b9bb5afcbbee9d0ff374b43f \
- --hash=sha256:70ad9e5c6cb9b8487280a02c0ad8a51581dcbbe8484ce058477692a27c151c0a \
- --hash=sha256:72b9e656e340447f827885b8d7a15fc8c4e68d410dc2297ef6787eec0f0ea409 \
- --hash=sha256:72cbcfd54df6caf85cc35264c77ede902452d6df41166010262374155947460c \
- --hash=sha256:792e5c12376594bfcb986ebf3855aa4b7c225754e9a9521298e460e92fb4a488 \
- --hash=sha256:7b7017b61bbcdd7f6363aeceb881e23c46583739cb69a3ab39cb384f6ec82e5b \
- --hash=sha256:81f8d5c81e483a9442d72d182e1fb6dcb9723f289a57e8030811bac9ea3fef8d \
- --hash=sha256:82aafa8d5eb68c8463b6e9baeb4f19043bb31fefc03eb7b216b51e6a9981ae09 \
- --hash=sha256:84c471a734240653a0ec91dec0996696eea227eafe72a33bd06c92697728046b \
- --hash=sha256:8c803ac3c28bbc53763e6825746f05cc407b20e4a69d0122e526a582e3b5e153 \
- --hash=sha256:93ce9e955cc95959df98505e4608ad98281fff037350d8c2671c9aa86bcf10a9 \
- --hash=sha256:9a3e5ddc44c14042f0844b8cf7d2cd455f6cc80fd7f5eefbe657292cf601d9ad \
- --hash=sha256:a4901622493f88b1a29bd30ec1a2f683782e57c3c16a2dbc7f2595ba01f639df \
- --hash=sha256:a5a4532a12314149d8b4e4ad8ff09dde7427731fcfa5917ff16d0291f13609df \
- --hash=sha256:b8831cb7332eda5dc89b21a7bce7ef6ad305548820595033a4b03cf3091235ed \
- --hash=sha256:b8e2f83c56e141920c39464b852de3719dfbfb6e3c99a2d8da0edf4fb33176ed \
- --hash=sha256:c70e94281588ef053ae8998039610dbd71bc509e4acbc77ab59d7d2937b10698 \
- --hash=sha256:c8a17b5d948f4ceeceb66384727dde11b240736fddeda54ca740b9b8b1556b29 \
- --hash=sha256:d82cdb63100ef5eedb8391732375e6d05993b765f72cb34311fab92103314649 \
- --hash=sha256:d89363f02658e253dbd171f7c3716a5d340a24ee82d38aab9183f7fdf0cdca49 \
- --hash=sha256:d99ec152570e4196772e7a8e4ba5320d2d27bf22fdf11743dd882936ed64305b \
- --hash=sha256:ddc4d832a0f0b4c52fff973a0d44b6c99839a9d016fe4e6a1cb8f3eea96479c2 \
- --hash=sha256:e3dacecfbeec9a33e932f00c6cd7996e62f53ad46fbe677577394aaa90ee419a \
- --hash=sha256:eb9fc393f3c61f9054e1ed26e6fe912c7321af2f41ff49d3f83d05bacf22cc78
+pillow==9.3.0 \
+ --hash=sha256:03150abd92771742d4a8cd6f2fa6246d847dcd2e332a18d0c15cc75bf6703040 \
+ --hash=sha256:073adb2ae23431d3b9bcbcff3fe698b62ed47211d0716b067385538a1b0f28b8 \
+ --hash=sha256:0b07fffc13f474264c336298d1b4ce01d9c5a011415b79d4ee5527bb69ae6f65 \
+ --hash=sha256:0b7257127d646ff8676ec8a15520013a698d1fdc48bc2a79ba4e53df792526f2 \
+ --hash=sha256:12ce4932caf2ddf3e41d17fc9c02d67126935a44b86df6a206cf0d7161548627 \
+ --hash=sha256:15c42fb9dea42465dfd902fb0ecf584b8848ceb28b41ee2b58f866411be33f07 \
+ --hash=sha256:18498994b29e1cf86d505edcb7edbe814d133d2232d256db8c7a8ceb34d18cef \
+ --hash=sha256:1c7c8ae3864846fc95f4611c78129301e203aaa2af813b703c55d10cc1628535 \
+ --hash=sha256:22b012ea2d065fd163ca096f4e37e47cd8b59cf4b0fd47bfca6abb93df70b34c \
+ --hash=sha256:276a5ca930c913f714e372b2591a22c4bd3b81a418c0f6635ba832daec1cbcfc \
+ --hash=sha256:2e0918e03aa0c72ea56edbb00d4d664294815aa11291a11504a377ea018330d3 \
+ --hash=sha256:3033fbe1feb1b59394615a1cafaee85e49d01b51d54de0cbf6aa8e64182518a1 \
+ --hash=sha256:3168434d303babf495d4ba58fc22d6604f6e2afb97adc6a423e917dab828939c \
+ --hash=sha256:32a44128c4bdca7f31de5be641187367fe2a450ad83b833ef78910397db491aa \
+ --hash=sha256:3dd6caf940756101205dffc5367babf288a30043d35f80936f9bfb37f8355b32 \
+ --hash=sha256:40e1ce476a7804b0fb74bcfa80b0a2206ea6a882938eaba917f7a0f004b42502 \
+ --hash=sha256:41e0051336807468be450d52b8edd12ac60bebaa97fe10c8b660f116e50b30e4 \
+ --hash=sha256:4390e9ce199fc1951fcfa65795f239a8a4944117b5935a9317fb320e7767b40f \
+ --hash=sha256:502526a2cbfa431d9fc2a079bdd9061a2397b842bb6bc4239bb176da00993812 \
+ --hash=sha256:51e0e543a33ed92db9f5ef69a0356e0b1a7a6b6a71b80df99f1d181ae5875636 \
+ --hash=sha256:57751894f6618fd4308ed8e0c36c333e2f5469744c34729a27532b3db106ee20 \
+ --hash=sha256:5d77adcd56a42d00cc1be30843d3426aa4e660cab4a61021dc84467123f7a00c \
+ --hash=sha256:655a83b0058ba47c7c52e4e2df5ecf484c1b0b0349805896dd350cbc416bdd91 \
+ --hash=sha256:68943d632f1f9e3dce98908e873b3a090f6cba1cbb1b892a9e8d97c938871fbe \
+ --hash=sha256:6c738585d7a9961d8c2821a1eb3dcb978d14e238be3d70f0a706f7fa9316946b \
+ --hash=sha256:73bd195e43f3fadecfc50c682f5055ec32ee2c933243cafbfdec69ab1aa87cad \
+ --hash=sha256:772a91fc0e03eaf922c63badeca75e91baa80fe2f5f87bdaed4280662aad25c9 \
+ --hash=sha256:77ec3e7be99629898c9a6d24a09de089fa5356ee408cdffffe62d67bb75fdd72 \
+ --hash=sha256:7db8b751ad307d7cf238f02101e8e36a128a6cb199326e867d1398067381bff4 \
+ --hash=sha256:801ec82e4188e935c7f5e22e006d01611d6b41661bba9fe45b60e7ac1a8f84de \
+ --hash=sha256:82409ffe29d70fd733ff3c1025a602abb3e67405d41b9403b00b01debc4c9a29 \
+ --hash=sha256:828989c45c245518065a110434246c44a56a8b2b2f6347d1409c787e6e4651ee \
+ --hash=sha256:829f97c8e258593b9daa80638aee3789b7df9da5cf1336035016d76f03b8860c \
+ --hash=sha256:871b72c3643e516db4ecf20efe735deb27fe30ca17800e661d769faab45a18d7 \
+ --hash=sha256:89dca0ce00a2b49024df6325925555d406b14aa3efc2f752dbb5940c52c56b11 \
+ --hash=sha256:90fb88843d3902fe7c9586d439d1e8c05258f41da473952aa8b328d8b907498c \
+ --hash=sha256:97aabc5c50312afa5e0a2b07c17d4ac5e865b250986f8afe2b02d772567a380c \
+ --hash=sha256:9aaa107275d8527e9d6e7670b64aabaaa36e5b6bd71a1015ddd21da0d4e06448 \
+ --hash=sha256:9f47eabcd2ded7698106b05c2c338672d16a6f2a485e74481f524e2a23c2794b \
+ --hash=sha256:a0a06a052c5f37b4ed81c613a455a81f9a3a69429b4fd7bb913c3fa98abefc20 \
+ --hash=sha256:ab388aaa3f6ce52ac1cb8e122c4bd46657c15905904b3120a6248b5b8b0bc228 \
+ --hash=sha256:ad58d27a5b0262c0c19b47d54c5802db9b34d38bbf886665b626aff83c74bacd \
+ --hash=sha256:ae5331c23ce118c53b172fa64a4c037eb83c9165aba3a7ba9ddd3ec9fa64a699 \
+ --hash=sha256:af0372acb5d3598f36ec0914deed2a63f6bcdb7b606da04dc19a88d31bf0c05b \
+ --hash=sha256:afa4107d1b306cdf8953edde0534562607fe8811b6c4d9a486298ad31de733b2 \
+ --hash=sha256:b03ae6f1a1878233ac620c98f3459f79fd77c7e3c2b20d460284e1fb370557d4 \
+ --hash=sha256:b0915e734b33a474d76c28e07292f196cdf2a590a0d25bcc06e64e545f2d146c \
+ --hash=sha256:b4012d06c846dc2b80651b120e2cdd787b013deb39c09f407727ba90015c684f \
+ --hash=sha256:b472b5ea442148d1c3e2209f20f1e0bb0eb556538690fa70b5e1f79fa0ba8dc2 \
+ --hash=sha256:b59430236b8e58840a0dfb4099a0e8717ffb779c952426a69ae435ca1f57210c \
+ --hash=sha256:b90f7616ea170e92820775ed47e136208e04c967271c9ef615b6fbd08d9af0e3 \
+ --hash=sha256:b9a65733d103311331875c1dca05cb4606997fd33d6acfed695b1232ba1df193 \
+ --hash=sha256:bac18ab8d2d1e6b4ce25e3424f709aceef668347db8637c2296bcf41acb7cf48 \
+ --hash=sha256:bca31dd6014cb8b0b2db1e46081b0ca7d936f856da3b39744aef499db5d84d02 \
+ --hash=sha256:be55f8457cd1eac957af0c3f5ece7bc3f033f89b114ef30f710882717670b2a8 \
+ --hash=sha256:c7025dce65566eb6e89f56c9509d4f628fddcedb131d9465cacd3d8bac337e7e \
+ --hash=sha256:c935a22a557a560108d780f9a0fc426dd7459940dc54faa49d83249c8d3e760f \
+ --hash=sha256:dbb8e7f2abee51cef77673be97760abff1674ed32847ce04b4af90f610144c7b \
+ --hash=sha256:e6ea6b856a74d560d9326c0f5895ef8050126acfdc7ca08ad703eb0081e82b74 \
+ --hash=sha256:ebf2029c1f464c59b8bdbe5143c79fa2045a581ac53679733d3a91d400ff9efb \
+ --hash=sha256:f1ff2ee69f10f13a9596480335f406dd1f70c3650349e2be67ca3139280cade0
# via matplotlib
pkginfo==1.8.3 \
--hash=sha256:848865108ec99d4901b2f7e84058b6e7660aae8ae10164e015a6dcf5b242a594 \
--hash=sha256:a84da4318dd86f870a9447a8c98340aa06216bfc6f2b7bdc4b8766984ae1867c
# via -r tools/python/requirements.txt
-pycairo==1.21.0 \
- --hash=sha256:251907f18a552df938aa3386657ff4b5a4937dde70e11aa042bc297957f4b74b \
- --hash=sha256:26b72b813c6f9d495f71057eab89c13e70a21c92360e9265abc049e0a931fa39 \
- --hash=sha256:31e1c4850db03201d33929cbe1905ce1b33202683ebda7bb0d4dba489115066b \
- --hash=sha256:4357f20a6b1de8f1e8072a74ff68ab4c9a0ae698cd9f5c0f2b2cdd9b28b635f6 \
- --hash=sha256:44a2ecf34968de07b3b9dfdcdbccbd25aa3cab267200f234f84e81481a73bbf6 \
- --hash=sha256:6d37375aab9f2bb6136f076c19815d72108383baae89fbc0d6cb8e5092217d02 \
- --hash=sha256:70936b19f967fa3cb3cd200c2608911227fa5d09dae21c166f64bc15e714ee41 \
- --hash=sha256:dace6b356c476de27f8e1522428ac21a799c225703f746e2957d441f885dcb6c \
- --hash=sha256:f63c153a9ea3d21aff85e2caeee4b0c5d566b2368b4ed64826020d12953d76a4
+pycairo==1.22.0 \
+ --hash=sha256:007ae728c56b9a0962d8c5513ae967a4fceff03e022940383c20f4f3d4c48dbe \
+ --hash=sha256:00c8a6b92c5075ee3be7ea1d33f676d259f11f92cad7e37077dd193437c8c27c \
+ --hash=sha256:356c9fc665e8522f497b6cbe026ad8decacbb04c93e13fd5d145956433f3d471 \
+ --hash=sha256:47aed13e950345c8248f77c8a51bff52188bef7afd3d5169584e0eddc21ba341 \
+ --hash=sha256:5a62cf1d2c6339028709a600d83c0c24111feedeef3cf977bca333fbb94a79c8 \
+ --hash=sha256:62ce5e8c97eeee70170ba9a74845a0ded4bde9b7f1701d88957cbadf8cb1ccd6 \
+ --hash=sha256:9fbe26b3fbe85fde063070e543b4a5f3609569ca8f79680867cecb837d5be29c \
+ --hash=sha256:b34517abdf619d4c7f0274f012b398d9b03bab7adc3efd2912bf36be3f911f3f \
+ --hash=sha256:b85807ec65a8b7966aca7aa41c39016b72515d6401a874a4b52c314471b31865 \
+ --hash=sha256:e31a5b70664c425f4d1b71ba8aaf259920de6937a9490132ffabadad2a89764f \
+ --hash=sha256:e81189414c11340134bffa6dcb06a378976cb87a6742f39aaefc79cb27612250
# via pygobject
pygobject==3.42.2 \
--hash=sha256:21524cef33100c8fd59dc135948b703d79d303e368ce71fa60521cc971cd8aa7
# via -r tools/python/requirements.txt
-pyparsing==3.0.6 \
- --hash=sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4 \
- --hash=sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81
+pyparsing==3.0.9 \
+ --hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb \
+ --hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc
# via
# matplotlib
# packaging
@@ -395,36 +526,28 @@
--hash=sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983 \
--hash=sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349
# via -r tools/python/requirements.txt
-scipy==1.7.3 \
- --hash=sha256:033ce76ed4e9f62923e1f8124f7e2b0800db533828c853b402c7eec6e9465d80 \
- --hash=sha256:173308efba2270dcd61cd45a30dfded6ec0085b4b6eb33b5eb11ab443005e088 \
- --hash=sha256:21b66200cf44b1c3e86495e3a436fc7a26608f92b8d43d344457c54f1c024cbc \
- --hash=sha256:2c56b820d304dffcadbbb6cbfbc2e2c79ee46ea291db17e288e73cd3c64fefa9 \
- --hash=sha256:304dfaa7146cffdb75fbf6bb7c190fd7688795389ad060b970269c8576d038e9 \
- --hash=sha256:3f78181a153fa21c018d346f595edd648344751d7f03ab94b398be2ad083ed3e \
- --hash=sha256:4d242d13206ca4302d83d8a6388c9dfce49fc48fdd3c20efad89ba12f785bf9e \
- --hash=sha256:5d1cc2c19afe3b5a546ede7e6a44ce1ff52e443d12b231823268019f608b9b12 \
- --hash=sha256:5f2cfc359379c56b3a41b17ebd024109b2049f878badc1e454f31418c3a18436 \
- --hash=sha256:65bd52bf55f9a1071398557394203d881384d27b9c2cad7df9a027170aeaef93 \
- --hash=sha256:7edd9a311299a61e9919ea4192dd477395b50c014cdc1a1ac572d7c27e2207fa \
- --hash=sha256:8499d9dd1459dc0d0fe68db0832c3d5fc1361ae8e13d05e6849b358dc3f2c279 \
- --hash=sha256:866ada14a95b083dd727a845a764cf95dd13ba3dc69a16b99038001b05439709 \
- --hash=sha256:87069cf875f0262a6e3187ab0f419f5b4280d3dcf4811ef9613c605f6e4dca95 \
- --hash=sha256:93378f3d14fff07572392ce6a6a2ceb3a1f237733bd6dcb9eb6a2b29b0d19085 \
- --hash=sha256:95c2d250074cfa76715d58830579c64dff7354484b284c2b8b87e5a38321672c \
- --hash=sha256:ab5875facfdef77e0a47d5fd39ea178b58e60e454a4c85aa1e52fcb80db7babf \
- --hash=sha256:b0e0aeb061a1d7dcd2ed59ea57ee56c9b23dd60100825f98238c06ee5cc4467e \
- --hash=sha256:b78a35c5c74d336f42f44106174b9851c783184a85a3fe3e68857259b37b9ffb \
- --hash=sha256:c9e04d7e9b03a8a6ac2045f7c5ef741be86727d8f49c45db45f244bdd2bcff17 \
- --hash=sha256:ca36e7d9430f7481fc7d11e015ae16fbd5575615a8e9060538104778be84addf \
- --hash=sha256:ceebc3c4f6a109777c0053dfa0282fddb8893eddfb0d598574acfb734a926168 \
- --hash=sha256:e2c036492e673aad1b7b0d0ccdc0cb30a968353d2c4bf92ac8e73509e1bf212c \
- --hash=sha256:eb326658f9b73c07081300daba90a8746543b5ea177184daed26528273157294 \
- --hash=sha256:eb7ae2c4dbdb3c9247e07acc532f91077ae6dbc40ad5bd5dca0bb5a176ee9bda \
- --hash=sha256:edad1cf5b2ce1912c4d8ddad20e11d333165552aba262c882e28c78bbc09dbf6 \
- --hash=sha256:eef93a446114ac0193a7b714ce67659db80caf940f3232bad63f4c7a81bc18df \
- --hash=sha256:f7eaea089345a35130bc9a39b89ec1ff69c208efa97b3f8b25ea5d4c41d88094 \
- --hash=sha256:f99d206db1f1ae735a8192ab93bd6028f3a42f6fa08467d37a14eb96c9dd34a3
+scipy==1.9.3 \
+ --hash=sha256:06d2e1b4c491dc7d8eacea139a1b0b295f74e1a1a0f704c375028f8320d16e31 \
+ --hash=sha256:0d54222d7a3ba6022fdf5773931b5d7c56efe41ede7f7128c7b1637700409108 \
+ --hash=sha256:1884b66a54887e21addf9c16fb588720a8309a57b2e258ae1c7986d4444d3bc0 \
+ --hash=sha256:1a72d885fa44247f92743fc20732ae55564ff2a519e8302fb7e18717c5355a8b \
+ --hash=sha256:2318bef588acc7a574f5bfdff9c172d0b1bf2c8143d9582e05f878e580a3781e \
+ --hash=sha256:4db5b30849606a95dcf519763dd3ab6fe9bd91df49eba517359e450a7d80ce2e \
+ --hash=sha256:545c83ffb518094d8c9d83cce216c0c32f8c04aaf28b92cc8283eda0685162d5 \
+ --hash=sha256:5a04cd7d0d3eff6ea4719371cbc44df31411862b9646db617c99718ff68d4840 \
+ --hash=sha256:5b88e6d91ad9d59478fafe92a7c757d00c59e3bdc3331be8ada76a4f8d683f58 \
+ --hash=sha256:68239b6aa6f9c593da8be1509a05cb7f9efe98b80f43a5861cd24c7557e98523 \
+ --hash=sha256:83b89e9586c62e787f5012e8475fbb12185bafb996a03257e9675cd73d3736dd \
+ --hash=sha256:83c06e62a390a9167da60bedd4575a14c1f58ca9dfde59830fc42e5197283dab \
+ --hash=sha256:90453d2b93ea82a9f434e4e1cba043e779ff67b92f7a0e85d05d286a3625df3c \
+ --hash=sha256:abaf921531b5aeaafced90157db505e10345e45038c39e5d9b6c7922d68085cb \
+ --hash=sha256:b41bc822679ad1c9a5f023bc93f6d0543129ca0f37c1ce294dd9d386f0a21096 \
+ --hash=sha256:c68db6b290cbd4049012990d7fe71a2abd9ffbe82c0056ebe0f01df8be5436b0 \
+ --hash=sha256:cff3a5295234037e39500d35316a4c5794739433528310e117b8a9a0c76d20fc \
+ --hash=sha256:d01e1dd7b15bd2449c8bfc6b7cc67d630700ed655654f0dfcf121600bad205c9 \
+ --hash=sha256:d644a64e174c16cb4b2e41dfea6af722053e83d066da7343f333a54dae9bc31c \
+ --hash=sha256:da8245491d73ed0a994ed9c2e380fd058ce2fa8a18da204681f2fe1f57f98f95 \
+ --hash=sha256:fbc5c05c85c1a02be77b1ff591087c83bc44579c6d2bd9fb798bb64ea5e1a027
# via
# -r tools/python/requirements.txt
# osqp
@@ -433,9 +556,9 @@
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
# via python-dateutil
-urllib3==1.26.12 \
- --hash=sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e \
- --hash=sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997
+urllib3==1.26.13 \
+ --hash=sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc \
+ --hash=sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8
# via requests
watchdog==2.1.9 \
--hash=sha256:083171652584e1b8829581f965b9b7723ca5f9a2cd7e20271edf264cfd7c1412 \
@@ -464,7 +587,11 @@
--hash=sha256:ed80a1628cee19f5cfc6bb74e173f1b4189eb532e705e2a13e3250312a62e0c9 \
--hash=sha256:ee3e38a6cc050a8830089f79cbec8a3878ec2fe5160cdb2dc8ccb6def8552658
# via mkdocs
-zipp==3.8.1 \
- --hash=sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2 \
- --hash=sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009
+yapf==0.32.0 \
+ --hash=sha256:8fea849025584e486fd06d6ba2bed717f396080fd3cc236ba10cb97c4c51cf32 \
+ --hash=sha256:a3f5085d37ef7e3e004c4ba9f9b3e40c54ff1901cd111f05145ae313a7c67d1b
+ # via -r tools/python/requirements.txt
+zipp==3.11.0 \
+ --hash=sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa \
+ --hash=sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766
# via importlib-metadata
diff --git a/tools/python/requirements.txt b/tools/python/requirements.txt
index 9bbecbf..a4cbd6a 100644
--- a/tools/python/requirements.txt
+++ b/tools/python/requirements.txt
@@ -11,3 +11,4 @@
pygobject
requests
scipy
+yapf
diff --git a/tools/python/whl_overrides.json b/tools/python/whl_overrides.json
index 81c4701..3d724b9 100644
--- a/tools/python/whl_overrides.json
+++ b/tools/python/whl_overrides.json
@@ -1,7 +1,7 @@
{
- "certifi==2022.9.14": {
- "sha256": "e232343de1ab72c2aa521b625c80f699e356830fd0e2c620b465b304b17b0516",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/certifi-2022.9.14-py3-none-any.whl"
+ "certifi==2022.9.24": {
+ "sha256": "90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/certifi-2022.9.24-py3-none-any.whl"
},
"charset_normalizer==2.1.1": {
"sha256": "83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f",
@@ -11,13 +11,17 @@
"sha256": "bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/click-8.1.3-py3-none-any.whl"
},
+ "contourpy==1.0.6": {
+ "sha256": "1dedf4c64185a216c35eb488e6f433297c660321275734401760dafaeb0ad5c2",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/contourpy-1.0.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
+ },
"cycler==0.11.0": {
"sha256": "3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/cycler-0.11.0-py3-none-any.whl"
},
- "fonttools==4.28.5": {
- "sha256": "edf251d5d2cc0580d5f72de4621c338d8c66c5f61abb50cf486640f73c8194d5",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/fonttools-4.28.5-py3-none-any.whl"
+ "fonttools==4.38.0": {
+ "sha256": "820466f43c8be8c3009aef8b87e785014133508f0de64ec469e4efb643ae54fb",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/fonttools-4.38.0-py3-none-any.whl"
},
"ghp_import==2.1.0": {
"sha256": "8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619",
@@ -27,17 +31,17 @@
"sha256": "90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/idna-3.4-py3-none-any.whl"
},
- "importlib_metadata==5.0.0": {
- "sha256": "ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/importlib_metadata-5.0.0-py3-none-any.whl"
+ "importlib_metadata==5.1.0": {
+ "sha256": "d84d17e21670ec07990e1044a99efe8d615d860fd176fc29ef5c306068fda313",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/importlib_metadata-5.1.0-py3-none-any.whl"
},
"jinja2==3.1.2": {
"sha256": "6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/Jinja2-3.1.2-py3-none-any.whl"
},
- "kiwisolver==1.3.2": {
- "sha256": "30fa008c172355c7768159983a7270cb23838c4d7db73d6c0f6b60dde0d432c6",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/kiwisolver-1.3.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl"
+ "kiwisolver==1.4.4": {
+ "sha256": "7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl"
},
"markdown==3.3.7": {
"sha256": "f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621",
@@ -47,53 +51,53 @@
"sha256": "56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
},
- "matplotlib==3.5.1": {
- "sha256": "87900c67c0f1728e6db17c6809ec05c025c6624dcf96a8020326ea15378fe8e7",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/matplotlib-3.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl"
+ "matplotlib==3.6.2": {
+ "sha256": "795ad83940732b45d39b82571f87af0081c120feff2b12e748d96bb191169e33",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/matplotlib-3.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
},
"mergedeep==1.3.4": {
"sha256": "70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/mergedeep-1.3.4-py3-none-any.whl"
},
- "mkdocs==1.4.0": {
- "sha256": "ce057e9992f017b8e1496b591b6c242cbd34c2d406e2f9af6a19b97dd6248faa",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/mkdocs-1.4.0-py3-none-any.whl"
+ "mkdocs==1.4.2": {
+ "sha256": "c8856a832c1e56702577023cd64cc5f84948280c1c0fcc6af4cd39006ea6aa8c",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/mkdocs-1.4.2-py3-none-any.whl"
},
- "numpy==1.21.5": {
- "sha256": "c293d3c0321996cd8ffe84215ffe5d269fd9d1d12c6f4ffe2b597a7c30d3e593",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/numpy-1.21.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl"
+ "numpy==1.23.5": {
+ "sha256": "33161613d2269025873025b33e879825ec7b1d831317e68f4f2f0f84ed14c719",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/numpy-1.23.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
},
"opencv_python==4.6.0.66": {
"sha256": "dbdc84a9b4ea2cbae33861652d25093944b9959279200b7ae0badd32439f74de",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/opencv_python-4.6.0.66-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
},
- "osqp==0.6.2.post5": {
- "sha256": "8003fc363f707daa46fef3af548e6a580372154d6cd49a7bf2f569ba5f807d15",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/osqp-0.6.2.post5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
+ "osqp==0.6.2.post8": {
+ "sha256": "22724b3ac4eaf17582e3ff35cb6660c026e71138f27fc21dbae4f1dc60904c64",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/osqp-0.6.2.post8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
},
"packaging==21.3": {
"sha256": "ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/packaging-21.3-py3-none-any.whl"
},
- "pillow==8.4.0": {
- "sha256": "b8831cb7332eda5dc89b21a7bce7ef6ad305548820595033a4b03cf3091235ed",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/Pillow-8.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
+ "pillow==9.3.0": {
+ "sha256": "97aabc5c50312afa5e0a2b07c17d4ac5e865b250986f8afe2b02d772567a380c",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/Pillow-9.3.0-cp39-cp39-manylinux_2_28_x86_64.whl"
},
"pkginfo==1.8.3": {
"sha256": "848865108ec99d4901b2f7e84058b6e7660aae8ae10164e015a6dcf5b242a594",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/pkginfo-1.8.3-py2.py3-none-any.whl"
},
- "pycairo==1.21.0": {
- "sha256": "c1fc681494d470c6af4864991ea406d1344680af69e060af06f7e8391c756ac0",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/pycairo-1.21.0-cp39-cp39-manylinux_2_31_x86_64.whl"
+ "pycairo==1.22.0": {
+ "sha256": "6d8325547b2ee5476d317045ca5824901309cc5444dced73bd7d1262b3e18b83",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/pycairo-1.22.0-cp39-cp39-manylinux_2_31_x86_64.whl"
},
"pygobject==3.42.2": {
- "sha256": "0ccbc4a4d8e3697a060fcff16f7c28780b429052e63277ab4efd78ae2ff0b110",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/PyGObject-3.42.2-cp39-cp39-manylinux_2_31_x86_64.whl"
+ "sha256": "c11807320f696b07525b97800570e80a6563a649f2950d66501e13474e5c3a36",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/PyGObject-3.42.2-cp39-cp39-linux_x86_64.whl"
},
- "pyparsing==3.0.6": {
- "sha256": "04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/pyparsing-3.0.6-py3-none-any.whl"
+ "pyparsing==3.0.9": {
+ "sha256": "5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/pyparsing-3.0.9-py3-none-any.whl"
},
"python_dateutil==2.8.2": {
"sha256": "961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9",
@@ -115,24 +119,28 @@
"sha256": "8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/requests-2.28.1-py3-none-any.whl"
},
- "scipy==1.7.3": {
- "sha256": "5d1cc2c19afe3b5a546ede7e6a44ce1ff52e443d12b231823268019f608b9b12",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/scipy-1.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
+ "scipy==1.9.3": {
+ "sha256": "c68db6b290cbd4049012990d7fe71a2abd9ffbe82c0056ebe0f01df8be5436b0",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/scipy-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
},
"six==1.16.0": {
"sha256": "8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/six-1.16.0-py2.py3-none-any.whl"
},
- "urllib3==1.26.12": {
- "sha256": "b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/urllib3-1.26.12-py2.py3-none-any.whl"
+ "urllib3==1.26.13": {
+ "sha256": "47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/urllib3-1.26.13-py2.py3-none-any.whl"
},
"watchdog==2.1.9": {
"sha256": "4f4e1c4aa54fb86316a62a87b3378c025e228178d55481d30d857c6c438897d6",
"url": "https://software.frc971.org/Build-Dependencies/wheelhouse/watchdog-2.1.9-py3-none-manylinux2014_x86_64.whl"
},
- "zipp==3.8.1": {
- "sha256": "47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009",
- "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/zipp-3.8.1-py3-none-any.whl"
+ "yapf==0.32.0": {
+ "sha256": "8fea849025584e486fd06d6ba2bed717f396080fd3cc236ba10cb97c4c51cf32",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/yapf-0.32.0-py2.py3-none-any.whl"
+ },
+ "zipp==3.11.0": {
+ "sha256": "83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa",
+ "url": "https://software.frc971.org/Build-Dependencies/wheelhouse/zipp-3.11.0-py3-none-any.whl"
}
}
diff --git a/y2020/vision/calibration.cc b/y2020/vision/calibration.cc
index b5d1b32..c6bacdb 100644
--- a/y2020/vision/calibration.cc
+++ b/y2020/vision/calibration.cc
@@ -38,11 +38,21 @@
event_loop, pi,
[this](cv::Mat rgb_image,
const aos::monotonic_clock::time_point eof,
- std::vector<int> charuco_ids,
- std::vector<cv::Point2f> charuco_corners, bool valid,
- Eigen::Vector3d rvec_eigen, Eigen::Vector3d tvec_eigen) {
+ std::vector<cv::Vec4i> charuco_ids,
+ std::vector<std::vector<cv::Point2f>> charuco_corners,
+ bool valid, std::vector<Eigen::Vector3d> rvecs_eigen,
+ std::vector<Eigen::Vector3d> tvecs_eigen) {
HandleCharuco(rgb_image, eof, charuco_ids, charuco_corners, valid,
- rvec_eigen, tvec_eigen);
+ rvecs_eigen, tvecs_eigen);
+ }),
+ image_callback_(
+ event_loop,
+ absl::StrCat(
+ "/pi", std::to_string(aos::network::ParsePiNumber(pi).value()),
+ "/camera"),
+ [this](cv::Mat rgb_image,
+ const aos::monotonic_clock::time_point eof) {
+ charuco_extractor_.HandleImage(rgb_image, eof);
}) {
CHECK(pi_number_) << ": Invalid pi number " << pi
<< ", failed to parse pi number";
@@ -50,13 +60,16 @@
CHECK(std::regex_match(camera_id_, re))
<< ": Invalid camera_id '" << camera_id_
<< "', should be of form YY-NN";
+ CHECK_EQ(FLAGS_target_type, "charuco")
+ << "Intrinsic calibration only works with Charuco board";
}
void HandleCharuco(cv::Mat rgb_image,
const aos::monotonic_clock::time_point /*eof*/,
- std::vector<int> charuco_ids,
- std::vector<cv::Point2f> charuco_corners, bool valid,
- Eigen::Vector3d rvec_eigen, Eigen::Vector3d tvec_eigen) {
+ std::vector<cv::Vec4i> charuco_ids,
+ std::vector<std::vector<cv::Point2f>> charuco_corners,
+ bool valid, std::vector<Eigen::Vector3d> rvecs_eigen,
+ std::vector<Eigen::Vector3d> tvecs_eigen) {
// Reduce resolution displayed on remote viewer to prevent lag
cv::resize(rgb_image, rgb_image,
cv::Size(rgb_image.cols / 2, rgb_image.rows / 2));
@@ -78,12 +91,17 @@
if (!valid) {
return;
}
+ CHECK(tvecs_eigen.size() == 1)
+ << "Charuco board should only return one translational pose";
+ CHECK(rvecs_eigen.size() == 1)
+ << "Charuco board should only return one rotational pose";
// Calibration calculates rotation and translation delta from last image
// stored to automatically capture next image
Eigen::Affine3d H_board_camera =
- Eigen::Translation3d(tvec_eigen) *
- Eigen::AngleAxisd(rvec_eigen.norm(), rvec_eigen / rvec_eigen.norm());
+ Eigen::Translation3d(tvecs_eigen[0]) *
+ Eigen::AngleAxisd(rvecs_eigen[0].norm(),
+ rvecs_eigen[0] / rvecs_eigen[0].norm());
Eigen::Affine3d H_camera_board_ = H_board_camera.inverse();
Eigen::Affine3d H_delta = H_board_camera * prev_H_camera_board_;
@@ -97,8 +115,8 @@
bool store_image = false;
double percent_motion =
std::max<double>(r_norm / kDeltaRThreshold, t_norm / kDeltaTThreshold);
- LOG(INFO) << all_charuco_ids_.size() << ": Moved " << percent_motion
- << "% of what's needed";
+ LOG(INFO) << "Captured: " << all_charuco_ids_.size() << " points; Moved "
+ << percent_motion << "% of what's needed";
// Verify that camera has moved enough from last stored image
if (r_norm > kDeltaRThreshold || t_norm > kDeltaTThreshold) {
// frame_ refers to deltas between current and last captured image
@@ -118,9 +136,10 @@
frame_r_norm < kFrameDeltaRLimit && frame_t_norm < kFrameDeltaTLimit;
double percent_stop = std::max<double>(frame_r_norm / kFrameDeltaRLimit,
frame_t_norm / kFrameDeltaTLimit);
- LOG(INFO) << all_charuco_ids_.size() << ": Moved enough ("
- << percent_motion << "%); Need to stop (last motion was "
- << percent_stop << "%";
+ LOG(INFO) << "Captured: " << all_charuco_ids_.size()
+ << "points; Moved enough (" << percent_motion
+ << "%); Need to stop (last motion was " << percent_stop
+ << "% of limit; needs to be < 1 to capture)";
}
prev_image_H_camera_board_ = H_camera_board_;
@@ -128,8 +147,13 @@
if (valid) {
prev_H_camera_board_ = H_camera_board_;
- all_charuco_ids_.emplace_back(std::move(charuco_ids));
- all_charuco_corners_.emplace_back(std::move(charuco_corners));
+ // Unpack the Charuco ids from Vec4i
+ std::vector<int> charuco_ids_int;
+ for (cv::Vec4i charuco_id : charuco_ids) {
+ charuco_ids_int.emplace_back(charuco_id[0]);
+ }
+ all_charuco_ids_.emplace_back(std::move(charuco_ids_int));
+ all_charuco_corners_.emplace_back(std::move(charuco_corners[0]));
if (r_norm > kDeltaRThreshold) {
LOG(INFO) << "Triggered by rotation delta = " << r_norm << " > "
@@ -164,7 +188,8 @@
img_size, cameraMatrix, distCoeffs, rvecs, tvecs,
stdDeviationsIntrinsics, stdDeviationsExtrinsics, perViewErrors,
calibration_flags);
- CHECK_LE(reprojection_error, 1.0) << ": Reproduction error is bad.";
+ CHECK_LE(reprojection_error, 1.0)
+ << ": Reproduction error is bad-- greater than 1 pixel.";
LOG(INFO) << "Reprojection Error is " << reprojection_error;
flatbuffers::FlatBufferBuilder fbb;
@@ -246,6 +271,7 @@
Eigen::Affine3d prev_image_H_camera_board_;
CharucoExtractor charuco_extractor_;
+ ImageCallback image_callback_;
};
namespace {
diff --git a/y2020/vision/extrinsics_calibration.cc b/y2020/vision/extrinsics_calibration.cc
index c561652..cf0c8f2 100644
--- a/y2020/vision/extrinsics_calibration.cc
+++ b/y2020/vision/extrinsics_calibration.cc
@@ -9,6 +9,7 @@
#include "aos/time/time.h"
#include "aos/util/file.h"
#include "frc971/control_loops/quaternion_utils.h"
+#include "frc971/vision/charuco_lib.h"
#include "frc971/vision/vision_generated.h"
#include "frc971/wpilib/imu_batch_generated.h"
#include "y2020/control_loops/superstructure/superstructure_status_generated.h"
@@ -40,6 +41,8 @@
CHECK(aos::configuration::MultiNode(reader.configuration()));
// Find the nodes we care about.
+ const aos::Node *const imu_node =
+ aos::configuration::GetNode(factory.configuration(), "imu");
const aos::Node *const roborio_node =
aos::configuration::GetNode(factory.configuration(), "roborio");
@@ -49,17 +52,20 @@
const aos::Node *const pi_node = aos::configuration::GetNode(
factory.configuration(), absl::StrCat("pi", *pi_number));
+ LOG(INFO) << "imu " << aos::FlatbufferToJson(imu_node);
LOG(INFO) << "roboRIO " << aos::FlatbufferToJson(roborio_node);
LOG(INFO) << "Pi " << aos::FlatbufferToJson(pi_node);
+ std::unique_ptr<aos::EventLoop> imu_event_loop =
+ factory.MakeEventLoop("calibration", imu_node);
std::unique_ptr<aos::EventLoop> roborio_event_loop =
factory.MakeEventLoop("calibration", roborio_node);
std::unique_ptr<aos::EventLoop> pi_event_loop =
factory.MakeEventLoop("calibration", pi_node);
// Now, hook Calibration up to everything.
- Calibration extractor(&factory, pi_event_loop.get(),
- roborio_event_loop.get(), FLAGS_pi, &data);
+ Calibration extractor(&factory, pi_event_loop.get(), imu_event_loop.get(),
+ FLAGS_pi, &data);
if (FLAGS_turret) {
aos::NodeEventLoopFactory *roborio_factory =
@@ -89,25 +95,42 @@
Eigen::Vector3d(0.0, 0.0, M_PI)));
const Eigen::Quaternion<double> nominal_pivot_to_camera(
Eigen::AngleAxisd(-0.5 * M_PI, Eigen::Vector3d::UnitX()));
+ const Eigen::Quaternion<double> nominal_pivot_to_imu(
+ Eigen::AngleAxisd(0.0, Eigen::Vector3d::UnitX()));
const Eigen::Quaternion<double> nominal_board_to_world(
Eigen::AngleAxisd(0.5 * M_PI, Eigen::Vector3d::UnitX()));
+ Eigen::Matrix<double, 6, 1> nominal_initial_state =
+ Eigen::Matrix<double, 6, 1>::Zero();
+ // Set y value to -1 m (approx distance from imu to board/world
+ nominal_initial_state(1, 0) = -1.0;
CalibrationParameters calibration_parameters;
calibration_parameters.initial_orientation = nominal_initial_orientation;
calibration_parameters.pivot_to_camera = nominal_pivot_to_camera;
+ calibration_parameters.pivot_to_imu = nominal_pivot_to_imu;
calibration_parameters.board_to_world = nominal_board_to_world;
+ calibration_parameters.initial_state = nominal_initial_state;
+ if (data.turret_samples_size() > 0) {
+ LOG(INFO) << "Have turret, so using pivot setup";
+ calibration_parameters.has_pivot = true;
+ }
Solve(data, &calibration_parameters);
LOG(INFO) << "Nominal initial_orientation "
<< nominal_initial_orientation.coeffs().transpose();
LOG(INFO) << "Nominal pivot_to_camera "
<< nominal_pivot_to_camera.coeffs().transpose();
-
- LOG(INFO) << "pivot_to_camera delta "
+ LOG(INFO) << "Nominal pivot_to_camera (rot-xyz) "
+ << frc971::controls::ToRotationVectorFromQuaternion(
+ nominal_pivot_to_camera)
+ .transpose();
+ LOG(INFO) << "pivot_to_camera change "
<< frc971::controls::ToRotationVectorFromQuaternion(
calibration_parameters.pivot_to_camera *
nominal_pivot_to_camera.inverse())
.transpose();
+ LOG(INFO) << "Nominal pivot_to_imu "
+ << nominal_pivot_to_imu.coeffs().transpose();
LOG(INFO) << "board_to_world delta "
<< frc971::controls::ToRotationVectorFromQuaternion(
calibration_parameters.board_to_world *
diff --git a/y2022/BUILD b/y2022/BUILD
index 5d29f04..4a351a5 100644
--- a/y2022/BUILD
+++ b/y2022/BUILD
@@ -47,6 +47,7 @@
],
data = [
":aos_config",
+ ":message_bridge_client.sh",
"//y2022/image_streamer:image_streamer_start",
],
dirs = [
diff --git a/y2022/constants.cc b/y2022/constants.cc
index c97058e..444e87d 100644
--- a/y2022/constants.cc
+++ b/y2022/constants.cc
@@ -131,23 +131,23 @@
// Interpolation table for comp and practice robots
r.shot_interpolation_table = InterpolationTable<Values::ShotParams>({
- {1.0, {0.05, 19.4}},
- {1.6, {0.05, 19.4}},
- {1.9, {0.1, 19.4}},
- {2.12, {0.13, 19.4}},
- {2.9, {0.24, 19.9}},
+ {1.0, {0.12, 19.4}},
+ {1.6, {0.12, 19.4}},
+ {1.9, {0.17, 19.4}},
+ {2.12, {0.21, 19.4}},
+ {2.9, {0.30, 19.9}},
- {3.2, {0.26, 20.7}},
+ {3.2, {0.33, 20.1}},
- {3.60, {0.33, 20.9}},
- {4.50, {0.38, 22.5}},
- {4.9, {0.4, 22.9}},
- {5.4, {0.4, 23.9}},
+ {3.60, {0.39, 20.65}},
+ {4.50, {0.44, 22.3}},
+ {4.9, {0.43, 22.75}}, // up to here
+ {5.4, {0.43, 23.85}},
- {6.0, {0.40, 25.4}},
- {7.0, {0.37, 28.1}},
+ {6.0, {0.42, 25.3}},
+ {7.0, {0.40, 27.7}},
- {10.0, {0.37, 28.1}},
+ {10.0, {0.40, 27.7}},
});
if (false) {
@@ -238,13 +238,22 @@
0.0634440443622909 + 0.213601224728352 + 0.0657973101027296 -
0.114726411377978 - 0.980314029089968 - 0.0266013159299456 +
0.0631240002215899 + 0.222882504808653 + 0.0370686419434252 -
- 0.0965027214840068 - 0.126737479717192;
+ 0.0965027214840068 - 0.126737479717192 - 0.0773753775457 +
+ 2.8132444751306;
turret->subsystem_params.zeroing_constants.measured_absolute_position =
- 1.3081068967929;
+ 1.16683731504739;
flipper_arm_left->potentiometer_offset = -6.4;
flipper_arm_right->potentiometer_offset = 5.56;
+ *turret_range = ::frc971::constants::Range{
+ .lower_hard = -7.0, // Back Hard
+ .upper_hard = 3.4, // Front Hard
+ .lower = -6.4, // Back Soft
+ .upper = 2.9 // Front Soft
+ };
+ turret_params->range = *turret_range;
+
catapult_params->zeroing_constants.measured_absolute_position =
1.71723370408082;
catapult->potentiometer_offset = -2.03383240293769;
@@ -256,6 +265,8 @@
break;
case kPracticeTeamNumber:
+ catapult_params->range.lower = -0.885;
+
r.shot_interpolation_table = InterpolationTable<Values::ShotParams>({
{1.0, {0.08, 20.0}},
{1.6, {0.08, 20.0}},
@@ -276,7 +287,8 @@
{10.0, {0.39, 28.25}},
});
- climber->potentiometer_offset = -0.1209073362519 + 0.0760598;
+ climber->potentiometer_offset =
+ -0.1209073362519 + 0.0760598 - 0.0221716219244 - 0.00321684;
intake_front->potentiometer_offset = 3.06604378582351 - 0.60745632979918;
intake_front->subsystem_params.zeroing_constants
.measured_absolute_position = 0.143667561169188;
@@ -291,14 +303,18 @@
0.0718028442723373 - 0.0793332946417493 + 0.233707527214682 +
0.0828349540635251 + 0.677740533247017 - 0.0828349540635251 -
0.0903654044329345 - 0.105426305171759 - 0.150609007388226 -
- 0.0338870266623506 - 0.0677740533247011;
+ 0.0338870266623506 - 0.0677740533247011 - 0.135548106649404 - 0.6852;
turret->subsystem_params.zeroing_constants.measured_absolute_position =
- 1.50798193457968;
- turret_range->upper = 2.9;
- turret_range->lower = -6.4;
+ 0.8306;
+ *turret_range = ::frc971::constants::Range{
+ .lower_hard = -7.0, // Back Hard
+ .upper_hard = 3.4, // Front Hard
+ .lower = -6.4, // Back Soft
+ .upper = 2.9 // Front Soft
+ };
turret_params->range = *turret_range;
- flipper_arm_left->potentiometer_offset = -4.39536583413615;
- flipper_arm_right->potentiometer_offset = 4.36264091401229;
+ flipper_arm_left->potentiometer_offset = -4.39536583413615 - 0.108401297910291;
+ flipper_arm_right->potentiometer_offset = 4.36264091401229 + 0.175896445665755;
catapult_params->zeroing_constants.measured_absolute_position =
1.62909518684227;
diff --git a/y2022/message_bridge_client.sh b/y2022/message_bridge_client.sh
index c81076a..733905e 100755
--- a/y2022/message_bridge_client.sh
+++ b/y2022/message_bridge_client.sh
@@ -5,7 +5,37 @@
ping -c 1 pi1 -W 1 && break;
sleep 1
done
+while true;
+do
+ ping -c 1 pi2 -W 1 && break;
+ sleep 1
+done
+while true;
+do
+ ping -c 1 pi3 -W 1 && break;
+ sleep 1
+done
+while true;
+do
+ ping -c 1 pi4 -W 1 && break;
+ sleep 1
+done
+while true;
+do
+ ping -c 1 pi5 -W 1 && break;
+ sleep 1
+done
+while true;
+do
+ ping -c 1 pi6 -W 1 && break;
+ sleep 1
+done
+while true;
+do
+ ping -c 1 roborio -W 1 && break;
+ sleep 1
+done
echo Pinged
-exec /home/admin/bin/message_bridge_client "$@"
+exec message_bridge_client "$@"
diff --git a/y2022/vision/BUILD b/y2022/vision/BUILD
index 4fda1ad..9726542 100644
--- a/y2022/vision/BUILD
+++ b/y2022/vision/BUILD
@@ -328,9 +328,9 @@
)
cc_binary(
- name = "extrinsics_calibration",
+ name = "calibrate_extrinsics",
srcs = [
- "extrinsics_calibration.cc",
+ "calibrate_extrinsics.cc",
],
target_compatible_with = ["@platforms//os:linux"],
visibility = ["//y2022:__subpackages__"],
@@ -339,6 +339,7 @@
"//aos/events/logging:log_reader",
"//frc971/control_loops:profiled_subsystem_fbs",
"//frc971/vision:extrinsics_calibration",
+ "//third_party:opencv",
"//y2022/control_loops/superstructure:superstructure_status_fbs",
],
)
diff --git a/y2022/vision/calibrate_extrinsics.cc b/y2022/vision/calibrate_extrinsics.cc
new file mode 100644
index 0000000..521992c
--- /dev/null
+++ b/y2022/vision/calibrate_extrinsics.cc
@@ -0,0 +1,236 @@
+#include "Eigen/Dense"
+#include "Eigen/Geometry"
+#include "absl/strings/str_format.h"
+#include "aos/events/logging/log_reader.h"
+#include "aos/init.h"
+#include "aos/network/team_number.h"
+#include "aos/time/time.h"
+#include "aos/util/file.h"
+#include "frc971/control_loops/quaternion_utils.h"
+#include "frc971/vision/extrinsics_calibration.h"
+#include "frc971/vision/vision_generated.h"
+#include "frc971/wpilib/imu_batch_generated.h"
+#include "y2020/vision/sift/sift_generated.h"
+#include "y2020/vision/sift/sift_training_generated.h"
+#include "y2020/vision/tools/python_code/sift_training_data.h"
+#include "y2022/control_loops/superstructure/superstructure_status_generated.h"
+
+DEFINE_string(pi, "pi-7971-2", "Pi name to calibrate.");
+DEFINE_bool(plot, false, "Whether to plot the resulting data.");
+DEFINE_bool(turret, true, "If true, the camera is on the turret");
+
+namespace frc971 {
+namespace vision {
+namespace chrono = std::chrono;
+using aos::distributed_clock;
+using aos::monotonic_clock;
+
+// TODO(austin): Source of IMU data? Is it the same?
+// TODO(austin): Intrinsics data?
+
+void Main(int argc, char **argv) {
+ CalibrationData data;
+
+ {
+ // Now, accumulate all the data into the data object.
+ aos::logger::LogReader reader(
+ aos::logger::SortParts(aos::logger::FindLogs(argc, argv)));
+
+ aos::SimulatedEventLoopFactory factory(reader.configuration());
+ reader.Register(&factory);
+
+ CHECK(aos::configuration::MultiNode(reader.configuration()));
+
+ // Find the nodes we care about.
+ const aos::Node *const imu_node =
+ aos::configuration::GetNode(factory.configuration(), "imu");
+ const aos::Node *const roborio_node =
+ aos::configuration::GetNode(factory.configuration(), "roborio");
+
+ std::optional<uint16_t> pi_number = aos::network::ParsePiNumber(FLAGS_pi);
+ CHECK(pi_number);
+ LOG(INFO) << "Pi " << *pi_number;
+ const aos::Node *const pi_node = aos::configuration::GetNode(
+ factory.configuration(), absl::StrCat("pi", *pi_number));
+
+ LOG(INFO) << "imu " << aos::FlatbufferToJson(imu_node);
+ LOG(INFO) << "roboRIO " << aos::FlatbufferToJson(roborio_node);
+ LOG(INFO) << "Pi " << aos::FlatbufferToJson(pi_node);
+
+ std::unique_ptr<aos::EventLoop> imu_event_loop =
+ factory.MakeEventLoop("calibration", imu_node);
+ std::unique_ptr<aos::EventLoop> roborio_event_loop =
+ factory.MakeEventLoop("calibration", roborio_node);
+ std::unique_ptr<aos::EventLoop> pi_event_loop =
+ factory.MakeEventLoop("calibration", pi_node);
+
+ // Now, hook Calibration up to everything.
+ Calibration extractor(&factory, pi_event_loop.get(), imu_event_loop.get(),
+ FLAGS_pi, &data);
+
+ if (FLAGS_turret) {
+ aos::NodeEventLoopFactory *roborio_factory =
+ factory.GetNodeEventLoopFactory(roborio_node->name()->string_view());
+ roborio_event_loop->MakeWatcher(
+ "/superstructure",
+ [roborio_factory, roborio_event_loop = roborio_event_loop.get(),
+ &data](const y2022::control_loops::superstructure::Status &status) {
+ data.AddTurret(
+ roborio_factory->ToDistributedClock(
+ roborio_event_loop->context().monotonic_event_time),
+ Eigen::Vector2d(status.turret()->position(),
+ status.turret()->velocity()));
+ });
+ }
+
+ factory.Run();
+
+ reader.Deregister();
+ }
+
+ LOG(INFO) << "Done with event_loop running";
+ CHECK(data.imu_samples_size() > 0) << "Didn't get any IMU data";
+ CHECK(data.camera_samples_size() > 0) << "Didn't get any camera observations";
+
+ // And now we have it, we can start processing it.
+ const Eigen::Quaternion<double> nominal_initial_orientation(
+ frc971::controls::ToQuaternionFromRotationVector(
+ Eigen::Vector3d(0.0, 0.0, M_PI)));
+ const Eigen::Quaternion<double> nominal_pivot_to_camera(
+ Eigen::AngleAxisd(-0.5 * M_PI, Eigen::Vector3d::UnitX()));
+ const Eigen::Quaternion<double> nominal_pivot_to_imu(
+ Eigen::AngleAxisd(0.0, Eigen::Vector3d::UnitX()));
+ const Eigen::Quaternion<double> nominal_board_to_world(
+ Eigen::AngleAxisd(0.5 * M_PI, Eigen::Vector3d::UnitX()));
+ Eigen::Matrix<double, 6, 1> nominal_initial_state =
+ Eigen::Matrix<double, 6, 1>::Zero();
+ // Set x value to 0.5 m (center view on the board)
+ // nominal_initial_state(0, 0) = 0.5;
+ // Set y value to -1 m (approx distance from imu to board/world)
+ nominal_initial_state(1, 0) = -1.0;
+
+ CalibrationParameters calibration_parameters;
+ calibration_parameters.initial_orientation = nominal_initial_orientation;
+ calibration_parameters.pivot_to_camera = nominal_pivot_to_camera;
+ calibration_parameters.pivot_to_imu = nominal_pivot_to_imu;
+ calibration_parameters.board_to_world = nominal_board_to_world;
+ calibration_parameters.initial_state = nominal_initial_state;
+
+ // Show the inverse of pivot_to_camera, since camera_to_pivot tells where the
+ // camera is with respect to the pivot frame
+ const Eigen::Affine3d nominal_affine_pivot_to_camera =
+ Eigen::Translation3d(calibration_parameters.pivot_to_camera_translation) *
+ nominal_pivot_to_camera;
+ const Eigen::Quaterniond nominal_camera_to_pivot_rotation(
+ nominal_affine_pivot_to_camera.inverse().rotation());
+ const Eigen::Vector3d nominal_camera_to_pivot_translation(
+ nominal_affine_pivot_to_camera.inverse().translation());
+
+ if (data.turret_samples_size() > 0) {
+ LOG(INFO) << "Have turret, so using pivot setup";
+ calibration_parameters.has_pivot = true;
+ }
+
+ LOG(INFO) << "Initial Conditions for solver. Assumes:\n"
+ << "1) board origin is same as world, but rotated pi/2 about "
+ "x-axis, so z points out\n"
+ << "2) pivot origin matches imu origin\n"
+ << "3) camera is offset from pivot (depends on which camera)";
+
+ LOG(INFO)
+ << "Nominal initial_orientation of imu w.r.t. world (angle-axis vector): "
+ << frc971::controls::ToRotationVectorFromQuaternion(
+ nominal_initial_orientation)
+ .transpose();
+ LOG(INFO) << "Nominal initial_state: \n"
+ << "Position: "
+ << nominal_initial_state.block<3, 1>(0, 0).transpose() << "\n"
+ << "Velocity: "
+ << nominal_initial_state.block<3, 1>(3, 0).transpose();
+ LOG(INFO) << "Nominal pivot_to_imu (angle-axis vector) "
+ << frc971::controls::ToRotationVectorFromQuaternion(
+ calibration_parameters.pivot_to_imu)
+ .transpose();
+ LOG(INFO) << "Nominal pivot_to_imu translation: "
+ << calibration_parameters.pivot_to_imu_translation.transpose();
+ // TODO<Jim>: Might be nice to take out the rotation component that maps into
+ // camera image coordinates (with x right, y down, z forward)
+ LOG(INFO) << "Nominal camera_to_pivot (angle-axis vector): "
+ << frc971::controls::ToRotationVectorFromQuaternion(
+ nominal_camera_to_pivot_rotation)
+ .transpose();
+ LOG(INFO) << "Nominal camera_to_pivot translation: "
+ << nominal_camera_to_pivot_translation.transpose();
+
+ Solve(data, &calibration_parameters);
+
+ LOG(INFO) << "RESULTS OF CALIBRATION SOLVER:";
+ LOG(INFO) << "initial_orientation of imu w.r.t. world (angle-axis vector): "
+ << frc971::controls::ToRotationVectorFromQuaternion(
+ calibration_parameters.initial_orientation)
+ .transpose();
+ LOG(INFO)
+ << "initial_state: \n"
+ << "Position: "
+ << calibration_parameters.initial_state.block<3, 1>(0, 0).transpose()
+ << "\n"
+ << "Velocity: "
+ << calibration_parameters.initial_state.block<3, 1>(3, 0).transpose();
+
+ LOG(INFO) << "pivot_to_imu rotation (angle-axis vec) "
+ << frc971::controls::ToRotationVectorFromQuaternion(
+ calibration_parameters.pivot_to_imu)
+ .transpose();
+ LOG(INFO) << "pivot_to_imu_translation "
+ << calibration_parameters.pivot_to_imu_translation.transpose();
+ const Eigen::Affine3d affine_pivot_to_camera =
+ Eigen::Translation3d(calibration_parameters.pivot_to_camera_translation) *
+ calibration_parameters.pivot_to_camera;
+ const Eigen::Quaterniond camera_to_pivot_rotation(
+ affine_pivot_to_camera.inverse().rotation());
+ const Eigen::Vector3d camera_to_pivot_translation(
+ affine_pivot_to_camera.inverse().translation());
+ LOG(INFO) << "camera to pivot (angle-axis vec): "
+ << frc971::controls::ToRotationVectorFromQuaternion(
+ camera_to_pivot_rotation)
+ .transpose();
+ LOG(INFO) << "camera to pivot translation: "
+ << camera_to_pivot_translation.transpose();
+ LOG(INFO) << "board_to_world (rotation) "
+ << frc971::controls::ToRotationVectorFromQuaternion(
+ calibration_parameters.board_to_world)
+ .transpose();
+ LOG(INFO) << "accelerometer bias "
+ << calibration_parameters.accelerometer_bias.transpose();
+ LOG(INFO) << "gyro_bias " << calibration_parameters.gyro_bias.transpose();
+ LOG(INFO) << "gravity " << 9.81 * calibration_parameters.gravity_scalar;
+
+ LOG(INFO) << "pivot_to_camera change "
+ << frc971::controls::ToRotationVectorFromQuaternion(
+ calibration_parameters.pivot_to_camera *
+ nominal_pivot_to_camera.inverse())
+ .transpose();
+ LOG(INFO) << "board_to_world delta "
+ << frc971::controls::ToRotationVectorFromQuaternion(
+ calibration_parameters.board_to_world *
+ nominal_board_to_world.inverse())
+ .transpose();
+
+ if (FLAGS_visualize) {
+ LOG(INFO) << "Showing visualization";
+ Visualize(data, calibration_parameters);
+ }
+
+ if (FLAGS_plot) {
+ Plot(data, calibration_parameters);
+ }
+}
+
+} // namespace vision
+} // namespace frc971
+
+int main(int argc, char **argv) {
+ aos::InitGoogle(&argc, &argv);
+
+ frc971::vision::Main(argc, argv);
+}
diff --git a/y2022/vision/camera_definition.py b/y2022/vision/camera_definition.py
index d3e44b7..3b34ca2 100644
--- a/y2022/vision/camera_definition.py
+++ b/y2022/vision/camera_definition.py
@@ -109,24 +109,24 @@
camera_yaw = 0.0
T = np.array([-9.5 * 0.0254, -3.5 * 0.0254, 34.5 * 0.0254])
elif pi_number == "pi3":
- camera_yaw = 179.0 * np.pi / 180.0
+ camera_yaw = 182.0 * np.pi / 180.0
T = np.array([-9.5 * 0.0254, 3.5 * 0.0254, 34.5 * 0.0254])
elif pi_number == "pi4":
camera_yaw = -90.0 * np.pi / 180.0
T = np.array([-10.25 * 0.0254, -5.0 * 0.0254, 27.5 * 0.0254])
elif team_number == 9971:
if pi_number == "pi1":
- camera_yaw = 180.5 * np.pi / 180.0
+ camera_yaw = 179.0 * np.pi / 180.0
T = np.array([-9.5 * 0.0254, 3.25 * 0.0254, 35.5 * 0.0254])
elif pi_number == "pi2":
camera_yaw = 0.0
T = np.array([-9.0 * 0.0254, -3.25 * 0.0254, 35.5 * 0.0254])
elif pi_number == "pi3":
camera_yaw = 90.0 * np.pi / 180.0
- T = np.array([-10.5 * 0.0254, -5.0 * 0.0254, 29.5 * 0.0254])
+ T = np.array([-10.5 * 0.0254, 5.0 * 0.0254, 29.5 * 0.0254])
elif pi_number == "pi4":
camera_yaw = -90.0 * np.pi / 180.0
- T = np.array([-10.5 * 0.0254, 5.0 * 0.0254, 28.0 * 0.0254])
+ T = np.array([-10.5 * 0.0254, -5.0 * 0.0254, 28.5 * 0.0254])
else:
glog.fatal("Unknown team number for extrinsics")
diff --git a/y2022/vision/extrinsics_calibration.cc b/y2022/vision/extrinsics_calibration.cc
deleted file mode 100644
index 49f2ca3..0000000
--- a/y2022/vision/extrinsics_calibration.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-#include "frc971/vision/extrinsics_calibration.h"
-
-#include "Eigen/Dense"
-#include "Eigen/Geometry"
-#include "absl/strings/str_format.h"
-#include "aos/events/logging/log_reader.h"
-#include "aos/init.h"
-#include "aos/network/team_number.h"
-#include "aos/time/time.h"
-#include "aos/util/file.h"
-#include "frc971/control_loops/quaternion_utils.h"
-#include "frc971/vision/vision_generated.h"
-#include "frc971/wpilib/imu_batch_generated.h"
-#include "y2022/control_loops/superstructure/superstructure_status_generated.h"
-#include "y2020/vision/sift/sift_generated.h"
-#include "y2020/vision/sift/sift_training_generated.h"
-#include "y2020/vision/tools/python_code/sift_training_data.h"
-
-DEFINE_string(pi, "pi-7971-2", "Pi name to calibrate.");
-DEFINE_bool(plot, false, "Whether to plot the resulting data.");
-
-namespace frc971 {
-namespace vision {
-namespace chrono = std::chrono;
-using aos::distributed_clock;
-using aos::monotonic_clock;
-
-// TODO(austin): Source of IMU data? Is it the same?
-// TODO(austin): Intrinsics data?
-
-void Main(int argc, char **argv) {
- CalibrationData data;
-
- {
- // Now, accumulate all the data into the data object.
- aos::logger::LogReader reader(
- aos::logger::SortParts(aos::logger::FindLogs(argc, argv)));
-
- aos::SimulatedEventLoopFactory factory(reader.configuration());
- reader.Register(&factory);
-
- CHECK(aos::configuration::MultiNode(reader.configuration()));
-
- // Find the nodes we care about.
- const aos::Node *const roborio_node =
- aos::configuration::GetNode(factory.configuration(), "roborio");
-
- std::optional<uint16_t> pi_number = aos::network::ParsePiNumber(FLAGS_pi);
- CHECK(pi_number);
- LOG(INFO) << "Pi " << *pi_number;
- const aos::Node *const pi_node = aos::configuration::GetNode(
- factory.configuration(), absl::StrCat("pi", *pi_number));
-
- LOG(INFO) << "roboRIO " << aos::FlatbufferToJson(roborio_node);
- LOG(INFO) << "Pi " << aos::FlatbufferToJson(pi_node);
-
- std::unique_ptr<aos::EventLoop> roborio_event_loop =
- factory.MakeEventLoop("calibration", roborio_node);
- std::unique_ptr<aos::EventLoop> pi_event_loop =
- factory.MakeEventLoop("calibration", pi_node);
-
- // Now, hook Calibration up to everything.
- Calibration extractor(&factory, pi_event_loop.get(),
- roborio_event_loop.get(), FLAGS_pi, &data);
-
- aos::NodeEventLoopFactory *roborio_factory =
- factory.GetNodeEventLoopFactory(roborio_node->name()->string_view());
- roborio_event_loop->MakeWatcher(
- "/superstructure",
- [roborio_factory, roborio_event_loop = roborio_event_loop.get(),
- &data](const y2022::control_loops::superstructure::Status &status) {
- data.AddTurret(
- roborio_factory->ToDistributedClock(
- roborio_event_loop->context().monotonic_event_time),
- Eigen::Vector2d(status.turret()->position(),
- status.turret()->velocity()));
- });
-
- factory.Run();
-
- reader.Deregister();
- }
-
- LOG(INFO) << "Done with event_loop running";
- // And now we have it, we can start processing it.
-
- const Eigen::Quaternion<double> nominal_initial_orientation(
- frc971::controls::ToQuaternionFromRotationVector(
- Eigen::Vector3d(0.0, 0.0, M_PI)));
- const Eigen::Quaternion<double> nominal_pivot_to_camera(
- Eigen::AngleAxisd(-0.5 * M_PI, Eigen::Vector3d::UnitX()));
- const Eigen::Quaternion<double> nominal_board_to_world(
- Eigen::AngleAxisd(0.5 * M_PI, Eigen::Vector3d::UnitX()));
-
- CalibrationParameters calibration_parameters;
- calibration_parameters.initial_orientation = nominal_initial_orientation;
- calibration_parameters.pivot_to_camera = nominal_pivot_to_camera;
- calibration_parameters.board_to_world = nominal_board_to_world;
-
- Solve(data, &calibration_parameters);
- LOG(INFO) << "Nominal initial_orientation "
- << nominal_initial_orientation.coeffs().transpose();
- LOG(INFO) << "Nominal pivot_to_camera "
- << nominal_pivot_to_camera.coeffs().transpose();
-
- LOG(INFO) << "pivot_to_camera delta "
- << frc971::controls::ToRotationVectorFromQuaternion(
- calibration_parameters.pivot_to_camera *
- nominal_pivot_to_camera.inverse())
- .transpose();
- LOG(INFO) << "board_to_world delta "
- << frc971::controls::ToRotationVectorFromQuaternion(
- calibration_parameters.board_to_world *
- nominal_board_to_world.inverse())
- .transpose();
-
- if (FLAGS_plot) {
- Plot(data, calibration_parameters);
- }
-}
-
-} // namespace vision
-} // namespace frc971
-
-int main(int argc, char **argv) {
- aos::InitGoogle(&argc, &argv);
-
- frc971::vision::Main(argc, argv);
-}
diff --git a/y2022/y2022_imu.json b/y2022/y2022_imu.json
index 817f051..bd2b326 100644
--- a/y2022/y2022_imu.json
+++ b/y2022/y2022_imu.json
@@ -367,7 +367,7 @@
"applications": [
{
"name": "message_bridge_client",
- "executable_name": "message_bridge_client",
+ "executable_name": "message_bridge_client.sh",
"nodes": [
"imu"
]
diff --git a/y2022/y2022_logger.json b/y2022/y2022_logger.json
index a8a4bbd..0f790c7 100644
--- a/y2022/y2022_logger.json
+++ b/y2022/y2022_logger.json
@@ -462,6 +462,38 @@
]
},
{
+ "name": "/pi3/camera",
+ "type": "frc971.vision.CameraImage",
+ "source_node": "pi3",
+ "logger": "LOCAL_AND_REMOTE_LOGGER",
+ "logger_nodes": [
+ "logger"
+ ],
+ "destination_nodes": [
+ {
+ "name": "logger",
+ "priority": 3,
+ "time_to_live": 500000000
+ }
+ ]
+ },
+ {
+ "name": "/localizer",
+ "type": "frc971.IMUValuesBatch",
+ "source_node": "imu",
+ "logger": "LOCAL_AND_REMOTE_LOGGER",
+ "logger_nodes": [
+ "logger"
+ ],
+ "destination_nodes": [
+ {
+ "name": "logger",
+ "priority": 3,
+ "time_to_live": 500000000
+ }
+ ]
+ },
+ {
"name": "/pi4/camera/decimated",
"type": "frc971.vision.CameraImage",
"source_node": "pi4",
@@ -502,7 +534,7 @@
"applications": [
{
"name": "logger_message_bridge_client",
- "executable_name": "message_bridge_client",
+ "executable_name": "message_bridge_client.sh",
"args": ["--rmem=8388608", "--rt_priority=16"],
"nodes": [
"logger"
diff --git a/y2022/y2022_pi_template.json b/y2022/y2022_pi_template.json
index a6b3f4a..99b04a1 100644
--- a/y2022/y2022_pi_template.json
+++ b/y2022/y2022_pi_template.json
@@ -186,7 +186,7 @@
"name": "/pi{{ NUM }}/camera",
"type": "y2022.vision.TargetEstimate",
"source_node": "pi{{ NUM }}",
- "frequency": 40,
+ "frequency": 80,
"num_senders": 2,
"max_size": 40000,
"logger": "LOCAL_AND_REMOTE_LOGGER",
@@ -358,7 +358,7 @@
"applications": [
{
"name": "message_bridge_client",
- "executable_name": "message_bridge_client",
+ "executable_name": "message_bridge_client.sh",
"args": ["--rt_priority=16"],
"nodes": [
"pi{{ NUM }}"