LightLib
PROS library for VEX V5: EKF/MCL localization, RAMSETE path following, high-level chassis API
Loading...
Searching...
No Matches
holo_drive.hpp
Go to the documentation of this file.
1#pragma once
2#include <climits>
3#include <cmath>
4#include <vector>
5
6#include "LightLib/api.h"
7#include "pros/imu.hpp"
8#include "pros/motors.hpp"
9
19namespace light {
20
28double wrap180(double a);
29
36struct HoloPID {
37 double kP = 0;
38 double kI = 0;
39 double kD = 0;
40 double integral = 0;
45 double integralCap = 1000.0;
46 double prev_error = 0;
47 double prev_measured = 0;
48 bool seeded_err = false;
49 bool seeded_meas = false;
50
57 double compute(double error) {
58 integral += error;
59 if (integralCap > 0.0) {
62 }
63 double deriv = seeded_err ? (error - prev_error) : 0.0;
64 prev_error = error;
65 seeded_err = true;
66 return kP * error + kI * integral + kD * deriv;
67 }
68
78 double compute(double error, double measured) {
79 integral += error;
80 if (integralCap > 0.0) {
83 }
84 double dmeas = seeded_meas ? (measured - prev_measured) : 0.0;
85 prev_measured = measured;
86 seeded_meas = true;
87 return kP * error + kI * integral - kD * dmeas;
88 }
89
91 void reset() {
92 integral = 0;
93 prev_error = 0;
94 prev_measured = 0;
95 seeded_err = false;
96 seeded_meas = false;
97 }
98
100 void set(double p, double i = 0, double d = 0) {
101 kP = p;
102 kI = i;
103 kD = d;
104 }
105};
106
134 public:
136 enum class Type { XDRIVE,
137 MECANUM };
138
159 HoloDrive(int fl_port, int fr_port, int bl_port, int br_port,
160 int imu_port,
161 double wheel_diameter,
162 double gear_ratio = 1.0,
163 Type type = Type::MECANUM);
164
179 void opcontrol(int throttle, int strafe, int turn);
188 void drive(double inches, int max_speed = 100, int timeout_ms = 3000);
190 void strafe(double inches, int max_speed = 100, int timeout_ms = 3000);
192 void turn_to(double heading_deg, int max_speed = 80, int timeout_ms = 2000);
194 void turn_relative(double degrees, int max_speed = 80, int timeout_ms = 2000);
202 void set_drive_pid(double kP, double kI = 0, double kD = 0);
204 void set_strafe_pid(double kP, double kI = 0, double kD = 0);
206 void set_turn_pid(double kP, double kI = 0, double kD = 0);
208 void set_heading_pid(double kP, double kI = 0, double kD = 0);
216 void calibrate(bool wait = true);
220 void set_brake_mode(pros::motor_brake_mode_e_t mode);
222 double get_heading() const;
225 private:
226 pros::Motor fl_, fr_, bl_, br_;
227 pros::Imu imu_;
228 Type type_;
229 double wheel_circumference_;
230 double gear_ratio_;
231
232 HoloPID drive_pid_, strafe_pid_, turn_pid_, heading_pid_;
233
234 // Last command actually written to each motor — set_holonomic() skips the
235 // smartport write when the new value matches. INT_MIN sentinel means
236 // "never written" so the first call always pushes a value.
237 int last_fl_ = INT_MIN, last_fr_ = INT_MIN;
238 int last_bl_ = INT_MIN, last_br_ = INT_MIN;
239
240 // Unified motor-mixing call — also handles scaling to ±127.
241 void set_holonomic(double throttle, double strafe, double turn);
242 double inches_to_deg(double inches) const;
243 double drive_pos() const; // avg forward encoder (all 4 motors)
244 double strafe_pos() const; // avg rightward encoder (−FL+FR+BL−BR)/4
245};
246
256class HDrive {
257 public:
274 HDrive(std::vector<int> left_ports,
275 std::vector<int> right_ports,
276 int center_port,
277 int imu_port,
278 double wheel_diameter,
279 double gear_ratio = 1.0);
280
295 void opcontrol(int throttle, int strafe, int turn);
303 void drive(double inches, int max_speed = 100, int timeout_ms = 3000);
305 void strafe(double inches, int max_speed = 100, int timeout_ms = 3000);
307 void turn_to(double heading_deg, int max_speed = 80, int timeout_ms = 2000);
309 void turn_relative(double degrees, int max_speed = 80, int timeout_ms = 2000);
316 void set_drive_pid(double kP, double kI = 0, double kD = 0);
317 void set_strafe_pid(double kP, double kI = 0, double kD = 0);
318 void set_turn_pid(double kP, double kI = 0, double kD = 0);
319 void set_heading_pid(double kP, double kI = 0, double kD = 0);
326 void calibrate(bool wait = true);
328 void set_brake_mode(pros::motor_brake_mode_e_t mode);
329 double get_heading() const;
332 private:
333 pros::MotorGroup left_, right_;
334 pros::Motor center_;
335 pros::Imu imu_;
336 double wheel_circumference_;
337 double gear_ratio_;
338
339 HoloPID drive_pid_, strafe_pid_, turn_pid_, heading_pid_;
340
341 void set_tank(double left_v, double right_v);
342 double inches_to_deg(double inches) const;
343 double drive_pos() const; // average of all left + right motor encoders
344};
345
346} // namespace light
PROS API header provides high-level user functionality.
Tank drive with a single center-mounted strafe wheel (H-drive layout).
void opcontrol(int throttle, int strafe, int turn)
Drive from joystick inputs.
void strafe(double inches, int max_speed=100, int timeout_ms=3000)
Strafe right inches (negative = left).
void turn_to(double heading_deg, int max_speed=80, int timeout_ms=2000)
Turn to absolute heading 0–360°.
void set_drive_pid(double kP, double kI=0, double kD=0)
void drive(double inches, int max_speed=100, int timeout_ms=3000)
Drive forward inches (negative = reverse).
void set_turn_pid(double kP, double kI=0, double kD=0)
HDrive(std::vector< int > left_ports, std::vector< int > right_ports, int center_port, int imu_port, double wheel_diameter, double gear_ratio=1.0)
Construct an H-drive.
void turn_relative(double degrees, int max_speed=80, int timeout_ms=2000)
Turn degrees CW (positive) or CCW (negative).
double get_heading() const
void set_strafe_pid(double kP, double kI=0, double kD=0)
void set_brake_mode(pros::motor_brake_mode_e_t mode)
void set_heading_pid(double kP, double kI=0, double kD=0)
void reset_sensors()
void calibrate(bool wait=true)
4-motor holonomic drive — supports X-Drive and Mecanum configurations.
void strafe(double inches, int max_speed=100, int timeout_ms=3000)
Strafe right inches (negative = left).
HoloDrive(int fl_port, int fr_port, int bl_port, int br_port, int imu_port, double wheel_diameter, double gear_ratio=1.0, Type type=Type::MECANUM)
Construct a 4-motor holonomic drive.
void set_heading_pid(double kP, double kI=0, double kD=0)
Set the heading-correction PID used during straight drive / strafe.
void drive(double inches, int max_speed=100, int timeout_ms=3000)
Drive forward inches (negative = reverse).
void set_drive_pid(double kP, double kI=0, double kD=0)
Set the linear-drive PID gains.
void set_strafe_pid(double kP, double kI=0, double kD=0)
Set the strafe PID gains.
void set_brake_mode(pros::motor_brake_mode_e_t mode)
Set brake mode for all four motors.
void turn_to(double heading_deg, int max_speed=80, int timeout_ms=2000)
Turn to absolute heading 0–360°.
void set_turn_pid(double kP, double kI=0, double kD=0)
Set the turn-in-place PID gains.
void opcontrol(int throttle, int strafe, int turn)
Drive from joystick inputs.
Type
Wheel layout option.
@ XDRIVE
Omni wheels mounted at 45°.
double get_heading() const
void calibrate(bool wait=true)
Calibrate the IMU.
void reset_sensors()
Tare motor encoders.
void turn_relative(double degrees, int max_speed=80, int timeout_ms=2000)
Turn degrees CW (positive) or CCW (negative).
Public LightLib odometry / pose-estimation API.
Definition pid.hpp:22
double wrap180(double a)
Normalize an angle in degrees to the half-open interval (-180, 180] so PID always takes the shortest ...
Internal PID used by HoloDrive / HDrive.
double kI
Integral gain.
void reset()
Zero out integral and previous-state history.
double integral
Accumulated integral term.
double compute(double error)
Compute output using derivative on error.
bool seeded_err
Whether prev_error is valid.
bool seeded_meas
Whether prev_measured is valid.
double kP
Proportional gain.
double prev_error
Previous-cycle error.
double prev_measured
Previous-cycle measurement (for derivative-on-measurement).
void set(double p, double i=0, double d=0)
Set all three gains in one call.
double integralCap
Same gating semantics as LightPID::integralCap: > 0 enables the clamp.
double kD
Derivative gain.
double compute(double error, double measured)
Compute output using derivative on measurement (suppresses derivative kick on target changes).