当前位置: 首页 > news >正文

【IOS】惯性导航详解(包含角度、加速度、修正方式的api分析)

参考文献

iPhone的惯性导航,基于步态。https://www.docin.com/p-811792664.html
Inertial Odometry on Handheld Smartphones: https://arxiv.org/pdf/1703.00154.pdf
惯性导航项目相关代码:https://github.com/topics/inertial-navigation-systems
useracceleration苹果官方文档:https://developer.apple.com/documentation/coremotion/cmdevicemotion/1616149-useracceleration
手机导航https://ieeexplore.ieee.org/document/6139701

give me example that use iOS api to get accelarate in xyz.
I use it in swift. print the acceleration of x y z.
make the data collection part in a class. and show it in CintentView using the data in class.

using a filter in the acceleration data

时间间隔获取

在iOS中进行积分时,您可以选择使用motionManager.accelerometerUpdateInterval(motion.timestamp - lastLocation.timestamp)作为时间间隔。

motionManager.accelerometerUpdateInterval:

motionManager.accelerometerUpdateInterval是CMMotionManager类的属性,表示加速度计更新的时间间隔。
这个值是由您设置的,通常用于控制加速度计数据的采样率。
如果您使用加速度计数据进行积分,可以使用这个时间间隔来估计每个采样点的时间间隔。
例如,如果您的加速度计更新间隔为0.01秒,您可以将其作为每个采样点之间的时间间隔。
这种方法适用于简单的运动情况,但可能受到加速度计的噪声和误差的影响。

(motion.timestamp - lastLocation.timestamp):

motion.timestamp是CMDeviceMotion对象的属性,表示获取数据的时间戳。
lastLocation.timestamp是上一个位置更新的时间戳,如果您使用位置数据进行积分,可以使用这个时间戳来计算时间间隔。
这种方法适用于使用位置数据进行积分的情况,例如计算行进距离。
请注意,这种方法要求您同时获取位置数据,并且需要在每个位置更新时记录时间戳

加速度获取

class MileMeter {let motionManager = CMMotionManager()var referenceAttitude: CMAttitude?func startMotionUpdates() {// 检查设备是否支持加速度计和陀螺仪guard motionManager.isAccelerometerAvailable, motionManager.isGyroAvailable else {print("设备不支持加速度计或陀螺仪")return}// 设置更新频率motionManager.accelerometerUpdateInterval = 1.0 / 100.0 // 启动加速度计和陀螺仪更新motionManager.startAccelerometerUpdates()motionManager.startGyroUpdates()// 获取初始参考姿态if let referenceAttitude = motionManager.deviceMotion?.attitude {self.referenceAttitude = referenceAttitude}// 处理加速度计数据motionManager.startDeviceMotionUpdates(to: .main) { (motionData, error) inguard let motionData = motionData else {print("无法获取加速度计数据: \(error?.localizedDescription ?? "")")return}// 获取用户加速度,而不是混合// 校准加速度计数据
//            if let referenceAttitude = self.referenceAttitude {
//                motionData.acceleration = motionData.acceleration.applying(referenceAttitude.rotationMatrix)
//            }// 进行距离估计let acceleration = motionData.userAcceleration   //用户对设备施加的加速度,而不包括重力的影响// 在此处可以使用估计的速度和位移数据进行进一步的处理print("加速度: \(acceleration)")}}func stopMotionUpdates() {motionManager.stopAccelerometerUpdates()motionManager.stopGyroUpdates()motionManager.stopDeviceMotionUpdates()}
}
在这里插入代码片

角度获取

陀螺仪有两种:var attitude: CMAttitude { get }和var rotationRate: CMRotationRate { get } :

CMAttitude:绝对角度

CMAttitude represents the device’s orientation or attitude in space.
It provides information about the device’s pitch, roll, and yaw angles.
The attitude is expressed as a quaternion, which is a mathematical representation of orientation.
You can access the attitude using the attitude property of a CMMotionManager object.
Example usage: let attitude = motionManager.deviceMotion?.attitude

CMRotationRate:旋转角度

CMRotationRate represents the device’s rotation rate or angular velocity.
It provides information about the device’s rotation speed around each axis (x, y, and z).
The rotation rate is expressed in radians per second.
You can access the rotation rate using the rotationRate property of a CMMotionManager object.
Example usage: let rotationRate = motionManager.deviceMotion?.rotationRate

校准

坐标系变换

            // 校准加速度计数据
//            if let referenceAttitude = self.referenceAttitude {
//                motionData.acceleration = motionData.acceleration.applying(referenceAttitude.rotationMatrix)
//            }

低通滤波器

func lowPassFilter(_ x: Double) -> Double {if abs(x) < 0.01 {return 0} else {return x}
}

卡尔曼滤波

import Foundationstruct KalmanFilter {var state: Doublevar covariance: Doublelet processNoise: Doublelet measurementNoise: Doublemutating func update(measurement: Double) {// Prediction steplet predictedState = statelet predictedCovariance = covariance + processNoise// Update steplet kalmanGain = predictedCovariance / (predictedCovariance + measurementNoise)state = predictedState + kalmanGain * (measurement - predictedState)covariance = (1 - kalmanGain) * predictedCovariance}
}// Example usage
var filter = KalmanFilter(state: 0, covariance: 1, processNoise: 0.1, measurementNoise: 1)let measurements = [1.2, 1.4, 1.6, 1.8, 2.0]for measurement in measurements {filter.update(measurement: measurement)print("Filtered measurement: \(filter.state)")
}

最终代码

class DistanceCalculator {private let motionManager = CMMotionManager()@Published var totalDistance: Double = 0.0@Published var lastLocation: CMDeviceMotion?@Published var ax: Double = 0.0 // 距离@Published var ay: Double = 0.0@Published var az: Double = 0.0@Published var acc_ax: Double = 0.0 // 加速度@Published var acc_ay: Double = 0.0@Published var acc_az: Double = 0.0@Published var m_acc_ax: Double = 0.0 // 修正后的加速度@Published var m_acc_ay: Double = 0.0@Published var m_acc_az: Double = 0.0@Published var m_dis_ax: Double = 0.0 // 修正后的路程@Published var m_dis_ay: Double = 0.0@Published var m_dis_az: Double = 0.0@Published var m_totalDistance: Double = 0.0init() {// 检查设备是否支持运动数据的获取guard motionManager.isDeviceMotionAvailable else {print("设备不支持运动数据")return}// 设置更新间隔 官方推荐100hz以上motionManager.deviceMotionUpdateInterval = 0.01// 开始获取设备运动数据motionManager.startDeviceMotionUpdates(to: .main) { [weak self] (motion, error) inguard let motion = motion else {return}if let lastLocation = self?.lastLocation {self?.acc_ax = motion.userAcceleration.xself?.acc_ay = motion.userAcceleration.yself?.acc_az = motion.userAcceleration.zlet velocity_x = motion.userAcceleration.x * (motion.timestamp - lastLocation.timestamp)let velocity_y = motion.userAcceleration.y * (motion.timestamp - lastLocation.timestamp)let velocity_z = motion.userAcceleration.z * (motion.timestamp - lastLocation.timestamp)self?.ax = velocity_xself?.ay += velocity_yself?.az += velocity_z// sqrt 有问题?变成nanself?.totalDistance += abs(velocity_x*velocity_x)
//                self?.totalDistance += sqrt(velocity_x*velocity_x + velocity_y+velocity_y + velocity_z*velocity_z)print("欧式距离里程:\(self?.totalDistance ?? 0)") //如果可选类型的值为nil,空合运算符会返回它的右侧的默认值(在这里是0)print("加速度:\(motion.userAcceleration)")// 使用低通滤波器let _m_acc_x = lowPassFilter(motion.userAcceleration.x)self?.m_acc_ax = _m_acc_xlet _m_acc_y = lowPassFilter(motion.userAcceleration.y)self?.m_acc_ay = _m_acc_ylet _m_acc_z = lowPassFilter(motion.userAcceleration.z)self?.m_acc_az = _m_acc_zlet m_velocity_x = _m_acc_x * (motion.timestamp - lastLocation.timestamp)let m_velocity_y = _m_acc_y * (motion.timestamp - lastLocation.timestamp)let m_velocity_z = _m_acc_z * (motion.timestamp - lastLocation.timestamp)self?.m_dis_ax = m_velocity_xself?.m_dis_ay += m_velocity_yself?.m_dis_az += m_velocity_zself?.m_totalDistance += abs(m_velocity_x)}self?.lastLocation = motion}}
}

相关文章:

【IOS】惯性导航详解(包含角度、加速度、修正方式的api分析)

参考文献 iPhone的惯性导航&#xff0c;基于步态。https://www.docin.com/p-811792664.html Inertial Odometry on Handheld Smartphones: https://arxiv.org/pdf/1703.00154.pdf 惯性导航项目相关代码&#xff1a;https://github.com/topics/inertial-navigation-systems use…...

Self-Attention

前置知识&#xff1a;RNN&#xff0c;Attention机制 在一般任务的Encoder-Decoder框架中&#xff0c;输入Source和输出Target内容是不一样的&#xff0c;比如对于英-中机器翻译来说&#xff0c;Source是英文句子&#xff0c;Target是对应的翻译出的中文句子&#xff0c;Attent…...

网络协议与攻击模拟_04ICMP协议与ICMP重定向

ICMP协议是网络层协议&#xff0c; 利用ICMP协议可以实现网络中监听服务和拒绝服务&#xff0c;如 ICMP重定向的攻击。 一、ICMP基本概念 1、ICMP协议 ICMP是Internet控制报文协议&#xff0c;用于在IP主机、路由器之间传递控制消息&#xff0c;控制消息指网络通不通、主机是…...

pytest-mock 数据模拟

文章目录 mock 测试unittest.mockMock类MagicMock类patch装饰器create_autospec函数断言的方法 pytest-mock 使用 mock 测试 在单元测试时&#xff0c;有些数据需要依赖其他服务或者不好获取到&#xff0c;此时需要使用mock来模拟对应的函数、对象等。 mock模拟数据的python…...

单片机原理及应用:定时器/计数器综合应用

本文是《单片机原理及应用》专栏中的最后一篇文章&#xff0c;笔者以编译器的安装配置——51单片机简介——LED和数码管外设——开关和按键控制功能切换——外部中断系统——定时器与计数器为知识大纲&#xff0c;介绍了C语言编程控制51单片机的入门教程。作为收尾&#xff0c;…...

R语言【paleobioDB】——pbdb_intervals():通过参数选择,返回多个地层年代段的基本信息

Package paleobioDB version 0.7.0 paleobioDB 包在2020年已经停止更新&#xff0c;该包依赖PBDB v1 API。 可以选择在Index of /src/contrib/Archive/paleobioDB (r-project.org)下载安装包后&#xff0c;执行本地安装。 Usage pbdb_interval (id, ...) Arguments 参数【..…...

阅读笔记lv.1

阅读笔记 sql中各种 count结论不同存储引擎计算方式区别count() 类型 责任链模式常见场景例子&#xff08;闯关游戏&#xff09; sql中各种 count 结论 innodb count(*) ≈ count(1) > count(主键id) > count(普通索引列) > count(未加索引列)myisam 有专门字段记录…...

小鼠的滚动疲劳仪-转棒实验|ZL-200C小鼠转棒疲劳仪

转棒实验|ZL-200C小鼠转棒疲劳仪用于检测啮齿类动物的运动功能。通过测量动物在滚筒上行走的持续时间&#xff0c;来评定**神经系统*病或损坏以及药物对运动协调功能和疲劳的影响。 疲劳实验中&#xff0c;让小鼠在不停转动的棒上运动&#xff0c;肌肉会很快进入疲劳状态&#…...

平衡搜索二叉树(AVL树)

目录 前言 一、AVL树的概念 二、AVL树的定义 三、AVL树的插入 四、AVL树的旋转 4.1、右单旋 4.2、左单旋 4.3、左右双旋 4.4、右左双旋 五、AVL树的验证 5.1、 验证其为二叉搜索树 5.2、 验证其为平衡树 六、AVL树的性能 前言 二叉搜索树虽可以缩短查找的效率&…...

2024年1月12日学习总结

学习目标 完成集中学习的readme 完成联邦学习的代码编写 边学习边总结 学习内容 Introduction to Early Stopping 1、Overfitting 过拟合是所有机器学习&#xff0c;深度学习中可能出现的一个比较严重的问题。具体表现就是&#xff1a;你的模型在训练集上处理的效果非常好&…...

PCL 使用克拉默法则进行四点定球(C++详细过程版)

目录 一、算法原理二、代码实现三、计算结果本文由CSDN点云侠原创,PCL 使用克拉默法则进行四点定球(C++详细过程版),爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT生成的文章。 一、算法原理 已知空间内不共面的四个点,设其坐标为 A (…...

前端导致浏览器奔溃原因分析

内存泄漏 内存泄漏&#xff08;Memory Leak&#xff09;是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放&#xff0c;造成系统内存的浪费&#xff0c;导致程序运行速度减慢甚至系统崩溃等严重后果。&#xff08;程序某个未使用的变量或者方法&#xff0c;长期占…...

力扣:209.长度最小的子数组

1.题目分析&#xff1a; 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0 。 示例 …...

常见类型的yaml文件如何编写?--kind: Service

基本说明 在 Kubernetes 中&#xff0c;Service 是一种抽象的方式&#xff0c;用于定义一组 Pod 的访问方式和网络服务。Service 提供了一个稳定的网络端点&#xff08;Endpoint&#xff09;&#xff0c;使得其他服务或外部用户可以通过 Service 来访问被管理的 Pod。 负载均…...

linux环境下安装postgresql

PostgreSQL: Linux downloads (Red Hat family)postgresql官网 PostgreSQL: Linux downloads (Red Hat family) 环境&#xff1a; centos7 postgresql14 选择版本 执行启动命令 配置远程连接文件 vi /var/lib/pqsql/14/data/postgresql.conf 这里将listen_addresses值由lo…...

专业课145+合肥工业大学833信号分析与处理考研经验合工大电子信息通信

今年专业课145也是考研科目中最满意的一门&#xff0c;其他基本相对平平&#xff0c;所以这里我总结一下自己的专业课合肥工业大学833信号分析与处理的复习经验。 我所用的教材是郑君里的《信号与系统》&#xff08;第三版&#xff09;和高西全、丁玉美的《数字信号处理》&…...

FreeRtos Queue (一)

本篇主要讲队列的数据结构和初始化 一、队列的数据结构 二、队列初始化完是什么样子的 队列初始化的函数调用关系&#xff1a;xQueueGenericCreate->prvInitialiseNewQueue->xQueueGenericReset 所以&#xff0c;最终初始化完的队列是这样的 假设申请了4个消息体&…...

深入理解 Hadoop (五)YARN核心工作机制浅析

概述 YARN 的核心设计理念是 服务化&#xff08;Service&#xff09; 和 事件驱动&#xff08;Event EventHandler&#xff09;。服务化 和 事件驱动 软件设计思想的引入&#xff0c;使得 YARN 具有低耦合、高内聚的特点&#xff0c;各个模块只需完成各自功能&#xff0c;而模…...

优化 - 重构一次Mysql导致服务器的OOM

概述 优化了一次前后端处理不当导致的CPU的一次爆机行为&#xff0c;当然&#xff0c;这和服务器的配置低也有着密不可分的关系&#xff0c;简单的逻辑学告诉我们&#xff0c;要找到真正的问题&#xff0c;进行解决&#xff0c;CPU爆机的关键点在于前后端两个方面&#xff0c;…...

【光波电子学】基于MATLAB的多模光纤模场分布的仿真分析

基于MATLAB的多模光纤模场分布的仿真分析 一、引言 &#xff08;1&#xff09;多模光纤的概念 多模光纤&#xff08;MMF&#xff09;是一种具有较大纤芯直径的光纤结构&#xff0c;其核心直径通常在10-50微米范围内。与单模光纤&#xff08;SMF&#xff09;相比&#xff0c;…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...