Skip to content

Commit 3725ff3

Browse files
author
NewtonCrosby
committed
Added PIDSubsystem to Commands2. robotpy#28
1 parent 12dfc59 commit 3725ff3

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

commands2/pidsubsystem.py

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Copyright (c) FIRST and other WPILib contributors.
2+
# Open Source Software; you can modify and/or share it under the terms of
3+
# the WPILib BSD license file in the root directory of this project.
4+
from __future__ import annotations
5+
6+
from wpimath.controller import PIDController
7+
from .subsystem import Subsystem
8+
9+
10+
class PIDSubsystem(Subsystem):
11+
def __init__(self, controller: PIDController, initial_position: float = 0.0):
12+
"""
13+
Creates a new PIDSubsystem.
14+
15+
:param controller: The PIDController to use.
16+
:param initial_position: The initial setpoint of the subsystem.
17+
"""
18+
self.m_controller: PIDController = controller
19+
self.setSetpoint(initial_position)
20+
self.addChild("PID Controller", self.m_controller)
21+
self.m_enabled = False
22+
23+
def periodic(self):
24+
"""
25+
Executes the PID control logic during each periodic update.
26+
27+
This method is called synchronously from the subsystem's periodic() method.
28+
"""
29+
if self.m_enabled:
30+
self.useOutput(
31+
self.m_controller.calculate(self.getMeasurement()), self.getSetpoint()
32+
)
33+
34+
def getController(self) -> PIDController:
35+
"""
36+
Returns the PIDController used by the subsystem.
37+
38+
:return: The PIDController.
39+
"""
40+
return self.m_controller
41+
42+
def setSetpoint(self, setpoint: float):
43+
"""
44+
Sets the setpoint for the subsystem.
45+
46+
:param setpoint: The setpoint for the subsystem.
47+
"""
48+
self.m_controller.setSetpoint(setpoint)
49+
50+
def getSetpoint(self) -> float:
51+
"""
52+
Returns the current setpoint of the subsystem.
53+
54+
:return: The current setpoint.
55+
"""
56+
return self.m_controller.getSetpoint()
57+
58+
def useOutput(self, output: float, setpoint: float):
59+
"""
60+
Uses the output from the PIDController.
61+
62+
:param output: The output of the PIDController.
63+
:param setpoint: The setpoint of the PIDController (for feedforward).
64+
"""
65+
raise NotImplementedError("Subclasses must implement this method")
66+
67+
def getMeasurement(self) -> float:
68+
"""
69+
Returns the measurement of the process variable used by the PIDController.
70+
71+
:return: The measurement of the process variable.
72+
"""
73+
raise NotImplementedError("Subclasses must implement this method")
74+
75+
def enable(self):
76+
"""Enables the PID control. Resets the controller."""
77+
self.m_enabled = True
78+
self.m_controller.reset()
79+
80+
def disable(self):
81+
"""Disables the PID control. Sets output to zero."""
82+
self.m_enabled = False
83+
self.useOutput(0, 0)
84+
85+
def isEnabled(self) -> bool:
86+
"""
87+
Returns whether the controller is enabled.
88+
89+
:return: Whether the controller is enabled.
90+
"""
91+
return self.m_enabled

0 commit comments

Comments
 (0)