WALT (WALT Latency Timer)

repository·master·Indexed 19 days ago

https://github.com/google/walt

A specialized toolset for measuring physical sensor and output latencies on mobile devices and computers, including touch, screen, audio, and MIDI. It features a three-step clock synchronization algorithm for asymmetric USB communication, a Python-based measurement tool (PyWALT) for Linux and ChromeOS, and dedicated apps for Android and iOS. The project includes detailed hardware specifications for assembly using a Teensy LC microcontroller, photodiodes, and accelerometers.

Tokens
9.5K
Snippets
19
Records
48
Agent score
66%

What's inside WALT

  1. Overview of WALT Latency Timer capabilities

    master

    WALT is a tool designed to measure the latency of physical sensors and outputs on mobile phones and computers. It provides specialized measurements for various hardware interactions, including:

    • Tap latency: Measures the time from physical contact (detected via an accelerometer on a probe) until the kernel timestamps an ACTION_DOWN or ACTION_UP event.
    • Drag latency: Measures scroll/drag latency.
    • Screen draw latency: Uses a photodiode to detect changes between black and white screen states.
    • Audio latency: Measures both audio output and microphone latencies.
    • MIDI latency: Measures MIDI input and output latencies.
  2. Understanding tap latency event types in Android

    master

    WALT's latency measurements rely on the timing of specific Android MotionEvent types. When measuring tap latency, the two critical events are:

    • ACTION_DOWN: Represents the initial contact with the screen.
    • ACTION_UP: Represents the release of contact from the screen.

    On Android, these events are exposed in Java as MotionEvent objects and include the kernel timestamp provided by the Linux Multi Touch (MT) implementation.

  3. How WALT measures screen response latency

    master

    WALT measures screen latency by detecting physical color changes (specifically between black and white) using a photodiode.

    On Android, the WALT app uses View.setBackgroundColor to trigger a color change. The latency reported is the time elapsed from the start of the next frame rendering event (governed by the Android Choreographer.FrameCallback) until the screen physically transitions to the new color.

    Key considerations for measurements:

    • Directionality: The physical transition time may differ depending on whether the screen is transitioning from black to white or white to black.
    • Hardware Variance: Transition speeds and the timing of different screen sections vary significantly based on screen technology and device models.
    • Setup for Accuracy: For consistent results, measurements should be taken with the device set to maximum brightness and the WALT hardware positioned in the middle of the screen.
  4. Understand the drag latency calculation method

    master

    The WALT app calculates latency by analyzing the relationship between motion events (coordinates and timestamps) and laser beam interruption events.

    1D Calculation (Standard)

    For standard measurements, the app assumes the laser beam is parallel to the x-axis and focuses on the vertical coordinate ($y$) as a function of time $y(t)$.

    • The app identifies points where the finger enters or exits the laser beam (marked as 'x' in plots).
    • It searches for a time shift $S$ that minimizes the standard deviation of $y(t + S)$.
    • A minimal standard deviation indicates that the 'x' marks align as closely as possible to a horizontal straight line, effectively compensating for the clock divergence between touch and laser events.
    • The final reported latency is the average of the two time shifts calculated for the two sides of the finger (the upper and lower lines of 'x' marks).

    2D Calculation (ChromeOS)

    For ChromeOS, a 2D extension of this method is used via a Python script. This method requires a considerable spread of the collected $x$ coordinates to function correctly.

  5. USB Communication via usbdevice_fs

    master

    WALT implements USB communication using the Linux API declared in linux/usbdevice_fs.h. It currently uses a BULK interface (typically exposed when Teensy code is compiled in "Serial" mode).

    There are two ways to perform communication via usbdevice_fs:

    1. Asynchronous way: Uses USBDEVFS_SUBMITURB followed by USBDEVFS_REAPURB (which blocks until a URB is available).
    2. Synchronous way: Uses USBDEVFS_BULK with a struct usbdevfs_bulktransfer configuration.

    Implementation Details:

    • All timestamps in the C code are recorded in microseconds.
    • Timestamped messages are single-byte.
    • The C code is compatible with both Android JNI and Linux.
    // Async way
    ioctl(fd, USBDEVFS_SUBMITURB, urb);
    // followed by
    ioctl(fd, USBDEVFS_REAPURB, &urb); // Blocks until there is a URB to read.
    
    // Sync way
    struct usbdevfs_bulktransfer  ctrl;
    ctrl.ep = endpoint;
    ctrl.len = length;
    ctrl.data = buffer;
    ctrl.timeout = timeout; // [milliseconds] Will timeout if there is nothing to read
    int ret = ioctl(fd, USBDEVFS_BULK, &ctrl);
  6. How drag/scroll latency is measured with WALT

    master

    WALT measures drag or scroll latency using a hardware-software co-measurement approach. A laser shines across the touch device toward a detector on the opposite side. A microcontroller monitors the laser detector and reports via USB when the beam is broken (e.g., by a finger interrupting the beam).

    By processing the touch events from the device and the laser events from the microcontroller together, WALT deduces the delay between the physical touch interaction and the system's reported touch events.

  7. Hardware and Clock Synchronization Notes

    master

    When using WALT, be aware of the following hardware and synchronization requirements:

    • Hardware Construction: Build instructions for the necessary hardware components are located in the hardware/ directory of this repository.
    • Clock Divergence: The clocks on Android/iOS devices and the Teensy microcontroller tend to diverge over time due to differing frequencies. They may go out of sync after several minutes.
    • Clock Re-synchronization: To fix divergence, use the WALT app to re-sync the clocks. Note that while some tests in the app automatically sync clocks when a measurement starts, others do not.
    • Detailed Sync Info: For technical details on clock synchronization, refer to the documentation in android/WALT/app/src/main/jni/README.md.
  8. How WALT measures tap latency

    master

    WALT measures tap latency using a specialized stylus equipped with an accelerometer and a grounded, flat metal tip that imitates a finger.

    Measurement Process:

    1. Tap (Collision): When the stylus hits the touchscreen, the accelerometer detects a shock (above 3g). This event is timestamped by a Teensy microcontroller.
    2. Release (Lift): To measure the lift-off latency, the stylus uses a retractable pen mechanism. As the stylus is lifted, a spring keeps the button in contact with the screen for the first few millimeters. This allows the hand to gain speed before the button is abruptly accelerated, generating a detectable shock for the accelerometer.

    For detailed procedural instructions, refer to the WALT usage documentation.

  9. How WALT Clock Synchronization works

    master

    WALT uses a three-step algorithm to synchronize a local clock with a remote clock, accounting for asymmetric USB latency. The goal is to bound the unknown clock difference E within a range minE < E < maxE.

    Step 1: Rough Sync

    1. Record local time T0.
    2. Instruct the remote device to zero its clock.
    3. Wait for confirmation from the remote.
    4. Set maxE = current_time() - T0.
    5. All subsequent local time is measured relative to T0.

    At this stage, the remote clock lags behind the local clock by E, where 0 = minE < E < maxE.

    Step 2: Find better lower bound (minE)

    To increase minE, send messages from local to remote. The remote replies with its timestamp (t_remote) of when it received the message. The local machine records the time right before sending (t_local).

    • Logic: E > t_local - t_remote (since travel time > 0).
    • Action: set minE to max(minE, t_local - t_remote).
    • Note: Send a batch of messages with random small delays before retrieving timestamps to mitigate kernel/hardware buffering delays.

    Step 3: Find better upper bound (maxE)

    To decrease maxE, the remote device sends messages to the local machine. The remote includes its timestamp (t_remote) of when the message was sent, and the local machine records the time of receipt (t_local).

    • Logic: E < t_local - t_remote.
    • Action: set maxE = min(maxE, t_local - t_remote).

    Comparison with NTP

    Unlike NTP, which assumes symmetric travel time (latency), WALT is designed for asymmetric USB communication. While the resulting synchronization interval deltaE = maxE - minE may be larger than NTP's on symmetric networks, WALT provides guaranteed bounds even when asymmetry is present.

  10. Understand how WALT measures audio latency

    master

    WALT measures audio latency as the time elapsed between an application's decision to output a tone and the moment that tone is detected via the headphone jack (for playback), or similarly for microphone latency (recording).

    Playback Latency

    WALT reports the time from the Enqueue() call in the player callback until a detectable signal is present on the wire.

    Note: This measurement deliberately omits the time between the application's decision to output a tone and the actual Enqueue() call. This omission is intended to reduce variance, as that interval is often uniformly distributed between 0 and the buffer length (e.g., 5 ms on a Nexus 5).

    To ensure accurate measurements and avoid 'warm-up' latency, it is recommended to constantly enqueue buffers containing silence. The WALT app follows this pattern.

    Recording Latency

    WALT reports the time from the moment the last frame in a buffer was recorded until the recorder callback receiving that buffer is executed.

  11. Hardware design notes and constraints

    master

    Electronics Implementation Notes

    • Teensy 3.1 Compatibility: If using a Teensy 3.1 instead of an LC, the screen photodiodes cannot be read directly. You must use a buffer opamp. While a single photodiode with a 1.5M resistor can work, it may hit the input impedance limits of the Teensy.
    • Photodiode Orientation: The BPW34 photodiode has a small protrusion on the cathode pin (cathode marker). The anode has a white dot near it.
    • Laser Setup: The laser photodiode setup uses an internal pullup resistor (~20k), enabled via pinMode(PD_LASER_PIN, INPUT_PULLUP);.

    Mechanical Requirements

    The enclosure must be made from a non-conductive and non-transparent material.

    Enclosure Options:

    • Production Version (r0.7): Uses WALT_recessed_enclosure.stl or .step files. Requires four M3x6 screws (McMaster-Carr PN 92000A116) and M3 hex nuts (McMaster-Carr PN 91828A211).
    • Desktop 3D Printing: A simpler version is available via OnShape or the WALT_3DP_enclosure_v7.stl file.
    • 2D Cutting: A minimal enclosure for 5-8mm thick substrates is available via OnShape.