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// Copyright 2026 California High Robotics, Team 1516X
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "velocityController.h"
5#include <cmath>
6
7int VoltageController::sign(double x) {
8 return (x > 0) - (x < 0); // returns 1, 0, or -1
9}
10
11VoltageController::VoltageController(double kv, double kaStraight, double kaTurn, double ksStraight, double ksTurn, double kp,
12 double ki, double integralThreshold, double trackWidth)
13 : kV(kv), kaStraight(kaStraight), kaTurn(kaTurn), ksStraight(ksStraight), ksTurn(ksTurn), kP(kp), kI(ki),
14 integralThreshold(integralThreshold), trackWidth(trackWidth) {}
15
16DrivetrainVoltages VoltageController::update(double targetLinearVelocity, double targetAngularVelocity, double measuredLeftVelocity,
17 double measuredRightVelocity) {
18
19 double deltaW = (targetAngularVelocity - prevAngularVelocity) / 0.01;
20
21 double deltaV = (targetLinearVelocity - prevLinearVelocity) / 0.01;
22
23 prevAngularVelocity = targetAngularVelocity;
24 prevLinearVelocity = targetLinearVelocity;
25
26 double leftVelocity = targetLinearVelocity - targetAngularVelocity * (trackWidth / 2.0);
27 double rightVelocity = targetLinearVelocity + targetAngularVelocity * (trackWidth / 2.0);
28
29 double leftError = leftVelocity - measuredLeftVelocity;
30 double rightError = rightVelocity - measuredRightVelocity;
31
32 if ((leftError < 0) != (prevLeftError < 0)) {
33 leftIntegral = 0;
34 }
35 if (std::abs(leftError) < integralThreshold) {
36 leftIntegral += leftError * 0.01;
37 }
38 if ((rightError < 0) != (prevRightError < 0)) {
39 rightIntegral = 0;
40 }
41 if (std::abs(rightError) < integralThreshold) {
42 rightIntegral += rightError * 0.01;
43 }
44
45 double kaLeft = (kaStraight * deltaV) - (kaTurn * deltaW);
46 double kaRight = (kaStraight * deltaV) + (kaTurn * deltaW);
47
48 double ksLeft = (ksStraight * sign(leftVelocity)) - (ksTurn * sign(targetAngularVelocity));
49 double ksRight = (ksStraight * sign(rightVelocity)) + (ksTurn * sign(targetAngularVelocity));
50
51 double leftVoltage =
52 (kV * leftVelocity) + (kaLeft) + (ksLeft) + (kP * leftError) + (kI * leftIntegral);
53 double rightVoltage =
54 (kV * rightVelocity) + (kaRight) + (ksRight) + (kP * rightError) + (kI * rightIntegral);
55 double ratio = std::max(fabs(leftVoltage), fabs(rightVoltage)) / 12000.0;
56 if (ratio > 1) {
57 leftVoltage /= ratio;
58 rightVoltage /= ratio;
59 }
60
61 prevLeftError = leftError;
62 prevRightError = rightError;
63 return {leftVoltage, rightVoltage};
64}