blob: a85ca0529e59e290aae84762881a0d7a528ccab8 [file] [log] [blame]
milind-ud4051fe2023-02-25 18:00:05 -08001#include "aos/init.h"
2#include "frc971/constants/constants_sender_lib.h"
3#include "frc971/control_loops/drivetrain/localization/localizer_output_generated.h"
4#include "frc971/vision/vision_generated.h"
5#include "glog/logging.h"
6#include "y2023/localizer/localizer.h"
milind-u607f3232023-02-26 15:22:40 -08007#include "y2023/localizer/utils.h"
milind-ud4051fe2023-02-25 18:00:05 -08008
9DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
10
11DEFINE_uint64(min_april_id, 1,
12 "Minimum april id to consider as part of the field and ignore");
13DEFINE_uint64(max_april_id, 8,
14 "Maximum april id to consider as part of the field and ignore");
15
16// This binary allows us to place extra april tags on the field and verify
17// that we can compute their field pose correctly
18
19namespace y2023::vision {
20
21using localizer::Localizer;
22
23Localizer::Transform LocalizerOutputToTransform(
24 const frc971::controls::LocalizerOutput &localizer) {
25 const auto T_field_robot =
26 Eigen::Translation3d(localizer.x(), localizer.y(), 0.0);
27
28 Eigen::AngleAxisd robot_yaw_angle(localizer.theta(),
29 Eigen::Vector3d::UnitZ());
30 const auto R_field_robot = Eigen::Quaterniond(robot_yaw_angle);
31 const Localizer::Transform H_field_robot =
32 (T_field_robot * R_field_robot).matrix();
33 return H_field_robot;
34}
35
36void HandleDetections(
37 const frc971::vision::TargetMap &detections,
38 const Localizer::Transform &H_robot_camera,
39 aos::Fetcher<frc971::controls::LocalizerOutput> *localizer_fetcher) {
40 localizer_fetcher->Fetch();
41 CHECK(localizer_fetcher->get());
42
43 for (const auto *target_pose : *detections.target_poses()) {
44 // Only look at april tags not part of the field
45 if (target_pose->id() >= FLAGS_min_april_id &&
46 target_pose->id() <= FLAGS_max_april_id) {
47 continue;
48 }
49
50 const Localizer::Transform H_camera_target =
51 localizer::PoseToTransform(target_pose);
52 const Localizer::Transform H_field_robot =
53 LocalizerOutputToTransform(*localizer_fetcher->get());
54
55 // Get the field-based target pose using the detection, extrinsics, and
56 // localizer output
57 const Localizer::Transform H_field_target =
58 H_field_robot * H_robot_camera * H_camera_target;
59
60 LOG(INFO) << "Field to target " << target_pose->id();
61 LOG(INFO) << "Transform: " << H_field_target;
62 LOG(INFO) << "Translation: "
63 << Eigen::Affine3d(H_field_target).translation();
64 LOG(INFO);
65 }
66}
67
68void LocalizationVerifierMain() {
69 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
70 aos::configuration::ReadConfig(FLAGS_config);
71
72 frc971::constants::WaitForConstants<Constants>(&config.message());
73
74 aos::ShmEventLoop event_loop(&config.message());
75
76 frc971::constants::ConstantsFetcher<Constants> constants_fetcher(&event_loop);
77
78 aos::Fetcher<frc971::controls::LocalizerOutput> localizer_fetcher =
79 event_loop.MakeFetcher<frc971::controls::LocalizerOutput>("/localizer");
80
81 for (const auto *camera : *constants_fetcher.constants().cameras()) {
82 CHECK(camera->has_calibration());
83 Localizer::Transform H_robot_camera =
84 frc971::control_loops::drivetrain::FlatbufferToTransformationMatrix(
85 *camera->calibration()->fixed_extrinsics());
86
87 const std::string_view pi_name =
88 camera->calibration()->node_name()->string_view();
89 event_loop.MakeWatcher(absl::StrCat("/", pi_name, "/camera"),
90 [&](const frc971::vision::TargetMap &target_map) {
91 HandleDetections(target_map, H_robot_camera,
92 &localizer_fetcher);
93 });
94
milind-ud4051fe2023-02-25 18:00:05 -080095 }
James Kuszmauldc41ea12023-03-04 20:05:08 -080096 event_loop.Run();
milind-ud4051fe2023-02-25 18:00:05 -080097}
98
99} // namespace y2023::vision
100
101int main(int argc, char **argv) {
102 aos::InitGoogle(&argc, &argv);
103 y2023::vision::LocalizationVerifierMain();
104}