Add Game Piece Detector
Signed-off-by: Filip Kujawa <filip.j.kujawa@gmail.com>
Change-Id: I4f460e64b1fb9fbe1e0d50581412e106a89515e2
diff --git a/y2023/BUILD b/y2023/BUILD
index a500a83..309ada4 100644
--- a/y2023/BUILD
+++ b/y2023/BUILD
@@ -70,6 +70,7 @@
"//aos/starter:irq_affinity",
"//y2023/vision:camera_reader",
"//aos/events/logging:logger_main",
+ "//y2023/vision:game_pieces_detector",
],
target_compatible_with = ["//tools/platforms/hardware:raspberry_pi"],
target_type = "pi",
@@ -114,6 +115,7 @@
"//frc971/vision:target_map_fbs",
"//frc971/vision:vision_fbs",
"//y2023/localizer:visualization_fbs",
+ "//y2023/vision:game_pieces_fbs",
"@com_github_foxglove_schemas//:schemas",
],
target_compatible_with = ["@platforms//os:linux"],
@@ -166,6 +168,7 @@
"//frc971/vision:vision_fbs",
"//frc971/vision:target_map_fbs",
"//y2023/constants:constants_fbs",
+ "//y2023/vision:game_pieces_fbs",
],
target_compatible_with = ["@platforms//os:linux"],
visibility = ["//visibility:public"],
diff --git a/y2023/vision/BUILD b/y2023/vision/BUILD
index 05e4f6c..9bd29fa 100644
--- a/y2023/vision/BUILD
+++ b/y2023/vision/BUILD
@@ -1,3 +1,5 @@
+load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_cc_library")
+
cc_binary(
name = "camera_reader",
srcs = [
@@ -167,3 +169,46 @@
"//y2023/vision:vision_util",
],
)
+
+cc_binary(
+ name = "game_pieces_detector",
+ srcs = [
+ "game_pieces_main.cc",
+ ],
+ target_compatible_with = ["@platforms//os:linux"],
+ visibility = ["//y2023:__subpackages__"],
+ deps = [
+ ":game_pieces_lib",
+ "//aos:init",
+ "//aos/events:shm_event_loop",
+ ],
+)
+
+cc_library(
+ name = "game_pieces_lib",
+ srcs = [
+ "game_pieces.cc",
+ ],
+ hdrs = [
+ "game_pieces.h",
+ ],
+ data = [
+ "//y2023:aos_config",
+ ],
+ target_compatible_with = ["@platforms//os:linux"],
+ visibility = ["//y2023:__subpackages__"],
+ deps = [
+ ":game_pieces_fbs",
+ "//aos/events:event_loop",
+ "//aos/events:shm_event_loop",
+ "//frc971/vision:vision_fbs",
+ ],
+)
+
+flatbuffer_cc_library(
+ name = "game_pieces_fbs",
+ srcs = ["game_pieces.fbs"],
+ gen_reflections = 1,
+ target_compatible_with = ["@platforms//os:linux"],
+ visibility = ["//visibility:public"],
+)
diff --git a/y2023/vision/game_pieces.cc b/y2023/vision/game_pieces.cc
new file mode 100644
index 0000000..868d5b0
--- /dev/null
+++ b/y2023/vision/game_pieces.cc
@@ -0,0 +1,47 @@
+#include "y2023/vision/game_pieces.h"
+
+#include "aos/events/event_loop.h"
+#include "aos/events/shm_event_loop.h"
+#include "frc971/vision/vision_generated.h"
+
+namespace y2023 {
+namespace vision {
+GamePiecesDetector::GamePiecesDetector(aos::EventLoop *event_loop)
+ : game_pieces_sender_(
+ event_loop->MakeSender<GamePieces>("/camera")) {
+ event_loop->MakeWatcher("/camera", [this](const CameraImage &camera_image) {
+ this->ProcessImage(camera_image);
+ });
+}
+
+void GamePiecesDetector::ProcessImage(const CameraImage &image) {
+ // Param is not used for now.
+ (void)image;
+
+ auto builder = game_pieces_sender_.MakeBuilder();
+
+ auto box_builder = builder.MakeBuilder<Box>();
+ box_builder.add_h(10);
+ box_builder.add_w(20);
+ box_builder.add_x(30);
+ box_builder.add_y(40);
+ auto box_offset = box_builder.Finish();
+
+ auto game_piece_builder = builder.MakeBuilder<GamePiece>();
+ game_piece_builder.add_piece_class(y2023::vision::Class::CONE_DOWN);
+ game_piece_builder.add_box(box_offset);
+ game_piece_builder.add_confidence(0.9);
+ auto game_piece = game_piece_builder.Finish();
+
+ flatbuffers::FlatBufferBuilder fbb;
+ auto game_pieces_vector =
+ fbb.CreateVector(std::vector<flatbuffers::Offset<GamePiece>>{game_piece});
+
+ auto game_pieces_builder = builder.MakeBuilder<GamePieces>();
+ game_pieces_builder.add_game_pieces(game_pieces_vector);
+
+ builder.CheckOk(builder.Send(game_pieces_builder.Finish()));
+}
+
+} // namespace vision
+} // namespace y2023
\ No newline at end of file
diff --git a/y2023/vision/game_pieces.fbs b/y2023/vision/game_pieces.fbs
new file mode 100644
index 0000000..e981712
--- /dev/null
+++ b/y2023/vision/game_pieces.fbs
@@ -0,0 +1,29 @@
+namespace y2023.vision;
+
+// Object class.
+enum Class : byte {
+ CONE_DOWN,
+ CONE_UP,
+ CUBE
+}
+
+// Bounding box dimensions and position.
+table Box {
+ //TODO(Filip): Are cords center of box or top left corner?
+ x:uint (id: 0);
+ y:uint (id: 1);
+ w:uint (id: 2);
+ h:uint (id: 3);
+}
+
+table GamePiece {
+ piece_class:Class (id: 0);
+ box:Box (id:1);
+ confidence:float (id:2);
+}
+
+table GamePieces {
+ game_pieces:[GamePiece] (id: 0);
+}
+
+root_type GamePieces;
\ No newline at end of file
diff --git a/y2023/vision/game_pieces.h b/y2023/vision/game_pieces.h
new file mode 100644
index 0000000..a41d52a
--- /dev/null
+++ b/y2023/vision/game_pieces.h
@@ -0,0 +1,26 @@
+#ifndef Y2023_VISION_GAME_PIECES_H_
+#define Y2023_VISION_GAME_PIECES_H_
+
+#include "aos/events/shm_event_loop.h"
+#include "frc971/vision/vision_generated.h"
+#include "y2023/vision/game_pieces_generated.h"
+
+namespace y2023 {
+namespace vision {
+
+using namespace frc971::vision;
+
+// Takes in camera images and detects game pieces in the image.
+// Note: Actual detection has not been implemented yet.
+class GamePiecesDetector {
+ public:
+ GamePiecesDetector(aos::EventLoop *event_loop);
+
+ void ProcessImage(const CameraImage &camera_image);
+
+ private:
+ aos::Sender<GamePieces> game_pieces_sender_;
+};
+} // namespace vision
+} // namespace y2023
+#endif
diff --git a/y2023/vision/game_pieces_main.cc b/y2023/vision/game_pieces_main.cc
new file mode 100644
index 0000000..97940b6
--- /dev/null
+++ b/y2023/vision/game_pieces_main.cc
@@ -0,0 +1,25 @@
+#include "aos/events/shm_event_loop.h"
+#include "aos/init.h"
+#include "y2023/vision/game_pieces.h"
+
+DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
+
+namespace y2023 {
+namespace vision {
+namespace {
+
+void GamePiecesDetectorMain() {
+ aos::FlatbufferDetachedBuffer<aos::Configuration> config =
+ aos::configuration::ReadConfig(FLAGS_config);
+ aos::ShmEventLoop event_loop(&config.message());
+ GamePiecesDetector game_pieces_detector(&event_loop);
+ event_loop.Run();
+}
+} // namespace
+} // namespace vision
+} // namespace y2023
+
+int main(int argc, char **argv) {
+ aos::InitGoogle(&argc, &argv);
+ y2023::vision::GamePiecesDetectorMain();
+}
diff --git a/y2023/y2023_logger.json b/y2023/y2023_logger.json
index 840ac23..387915d 100644
--- a/y2023/y2023_logger.json
+++ b/y2023/y2023_logger.json
@@ -41,6 +41,38 @@
]
},
{
+ "name": "/camera",
+ "type": "y2023.vision.GamePieces",
+ "source_node": "logger",
+ "logger": "LOCAL_AND_REMOTE_LOGGER",
+ "logger_nodes": [
+ "roborio"
+ ],
+ "frequency": 40,
+ "num_senders": 2,
+ "max_size": 1024,
+ "destination_nodes": [
+ {
+ "name": "roborio",
+ "priority": 2,
+ "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
+ "timestamp_logger_nodes": [
+ "roborio"
+ ],
+ "time_to_live": 5000000
+ }
+ ]
+ },
+ {
+ "name": "/logger/aos/remote_timestamps/roborio/camera/y2023-vision-GamePieces",
+ "type": "aos.message_bridge.RemoteMessage",
+ "source_node": "logger",
+ "logger": "NOT_LOGGED",
+ "frequency": 40,
+ "num_senders": 2,
+ "max_size": 200
+ },
+ {
"name": "/roborio/aos/remote_timestamps/logger/drivetrain/frc971-control_loops-drivetrain-Position",
"type": "aos.message_bridge.RemoteMessage",
"source_node": "roborio",
@@ -499,6 +531,13 @@
"nodes": [
"logger"
]
+ },
+ {
+ "name": "game_piece_detector",
+ "executable_name": "game_piece_detector",
+ "nodes": [
+ "logger"
+ ]
}
],
"nodes": [