基于iPhone 上的运动协处理器M7判断用户当前的运动(姿态)类型

1,676 阅读4分钟

前言

在开发运动app时我们可能需要知道用户当前的运动姿态来做一些数据上的判断处理(cycling、running、walking、automotive),我发现了CoreMotion 框架下的CMMotionActivityManager似乎可以帮助我们来处理这个问题。 活动数据的来源是由Apple的运动协处理器M7(M7在iPhone5s开始使用后面更新依次是M8、M9...)来处理来自iPhone中各种传感器的运动数据。这涉及到iPhone中陀螺仪,加速度计和指南针的测量 具体可以维基百科上查看一下Apple motion coprocessors Apple运动协处理器

image.png

什么是运动协处理器 (M7 motion processor)?

2013年9月10日星期二,Apple发布了iPhone 5s。这款iPhone是第一款配备M7运动处理器的iPhone,这款芯片可以收集大量的移动数据,而不会让iPhone电池快速耗尽。从那时起,运动处理器不断更新,接着是型号M8,M9和M10、M11....... 运动处理器是一个独立的处理器,可以连续处理来自iPhone中各种传感器的运动数据。这涉及到iPhone中陀螺仪,加速度计和指南针的测量。该芯片确保这些过程不需要由主处理器(A7,A8,A9,A10等)完成,这意味着需要更少的能量。当iPhone放在口袋中时,iPhone会继续收集运动信息,例如,可以区分步行和骑自行车。 在iPhone和iPad中的运动处理器可以不被人注意地捕捉您的运动,而不会给电池带来压力 在Phone中的运动处理器可以测量您的所有动作,而且不会消耗太多电量。

协处理器对与运动数据带来的作用

运动处理器的巨大优势在于该芯片可以以节能的方式收集数据,因此应用程序无需通过耗能的GPS芯片单独进行。通过集中进行此数据收集,Apple可以防止各种应用程序不断跟踪您的位置和移动。您不必在后台运行多个运动和锻炼数据。 安装的应用程序可以访问运动处理器收集的所有信息,但只有您授予它的权限。大多数数据将通过HealthKit健康应用程序收集,和其他应用程序可以使用 这使得开发能够读取已经收集的数据的健身应用成为可能。例如,如果您安装了计步器应用程序,您将立即看到前几周的运动数据。

<CoreMotion/CoreMotion.h>

iOS核心运动传感器器框架陀螺仪、加速计、计步计(CMPedometer)... 实现微信摇一摇、运动计步、相机方向调整等等... 后面我可以吧计步补上 没有了解过的可以去Google一下 这些都有文章写过了我这里就不再啰嗦了 可以去看看别人的博客使用CoreMotion陀螺仪、加速计的使用

CMMotionActivityManager 运动活动管理类

我们可以先看一下她的头文件

//引入了CoreMotion框架下的运动活动和认证授权
#import <CoreMotion/CMMotionActivity.h>
#import <CoreMotion/CMAvailability.h>
#import <CoreMotion/CMAuthorization.h>

//是否处于活跃状态
+ (BOOL)isActivityAvailable;

//授权状态
+ (CMAuthorizationStatus)authorizationStatus NS_AVAILABLE(NA, 11_0) __WATCHOS_AVAILABLE(4_0);

//查询某一天startDate到某一天EndDate到活动数据
- (void)queryActivityStartingFromDate:(NSDate *)start
                               toDate:(NSDate *)end
                              toQueue:(NSOperationQueue *)queue
                          withHandler:(CMMotionActivityQueryHandler)handler;

//开始获取更新当前的活动状态 以CMMotionActivity对象包裹数据返回block
- (void)startActivityUpdatesToQueue:(NSOperationQueue *)queue
                        withHandler:(CMMotionActivityHandler)handler;

//停止数据获取状态更新
- (void)stopActivityUpdates;

乍一看API很简单用起来也很简单 你只需要去调用startActivityUpdatesToQueue 获取活动状态 返回你一个CMMotionActivity对象 这个对象的数据也很简洁 之前说过Apple是通过M系列运动协处理器内部收集和处理计算用户的运动活动状态 我们可以利用这些状态和查询记录结合我们的运动记录数据软件做一些更精准的区分和计算处理

@interface CMMotionActivity : CMLogItem

/*
 *  confidence
 *
 *  Discussion:
 *    A confidence estimate associated with this state.
 *
 *    CoreMotion always provides the most likely state.  Confidence represents
 *    how likely that the state is to be correct.
 */
@property(readonly, nonatomic) CMMotionActivityConfidence confidence;

/*
 *  startDate
 *
 *  Discussion:
 *    Time at which the activity started.
 */
@property(readonly, nonatomic) NSDate *startDate;

/*
 *  unknown
 *
 *  Discussion:
 *    True if there is no estimate of the current state.  This can happen if
 *    the device was turned off.
 */
@property(readonly, nonatomic) BOOL unknown;

/*
 *  stationary
 *
 *  Discussion:
 *    True if the device is not moving.
 */
@property(readonly, nonatomic) BOOL stationary;

/*
 *  walking
 *
 *  Discussion:
 *    True if the device is on a walking person.
 */
@property(readonly, nonatomic) BOOL walking;

/*
 *  running
 *
 *  Discussion:
 *    True if the device is on a running person.
 */
@property(readonly, nonatomic) BOOL running;

/*
 *  automotive
 *
 *  Discussion:
 *    True if the device is in a vehicle.
 */
@property(readonly, nonatomic) BOOL automotive;

/*
 *  cycling
 *
 *  Discussion:
 *    True if the device is on a bicycle.
 */
@property(readonly, nonatomic) BOOL cycling NS_AVAILABLE(NA, 8_0);

使用:用的人应该比较少 暂时先写着么多后面有机会再了解补充
self.motionActivityManager = [[CMMotionActivityManager alloc] init];
[self.motionActivityManager startActivityUpdatesToQueue:[[NSOperationQueue alloc] init] withHandler:^(CMMotionActivity *activity) {
            dispatch_async(dispatch_get_main_queue(), ^{
                
                if (activity.walking) {
                  //走路
                } else if (activity.running) {
                  //跑步
                } else if (activity.automotive) {
                  //汽车
                } else if (activity.stationary || activity.unknown) {
                    
                }else if (activity.cycling){
                  //骑行
                }

参考文章:Hoe werkt de motion processor in iPhone en iPad?