Odrive0.5.1-FOC电机控制 arm_cos_f32.cpp arm_sin_f32.cpp代码实现(一)

news2025/4/15 20:18:40

01 查表法

在 our_arm_cos_f32 函数中,查表(Look-Up Table, LUT) 的核心是 预计算的正弦值表 sinTable_f32,通过巧妙利用余弦与正弦的相位关系实现快速余弦计算。以下是详细解析:
1. 查的是什么表?
(1) 表内容
表名:sinTable_f32(通常是一个全局常量数组)
存储内容:对正弦函数一个周期([0, 2π])的离散采样值。
长度:FAST_MATH_TABLE_SIZE(例如256点,即每 2π/256 ≈ 0.0245 弧度一个采样点)。

(2) 表的生成
表通常在编译时预计算,类似以下代码:
#define FAST_MATH_TABLE_SIZE 256
const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1] = {
    0.0f, 0.024541f, 0.049068f, ..., 0.000000f  //多一项:FAST_MATH_TABLE_SIZE + 1 是为了安全访问 index+1。
};


02 离散采样值

在数学和信号处理中, 离散采样值(Discrete Sampled Values)指的是对连续信号(如正弦波、余弦波)在特定时间或位置间隔上采集的 有限个数据点。这些点是对原始连续信号的数字化近似,用于计算机或嵌入式系统处理。以下是详细解释:

1. 离散采样值的本质

  • 连续信号:如理想的余弦函数 cos⁡(x)cos(x) 是无限平滑且连续的(任意 xx 都有对应的值)。
  • 离散采样:在连续信号上按固定间隔(如每 ΔθΔθ 弧度)取点,生成有限个数值,形成一张查找表(LUT)
示例:对 cos⁡(x)cos( x) 在 [0,2π][0,2 π] 区间内采样256次,得到256个离散值。

2. 在代码中的具体体现

在  our_arm_cos_f32 函数中:
  • sinTable_f32就是一个离散采样表,存储了正弦函数在一个周期内的256(或其它数量)个等间隔采样值。
例如: FAST_MATH_TABLE_SIZE=256 时, Δ θ≈0.0245 弧度。

3. 为什么需要离散采样?

场景
连续函数
离散采样
计算方式
实时计算(如泰勒展开)
预计算后查表
速度
慢(需多次浮点运算)
快(直接内存访问)
资源占用
低(仅需代码)
高(需存储表)
适用场景
高精度通用计算
实时嵌入式系统(如电机控制)

4. 离散采样的工作原理

(1) 采样过程
假设对 sin⁡(x)采样,生成表:
import numpy as np
FAST_MATH_TABLE_SIZE = 8
x_samples = np.linspace(0, 2*np.pi, FAST_MATH_TABLE_SIZE, endpoint=False)
sin_table = np.sin(x_samples)  # 得到离散采样值:[0.0, 0.707, 1.0, 0.707, 0.0, -0.707, -1.0, -0.707]

(2) 查表示例
计算 cos⁡(0.785)cos(0.785)(即 π/4≈0.785 π/4≈0.785 弧度):
  1. 转换相位:cos⁡(0.785)=sin(0.785+π/2)=sin(2.356)
  2. 归一化索引:2.356/(2π)×8≈3.0 → 索引 3(第4个点)
  3. 查表:sin_table[3] = 0.707 → 结果 cos⁡(0.785)≈0.707

5. 插值的作用

离散采样会引入 量化误差,通过插值可提高精度:
  • 线性插值:
若索引非整数(如3.5),取相邻两点(索引3和4)的加权平均:
其中 α 是小数部分(如3.5的 α=0.5)。

6. 实际应用中的权衡

  • 表越大
:精度越高,但内存占用增加(如512点占2KB内存)。
  • 表越小
:速度更快,但误差增大(电机控制中典型用256点,误差±0.1%)。

总结

离散采样值是通过 预先存储连续函数的有限个关键点,用查表代替实时计算的一种优化技术。在嵌入式系统(如ODrive的电机控制)中,它实现了:
  1. 极速计算:比实时计算快10倍以上
  2. 可控精度:通过调整采样密度平衡性能
  3. 资源节省:共享正弦/余弦表,减少重复存储
这种方法的代价是 内存占用轻微的精度损失,但在实时性要求高的场景(如FOC算法)中至关重要!

03 代码实现 float32_t our_arm_cos_f32(float32_t x)

这段代码实现了一个优化的浮点余弦函数 (our_arm_cos_f32) ,主要用于实时嵌入式系统中的快速三角函数计算。以下是详细解析:
函数功能
  • 输入:弧度值 x(范围无限制,自动处理周期性)
  • 输出:cos(x) 的近似值(基于查表和线性插值)
  • 特点:
    • 比标准库 cosf() 更快(适合实时控制)
    • 牺牲少量精度换取速度
    • 依赖预计算的 sinTable_f32(正弦表)
float32_t our_arm_cos_f32(float32_t x)
{
  float32_t cosVal, fract, in;                   /* Temporary variables for input, output */
  uint16_t index;                                /* Index variable */
  float32_t a, b;                                /* Two nearest output values */
  int32_t n;
  float32_t findex;

 // 转换为正弦计算:cos(x) = sin(x + π/2)
  in = x * 0.159154943092f + 0.25f;  // 等价于 x/(2π) + 0.25

  //周期处理:利用三角函数的周期性,将输入映射到第一个周期 [0,1]。
  n = (int32_t) in;// 取整数部分
  if (in < 0.0f) //处理负数输入
  {
    n--;
  }

  /* Map input value to [0 1] */
  in = in - (float32_t) n; // 取小数部分

  //查表索引计算:
  findex = (float32_t)FAST_MATH_TABLE_SIZE * in; //FAST_MATH_TABLE_SIZE:正弦表长度(如256),决定精度和内存开销。
  index = (uint16_t)findex; //fract:插值权重(距离上一个表项的比例)。
  if (index >= FAST_MATH_TABLE_SIZE) {
    index = 0;
    findex -= (float32_t)FAST_MATH_TABLE_SIZE; // 小数部分用于插值
  }

  /* fractional value calculation */
  fract = findex - (float32_t) index;

  //线性插值:用相邻两个表项的值线性组合,减少查表误差。
  a = sinTable_f32[index]; // 当前表项值
  b = sinTable_f32[index+1]; // 下一表项值

  /* Linear interpolation process */
  cosVal = (1.0f-fract)*a + fract*b; // 加权平均

  /* Return the output value */
  return (cosVal);
}

/**
 * @} end of cos group
 */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2334314.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机械臂只有位置信息是否可以进行手眼标定?

平常我在做手眼标定时&#xff0c;一般都是通过OpenCV的cv::calibrateHandEye函数进行求解&#xff0c;需要输入多组不同的机械臂位姿。今天遇到了一款舵机机器人&#xff0c;只能获取位置&#xff0c;得不到姿态信息&#xff0c;想着那就把姿态都设为0&#xff0c;结果求不出来…

Python 数据分析01 环境搭建教程

Python 数据分析01 环境搭建教程 一、安装 Python 环境 访问 Python 官方网站 Python 官网&#xff0c;选择适合你操作系统的 Python 版本进行下载。下载完成后&#xff0c;运行安装程序。在安装过程中&#xff0c;建议选择“Add Python to PATH”选项&#xff0c;这样可以在…

使用 Visual Studio 2022 (VS2022) 编译 FreeCAD 1.0.0 的详细教程

一、环境准备 官方教程&#xff1a;在 Windows 上编译 - FreeCAD Documentation Windows 10/11&#xff08;推荐&#xff09; git vs2022 cmake 3.26.4 Doxygen1.12 二、获取源码与依赖 版本关系 打开Git Bash或CMD&#xff0c;执行以下命令 git clone --recurse-sub…

蓝桥杯单片机频率

long int Freq; unsigned int Timer_1000Ms; 加上 TMOD | 0x05; void Timer0Init(void) //0毫秒12.000MHz {AUXR & 0x7F; //定时器时钟12T模式TMOD & 0xF0; //设置定时器模式TMOD | 0x05;TL0 0x00; //设置定时初值TH0 0x00; //设置定时初值TF0 0; //清除TF0标…

遵循IEC 62304:构建安全可靠的医疗器械软件

目录 一、IEC 62304 标准概述 1. 标准定位与适用范围 二、核心内容与要求 1. 软件安全等级&#xff08;Software Safety Classification&#xff09; &#xff08;1&#xff09;分级标准 &#xff08;2&#xff09;分级依据 &#xff08;3&#xff09;验证要求 2. 软件…

互联网三高-数据库高并发之分库分表

1 数据库概述 1.1 数据库本身的瓶颈 ① 连接数 MySQL默认最大连接数为100&#xff0c;允许的最大连接数为16384 ② 单表海量数据查询性能 单表最好500w左右&#xff0c;最大警戒线800w ③ 单数据库并发压力问题 MySQL QPS&#xff1a;1500左右/秒 ④ 系统磁盘IO、CPU瓶颈 1.2 数…

UE5 在UE中创建骨骼动画

文章目录 创建动画的三种方式修改骨骼动画 创建动画的三种方式 方法一 打开一个已有的动画&#xff0c;左上角“创建资产/创建动画/参考姿势” 这将创建一个默认的A字形的骨骼&#xff0c;不建议这么做 方法二 打开一个已有的动画&#xff0c;左上角“创建资产/创建动画/当前…

[ctfshow web入门] web38

信息收集 过滤多了php和file if(isset($_GET[c])){$c $_GET[c];if(!preg_match("/flag|php|file/i", $c)){include($c);echo $flag;}}else{highlight_file(__FILE__); }解题 更多解法参考 [ctfshow web入门] web37 我们选个最简单的。但是因为php被过滤了我们改用…

汽车CAN总线采样点和采样率详解

写在前面 本篇文章主要讲解在汽车电子中CAN总线采样率的相关知识点,内容涉及CAN波特率、采样点、时间份额、同步跳转宽度以及采样率的计算。 若有相关问题,欢迎评论沟通,共同进步。(*^▽^*) 1、CAN波特率 CAN波特率常规分为250kbps和500kbps,本文章主要以这两个波特率为…

Maven error:Could not transfer artifact

问题描述 当项目从私有仓库下载依赖时&#xff0c;Maven 报错&#xff0c;无法从远程仓库下载指定的依赖包&#xff0c;错误信息如下&#xff1a; Could not transfer artifact com.ding.abcd:zabk-java:pom from/to releases (http://192.1122.101/repory/mavenleases/): 此…

pytorch 反向传播

文章目录 概念计算图自动求导的两种模式 自动求导-代码标量的反向传播非标量变量的反向传播将某些计算移动到计算图之外 概念 核心&#xff1a;链式法则 深度学习框架通过自动计算导数(自动微分)来加快求导。 实践中&#xff0c;根据涉及号的模型&#xff0c;系统会构建一个计…

WindowsPE文件格式入门06.手写最小PE

https://bpsend.net/thread-346-1-1.html 实现目标 实现目标&#xff1a;手写实现不大于 200 Byte大小的PE文件&#xff08;又名&#xff1a;畸形PE/变形PE&#xff09;&#xff0c;要求MessageBox弹框显示一个字符串。实现要点&#xff1a;充分利用空间&#xff0c;在保证遵…

并发编程--互斥锁与读写锁

并发编程–互斥锁与读写锁 文章目录 并发编程--互斥锁与读写锁1. 基本概念2. 互斥锁2.1 基本逻辑2.2 函数接口2.3示例代码12.4示例代码2 3. 读写锁3.1 基本逻辑3.2示例代码 1. 基本概念 互斥与同步是最基本的逻辑概念&#xff1a; 互斥指的是控制两个进度使之互相排斥&#x…

记录第一次使用H5的WebBluetooth完成蓝牙标签打印机的(踩坑)过程

第1步 首先第一步&#xff0c;调试环境必须是https的&#xff0c;由于浏览器的强制安全策略&#xff0c;本地可以采用localhost 第2步 然后&#xff0c;如果打印需要服务UUID&#xff08;Service UUID&#xff09; 和 特征UUID&#xff08;Characteristic UUID&#xff09;&…

【WRF理论第十七期】单向/双向嵌套机制(含namelist.input详细介绍)

WRF运行的单向/双向嵌套机制 准备工作&#xff1a;WRF运行的基本流程namelist.input的详细设置&time_control 设置&domain 嵌套结构&bdy_control 配置部分 namelist 其他注意事项Registry.EM 运行 ARW 嵌套双向嵌套&#xff08;two-way nesting&#xff09;Moving …

React 学习 JSX

APP根组件被index.js渲染到public下的index.html下 JS中写 HTML 代码 渲染列表 条件渲染 复杂条件渲染 事件绑定 传递自定义参数 button标签中写箭头函数引用的格式 自定义参数和事件本身对象都想要的情况

大模型论文:Language Models are Few-Shot Learners(GPT3)

大模型论文&#xff1a;Language Models are Few-Shot Learners(GPT3) 文章地址&#xff1a;https://proceedings.neurips.cc/paper_files/paper/2020/file/1457c0d6bfcb4967418bfb8ac142f64a-Paper.pdf 一、摘要 我们证明了&#xff0c;扩大语言模型的规模在任务无关的 few…

一周学会Pandas2 Python数据处理与分析-Pandas2数据导出

锋哥原创的Pandas2 Python数据处理与分析 视频教程&#xff1a; 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 任何原始格式的数据载入DataFrame后&#xff0c;都可以使用类似 DataFrame.to_csv()的方法输出到相应格式的文件或者…

深入解析栈式虚拟机与反向波兰表示法

1.1 什么是虚拟机&#xff1f; 虚拟机&#xff08;Virtual Machine, VM&#xff09;是一种软件实现的计算机系统&#xff0c;提供与物理计算机相类似的环境&#xff0c;但在软件层面运行。虚拟机的存在简化了跨平台兼容性、资源管理以及安全隔离等问题。 1.2 栈式虚拟机的架构…

学习MySQL的第八天

海到无边天作岸 山登绝顶我为峰 一、数据库的创建、修改与删除 1.1 引言 在经过前面七天对于MySQL基本知识的学习之后&#xff0c;现在我们从基本的语句命令开始进入综合性的语句的编写来实现特定的需求&#xff0c;从这里开始需要我们有一个宏观的思想&…