1516X Push Back 1.0
1516X's robot code for the 2025-2026 VEX Robotics Competition
Loading...
Searching...
No Matches
velocityController.cpp
Go to the documentation of this file.
1#include "velocityController.h"
2#include <cmath>
3
4int VoltageController::sign(double x) {
5 return (x > 0) - (x < 0); // returns 1, 0, or -1
6}
7
8VoltageController::VoltageController(double kv, double kaStraight, double kaTurn, double ksStraight, double ksTurn, double kp,
9 double ki, double integralThreshold, double trackWidth)
10 : kV(kv), kaStraight(kaStraight), kaTurn(kaTurn), ksStraight(ksStraight), ksTurn(ksTurn), kP(kp), kI(ki),
11 integralThreshold(integralThreshold), trackWidth(trackWidth) {}
12
13DrivetrainVoltages VoltageController::update(double targetLinearVelocity, double targetAngularVelocity, double measuredLeftVelocity,
14 double measuredRightVelocity) {
15
16 // Change in target angular velocity (angular acceleration)
17 double deltaW = (targetAngularVelocity - prevAngularVelocity) / 0.01;
18 // Change in target linear velocity (linear acceleration)
19 double deltaV = (targetLinearVelocity - prevLinearVelocity) / 0.01;
20
21 prevAngularVelocity = targetAngularVelocity;
22 prevLinearVelocity = targetLinearVelocity;
23
24 // Differential drive kinematics
25 double leftVelocity = targetLinearVelocity - targetAngularVelocity * (trackWidth / 2.0);
26 double rightVelocity = targetLinearVelocity + targetAngularVelocity * (trackWidth / 2.0);
27
28 // Velocity errors
29 double leftError = leftVelocity - measuredLeftVelocity;
30 double rightError = rightVelocity - measuredRightVelocity;
31
32 // Integrals
33 if ((leftError < 0) != (prevLeftError < 0)) {
34 leftIntegral = 0;
35 }
36 if (std::abs(leftError) < integralThreshold) {
37 leftIntegral += leftError * 0.01;
38 }
39 if ((rightError < 0) != (prevRightError < 0)) {
40 rightIntegral = 0;
41 }
42 if (std::abs(rightError) < integralThreshold) {
43 rightIntegral += rightError * 0.01;
44 }
45
46 // Feedforward Terms
47 // Acceleration term when going straight (a = F/m); kaTurn from moment of inertia (α = τ/I).
48 double kaLeft = (kaStraight * deltaV) - (kaTurn * deltaW);
49 double kaRight = (kaStraight * deltaV) + (kaTurn * deltaW);
50
51 // Static friction component
52 double ksLeft = (ksStraight * sign(leftVelocity)) - (ksTurn * sign(targetAngularVelocity));
53 double ksRight = (ksStraight * sign(rightVelocity)) + (ksTurn * sign(targetAngularVelocity));
54
55 //double leftVoltage =
56 // std::clamp((kV * leftVelocity) + (kaLeft) + (ksLeft) + (kP * leftError) + (kI * leftIntegral), -12.0, 12.0);
57 //double rightVoltage =
58 // std::clamp((kV * rightVelocity) + (kaRight) + (ksRight) + (kP * rightError) + (kI * rightIntegral), -12.0, 12.0);
59 double leftVoltage =
60 (kV * leftVelocity) + (kaLeft) + (ksLeft) + (kP * leftError) + (kI * leftIntegral);
61 double rightVoltage =
62 (kV * rightVelocity) + (kaRight) + (ksRight) + (kP * rightError) + (kI * rightIntegral);
63 double ratio = std::max(fabs(leftVoltage), fabs(rightVoltage)) / 12000.0;
64 if (ratio > 1) {
65 leftVoltage /= ratio;
66 rightVoltage /= ratio;
67 }
68
69 return {leftVoltage, rightVoltage};
70}