Skip to content

Commit a55e3e7

Browse files
committed
Added a TalonController to work with hardware-based PID control on Talon SRX
1 parent de6eed3 commit a55e3e7

File tree

10 files changed

+1189
-52
lines changed

10 files changed

+1189
-52
lines changed

strongback-testing/src/org/strongback/mock/Mock.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,4 +247,12 @@ public static MockTalonSRX stoppedTalonSRX() {
247247
public static MockTalonSRX runningTalonSRX(double speed) {
248248
return new MockTalonSRX(speed);
249249
}
250+
251+
/**
252+
* Create a mock controller.
253+
* @return the mock controller; never null
254+
*/
255+
public static MockController controller() {
256+
return new MockController();
257+
}
250258
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Strongback
3+
* Copyright 2015, Strongback and individual contributors by the @authors tag.
4+
* See the COPYRIGHT.txt in the distribution for a full listing of individual
5+
* contributors.
6+
*
7+
* Licensed under the MIT License; you may not use this file except in
8+
* compliance with the License. You may obtain a copy of the License at
9+
* http://opensource.org/licenses/MIT
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.strongback.mock;
18+
19+
import org.strongback.Executable;
20+
import org.strongback.control.Controller;
21+
22+
/**
23+
* A {@link Controller} implementation that tests can use to manually {@link #setError(double) set the error}.
24+
*
25+
* @author Randall Hauch
26+
*/
27+
public class MockController implements Controller {
28+
29+
private boolean enabled = true;
30+
private double setpoint = 0.0d;
31+
private double tolerance = 0.0d;
32+
private double error = 0.0d;
33+
private final Executable executable = (time)->computeOutput();
34+
35+
@Override
36+
public boolean isEnabled() {
37+
return enabled;
38+
}
39+
40+
@Override
41+
public Controller enable() {
42+
enabled = true;
43+
return this;
44+
}
45+
46+
@Override
47+
public Controller disable() {
48+
enabled = false;
49+
return this;
50+
}
51+
52+
@Override
53+
public double getSetpoint() {
54+
return setpoint;
55+
}
56+
57+
@Override
58+
public Controller setpoint(double setpoint) {
59+
this.setpoint = setpoint;
60+
return this;
61+
}
62+
63+
@Override
64+
public Controller tolerance(double tolerance) {
65+
this.tolerance = tolerance;
66+
return this;
67+
}
68+
69+
@Override
70+
public boolean withinTolerance() {
71+
// Determine if we're within the tolerance ...
72+
return Math.abs(error) < tolerance;
73+
}
74+
75+
@Override
76+
public boolean checkTolerance(double value) {
77+
return Math.abs(value) <= (setpoint - tolerance);
78+
}
79+
80+
@Override
81+
public boolean computeOutput() {
82+
return withinTolerance();
83+
}
84+
85+
@Override
86+
public Controller reset() {
87+
error = 0.0;
88+
return this;
89+
}
90+
91+
@Override
92+
public boolean hasExecutable() {
93+
return true;
94+
}
95+
96+
@Override
97+
public Executable executable() {
98+
return executable;
99+
}
100+
101+
public MockController setError( double error ) {
102+
this.error = error;
103+
return this;
104+
}
105+
}

strongback-testing/src/org/strongback/mock/MockTalonSRX.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package org.strongback.mock;
1818

1919
import org.strongback.components.TalonSRX;
20+
import org.strongback.components.TemperatureSensor;
21+
import org.strongback.components.VoltageSensor;
2022

2123
/**
2224
* @author Randall Hauch
@@ -26,6 +28,9 @@ public class MockTalonSRX extends MockMotor implements TalonSRX {
2628

2729
private final MockAngleSensor encoder = new MockAngleSensor();
2830
private final MockCurrentSensor current = new MockCurrentSensor();
31+
private final MockVoltageSensor voltage = new MockVoltageSensor();
32+
private final MockVoltageSensor busVoltage = new MockVoltageSensor();
33+
private final MockTemperatureSensor temperature = new MockTemperatureSensor();
2934
private final MockSwitch forwardLimitSwitch = new MockSwitch();
3035
private final MockSwitch reverseLimitSwitch = new MockSwitch();
3136

@@ -49,6 +54,21 @@ public MockCurrentSensor getCurrentSensor() {
4954
return current;
5055
}
5156

57+
@Override
58+
public VoltageSensor getVoltageSensor() {
59+
return voltage;
60+
}
61+
62+
@Override
63+
public VoltageSensor getBusVoltageSensor() {
64+
return busVoltage;
65+
}
66+
67+
@Override
68+
public TemperatureSensor getTemperatureSensor() {
69+
return temperature;
70+
}
71+
5272
@Override
5373
public MockSwitch getForwardLimitSwitch() {
5474
return forwardLimitSwitch;

strongback/src/org/strongback/components/TalonSRX.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,31 @@ public interface TalonSRX extends LimitedMotor {
3434
public AngleSensor getAngleSensor();
3535

3636
/**
37-
* Get the Talon SRX's current sensor.
37+
* Get the Talon SRX's output current sensor.
3838
*
39-
* @return the current sensor; never null
39+
* @return the output current sensor; never null
4040
*/
4141
public CurrentSensor getCurrentSensor();
4242

43+
/**
44+
* Get the Talon SRX's output voltage sensor.
45+
*
46+
* @return the output voltage sensor; never null
47+
*/
48+
public VoltageSensor getVoltageSensor();
49+
50+
/**
51+
* Get the Talon SRX's bus voltage.
52+
*
53+
* @return the bus voltage sensor; never null
54+
*/
55+
public VoltageSensor getBusVoltageSensor();
56+
57+
/**
58+
* Get the Talon SRX's temperature sensor.
59+
*
60+
* @return the temperature sensor; never null
61+
*/
62+
public TemperatureSensor getTemperatureSensor();
63+
4364
}

strongback/src/org/strongback/control/Controller.java

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
package org.strongback.control;
1818

19+
import org.strongback.Executable;
20+
import org.strongback.Executor;
21+
import org.strongback.Strongback;
22+
1923
/**
2024
* A basic controller.
2125
*
@@ -24,28 +28,41 @@
2428
public interface Controller {
2529

2630
/**
27-
* Calculate the next controller output. This usually involves reading one or more inputs and computing the output based
28-
* upon a model of the system.
31+
* Determine if this controller is {@link #enable() enabled}.
2932
*
30-
* @return <code>true</code> if the execution completed because it resulted in a value that is within the tolerance of the
31-
* setpoint, or <code>false</code> if this controller is not {@link #isEnabled() enabled} or has not yet reached the
32-
* setpoint given the tolerance
33+
* @return <code>true</code> if enabled, or <code>false</code> otherwise
3334
*/
34-
public boolean computeOutput();
35+
public boolean isEnabled();
3536

3637
/**
37-
* Determines whether the supplied value is within the tolerance of the setpoint.
38+
* Enable this controller so that it does read inputs, compute errors, and generate outputs when {@link #computeOutput()} is
39+
* called.
3840
*
39-
* @param value the proposed value
40-
* @return <code>true</code> if the proposed value is within the tolerance of the setpoint, or <code>false</code> otherwise
41+
* @return this object so that methods can be chained; never null
4142
*/
42-
public boolean checkTolerance(double value);
43+
public Controller enable();
44+
45+
/**
46+
* Disable this controller to <em>not</em> read inputs, compute errors, and generate outputs when {@link #computeOutput()}
47+
* is called.
48+
*
49+
* @return this object so that methods can be chained; never null
50+
*/
51+
public Controller disable();
52+
53+
/**
54+
* Get the target value for this controller.
55+
* @return the target value
56+
* @see #setpoint(double)
57+
*/
58+
public double getSetpoint();
4359

4460
/**
4561
* Sets the target value for this controller.
4662
*
4763
* @param setpoint the desired setpoint that this controller will use as a target
4864
* @return this object so that methods can be chained; never null
65+
* @see #getSetpoint()
4966
*/
5067
public Controller setpoint(double setpoint);
5168

@@ -58,33 +75,57 @@ public interface Controller {
5875
public Controller tolerance(double tolerance);
5976

6077
/**
61-
* Reset any error values stored from previous {@link #computeOutput() executions}.
78+
* Determines whether the current value is within the tolerance of the setpoint.
6279
*
63-
* @return this object so that methods can be chained; never null
80+
* @return <code>true</code> if the current value is within the tolerance of the setpoint, or <code>false</code> otherwise
81+
* @see #checkTolerance(double)
6482
*/
65-
public Controller reset();
83+
public boolean withinTolerance();
6684

6785
/**
68-
* Determine if this controller is {@link #enable() enabled}.
86+
* Determines whether the supplied value is within the tolerance of the setpoint.
6987
*
70-
* @return <code>true</code> if enabled, or <code>false</code> otherwise
88+
* @param value the proposed value
89+
* @return <code>true</code> if the proposed value is within the tolerance of the setpoint, or <code>false</code> otherwise
90+
* @see #withinTolerance()
7191
*/
72-
public boolean isEnabled();
92+
public boolean checkTolerance(double value);
7393

7494
/**
75-
* Enable this controller so that it does read inputs, compute errors, and generate outputs when {@link #computeOutput()} is
76-
* called.
95+
* Calculate the next controller output. This usually involves reading one or more inputs and computing the output based
96+
* upon a model of the system.
7797
*
78-
* @return this object so that methods can be chained; never null
98+
* @return <code>true</code> if the execution completed because it resulted in a value that is within the tolerance of the
99+
* setpoint, or <code>false</code> if this controller is not {@link #isEnabled() enabled} or has not yet reached the
100+
* setpoint given the tolerance
79101
*/
80-
public Controller enable();
102+
public boolean computeOutput();
81103

82104
/**
83-
* Disable this controller to <em>not</em> read inputs, compute errors, and generate outputs when {@link #computeOutput()}
84-
* is called.
105+
* Reset any error values stored from previous {@link #computeOutput() executions}.
85106
*
86107
* @return this object so that methods can be chained; never null
87108
*/
88-
public Controller disable();
109+
public Controller reset();
110+
111+
/**
112+
* Return whether the {@link Executable} instance returned by {@link #executable()} does anything useful. Software-based
113+
* controllers may often return <code>true</code>, whereas many hardware-based controllers may return <code>false</code>.
114+
* @return <code>true</code> if the {@link #executable()} does useful work and enables the controller to operate
115+
* continually and automatically, or <code>false</code> if the {@link #executable()} does nothing.
116+
*/
117+
public boolean hasExecutable();
118+
119+
/**
120+
* Get the {@link Executable} instance that will continuously {@link #computeOutput() execute} this controller to read
121+
* inputs from the source and generate outputs to reach the {@link #setpoint(double) setpoint}.
122+
* <p>
123+
* If this is used, then this same controller should <em>never</em> be used with commands. This is not checked, so robot
124+
* programs are responsible for ensuring this does not happen.
125+
*
126+
* @return the {@link Executable} object that can be registered with an {@link Executor} (typically Strongback's
127+
* {@link Strongback#executor() central executor}); never null and always the same instance for this controller
128+
*/
129+
public Executable executable();
89130

90131
}

0 commit comments

Comments
 (0)