milind-u | d4051fe | 2023-02-25 18:00:05 -0800 | [diff] [blame] | 1 | #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-u | 607f323 | 2023-02-26 15:22:40 -0800 | [diff] [blame] | 7 | #include "y2023/localizer/utils.h" |
milind-u | d4051fe | 2023-02-25 18:00:05 -0800 | [diff] [blame] | 8 | |
| 9 | DEFINE_string(config, "aos_config.json", "Path to the config file to use."); |
| 10 | |
| 11 | DEFINE_uint64(min_april_id, 1, |
| 12 | "Minimum april id to consider as part of the field and ignore"); |
| 13 | DEFINE_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 | |
| 19 | namespace y2023::vision { |
| 20 | |
| 21 | using localizer::Localizer; |
| 22 | |
| 23 | Localizer::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 | |
| 36 | void 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 | |
| 68 | void 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 | |
| 95 | event_loop.Run(); |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | } // namespace y2023::vision |
| 100 | |
| 101 | int main(int argc, char **argv) { |
| 102 | aos::InitGoogle(&argc, &argv); |
| 103 | y2023::vision::LocalizationVerifierMain(); |
| 104 | } |