Skip to content

Commit 9ebd8fd

Browse files
committed
Add Motion Magic Talon config
Resolves #20
1 parent 16a789f commit 9ebd8fd

File tree

10 files changed

+255
-6
lines changed

10 files changed

+255
-6
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.strykeforce.thirdcoast.talon;
2+
3+
import com.ctre.CANTalon;
4+
import com.ctre.CANTalon.TalonControlMode;
5+
import com.ctre.CANTalon.VelocityMeasurementPeriod;
6+
import org.jetbrains.annotations.NotNull;
7+
8+
public class MotionMagicTalonConfiguration extends PIDTalonConfiguration {
9+
10+
private final Double motionMagicAcceleration;
11+
private final Double motionMagicCruiseVelocity;
12+
13+
MotionMagicTalonConfiguration(@NotNull String name,
14+
double setpointMax,
15+
Encoder encoder,
16+
Boolean isBrakeInNeutral,
17+
Boolean isOutputReversed,
18+
VelocityMeasurementPeriod velocityMeasurementPeriod,
19+
Integer velocityMeasurementWindow,
20+
LimitSwitch forwardLimitSwitch,
21+
LimitSwitch reverseLimitSwitch,
22+
SoftLimit forwardSoftLimit,
23+
SoftLimit reverseSoftLimit,
24+
Integer currentLimit,
25+
Double voltageRampRate,
26+
Double outputVoltageMax,
27+
Double closedLoopRampRate,
28+
Double forwardOutputVoltagePeak,
29+
Double reverseOutputVoltagePeak,
30+
Double forwardOutputVoltageNominal,
31+
Double reverseOutputVoltageNominal,
32+
Integer allowableClosedLoopError,
33+
Double nominalClosedLoopVoltage,
34+
Double pGain, Double iGain, Double dGain, Double fGain, Integer iZone,
35+
Double motionMagicAcceleration, Double motionMagicCruiseVelocity) {
36+
super(name, TalonControlMode.MotionMagic, setpointMax, encoder, isBrakeInNeutral, isOutputReversed,
37+
velocityMeasurementPeriod, velocityMeasurementWindow, forwardLimitSwitch,
38+
reverseLimitSwitch, forwardSoftLimit, reverseSoftLimit, currentLimit, voltageRampRate,
39+
outputVoltageMax, closedLoopRampRate, forwardOutputVoltagePeak, reverseOutputVoltagePeak,
40+
forwardOutputVoltageNominal, reverseOutputVoltageNominal, allowableClosedLoopError,
41+
nominalClosedLoopVoltage, pGain, iGain, dGain, fGain, iZone);
42+
this.motionMagicAcceleration = motionMagicAcceleration;
43+
this.motionMagicCruiseVelocity = motionMagicCruiseVelocity;
44+
}
45+
46+
@Override
47+
public void configure(@NotNull CANTalon talon) {
48+
super.configure(talon);
49+
talon.changeControlMode(TalonControlMode.MotionMagic);
50+
talon.setMotionMagicAcceleration(valueOrElse(motionMagicAcceleration, 0));
51+
talon.setMotionMagicCruiseVelocity(valueOrElse(motionMagicCruiseVelocity, 0));
52+
}
53+
54+
public Double getMotionMagicAcceleration() {
55+
return motionMagicAcceleration;
56+
}
57+
58+
public Double getMotionMagicCruiseVelocity() {
59+
return motionMagicCruiseVelocity;
60+
}
61+
62+
@Override
63+
public String toString() {
64+
return "MotionMagicTalonConfiguration{" +
65+
"motionMagicAcceleration=" + motionMagicAcceleration +
66+
", motionMagicCruiseVelocity=" + motionMagicCruiseVelocity +
67+
"} " + super.toString();
68+
}
69+
}

core/src/main/java/org/strykeforce/thirdcoast/talon/PIDTalonConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,14 @@ public void configure(@NotNull CANTalon talon) {
8787
super.configure(talon);
8888
}
8989

90-
private double valueOrElse(@Nullable Double value, double def) {
90+
protected double valueOrElse(@Nullable Double value, double def) {
9191
if (value != null) {
9292
return value;
9393
}
9494
return def;
9595
}
9696

97-
private int valueOrElse(@Nullable Integer value, int def) {
97+
protected int valueOrElse(@Nullable Integer value, int def) {
9898
if (value != null) {
9999
return value;
100100
}

core/src/main/java/org/strykeforce/thirdcoast/talon/TalonConfigurationBuilder.java

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ public class TalonConfigurationBuilder {
8282
@Nullable
8383
private Integer iZone;
8484

85+
// MotionMagicTalonConfiguration
86+
@Nullable
87+
private Double motionMagicAcceleration;
88+
@Nullable
89+
private Double motionMagicCruiseVelocity;
90+
8591
/**
8692
* Create a builder with defaults.
8793
*/
@@ -111,6 +117,11 @@ public TalonConfigurationBuilder(final TalonConfiguration config) {
111117
mode = TalonControlMode.Speed;
112118
} else if (config instanceof PositionTalonConfiguration) {
113119
mode = TalonControlMode.Position;
120+
} else if (config instanceof MotionMagicTalonConfiguration) {
121+
mode = TalonControlMode.MotionMagic;
122+
MotionMagicTalonConfiguration mm = (MotionMagicTalonConfiguration) config;
123+
motionMagicAcceleration = mm.getMotionMagicAcceleration();
124+
motionMagicCruiseVelocity = mm.getMotionMagicCruiseVelocity();
114125
} else {
115126
throw new AssertionError(config.getClass().getCanonicalName());
116127
}
@@ -150,11 +161,13 @@ public static TalonConfiguration create(Toml config) {
150161
case Speed:
151162
talonConfiguration = config.to(SpeedTalonConfiguration.class);
152163
break;
164+
case MotionMagic:
165+
talonConfiguration = config.to(MotionMagicTalonConfiguration.class);
166+
break;
153167
case PercentVbus:
154168
case Current:
155169
case Follower:
156170
case MotionProfile:
157-
case MotionMagic:
158171
case Disabled:
159172
throw new UnsupportedOperationException(mode.name());
160173
}
@@ -214,10 +227,19 @@ public TalonConfiguration build() {
214227
reverseOutputVoltagePeak, forwardOutputVoltageNominal, reverseOutputVoltageNominal,
215228
allowableClosedLoopError, nominalClosedLoopVoltage, pGain, iGain, dGain, fGain, iZone);
216229
break;
217-
case Follower:
218230
case MotionMagic:
219-
case Current:
231+
tc = new MotionMagicTalonConfiguration(name, setpointMax, encoder, brakeInNeutral,
232+
outputReversed, velocityMeasurementPeriod, velocityMeasurementWindow,
233+
forwardLimitSwitch, reverseLimitSwitch, forwardSoftLimit, reverseSoftLimit,
234+
currentLimit, voltageRampRate, outputVoltageMax, closedLoopRampRate,
235+
forwardOutputVoltagePeak,
236+
reverseOutputVoltagePeak, forwardOutputVoltageNominal, reverseOutputVoltageNominal,
237+
allowableClosedLoopError, nominalClosedLoopVoltage, pGain, iGain, dGain, fGain, iZone,
238+
motionMagicAcceleration, motionMagicCruiseVelocity);
239+
break;
240+
case Follower:
220241
case MotionProfile:
242+
case Current:
221243
case Disabled:
222244
case PercentVbus:
223245
throw new UnsupportedOperationException(mode.name());
@@ -578,6 +600,30 @@ public TalonConfigurationBuilder iZone(int iZone) {
578600
return this;
579601
}
580602

603+
/**
604+
* Set the motion-magic acceleration.
605+
*
606+
* @param accel value for acceleration.
607+
* @return this builder.
608+
*/
609+
@NotNull
610+
public TalonConfigurationBuilder motionMagicAcceleration(double accel) {
611+
this.motionMagicAcceleration = accel;
612+
return this;
613+
}
614+
615+
/**
616+
* Set the motion-magic cruise velocity.
617+
*
618+
* @param vel value for cruise velocity.
619+
* @return this builder.
620+
*/
621+
@NotNull
622+
public TalonConfigurationBuilder motionMagicCruiseVelocity(double vel) {
623+
this.motionMagicCruiseVelocity = vel;
624+
return this;
625+
}
626+
581627
/**
582628
* Get the forward limit switch.
583629
*

core/src/test/groovy/org/strykeforce/thirdcoast/talon/PIDTalonConfigurationTest.groovy

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ class PIDTalonConfigurationTest extends Specification {
3838
mode = "Speed"
3939
setpointMax = 1.0
4040
41+
[[TALON]]
42+
name = "motion_magic"
43+
mode = "MotionMagic"
44+
motionMagicAcceleration = 2.7
45+
motionMagicCruiseVelocity = 6.7
4146
'''
4247

4348
def talon = Mock(CANTalon)
@@ -152,4 +157,18 @@ class PIDTalonConfigurationTest extends Specification {
152157
t.class == SpeedTalonConfiguration
153158
}
154159

160+
def "configures motion magic mode talon"() {
161+
when:
162+
def t = provisioner.configurationFor("motion_magic")
163+
t.configure(talon)
164+
165+
then:
166+
t.name == "motion_magic"
167+
t.class == MotionMagicTalonConfiguration
168+
169+
and:
170+
1 * talon.setMotionMagicAcceleration(2.7)
171+
1 * talon.setMotionMagicCruiseVelocity(6.7)
172+
}
173+
155174
}

core/src/test/groovy/org/strykeforce/thirdcoast/talon/TalonConfigurationBuilderTest.groovy

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ package org.strykeforce.thirdcoast.talon
33
import com.moandjiezana.toml.Toml
44
import spock.lang.Specification
55

6-
import static com.ctre.CANTalon.FeedbackDevice.*
6+
import static com.ctre.CANTalon.FeedbackDevice.EncRising
7+
import static com.ctre.CANTalon.FeedbackDevice.QuadEncoder
78
import static com.ctre.CANTalon.TalonControlMode.*
89
import static com.ctre.CANTalon.VelocityMeasurementPeriod.Period_25Ms
910
import static com.ctre.CANTalon.VelocityMeasurementPeriod.Period_5Ms
@@ -328,6 +329,22 @@ pGain = 1.2
328329
tc.IZone == 2767
329330
}
330331

332+
def "configure motionMagicAcceleration"() {
333+
when:
334+
MotionMagicTalonConfiguration tc = tcb.mode(MotionMagic).motionMagicAcceleration(27.67).build()
335+
336+
then:
337+
tc.motionMagicAcceleration == 27.67
338+
}
339+
340+
def "configure motionMagicCruiseVelocity"() {
341+
when:
342+
MotionMagicTalonConfiguration tc = tcb.mode(MotionMagic).motionMagicCruiseVelocity(27.67).build()
343+
344+
then:
345+
tc.motionMagicCruiseVelocity == 27.67
346+
}
347+
331348
def "checks config for proper operating mode"() {
332349
given:
333350
def toml = new Toml().read("mode = \"Disabled\"\nsetpointMax = 0.0")
@@ -371,5 +388,24 @@ voltageRampRate = 4.0
371388
vtc.voltageRampRate == 4.0
372389
}
373390

391+
def "reads motion magic params from MotionMagicTalonConfiguration"() {
392+
def input = '''
393+
name = "foo"
394+
mode = "MotionMagic"
395+
setpointMax = 0.0
396+
motionMagicAcceleration = 2.7
397+
motionMagicCruiseVelocity = 6.7
398+
'''
399+
when:
400+
def mmtc = (MotionMagicTalonConfiguration) new TalonConfigurationBuilder(TalonConfigurationBuilder.create(new Toml().read(input))).build()
401+
402+
then:
403+
mmtc instanceof MotionMagicTalonConfiguration
404+
mmtc.name == 'foo'
405+
mmtc.setpointMax == 0.0
406+
mmtc.motionMagicAcceleration == 2.7
407+
mmtc.motionMagicCruiseVelocity == 6.7
408+
}
409+
374410
}
375411

tct/src/main/java/org/strykeforce/thirdcoast/telemetry/tct/talon/InspectCommand.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.slf4j.LoggerFactory;
1313
import org.strykeforce.thirdcoast.talon.Encoder;
1414
import org.strykeforce.thirdcoast.talon.LimitSwitch;
15+
import org.strykeforce.thirdcoast.talon.MotionMagicTalonConfiguration;
1516
import org.strykeforce.thirdcoast.talon.PIDTalonConfiguration;
1617
import org.strykeforce.thirdcoast.talon.SoftLimit;
1718
import org.strykeforce.thirdcoast.talon.TalonConfiguration;
@@ -112,6 +113,12 @@ public void perform() {
112113
doubleLine("D:", pid.getDGain());
113114
doubleLine("F:", pid.getFGain());
114115
intLine("I-zone:", pid.getIZone());
116+
if (config.getMode() == TalonControlMode.MotionMagic) {
117+
writer.println();
118+
MotionMagicTalonConfiguration mmtc = (MotionMagicTalonConfiguration) pid;
119+
doubleLine("MM Cruise Velocity:", mmtc.getMotionMagicCruiseVelocity());
120+
doubleLine("MM Acceleration:", mmtc.getMotionMagicAcceleration());
121+
}
115122
writer.println();
116123
intLine("Allowable CL Error:", pid.getAllowableClosedLoopError());
117124
doubleLine("Nominal CL Voltage:", pid.getNominalClosedLoopVoltage());

tct/src/main/java/org/strykeforce/thirdcoast/telemetry/tct/talon/config/cl/ClosedLoopMenuModule.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,14 @@ public static Menu configMenu(@Named("TALON_CONFIG_CL") CommandAdapter commandAd
6161
@IntoSet
6262
@Named("TALON_CONFIG_CL")
6363
public abstract Command allowableClosedLoopErrorCommand(AllowableClosedLoopErrorCommand command);
64+
65+
@Binds
66+
@IntoSet
67+
@Named("TALON_CONFIG_CL")
68+
public abstract Command motionMagicAccelerationCommand(MotionMagicAccelerationCommand command);
69+
70+
@Binds
71+
@IntoSet
72+
@Named("TALON_CONFIG_CL")
73+
public abstract Command motionMagicCruiseVelocityCommand(MotionMagicCruiseVelocityCommand command);
6474
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.strykeforce.thirdcoast.telemetry.tct.talon.config.cl;
2+
3+
import com.ctre.CANTalon;
4+
import javax.inject.Inject;
5+
import org.jline.reader.LineReader;
6+
import org.strykeforce.thirdcoast.telemetry.tct.talon.TalonSet;
7+
import org.strykeforce.thirdcoast.telemetry.tct.talon.config.AbstractDoubleConfigCommand;
8+
9+
/**
10+
* Configure Motion Magic Acceleration.
11+
*/
12+
public class MotionMagicAccelerationCommand extends AbstractDoubleConfigCommand {
13+
14+
public final static String NAME = "Motion Magic Acceleration";
15+
16+
@Inject
17+
public MotionMagicAccelerationCommand(LineReader reader, TalonSet talonSet) {
18+
super(NAME, reader, talonSet);
19+
}
20+
21+
@Override
22+
protected void saveConfig(double value) {
23+
talonSet.talonConfigurationBuilder().motionMagicAcceleration(value);
24+
}
25+
26+
@Override
27+
protected void config(CANTalon talon, double value) {
28+
talon.setMotionMagicAcceleration(value);
29+
}
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.strykeforce.thirdcoast.telemetry.tct.talon.config.cl;
2+
3+
import com.ctre.CANTalon;
4+
import javax.inject.Inject;
5+
import org.jline.reader.LineReader;
6+
import org.strykeforce.thirdcoast.telemetry.tct.talon.TalonSet;
7+
import org.strykeforce.thirdcoast.telemetry.tct.talon.config.AbstractDoubleConfigCommand;
8+
9+
/**
10+
* Configure Motion Magic Cruise Velocity.
11+
*/
12+
public class MotionMagicCruiseVelocityCommand extends AbstractDoubleConfigCommand {
13+
14+
public final static String NAME = "Motion Magic Cruise Velocity";
15+
16+
@Inject
17+
public MotionMagicCruiseVelocityCommand(LineReader reader, TalonSet talonSet) {
18+
super(NAME, reader, talonSet);
19+
}
20+
21+
@Override
22+
protected void saveConfig(double value) {
23+
talonSet.talonConfigurationBuilder().motionMagicCruiseVelocity(value);
24+
}
25+
26+
@Override
27+
protected void config(CANTalon talon, double value) {
28+
talon.setMotionMagicCruiseVelocity(value);
29+
}
30+
}

tct/src/main/resources/org/strykeforce/thirdcoast/telemetry/tct/menu.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ TALON_CONFIG_CL = [
3232
"org.strykeforce.thirdcoast.telemetry.tct.talon.config.cl.FCommand",
3333
"org.strykeforce.thirdcoast.telemetry.tct.talon.config.cl.IZoneCommand",
3434
"org.strykeforce.thirdcoast.telemetry.tct.talon.config.cl.AllowableClosedLoopErrorCommand",
35+
"org.strykeforce.thirdcoast.telemetry.tct.talon.config.cl.MotionMagicCruiseVelocityCommand",
36+
"org.strykeforce.thirdcoast.telemetry.tct.talon.config.cl.MotionMagicAccelerationCommand",
3537
]
3638

3739
TALON_CONFIG_ENC = [

0 commit comments

Comments
 (0)