Class LightingSweep

java.lang.Object
com.crossbotics.ftchelper.vision.LightingSweep

public final class LightingSweep extends Object
Tries a few camera settings one after the other, counts how many pictures see AprilTags with each, and keeps the best one. Used for venue lighting: a gym, a practice room and a dark event hall need different camera settings. LimelightTags.autoPipelines(int...) (one Limelight pipeline per setting) and WebcamTags.autoExposure() (one exposure per setting) use it; you rarely make one yourself.

How it works, setting by setting: ask the camera to switch to it; once the camera says the switch is done (switched()), wait a moment for it to settle, then look at the next few pictures and count the ones that see at least one tag. After the last setting, the one with the most pictures with tags wins (a tie goes to the one earlier in the list, so put your usual setting first). If no setting saw enough tags (the robot was not facing any), it starts over and keeps trying, all through INIT. At START it stops and keeps the best setting so far (the first one if none saw a tag), so the robot never aims with pictures from a setting being tried. So: have a tag in view at INIT, or the test cannot help.

A setting the camera refuses (switchFailed()), or one that never sends pictures while the camera still sends pictures from another setting (a Limelight pipeline that is not set up), gets no score and is skipped in later rounds.

It never waits: update(int) is one quick step per loop. Switching a setting is done by the apply code you give it; the cameras send that to a background helper (see docs/guides/non-blocking.md).


 LightingSweep sweep = new LightingSweep(Arrays.asList("bright", "normal", "dim"),
         i -> worker.submitLatest("pipeline", () -> limelight.pipelineSwitch(i)), System::nanoTime);
 // every loop, INIT and after START:
 if (firstPictureFromTheNewSetting) sweep.switched();
 sweep.update(newPicture ? (fromTheSettingTried ? tagsInIt : LightingSweep.OTHER_SETTING) : LightingSweep.NO_PICTURE);
 telemetry.addLine(sweep.status());     // "dim (9 of 10 pictures saw tags)"
 
Docs: docs/modules/vision.md (section "Venue lighting")
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    Give this to update(int) when there is no new picture.
    static final int
    Give this to update(int) for a new picture taken with another setting (the one before).
  • Constructor Summary

    Constructors
    Constructor
    Description
    LightingSweep(List<String> labels, IntConsumer apply, LongSupplier clockNanos)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    int
    The setting kept (0 = the first label), or -1 while still trying.
    The label of the kept setting, or null while still trying.
    int
    The setting being tried now (or kept), -1 before the first update.
    boolean
    True if no setting saw a tag before it had to stop, so it kept the first one.
    giveUpAfterStartMs(double ms)
    After START, how long to keep trying when no setting has worked yet (milliseconds, default 0 = stop at START and keep the best so far).
    int
    hitsOf(int i)
    How many pictures saw tags with setting i in its last try (0 if not tried yet, refused or missing).
    boolean
    True once a setting is kept (found, or stopped at START).
    The settings, in the order they are tried.
    boolean
    True after matchStarted() (for the cameras: hide trial pictures during the match).
    void
    Tell it the match has started (the OpMode's START).
    minPictures(int count)
    How many pictures must see a tag for a setting to count as good (default 3).
    void
    A new camera session (the camera was closed and started again): everything as new, INIT again.
    boolean
    True while it is still looking for tags (a round found none: the robot should face a tag).
    pictures(int count)
    How many pictures to look at per setting (default 10).
    int
    picturesOf(int i)
    How many pictures were counted with setting i in its last try.
    Problems to show, one per skipped setting, e.g.
    void
    Forgets the result and tries every setting again (for a button, e.g.
    Every setting's score, e.g.
    settleMs(double ms)
    How long to wait after the camera has switched before counting pictures (milliseconds, default 300).
    boolean
    skipped(int i)
    True if setting i is skipped (the camera refused it, or sent no pictures from it).
    One line for the Driver Station, e.g.
    void
    The camera says it has the setting being tried now (its pictures are from it).
    void
    The camera refused the setting being tried: it gets no score and is skipped from now on.
    switchTimeoutMs(double ms)
    The most time the camera gets to switch to a setting (milliseconds, default 1500).
    trialMs(double ms)
    The most time one setting gets once switched, settling included (milliseconds, default 2000).
    void
    update(int tagsInNewPicture)
    One quick step.
    void
    For a camera that is not ready yet (a webcam that is not streaming): no switching, only the time limits are checked, so START still ends the test.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Constructor Details

    • LightingSweep

      public LightingSweep(List<String> labels, IntConsumer apply, LongSupplier clockNanos)
      Parameters:
      labels - one short name per setting, in the order to try them (e.g. "pipeline 0"). Put your usual setting FIRST: it wins ties and is kept if nothing sees a tag.
      apply - switches the camera to setting number i (0 = the first label). Must not wait: send slow requests to a BackgroundWorker.
      clockNanos - the time now in nanoseconds; System::nanoTime on the robot, a pretend clock in tests
  • Method Details

    • settleMs

      public LightingSweep settleMs(double ms)
      How long to wait after the camera has switched before counting pictures (milliseconds, default 300).
    • pictures

      public LightingSweep pictures(int count)
      How many pictures to look at per setting (default 10).
    • trialMs

      public LightingSweep trialMs(double ms)
      The most time one setting gets once switched, settling included (milliseconds, default 2000).
    • switchTimeoutMs

      public LightingSweep switchTimeoutMs(double ms)
      The most time the camera gets to switch to a setting (milliseconds, default 1500).
    • minPictures

      public LightingSweep minPictures(int count)
      How many pictures must see a tag for a setting to count as good (default 3).
    • giveUpAfterStartMs

      public LightingSweep giveUpAfterStartMs(double ms)
      After START, how long to keep trying when no setting has worked yet (milliseconds, default 0 = stop at START and keep the best so far). While it tries after START, the cameras report no targets, so nothing aims with a trial picture. Tunables: lightingAfterStartMs.
    • matchStarted

      public void matchStarted()
      Tell it the match has started (the OpMode's START). With the default it stops now and keeps the best so far.
    • matchHasStarted

      public boolean matchHasStarted()
      True after matchStarted() (for the cameras: hide trial pictures during the match).
    • restart

      public void restart()
      Forgets the result and tries every setting again (for a button, e.g. after moving to a new field). During the match it gets giveUpAfterStartMs from now (and the cameras report no targets until it is done).
    • newSession

      public void newSession()
      A new camera session (the camera was closed and started again): everything as new, INIT again.
    • switched

      public void switched()
      The camera says it has the setting being tried now (its pictures are from it). Settling starts.
    • switchFailed

      public void switchFailed()
      The camera refused the setting being tried: it gets no score and is skipped from now on.
    • update

      public void update(int tagsInNewPicture)
      One quick step. Call it every loop, in INIT and after START, until isDone().
      Parameters:
      tagsInNewPicture - how many tags the newest picture saw; NO_PICTURE when there is no new picture; OTHER_SETTING for a picture from another setting
    • waitingForCamera

      public void waitingForCamera()
      For a camera that is not ready yet (a webcam that is not streaming): no switching, only the time limits are checked, so START still ends the test.
    • isDone

      public boolean isDone()
      True once a setting is kept (found, or stopped at START).
    • gaveUp

      public boolean gaveUp()
      True if no setting saw a tag before it had to stop, so it kept the first one.
    • chosen

      public int chosen()
      The setting kept (0 = the first label), or -1 while still trying.
    • current

      public int current()
      The setting being tried now (or kept), -1 before the first update.
    • noTagsYet

      public boolean noTagsYet()
      True while it is still looking for tags (a round found none: the robot should face a tag).
    • chosenLabel

      public String chosenLabel()
      The label of the kept setting, or null while still trying.
    • labels

      public List<String> labels()
      The settings, in the order they are tried.
    • hitsOf

      public int hitsOf(int i)
      How many pictures saw tags with setting i in its last try (0 if not tried yet, refused or missing).
    • picturesOf

      public int picturesOf(int i)
      How many pictures were counted with setting i in its last try.
    • skipped

      public boolean skipped(int i)
      True if setting i is skipped (the camera refused it, or sent no pictures from it).
    • status

      public String status()
      One line for the Driver Station, e.g. "dim (9 of 10 pictures saw tags)", "trying 2 of 3: normal", "trying 1 of 3: normal (no tags yet: face a tag)", or "NO TAGS SEEN: kept normal (have a tag in view at INIT next time)".
    • problems

      public List<String> problems()
      Problems to show, one per skipped setting, e.g. "no pictures from pipeline 2 (missing?)".
    • scores

      public String scores()
      Every setting's score, e.g. "bright 2/10, normal 9/10, dim 5/10" ("skipped" for a skipped one).