Class Interlock
Robot.java, and the library keeps
to it every loop, in TeleOp and autonomous, whoever moves the part (a button, a stick, an action, a
following turret, a step).
// Robot.java, in define(), after the parts:
keepApart("TurretLift", turret.zone(), lift.zoneAbove());
// Tunables.java: the rule's numbers, in each part's own units
public static class TurretLift {
public static double turretFrom = 154, turretTo = 218; // degrees: the turret's zone
public static double liftAbove = 620; // counts: the lift's zone
public static double turretMargin = 4, liftMargin = 60; // optional: extra safety distances
public static double turretStopSec = 0.2; // optional: seconds to stop (default 0.15)
}
The rule: the two parts are never both in their zones. Whoever is in its zone first keeps it; the other part waits outside its own zone until the first one leaves.
- A part that wants to go into its zone (a target inside it, or a stick pushing toward it) goes, if the other part is out of its zone. The other part is then held out of its zone.
- A held part stops at a safe distance from its zone (two margins) and waits there. Its target is kept: it goes on by itself when the other part leaves. The Driver Station says so: "Turret held at 150 deg: Lift is above 620 counts".
- A turret whose target is on the other side of its zone goes the other way round if its range allows (e.g. a range of -190 to 190, or a slip ring); else it waits at the edge.
- Both want in at the same moment: the first part named in the rule goes first.
- Both already in their zones (at START, or after one was pushed by hand): neither may go deeper. Each may only move OUT. As soon as one is out, the other keeps its zone. The Driver Station says "both in their zones: move one out".
- A part whose position is not known (a turret not homed yet; a servo before its first command, or while it is still moving) counts as "maybe anywhere it could be": in its zone, if the zone is in reach. So the other part waits.
- And the other way round: a part whose position is not known does not move at all (no homing, no stick, no first servo move) while the other part is in its zone, since it could sweep through it. The Driver Station says "Turret waits (not homed yet): Lift is above 620 counts; move Lift out of its zone first". It goes as soon as the other part is out.
Stop distance (motor parts: a turret, lift or arm): a moving motor does not stop at once. It
goes on until the next loop (which may be slow: a camera, a busy hub; and its position is from the last
loop, so count that one too), then it coasts while it brakes. So every loop the rule measures the part's
speed (from its encoder) and works out how far it would still go if told to stop now: speed x (2 x the
slowest of the last 25 loops + half its <part>StopSec, default 0.15 s). A part that is kept out
may only use the power that lets it stop in time: it slows down near its waiting point and brakes as
soon as that distance would take it past it. A part that could not stop before its zone counts as
already in it (the other part waits). A servo needs none: it is never sent past the fence.
Margins (<part>Margin, in its units; defaults: 3 degrees or twice the turret's
tolerance, twice a lift's or arm's tolerance (at least 1/50 of its range), 0.02 for a servo, 1/50 of a
hood's range): a part counts as in its zone within one margin of it, and a held part waits two margins
away. The stop distance already covers coasting: the margin is extra safety (an encoder that slips, a
part that bends).
Measured, not guessed: motors use their encoders every loop. A servo cannot say where it is,
so it counts as anywhere between where it was and where it was sent, until its travelSec
(Tunables) says it has arrived.
Checked at INIT (the OpMode stops with the reason): the rule's Tunables section and every
number it needs; a zone that is empty (from is not below to), outside the part's range, or covering
its whole range (the part could never be out of it); a negative margin; a part that is not on the
robot, or one with no position (an intake roller: use Zone.when(java.lang.String, java.util.function.BooleanSupplier)); a stop time outside 0 to 2 s.
Not changeable live. The numbers are read once at INIT and are not in the tuning menu: a zone
that moves while the parts move could suddenly put both in their zones. Change them in
Tunables.java, then INIT again.
Software only: it does not replace hard stops, and a part pushed by hand (or by another robot) can still end up in its zone. The rule then only lets it move out. Docs: docs/modules/robot.md (section "Interlock"), docs/guides/interlocks.md
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final doubleThe default<part>StopSec: a motor part in BRAKE stops in about this long (seconds). -
Method Summary
Modifier and TypeMethodDescriptionbooleanTrue while the rule is holding a part back (it wants to go further but must wait).booleanisOff()True if the rule is off because one of its parts is not on the robot (Module.optional()).name()The rule's name: its section inTunables.java.status()What it is doing, for the Driver Station ("" when nothing is held).words()The rule in words: "Turret between 154 and 218 deg / Lift above 620 counts".
-
Field Details
-
DEFAULT_STOP_SEC
public static final double DEFAULT_STOP_SECThe default<part>StopSec: a motor part in BRAKE stops in about this long (seconds).- See Also:
-
-
Method Details
-
name
The rule's name: its section inTunables.java. -
isHolding
public boolean isHolding()True while the rule is holding a part back (it wants to go further but must wait). -
status
What it is doing, for the Driver Station ("" when nothing is held). -
words
The rule in words: "Turret between 154 and 218 deg / Lift above 620 counts". -
isOff
public boolean isOff()True if the rule is off because one of its parts is not on the robot (Module.optional()).
-