Connect with us

Разработка

Как использовать CoreMotion для получения сенсорных данных

В этой статье мы разберемся, как он работает, и создадим простой интерфейс для отображения собранных данных.

Опубликовано

/

     
     

Вдохновленный Swift Student Challenge 2023 и моим желанием попробовать что-то новое, я бросил вызов себе и решил изучить фреймворк, который я никогда раньше не использовал — CoreMotion.

В этой статье мы разберемся, как он работает, и создадим простой интерфейс для отображения собранных данных.

Как использовать CoreMotion для получения сенсорных данных

Что такое CoreMotion

CoreMotion — это фреймворк Apple, который передает информацию о движении и окружающей среде от бортовых датчиков устройства. Он, в частности, позволяет разработчикам получать доступ к данным о движении устройства, таким как ускорение, скорость и ориентация.

Кроме того, он оптимизирован для получения точных данных о движении даже в сложных условиях, таких как быстрое движение или изменение направления, поскольку использует датчики устройства для измерения и отслеживания движения в режиме реального времени.

Вы можете использовать этот фреймворк для доступа к данным, генерируемым оборудованием, и использовать их для всего, что только можно себе представить. Например, игра может использовать данные акселерометра и гироскопа для управления поведением игры на экране.

Погружение в CoreMotion

Пользователи генерируют события движения, когда двигают, трясут или наклоняют устройство. Эти события движения обнаруживаются аппаратным обеспечением устройства, и фреймворк позволяет вашему приложению получать и обрабатывать данные о движении.

Каждое устройство Apple имеет встроенное оборудование, которое можно использовать для сбора интересных данных. Давайте рассмотрим три основных компонента фреймворка CoreMotion:

  • Акселерометр: Измеряет ускорение устройства и используется для обнаружения изменений в скорости и направлении движения
  • Гироскоп: Измеряет угловую скорость устройства и используется для обнаружения изменений в ориентации и вращении.
  • Магнитометр: Измеряет магнитное поле устройства и используется для определения ориентации устройства относительно магнитного поля Земли.

Существуют и другие типы датчиков, такие как барометры, шагомеры и датчики приближения, которые также хорошо задокументированы и информацию о них вы можете найти здесь.

Прежде чем мы сможем прочитать данные от этих датчиков, нам нужно глубоко погрузиться в то, как они представляются. Во-первых, важно понимать, что все значения, записываемые фреймворком устройства, относятся к референсной системе координат.

Как использовать CoreMotion для получения сенсорных данных

Это трехмерная система координат с тремя осями. Ось Z всегда направлена вниз по направлению силы тяжести (центр Земли), а направление оси X может быть определено вами при настройке менеджера движения. Наконец, ось Y перпендикулярна осям X и Z, завершая трехмерную систему координат.

Направление оси Y можно определить по правилу правой руки: если вы направляете большой палец в направлении оси X, а указательный палец — в направлении оси Z, то средний палец указывает в направлении оси Y.

Итак, чтобы лучше понять основные датчики и то, как они помогают отслеживать движение, мы можем взглянуть на то, что они могут измерять в своих трех координатах:

  • Ускорение пользователя — ускорение, которое пользователь придает устройству
  • Гравитация — ускорение под действием силы тяжести
  • Скорость вращения — как пользователь вращает смартфон

Как использовать

В этой статье мы будем использовать SwiftUI и архитектуру MVVM.

Сначала вам нужно создать представление для отображения данных, которые вы будете получать. Вы можете спроектировать его как угодно, или посмотреть исходный код того, который я создал, здесь.

Теперь перейдем к собственно логике. Первое, что вам нужно сделать, это импортировать CoreMotion и создать экземпляр CMMotionManager. Кроме того, вам понадобятся некоторые свойства для хранения полученных значений.

class HomeViewModel: ObservableObject {
    
    @Published var accelerationValue: String = ""
    @Published var gravityValue: String = ""
    @Published var rotationValue: String = ""
    
    // The instance of CMMotionManager responsible for handling sensor updates
    private let motionManager = CMMotionManager()
    
    // Properties to hold the sensor values
    private var userAcceleration: CMAcceleration = CMAcceleration()
    private var gravity: CMAcceleration = CMAcceleration()
    private var rotationRate: CMRotationRate = CMRotationRate()
  
}

Затем нам нужно получить фактические данные, которые мы получаем от датчиков. Поэтому мы создадим private функцию, которая будет проверять, доступны ли они, а затем начнет обновлять их, вызывая соответствующие методы.

private func startFetchingSensorData() {
        // Check if the motion manager is available and the sensors are available
        if motionManager.isDeviceMotionAvailable && motionManager.isAccelerometerAvailable && motionManager.isGyroAvailable {
            // Start updating the sensor data
            motionManager.startDeviceMotionUpdates(to: .main) { [weak self] (motion, error) in
                guard let self = self else { return } // Avoid memory leaks
                // Check if there's any error in the sensor update
                if let error = error {
                    print("Error: \(error.localizedDescription)")
                }
                getMotionAndGravity(motion: motion)
            }
            motionManager.startGyroUpdates(to: .main) { [weak self] (gyroData, error) in
                guard let self = self else { return }
                getRotation(gyroData: gyroData)
            }
        }
    }

Далее нам останется только создать методы, которые будут извлекать значения ускорения, гравитации и вращения, и сделать так, чтобы они обновляли соответствующие @Published свойства, чтобы они могли публиковать изменения подписчикам нашего представления.

private func getMotionAndGravity(motion: CMDeviceMotion?){
        if let motion = motion {
            // Get user acceleration and gravity data
            self.userAcceleration = motion.userAcceleration
            self.gravity = motion.gravity
            // Update publishers with the new sensor data
            self.accelerationValue = "X: \(userAcceleration.x), \n Y: \(userAcceleration.y), \n Z: \(userAcceleration.z)"
            self.gravityValue = "X: \(gravity.x), \n Y: \(gravity.y), \n Z: \(gravity.z)"
        }
    }
    
    private func getRotation(gyroData: CMGyroData?){
        if let gyroData = gyroData {
            // Get rotation rate data
            self.rotationRate = gyroData.rotationRate
            // Update publisher with the new sensor data
            self.rotationValue = "X: \(rotationRate.x), \n Y: \(rotationRate.y), \n Z: \(rotationRate.z)"
        }
    }

После этого вы можете начать перемещаться и вращать свое устройство, чтобы увидеть обновление данных в режиме реального времени! Я призываю вас начать исследовать возможности взаимодействия на основе движения в ваших собственных проектах.

Заключение

CoreMotion — это мощный фреймворк, открывающий бесчисленные возможности для использования движений. Он полезен не только для разработчиков, но и для пользователей, которые могут извлечь пользу из нового и уникального опыта.

Я использовал его для создания своего проекта-победителя WWDC 23, Space Cruiser! 🏆

Как использовать CoreMotion для получения сенсорных данных

Логика игры предполагает управление космическим кораблем, а движение устройства используется для управления его перемещением. Космический корабль управляется с помощью наклона устройства, что добавляет игре новый уровень погружения.

Space Cruiser доступен на GitHub, как и исходный код для этой статьи.

Источник

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.

Наши партнеры:

LEGALBET

Мобильные приложения для ставок на спорт
Хорошие новости

Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: