Skip to content

Commit 66c0941

Browse files
Tony Braramikhalev
authored andcommitted
replace algorithm for trapezoid controller
1 parent 83bbb7e commit 66c0941

File tree

1 file changed

+93
-29
lines changed

1 file changed

+93
-29
lines changed
Lines changed: 93 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,124 @@
11
package org.teamtators.rotator.control;
22

3+
import org.teamtators.rotator.config.ConfigException;
34
import org.teamtators.rotator.config.Configurable;
45

56
/**
67
* A controller for motion with a trapezoidal velocity graph
78
*/
89
public class TrapezoidController extends AbstractController implements Configurable<TrapezoidController.Config> {
9-
private double startSpeed;
10-
private double endSpeed;
11-
private double maxVelocity;
12-
private double accelerationEnd;
13-
private double decelerationStart;
14-
private double decelerationEnd;
10+
private double startVelocity;
11+
private double endVelocity;
12+
private double travelVelocity;
13+
private double maxAbsAcceleration;
14+
15+
private boolean isTrapezoidal;
16+
private double time;
17+
private double totalTime;
18+
private double startSectionTime;
19+
private double flatTime;
1520

1621
public TrapezoidController(String name) {
1722
super(name);
23+
time = 0;
1824
}
1925

2026
public TrapezoidController() {
2127
this("TrapezoidController");
2228
}
2329

30+
public double getStartVelocity() {
31+
return startVelocity;
32+
}
33+
34+
public void setStartVelocity(double startVelocity) {
35+
this.startVelocity = startVelocity;
36+
}
37+
38+
public double getEndVelocity() {
39+
return endVelocity;
40+
}
41+
42+
public void setEndVelocity(double endVelocity) {
43+
this.endVelocity = endVelocity;
44+
}
45+
46+
public double getTravelVelocity() {
47+
return travelVelocity;
48+
}
49+
50+
public void setTravelVelocity(double travelVelocity) {
51+
this.travelVelocity = travelVelocity;
52+
}
53+
54+
public double getMaxAbsAcceleration() {
55+
return maxAbsAcceleration;
56+
}
57+
58+
public void setMaxAbsAcceleration(double maxAbsAcceleration) {
59+
this.maxAbsAcceleration = maxAbsAcceleration;
60+
}
61+
62+
@Override
63+
public void onEnable() {
64+
startSectionTime = Math.abs(travelVelocity - startVelocity) / maxAbsAcceleration;
65+
double endSectionTime = Math.abs(travelVelocity - endVelocity) / maxAbsAcceleration;
66+
double startDistance = startSectionTime * (travelVelocity + startVelocity) / 2;
67+
double endDistance = endSectionTime * (travelVelocity + endVelocity) / 2;
68+
double flatDistance = getSetpoint() - (startDistance + endDistance);
69+
flatTime = flatDistance / travelVelocity;
70+
isTrapezoidal = flatTime >= 0;
71+
if (!isTrapezoidal) {
72+
totalTime = Math.sqrt(getSetpoint() / maxAbsAcceleration) * 2;
73+
}
74+
super.onEnable();
75+
}
76+
2477
@Override
2578
protected double computeOutput(double delta) {
26-
double input = getInput();
27-
if (input < accelerationEnd) {
28-
return startSpeed
29-
+ (maxVelocity - startSpeed) * (input / accelerationEnd);
30-
} else if (input >= accelerationEnd && input < decelerationStart) {
31-
return maxVelocity;
32-
} else if (input >= decelerationStart && input < decelerationEnd) {
33-
return maxVelocity - (maxVelocity - endSpeed)
34-
* (input - decelerationStart)
35-
/ (decelerationEnd - decelerationStart);
79+
time += delta;
80+
double velocity;
81+
if (isTrapezoidal) {
82+
if (time < startSectionTime) {
83+
// accelerating
84+
velocity = Math.signum(travelVelocity - startVelocity) * maxAbsAcceleration * time + startVelocity;
85+
} else if (time >= startSectionTime + flatTime) {
86+
// decelerating
87+
velocity = Math.signum(endVelocity - travelVelocity) * maxAbsAcceleration
88+
* (time - (startSectionTime + flatTime)) + endVelocity;
89+
} else {
90+
// constant velocity
91+
velocity = travelVelocity;
92+
}
3693
} else {
37-
return endSpeed;
94+
if (time < totalTime / 2) {
95+
velocity = Math.signum(travelVelocity - startVelocity) * maxAbsAcceleration * time + startVelocity;
96+
} else {
97+
velocity = Math.signum(endVelocity - travelVelocity) * maxAbsAcceleration * time + endVelocity;
98+
}
3899
}
100+
return velocity;
39101
}
40102

41103
@Override
42104
public void configure(Config config) {
43-
startSpeed = config.startSpeed;
44-
endSpeed = config.endSpeed;
45-
maxVelocity = config.maxVelocity;
46-
accelerationEnd = config.accelerationEnd;
47-
decelerationStart = config.decelerationStart;
48-
decelerationEnd = config.decelerationEnd;
105+
travelVelocity = config.travelVelocity;
106+
maxAbsAcceleration = config.maxAbsAcceleration;
107+
startVelocity = config.startVelocity;
108+
endVelocity = config.endVelocity;
109+
if (maxAbsAcceleration <= 0) {
110+
throw new ConfigException("Absolute value of maxAbsAcceleration must be a positive number");
111+
}
112+
if (travelVelocity == 0) {
113+
throw new ConfigException("Travel velocity must not be 0");
114+
}
49115
super.configure(config);
50116
}
51117

52118
static class Config extends AbstractController.Config {
53-
public double startSpeed = 0;
54-
public double endSpeed = 0;
55-
public double maxVelocity;
56-
public double accelerationEnd = 0;
57-
public double decelerationStart;
58-
public double decelerationEnd;
119+
public double startVelocity = 0;
120+
public double endVelocity = 0;
121+
public double travelVelocity;
122+
public double maxAbsAcceleration;
59123
}
60124
}

0 commit comments

Comments
 (0)