ECU 应用层软件模型之定点化7

文摘   2024-12-02 06:56   上海  

ECU 应用层软件模型系列文章不断更新中,从零开始教你做应用层开发:


在之前这几篇文章已经介绍了模型如何生成代码,但有个重要的话题一直没有提,那就是对于变量或者常量的数据类型,之前都是将它们设置为默认的。


生成代码后,它们的数据类型其实都是double。
这样肯定是不合理的,应该根据实际情况定义各变量和常量的数据类型。况且对于ECU应用软件模型,很多ECU都不支持浮点运算,要求进行定点化处理。为什么呢?
1 为什么采用定点数?

ECU软件需要定点化的原因有性能、成本、实时性和可靠性等多个方面的考虑。比如:

  • 计算速度。相比于浮点运算,定点运算的计算速度更快。浮点运算需要进行复杂的指数和尾数运算,而定点运算只需要进行简单的整数运算。考虑到ECU需要在非常短的时间内完成大量的计算任务,比如在底盘和传动系统中,许多任务需要在5ms、10ms或20ms的周期内完成,因此需要利用定点运算的高速特性来满足这些实时性要求。

  • 硬件成本。相比于浮点MCU(微控制器)需要内置复杂性和成本更高的浮点运算单元(FPU),定点MCU的结构更简单,功耗更低,制造成本也更低。另外,定点MCU的功耗更低,这对于汽车应用来说非常重要,因为汽车ECU需要长时间稳定运行,低功耗有助于提高整体系统的能效。

  • 内存和存储资源。定点数使用较少的位数来表示数据,其占用的内存资源更少,这意味着ECU的内存需求更小;对于ECU有限的存储空间,定点数带来更高的存储效率。

  • 稳定性和可靠性。浮点运算可能会引入不确定性和误差,尤其是在涉及大量乘除法和指数运算时。定点运算则更加稳定,可以精确控制计算过程中的误差。在进行除法运算时,定点运算可以更容易地实现除0保护。通过在进行除法运算前检查除数是否为零,可以避免除0操作导致的计算错误和系统崩溃。

因此,在这样的背景下,实际ECU软件开发,基本都采取定点数方式,比如在电机控制算法中常见的参数(电流、电压和速度等),都通过合适的量化方法转化为定点数进行处理。

2 定点数的量化方法

常见的定点数量化方法有:
  • 缩放(Scaling):为了将浮点数转换为定点数,可以使用缩放技术。通过选择合适的缩放因子,可以将浮点数转换为整数表示。比如需要将0.08和0.3相加,可以将它们分别乘以100,得到8和30,然后进行加法运算,结果为38。如果需要进一步使用这个结果,可以将其除以100,得到0.38。
  • LSB和Offset:比如在TargetLink等工具中,可以通过设置LSB(最低有效位)和Offset来实现缩放。LSB定义了每个单位的值,Offset定义了偏移量,从而将浮点数转换为定点数,如下所示:
source:基于Embedded Coder 或TargetLink 的AUTOSAR 模型的静态分析方案详解。
下面举一个例子更详细地说明一下,假设ECU应用层软件模型将从底层软件接收到车速信号的原始值,一个无符号16位数(即Uint16),需要将其转换为车速信号的物理值,其转换关系为:物理值=0.1*原始值+4.5
假如我们不需要考虑各变量和常量的数据类型,搭建的模型如下所示:
但考虑到ECU应用层软件不允许使用浮点数,那么我们就需要将浮点数转换为定点数进行处理,比如采用上面提到的缩放方法,那么我们可以将将转换关系式左边乘以10处理,这样小数就变成整数,最后除以10就行。

但这样还是有一个点需要注意,最终输出车速信号的物理值,如果其为整数,那么设置为整形数据即可,比如uint16。如果其为小数,且要求不能为浮点数,那么该如何设置?

下面是一种解决方法,就是在最后除法模块的信号属性中,选择定点化的数据类型fixdt。

最后我们给同样的输入,假设车速信号的原始值为32,那么通过上面三种不同数据类型的设置,它们的仿真计算结果情况会如何?如下所示:

先从理论计算来说,预期车速信号的物理值为:0.1*32+4.5=7.7,前两者结果不难理解与理论计算的一致,但是完全定点化之后计算出来结果为7.5,存在0.2的偏差。也就是说定点化后存在精度损失,但这个精度损失是否能接收?以及精度损失可以被控制吗?
3 如何使用fixdt函数
上面导致精度损失为0.2的关键点在定点数类型fixdt(fixed point data type),该如何使用fixdt函数?大致有如下几种用法:
source:fixdt (mathworks.cn)

这里主要介绍两种用法: fixdt(Signed,WordLength,FractionLength)和fixdt(Signed,WordLength,Slope,Bias)。

1)fixdt(Signed,WordLength,FractionLength)

fixdt(Signed,WordLength,FractionLength)包含三个主要参数,分别是符号、数据长度和小数位长度。具体说明如下:

  • Signed,即符号:决定了是否允许负数的存在。fixdt(1,...) 表示有符号数;fixdt(0,...) 表示无符号数。

  • WordLength,即数据长度:这是指定总的二进制位数。

  • FractionLength,即小数位长度:这是指定多少位被分配给小数部分。

实际值(Real World Value, RWV)和定点数的整数表示(Stored Integer, SI)之间的关系可以通过以下公式表示:

所以当我们设置fixdt(1, 8, 3),则表示:
  • 第一个参数 1 表示这是一个有符号的数。
  • 第二个参数 8 表示总共有8位可用。
  • 第三个参数 3表示这8位中有3位是用来表示小数的部分。
实际值和定点数的整数表示之间的关系为:RWV= SI/(2^3)=SI/8,另外fixdt(1,8,3)也意味着其范围为:

2)fixdt(Signed,WordLength,Slope,Bias)

带斜率和偏置的 fixdt 是一种更为灵活的固定点数据类型表示方法,通过斜率和偏置,可以将实际值映射到定点数的整数表示上,从而实现更精确的数据表示和处理。

fixdt(Signed,WordLength,Slope,Bias) 包含四个主要参数,分别是符号、数据长度,斜率和偏置。具体说明如下:
  • Signed,即符号:决定了是否允许负数的存在。fixdt(1,...) 表示有符号数;fixdt(0,...) 表示无符号数。
  • WordLength,即数据长度:这是指定总的二进制位数。
  • Slope,即斜率 : 比例因子,用于将实际值转换为定点数的整数表示。
  • Bias,即偏置: 常数,用于将实际值进一步调整到定点数的整数表示上。

实际值(Real World Value, RWV)和定点数的整数表示(Stored Integer, SI)之间的关系可以通过以下公式表示

fixdt 函数可以接受多种参数组合来定义带斜率和偏置的固定点数据类型,这里只看一个例子,假设我们需要定义一个 16 位有符号的固定点数据类型,斜率为2^-2,偏置为 4,即fixdt(1,16,2^-2,4),那么

  • signed 为 1,表示有符号;
  • word_length 为 16,表示总共有 16 位;
  • slope 为2^-2,表示斜率为 0.25;
  • bias 为 4,表示偏置为 4。

实际值和定点数的整数表示之间的关系为:

以上就是对于fixdt函数的介绍,那么不难理解之前模型中定义fixdt(1,16,1),这意味着RWV = SI/2,即精度为0.5,如果需要将精度控制在0.1以内,那么我们可以设置为fixdt(1,16,4),这样计算结果为7.688,与7.7的差值为0.012,满足要求。

4 小结

以上就通过理论与实际相结合的方式简要介绍了定点化的概念和实现方式,定点化是一个非常关键的概念和技术点,下篇文章继续来探讨这个话题,如有兴趣,敬请关注。

创作不易,欢迎关注点赞再看收藏


汽车研发交流群,有兴趣的朋友请添加群主:prOmiseyes,备注:公司+职务入群。仅限汽车从业人员。

谦益行
分享汽车研发日常,助力你我共同成长。
 最新文章