当前位置: 首页 > 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;…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...