-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMechanism.java
More file actions
190 lines (171 loc) · 7.21 KB
/
Mechanism.java
File metadata and controls
190 lines (171 loc) · 7.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/**
* © 2025 Excalibur FRC. All rights reserved.
* This file is part of ExcaLIb and may not be copied, modified,
* or distributed without permission, except as permitted by license.
* learn more at - https://github.com/ExaliburFRC/ExcaLIb
*/
package frc.excalib.mechanisms;
import edu.wpi.first.units.measure.*;
import edu.wpi.first.wpilibj2.command.*;
import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine;
import frc.excalib.control.gains.SysidConfig;
import frc.excalib.control.motor.controllers.Motor;
import frc.excalib.control.motor.motor_specs.IdleState;
import monologue.Logged;
import java.util.function.DoubleSupplier;
import static edu.wpi.first.units.Units.*;
import static edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine.Direction;
import static monologue.Annotations.Log;
/**
* A class representing a generic Mechanism
*/
public class Mechanism implements Logged {
protected final Motor m_motor;
protected final MutVoltage m_appliedVoltage = Volts.mutable(0);
protected final MutAngle m_radians = Radians.mutable(0);
protected final MutDistance m_meter = Meters.mutable(0);
protected final MutAngularVelocity m_velocity = RadiansPerSecond.mutable(0);
protected final MutLinearVelocity m_Linearvelocity = MetersPerSecond.mutable(0);
private final IdleState m_DEFAULT_IDLE_STATE;
/**
* @param motor the motor controlling the mechanism
*/
public Mechanism(Motor motor) {
m_motor = motor;
m_DEFAULT_IDLE_STATE = m_motor.getIdleState();
}
/**
* @param output set the duty cycle output
*/
public void setOutput(double output) {
m_motor.setPercentage(output);
}
/**
* @param voltage set the voltage cycle output
*/
public void setVoltage(double voltage) {
m_motor.setVoltage(voltage);
}
/**
* @param outputSupplier the dynamic setpoint for the mechanism (voltage)
* @return a command which controls the mechanism manually
*/
public Command manualCommand(DoubleSupplier outputSupplier, SubsystemBase... requirements) {
return Commands.runEnd(
() -> setOutput(outputSupplier.getAsDouble()),
() -> setOutput(0),
requirements
);
}
/**
* @return an instant command to stop the motor
*/
public Command stopMotorCommand(SubsystemBase... requirements) {
return new InstantCommand(() -> setOutput(0), requirements);
}
/**
* @return the velocity
*/
@Log.NT
public double logVelocity() {
return m_motor.getMotorVelocity();
}
/**
* @return the position
*/
@Log.NT
public double logPosition() {
return m_motor.getMotorPosition();
}
@Log.NT
public double logVoltage() {
return m_motor.getVoltage();
}
@Log.NT
public double logCurrent() {
return m_motor.getCurrent();
}
/**
* Creates a SysIdRoutine for linear mechanisms.
*
* @param subsystem the subsystem associated with the mechanism
* @param sensorInput a supplier providing the sensor input for the mechanism
* @param config the configuration for the SysIdRoutine
* @return a SysIdRoutine configured for linear mechanisms
*/
private SysIdRoutine getLinearSysIdRoutine(SubsystemBase subsystem, DoubleSupplier sensorInput, SysidConfig config) {
return new SysIdRoutine(
config,
new SysIdRoutine.Mechanism(
(Voltage volts) -> m_motor.setVoltage(volts.in(Volts)),
log -> log.motor("motor")
.voltage(m_appliedVoltage.mut_replace(
m_motor.getVoltage(), Volts))
.linearPosition(m_meter.mut_replace(sensorInput.getAsDouble(), Meters))
.linearVelocity(m_Linearvelocity.mut_replace(logVelocity(), MetersPerSecond)),
subsystem
)
);
}
/**
* Creates a SysIdRoutine for angular mechanisms.
*
* @param subsystem the subsystem associated with the mechanism
* @param sensorInput a supplier providing the sensor input for the mechanism
* @param config the configuration for the SysIdRoutine
* @return a SysIdRoutine configured for angular mechanisms
*/
private SysIdRoutine getAngularSysIdRoutine(SubsystemBase subsystem, DoubleSupplier sensorInput, SysidConfig config) {
return new SysIdRoutine(
config,
new SysIdRoutine.Mechanism(
(Voltage volts) -> m_motor.setVoltage(volts.in(Volts)),
log -> log.motor("motor")
.voltage(m_appliedVoltage.mut_replace(
m_motor.getVoltage(), Volts))
.angularPosition(m_radians.mut_replace(sensorInput.getAsDouble(), Radians))
.angularVelocity(m_velocity.mut_replace(logVelocity(), RadiansPerSecond)),
subsystem
)
);
}
/**
* @return a command which puts the mechanism on coast mode
*/
public Command coastCommand(SubsystemBase... requirements) {
return new StartEndCommand(
() -> m_motor.setIdleState(IdleState.COAST),
() -> m_motor.setIdleState(m_DEFAULT_IDLE_STATE),
requirements
).ignoringDisable(true);
}
/**
* Creates a SysIdRoutine for performing a quasistatic test on the mechanism.
*
* @param direction the direction of the test (forward or backward)
* @param subsystem the subsystem associated with the mechanism
* @param positionSupplier a supplier providing the position of the mechanism
* @param config the configuration for the SysIdRoutine
* @param isLinear true if the mechanism is linear, false if it is angular
* @return a Command that performs a quasistatic test
*/
public Command sysIdQuasistatic(Direction direction, SubsystemBase subsystem, DoubleSupplier positionSupplier, SysidConfig config, boolean isLinear) {
if (isLinear) return getLinearSysIdRoutine(subsystem, positionSupplier, config).quasistatic(direction);
return getAngularSysIdRoutine(subsystem, positionSupplier, config).quasistatic(direction);
}
/**
* Creates a SysIdRoutine for performing a dynamic test on the mechanism.
*
* @param direction the direction of the test (forward or backward)
* @param subsystem the subsystem associated with the mechanism
* @param positionSupplier a supplier providing the position of the mechanism
* @param config the configuration for the SysIdRoutine
* @param isLinear true if the mechanism is linear, false if it is angular
* @return a Command that performs a dynamic test
*/
public Command sysIdDynamic(Direction direction, SubsystemBase subsystem, DoubleSupplier positionSupplier, SysidConfig config, boolean isLinear) {
if (isLinear)
return getLinearSysIdRoutine(subsystem, positionSupplier, config).dynamic(direction);
return getAngularSysIdRoutine(subsystem, positionSupplier, config).dynamic(direction);
}
}