电机速度曲线规划1:梯形速度曲线设计与实现

  电机驱动是很常见的应用,在很多系统中我们都会碰到需要改变电机的速度以实现相应的控制功能,这就涉及到电机速度曲线规划的问题。在这篇中我们就来简单讨论一下电机的梯形曲线规划的问题。

1、基本原理

  梯形速度曲线控制算法是工业控制领域应用最为广泛的加减速控制策略之一。所谓梯形速度曲线将整个运动过程分为匀加速、匀速和匀减速三个阶段,在变速过程中加速度保持不变。

  从变速过程中加速度保持不变这特点来说,其加减速过程其实是一个线性过程。我们可以采用一个线性函数来描述它。

  这一线性函数,具体到我们的加减速过程中就是速度与时间的函数关系,函数结果就是我们某一时刻的速度,变量就是时间,斜率就是加速度,初始速度就是截距,具体如下:

  这一函数表达的是连续的,但实际使用中我们需要离散化处理,我们必定以一定的时间间隔来处理速度的增加问题。这样实际的速度变化就不可能是连续的,而是阶梯状的,具体如下:

  为了速度的变化尽量平缓,我们需要尽可能地让时间间隔小一些,这其实是我们在考虑编写程序时需要处理的一个参数。

2、设计与实现

  我们已经简单描述了S型速度规划曲线的数学原理及应用表达式。接下来我们来考虑怎么实现它。

  考虑到在同一个驱动器中可能因为应用场景的需要存在多条的速度规划曲线。所以我们以基于对象的思路来考虑它,这样我们在更换不同的曲线就只需要更换不同的曲线实力就可以了。所以我们先来分析一下曲线对象的属性和操作。

  鉴于前面的分析,我们认为作为一个调速曲线对象至少要记录:开始调速时的初始速度、当前速度、目标速度、加速度、最大速度、最小速度、调速时间、调速时间跨度、曲线类型等,我们将这些记为对象的属性。据此我们可以定义电机速度曲线的对象类型为:

/* 定义电机速度曲线对象 */
typedef struct CurveObject {float startSpeed;    //开始调速时的初始速度float currentSpeed;   //当前速度float targetSpeed;    //目标速度float stepSpeed;     //加速度float speedMax;     //最大速度float speedMin;     //最小速度uint32_t aTimes;     //调速时间uint32_t maxTimes;    //调速跨度SpeedCurveType curveMode;  //曲线类型
}CurveObjectType;

 我们已经定义了一个速度曲线对象类型,接下来我们就来分析如何实现一个T型调速曲线。我们已经描述过,速度其实就是时间的函数,根据我们前面分析的速度时间的函数表达式,我们实现如下:

void (*pCalCurve[])(CurveObjectType *curve)={CalCurveNone,CalCurveTRAP,CalCurveSPTA};/* 电机曲线加减速操作-------------------------------------------------------- */
void MotorVelocityCurve(CurveObjectType *curve)
{float temp=0;if(curve->targetSpeed>curve->speedMax){curve->targetSpeed=curve->speedMax;}if(curve->targetSpeed<curve->speedMin){curve->targetSpeed=curve->speedMin;}if((fabs(curve->currentSpeed-curve->startSpeed)<=curve->stepSpeed)&&(curve->maxTimes==0)){if(curve->startSpeed<curve->speedMin){curve->startSpeed=curve->speedMin;}temp=fabs(curve->targetSpeed-curve->startSpeed);temp=temp/curve->stepSpeed;curve->maxTimes=(uint32_t)(temp)+1;curve->aTimes=0;}if(curve->aTimes<curve->maxTimes){pCalCurve[curve->curveMode](curve);curve->aTimes++;}else{curve->currentSpeed=curve->targetSpeed;curve->maxTimes=0;curve->aTimes=0;}
}/*梯形曲线速度计算*/
static void CalCurveTRAP(CurveObjectType *trap)
{float slope=0.0;slope=(trap->targetSpeed-trap->startSpeed)/trap->maxTimes;trap->currentSpeed=trap->startSpeed+slope*trap->aTimes;if(trap->currentSpeed>trap->speedMax){trap->currentSpeed=trap->speedMax;}if(trap->currentSpeed<trap->speedMin){trap->currentSpeed=trap->speedMin;}
}

  在这个实现中,我们出于更普遍的实用性考虑,将各种曲线的相同操作集成在一起,然后将它们差异的部分通过曲线类型属性以回调函数的方式集成。

3、应用与验证

  我们实现了T形电机速度规划曲线的基本设计与实现。接下来,我们就是用这一调速曲线来实现一个电机调速的实例。我们定义速度规划曲线时,是及与对象的思想来实现的,所以我们先声明一条曲线对象实例。

  CurveObjectType curve; //电机调速曲线

  在声明了这一曲线对象后,我们需要对其初始化赋值才能正确的使用。大多数的属性直接根据应用对象的要求给予初始值就可以了。需要注意的是曲线类型这一属性,这将决定使用什么样的速度规划曲线。该属性为SpeedCurveType枚举,该枚举定义如下:

/* 定义电机速度曲线类型枚举 */
typedef enum SpeedCurve {CURVE_NONE=0,  //直启CURVE_TRAP=1,  //梯形曲线CURVE_SPTA=2   //S型曲线
}SpeedCurveType;

  在这里我们需要将曲线类型初始化为T形速度规划曲线。具体操作如下:

  curve.curveMode=CURVE_TRAP;

  初始化完成之后就可以使用曲线对象来实现电机速度的调节了。使用也很简单,只要按一定的时间周期调用我们前面实现的MotorVelocityCurve函数就可以实现整个调速过程。具体如下:

  MotorVelocityCurve(&curve);

  在每次调速开始之前都需要设置取下的开始速度和目标速度,这样函数就会按照设定的起始速度和目标速度实现速度调整。

4、小结

  我们实现了梯形加减速曲线,并使用其实现了具体的应用。总体来说,当我们将参数设置的合适时,所起到的效果也是非常明显的。在我们的实际使用过程中,梯形曲线对大多数的应用基本都合适。不仅是在启动和停车过程,在运行过程中如果速度设定发生改变,也会调用曲线实现加减速过程。

  梯形速度曲线虽说实现简单,在一般的应用场合也能有不错的效果,但实际上还是有一定的问题。梯形速度曲线的加速度是一个常量,这就造成加速度的变化过程并不连续,在加减速阶段和匀速运动阶段的连接部分,加速度会发生突变,而这种突变可能会对控制目标产生冲击,而有些应用场合这种冲击是不允许的。

欢迎关注:

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

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

相关文章

文件系统应用笔记之一:FatFS在STM32F4上的移植

在实现如U盘文件读写&#xff0c;SD卡的文件读写等工作时&#xff0c;我们往往需要一个文件系统来支持我们的工作。特别在一些MCU应用中&#xff0c;文件系统的加入能明显改善系统交互的友好性。在这一篇中&#xff0c;我们就来讨论FatFS文件系统在STM32F4上的移植和应用。 1、…

通讯接口应用笔记3:使用W5500实现Modbus TCP服务器

前面我们设计实现了W5500的驱动程序&#xff0c;也讲解了驱动的使用方式。在最近一次的项目应用中&#xff0c;正好有一个使用W5500实现TCP通讯的需求&#xff0c;所以我们就使用该驱动程序轻松实现。这一篇中我们就来说一说基于我们W5500通讯驱动程序实现TCP通讯的过程。 1、…

电机速度曲线规划2:S形速度曲线设计与实现

电机驱动是很常见的应用&#xff0c;在很多系统中我们都会碰到需要改变电机的速度以实现相应的控制功能&#xff0c;这就涉及到电机速度曲线规划的问题。在这篇中我们就来简单讨论一下电机的S型曲线规划的问题。 1、基本原理 S型速度曲线控制算法是工业控制领域另一种常用的加…

USB应用开发笔记之一:STM32上实现USB主机读写U盘

在项目应用中&#xff0c;经常会有对外交换数据的需求。USB接口读写U盘无疑是一种颇为方便的选择。在这一篇中&#xff0c;我们就来讨论如何在STM32上实现USB主机读写U盘文件的方法。 1、应用概述 在我们的产品上有这样一个需求&#xff0c;希望通过大容量的U盘存取数据。我们…

Modbus协议栈综合实例设计

自我们开源了我们的Modbus协议栈之后&#xff0c;就一直有朋友来信说希望提供示例。这次我们整理了几个例子以供参考。 1、应用实例规划 在这次的实例中&#xff0c;我们使用的目标板拥有一个以太网接口、一个RS232串行接口和一个RS485串行接口&#xff0c;所以我们规划实现&a…

ThreadX应用开发笔记之二:移植ThreadX到STM32H7平台

前面我们将ThreadX成功移植到了STM32F4平台&#xff0c;但这只是我们的部分应用。我们希望将ThreadX的优势发挥到我们的更多应用中&#xff0c;所以在这一篇中我们就来实现将ThreadX移植到STM32H7平台中。 1、前期准备 在开始将ThreadX移植到STM32H7平台之前&#xff0c;我们需…

外设驱动库开发笔记31:S-Modlue远红外气体传感器驱动

在气体分析类产品中&#xff0c;我们经常会用到远红外气体传感器。我们就在碳氢类气体成分分析中使用了S-Modlue远红外气体传感器。接下来&#xff0c;我们将讨论S-Modlue远红外气体传感器驱动的设计与实现。 1、功能概述 S-MODULE EVO 使用非分散红外检测技术NDIR&#xff0c…

外设驱动库开发笔记32:HLPM025K3 PM2.5传感器驱动

现在人们对大气环境及室内环境都比较关注。PM2.5在生活中也是常见的词汇。在有些产品中就要求检测PM2.5的数值。检测PM2.5的手段多种多样&#xff0c;在要求不高时我们通常可以采用激光模块。在这一篇中&#xff0c;我们将讨论HLPM025K3 PM2.5传感器驱动的设计与实现。 1、功能…

外设驱动库开发笔记33:LCD1602液晶显示屏驱动

LCD1602是一种工业字符型液晶&#xff0c;能够同时显示16x02即32个字符。LCD1602液晶显示的原理是利用液晶的物理特性&#xff0c;通过电压对其显示区域进行控制&#xff0c;即可以显示出图形。在这一章我们就来讨论LCD1602液晶显示屏驱动的设计与实现。 1、功能概述 LCD1602液…

滤波器开发之四:基于算术平均的中值滤波器

在信号采集系统中&#xff0c;除了我们感兴趣的数据外&#xff0c;难免会有一些来自于环境的干扰信号。但我们总希望我们得到的数据是纯净而真实的&#xff0c;为了达到这个目标&#xff0c;我们不得不想办法去除这些干扰信号&#xff0c;于是滤波器就成为我们必不可少的帮手。…

LwIP应用开发笔记之十一:LwIP带操作系统UDP服务器

我们已经实现了在FreeRTOS系统上的LwIP的移植工作&#xff0c;但只是简单的在系统平台上跑了起来。我们还希望能做更多的事情&#xff0c;这一节我们就在FreeRTOS系统上实现基于LwIP的UDP服务器。 1、UDP协议简述 UDP协议全称是用户数据报协议&#xff0c;在网络中它与TCP协议…

滤波器开发之五:基于算术平均的限幅滤波器

通过AD采集数据时&#xff0c;我们总是希望采集到的数据是纯净而真实的&#xff0c;而实际上环境中存在太多的干扰信号&#xff0c;为了让我们得到的数据尽可能地接近实际值&#xff0c;我们需要降低这些干扰信号的影响。所以软件实现的数字滤波器应运而生&#xff0c;这一篇我…

外设驱动库开发笔记34:OLED显示屏驱动

现在OLED显示屏在嵌入式系统中应用的越来越多。对于一些显示信息不太复杂&#xff0c;以显示信息为主的需求&#xff0c;我们一般会选择OLED显示屏。在这一篇中&#xff0c;我们将讨论OLED显示屏驱动的设计与实现。 1、功能概述 从使用的情况来说&#xff0c;较为常用的是0.96…

外设驱动库开发笔记35:迪文触摸屏驱动

有些时候嵌入式系统也需要显示更为复杂的图形&#xff0c;需要更丰富的数据展示。为此&#xff0c;我们需要更大&#xff0c;色彩更丰富&#xff0c;带触屏的显示屏&#xff0c;当然性价比更高就最好了。在我们的项目中遇到此类需求&#xff0c;我们有时会选择DWIN触摸屏。在本…

快速实现一个室内空气质量检测仪

冬天我们大多会关闭门窗&#xff0c;而依靠暖通空调设备来维持室内温度。而在保证居室温度的同时&#xff0c;我们也希望保持居室内大气环境的健康度。鉴于此&#xff0c;我们设计了一个简单的室内空气质量检测器。 1、系统概述 我们依靠暖通空调设备来维持室内温度、湿度和通…

外设驱动库开发笔记36:NTC负温度系数热电阻测温驱动

在嵌入式产品中&#xff0c;温度检测非常常见。在成本比较敏感而精度要求较低时&#xff0c;NTC电阻是个不错的选择。在这一篇中&#xff0c;我们将讨论如何和设计并实现一个通用的NTC驱动&#xff0c;以便在后续的项目中更方便的复用。 1、功能概述 NTC是指随温度上升电阻呈指…

外设驱动库开发笔记37:S1336-5BQ光敏二极管作为光度计驱动

光敏二极管能够实现很多应用&#xff0c;用于光度检测即是其一。我们在一些产品中就曾使用S1336-5BQ光敏二极管进行光度值检测。所以在本篇中&#xff0c;我们将讨论如何设计并实现S1336-5BQ光敏二极管用于光度检测的驱动。 1、功能概述 根据相关的资料&#xff0c;光电二极管…

PID控制器改进笔记之六:改进PID控制器之参数设定

前面我们发布了一系列PID控制器相关的文章&#xff0c;包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能&#xff0c;也在实际使用中取得了良好效果&#xff0c;但还有很多的细节部分可以改进以提高性能和灵活性。这篇中我们来讨论改进PID控制…

软件设计开发笔记1:基于状态机的程序设计

在编码实现的过程中&#xff0c;我们会经常使用到条件判断结构&#xff0c;而且使用起来很方便。但是在需要转移的状态比较多&#xff0c;或是条件比较复杂时&#xff0c;我们就可能需要很长的条件判断结构来处理。不过&#xff0c;过于复杂的条件判断结构会给代码的编写和维护…

外设驱动库开发笔记38:RTD热电阻测温驱动

我们已经讨论过多种温度检测方式&#xff0c;但我们尚未关注热电阻温度检测&#xff0c;但热电阻测温在工业环境中是非常常见的。尽管有很多集成的数字式的热电阻接口元器件&#xff0c;但这些器件不但成本较高&#xff0c;灵活性也大打折扣。所以我们有时会使用更简单灵活的电…