Я работаю над приложением для iOS, которое запускает внутренний вибромотор iPhone и, пока телефон вибрирует, собирает показания акселерометра и гироскопа. Я визуализировал данные после сбора и ясно видел вибрации на гироскопе, но ничего не видел на акселерометре. Мне было интересно, делал ли кто-нибудь подобное раньше на iPhone и мог видеть вибрацию акселерометра.
Ниже я поделюсь кодом, который я использовал для сбора данных акселерометра и гироскопа.
Во-первых, этот класс отвечает за процесс сбора:
Я работаю над приложением для iOS, которое запускает внутренний вибромотор iPhone и, пока телефон вибрирует, собирает показания акселерометра и гироскопа. Я визуализировал данные после сбора и ясно видел вибрации на гироскопе, но ничего не видел на акселерометре. Мне было интересно, делал ли кто-нибудь подобное раньше на iPhone и мог видеть вибрацию акселерометра. Ниже я поделюсь кодом, который я использовал для сбора данных акселерометра и гироскопа. Во-первых, этот класс отвечает за процесс сбора: [code]class SensorCollector: ObservableObject { private let motionManager = CMMotionManager() private let sensorQueue = OperationQueue()
var accBuffer: [VibrateView.SensorReading] = [] var gyrBuffer: [VibrateView.SensorReading] = []
// Check availability var isAccelAvailable: Bool { motionManager.isAccelerometerAvailable } var isGyroAvailable: Bool { motionManager.isGyroAvailable } } [/code] Затем я использую эту функцию для запуска внутреннего вибромотора iPhone. Пользователь выбирает тест в пользовательском интерфейсе: [code] struct VibrationEvent { let time: TimeInterval let duration: TimeInterval let intensity: Float }
func vibrateDevice(forTest test: String) async throws { var events = [CHHapticEvent]() let traceDuration: TimeInterval = 2.0 let currentTime: TimeInterval = 0
if selectedTest.contains("Test 1"){ someEvents = test1 } else if selectedTest.contains("Test 2") { someEvents = test2 } else if selectedTest.contains("Test 3") { someEvents = test3 } else if selectedTest.contains("Test 4") { someEvents = test4 } else if selectedTest.contains("Test 5") { someEvents = test5 } else if selectedTest.contains("Test 6"){ someEvents = test6 }
for event in someEvents { events.append(addVibration(at: event.time, duration: event.duration, intensity: event.intensity)) }
do { let pattern = try CHHapticPattern(events: events, parameters: []) let player = try engine?.makePlayer(with: pattern) try player?.start(atTime: 0) } catch { print("Failed to play pattern: \(error.localizedDescription)") }
let totalDuration = (someEvents.map { $0.time + $0.duration }.max() ?? 0) try await Task.sleep(nanoseconds: UInt64(totalDuration * 1_000_000_000)) } [/code] Наконец, я использую эту функцию, чтобы собрать все воедино: [code]func startVibrationTest() async { // 1. UI Setup testRunning = true canClearResults = false tracesData = []
testStartTime = currentUptimeSeconds()
do { try await prepareHaptics()
// MARK: - SCENARIO A: Test 0 (Rest Only) if selectedTest.contains("Test 0") { let restDuration: TimeInterval = 10.0 let restStart = currentUptimeSeconds()
// A. Start Collecting collector.startSensors(startTime: currentUptimeSeconds())
// B. Wait try await Task.sleep(nanoseconds: UInt64(restDuration * 1_000_000_000))
// C. Stop Collecting collector.stopSensors()
// D. Save Data let restTrace = TraceReadings( id: 1, accelerometer: collector.accBuffer, gyroscope: collector.gyrBuffer, startTime: restStart, endTime: currentUptimeSeconds(), traceType: .rest )
// Append to array (UI Update on Main Actor) await MainActor.run { tracesData.append(restTrace) }
sendDataToServer() }
// MARK: - SCENARIO B: Vibration Tests (1-6) else { let numberOfTraces = 10 let breakDuration: TimeInterval = 10.0