2
2
# Open Source Software; you can modify and/or share it under the terms of
3
3
# the WPILib BSD license file in the root directory of this project.
4
4
from __future__ import annotations
5
- from typing import Set , Callable , Union , List
5
+ from typing import Set , Callable , Union , List , Optional
6
6
7
7
from wpimath .controller import (
8
8
HolonomicDriveController ,
@@ -40,11 +40,6 @@ class MecanumControllerCommand(Command):
40
40
to the angle given in the final state of the trajectory.
41
41
"""
42
42
43
- __FRONT_LEFT_INDEX = 0
44
- __REAR_LEFT_INDEX = 1
45
- __FRONT_RIGHT_INDEX = 2
46
- __REAR_RIGHT_INDEX = 3
47
-
48
43
def __init__ (
49
44
self ,
50
45
trajectory : Trajectory ,
@@ -55,115 +50,108 @@ def __init__(
55
50
thetaController : ProfiledPIDControllerRadians ,
56
51
# rotationSupplier: Callable[[], Rotation2d],
57
52
maxWheelVelocityMetersPerSecond : float ,
58
- outputConsumer : Callable [[Union [ List [ float ], MecanumDriveWheelSpeeds ] ], None ],
53
+ outputConsumer : Callable [[MecanumDriveWheelSpeeds ], None ],
59
54
* requirements : Subsystem ,
60
- feedforward : SimpleMotorFeedforwardMeters | None = None ,
61
- chassisWheelPIDControllers : List [PIDController ] | None = None ,
62
- currentWheelSpeedsSupplier : Callable [[], MecanumDriveWheelSpeeds ] | None = None ,
55
+ feedforward : Optional [SimpleMotorFeedforwardMeters ] = None ,
56
+ frontLeftController : Optional [PIDController ] = None ,
57
+ rearLeftController : Optional [PIDController ] = None ,
58
+ frontRightController : Optional [PIDController ] = None ,
59
+ rearRightController : Optional [PIDController ] = None ,
60
+ currentWheelSpeedsSupplier : Optional [
61
+ Callable [[], MecanumDriveWheelSpeeds ]
62
+ ] = None ,
63
63
):
64
64
super ().__init__ ()
65
65
66
- self .trajectory : Trajectory = trajectory
67
- self .pose = pose
68
- self .kinematics = kinematics
69
- self .controller = HolonomicDriveController (
66
+ self ._trajectory : Trajectory = trajectory
67
+ self ._pose = pose
68
+ self ._kinematics = kinematics
69
+ self ._controller = HolonomicDriveController (
70
70
xController , yController , thetaController
71
71
)
72
72
# self.rotationSupplier = rotationSupplier
73
- self .maxWheelVelocityMetersPerSecond = maxWheelVelocityMetersPerSecond
74
- self .outputConsumer = outputConsumer
73
+ self ._maxWheelVelocityMetersPerSecond = maxWheelVelocityMetersPerSecond
74
+ self ._outputConsumer = outputConsumer
75
75
76
76
# Member to track time of last loop execution
77
- self .prevTime = 0
78
- self .usePID = False
77
+ self ._prevTime = 0
78
+ self ._usePID = False
79
79
80
80
# Optional requirements checks. If any one of the feedforward, pidcontrollers, or wheelspeedsuppliers
81
81
# are not None, then all should be non-null. Raise RuntimeError if they are. The List of PID controllers
82
82
# should be equal to each corner of the robot being commanded.
83
83
if (
84
84
feedforward
85
- or chassisWheelPIDControllers
85
+ or frontLeftController
86
+ or rearLeftController
87
+ or frontRightController
88
+ or rearRightController
86
89
or currentWheelSpeedsSupplier is not None
87
90
):
88
91
if (
89
92
feedforward
90
- or chassisWheelPIDControllers
93
+ or frontLeftController
94
+ or rearLeftController
95
+ or frontRightController
96
+ or rearRightController
91
97
or currentWheelSpeedsSupplier is None
92
98
):
93
99
raise RuntimeError (
94
- f"Failed to instantiate MecanumControllerCommand, one of the arguments passed in was None: \n \
95
- \t Feedforward: { feedforward } - chassisWheelPIDControllers: { chassisWheelPIDControllers } - wheelSpeedSupplier: { currentWheelSpeedsSupplier } "
100
+ f"Failed to instantiate MecanumControllerCommand, one of the arguments passed in was None "
96
101
)
97
102
98
- # check the length of the PID controllers
99
- if len (chassisWheelPIDControllers != 4 ):
100
- raise RuntimeError (
101
- f"Failed to instantiate MecanumControllerCommand, not enough PID controllers provided.\n \
102
- \t Required: 4 - Provided: { len (chassisWheelPIDControllers )} "
103
- )
104
-
105
- self .frontLeftController = chassisWheelPIDControllers [
106
- self .__FRONT_LEFT_INDEX
107
- ]
108
- self .rearLeftController = chassisWheelPIDControllers [self .__REAR_LEFT_INDEX ]
109
- self .frontRightController = chassisWheelPIDControllers [
110
- self .__FRONT_RIGHT_INDEX
111
- ]
112
- self .rearRightController = chassisWheelPIDControllers [
113
- self .__REAR_RIGHT_INDEX
114
- ]
103
+ self ._frontLeftController = frontLeftController
104
+ self ._rearLeftController = rearLeftController
105
+ self ._frontRightController = frontRightController
106
+ self ._rearRightController = rearRightController
115
107
116
108
if currentWheelSpeedsSupplier is None :
117
109
raise RuntimeError (
118
110
f"Failed to instantiate MecanumControllerCommand, no WheelSpeedSupplierProvided."
119
111
)
120
112
121
- self .currentWheelSpeeds = currentWheelSpeedsSupplier
113
+ self ._currentWheelSpeeds = currentWheelSpeedsSupplier
122
114
123
115
if feedforward is None :
124
116
raise RuntimeError (
125
117
f"Failed to instantiate MecanumControllerCommand, no SimpleMotorFeedforwardMeters supplied."
126
118
)
127
119
128
- self .feedforward : SimpleMotorFeedforwardMeters = feedforward
120
+ self ._feedforward = feedforward
129
121
130
122
# All the optional requirements verify, set usePid flag to True
131
- self .usePID = True
123
+ self ._usePID = True
132
124
133
125
# Set the requirements for the command
134
126
self .addRequirements (* requirements )
135
127
136
- self .timer = Timer ()
128
+ self ._timer = Timer ()
137
129
138
130
def initialize (self ):
139
- initialState : Trajectory . State = self .trajectory .sample (0 )
131
+ initialState = self ._trajectory .sample (0 )
140
132
initialXVelocity = initialState .velocity * initialState .pose .rotation ().cos ()
141
133
initialYVelocity = initialState .velocity * initialState .pose .rotation ().sin ()
142
- self .m_prevSpeeds = self .kinematics .toWheelSpeeds (
134
+ self .m_prevSpeeds = self ._kinematics .toWheelSpeeds (
143
135
ChassisSpeeds (initialXVelocity , initialYVelocity , 0.0 )
144
136
)
145
- self .timer .restart ()
146
- self .prevTime = 0
137
+ self ._timer .restart ()
147
138
148
139
def execute (self ):
149
- curTime = self .timer .get ()
150
- dt = curTime - self .prevTime
151
- desiredState : Trajectory .State = self .trajectory .sample (curTime )
152
- targetChassisSpeeds = self .controller .calculate (
153
- self .pose (),
154
- desiredState ,
155
- desiredState .pose .rotation ()
156
- # self.pose.get(), desiredState, self.rotationSupplier.get()
140
+ curTime = self ._timer .get ()
141
+ dt = curTime - self ._prevTime
142
+ desiredState = self ._trajectory .sample (curTime )
143
+ targetChassisSpeeds = self ._controller .calculate (
144
+ self ._pose (), desiredState , desiredState .pose .rotation ()
157
145
)
158
- targetWheelSpeeds = self .kinematics .toWheelSpeeds (targetChassisSpeeds )
159
- targetWheelSpeeds .desaturate (self .maxWheelVelocityMetersPerSecond )
146
+ targetWheelSpeeds = self ._kinematics .toWheelSpeeds (targetChassisSpeeds )
147
+ targetWheelSpeeds .desaturate (self ._maxWheelVelocityMetersPerSecond )
160
148
frontLeftSpeedSetpoint = targetWheelSpeeds .frontLeft
161
149
rearLeftSpeedSetpoint = targetWheelSpeeds .rearLeft
162
150
frontRightSpeedSetpoint = targetWheelSpeeds .frontRight
163
151
rearRightSpeedSetpoint = targetWheelSpeeds .rearRight
164
152
165
- if not self .usePID :
166
- self .outputConsumer (
153
+ if not self ._usePID :
154
+ self ._outputConsumer (
167
155
MecanumDriveWheelSpeeds (
168
156
frontLeftSpeedSetpoint ,
169
157
frontRightSpeedSetpoint ,
@@ -172,51 +160,57 @@ def execute(self):
172
160
)
173
161
)
174
162
else :
175
- frontLeftFeedforward = self .feedforward .calculate (
163
+ frontLeftFeedforward = self ._feedforward .calculate (
176
164
frontLeftSpeedSetpoint ,
177
165
(frontLeftSpeedSetpoint - self .m_prevSpeeds .frontLeft ) / dt ,
178
166
)
179
- rearLeftFeedforward = self .feedforward .calculate (
167
+ rearLeftFeedforward = self ._feedforward .calculate (
180
168
rearLeftSpeedSetpoint ,
181
169
(rearLeftSpeedSetpoint - self .m_prevSpeeds .rearLeft ) / dt ,
182
170
)
183
- frontRightFeedforward = self .feedforward .calculate (
171
+ frontRightFeedforward = self ._feedforward .calculate (
184
172
frontRightSpeedSetpoint ,
185
173
(frontRightSpeedSetpoint - self .m_prevSpeeds .frontRight ) / dt ,
186
174
)
187
- rearRightFeedforward = self .feedforward .calculate (
175
+ rearRightFeedforward = self ._feedforward .calculate (
188
176
rearRightSpeedSetpoint ,
189
177
(rearRightSpeedSetpoint - self .m_prevSpeeds .rearRight ) / dt ,
190
178
)
191
- frontLeftOutput = frontLeftFeedforward + self .frontLeftController .calculate (
192
- self .currentWheelSpeeds ().frontLeft ,
193
- frontLeftSpeedSetpoint ,
179
+ frontLeftOutput = (
180
+ frontLeftFeedforward
181
+ + self ._frontLeftController .calculate (
182
+ self ._currentWheelSpeeds ().frontLeft ,
183
+ frontLeftSpeedSetpoint ,
184
+ )
194
185
)
195
- rearLeftOutput = rearLeftFeedforward + self .rearLeftController .calculate (
196
- self .currentWheelSpeeds ().rearLeft ,
186
+ rearLeftOutput = rearLeftFeedforward + self ._rearLeftController .calculate (
187
+ self ._currentWheelSpeeds ().rearLeft ,
197
188
rearLeftSpeedSetpoint ,
198
189
)
199
190
frontRightOutput = (
200
191
frontRightFeedforward
201
- + self .frontRightController .calculate (
202
- self .currentWheelSpeeds ().frontRight ,
192
+ + self ._frontRightController .calculate (
193
+ self ._currentWheelSpeeds ().frontRight ,
203
194
frontRightSpeedSetpoint ,
204
195
)
205
196
)
206
- rearRightOutput = rearRightFeedforward + self .rearRightController .calculate (
207
- self .currentWheelSpeeds ().rearRight ,
208
- rearRightSpeedSetpoint ,
197
+ rearRightOutput = (
198
+ rearRightFeedforward
199
+ + self ._rearRightController .calculate (
200
+ self ._currentWheelSpeeds ().rearRight ,
201
+ rearRightSpeedSetpoint ,
202
+ )
209
203
)
210
- self .outputConsumer (
204
+ self ._outputConsumer (
211
205
frontLeftOutput , frontRightOutput , rearLeftOutput , rearRightOutput
212
206
)
213
207
214
208
# Store current call information for next call
215
- self .prevTime = curTime
209
+ self ._prevTime = curTime
216
210
self .m_prevSpeeds = targetWheelSpeeds
217
211
218
212
def end (self , interrupted ):
219
- self .timer .stop ()
213
+ self ._timer .stop ()
220
214
221
215
def isFinished (self ):
222
- return self .timer .hasElapsed (self .trajectory .totalTime ())
216
+ return self ._timer .hasElapsed (self ._trajectory .totalTime ())
0 commit comments