blob: 5d338c4a603572bafc29653b10b1861892d8e76c [file] [log] [blame]
Milind Upadhyayf61e1482022-02-11 20:42:55 -08001#ifndef Y2022_VISION_TARGET_ESTIMATOR_H_
2#define Y2022_VISION_TARGET_ESTIMATOR_H_
milind-u92195982022-01-22 20:29:31 -08003
Milind Upadhyayf61e1482022-02-11 20:42:55 -08004#include <optional>
5
6#include "Eigen/Dense"
7#include "Eigen/Geometry"
8#include "opencv2/core/types.hpp"
milind-u92195982022-01-22 20:29:31 -08009#include "opencv2/imgproc.hpp"
10#include "y2022/vision/target_estimate_generated.h"
11
12namespace y2022::vision {
Milind Upadhyay14279de2022-02-26 16:07:53 -080013
Milind Upadhyayf61e1482022-02-11 20:42:55 -080014// Class to estimate the polar coordinates and rotation from the camera to the
15// target.
milind-u92195982022-01-22 20:29:31 -080016class TargetEstimator {
17 public:
Milind Upadhyayf61e1482022-02-11 20:42:55 -080018 TargetEstimator(cv::Mat intrinsics, cv::Mat extrinsics);
19
20 // Runs the solver to estimate the target
21 // centroids must be in sorted order from left to right on the circle.
22 // TODO(milind): seems safer to sort them here.
23 // If image != std::nullopt, the solver's progress will be displayed
24 // graphically.
25 void Solve(const std::vector<cv::Point> &centroids,
26 std::optional<cv::Mat> image);
27
28 // Cost function for the solver.
29 // Takes in the rotation of the camera in the hub's frame, the horizontal
30 // polar coordinates of the camera in the hub's frame, and the height of the
31 // camera (can change if the robot is shaking).
32 // Hub frame is relative to the center of the bottom of the hub.
33 // Compares the projected pieces of tape with these values to the detected
34 // blobs for calculating the cost.
35 template <typename S>
36 bool operator()(const S *const roll, const S *const pitch, const S *const yaw,
37 const S *const distance, const S *const theta,
38 const S *const camera_height, S *residual) const;
39
40 inline double roll() const { return roll_; }
41 inline double pitch() const { return pitch_; }
42 inline double yaw() const { return yaw_; }
43
44 inline double distance() const { return distance_; }
45 inline double angle_to_camera() const { return angle_to_camera_; }
46 inline double angle_to_target() const { return M_PI - yaw_; }
47 inline double camera_height() const { return camera_height_; }
48
Milind Upadhyay14279de2022-02-26 16:07:53 -080049 inline double confidence() const { return confidence_; }
50
Milind Upadhyayf61e1482022-02-11 20:42:55 -080051 // Draws the distance, angle, and rotation on the given image
52 static void DrawEstimate(const TargetEstimate &target_estimate,
53 cv::Mat view_image);
54 void DrawEstimate(cv::Mat view_image) const;
milind-u92195982022-01-22 20:29:31 -080055
56 private:
57 // Height of the center of the tape (m)
58 static constexpr double kTapeHeight = 2.58 + (0.05 / 2);
59 // Horizontal distance from tape to center of hub (m)
60 static constexpr double kUpperHubRadius = 1.22 / 2;
Milind Upadhyayf61e1482022-02-11 20:42:55 -080061 static constexpr size_t kNumPiecesOfTape = 16;
62
63 // 3d points of the visible pieces of tape in the hub's frame
64 static const std::vector<cv::Point3d> kTapePoints;
65 static std::vector<cv::Point3d> ComputeTapePoints();
66
67 template <typename S>
68 cv::Point_<S> DistanceFromTape(
69 size_t centroid_index,
70 const std::vector<cv::Point_<S>> &tape_points) const;
71
72 std::vector<cv::Point> centroids_;
73 std::optional<cv::Mat> image_;
74
75 Eigen::Matrix3d intrinsics_;
76 Eigen::Matrix4d extrinsics_;
77
78 double roll_;
79 double pitch_;
80 double yaw_;
81
82 double distance_;
83 double angle_to_camera_;
84 double camera_height_;
Milind Upadhyay14279de2022-02-26 16:07:53 -080085 double confidence_;
milind-u92195982022-01-22 20:29:31 -080086};
87
88} // namespace y2022::vision
89
Milind Upadhyayf61e1482022-02-11 20:42:55 -080090#endif // Y2022_VISION_TARGET_ESTIMATOR_H_