基于单片机的角度传感器线性化

基于单片机的角度传感器线性化

由Dominik Geisler,
雷竞技竞猜下载快板微系统公司有限责任公司

下载PDF版本

介绍

磁角传感器通常是快速,可靠,非接触式测量系统的良好选择,特别是在脏环境中,光学编码器可能不具有良好拟合。

雷竞技竞猜下载Allegro MicroSystems,LLC,为不同的应用提供了多种角度传感器IC [1]。雷竞技最新网址这些传感器IC可以测量径向磁化编码器磁体的角度
在侧轴或端轴安装,如图1所示。

图1:侧轴测量角(左)和轴尾测量角(右)
图1:侧轴测量角(左)和
轴端角度测量(右)

测量误差

所有的Allegro角度传感器ic在工厂的最终测试中使用均匀磁场进行校准。这样做是为了尽量减少传感器的固有误差。然而,特别是在侧轴应用中,传感器传感器处的磁场角度与要测量的轴的机械雷竞技最新网址角度不相同。造成这种差异的主要原因是编码器磁铁发出的磁场的形状。

机械和磁场角之间的其他不匹配源是磁体未对准,磁体缺陷,剩余传感器不准确和漂移,以及铁磁材料的假期。

由此可以得出结论,所有系统,尤其是侧轴系统,都存在编码器角与测量角不匹配的问题。在图2中可以看到一个典型的侧轴应用的传递曲线。

图2:在侧轴设置中模拟传感器读数与编码器角度
图2:模拟传感器读取与编码器
在侧轴设置的角度

这些测量误差称为非线性,可以通过线性化过程进行补偿。

线性化

一些Allegro传感器ic,如A1335,AAS33001,而且AAS33051具有允许输入数据线性化的嵌入式逻辑。然而,其他传感器集成电路,如A1330A1333A1337A1338,或A1339,芯片上没有此功能。如果使用没有内置功能来线性化数据的传感器IC,则可能需要使用微控制器进行外部线性化,以在特定应用中达到所需的精度。

此应用程序注意将:

  • 解释线性化的基本原理
  • 演示如何处理实际测量数据以计算修正数据
  • 详细介绍了校正数据的三种存储方法
  • 详细信息如何应用更正
  • 比较所提出的方法的准确性

定义

编码器角度

通过精确的高分辨率外部编码器报告的角度。

传感器的角度

角度传感器IC报告的角度。

角误差

角度误差是磁体的实际位置与角度传感器IC测量到的磁体位置之间的差值,计算方法是用传感器角度减去编码器角度:

误差= (α_sensor - α _编码器)。

但是,如果传感器角度为359°,编码器角度为0°,则误差应为-1°,而不是+359°。为了将误差包绕在±180°之外,可以使用模算子:

error = mod [(α_sensor - α_encoder)+ 180,360] - 180。

图3给出了侧轴应用中角度误差的样图。

最大绝对角度误差

最大绝对角度误差是在整个旋转过程中,角度传感器IC测量到的磁体实际位置与磁体位置之间的最大绝对差。

在图3中,编码器角度为56°时,最大角度误差为21.46°。

图3:与传感器输出图相比的角度误差
图3:与传感器输出图相比的角度误差

线性化的目标

线性化的目标是确定、存储和应用一个函数,使测量的传感器角度误差相对于编码器角度值最小。这将使测量的传感器角度和实际编码器角度之间的差异最小化。

图4:线性化的目标:从传感器角度到编码器角度
图4:线性化的目标:从传感器角度到编码器角度

这种目标可以以不同的方式实现。在此应用中将详细介绍三种常见技术。雷竞技最新网址

呈现的技术取决于单个校准相(通常在客户端的线末端测试中执行),之后应用固定校正功能。

线性化的先决条件

使用这里详细介绍的技术进行线性化的先决条件如下:

  • 在生产过程中,需要将已知的角度应用到传感器系统中。
  • 在生产过程中,需要读出传感器角度。
  • 要线性化的系统需要一个微控制器,在生产过程中写入线性化信息,并且在应用程序中执行线性化。

线性化的极限

使用这里描述的方法进行线性化有一些限制:

  • 传感器噪声不会被线性化校正。
  • 校准后传感器的任何漂移都不会被校正。
  • 校准后的机械系统的变化将不会被线性化校正。一个常见的例子是磁铁的位置由于振动和扭矩的动态变化
  • 如果在校准期间的输入位置不准确地记录,则校正的准确性将以相同的方式受到限制。

线性化方法

1.数据记录

为了产生线性化所需的数据,测量传感器输出[y0y……n]以已知的编码器角度[X0x……n].这些编码器的角不需要等距,尽管通常使用等距角。

值的记录如图5所示。

图5:数据记录
图5:数据记录

2.坐标转换为传感器角度由于校正函数必须基于传感器数据工作,因此记录的数据点需要转换为传感器坐标系统。

这意味着不需要将传感器角度表示为实角度的函数,而需要将实角度表示为传感器角度的函数。因此,传感器角度[y '0...... y'n],对应的编码器角[x '0…x 'n需要确定。要做到这一点,需要通过数据点应用匹配。这可以通过样条插值来实现,如图6所示。


图6:坐标转换为传感器角度
图6:坐标转换为传感器角度

3.修正曲线计算

为了创建一个将传感器测得的角度转换为编码器角度的函数,需要计算校正值。这些校正值计算为[C0c…n] = [x '0…x 'n] - [y'0...... y'n].

图7:校正值计算
图7:校正值计算

最后,这些值描述了一条校正曲线c,该曲线给出了校正值与传感器角度的函数关系。图8显示了曲线c /传感器角度的曲线。

图8:修正曲线
图8:修正曲线

4.修正曲线在数据中的应用

为了对被测传感器数据点进行校正,需要根据校正曲线C计算传感器数据点Y的校正值C

图9修正曲线C的值C = f(Y
图9修正曲线C的值C = f(Y

然后将正确的角度值x确定为x = y + c.这是图形的图10中表示的。

图10:使用
图10:使用修正曲线求值X = Y + C

校正曲线存储选项

在本文档中,将研究三种存储校正曲线的方法。还有许多其他的可能性。然而,这里提出的方法满足广泛的需求,同时需要适度的实现和计算工作。其中,A1335、AAS33001和AAS33051硬件实现了线性插值。谐波校正只在A1335中实现。

谐波校正

校正曲线通常具有周期性的形状。通过将其解剖到谐波并存储谐波的相位和幅度,可以进行紧凑的存储。这显然是这种情况,例如,在图3中。

谐波校正的优点是只需要存储很少的参数来校正传感器数据。缺点是单片机需要进行余弦计算,限制了速度。

线性插值

作为第二种方法,可以使用分段线性函数近似校正曲线。

该方法比谐波校正需要更多的存储参数,但计算时间更短。计算方法的代码大小也更小。

查找表

存储修正曲线的第三种方法是使用查找表。这需要一个存储校正参数的大表,但由于校正值可以直接从查找表中获取,因此不需要插入步骤。

这使线性化代码保持非常简单和快速。

校正方法比较

图11和图12显示了将修正曲线存储为调和近似、分段线性插值和查找表时,图3中的数据所获得的预期输出之间的比较。

图11:修正曲线(黑色)和三种近似方法
图11:修正曲线(黑色)和三种近似方法
图12:图11的放大率突出显示差异
图12:图11的放大率突出显示差异

校正曲线确定

本文档中的实现是在MathWorks Matlab™中实现的。由于这是商业软件,许可费用适用于使用它,这可能会阻碍在生产环境中使用。Matlab的免费软件替代品是GNU Octave,可免费提供GNU GPLv3许可证。

本文档中使用的所有函数均由MATLAB和GNU Octave支持。

在这些脚本中,假定传感器角度随编码器角度的增加而增加。如果不是这样,则必须在进行其他处理步骤之前将传感器角度倒置。

传感器输出捕获

用户必须捕获传感器角度输出的初始数据。这是通过设置某些已知的角度来实现的,在本文档中称为编码器角度。然后记录传感器角度。传感器角度是由传感器测量的角度。记录的点数可以比线性修正点数多或少。记录更多的分数,如果
可能,总是更好。

通常,记录至少16个数据点就足以在轴上的情况下获得良好的校正性能。在离轴情况下,建议至少32点。

使用N个段(例如32)应用分段线性校正,记录至少n个点将充分利用可用的校正点。录制大约2×n点导致几乎理想的性能。表1给出了记录点的真实例子。

表1:记录的编码器和输出角度

图13:来自表1的数据图
图13:来自表1的数据图

传感器输出溢出清除

传感器数据在100°输入角左右的跳跃将给下一步的处理步骤带来困难。它被移除通过添加360°的所有值后,跳转到负方向。同时,数据的均值应在±180°以内,以避免后期处理中出现其他问题。这可以通过以下几行来实现:

% %预处理
sensor_data_2 = sensor_data (:);
angle_input = angle_input (:);
%检查是否连续上升,最多有一个溢出
If any(diff(sensor_data_2) == 0)
误差(“传感器数据必须单调递增”)
ELESEIF SUM(差异(SENSOR_DATA_2)<0)<= 1
%上升角度数据具有零或一个溢出,溢出将被纠正
Sensor_data_2 = Sensor_data_2 (:) + 360*cumsum([false;diff (sensor_
Data_2 (:) < 0]);
elsefif sum(diff(sensor_data_2)<0)> 1
错误('只允许一个数据减少作为溢出')
结束
%正确地包裹传感器数据
rollovercorrection = round((平均值(sensor_data_2) - 180)/ 360)* 360;
sensor_data_2 = sensor_data_2 - 翻转粗描;

结果值如表2所示。

表2:拆除溢出后的编码器和输出角度

图14:来自表2的数据图
图14:来自表2的数据图

数据复制

最后,需要根据传感器角度从0°到360°进行校正。为了避免任何边缘效应,传感器数据将被复制三次。这避免了所有情况下的边缘效应,因为它提供了总是安全地从传感器角度360°到720°提取值的可能性。

%延长传感器数据
sensor_data_ext = [sensor_data_2 (:);sensor_data_2 (:) + 360;......
sensor_data_2(:) + 720];
%扩展输入数据
discle_input_ext = [Anight_Input(:);Angle_Input(:) + 360;......
Angle_Input(:) + 720];

投射到传感器数据网格上

在接下来的步骤中,编码器的角度输入对应于传感器在360°和720°之间的输出(在下面的代码中称为“intermediategrid”)。这是通过4096个步骤完成的,因为中间步骤的高分辨率有利于最终输出质量。

使用样条将数据从有序的输入网格中移动
%到有序输出网格上:
Ordered_output_grid = 0:(360/4096):( 360-360 / 4096);
intermediateGrid = Ordered_output_grid + 360;
投影=样条(sensor_data_ext, angle_input_ext,…)
中间奖金);

该步骤在图15中以图形方式示出。

图15:找到编码器角度(“投影”)作为固定网格传感器角度的投影(“中间奖金”)
图15:找到编码器角度(“投影”)作为固定网格传感器角度的投影(“中间奖金”)

角度编码器的值与传感器输出的差值就是校正曲线,可以用计算出的匹配编码器角减去固定网格传感器角来计算。

%计算所需修正的数据:
Correction_curve =投影- intermediategrid;
校正_curve = correnction_curve(:);
校正曲线如图16所示。

图16:我们示例的修正曲线
图16:我们示例的修正曲线

可以做一个简短的检查,看看这条曲线是否正确。由表1可知,当传感器角度为137.46°时,编码器角度为213.75°。由图16的校正曲线可知,在传感器角度为137.5°时,需要进行+76.29°的校正。137.46 + 76.26 = 213.72°≅213.75°,计算得到的修正曲线是适用的。

下一步,需要高效地存储修正曲线,以便任意输入都能计算出修正值。这将使用谐波近似、线性插值和查找表来完成。

谐波近似

概念

每个重复信号可以分为其构成频率。

在每次旋转之后重复校正曲线,使得它可以完全描述为一组频率。重复校正曲线可以使其更清楚地校正校正曲线中的各种频率。

图17重复校正曲线包含不同频率
图17重复校正曲线包含不同频率

谐波近似的优点是可以仅使用少数参数来描述校正曲线。但是,余弦的计算也可能是
某些平台或应用程序运行缓慢。雷竞技最新网址

执行

使用傅里叶变换,可以确定校正曲线的每个组成频率的相位和幅值。修正曲线的4096个数据点得到了4096点的FFT结果。然而,大多数能量是在较低的频率。下面只提取了校正曲线的偏移值和前16次谐波:

%%傅里叶变换校正后,丢弃16后的值
%和按表的长度缩放能量
fft_table = fft(校正_curve)/长度(介入);
offset_correction = abs(fft_table(1));
correction_pha =角(fft_table (17));
correction_amp = 2 * abs (fft_table (17));
这产生了89.82°的偏移校正,谐波的振幅如下:

图18:校正曲线的前16个谐波的幅度
图18:校正曲线的前16个谐波的幅度

下面发现完整的结果表最多可以找到第16次谐波:

表3:谐波幅度和相位数据

应用程序

可以找到nth谐波的校正值,如:

corr(n)=校正(n)×cos [n×sensor_angle + corrcion_pha(n)],

其中0谐波偏移校正,也应考虑到。实际应用,以下代码会导致四个谐波。随着余弦功能预期弧度
作为输入,角度值被转换为弧度。存储在表中的校正以学位为程度,因为傅里叶变换的输入处于度数。

%%应用四个谐波的谐波校正
Restored_signal_4_harmonics = mod(sensor_data +(…
offset_correction + ...
校正_PAM(1)* COS(1 *(SENSOR_DATA / 360 * 2 * PI)+ CORRECION_PHA(1))+ ...
校正_PAM(2)* COS(2 *(SENSOR_DATA / 360 * 2 * PI)+ CORRECING_PHA(2))+ ...
(3*(sensor_data/360*2*pi) + correction_pha(3)) +…
校正_PAM(4)* COS(4 *(SENSOR_DATA / 360 * 2 * PI)+ CORRECION_PHA(4))...
), 360);

此代码执行所有传感器角度的校正sensor_data。

在循环中实现这个修正将减少微控制器实现的代码大小,但出于代码清晰度的原因,这里没有使用。

图19显示了对表1中记录的16个角度进行线性化后剩下的输出误差。剩下的误差通过增加更多的谐波来减少。在选择补偿谐波时,最好按幅值减小的顺序选择谐波。例如,如果谐波1、2和4的振幅较大,而谐波3的振幅较小,那么修正谐波1、2和4的结果会比修正谐波1、2和3的结果更好。

图19:本文档示例中,随着谐波量的增加,线性化后的剩余角度误差
图19:本文档示例中,随着谐波量的增加,线性化后的剩余角度误差

线性插值

概念

校正曲线可以通过分段线性函数近似。对于此功能,需要将支持点存储为传感器坐标对和校正值。

在图8中,这些对将是[(y'0c0)……(y 'ncn)]。在支撑点之间进行线性插值。在角度传感器线性化应用中,使用等距传感器角度网格是有用的。雷竞技最新网址这样,传感器的角度值[y'0...... y'n]不需要存储,线性校正的实现变得更容易。例如,可以存储32个校正值,然后应用于0°、11.25°、22.50°等传感器角度。

要存储的点可以通过不同的标准来确定。

确定它们的最简单方法是通过在所述传感器角处选择校正曲线上的点,这将被称为“曲线上”线性插值。然而,也可以针对存储的校正曲线的最小二乘误差进行优化。这将被称为“最小二乘”线性插值。其他优化策略是可能的,但不会是
本文档中描述。

图20:使用由曲线和最小二乘法测定的参数的Lige校正曲线对线性插值的比较
图20:理想校正曲线与
由确定参数的线性插值
曲线上和最小二乘法

对于相同的最大误差,最小二乘法减少了约50%所需的存储参数量,对单个测量异常值不太敏感。因此,这里将使用至少方法来确定线性插值支持点。

执行

修正曲线需要用分段线性函数来近似。由于支撑点的选择应采用最小二乘误差的方式,即支撑点前后的数据
点也有助于确定其最终价值。

这给第一点和最后一点带来了问题。第一个支撑点在0°只在该点右侧有一条修正曲线,所以接近360°的数据不考虑。为了避免这个问题,修正曲线将重复三次,并计算该曲线的分段线性最小二乘近似。然后,只使用中心部分来选择所使用的参数。这个概念如图21所示。

图21:重复三次的校正曲线,最小二乘拟合,使用中心点
图21:重复三次的校正曲线,最小二乘拟合,使用中心点

适合计算

复制修正曲线并计算拟合的代码如下:

校正曲线的%%分段线性近似
lin_sup_nodes = 32;
%重复校正表三次以避免
修正计算的%角效果。
triple_correction_curve = repmat(校正_curve,3,1);
triple_correction_curve结束(+ 1)= triple_correction_curve (1);
%对输入的角度做同样的处理
triple_output_grid = 0 (360/4096): (3 * 360);
计算支撑点
XI_lin_triple = linspace (0 3 * 360 lin_sup_nodes * 3 + 1);
YI_lin_triple = lsq_lut_piecewise(triple_output_grid(:),…
triple_correction_curve,xi_lin_triple);
%仅使用中心点来计算校正:
yi_lin = yi_lin_triple(lin_sup_nodes + 1:2 * lin_sup_nodes + 1);
xi_lin = linspace(0,360,lin_sup_nodes + 1);

LSQ_LUT_PICEWISE功能在附录A中重印。

32点线性插值的校正参数列表如下:

表4:线性插值参数


注意,360°的值也添加了,尽管它与0°的值是相同的。这是需要校正的角度之间的348.75°和360°可能不使用技巧。

应用程序

在MATLAB中,使用内置的1D插值函数可以直接应用校正:

%%执行线性插值
Restored_linear_signal = mod(sensor_data(:) +…
interp1 (XI_lin、YI_lin sensor_data(:),“线性”),360);
同样的功能也可以如下实现,以演示如何在微控制器中执行计算:
%%手动执行线性插值
restored_linear_signal_man = 0(长度(sensor_data), 1);
lin_sup_res = 360 / lin_sup_nodes;
对于i = 1:长度(sensor_data)
在传感器角度之前获得表条目的索引
baseangle_idx =楼层(sensor_data(i)/ lin_sup_res);
baseangle = baseangle_idx * lin_sup_res;
%获得了我们经过表格条目的程度
Offsetangle = sensor_data(i) -基角;
%修正为基数+
纠正val = yi_lin(baseangle_idx + 1)+ ...
((yi_lin(baseangle_idx + 2) - ...
yi_lin(baseangle_idx + 1))* offstangle / lin_sup_res);
Restored_linear_signal_man(i)= mod(sensor_data(i)+ ...
correctionval, 360);
结束

这段代码对sensor_data中的所有传感器角度进行了校正。

在微控制器实现中,有效地使用位移位和位掩码可以消除除法操作的需要。模运算可以被有意使用的整数溢出所替代。但是,仍然需要减法,加法和乘法。

在我们的例子中,线性化后剩余的输出误差如下所示,超过了16个记录的角度。剩下的误差通过增加更多的线性化点来减小。

图22:在本文档示例中,随着线性支持节点数量的增加,线性化后的剩余角度误差
图22:在本文档示例中,随着线性支持节点数量的增加,线性化后的剩余角度误差

查找表

概念

对于校正曲线的线性插值,需要在支撑点之间插入。这需要一些数学操作,这可能经常需要太长。

可以直接使用最接近的校正值,而不是在两个支持值之间进行插值。此方法在本文档中称为查找表。

每一组角度的修正值,或称箱,将被选择为该箱内修正曲线值的平均值。这将确保校正曲线的最小均方根误差
表示。其他的策略,如在各自的容器的最小和最大校正之间选择平均值,是可能的,但在本文档中将不使用。

使用查找表需要存储大量值以达到可接受的性能。通常需要约256个值。值的数量不需要是两个的力量;但是,固定点代码中的微控制器实现将受益于两个表条目的两个功率。

执行

首先,需要定义宾纳界限。然后,可以确定该边界内部的校正曲线值的平均值。

%%查表近似修正曲线
number_table_entries = 64;
%选择仓边界
xi_binlimits = linspace(0,360,number_table_entries + 1);
%使用函数bin_lut找到每个垃圾箱的点的平均值:
yi_lut = bin_mean(somented_output_grid(:),...
correction_curve (:), XI_binlimits (:));

函数bin_lut在附录B中打印。应当注意,校正曲线值完全在两个箱之间的边界上的校正曲线值包括在较大的值的平均值中,并且被排除在仓中的较小值。

例如,对于64个条目,180°角的校正曲线数据用于箱180°的值185.625°,并且不用于174.375°10°180°。

图23中可以看到64个表条目的校正曲线。

图23:使用64个垃圾箱查找表表示校正曲线
图23:查找表表示
使用64个垃圾箱的校正曲线

可以在表5中找到包含64个条目的结果表。

表5:64个条目的查找表

应用程序

在MATLAB中,使用内置的1D插值函数先前邻居值,校正的应用很简单:

Restored_lut_signal = mod(sensor_data(:) +…
interp1 (XI_binlimits (1: end-1),……
YI_lut sensor_data(:),‘以前’,‘extrap’),360);

同样的功能也可以实现,如下所示
如何在微控制器中执行计算:
number_table_entries = 64;
Restored_lut_signal_man = zeros(长度(sensor_data),1);
table_res = 360 / number_table_enties;
对于i = 1:长度(sensor_data)
在传感器角度之前获得表条目的索引
baseangle_idx =楼层(sensor_data(i)/ table_res);
correctionval = YI_lut (baseangle_idx + 1);
Restored_lut_signal_man(i)= mod(sensor_data(i)+ ...
correctionval, 360);
结束

这段代码对sensor_data中的所有传感器角度进行了校正。

在微控制器实现中,有效地使用位移位和位掩码可以消除除法操作的需要。角度可以用来在位移动或掩蔽后直接索引表项。模运算可以被有意使用的整数溢出所替代。只需要添加一个即可。

在我们的例子中,线性化后剩余的输出误差如下所示,超过了16个记录的角度。剩下的错误通过添加更多的查找表项来减少。

图24:在本文档示例中,随着查找表条目数量的增加,线性化后的剩余角度误差
图24:在本文档示例中,随着查找表条目数量的增加,线性化后的剩余角度误差

性能比较

为了比较本文解释的三种方法的性能,分析了理想修正曲线与三种讨论方法的表示之间的差异。

这是使用图16中的校正曲线完成的。其他曲线会给出不同的结果。

在轴上应用中,需要的修雷竞技最新网址正量很小,可以减少条目的数量。

为了比较方法的存储需求,我们假设查找表和线性插值存储的每个值都需要一个存储条目。

对于谐波线性化,每个谐波需要两个存储项(相位和幅值),同时还需要存储一个直流偏置。这带来了n次谐波的存储条目的数量
n+ 1。

为了谐波校正,以减小幅度的顺序选择施用的谐波。这意味着,例如,是为第七和第八次谐波(的0.0361和0.0257°,振幅)将校正前添加的9次谐波(的0.0429°振幅)的校正。对于侧轴应用,常见的是,第2和雷竞技最新网址第4次谐波比其他谐波强大。在这种情况下,仅校正这两个可能是有用的。

在图25中,确定了全旋转时的最大绝对误差并绘制了存储需求。

图25:为此文档中示例的谐波,线性和查找表校正剩余校正不准确性的最大值
图25:为此文档中示例的谐波,线性和查找表校正剩余校正不准确性的最大值

结论

本文档详细介绍了使用微控制器线性化角度传感器数据的三种可能的方法。实现涵盖了各种内存和处理时间要求。

联系An.快速的代表任何剩余的问题或支持。

附录a:函数lsq_lut_piecewise

https://uk.mathworks.com/matlabcentral/fileexchange/40913-piecewise-linear-least-square-fit。
版权所有(c)2013,Guido Albertin
版权所有。

如果满足以下条件,则允许在源和二进制表单中重新分配和使用或不使用修改使用:

*重新发布源代码必须保留上述版权声明、本条件列表和以下免责声明。

*以二进制形式重新发布必须在发布的文件和/或其他材料中复制上述版权声明、本条件列表和以下免责声明

本软件由版权持有人和贡献者“按现状”提供,任何明示或暗示的保证,包括但不限于,暗示的适销性和适合于特定目的的保证均不予承认。在任何情况下,版权所有人或贡献者均无需对任何直接、间接、附带、特殊、示范或相应的损害(包括但不限于采购替代商品或服务;丧失使用、资料或利润;(或业务中断),无论如何造成的,并根据任何责任理论,无论是在合同、严格责任或侵权(包括过失或其他),以任何方式产生的使用本软件,即使通知该等损害的可能性。

功能[yi] = lsq_lut_piecewise(x,y,xi)
1-D插值的%LSQ_LUT_PIECEWISE分段线性插值(表查找)
% YI = lsq_lut_分段(x, y, XI)获得最优(最小二乘意义)
%向量与线性插值程序一起使用。
目标是在给定X的条件下求出函数的最小值
%f = | y-interp1(xi,yi,x)| ^ 2

%的输入
%x测量数据矢量
% y测量数据向量
1-D表的% XI断点

%输出
1-D表的% YI插值点
% y = interp1(XI,YI,x)

If size(x,2) ~= 1
错误('向量x必须具有维度n x 1.');
ELESEIF大小(y,2)〜= 1
错误('矢量y必须具有维度n x 1.');
mapname (x,1) = mapname (x,1)
错误('向量x和y必须具有维度n x 1.');
结束
由x测量值定义的%矩阵
一个=稀疏([]);
Y测量的%矢量
Y = [];
j = 2:长度(XI)
%获得箱中的点索引[xi(j-1)xi(j)]
ix = x> = xi(j-1)&x 检查bin中是否有数据点
如果〜任何(ix)
'Bin [%f %f]没有数据点,检查估计。
',XI(j-1),XI(j)));
结束
%get x和y数据子集
间= x (ix);
y_ = y (ix);
创建要添加到A的临时矩阵
tmp = [((-x_ + xi(j-1))/(xi(j)-xi(j-1))+ 1)((x_-xi(j-1))/(xi(j) -XI(J-1))))];
用约束构建测量矩阵
[m1,n1] =尺寸(a);
(m2, n2) = (tmp)大小;
a = [[[零(m1,n2-1)]; [零(m2,n1-1)tmp];
箱的%contenate y测量
Y = [Y;y_];
结束
%获得最少的平方Y估计
易= \ Y;


附录b:函数bin_mean

版权所有(c) 2018, dominique Geisler, Alle雷竞技竞猜下载gro MicroSystems Germany GmbHvAll rights reserved。

如果满足以下条件,则允许在源和二进制表单中重新分配和使用或不使用修改使用:

*重新发布源代码必须保留上述版权声明、本条件列表和以下免责声明。

*以二进制形式重新发布必须在发布的文件和/或其他材料中复制上述版权声明、本条件列表和以下免责声明

本软件由版权持有人和贡献者“按现状”提供,任何明示或暗示的保证,包括但不限于,暗示的适销性和适合于特定目的的保证均不予承认。在任何情况下,版权所有人或贡献者均无需对任何直接、间接、附带、特殊、示范或相应的损害(包括但不限于采购替代商品或服务;丧失使用、资料或利润;(或业务中断),无论如何造成的,并根据任何责任理论,无论是在合同、严格责任或侵权(包括过失或其他),以任何方式产生的使用本软件,即使通知该等损害的可能性。

功能[yi] = bin_mean(x,y,xi)
% BIN_LUT bin查找表用于1-D插值(查找表)
% YI = lsq_lut_piecewise(x, y, XI)得到最优(最小二乘意义)bin
在XI中定义的BIN边界之间的最近邻近查找表的%值。
If ((size(x,1) ~= 1) && (size(x,2) ~= 1))
错误('向量x必须有n x 1或1 x n');
Elseif ((size(y,1) ~= 1) && (size(y,2) ~= 1))
错误('向量y必须有n x 1或1 x n');
Elseif长度(x) ~=长度(y)
错误('矢量x和y必须具有相同的长度');
结束
易= 0((长度(XI) 1), 1);
j = 1:(长度(XI) 1)
YI(j) = mean(y((x>=XI(j)) & (x结束

附录c:本应用程序中使用的整个函数脚本说明

版权所有(c)2018,Dominik Geisler,Allegro M雷竞技竞猜下载icrosystems德国GmbH保留所有权利。

如果满足以下条件,则允许在源和二进制表单中重新分配和使用或不使用修改使用:

*重新发布源代码必须保留上述版权声明、本条件列表和以下免责声明。

*以二进制形式重新发布必须在发布的文件和/或其他材料中复制上述版权声明、本条件列表和以下免责声明

本软件由版权持有人和贡献者“按现状”提供,任何明示或暗示的保证,包括但不限于,暗示的适销性和适合于特定目的的保证均不予承认。在任何情况下,版权所有人或贡献者均无需对任何直接、间接、附带、特殊、示范或相应的损害(包括但不限于采购替代商品或服务;丧失使用、资料或利润;(或业务中断),无论如何造成的,并根据任何责任理论,无论是在合同、严格责任或侵权(包括过失或其他),以任何方式产生的使用本软件,即使通知该等损害的可能性。

传感器数据定义
angle_input = [0:11.25:348.75];
Sensor_data = [266.31 278.61 290.39 301.99 312.45 323.00 332.75 342.69 352.79 3.16 .
14.24 26.02 38.94 52.91 67.15 82.18 97.12 111.45 124.98 137.46 148.62 158.82
167.96 176.48 184.48 192.92 201.27 210.50 220.43 230.98 242.31 254.36];
检查上升参考角度
If any(diff(angle_input)<=0) || any(angle_input>360) || any(diff(angle_input)<=0)
误差('参考角度必须在0和360之间单调上升');
结束
检查正确的传感器角度范围
If any(sensor_data<0) || any(sensor_data>360)
误差('传感器角度必须在0和360之间');
结束
% %预处理
sensor_data_2 = sensor_data (:);
angle_input = angle_input (:);
%检查是否连续上升,最多有一个溢出
If any(diff(sensor_data_2) == 0)
误差(“传感器数据必须单调递增”)
ELESEIF SUM(差异(SENSOR_DATA_2)<0)<= 1
%上升角度数据具有零或一个溢出,溢出将被纠正
sensor_data_2 = sensor_data_2(:) + 360 * cumsum([false; diff(sensor_data_2(:))<0];
elsefif sum(diff(sensor_data_2)<0)> 1
错误('只允许一个数据减少作为溢出')
结束
%正确地包裹传感器数据
rollovercorrection = round((平均值(sensor_data_2) - 180)/ 360)* 360;
sensor_data_2 = sensor_data_2 - 翻转粗描;
%延长传感器数据
sensor_data_ext = [sensor_data_2 (:);sensor_data_2 (:) + 360;......
sensor_data_2(:) + 720];
%延长输入数据
discle_input_ext = [Anight_Input(:);Angle_Input(:) + 360;......
Angle_Input(:) + 720];
%磁测图经过预处理后完成
人物,情节([angle_input (:)), [sensor_data_2(:)),“啊——”);
Xlabel('编码器角度°');
ylabel('输出角度[deg]');
网格;
xlim (360 [0]);
标题({'输出字段方向上通过编码器方向'});
使用样条将数据从有序的输入网格中移动
%到有序输出网格上:
Ordered_output_grid = 0:(360/4096):( 360-360 / 4096);
intermediateGrid = Ordered_output_grid + 360;
投影=样条(sensor_data_ext, angle_input_ext,…)
中间奖金);
%计算所需修正的数据:
Correction_curve =投影- intermediategrid;
校正_curve = correnction_curve(:);
%%傅里叶变换校正后,丢弃16后的值
%和按表的长度缩放能量
雷竞技竞猜下载Allegro MicroSystems,LLC 20
周边路955号
曼彻斯特,美国新罕布什尔州03103-3353
www.wasanxing.com
fft_table = fft长度(correction_curve) / (ordered_output_grid);
offset_correction = abs(fft_table(1));
correction_pha =角(fft_table (17));
correction_amp = 2 * abs (fft_table (17));
%%应用四个谐波的谐波校正
Restored_signal_4_harmonics = mod(sensor_data +(…
offset_correction + ...
校正_PAM(1)* COS(1 *(SENSOR_DATA / 360 * 2 * PI)+ CORRECION_PHA(1))+ ...
校正_PAM(2)* COS(2 *(SENSOR_DATA / 360 * 2 * PI)+ CORRECING_PHA(2))+ ...
(3*(sensor_data/360*2*pi) + correction_pha(3)) +…
校正_PAM(4)* COS(4 *(SENSOR_DATA / 360 * 2 * PI)+ CORRECION_PHA(4))...
), 360);
校正曲线的%%分段线性近似
lin_sup_nodes = 32;
%重复校正表三次以避免
修正计算的%角效果。
triple_correction_curve = repmat(校正_curve,3,1);
triple_correction_curve结束(+ 1)= triple_correction_curve (1);
%对输入的角度做同样的处理
triple_output_grid = 0 (360/4096): (3 * 360);
计算支撑点
XI_lin_triple = linspace (0 3 * 360 lin_sup_nodes * 3 + 1);
YI_lin_triple = lsq_lut_piecewise(triple_output_grid(:),…
triple_correction_curve,xi_lin_triple);
%仅使用中心点来计算校正:
yi_lin = yi_lin_triple(lin_sup_nodes + 1:2 * lin_sup_nodes + 1);
xi_lin = linspace(0,360,lin_sup_nodes + 1);
%%执行线性插值
Restored_linear_signal = mod(sensor_data(:) +…
interp1 (XI_lin、YI_lin sensor_data(:),“线性”),360);
%%手动执行线性插值
restored_linear_signal_man = 0(长度(sensor_data), 1);
lin_sup_res = 360 / lin_sup_nodes;
对于i = 1:长度(sensor_data)
在传感器角度之前获得表条目的索引
baseangle_idx =楼层(sensor_data(i)/ lin_sup_res);
baseangle = baseangle_idx * lin_sup_res;
%获得了我们经过表格条目的程度
Offsetangle = sensor_data(i) -基角;
%修正为基数+
纠正val = yi_lin(baseangle_idx + 1)+ ...
((yi_lin(baseangle_idx + 2) - ...
yi_lin(baseangle_idx + 1))* offstangle / lin_sup_res);
Restored_linear_signal_man(i)= mod(sensor_data(i)+ ...
correctionval, 360);
结束
%%进行查表校正
number_table_entries = 64;
%选择仓边界
xi_binlimits = linspace(0,360,number_table_entries + 1);
%使用函数bin_lut找到每个垃圾箱的点的平均值:
yi_lut = bin_mean(somented_output_grid(:),...
correction_curve (:), XI_binlimits (:));
应用查表线性化
Restored_lut_signal = mod(sensor_data(:) +…
interp1 (XI_binlimits (1: end-1),……
YI_lut sensor_data(:),‘以前’,‘extrap’),360);
手动应用查找表线性化
Restored_lut_signal_man = zeros(长度(sensor_data),1);
table_res = 360 / number_table_enties;
对于i = 1:长度(sensor_data)
在传感器角度之前获得表条目的索引
baseangle_idx =楼层(sensor_data(i)/ table_res);
correctionval = YI_lut (baseangle_idx + 1);
Restored_lut_signal_man(i)= mod(sensor_data(i)+ ...
correctionval, 360);
结束
%%绘制三种方法平面化后的剩余误差
图;
绘图(Aligh_Input(:),mod(180 + Restored_linear_Linear_Linear_signal(:) - Angle_Input(:),360)-180,'.-',......
Angle_Input(:),mod(180 + Restored_signal_4_Harmonics(:) - Angle_Input(:),360)-180,'.-',......
Angle_Input(:),mod(180 + Restored_lut_Signal(:) - Angle_Input(:),360)-180,'.-'......
);
('线性插值(32段)','谐波校正(4次谐波)',
'查找表(64项)');
xlim (360 [0]);包含(“测量角(度)”);
ylabel('线性化后的预期误差[deg]');


本文档中包含的信息不构成关于本文件主题的Allegro向客户提供的任何代表性,保证,保证,担保或诱导。所提供的信息并不能保证基于此信息的过程是可靠的,或者Allegro探讨了所有可能的失败模式。客户有责任对最终产品进行充分的资格测试,以确保它是可靠的,满足所有设计要求。

1] Allegro角度位置传感器IC,/ EN /产品/磁性 -
Linear-And-Angular-Position-Sensor-ICs / Angular-Position-Sensor-ICs.aspx