@horizon36596/zenith-core 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +18 -0
  3. package/README.md +16 -0
  4. package/dist/canonicalize.d.ts +25 -0
  5. package/dist/canonicalize.d.ts.map +1 -0
  6. package/dist/canonicalize.js +199 -0
  7. package/dist/canonicalize.js.map +1 -0
  8. package/dist/check.d.ts +26 -0
  9. package/dist/check.d.ts.map +1 -0
  10. package/dist/check.js +231 -0
  11. package/dist/check.js.map +1 -0
  12. package/dist/checks/heading.d.ts +17 -0
  13. package/dist/checks/heading.d.ts.map +1 -0
  14. package/dist/checks/heading.js +78 -0
  15. package/dist/checks/heading.js.map +1 -0
  16. package/dist/checks/intake.d.ts +28 -0
  17. package/dist/checks/intake.d.ts.map +1 -0
  18. package/dist/checks/intake.js +131 -0
  19. package/dist/checks/intake.js.map +1 -0
  20. package/dist/checks/motion.d.ts +28 -0
  21. package/dist/checks/motion.d.ts.map +1 -0
  22. package/dist/checks/motion.js +252 -0
  23. package/dist/checks/motion.js.map +1 -0
  24. package/dist/checks/schedule.d.ts +29 -0
  25. package/dist/checks/schedule.d.ts.map +1 -0
  26. package/dist/checks/schedule.js +166 -0
  27. package/dist/checks/schedule.js.map +1 -0
  28. package/dist/checks/season.d.ts +6 -0
  29. package/dist/checks/season.d.ts.map +1 -0
  30. package/dist/checks/season.js +126 -0
  31. package/dist/checks/season.js.map +1 -0
  32. package/dist/continuity.d.ts +38 -0
  33. package/dist/continuity.d.ts.map +1 -0
  34. package/dist/continuity.js +69 -0
  35. package/dist/continuity.js.map +1 -0
  36. package/dist/diff.d.ts +37 -0
  37. package/dist/diff.d.ts.map +1 -0
  38. package/dist/diff.js +258 -0
  39. package/dist/diff.js.map +1 -0
  40. package/dist/edit/command.d.ts +4 -0
  41. package/dist/edit/command.d.ts.map +1 -0
  42. package/dist/edit/command.js +16 -0
  43. package/dist/edit/command.js.map +1 -0
  44. package/dist/edit/errors.d.ts +9 -0
  45. package/dist/edit/errors.d.ts.map +1 -0
  46. package/dist/edit/errors.js +12 -0
  47. package/dist/edit/errors.js.map +1 -0
  48. package/dist/edit/fields.d.ts +40 -0
  49. package/dist/edit/fields.d.ts.map +1 -0
  50. package/dist/edit/fields.js +150 -0
  51. package/dist/edit/fields.js.map +1 -0
  52. package/dist/edit/finish.d.ts +15 -0
  53. package/dist/edit/finish.d.ts.map +1 -0
  54. package/dist/edit/finish.js +36 -0
  55. package/dist/edit/finish.js.map +1 -0
  56. package/dist/edit/groups.d.ts +66 -0
  57. package/dist/edit/groups.d.ts.map +1 -0
  58. package/dist/edit/groups.js +277 -0
  59. package/dist/edit/groups.js.map +1 -0
  60. package/dist/edit/ids.d.ts +39 -0
  61. package/dist/edit/ids.d.ts.map +1 -0
  62. package/dist/edit/ids.js +76 -0
  63. package/dist/edit/ids.js.map +1 -0
  64. package/dist/edit/index.d.ts +22 -0
  65. package/dist/edit/index.d.ts.map +1 -0
  66. package/dist/edit/index.js +22 -0
  67. package/dist/edit/index.js.map +1 -0
  68. package/dist/edit/meta.d.ts +15 -0
  69. package/dist/edit/meta.d.ts.map +1 -0
  70. package/dist/edit/meta.js +13 -0
  71. package/dist/edit/meta.js.map +1 -0
  72. package/dist/edit/path.d.ts +36 -0
  73. package/dist/edit/path.d.ts.map +1 -0
  74. package/dist/edit/path.js +135 -0
  75. package/dist/edit/path.js.map +1 -0
  76. package/dist/edit/steps.d.ts +53 -0
  77. package/dist/edit/steps.d.ts.map +1 -0
  78. package/dist/edit/steps.js +0 -0
  79. package/dist/edit/steps.js.map +1 -0
  80. package/dist/edit/template.d.ts +18 -0
  81. package/dist/edit/template.d.ts.map +1 -0
  82. package/dist/edit/template.js +30 -0
  83. package/dist/edit/template.js.map +1 -0
  84. package/dist/edit/timing.d.ts +11 -0
  85. package/dist/edit/timing.d.ts.map +1 -0
  86. package/dist/edit/timing.js +23 -0
  87. package/dist/edit/timing.js.map +1 -0
  88. package/dist/edit/tree.d.ts +32 -0
  89. package/dist/edit/tree.d.ts.map +1 -0
  90. package/dist/edit/tree.js +90 -0
  91. package/dist/edit/tree.js.map +1 -0
  92. package/dist/estimate.d.ts +48 -0
  93. package/dist/estimate.d.ts.map +1 -0
  94. package/dist/estimate.js +443 -0
  95. package/dist/estimate.js.map +1 -0
  96. package/dist/findingHelp.d.ts +18 -0
  97. package/dist/findingHelp.d.ts.map +1 -0
  98. package/dist/findingHelp.js +114 -0
  99. package/dist/findingHelp.js.map +1 -0
  100. package/dist/fix.d.ts +21 -0
  101. package/dist/fix.d.ts.map +1 -0
  102. package/dist/fix.js +180 -0
  103. package/dist/fix.js.map +1 -0
  104. package/dist/footprint.d.ts +33 -0
  105. package/dist/footprint.d.ts.map +1 -0
  106. package/dist/footprint.js +71 -0
  107. package/dist/footprint.js.map +1 -0
  108. package/dist/geometry/angle.d.ts +13 -0
  109. package/dist/geometry/angle.d.ts.map +1 -0
  110. package/dist/geometry/angle.js +21 -0
  111. package/dist/geometry/angle.js.map +1 -0
  112. package/dist/geometry/curve.d.ts +24 -0
  113. package/dist/geometry/curve.d.ts.map +1 -0
  114. package/dist/geometry/curve.js +78 -0
  115. package/dist/geometry/curve.js.map +1 -0
  116. package/dist/geometry/path.d.ts +29 -0
  117. package/dist/geometry/path.d.ts.map +1 -0
  118. package/dist/geometry/path.js +61 -0
  119. package/dist/geometry/path.js.map +1 -0
  120. package/dist/geometry/quadrature.d.ts +13 -0
  121. package/dist/geometry/quadrature.d.ts.map +1 -0
  122. package/dist/geometry/quadrature.js +57 -0
  123. package/dist/geometry/quadrature.js.map +1 -0
  124. package/dist/geometry/sat.d.ts +40 -0
  125. package/dist/geometry/sat.d.ts.map +1 -0
  126. package/dist/geometry/sat.js +86 -0
  127. package/dist/geometry/sat.js.map +1 -0
  128. package/dist/geometry/vec.d.ts +27 -0
  129. package/dist/geometry/vec.d.ts.map +1 -0
  130. package/dist/geometry/vec.js +30 -0
  131. package/dist/geometry/vec.js.map +1 -0
  132. package/dist/heading.d.ts +77 -0
  133. package/dist/heading.d.ts.map +1 -0
  134. package/dist/heading.js +164 -0
  135. package/dist/heading.js.map +1 -0
  136. package/dist/headingRanges.d.ts +48 -0
  137. package/dist/headingRanges.d.ts.map +1 -0
  138. package/dist/headingRanges.js +132 -0
  139. package/dist/headingRanges.js.map +1 -0
  140. package/dist/index.d.ts +41 -0
  141. package/dist/index.d.ts.map +1 -0
  142. package/dist/index.js +41 -0
  143. package/dist/index.js.map +1 -0
  144. package/dist/kinematics.d.ts +63 -0
  145. package/dist/kinematics.d.ts.map +1 -0
  146. package/dist/kinematics.js +71 -0
  147. package/dist/kinematics.js.map +1 -0
  148. package/dist/ledger.d.ts +49 -0
  149. package/dist/ledger.d.ts.map +1 -0
  150. package/dist/ledger.js +136 -0
  151. package/dist/ledger.js.map +1 -0
  152. package/dist/load.d.ts +12 -0
  153. package/dist/load.d.ts.map +1 -0
  154. package/dist/load.js +12 -0
  155. package/dist/load.js.map +1 -0
  156. package/dist/mirror.d.ts +81 -0
  157. package/dist/mirror.d.ts.map +1 -0
  158. package/dist/mirror.js +282 -0
  159. package/dist/mirror.js.map +1 -0
  160. package/dist/plan.d.ts +29 -0
  161. package/dist/plan.d.ts.map +1 -0
  162. package/dist/plan.js +159 -0
  163. package/dist/plan.js.map +1 -0
  164. package/dist/prBody.d.ts +24 -0
  165. package/dist/prBody.d.ts.map +1 -0
  166. package/dist/prBody.js +112 -0
  167. package/dist/prBody.js.map +1 -0
  168. package/dist/provenance.d.ts +21 -0
  169. package/dist/provenance.d.ts.map +1 -0
  170. package/dist/provenance.js +46 -0
  171. package/dist/provenance.js.map +1 -0
  172. package/dist/render.d.ts +18 -0
  173. package/dist/render.d.ts.map +1 -0
  174. package/dist/render.js +464 -0
  175. package/dist/render.js.map +1 -0
  176. package/dist/resolve.d.ts +39 -0
  177. package/dist/resolve.d.ts.map +1 -0
  178. package/dist/resolve.js +172 -0
  179. package/dist/resolve.js.map +1 -0
  180. package/dist/season.d.ts +65 -0
  181. package/dist/season.d.ts.map +1 -0
  182. package/dist/season.js +16 -0
  183. package/dist/season.js.map +1 -0
  184. package/dist/sim/commands.d.ts +97 -0
  185. package/dist/sim/commands.d.ts.map +1 -0
  186. package/dist/sim/commands.js +185 -0
  187. package/dist/sim/commands.js.map +1 -0
  188. package/dist/sim/curves.d.ts +37 -0
  189. package/dist/sim/curves.d.ts.map +1 -0
  190. package/dist/sim/curves.js +187 -0
  191. package/dist/sim/curves.js.map +1 -0
  192. package/dist/sim/follower.d.ts +124 -0
  193. package/dist/sim/follower.d.ts.map +1 -0
  194. package/dist/sim/follower.js +472 -0
  195. package/dist/sim/follower.js.map +1 -0
  196. package/dist/sim/ideal.d.ts +103 -0
  197. package/dist/sim/ideal.d.ts.map +1 -0
  198. package/dist/sim/ideal.js +393 -0
  199. package/dist/sim/ideal.js.map +1 -0
  200. package/dist/sim/index.d.ts +11 -0
  201. package/dist/sim/index.d.ts.map +1 -0
  202. package/dist/sim/index.js +10 -0
  203. package/dist/sim/index.js.map +1 -0
  204. package/dist/sim/params.d.ts +91 -0
  205. package/dist/sim/params.d.ts.map +1 -0
  206. package/dist/sim/params.js +195 -0
  207. package/dist/sim/params.js.map +1 -0
  208. package/dist/sim/pedroPath.d.ts +41 -0
  209. package/dist/sim/pedroPath.d.ts.map +1 -0
  210. package/dist/sim/pedroPath.js +191 -0
  211. package/dist/sim/pedroPath.js.map +1 -0
  212. package/dist/sim/plant.d.ts +59 -0
  213. package/dist/sim/plant.d.ts.map +1 -0
  214. package/dist/sim/plant.js +128 -0
  215. package/dist/sim/plant.js.map +1 -0
  216. package/dist/sim/residuals.d.ts +36 -0
  217. package/dist/sim/residuals.d.ts.map +1 -0
  218. package/dist/sim/residuals.js +86 -0
  219. package/dist/sim/residuals.js.map +1 -0
  220. package/dist/sim/simulate.d.ts +27 -0
  221. package/dist/sim/simulate.d.ts.map +1 -0
  222. package/dist/sim/simulate.js +924 -0
  223. package/dist/sim/simulate.js.map +1 -0
  224. package/dist/sim/types.d.ts +209 -0
  225. package/dist/sim/types.d.ts.map +1 -0
  226. package/dist/sim/types.js +2 -0
  227. package/dist/sim/types.js.map +1 -0
  228. package/dist/tokens.d.ts +93 -0
  229. package/dist/tokens.d.ts.map +1 -0
  230. package/dist/tokens.js +93 -0
  231. package/dist/tokens.js.map +1 -0
  232. package/dist/trace.d.ts +89 -0
  233. package/dist/trace.d.ts.map +1 -0
  234. package/dist/trace.js +187 -0
  235. package/dist/trace.js.map +1 -0
  236. package/dist/types.d.ts +219 -0
  237. package/dist/types.d.ts.map +1 -0
  238. package/dist/types.js +2 -0
  239. package/dist/types.js.map +1 -0
  240. package/dist/unimplemented.d.ts +8 -0
  241. package/dist/unimplemented.d.ts.map +1 -0
  242. package/dist/unimplemented.js +11 -0
  243. package/dist/unimplemented.js.map +1 -0
  244. package/package.json +59 -0
@@ -0,0 +1,472 @@
1
+ import { normalizeAngle, normalizeSigned, theta, turnDirection } from "./pedroPath.js";
2
+ const ZERO = { forward: 0, strafe: 0, turn: 0 };
3
+ /** `DiamondDrivetrainModel.interpolateVelocity`. */
4
+ export const diamondVelocity = (xRadius, yRadius, thetaRad) => 1 / (Math.abs(Math.cos(thetaRad)) / xRadius + Math.abs(Math.sin(thetaRad)) / yRadius);
5
+ /** `Utils.solveQuadratic`: the two roots of a x^2 + b x + c, in the numerically stable form. */
6
+ export function solveQuadratic(a, b, c) {
7
+ const sqrtD = Math.sqrt(b * b - 4 * a * c);
8
+ const signed = b < 0 || Object.is(b, -0) ? -sqrtD : sqrtD;
9
+ const q = -0.5 * (b + signed);
10
+ return [q / a, c / q];
11
+ }
12
+ /** `Control.clampBrakingPower`: cap power that opposes the motion at `maxBrakingPower`. */
13
+ export function clampBrakingPower(power, directionOfMotion, max) {
14
+ if (directionOfMotion * power >= 0)
15
+ return power;
16
+ return Math.sign(power) * Math.min(Math.abs(power), max);
17
+ }
18
+ /** `Control.cosineScale`. */
19
+ const cosineScale = (error, falloff) => Math.cos(Math.min(Math.abs(error) * (Math.PI / 2 / falloff), Math.PI / 2));
20
+ /** `Mecanum.computeWheelPowersUnnormalized`, in [FL, FR, BL, BR] order. */
21
+ export function wheelPowers(p, out = [0, 0, 0, 0]) {
22
+ out[0] = p.forward - p.strafe - p.turn;
23
+ out[1] = p.forward + p.strafe + p.turn;
24
+ out[2] = p.forward + p.strafe - p.turn;
25
+ out[3] = p.forward - p.strafe + p.turn;
26
+ return out;
27
+ }
28
+ const scratchA = [0, 0, 0, 0];
29
+ const scratchB = [0, 0, 0, 0];
30
+ /** `Mecanum.maxScaling`: the largest share of `delta` that keeps every wheel inside [-1, 1]. */
31
+ export function mecanumMaxScaling(current, delta) {
32
+ let lambda = 1;
33
+ const a = wheelPowers(current, scratchA);
34
+ const b = wheelPowers(delta, scratchB);
35
+ for (let i = 0; i < 4; i += 1) {
36
+ const ai = a[i];
37
+ const bi = b[i];
38
+ if (Math.abs(bi) < 1e-9)
39
+ continue;
40
+ const t1 = (1 - ai) / bi;
41
+ const t2 = (-1 - ai) / bi;
42
+ if (t1 >= 0 && t1 < lambda)
43
+ lambda = t1;
44
+ if (t2 >= 0 && t2 < lambda)
45
+ lambda = t2;
46
+ }
47
+ return lambda < 0 ? 0 : lambda > 1 ? 1 : lambda;
48
+ }
49
+ export const initialFollowerState = () => ({
50
+ mode: "IDLE",
51
+ path: null,
52
+ segmentIndex: 0,
53
+ maxVelocityInPerS: Infinity,
54
+ holdPose: null,
55
+ closestT: 0,
56
+ projectedClosestT: 0,
57
+ curveCompletion: 0,
58
+ remainingDistance: 0,
59
+ tangentialSpeed: 0,
60
+ closestTangentX: 0,
61
+ closestTangentY: 0,
62
+ translationalError: 0,
63
+ headingError: 0,
64
+ busy: false,
65
+ holdTimerStartS: null,
66
+ });
67
+ export const copyFollowerState = (state) => ({
68
+ ...state,
69
+ holdPose: state.holdPose === null ? null : { ...state.holdPose },
70
+ });
71
+ export class PedroFollower {
72
+ params;
73
+ forwardVel;
74
+ strafeVel;
75
+ /** `Follower.holdEnd`: hold the end pose when a path finishes, rather than stop. */
76
+ holdEnd;
77
+ state;
78
+ constructor(params, forwardVel, strafeVel, holdEnd) {
79
+ this.params = params;
80
+ this.forwardVel = forwardVel;
81
+ this.strafeVel = strafeVel;
82
+ this.holdEnd = holdEnd;
83
+ this.state = initialFollowerState();
84
+ }
85
+ follow(path, speedFraction) {
86
+ this.clear();
87
+ const s = this.state;
88
+ s.mode = "FOLLOW";
89
+ s.path = path;
90
+ s.segmentIndex = 0;
91
+ // `FORESIGHT_CONFIG.setPathSpeed(f)`: the velocity cap is a fraction of the forward maximum.
92
+ s.maxVelocityInPerS = this.forwardVel * speedFraction;
93
+ this.reset();
94
+ }
95
+ hold(pose) {
96
+ this.clear();
97
+ this.state.mode = "HOLD";
98
+ this.state.holdPose = { ...pose };
99
+ }
100
+ stop() {
101
+ this.clear();
102
+ this.state.mode = "IDLE";
103
+ }
104
+ clear() {
105
+ const s = this.state;
106
+ s.path = null;
107
+ s.holdPose = null;
108
+ s.maxVelocityInPerS = Infinity;
109
+ }
110
+ /** `ForesightV3.reset`. */
111
+ reset() {
112
+ const s = this.state;
113
+ s.holdTimerStartS = null;
114
+ s.busy = true;
115
+ s.closestT = 0;
116
+ s.projectedClosestT = 0;
117
+ }
118
+ get following() {
119
+ return this.state.mode === "FOLLOW";
120
+ }
121
+ /** `PathTracker.remainingPaths`. */
122
+ remaining() {
123
+ const s = this.state;
124
+ return s.path === null ? 0 : s.path.segments.length - s.segmentIndex;
125
+ }
126
+ /**
127
+ * `Follower.update(deltaTime)`: the powers to write this tick, or null when Pedro writes none and
128
+ * the motors keep what they were last given (the tick a finished path hands over to the hold).
129
+ */
130
+ update(motion, nowS) {
131
+ const s = this.state;
132
+ switch (s.mode) {
133
+ case "FOLLOW": {
134
+ if (s.path === null || s.segmentIndex >= s.path.segments.length) {
135
+ const end = s.path?.endPose ?? { x: motion.x, y: motion.y, heading: motion.heading };
136
+ if (this.holdEnd)
137
+ this.hold(end);
138
+ else
139
+ this.stop();
140
+ return null;
141
+ }
142
+ return this.calculatePath(motion);
143
+ }
144
+ case "HOLD":
145
+ return this.calculateHold(motion, nowS);
146
+ case "IDLE":
147
+ return ZERO;
148
+ }
149
+ }
150
+ /** How far along the current path the follower says it is, as `PathMarkers.Runner` reads it. */
151
+ distanceAlongIn() {
152
+ const s = this.state;
153
+ const path = s.path;
154
+ if (path === null)
155
+ return 0;
156
+ const lengths = path.runtimeLengthsIn;
157
+ if (s.segmentIndex >= lengths.length)
158
+ return path.runtimeTotalIn;
159
+ let before = 0;
160
+ for (let i = 0; i < s.segmentIndex; i += 1)
161
+ before += lengths[i];
162
+ let completion = s.curveCompletion;
163
+ if (Number.isNaN(completion))
164
+ completion = 0;
165
+ completion = Math.max(0, Math.min(1, completion));
166
+ return before + completion * lengths[s.segmentIndex];
167
+ }
168
+ /** Pedro's hold end constraints, which `settledS` reports. */
169
+ endConstraintsMet() {
170
+ const s = this.state;
171
+ const p = this.params;
172
+ return (s.mode === "HOLD" &&
173
+ s.tangentialSpeed < p.endVelocityToleranceInPerS &&
174
+ Math.abs(s.translationalError) < p.endTranslationalToleranceIn &&
175
+ Math.abs(s.headingError) < p.endHeadingToleranceRad);
176
+ }
177
+ /** `ForesightV3.getBrakeDisplacement`: where braking now would leave the robot, relative to it. */
178
+ brakeDisplacement(motion) {
179
+ const p = this.params;
180
+ const vx = motion.twistX;
181
+ const vy = motion.twistY;
182
+ const w = motion.omega;
183
+ const bodyX = p.brakeQuadraticForwardS2PerIn * vx * Math.abs(vx) + p.brakeLinearForwardS * vx;
184
+ const bodyY = p.brakeQuadraticStrafeS2PerIn * vy * Math.abs(vy) + p.brakeLinearStrafeS * vy;
185
+ const headingDisp = w * Math.abs(w) * p.headingBrakeQuadraticS2PerRad + w * p.headingBrakeLinearS;
186
+ const h = motion.heading;
187
+ let dx;
188
+ let dy;
189
+ if (Math.abs(headingDisp) < 1e-9) {
190
+ // `Pose.exp(Twist)` with no rotation: the body displacement turned into the field frame.
191
+ dx = bodyX * Math.cos(h) - bodyY * Math.sin(h);
192
+ dy = bodyX * Math.sin(h) + bodyY * Math.cos(h);
193
+ }
194
+ else {
195
+ const sin = Math.sin(headingDisp);
196
+ const cos = Math.cos(headingDisp);
197
+ const localX = (sin * bodyX - (1 - cos) * bodyY) / headingDisp;
198
+ const localY = ((1 - cos) * bodyX + sin * bodyY) / headingDisp;
199
+ dx = localX * Math.cos(h) - localY * Math.sin(h);
200
+ dy = localX * Math.sin(h) + localY * Math.cos(h);
201
+ }
202
+ return { x: dx, y: dy, heading: normalizeAngle(headingDisp) };
203
+ }
204
+ /** `ForesightV3.getVelocityToBrakeInTime`. */
205
+ velocityToBrakeInTime(distance, tangent, heading) {
206
+ const p = this.params;
207
+ const cos = Math.cos(-heading);
208
+ const sin = Math.sin(-heading);
209
+ const tx = Math.abs(tangent.x * cos - tangent.y * sin);
210
+ const ty = Math.abs(tangent.x * sin + tangent.y * cos);
211
+ const k1 = p.brakeQuadraticForwardS2PerIn * tx * tx * tx + p.brakeQuadraticStrafeS2PerIn * ty * ty * ty;
212
+ const k2 = p.brakeLinearForwardS * tx * tx + p.brakeLinearStrafeS * ty * ty;
213
+ const [r1, r2] = solveQuadratic(k1, k2, -Math.abs(distance) / p.brakeAggression);
214
+ const result = Math.max(r1, r2) * Math.sign(distance);
215
+ // Pedro produces NaN here only when both the distance and the linear term are exactly zero.
216
+ return Number.isNaN(result) ? 0 : result;
217
+ }
218
+ /** `ForesightV3.translationalCorrection`: [error, field-frame power vector]. */
219
+ translationalCorrection(px, py, heading, targetX, targetY, normal) {
220
+ const p = this.params;
221
+ const ex = targetX - px;
222
+ const ey = targetY - py;
223
+ const nn = normal.x * normal.x + normal.y * normal.y;
224
+ if (!(nn > 0))
225
+ return [0, 0, 0];
226
+ const scale = (ex * normal.x + ey * normal.y) / nn;
227
+ const dispX = normal.x * scale;
228
+ const dispY = normal.y * scale;
229
+ const error = Math.hypot(dispX, dispY);
230
+ if (error < p.minCorrectionDistanceIn)
231
+ return [0, 0, 0];
232
+ const cos = Math.cos(-heading);
233
+ const sin = Math.sin(-heading);
234
+ const bx = dispX * cos - dispY * sin;
235
+ const by = dispX * sin + dispY * cos;
236
+ const gx = p.forwardTranslationalPowerPerIn * bx;
237
+ const gy = p.strafeTranslationalPowerPerIn * by;
238
+ const bb = bx * bx + by * by;
239
+ const k = bb === 0 ? 0 : (gx * bx + gy * by) / bb;
240
+ const cx = bx * k;
241
+ const cy = by * k;
242
+ const c2 = Math.cos(heading);
243
+ const s2 = Math.sin(heading);
244
+ return [error, cx * c2 - cy * s2, cx * s2 + cy * c2];
245
+ }
246
+ /** `ForesightPowerAllocator.getDrivePowers`. */
247
+ drivePowers(fx, fy, turn, motion) {
248
+ const h = -motion.heading;
249
+ const cos = Math.cos(h);
250
+ const sin = Math.sin(h);
251
+ const rx = fx * cos - fy * sin;
252
+ const ry = fx * sin + fy * cos;
253
+ const max = this.params.maxBrakingPower;
254
+ return {
255
+ forward: clampBrakingPower(rx, motion.twistX, max),
256
+ strafe: clampBrakingPower(ry, motion.twistY, max),
257
+ turn,
258
+ };
259
+ }
260
+ /** `ForesightPowerAllocator.allocatePowers` and `clampPowers`. */
261
+ allocate(motion, headingFeedforward, tx, ty, dx, dy, headingPower, translationalError, headingError) {
262
+ const p = this.params;
263
+ const translationalPriority = Math.abs(translationalError) > p.translationalDeviationToleranceIn;
264
+ const headingPriority = Math.abs(headingError) > p.headingDeviationToleranceRad;
265
+ const ff = headingFeedforward + headingPower * p.headingDriveRatio;
266
+ const fb = headingPower * (1 - p.headingDriveRatio);
267
+ // The normal feedforward vector V3 passes is zero, so it is left out of every order below.
268
+ const translational = { angular: false, x: tx, y: ty };
269
+ const drive = { angular: false, x: dx, y: dy };
270
+ const feedforward = { angular: true, value: ff };
271
+ const feedback = { angular: true, value: fb };
272
+ const order = translationalPriority && headingPriority
273
+ ? [feedforward, translational, feedback, drive]
274
+ : headingPriority
275
+ ? [feedforward, feedback, translational, drive]
276
+ : [feedforward, translational, drive, feedback];
277
+ let pathX = 0;
278
+ let pathY = 0;
279
+ let turn = 0;
280
+ for (const item of order) {
281
+ const current = this.drivePowers(pathX, pathY, turn, motion);
282
+ if (item.angular) {
283
+ const delta = this.drivePowers(0, 0, item.value, motion);
284
+ turn += mecanumMaxScaling(current, delta) * item.value;
285
+ }
286
+ else {
287
+ const delta = this.drivePowers(item.x, item.y, 0, motion);
288
+ const scaling = mecanumMaxScaling(current, delta);
289
+ pathX += item.x * scaling;
290
+ pathY += item.y * scaling;
291
+ }
292
+ }
293
+ return this.drivePowers(pathX, pathY, turn, motion);
294
+ }
295
+ /** `ForesightV3.calculatePath`, with Pedro's recursion on advancing a segment as a loop. */
296
+ calculatePath(motion) {
297
+ const s = this.state;
298
+ const p = this.params;
299
+ const path = s.path;
300
+ for (let guard = 0; guard <= path.segments.length; guard += 1) {
301
+ const segment = path.segments[s.segmentIndex];
302
+ if (segment === undefined)
303
+ return ZERO;
304
+ const curve = segment.curve;
305
+ s.closestT = curve.closestT(motion.x, motion.y, s.closestT);
306
+ if (s.closestT >= 1 - p.endParametricT) {
307
+ // The end constraint: this segment is done. Advance, and either carry on with the next one
308
+ // this same tick or, at the last, drive nothing and let the next update hand over to hold.
309
+ s.closestT = 1;
310
+ s.segmentIndex += 1;
311
+ this.reset();
312
+ if (s.segmentIndex < path.segments.length)
313
+ continue;
314
+ return ZERO;
315
+ }
316
+ const targetHeading = segment.heading(s.closestT);
317
+ const closest = curve.get(s.closestT);
318
+ s.remainingDistance = curve.remainingDistance(s.closestT);
319
+ s.curveCompletion = curve.lengthIn === 0 ? 1 : 1 - s.remainingDistance / curve.lengthIn;
320
+ const tangent = curve.tangent(s.closestT);
321
+ s.closestTangentX = tangent.x;
322
+ s.closestTangentY = tangent.y;
323
+ s.tangentialSpeed = motion.vx * tangent.x + motion.vy * tangent.y;
324
+ s.translationalError = Math.hypot(motion.x - closest.x, motion.y - closest.y);
325
+ s.headingError = normalizeSigned(targetHeading - motion.heading);
326
+ const disp = this.brakeDisplacement(motion);
327
+ const projX = motion.x + disp.x;
328
+ const projY = motion.y + disp.y;
329
+ const projHeading = normalizeAngle(motion.heading + disp.heading);
330
+ s.projectedClosestT = curve.closestT(projX, projY, s.projectedClosestT);
331
+ const projectedTargetHeading = segment.heading(s.projectedClosestT);
332
+ const projTangent = curve.tangent(s.projectedClosestT);
333
+ const projTarget = curve.get(s.projectedClosestT);
334
+ const projNormal = { x: -projTangent.y, y: projTangent.x };
335
+ let projectedRemaining = curve.remainingDistance(s.projectedClosestT);
336
+ if (projectedRemaining <= 0.01) {
337
+ projectedRemaining =
338
+ projTangent.x * (projTarget.x - projX) + projTangent.y * (projTarget.y - projY);
339
+ }
340
+ const angleToTangent = theta(projTangent) - projHeading;
341
+ const brakeVelocity = this.velocityToBrakeInTime(projectedRemaining, projTangent, projHeading);
342
+ const isBraking = brakeVelocity <= 0 || projectedRemaining <= 0;
343
+ // `brakeAtEnd` is true in biobuzz and by default, so only a segment before the last hands
344
+ // over early: once the projected stop passes its end, the next segment takes the robot.
345
+ if (isBraking && this.remaining() > 1) {
346
+ s.segmentIndex += 1;
347
+ continue;
348
+ }
349
+ const headingError = normalizeSigned(projectedTargetHeading - projHeading);
350
+ const currentHeadingError = normalizeSigned(targetHeading - motion.heading);
351
+ const total = p.headingPowerPerRad * headingError;
352
+ let feedback = p.headingPowerPerRad * currentHeadingError;
353
+ let feedforward;
354
+ if (Math.abs(total) <= 1e-3) {
355
+ feedback = 0;
356
+ feedforward = 0;
357
+ }
358
+ else if (total * feedback < 0) {
359
+ feedforward = total;
360
+ feedback = 0;
361
+ }
362
+ else if (Math.abs(feedback) >= Math.abs(total)) {
363
+ feedforward = 0;
364
+ feedback = total;
365
+ }
366
+ else {
367
+ feedforward = total - feedback;
368
+ }
369
+ feedforward += p.headingStaticPower * Math.sign(turnDirection(headingError));
370
+ const drivePower = this.drivePower(isBraking, brakeVelocity, angleToTangent);
371
+ let driveX = projTangent.x * drivePower;
372
+ let driveY = projTangent.y * drivePower;
373
+ const [translationalError, tx, ty] = this.translationalCorrection(projX, projY, projHeading, projTarget.x, projTarget.y, projNormal);
374
+ if (s.projectedClosestT <= p.endParametricT) {
375
+ const start = curve.start;
376
+ const toStartX = start.x - projX;
377
+ const toStartY = start.y - projY;
378
+ const alongToStart = toStartX * s.closestTangentX + toStartY * s.closestTangentY;
379
+ const beforePath = alongToStart > 1 && translationalError > p.translationalDeviationToleranceIn;
380
+ const headingBeforePath = Math.abs(headingError) > p.headingDeviationToleranceRad;
381
+ if (beforePath && p.cosineScale) {
382
+ driveX *= alongToStart / translationalError;
383
+ driveY *= alongToStart / translationalError;
384
+ }
385
+ if (headingBeforePath && p.cosineScale) {
386
+ if (p.turnBeforeDriving) {
387
+ driveX = 0;
388
+ driveY = 0;
389
+ }
390
+ const scalar = this.driveScalar(0, headingError);
391
+ driveX *= scalar;
392
+ driveY *= scalar;
393
+ }
394
+ }
395
+ else if ((Math.abs(headingError) > 2 * p.headingDeviationToleranceRad ||
396
+ Math.abs(translationalError) > 2 * p.translationalDeviationToleranceIn) &&
397
+ p.cosineScale) {
398
+ const scalar = this.driveScalar(translationalError, headingError);
399
+ driveX *= scalar;
400
+ driveY *= scalar;
401
+ }
402
+ return this.allocate(motion, feedforward, tx, ty, driveX, driveY, feedback, translationalError, headingError);
403
+ }
404
+ return ZERO;
405
+ }
406
+ /** `ForesightPowerAllocator.getDriveScalar`. */
407
+ driveScalar(normalError, headingError) {
408
+ const p = this.params;
409
+ return (cosineScale(normalError, p.translationalDeviationToleranceIn) *
410
+ cosineScale(headingError, p.headingDeviationToleranceRad));
411
+ }
412
+ /** `ForesightV3.drive` and `coast`, with no acceleration or deceleration constraint set. */
413
+ drivePower(isBraking, profiledVelocity, angleToTangent) {
414
+ const p = this.params;
415
+ const maxAchievable = diamondVelocity(this.forwardVel, this.strafeVel, angleToTangent);
416
+ const target = Math.min(profiledVelocity, maxAchievable);
417
+ if (isBraking)
418
+ return p.brakeFeedforwardPowerPerInPerS * target;
419
+ let coastTarget = maxAchievable;
420
+ if (Number.isFinite(this.state.maxVelocityInPerS)) {
421
+ coastTarget = Math.min(coastTarget, this.state.maxVelocityInPerS);
422
+ }
423
+ if (coastTarget >= maxAchievable)
424
+ return 1;
425
+ const error = Math.max(0, coastTarget);
426
+ return Math.max(p.coastPowerPerInPerS * error + p.coastFeedforwardPowerPerInPerS * coastTarget, 0);
427
+ }
428
+ /** `ForesightV3.calculateHold`, without the optional hold scaling (`hold(pose)` passes false). */
429
+ calculateHold(motion, nowS) {
430
+ const s = this.state;
431
+ const p = this.params;
432
+ const target = s.holdPose;
433
+ if (s.holdTimerStartS === null)
434
+ s.holdTimerStartS = nowS;
435
+ const disp = this.brakeDisplacement(motion);
436
+ const projX = motion.x + disp.x;
437
+ const projY = motion.y + disp.y;
438
+ const projHeading = normalizeAngle(motion.heading + disp.heading);
439
+ const projError = normalizeSigned(target.heading - projHeading);
440
+ const headingCorrection = p.headingPowerPerRad * projError + p.headingStaticPower * Math.sign(turnDirection(projError));
441
+ s.headingError = normalizeSigned(target.heading - motion.heading);
442
+ const dispX = target.x - projX;
443
+ const dispY = target.y - projY;
444
+ const dist = Math.hypot(dispX, dispY);
445
+ s.translationalError = Math.hypot(target.x - motion.x, target.y - motion.y);
446
+ if (dist < 1e-9) {
447
+ s.tangentialSpeed = 0;
448
+ s.closestTangentX = 0;
449
+ s.closestTangentY = 0;
450
+ }
451
+ else {
452
+ s.closestTangentX = dispX / dist;
453
+ s.closestTangentY = dispY / dist;
454
+ s.tangentialSpeed = s.closestTangentX * motion.vx + s.closestTangentY * motion.vy;
455
+ }
456
+ const timedOut = nowS - s.holdTimerStartS > p.holdTimeoutS;
457
+ if ((s.busy && timedOut) || this.endConstraintsMet())
458
+ s.busy = false;
459
+ // Pedro divides by the distance here and so produces NaN when the projected pose sits exactly on
460
+ // the target; `CachedMotor` then ignores the NaN. No correction is the same outcome.
461
+ let tx = 0;
462
+ let ty = 0;
463
+ if (dist >= 1e-9) {
464
+ [, tx, ty] = this.translationalCorrection(projX, projY, projHeading, target.x, target.y, {
465
+ x: dispX / dist,
466
+ y: dispY / dist,
467
+ });
468
+ }
469
+ return this.drivePowers(tx, ty, headingCorrection, motion);
470
+ }
471
+ }
472
+ //# sourceMappingURL=follower.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"follower.js","sourceRoot":"","sources":["../../src/sim/follower.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ import { type Pose } from "../geometry/vec.js";
2
+ import type { Estimate, Plan, PlanStep } from "../types.js";
3
+ /**
4
+ * The ideal playback level (site/docs/simulation.md, "Playback levels"): the robot follows the
5
+ * planned geometry exactly, with no wobble and no overshoot, and its heading is the heading
6
+ * interpolation exactly, the way the public Pedro visualizer draws a path. The clock is the one the
7
+ * timeline already uses, the kinematic estimate (`estimate.ts`), so a path step drives along its
8
+ * samples at `timeAtSampleS` and then holds its end pose for the settle time the estimate adds.
9
+ *
10
+ * The one thing the estimate does not time is a gap: a step that starts somewhere other than where
11
+ * the robot is, or facing another way (a literal `from`, or a heading mode whose first heading is
12
+ * not the last one). The robot has to get there, so the ideal robot does, visibly: a transition that
13
+ * turns and drives in a straight line from the pose it has to the pose the next path starts at,
14
+ * timed with the same kinematic model (the same caps, acceleration and deceleration as a path
15
+ * step, from rest to rest). A transition therefore makes the ideal run longer than the estimate by
16
+ * exactly its own duration.
17
+ *
18
+ * A wait or a command holds the pose for its estimated seconds, as the time model does. A parallel
19
+ * group follows the member that drives (its deadline when that drives, else the last member with a
20
+ * path, the same member the estimate carries the velocity through) for as long as the group lasts;
21
+ * a branch drives its `then` side, the side the instant sim takes when it cannot read the
22
+ * condition, and lasts as long as the estimate says (the longer side).
23
+ *
24
+ * Pure and deterministic, like the rest of core: the same plan and estimate give the same poses.
25
+ */
26
+ /** Position gaps below this are the same place, in inches: canonical form rounds to 1e-4. */
27
+ export declare const IDEAL_POSITION_TOLERANCE_IN = 0.01;
28
+ /** Heading gaps below this are the same heading, in radians. */
29
+ export declare const IDEAL_HEADING_TOLERANCE_RAD = 0.001;
30
+ /** The robot holds still: at a wait, a command, a path's settle, or the end of a group. */
31
+ export interface IdealHold {
32
+ kind: "hold";
33
+ /** The step whose time this is, or null for a hold that belongs to no step. */
34
+ stepId: string | null;
35
+ startS: number;
36
+ endS: number;
37
+ pose: Pose;
38
+ }
39
+ /** The robot drives a path step along its planned geometry. */
40
+ export interface IdealPathMotion {
41
+ kind: "path";
42
+ stepId: string;
43
+ startS: number;
44
+ endS: number;
45
+ step: PlanStep;
46
+ /** The routine clock at each of the step's plan samples. */
47
+ timesS: readonly number[];
48
+ /** h(t) for the step's heading mode, evaluated exactly rather than between samples. */
49
+ headingAt: (t: number) => number;
50
+ }
51
+ /** The robot turns and drives from where it is to where the next path starts. */
52
+ export interface IdealTransition {
53
+ kind: "transition";
54
+ /** The step this transition leads into. */
55
+ stepId: string;
56
+ startS: number;
57
+ endS: number;
58
+ fromPose: Pose;
59
+ toPose: Pose;
60
+ /** How far it drives, in inches, and how far it turns (signed, the short way), in radians. */
61
+ translateIn: number;
62
+ turnRad: number;
63
+ /** Distance along the straight line and the clock there, from the profile. */
64
+ sIns: readonly number[];
65
+ timesS: readonly number[];
66
+ }
67
+ export type IdealSegment = IdealHold | IdealPathMotion | IdealTransition;
68
+ /** When a step starts and ends on the ideal clock. */
69
+ export interface IdealSpan {
70
+ stepId: string;
71
+ startS: number;
72
+ endS: number;
73
+ /** Seconds of transition inside the span: before the step, or inside a group's members. */
74
+ transitionS: number;
75
+ }
76
+ export interface IdealTrajectory {
77
+ startPose: Pose;
78
+ /** Contiguous, in time order, from 0 to `totalS`. */
79
+ segments: IdealSegment[];
80
+ /** Every step, groups and their members included, in document order. */
81
+ spans: IdealSpan[];
82
+ transitions: IdealTransition[];
83
+ totalS: number;
84
+ }
85
+ /** True when the robot has to move or turn to get from one pose to the other. */
86
+ export declare function posesDiffer(a: Pose, b: Pose): boolean;
87
+ /**
88
+ * Lays the plan on the ideal clock. Throws nothing: a step without an estimate takes no time, the
89
+ * way it counts as zero in the estimate's total.
90
+ */
91
+ export declare function idealTrajectory(plan: Plan, estimate: Estimate): IdealTrajectory;
92
+ /**
93
+ * The ideal robot's pose at a routine time: on the planned path exactly while a path runs, on the
94
+ * straight line of a transition while it closes a gap, and still otherwise. Before 0 it is at the
95
+ * start pose, and after the end at the last pose.
96
+ */
97
+ export declare function idealPoseAt(trajectory: IdealTrajectory, atS: number): Pose;
98
+ /**
99
+ * The ideal clock when the robot reaches arc-length fraction `t` of a path step, or null when the
100
+ * step is not driven on the ideal run (a member that is timed but not drawn).
101
+ */
102
+ export declare function idealTimeAt(trajectory: IdealTrajectory, stepId: string, t: number): number | null;
103
+ //# sourceMappingURL=ideal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ideal.d.ts","sourceRoot":"","sources":["../../src/sim/ideal.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAIzD,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,6FAA6F;AAC7F,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAEhD,gEAAgE;AAChE,eAAO,MAAM,2BAA2B,QAAO,CAAC;AAKhD,2FAA2F;AAC3F,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,4DAA4D;IAC5D,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,uFAAuF;IACvF,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAClC;AAED,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,IAAI,CAAC;IACf,MAAM,EAAE,IAAI,CAAC;IACb,8FAA8F;IAC9F,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,eAAe,GAAG,eAAe,CAAC;AAEzE,sDAAsD;AACtD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,2FAA2F;IAC3F,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,IAAI,CAAC;IAChB,qDAAqD;IACrD,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,wEAAwE;IACxE,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAOD,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,OAAO,CAKrD;AAoCD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,GAAG,eAAe,CAgM/E;AAwED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAc1E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBjG"}