Conflict resolution¶
Overview¶
Conflict resolution in FTCLib, NextFTC, and similar libraries is very basic. ducklib introduces a rich priority system, allowing for easy implementations of input buffering, default commands, and more.
To set the priority
or OnHigherConflict
or OnEqualConflict
properties of a command,
check out the command configuration page.
TL;DR:
val cmd = NoOpCommand().configure {
priority = 1.priority
onEqualConflict = OnEqualConflict.QUEUE
onHigherConflict = OnHigherConflict.CANCEL
}
// or
val cmd = NoOpCommand()
.setPriority(priority = 1.priority)
.setOnEqualConflict(OnEqualConflict.QUEUE)
.setOnHigherConflict(OnHigherConflict.CANCEL)
Situation 1: no conflicts¶
Say you have a command, cmd1
, that requires subsystem1
.
Now, you try to schedule another command, cmd2
, that requires subsystem2
.
Since neither of their requirements overlap,
everything goes smoothly, and both commands are scheduled.
Situation 1: conflicts, but cmd2
has higher priority¶
Now, cmd2
requires subsystem1
.
Their requirements overlap, so we have a conflict that we need to resolve.
The first step is to compare their priorities.
In this case, cmd2
has a higher priority than cmd1
.
This means that no matter what, cmd2
is going to run.
To do this, cmd1
will have to be suspended or canceled,
so its suspend
function will get called to aid in a smooth handoff,
and cmd2
will take over control.
When cmd2
finishes,
assuming cmd1
got suspended and not canceled,
cmd1
will get resumed and rescheduled.
What determines whether a command is suspendable or not is the suspendable
property on Command
, and is set by the command.
Situation 2: conflicts, but cmd2
has lower priority¶
Again, the first step is to compare their priorities.
In this case, cmd2
has a lower priority than cmd1
.
This means that no matter what, cmd1
is going to finish running.
cmd2
has two choices:
it can give up,
or it can get queued for later scheduling.
By default the latter is chosen,
although you can set it with one one of the configuration functions.
Situation 3: conflicts, but they have equal priority¶
cmd1
can't wait,
and cmd2
can't wait,
so now what happens is determined by the user with one of the configuration functions.
They can either make cmd2
cancel cmd1
with OnEqualConflict.OVERRIDE
,
or make it queue with OnEqualConflict.QUEUE
.
Recap¶
Basically, the flow is this:
graph TB
Start(Command wants to get scheduled) --> HasConflicts
HasConflicts{Has conflicts?} -->|Yes| ConflictPriority{Conflicting command's priority higher, lower or equal?}
ConflictPriority -->|Higher| HigherConflict{What is <code>OnHigherConflict</code>?}
Queue(Queue for rescheduling attempt next tick)
HigherConflict -->|CANCEL| HigherConflictEnd(Stop trying, cancel scheduling)
HigherConflict -->|QUEUE| Queue
ConflictPriority -->|Equal| EqualConflict{What is <code>OnEqualConflict</code>?}
EqualConflict -->|QUEUE| Queue
ConflictPriority -->|Lower| SuspendOrCancel
SuspendOrCancel{Is conflict suspendable?}
SuspendOrCancelSuspendable(Suspend the conflict) --> ScheduleCommand
SuspendOrCancelUnsuspendable(Cancel the conflict) --> ScheduleCommand
SuspendOrCancel -->|Yes| SuspendOrCancelSuspendable
SuspendOrCancel -->|No| SuspendOrCancelUnsuspendable
EqualConflict -->|OVERRIDE| SuspendOrCancel
ScheduleCommand(Command gets scheduled)
Queue -.->|after one tick| Start