5#include "core/subsystems/custom_encoder.h"
6#include "core/subsystems/odometry/odometry_base.h"
7#include "core/math/util.h"
52template <
int WHEELS>
class OdometryNWheel :
public OdometryBase {
63 const std::array<CustomEncoder, WHEELS> &encoders,
const std::array<tracking_wheel_cfg_t, WHEELS> wheel_configs,
64 vex::inertial *imu,
bool is_async
67 Eigen::Matrix<double, WHEELS, 3> transfer_matrix;
68 for (
int i = 0; i < WHEELS; i++) {
69 double x = wheel_configs[i].x;
70 double y = wheel_configs[i].y;
71 double theta_rad = wheel_configs[i].theta_rad;
72 double radius = wheel_configs[i].radius;
75 wheel_radii(i) = radius;
77 double x_factor = cos(theta_rad);
78 double y_factor = -sin(theta_rad);
79 double theta_factor = -(x * sin(theta_rad)) - (y * cos(theta_rad));
82 if (abs(y_factor) < 1e-9) {
85 if (abs(x_factor) < 1e-9) {
89 transfer_matrix.row(i) << x_factor, y_factor, theta_factor;
92 transfer_matrix_pseudoinverse = transfer_matrix.completeOrthogonalDecomposition().pseudoInverse();
94 old_wheel_angles.fill(0);
103 Pose2d update()
override {
104 Eigen::Vector<double, WHEELS> radian_deltas;
106 for (
int i = 0; i < WHEELS; i++) {
107 double angle_rad = encoders[i].position(vex::rev) * std::numbers::pi * 2;
108 radian_deltas(i) = angle_rad - old_wheel_angles[i];
110 old_wheel_angles[i] = angle_rad;
113 Pose2d updated_pos = calculate_new_pos(radian_deltas,
current_pos);
116 if (imu !=
nullptr) {
119 angle = -imu->rotation(vex::rotationUnits::rev) * 2 * std::numbers::pi;
121 angle += angle_offset;
124 static Pose2d last_pos = updated_pos;
125 static double last_speed = 0;
126 static double last_ang_speed = 0;
127 static vex::timer tmr;
129 double speed_local = 0;
130 double accel_local = 0;
131 double ang_speed_local = 0;
132 double ang_accel_local = 0;
133 bool update_vel_accel = tmr.time(vex::sec) > 0.1;
136 if (update_vel_accel) {
141 accel_local = (speed_local - last_speed) / tmr.time(vex::sec);
147 ang_accel_local = (ang_speed_local - last_ang_speed) / tmr.time(vex::sec);
150 last_pos = updated_pos;
151 last_speed = speed_local;
152 last_ang_speed = ang_speed_local;
156 if (update_vel_accel) {
157 this->
speed = speed_local;
158 this->
accel = accel_local;
163 if (imu !=
nullptr) {
171 void set_position(
const Pose2d &newpos)
override {
183 Pose2d get_position(
void) {
186 return with_wrapped_angle;
198 Pose2d calculate_new_pos(Eigen::Vector<double, WHEELS> radian_deltas, Pose2d old_pose) {
201 Eigen::Vector3d pose_delta = transfer_matrix_pseudoinverse * (radian_deltas.asDiagonal() * wheel_radii);
202 Eigen::Vector3d old_pose_vector{old_pose.
x(units::in), old_pose.
y(units::in), old_pose.
rotation().
radians()};
205 if (imu !=
nullptr) {
206 pose_delta(2) = angle - old_angle;
208 Pose2d pose_delta2d(pose_delta, units::in);
209 Pose2d old_pose_Pose2d(old_pose_vector, units::in);
211 Pose2d new_pose = old_pose_Pose2d.exp(
Twist2d(pose_delta, units::in));
214 if (imu !=
nullptr) {
227 Eigen::Matrix<double, 3, WHEELS> transfer_matrix_pseudoinverse;
229 std::array<CustomEncoder, WHEELS> encoders;
230 Eigen::Vector<double, WHEELS> wheel_radii;
232 Eigen::Vector<double, WHEELS> old_wheel_angles;
constexpr Q distance(LinearVector2d other) const
Gets the distance between two vectors.
Definition translation2d.h:108
Definition odometry_base.h:27
double ang_accel_deg
Definition odometry_base.h:134
double ang_speed_deg
Definition odometry_base.h:133
Pose2d current_pos
Current position of the robot in terms of x,y,rotation.
Definition odometry_base.h:129
double speed
Definition odometry_base.h:131
OdometryBase(bool is_async)
Definition odometry_base.cpp:12
static double smallest_angle(double start_deg, double end_deg)
Definition odometry_base.cpp:78
vex::mutex mut
Mutex to control multithreading.
Definition odometry_base.h:126
double accel
Definition odometry_base.h:132
virtual Pose2d get_position(void)
Gets the current position and rotation.
Definition odometry_base.cpp:46
virtual void set_position(const Pose2d &newpos=zero_pos)
Sets the current position of the robot.
Definition odometry_base.cpp:58
constexpr Rotation2d rotation() const
Gets the rotation.
Definition pose2d.h:102
constexpr void set_rotation(Rotation2d val)
Sets the rotation.
Definition pose2d.h:105
constexpr units::Length y() const
Gets the y value of the translation.
Definition pose2d.h:87
constexpr Translation2d translation() const
Gets the translation.
Definition pose2d.h:96
constexpr units::Length x() const
Gets the x value of the translation.
Definition pose2d.h:78
constexpr double radians() const
Gets the rotation in radians.
Definition rotation2d.h:72
constexpr double degrees() const
Gets the rotation in degrees.
Definition rotation2d.h:75
constexpr Rotation2d()=default
Default Constructor for Rotation2d.
constexpr double wrapped_radians_360() const
Gets the value of this rotation in radians from [0, 2pi).
Definition rotation2d.h:114
constexpr Twist2d()
Default Constructor for Twist2d.
Definition twist2d.h:28
Definition odometry_nwheel.h:45
double x
Definition odometry_nwheel.h:46
double radius
Definition odometry_nwheel.h:49
double theta_rad
Definition odometry_nwheel.h:48
double y
Definition odometry_nwheel.h:47