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

2023-10-27

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

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、小结

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

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

欢迎关注:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

电机速度曲线规划1:梯形速度曲线设计与实现 的相关文章

  • 面试官:Java为什么只有值传递?

    面试官爱问的一个基础问题 Java是值传递还是引用传递 想必大家都对这个问题都有自己的看法 那到底事实是怎样的 我们又该如何回答面试官这个问题呢 今天咱们就来好好分析一波 值传递 引用传递 首先 我们得先知道什么叫值传递 什么叫引用传递 知
  • Git第十八讲 Git常见问题解决

    Git常见问题解决 在使用 Git 进行版本控制时 你可能会遇到一些常见问题和错误 本文将介绍一些常见问题 并提供解决方案 以帮助你更好地使用 Git 1 Git 报错和常见问题解决方案 Git 在使用过程中可能会产生各种报错信息 这些错误

随机推荐

  • 刷脸支付全国范围火爆招募合伙人

    出门不带钱 买任何东西都靠手机的生活已经完全颠覆了我们对社会生活的认知 而这样改变仅仅出现3年之久 往前追溯 我们会发现 眼下的信息技术进步呈爆炸式递增的态势 刷脸支付技术的出现与应用 更是将信息生活的便捷度提升到了一个更高的档次上 除了让
  • 524. Longest Word in Dictionary through Deleting

    Given a string and a string dictionary find the longest string in the dictionary that can be formed by deleting some cha
  • [pcl::VoxelGrid::applyFilter] Leaf size is too small for the input dataset 报错解决,亲测可行

    pcl VoxelGrid applyFilter Leaf size is too small for the input dataset 报错解决 亲测可行 1 报错日志 Python pcl 点云下采样时报错如下 pcl VoxelG
  • Android 通过WebService进行网络编程,使用工具类轻松实现

    相信大家在平常的开发中 对网络的操作用到HTTP协议比较多 通过我们使用Get或者Post的方法调用一个数据接口 然后服务器给我们返回JSON格式的数据 我们解析JSON数据然后展现给用户 相信很多人很喜欢服务器给我们返回JSON数据格式
  • 软件测试/测试开发丨利用ChatGPT自动生成测试用例思维导图

    点此获取更多相关资料 简介 思维导图是一种用图形方式表示思维和概念之间关系的工具 有些公司会使用思维导图编写测试用例 这样做的优点是 1 可视化和结构化 2 易于理解 提高效率 而 ChatGPT 是无法直接生成 xmind 格式的文件的
  • webdriver.Chrome()报错:selenium.common.exceptions.WebDriverException: Message: 'chromedriver' ...

    使用selenium模块的webdriver打开谷歌浏览器的时候报错 源代码如下 from selenium import webdriver browser webdriver Chrome print type browser brow
  • 12-8 副作用与纯函数

    1 副作用 函数副作用 指当调用函数时 除了返回函数值之外 还对主调用函数产生附加的影响 例如修改全局变量 函数外的变量 或修改参数 表达式副作用 在表达式求值过程中 需要获取变量的值 但并不改变这些变量的值 这样的表达式称为无副作用的表达
  • 关于Visual Studio内登录microsoft账号白屏问题的解决办法

    如果连接常规Wi Fi无效的话可尝试以下方法 1 断开Wi Fi连接 关闭程序 2 打开手机热点 使电脑连接上 3 再次打开程序进行输入账号与密码的操作 4 此时尝试登录可有效避免白屏卡顿现象 亲测有效 PS 本人WiFi为中国电信 手机卡
  • 怎样使用Cubase进行人声消除

    所谓分离伴奏 指的就是消除人声 通常在一首歌曲的音频文件中 混音师一般都会将人声放在声像位置的正中间再输出为一个立体声音频文件 一般情况下是这样 但不代表全是这样 因此 人声的波形在该立体声音频文件的左声道和右声道中应该是相同或相似的 所以
  • 不好意思, Maven 该换了!

    相信使用Java的同学都用过Maven 这是一个非常经典好用的项目构建工具 但是如果你经常使用Maven 可能会发现Maven有一些地方用的让人不太舒服 一来Maven的配置文件是XML格式的 假如你的项目依赖的包比较多 那么XML文件就会
  • SLAM代码(三维重建)

    版权声明 本文为博主原创文章 遵循 CC 4 0 BY SA 版权协议 转载请附上原文出处链接和本声明 本文链接 https blog csdn net wendox article details 52719252 三维重建的一般步骤 特
  • 爬虫隐藏自身的ip并伪装成浏览器

    爬虫隐藏自身的ip并伪装成浏览器 使用代理访问 就是说使用代理 代理 访问url之后 再将网页的内容在传给本机的 使用代理访问 import urllib request import random url http www whatism
  • 堆排序【C语言】

    堆排序 基本思想 利用堆 小顶堆 进行排序的过程 首先把待排序序列 R1 R2 Rn 转换成一个堆 这时 根结点具有最小值 输出根结点 可以将其与堆数组中的末尾元素交换 此时末尾元素就是最小值 然后将剩下的n 1个结点重新调整为一个堆 反复
  • vue-element el-table 使用sortablejs拖拽排序

    需求描述 vue element admin开发过程中需要对el table行进行排序 即每一行可以上下移动 然后将排序后的数据传给后台更新数据 该表格无分页 问题分析 方法一 可以采用在每条数据中加两个上下移动的按钮 每次移动一行 该方法
  • 自制脚本语言(12) 作用域与符号表

    摘要 介绍了自制语言的编译器对符号表的处理 YF语言中 符号表的基本结构是hash表 每个AST 附带了3个hash表 变量表 类型表 函数表 例如
  • python Django项目点击run或debug时出现Type ‘manage.py help <subcommand>‘ for help on a specific subcommand.

    报错 D python3 7 python exe E code dailyfresh test1 test2 manage py Type manage py help
  • python requests cookies怎么转为_如何将requests.RequestsCookieJar转换为字符串

    新答案 好吧 所以我还是不知道你到底想达到什么目的 如果您想从requests RequestCookieJar对象中提取原始url 这样您就可以检查是否与给定的子域匹配 这是 据我所知 不可能的 不过 你也可以做些类似的事情 usr bi
  • Linux-线程的同步与互斥

    线程的同步与互斥 进程 线程间的互斥相关背景概念 互斥量 互斥量接口 互斥量的初始化 互斥量的销毁 加锁和解锁 改善抢票系统 互斥量原理 可重入与线程安全 重入和线程安全的概念 常见线程不安全情况 常见线程安全的情况 常见不可重入情况 常见
  • 【软件工程】-可行性研究报告

    GB8567 88 可行性研究报告 1引言 1 1编写目的 为了提高机房收费管理的灵活性和效率 减轻机房工作人员的工作负担 节约时间 对机房收费业务做到快速准确管理的目的 从而降低人力 经济的更各方面的消耗 本次编写主要是为了分析廊坊师范学
  • 电机速度曲线规划1:梯形速度曲线设计与实现

    电机驱动是很常见的应用 在很多系统中我们都会碰到需要改变电机的速度以实现相应的控制功能 这就涉及到电机速度曲线规划的问题 在这篇中我们就来简单讨论一下电机的梯形曲线规划的问题 1 基本原理 梯形速度曲线控制算法是工业控制领域应用最为广泛的加