基于微控制器的角度传感器IC的线性化

基于微控制器的角度传感器IC的线性化

杜米尼克聊聊,
亚博棋牌游戏Allegro Microsystems,LLC

下载版本

介绍

磁角传感器通常是快速、可靠、非接触测量系统角位置的好选择,特别是在光学编码器可能不适合的肮脏环境中。

亚博棋牌游戏Allegro MicroSystems, LLC为不同的应用提供了广泛的角度传感器ic[1]。亚博尊贵会员这些传感器芯片可以测量编码器磁体的直径磁化角度
在侧轴或轴尾设置,如图1所示。

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

测量误差

所有Allegro角度传感器IC都使用同质磁场在出厂的最终测试中校准。这样做是为了最小化传感器的本地错误。然而,特别是在侧轴应用中,传感器换能器处的磁场角与待测量的轴的机械角亚博尊贵会员度不相同。这种差异的主要贡献者是从编码器磁体发出的磁场的形状。

机械和磁场角度不匹配的其他来源是磁体不对准,磁体缺陷,剩余的传感器不准确和漂移,以及铁磁性材料的存在。

可以得出结论,所有系统,特别是侧轴系统,遭受了编码器角度和测量角度之间的不匹配。侧轴应用的典型转移曲线如图2所示。

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

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

线性化

一些allegro传感器IC,如A1335., 这AAS33001,而且AAS33051具有嵌入式逻辑,允许输入数据的线性化。但是,其他传感器IC,如A1330A1333A1337A1338,或A1339,在芯片上没有此功能。在使用没有内置功能的传感器IC来线性化数据的情况下,可能需要使用微控制器的外部线性化以在特定应用中实现所需的精度。

本申请须知将:

  • 解释线性化的基础
  • 展示如何处理真实测量数据以计算校正数据
  • 详细信息存储校正数据的三种方式
  • 详细说明如何应用更正
  • 比较了提出的方法的准确性

定义

编码器角度

由一个精确的,高分辨率的外部编码器报告的角度。

传感器的角度

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

角度错误

角度误差是通过角度传感器IC测量的磁体的实际位置与磁体的位置之间的差异。这是通过从传感器角度减去编码器角度来计算的:

误差= (α_sensor - α_encode)。

但是,如果传感器角度为359°,则编码器角为0°,则误差应为-1°且不+ 359°。要在±180°之外的任何错误缠绕,可以使用Modulo操作员:

误差= mod[(α_sensor - α_encoder) + 180360] - 180。

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

最大绝对角度误差

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

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

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

线性化的目标

线性化的目标是确定,存储和应用一个功能,该功能最小化测量的传感器角度误差与编码器角度值相比。这最大限度地减少了测量的传感器角度和实际编码器角之间的差异。

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

这个目标可以通过不同的方式实现。本文将详细介绍三种常用技术。亚博尊贵会员

所提供的技术依赖于单个校准阶段(通常在客户的线尾测试时执行),之后应用固定校正功能。

先决条件线性化

使用此处详述的技术进行线性化的先决条件如下:

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

限制线性化

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

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

线性化方法

1.数据记录

要生成线性化所需的数据,请测量传感器输出[y0.......N]在已知编码器角度[x0.… XN]。这些编码器角度不需要等距离,尽管通常使用等距角度常见。

值的记录如图5所示。

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

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

这意味着代替将传感器角度表达为实角度,而是需要表达作为传感器角度的功能的实角度。因此,传感器角度[y'0.y……”N选择,相应的编码器角度[X'0.…x 'N]需要确定。为此,需要通过数据点应用拟合。这可以通过样条插值来完成,如图6所示。


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

3.校正曲线计算

为了创建将在传感器上测量的角度转换为编码器角度的功能,需要计算校正值。这些校正值计算为[c0.… CN] = [x '0.…x 'N] - [y '0.y……”N]。

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

最后,这些值描述了校正曲线C,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:求值X = Y + C
图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(:);
discle_input = conte_input(:);
%检查是否连续上升,最多有一个溢出
如果有的话(screat(sensor_data_2)== 0)
错误('传感器数据必须单调增加')
Elseif sum(diff(sensor_data_2) < 0) <= 1
%上升角度数据有零或一个溢出,溢出将被纠正
sensor_data_2 = sensor_data_2(:) + 360 * cumsum([false; diff(sensor_
Data_2 (:)) < 0]);
case " Elseif sum(diff(sensor_data_2) < 0) >
错误('只允许一个数据减少溢出')
结束
%正确环绕传感器数据
Rollovercorrection = round((mean(sensor_data_2) - 180)/360) * 360;
Sensor_data_2 = Sensor_data_2 - rollovercorrection;

结果值如表2所示。

表2:去掉溢流后的编码器和输出角度

图14:表2中的数据绘图
图14:表2中的数据绘图

数据复制

最终,需要基于0°至360°的基于传感器角度的校正数据。为避免任何边缘效果,传感器数据将被复制三次。这通过始终始终安全地将来自传感器角度360°至720°的值放置的可能性来避免所有情况下的边缘效应。

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

投影到传感器数据网格上

在下一步骤中,计算与在下面的代码中的360°和720°之间的传感器输出相对应的编码器角输入(称为“中间化”)。这是通过4096步进行的,作为这种中间步骤的高分辨率,有利于最终输出质量。

%%使用样条曲线从有序的输入网格移动数据
%到一个有序的输出网格:
ordered_output_grid = 0 (360/4096): (360 - 360/4096);
Intermediategrid = ordered_output_grid + 360;
投影=样条曲序(Sensor_data_ext,Antle_Input_ext,...
intermediategrid);

这一步如图15所示。

图15:寻找编码器角度(“投影”)作为固定网格传感器角度的投影(“intermediategrid”)
图15:寻找编码器角度(“投影”)作为固定网格传感器角度的投影(“intermediategrid”)

角度编码器值和传感器输出之间的差异是校正曲线,并且可以通过从计算出的匹配编码器角减去固定网格传感器角来计算。

%计算数据所需的校正:
校正_curve =投影 - 介入;
correction_curve = correction_curve (:);
校正曲线可以在图16中看到。

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

简要检查是否可以看到此曲线是正确的。在表1中,可以看出,对于137.46°的传感器角度,编码器角度为213.75°。图16的校正曲线显示,在137.5°的传感器角度,需要施加+ 76.29°的校正。AS 137.46 + 76.26 = 213.72°≅213.75°,计算的校正曲线适用。

在下一步,需要以有效的方式存储校正曲线,从而可以为任​​何输入计算校正值。这将是使用谐波近似,线性插值和查找表进行的。

谐波近似

概念

每个重复信号可以分为它的组成频率。

修正曲线在每次旋转后重复,因此可以完全描述为一组频率。重复校正曲线可以更清楚地看出校正曲线中包含了不同的频率。

图17:重复的校正曲线包含各种频率
图17:重复的校正曲线包含各种频率

谐波近似的一个优点是校正曲线可以用少量的参数以可接受的精度来描述。然而,余弦的计算可能也是
一些平台或应用程序慢。亚博尊贵会员

实现

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

%%傅立叶变换纠正,丢弃16th之后的值
%和按表长度缩放能量
fft_table = fft长度(correction_curve) / (intermediategrid);
offset_correction = abs (fft_table (1));
correction_pha =角(fft_table (17));
校正_AMP = 2 * ABS(FFT_TABLE(2:17));
这产生了89.82°的偏移校正,以及谐波的以下幅度:

图18:校正曲线前16次谐波的振幅
图18:校正曲线前16次谐波的振幅

到第16次谐波的完整结果表如下:

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

应用

第n次谐波在特定角度下的修正值为:

Corr (n) = correction_amp(n)× cos[n × sensor_angle + correction_pha(n)],

其中第0次谐波是偏移校正,也应考虑在内。在实际应用中,下面的代码产生了四次谐波。因为余弦函数需要弧度
作为输入,角度值被转换为弧度。由于傅里叶变换的输入是以度为单位的,所以表中存储的修正幅度是以度为单位的。

%%对四个谐波进行谐波校正
Restored_signal_4_harmonics = mod(sensor_data +(…
offset_correction +……
Correction_amp (1)*cos(1*(sensor_data/360*2*pi) + correction_pha(1)) +…
Correction_amp (2)*cos(2*(sensor_data/360*2*pi) + correction_pha(2)) +…
校正_pm(3)* cos(3 *(sensor_data / 360 * 2 * pi)+校正_pha(3))+ ...
Correction_amp (4)*cos(4*(sensor_data/360*2*pi) + correction_pha(4))…
), 360);

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

在循环中实现此校正将降低微控制器实现的代码大小,但在此处不用于代码清晰度原因。

图19显示了从表1的16个录制的角度上线性化后的剩余输出不准确性。剩余误差通过添加更多谐波来减小。选择次谐波补偿时,最好按照降低幅度选择谐波。例如,如果谐波1,2和4具有大的幅度,而谐波3具有较小的幅度,则校正谐波1,2和4将提供比校正谐波1,2和3更好的结果。

图19:线性化后的剩余角度误差随着本文档中示例的升级量增加而升高
图19:线性化后的剩余角度误差随着本文档中示例的升级量增加而升高

线性插值

概念

修正曲线可以用分段线性函数来近似。该功能需要将支撑点存储为传感器坐标对和修正值对。

在图8中,这些对将是[(y'0., C0.,)...(y'N, CN)]。在支撑点之间进行线性插补。在角度传感器线性化应用中,使用传感器角度的等距网格是有用的。亚博尊贵会员这样,传感器角度值[y'0.y……”N]不需要存储,并且实现线性校正变得更加容易。例如,可以存储32个校正值,然后应用于0°、11.25°、22.50°等传感器角度。

要存储的点可以由不同的标准确定。

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

图20:理想校正曲线与曲线上、最小二乘法确定参数的线性插值曲线对比
图20理想校正曲线与
与参数的线性插值
曲线上和最小二乘法

对于相同的最大误差,最小二乘方法减少了大约50%的存储参数所需的数量,并且对单个测量离群值不太敏感。因此,本文将采用最小二乘法来确定线性插补支撑点。

实现

修正曲线需要用分段线性函数逼近。由于支撑点的选择应以最小二乘误差的方式进行,因此支撑点前后的数据应保持一致
点也有助于决定它的最终值。

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

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

适合计算

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

修正曲线的%%分段线性逼近
lin_sup_nodes = 32;
%重复校正表三次以避免
%拐角对校正计算的影响。
triple_correction_curve = repmat (correction_curve 3 1);
triple_correction_curve(end + 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(0360年,lin_sup_nodes + 1);

附录A中重印了lsq_lut_piecewise函数。

下面找到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:length(sensor_data)
%获取表项在传感器角度之前的索引
baseangle_idx =地板(sensor_data(我)/ lin_sup_res);
baseangle = baseangle_idx * lin_sup_res;
%获取超过表项的度数
offstangle = sensor_data(i) - 胸部;
%校正是基础+
纠正val = yi_lin(baseangle_idx + 1)+ ...
((YI_lin (baseangle_idx + 2) -…
YI_lin (baseangle_idx + 1) * offsetangle / lin_sup_res);
Restored_linear_signal_man (i) = mod(sensor_data(i) +…
校正,360);
结束

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

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

我们的示例的线性化后的剩余输出不准确性在下面显示在16个录制的角度下方。通过添加更多线性化点来减少剩余的错误。

图22:线性化后的剩余角度误差随着本文档中的示例的越来越多的线性支撑节点
图22:线性化后的剩余角度误差随着本文档中的示例的越来越多的线性支撑节点

查找表

概念

对于校正曲线的线性插补,需要在支撑点之间插补。这需要一些数学运算,这通常需要很长时间。

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

将选择每组角度或垃圾箱的校正值作为该箱内校正曲线值的平均值。这将确保校正曲线的最低结果RMS错误
表示。其他策略,例如选择相应箱的最小和最大校正之间的平均值,但不会在本文档中使用。

使用查找表需要存储大量的值以达到可接受的性能。通常需要大约256个值。值的个数不需要是2的幂;然而,定点代码中的微控制器实现将受益于使用2的幂作为表项的数量。

实现

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

%%查找表近似校正曲线
number_table_entries = 64;
%选择bin边界
XI_binlimits = linspace(0360年,number_table_entries + 1);
使用bin_lut函数查找每个bin的平均点:
YI_lut = bin_mean(ordered_output_grid(:),…
correction_curve (:), XI_binlimits (:));

在附录b中打印了函数bin_lut。应该注意的是,对于较大的值,恰好在两个箱子之间边界上的修正曲线值将被包含在箱子的平均值中,而对于较小的值则被排除在箱子之外。

例如,对于64个条目,180°角的校正曲线数据用于180°…185.625°,而不用于174.375°…180°。

64个表项的校正曲线如图23所示。

图23:使用64个箱子的修正曲线的查找表表示
图23:查找表表示
用64个箱子的修正曲线

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

表5:64条参赛作品的查找表

应用

在MATLAB中,使用内置的一维插值函数前邻值,校正的应用是直接的:

Restored_lut_signal = mod(sensor_data(:) +…
interp1(xi_binlimits(1:end-1),...
yi_lut,sensor_data(:),'上一个','instrap'),360);

相同的功能也可以实施如下以证明
如何在微控制器中执行计算:
number_table_entries = 64;
restored_lut_signal_man = 0(长度(sensor_data), 1);
table_res = 360 / number_table_entries;
对于I = 1:length(sensor_data)
%获取表项在传感器角度之前的索引
baseangle_idx =地板(sensor_data(我)/ table_res);
纠正val = yi_lut(baseangle_idx + 1);
Restored_lut_signal_man (i) = mod(sensor_data(i) +…
校正,360);
结束

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

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

我们的示例的线性化后的剩余输出不准确性在下面显示在16个录制的角度下方。剩余的错误通过添加更多查找表条目来减少。

图24:线性化后的剩余角度误差随着本文档中示例的越来越多的查找表条目
图24:线性化后的剩余角度误差随着本文档中示例的越来越多的查找表条目

性能比较

为了比较本文档中说明的三种方法的性能,分析了理想校正曲线与使用三种讨论的方法的表示之间的差异。

这是使用图16的校正曲线完成的。其他曲线将提供不同的结果。

在所需校正很小的轴上应亚博尊贵会员用程序中,可以减少所用条目的数量。

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

对于谐波线性化,每个谐波需要两个存储条目(相位和幅度),并且还需要存储DC偏移。这带来了N谐波的存储条目量
到2×N+ 1。

对于谐波校正,按幅值递减的顺序选择谐波。这意味着,例如,在对第9次谐波(振幅为0.0429°)进行校正之前,先对第7次和第8次谐波(振幅分别为0.0361和0.0257°)进行校正。对于侧轴应用,它是常见的,第二亚博尊贵会员和第四谐波比其他强得多。在这种情况下,只有纠正这两个问题才有用。

图25确定了一个完整旋转的最大绝对误差并绘制了存储需求。

图25:本文档中示例的谐波、线性和查询表校正误差的剩余最大值
图25:本文档中示例的谐波、线性和查询表校正误差的剩余最大值

结论

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

接触一个Allegro代表有任何问题或支持。

附录A:功能LSQ_LUT_PICEWISE

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插值的分段线性插值(查表)
%yi = lsq_lut_piecewise(x,y,xi)获得最佳(最小二乘意义)
%向量用于线性插值例程。
%目标是找到y给定x的最小化功能
y-interp1(XI,YI,x)|^2, y-interp1(XI,YI,x)|^2

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

% 输出
1-D表的%yi插值点
%y = Interp1(xi,yi,x)

如果尺寸(x,2)〜= 1
error('向量x必须有n x 1.');
Elseif size(y,2) ~= 1
error('向量y必须有n x 1.');
Elseif size(x,1) ~= size(x,1)
error('向量x和y必须有n x 1.');
结束
%矩阵由X测量定义
a =稀疏([]);
%向量的y测量
Y = [];
j = 2:长度(XI)
% get bin中点的索引[XI(j-1) XI(j)]
x = x>=XI(j-1) & x%检查我们是否在箱中有数据点
如果~(第九)
警告(Sprintf('bin [%f%f]没有数据点,检查估计。
请相应地重新定义X向量。',Xi(J-1),XI(J)));
结束
%获取x和y数据子集
x_ = x(ix);
y_ = y(ix);
%创建临时矩阵要添加到a
tmp =(((间+ XI (j - 1)) / (XI (j)习近平(j - 1)) + 1) ((x_-XI (j - 1)) / (XI (j)习近平(j - 1))));
%构建有约束的度量矩阵
(m1, n1) = (A)大小;
[M2,N2] =尺寸(TMP);
[0 (m1, n1-1) tmp]];
%连接y测量bin
Y = [Y;y_];
结束
%获得最小二乘Y估计
yi = a \ y;


附录b:函数bin_mean

版权所有(c)2018,Dominik Geisler,Allegro M亚博棋牌游戏icrosystems德国GmbHvall Rights Reserved。

在满足以下条件的情况下,允许重新分发和以源代码和二进制形式使用,无论是否修改:

*源代码的重新分配必须保留上述版权声明,此条件清单和以下免责声明。

*以二进制形式重新发布必须将上述版权声明、本条件清单和以下免责声明复制到随发布而提供的文件和/或其他材料中

该软件由版权所有者和贡献者提供“原样”,并提供任何明示或暗示的保证,包括但不限于默示的默示和特定目的的适应性的暗示保证。在任何情况下,版权所有者或贡献者都应对任何直接,间接,偶然,特殊,示范性或相应的损害负责(包括但不限于采购替代商品或服务;使用丧失,数据或利润;然而,或者业务中断)造成和任何责任理论,无论是在合同,严格的责任或侵权行为(包括疏忽或其他方式),也以任何方式出现在使用本软件的情况下,即使涉及此类损害的可能性也是如此。

函数[YI] = bin_mean(x, y, XI)
1-D插值的%bin_lut bin查找表(表查找)
%yi = lsq_lut_piecewise(x,y,xi)获得最佳(最小二乘感)箱
在XI中定义的bin边界之间的最近邻居查找表的%值。
If ((size(x,1) ~= 1) && (size(x,2) ~= 1))
错误('矢量x必须具有尺寸n x 1或1 x n');
elseff((size(y,1)〜= 1)&&(size(y,2)〜= 1)))
错误('向量Y必须具有尺寸n x 1或1 x n');
elsefif长度(x)〜=长度(y)
error('向量x和y必须有相同的长度');
结束
yi = zeros((长度(xi)-1),1);
对于j = 1 :(长度(xi)-1)
yi(j)=均值(y((x> = xi(j))&(x 结束

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

版权所有(c) 2018, Dominik Geisler, Allegr亚博棋牌游戏o MicroSystems Germany 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];
%%检查上升参考角度
如果any(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(:);
discle_input = conte_input(:);
%检查是否连续上升,最多有一个溢出
如果有的话(screat(sensor_data_2)== 0)
错误('传感器数据必须单调增加')
Elseif sum(diff(sensor_data_2) < 0) <= 1
%上升角度数据有零或一个溢出,溢出将被纠正
sensor_data_2 = sensor_data_2(:) + 360 * cumsum([false; diff(sensor_Data_2 (:)) < 0]);
case " Elseif sum(diff(sensor_data_2) < 0) >
错误('只允许一个数据减少溢出')
结束
%正确环绕传感器数据
Rollovercorrection = round((mean(sensor_data_2) - 180)/360) * 360;
Sensor_data_2 = Sensor_data_2 - rollovercorrection;
%扩展传感器数据
sensor_data_ext = [sensor_data_2(:);sensor_data_2(:) + 360;...
sensor_data_2 (:) + 720];
%扩展输入数据
angle_input_ext = [angle_input (:);angle_input (:) + 360;...
angle_input (:) + 720];
预处理完成后%%绘图磁体测量
图;绘图([Anight_Input(:)],[Sensor_Data_2(:)],'O-');
包含(“编码器角度(度)”);
ylabel(“输出角(度)”);
网格;
xlim (360 [0]);
标题({'输出字段方向超过编码器方向'});
%%使用样条曲线从有序的输入网格移动数据
%到一个有序的输出网格:
ordered_output_grid = 0 (360/4096): (360 - 360/4096);
Intermediategrid = ordered_output_grid + 360;
投影=样条曲序(Sensor_data_ext,Antle_Input_ext,...
intermediategrid);
%计算数据所需的校正:
校正_curve =投影 - 介入;
correction_curve = correction_curve (:);
%%傅立叶变换纠正,丢弃16th之后的值
%和按表长度缩放能量
亚博棋牌游戏阿莱格微系统有限公司
955周边路
曼彻斯特,NH 03103-3353 U.S.A.
www.wangzuanquan.com
fft_table = fft长度(correction_curve) / (ordered_output_grid);
offset_correction = abs (fft_table (1));
correction_pha =角(fft_table (17));
校正_AMP = 2 * ABS(FFT_TABLE(2:17));
%%对四个谐波进行谐波校正
Restored_signal_4_harmonics = mod(sensor_data +(…
offset_correction +……
Correction_amp (1)*cos(1*(sensor_data/360*2*pi) + correction_pha(1)) +…
Correction_amp (2)*cos(2*(sensor_data/360*2*pi) + correction_pha(2)) +…
校正_pm(3)* cos(3 *(sensor_data / 360 * 2 * pi)+校正_pha(3))+ ...
Correction_amp (4)*cos(4*(sensor_data/360*2*pi) + correction_pha(4))…
), 360);
修正曲线的%%分段线性逼近
lin_sup_nodes = 32;
%重复校正表三次以避免
%拐角对校正计算的影响。
triple_correction_curve = repmat (correction_curve 3 1);
triple_correction_curve(end + 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(0360年,lin_sup_nodes + 1);
%%执行线性插值
Restored_linear_signal = mod(sensor_data(:) + ...
interp1(xi_lin,yi_lin,sensor_data(:),'linear'),360);
%%手动执行线性插值
restored_linear_signal_man = 0(长度(sensor_data), 1);
lin_sup_res = 360 / lin_sup_nodes;
对于I = 1:length(sensor_data)
%获取表项在传感器角度之前的索引
baseangle_idx =地板(sensor_data(我)/ lin_sup_res);
baseangle = baseangle_idx * lin_sup_res;
%获取超过表项的度数
offstangle = sensor_data(i) - 胸部;
%校正是基础+
纠正val = yi_lin(baseangle_idx + 1)+ ...
((YI_lin (baseangle_idx + 2) -…
YI_lin (baseangle_idx + 1) * offsetangle / lin_sup_res);
Restored_linear_signal_man (i) = mod(sensor_data(i) +…
校正,360);
结束
%%执行查找表校正
number_table_entries = 64;
%选择bin边界
XI_binlimits = linspace(0360年,number_table_entries + 1);
使用bin_lut函数查找每个bin的平均点:
YI_lut = bin_mean(ordered_output_grid(:),…
correction_curve (:), XI_binlimits (:));
%%应用查找表线性化
Restored_lut_signal = mod(sensor_data(:) +…
interp1(xi_binlimits(1:end-1),...
yi_lut,sensor_data(:),'上一个','instrap'),360);
手动应用查找表线性化
restored_lut_signal_man = 0(长度(sensor_data), 1);
table_res = 360 / number_table_entries;
对于I = 1:length(sensor_data)
%获取表项在传感器角度之前的索引
baseangle_idx =地板(sensor_data(我)/ table_res);
纠正val = yi_lut(baseangle_idx + 1);
Restored_lut_signal_man (i) = mod(sensor_data(i) +…
校正,360);
结束
%%用三种方法绘制滞环后的剩余误差
数字;
情节(angle_input(:),国防部(180 + restored_linear_signal (:) -angle_input(:), 360), -180年”。——“,……
angle_input(:),国防部(180 + restored_signal_4_harmonics (:) -angle_input(:), 360), -180年”。——“,……
angle_input(:),国防部(180 + restored_lut_signal (:) -angle_input(:), 360), -180年”。——“…
);
网格;图例('线性插值(32个段)','谐波校正(4次谐波)',
'查找表(64个条目)');
xlim (360 [0]);包含(“测量角(度)”);
ylabel('线性化后的预期误差[deg]');


本文件中包含的信息不构成Allegro对客户就本文件主题事项的任何陈述、保证、保证、担保或引诱。提供的信息并不能保证基于这些信息的过程是可靠的,或者Allegro已经探索了所有可能的故障模式。客户有责任对最终产品进行充分的合格测试,以确保其可靠性和满足所有设计要求。

1] Allegro角度位置传感器ic, /en/产品/磁-
线性和角位置传感器-IC / Angular-Position-Sensor-ICS.aspx