# VAP (Vertical Alignment and Proximity) Tool

- This tool performs two operations:
  
  - A *"proximity calibration"* to measure and calibrate the proximity sensor of the HMD, notifying of a faulty unit in the process.  
  - A *"rotational calibration"* to account for the small rotational differences between the virtual camera and the variations in physical optics.

- To run this tool:
  
  - Set up the VAP unit in a dark room, with the `measurement camera` a couple of feet below where the HMD will sit.
  - Ensure the `measurement camera` has the displays of the HMD large, in-frame, and in-focus.
  - Connect the `measurement camera` to your PC, and ensure the HMD is also connected and running through SteamVR.
  - Retrieve the following python dependencies:

        pip install hidapi glfw opencv-python imgui numpy pywin32 pillow
    
  - Run:

        py main.py

## Proximity Calibration

  - The purpose of this step is to both calibrate the proximity sensor, as well as check whether the unit is faulty, accepting or rejecting the HMD.
  - How it works:
    
    * The process begins by clearing out the current proximity calibration of the HMD.
    * The HMD is then placed on the VAP unit, on the side *without* the proximity pad near the nose bridge.
    * The tool then reads the current proximity value, and saves it to the HMD.
    * The HMD is then placed on the side of the VAP unit *with* the proximity pad.
    * The tool then reads the current proximity value, which is used to determine a PASS vs FAIL of the proximity sensor.
    * If the HMD passes, this value is also saved to the HMD.
   
## Rotational Calibration

 - The purpose of this step is to correct the `virtual camera` rotation to match with the minor differences that occur in the optics during production.
   We measure the best rotation on all three axes (pitch, roll, yaw) that creates this alignment, and give it to SteamVR which will pre-rotate the
   virtual camera of applications to match that of your physical displays/optics.
   
 - Process:
   * It is essential that the VAP unit is in a dark room, so that the `measurement camera` can easily pick up the image displayed through the HMD, and so that the computer
     vision is not thrown off by extraneous light.
   * Secondly it is important that the `measurement camera` is a couple of feet away from the HMD on the VAP unit, and that the displays are in focus. This can be adjusted
     by rotating the various knobs on the `measurement camera` itself.
   * At the beginning of this stage, the HMD should be sitting in the VAP unit, on the proximity pad side, facing down, where the `measurement camera` can see the displays
     largely and clearly.
   * The tool begins by launching a background Unity VR application that should be run through SteamVR and displayed on the HMD.
   * The Unity application draws either a horizontal or vertical white line, against a black background, depending on what axis we are solving for.
   * During the process, the line will move across the displays by rotating the `virtual camera` in the Unity scene. This is ultimately what SteamVR will be doing for
     correction.
   * When the line is aligned with the correct axis on the displays through a specific rotation, it will light up most of the display itself due to the nature of the
     optics and the direction of reflection/refraction.

- The above process will occur for both eyes independently, and the result is the set of rotations for each eye that most closely solves the alignment.

- Closed form?
  
  * There are closed form methods for solving for these same values, located in `_old_horizon_correction.py` but they were found to be very unreliable without a
    significant amount of time spent filtering inter-reflections and other optical artifacts, as well as verifying the lines found with CV are the lines that are
    important to us for the solution. Even then, the slopes of the line-detection lines were unreliable and varied between repeated uses.
