# Package edu.wpi.first.wpilibj.vision

Classes in the `edu.wpi.first.wpilibj.vision` package are designed to simplify using OpenCV vision processing code from a robot program.

See: Description

- Interface Summary
  Interface | Description
  --- | ---
  VisionPipeline | A vision pipeline is responsible for running a group of OpenCV algorithms to extract data from an image.
  VisionRunner.Listener<P extends VisionPipeline> | Listener interface for a callback that should run after a pipeline has processed its input.

- Class Summary
  Class | Description
  --- | ---
  VisionRunner<P extends VisionPipeline> | A vision runner is a convenient wrapper object to make it easy to run vision pipelines from robot code.
  VisionThread | A vision thread is a special thread that runs a vision pipeline.

## Package edu.wpi.first.wpilibj.vision Description

Classes in the `edu.wpi.first.wpilibj.vision` package are designed to simplify using OpenCV vision processing code from a robot program.

An example use case for grabbing a yellow tote from 2015 in autonomous:

     public class Robot extends IterativeRobot
         implements VisionRunner.Listener<MyFindTotePipeline> {

          // A USB camera connected to the roboRIO.
          private VideoSource usbCamera;

          // A vision pipeline. This could be handwritten or generated by GRIP.
          // This has to implement VisionPipeline.
          // For this example, assume that it's perfect and will always see the tote.
          private MyFindTotePipeline findTotePipeline;
          private VisionThread findToteThread;

          // The object to synchronize on to make sure the vision thread doesn't
          // write to variables the main thread is using.
          private final Object visionLock = new Object();

          // The pipeline outputs we want
          private boolean pipelineRan = false; // lets us know when the pipeline has actually run
          private double angleToTote = 0;
          private double distanceToTote = 0;

          @Override
          public void copyPipelineOutputs(MyFindTotePipeline pipeline) {
              synchronized (visionLock) {
                  // Take a snapshot of the pipeline's output because
                  // it may have changed the next time this method is called!
                  this.pipelineRan = true;
                  this.angleToTote = pipeline.getAngleToTote();
                  this.distanceToTote = pipeline.getDistanceToTote();
              }
          }

          @Override
          public void robotInit() {
              usbCamera = CameraServer.getInstance().startAutomaticCapture(0);
              findTotePipeline = new MyFindTotePipeline();
              findToteThread = new VisionThread(usbCamera, findTotePipeline, this);
          }

          @Override
          public void autonomousInit() {
              findToteThread.start();
          }

          @Override
          public void autonomousPeriodic() {
              double angle;
              double distance;
              synchronized (visionLock) {
                  if (!pipelineRan) {
                      // Wait until the pipeline has run
                      return;
                  }
                  // Copy the outputs to make sure they're all from the same run
                  angle = this.angleToTote;
                  distance = this.distanceToTote;
              }
              if (!aimedAtTote()) {
                  turnToAngle(angle);
              } else if (!droveToTote()) {
                  driveDistance(distance);
              } else if (!grabbedTote()) {
                  grabTote();
              } else {
                  // Tote was grabbed and we're done!
                  return;
              }
          }

     }