Skip to content

Commit 7b137ae

Browse files
Integrate back into after time and disp
1 parent 855afe9 commit 7b137ae

2 files changed

Lines changed: 26 additions & 44 deletions

File tree

road-runner/actions/src/main/kotlin/com/acmerobotics/roadrunner/Actions.kt

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -353,29 +353,41 @@ class TrajectoryActionBuilder private constructor(
353353
}
354354

355355
/**
356-
* Schedules action [a] to execute in parallel starting at a displacement [ds] after the previous trajectory segment.
357-
* The action start is clamped to the span of the current trajectory.
356+
* Schedules action [a] to execute in parallel starting at a displacement [ds] relative to the start of the next trajectory segment, turn, or other action.
357+
*
358+
* If [ds] is positive, the action will execute [ds] units after the start of the next trajectory segment.
359+
* If [ds] is negative, the action will execute [ds] units before the end of the previous trajectory segment.
360+
* Note that the start of the next trajectory segment is the same as the end of the previous trajectory segment.
361+
*
362+
* The action start is clamped to the span of the current trajectory (not the trajectory segment),
363+
* but the current trajectory will wait for the action to complete.
358364
*
359365
* Cannot be called without an applicable pending trajectory.
360366
*/
361367
// TODO: Should calling this without an applicable trajectory implicitly begin an empty trajectory and execute the
362368
// action immediately?
363369
fun afterDisp(ds: Double, a: Action): TrajectoryActionBuilder {
364-
require(ds >= 0.0) { "Displacement ($ds) must be non-negative" }
370+
val relativeToStart = ds >= 0.0
365371

366372
return TrajectoryActionBuilder(
367373
this, tb, n, lastPoseUnmapped, lastPose, lastTangent,
368-
ms + listOf(DispMarkerFactory(n, ds, a)), cont
374+
ms + listOf(DispMarkerFactory(if (relativeToStart) n else n - 1, ds, a, relativeToStart)), cont,
369375
)
370376
}
371377
fun afterDisp(ds: Double, f: InstantFunction) = afterDisp(ds, InstantAction(f))
372378

373379
/**
374-
* Schedules action [a] to execute in parallel starting [dt] seconds after the previous trajectory segment, turn, or
375-
* other action.
380+
* Schedules action [a] to execute in parallel starting [dt] seconds relative to the start of the next trajectory segment, turn, or other action.
381+
*
382+
* If [dt] is positive, the action will execute [dt] seconds after the start of the next trajectory segment.
383+
* If [dt] is negative, the action will execute [dt] seconds before the end of the previous trajectory segment.
384+
* Note that the start of the next trajectory segment is the same as the end of the previous trajectory segment.
385+
*
386+
* The action start is clamped to the span of the current trajectory (not the trajectory segment),
387+
* but the current trajectory will wait for the action to complete.
376388
*/
377389
fun afterTime(dt: Double, a: Action): TrajectoryActionBuilder {
378-
require(dt >= 0.0) { "Time ($dt) must be non-negative" }
390+
val relativeToStart = dt >= 0.0
379391

380392
return if (n == 0) {
381393
TrajectoryActionBuilder(this, tb, 0, lastPoseUnmapped, lastPose, lastTangent, emptyList()) { tail ->
@@ -384,42 +396,12 @@ class TrajectoryActionBuilder private constructor(
384396
} else {
385397
TrajectoryActionBuilder(
386398
this, tb, n, lastPoseUnmapped, lastPose, lastTangent,
387-
ms + listOf(TimeMarkerFactory(n, dt, a)), cont
399+
ms + listOf(TimeMarkerFactory(if (relativeToStart) n else n - 1, dt, a, relativeToStart)), cont,
388400
)
389401
}
390402
}
391403
fun afterTime(dt: Double, f: InstantFunction) = afterTime(dt, InstantAction(f))
392404

393-
/**
394-
* Schedules action [a] to execute in parallel starting at a displacement [ds] before the end of the current trajectory segment.
395-
*
396-
* Cannot be called without an applicable pending trajectory.
397-
*/
398-
fun beforeEndDisp(ds: Double, a: Action): TrajectoryActionBuilder {
399-
require(ds >= 0.0) { "Displacement ($ds) must be non-negative" }
400-
401-
return TrajectoryActionBuilder(
402-
this, tb, n, lastPoseUnmapped, lastPose, lastTangent,
403-
ms + listOf(DispMarkerFactory(n, -ds, a, false)), cont,
404-
)
405-
}
406-
fun beforeEndDisp(ds: Double, f: InstantFunction) = beforeEndDisp(ds, InstantAction(f))
407-
408-
/**
409-
* Schedules action [a] to execute in parallel starting [dt] seconds before the end of the current trajectory segment.
410-
*
411-
* Cannot be called without an applicable pending trajectory.
412-
*/
413-
fun beforeEndTime(dt: Double, a: Action): TrajectoryActionBuilder {
414-
require(dt >= 0.0) { "Time ($dt) must be non-negative" }
415-
416-
return TrajectoryActionBuilder(
417-
this, tb, n, lastPoseUnmapped, lastPose, lastTangent,
418-
ms + listOf(TimeMarkerFactory(n, -dt, a, false)), cont,
419-
)
420-
}
421-
fun beforeEndTime(dt: Double, f: InstantFunction) = beforeEndTime(dt, InstantAction(f))
422-
423405
fun setTangent(r: Rotation2d) =
424406
TrajectoryActionBuilder(this, tb.setTangent(r), n, lastPoseUnmapped, lastPose, lastTangent, ms, cont)
425407
fun setTangent(r: Double) = setTangent(Rotation2d.exp(r))

road-runner/actions/src/test/kotlin/com/acmerobotics/roadrunner/ActionRegressionTest.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ class ActionRegressionTest {
158158
"SequentialAction(initialActions=[SleepAction(dt=2.32842712474619), A])" +
159159
"])",
160160
base
161-
.beforeEndTime(0.5, LabelAction("A"))
162161
.lineToX(20.0)
162+
.afterTime(-0.5, LabelAction("A"))
163163
.lineToXLinearHeading(30.0, Math.PI / 2)
164164
.build()
165165
.toString()
@@ -172,8 +172,8 @@ class ActionRegressionTest {
172172
"])])",
173173
base
174174
.lineToX(10.0)
175-
.beforeEndTime(0.5, LabelAction("A"))
176175
.lineToXLinearHeading(20.0, Math.PI / 2)
176+
.afterTime(-0.5, LabelAction("A"))
177177
.lineToX(30.0)
178178
.build()
179179
.toString(),
@@ -187,8 +187,8 @@ class ActionRegressionTest {
187187
base
188188
.lineToX(10.0)
189189
.lineToXLinearHeading(20.0, Math.PI / 2)
190-
.beforeEndTime(0.5, LabelAction("A"))
191190
.lineToX(30.0)
191+
.afterTime(-0.5, LabelAction("A"))
192192
.build()
193193
.toString()
194194
)
@@ -257,8 +257,8 @@ class ActionRegressionTest {
257257
"SequentialAction(initialActions=[SleepAction(dt=2.121320343559643), A])" +
258258
"])",
259259
base
260-
.beforeEndDisp(2.5, LabelAction("A"))
261260
.lineToX(20.0)
261+
.afterDisp(-2.5, LabelAction("A"))
262262
.lineToXLinearHeading(30.0, Math.PI / 2)
263263
.build()
264264
.toString()
@@ -271,8 +271,8 @@ class ActionRegressionTest {
271271
"])])",
272272
base
273273
.lineToX(10.0)
274-
.beforeEndDisp(2.5, LabelAction("A"))
275274
.lineToXLinearHeading(20.0, Math.PI / 2)
275+
.afterDisp(-2.5, LabelAction("A"))
276276
.lineToX(30.0)
277277
.build()
278278
.toString(),
@@ -286,8 +286,8 @@ class ActionRegressionTest {
286286
base
287287
.lineToX(10.0)
288288
.lineToXLinearHeading(20.0, Math.PI / 2)
289-
.beforeEndDisp(2.5, LabelAction("A"))
290289
.lineToX(30.0)
290+
.afterDisp(-2.5, LabelAction("A"))
291291
.build()
292292
.toString()
293293
)

0 commit comments

Comments
 (0)