Skip to content

ojowwalker77/attention-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AttentionEngine

A lightweight, whitelabel iOS library for real-time attention detection using ARKit (TrueDepth) and Vision (fallback). Drop it into any app — reader, video player, learning tool, etc. — and receive high-level attention events with zero coupling to your domain.

What it does

  • Eye tracking — gaze direction, horizontal deviation
  • Blink detection — distinguishes voluntary blinks from sustained eye closure
  • Head pose — yaw (left/right) and pitch (up/down) via 4×4 → Euler matrix decomposition
  • Adaptive baseline — slowly learns each user's normal posture; no manual calibration
  • Confidence weighting — temporal trend analysis across a 1-second rolling window
  • Sleepiness detection — eyes closed continuously > N seconds (configurable)
  • Attention degradation — rolling 10/20/30/60s windows detect sustained inattention and emit severity levels
  • Auto fallback — ARKit TrueDepth → Vision face detection on older devices
  • App lifecycle — automatically pauses/resumes with app foreground/background

Requirements

  • iOS 16+
  • Swift 5.9+
  • NSCameraUsageDescription in your app's Info.plist

Installation

Swift Package Manager

// Package.swift
.package(url: "https://github.com/your-org/attention-engine", from: "0.1.0")

Or add via Xcode: File → Add Packages…

Quick Start

import AttentionEngine

@MainActor
class MyViewController: UIViewController, AttentionEngineDelegate {

    let engine = AttentionEngine(config: .init(sensitivity: .medium, wellnessEnabled: true))

    override func viewDidLoad() {
        super.viewDidLoad()
        engine.delegate = self
        engine.start()
    }

    // MARK: - AttentionEngineDelegate

    func attentionEngineDidLoseAttention(_ engine: AttentionEngine) {
        // e.g. pause video, dim screen
    }

    func attentionEngineDidRestoreAttention(_ engine: AttentionEngine) {
        // e.g. resume video
    }

    func attentionEngineDetectedSleepiness(_ engine: AttentionEngine) {
        // e.g. show "Take a break?" alert
    }

    func attentionEngineDetectedDegradation(_ engine: AttentionEngine,
                                             level: AttentionDegradationLevel,
                                             lastGoodAttentionTime: Date) {
        // e.g. offer to rewind to lastGoodAttentionTime
    }

    func attentionEngineStatusChanged(_ engine: AttentionEngine, isActive: Bool, mode: AttentionDetectionMode) {
        print("Detection \(isActive ? "started" : "stopped") using \(mode)")
    }
}

Combine

engine.publisher
    .receive(on: DispatchQueue.main)
    .sink { event in
        switch event {
        case .attentionLost:        pausePlayback()
        case .attentionRestored:    resumePlayback()
        case .sleepinessDetected:   showBreakAlert()
        case .degradation(let lvl, let since): rewindTo(since)
        case .statusChanged:        break
        }
    }
    .store(in: &cancellables)

SwiftUI

struct ContentView: View {
    @StateObject private var engine = AttentionEngine()

    var body: some View {
        Circle()
            .fill(engine.isAttentionLost ? .red : .green)
            .frame(width: 12, height: 12)
            .onAppear { engine.start() }
            .onDisappear { engine.stop() }
    }
}

Configuration

let config = AttentionConfig(
    sensitivity: .high,            // .low | .medium | .high
    awayThreshold: 0.1,            // seconds before attentionLost fires
    resumeThreshold: 0.05,         // seconds before attentionRestored fires
    wellnessEnabled: true,         // enable sleepiness detection
    sleepinessEyeClosedDuration: 3.0,
    sleepinessEventCount: 3,       // events before alert
    degradationEnabled: true
)

Sensitivity presets

Level Away Resume Blink Gaze
low 250 ms 150 ms 0.75 0.40
medium 150 ms 100 ms 0.65 0.30
high 100 ms 50 ms 0.55 0.20

Events

Event When
attentionLost User looks away / eyes close beyond thresholds
attentionRestored User looks back
sleepinessDetected Eyes closed continuously ≥ sleepinessEyeClosedDuration × sleepinessEventCount
degradation(level, lastGoodAttentionTime) Rolling window drops below quality threshold
statusChanged(isActive, mode) Detection started/stopped, mode changed

Degradation levels

Level Window condition
low 30s avg < 0.70 and 60s avg < 0.75
veryLow 20s avg < 0.60 and 30s avg < 0.65
critical 10s avg < 0.55 and 20s avg < 0.60

License

MIT

About

iOS library for real-time attention detection using ARKit (TrueDepth) and Vision (fallback).

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages