GRBL源码简单分析
结构体说明
GRBL里面的速度规划是带运动段前瞻的,所以有规划运动段数据和微小运动段的区分
这里的“规划运动段”对应的数据结构是plan_block_t,前瞻和加减速会使用到,也就是通过解析G代码后出来的直接直线数据或是圆弧插补出来的拟合直线数据
“微小运动段”对应的数据结构是segment_t,加减速的终端数据持有者,也就是plan_block_t数据经过了加减速后的计算数据
plan_block_t的数据还有一个临时的数据缓冲区,st_block_buffer,作用如上所述,其中存储的是脉冲发生ISR里面需要用到的数据
stepper.c里面有个静态变量static st_prep_t prep,这个变量是plan_block_t数据转换为segment_t数据时的一个缓冲,即从plan_block_t里面提取相关数据,然后生成新的segment_t数据
加减速处理
加减速处理在stepper.c的st_prep_buffer()函数里,流程为:
1.segment_t缓冲区有空余位置才会进行加减速数据生成,否则退出函数;有接收到停止运动指令,同样停止生成数据
2.从规划器的plan_block_t队列里面找到当前要进行分解的运动段,此处会分为“系统运动段”和“普通运动段”,就是一般操作和G代码解析的区分
3.判断prep里面的重新计算标志是否有效,有效则重新计算当前的运动段分解
什么时候会需要重新计算呢?一般是调整了速度修调(Ratio)之后,会对未被执行的运动段重新进行计算
4.如果不需要重新计算了,则直接把plan_block_t里面对应的Bresenham算法需要用到的脉冲输出阈值和总步数,记录到st_block_buffer里面
5.此时开始根据plan_block_t里面的数据和系统当前状态来确定加减速的状态,这里有好几个条件分支,其中牵扯到前瞻计算的初始速度和终止速度,以及系统的速度修调率。
5.1如果检测到系统有进给保持(HOLD)状态指令,则直接进入全减速状态(RAMP_DECEL)
5.2如果速度修调被降低了,则判断当前运动段的距离够不够减速到对应的终止速度,不够则进入全减速状态(RAMP_DECEL),如果是足够的,则进入半减速状态(RAMP_DECEL_OVERRIDE),如果是进入了规划的减速段,则也进入全减速状态(RAMP_DECEL)
5.3如果是速度修调被升高了,或是一开始进入加速运动,则要进入加速状态(RAMP_ACCEL)
5.4如果是加速到了目标速度,则应该进入匀速状态(RAMP_CRUISE)
5.5其中,在加速状态的时候,可以计算出要进行梯形加减速还是三角形加减速
6.在确定了当前运动段的加减速状态后,则根据该状态进行segment_t微小运动段的分解计算,分解计算是依靠一个固定的时基DT_SEGMENT来进行的
注意,该固定时基只在计算segment_t数据时使用,跟脉冲发生的时间没有直接关系
7.分解微小运动段的方法是:根据加减速状态和pl_block的速率,算出在DT_SEGMENT单元时间内的进给量(即应输出的脉冲量)
7.1半减速处理(RAMP_DECEL_OVERRIDE):首先计算减速到目标速度的时间,然后算出减速状态下的进给,再把加减速状态设置为匀速状态(RAMP_CRUISE),剩下的时间会在循环条件里再次进入匀速状态计算进给
7.2全加速处理(RAMP_ACCEL):计算全加速下,是否会到达运动段的加速段目标位置,如果还可以加速,则继续处于全加速状态,否则看加减速是梯形条件还是三角形条件,如果是梯形则进入匀速状态(RAMP_CRUISE),如果是三角形则进入全减速状态(RAMP_DECEL)
7.3匀速处理(RAMP_CRUISE):计算匀速段是否结束了,是则进入全减速状态(RAMP_DECEL),否则保持该状态;另外,如果匀速状态在DT_SEGMENT时间内就结束了,同样地,把剩余时间在全减速状态再计算一次进给量
7.4全减速处理(RAMP_DECEL):如果剩余的距离还可以继续减速,则保持该状态,然后计算出该次的进给量;如果剩余的距离可以在该次减速中完成,则要算出完成减速的时间量和进给量,然后退出该运动段pl_block的加减速
7.5另外,加减速处理中有“最小步”的输出要求,如果在1个DT_SEGMENT内,没有达到“最小步”的要求,则继续累加1个DT_SEGMENT的时间,知道满足“最小步”输出要求,才退出步骤7
8.要注意的是,步骤5是segment_t根据pl_block_t的状态初始化自己数据的流程,里面有步骤7计算时需要用到的初始数据
步骤7是计算一个完整segment_t数据的流程,里面有输出脉冲的条件数据,比如在多长的时间内输出多少个脉冲
然后就是初始化T1定时器计数,并且触发ISR,在ISR中计算脉冲输出条件
9.另外,1个pl_block_t可以分解成很多个segment_t,如果segment_t的缓冲满了,pl_block_t还没有结束,则暂停生成segment_t,等缓冲区空闲了再计算,否则会一直生成segment_t;
相反,也有可能1个pl_block_t就对应1个segment_t,且segment_t可能会在DT_SEGMENT内就完成了pl_block_t的目标距离,时间是以实际计算的为准
10.脉冲输出的时基,即T1定时器的溢出中断计数,是根据segment_t的需要输出脉冲数和segment_t使用的时间(不一定是DT_SEGMENT)来直接计算的。在单个segment_t的脉冲输出期间,T1的溢出中断时间间隔一致,但一般不同的segment_t会有不同的T1时间间隔
pl_block->step_event_count 是完成这个block所需走的步数,就是steps[x], steps[y], steps[z], 的最大值,即是三个轴中的最长轴。如果某个轴是最长轴,意味着这个轴的步进电机每个中断都有脉冲输出。
其他轴按照DDA算法输出
所谓的DDA算法如下
假设从P0点(0,0,0)插补到P1点(2,4,8),坐标分别对应X,Y,Z,则最长轴是Z,每个周期应该Z步数增加1个单位,总共需要8个周期
再假设event_step = 8,step_x = 2,step_y = 4,step_z = 8,cnt_x = cnt_y = cnt_z = 0;
要Z每个周期都输出脉冲,则有:
cnt_x += step_x;
if (cnt_x >= event_step) {输出X脉冲,cnt_x -= event_step} //这里会在第4和第8个周期分别输出脉冲
cnt_y += step_y;
if (cnt_y >= event_step) {输出Y脉冲,cnt_y -= event_step} //这里会在第2/4/6/8个周期分别输出脉冲
cnt_z += step_z;
if (cnt_z >= event_step) {输出Z脉冲,cnt_z -= event_step} //每个周期都输出脉冲
你按照每个周期来算一下就知道,X/Y/Z会按照插值法来输出脉冲了,这个就是DDA的一个例子
假设需要从点(0,0,0)到点(31,21,5),从(0,0,0)到(31,21,5)最终的执行结果是X轴步进电机移动31步、Y轴步进电机移动21步、Z轴步进电机移动了5步。
那么代码执行的详细情况如下
current_block->steps[X_AXIS] = 31;
current_block->steps[Y_AXIS] = 21;
current_block->steps[Z_AXIS] = 5;
current_block->step_event_count = 31;
//st.counter_x = st.counter_y = st.counter_z = (st.exec_block->step_event_count >> 1);
counter_x = (current_block->step_event_count>>1) = 15;
counter_y = counter_z = counter_e = counter_x;
第一步
Counter_x = counter_x + current_block->steps[X_AXIS] = 15 + 31 = 46;
因为条件counter_x > current_block->step_event_count为true, 所以X电机向前走一步
counter_x = counter_x - current_block->step_event_count = 46 - 31; = 15;
counter_y = counter_y + current_block->steps[Y_AXIS] = 15 + 21 = 36;
因为条件counter_y > current_block->step_event_count为true,所以Y电机向前走一步
counter_y = counter_y - current_block->step_event_count = 36 - 31 = 5;
counter_z = counter_z + current_block->steps[Z_AXIS] = 15 + 5 = 20;
因为条件counter_z > current_block->step_event_count为false,所以Z电机不动
第二步
Counter_x = counter_x + current_block->steps[X_AXIS] = 15 + 31 = 46;
因为条件counter_x > current_block->step_event_count为true, 所以X电机向前走一步
counter_x = counter_x - current_block->step_event_count = 46 - 31 = 15;
counter_y = counter_y + current_block->steps[Y_AXIS] = 5 + 21 = 26;
因为条件counter_y > current_block->step_event_count为false,所以Y电机不动
counter_z = counter_z + current_block->steps[Z_AXIS] = 20 + 5 = 25;
因为条件counter_z > current_block->step_event_count为false,所以Z电机不动
相关文章:
GRBL源码简单分析
结构体说明 GRBL里面的速度规划是带运动段前瞻的,所以有规划运动段数据和微小运动段的区分 这里的“规划运动段”对应的数据结构是plan_block_t,前瞻和加减速会使用到,也就是通过解析G代码后出来的直接直线数据或是圆弧插补出来的拟合直线数据…...
第一部分:简单句——第一章:简单句的核心——二、简单句的核心变化(谓语动词的情态)
二、简单句的核心变化 简单句的核心变化其实就是 一主一谓(n. v.) 表达一件事情,谓语动词是其中最重要的部分,谓语动词的变化主要有四种:三态加一否(时态、语态、情态、否定),其中…...
软考高级考试中有五大证书,其中哪个更值得考?
计算机软考属于专业技术人员职业资格水平评价类,是职业资格、专业技术资格(职称)和专业技术水平"三合一"的考试,是目前IT行业仅有的国家级考试。考试不受学历、专业、资历等条件限制。软考高级考试中有五大证书…...
FlexRay™ 协议控制器 (E-Ray)-04
网络管理 累积的网络管理 (NM) 向量位于网络管理寄存器 1 到网络管理寄存器 3 (NMVx (x = 1-3)) 中。【The accrued Network Management (NM) vector is located in the Network Management Register 1 to Network Management Register 3 (NMVx (x = 1-3)).】 网络管理向量 x…...
container_of 根据成员变量获得包含其的对象的地址!
写在前面 本系列文章的灵感出处均是各个技术书籍的读后感,详细书籍信息见文章最后的参考文献 CONTAINER_OF 在书中发现一个很有意思的宏,以此可以衍生出来其很多的用法,这个宏可以根据某个成员变量的地址得到包含这个成员变量地址的对象的…...
Linux进程概念
Linux进程概念前言冯诺依曼体系操作系统设计操作系统的目的如何理解OS是一款搞“管理”的软件?系统调用和库函数的概念进程的概念描述进程组织进程查看进程fork()前言 本篇博客主要介绍一些:冯诺依曼体系、OS的理解、进程的一些概…...
算法设计与分析
两个例子:调度问题与投资问题 例1:调度问题 问题 有 n 项任务,每项任务加工时间已知.从 0时刻开始陆续安排到一台机器上加工. 每个任务的完成时间是从 0 时刻到任务加工截止的时间. 求: 总完成时间(所有任务完成时间之和)最短…...
C++ 基础
命名空间 在 C/C 中,变量、函数和类都是大量存在的,这些变量、函数和类的名称将都存在全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace 关键字的…...
[golang gin框架] 2.Gin HTML模板渲染以及模板语法,自定义模板函数,静态文件服务
一.Gin HTML 模板渲染全部模板放在一个目录里面的配置方法首先在项目根目录新建 templates 文件夹,然后在文件夹中新建 对应的index.html<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta http…...
数据仓库层Repository(CrudRepository、PagingAndSortingRepository、JpaRepository)
什么是数据仓库层Repository? 数据仓库接口的作用:Repository原意指的是仓库,即数据仓库的意思。Repository居于业务层和数据层之间,将两者隔离开来,在它的内部封装了数据查询和存储的逻辑。 Repository接口ÿ…...
大数据技术架构(组件)33——Spark:Spark SQL--Join Type
2.2.2、Join Type2.2.2.1、Broadcast Hash Join (Not Shuffled)就是常说的MapJoin,join操作在map端进行的。场景:join的其中一张表要很小,可以放到Driver或者Executor端的内存中。原理:1、将小表的数据广播到所有的Executor端,利用collect算子…...
Linux: bash起后台进程引发的僵尸进程
1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 2. 案例 原来的故事是 这样 的,感兴趣的读者可以直接前往。我从中截取了一段重现故事中问题的代码(对原代码做了小小调整&a…...
网络安全攻防中,Rock-ON自动化的多功能网络侦查工具,Burpsuite被动扫描流量转发
网络安全攻防中,Rock-ON自动化的多功能网络侦查工具,Burpsuite被动扫描流量转发。 #################### 免责声明:工具本身并无好坏,希望大家以遵守《网络安全法》相关法律为前提来使用该工具,支持研究学习ÿ…...
电子技术——共模抑制
电子技术——共模抑制 我们在之前学习过,无论是MOS还是BJT的差分输入对,共模信号并不会改变漏极电流的大小,因此我们说差分输入对共模信号无响应。但是实际上由于各种客观非理想因素,例如电流源有限阻抗等,此时共模是影…...
对KMP简单的理解
声明:下边的例子均表示下标从1开始的数组 ne数组的定义: next[i] 就是使子串 s[1…i] 有最长相等前后缀的前缀的最后一位的下标。ne[i]也可以表示相等子串的长度 准备执行jne[j]时, 表示当前s[i]!p[j1] , 如果ne[j]1 ,那么下…...
Hibernate不是过时了么?SpringDataJpa又是什么?和Mybatis有什么区别?
一、前言 ps: 大三下学期,拿到了一份实习。进入公司后发现用到的技术栈有Spring Data Jpa\Hibernate,但对于持久层框架我只接触了Mybatis\Mybatis-Plus,所以就来学习一下Spring Data Jpa。 1.回顾MyBatis 来自官方文档的介绍:MyBatis 是一款…...
数学建模拓展内容:卡方检验和Fisher精确性检验(附有SPSS使用步骤)
卡方检验和Fisher精确性检验卡方拟合度检验卡方独立性检验卡方检验的前提假设Fisher精确性检验卡方拟合度检验 卡方拟合度检验概要:卡方拟合度检验也被称为单因素卡方检验,用于检验一个分类变量的预期频率和观察到的频率之间是否存在显著差异。 卡方拟…...
【Python学习笔记之七大数据类型】
Python数据类型:Number数字、Boolean布尔值、String字符串、list列表、tuple元组、set集合、dictionary字典 int整数 a1 print(a,type(a))float浮点数 b1.1 print(b,type(b))complex复数 c100.5j print(c,type(c))bool布尔值:True、False,true和false并非Python…...
Android系统之onFirstRef自动调用原理
前言:抽丝剥茧探究onFirstRef究竟为何在初始化sp<xxx>第一个调用?1.onFirstRef调用位置<1>.system/core/libutils/RefBase.cpp#include <utils/RefBase.h>//1.初始化强指针 void RefBase::incStrong(const void* id) const {weakref_i…...
ipv6上网配置
一般现在的宽带都已经支持ipv6了,但是需要一些配置才能真正用上ipv6。记录一下配置过程。 当前测试环境为移动宽带,光猫下面接了一个路由器,家里所有的设备都挂到这个路由器下面的。 1. 光猫改桥接 光猫在使用路由模式下,ipv6无…...
python实现聚类技术—复杂网络社团检测 附完整代码
实验内容 某跆拳道俱乐部数据由 34 个节点组成,由于管理上的分歧,俱乐部要分解成两个社团。 该实验的任务即:要求我们在给定的复杂网络上检测出两个社团。 分析与设计 实验思路分析如下: 聚类算法通常可以描述为用相似度来衡量两个数据的远近,搜索可能的划分方案,使得目标…...
如何判断两架飞机在汇聚飞行?(如何计算两架飞机的航向夹角?)内含程序源码
ok,在开始一切之前,让我先猜一猜,你是不是想百度“二维平面下如何计算两个移动物体的航向夹角?”如果是,那就请继续往下看。 首先,我们要明确一个概念:航向角≠航向夹角!࿰…...
Scipy稀疏矩阵bsr_array
文章目录基本原理初始化内置方法基本原理 bsr,即Block Sparse Row,bsr_array即块稀疏行矩阵,顾名思义就是将稀疏矩阵分割成一个个非0的子块,然后对这些子块进行存储。通过输入维度,可以创建一个空的bsr数组࿰…...
LeetCode笔记:Weekly Contest 332
LeetCode笔记:Weekly Contest 332 1. 题目一 1. 解题思路2. 代码实现 2. 题目二 1. 解题思路2. 代码实现 3. 题目三 1. 解题思路2. 代码实现 4. 题目四 1. 解题思路2. 代码实现 比赛链接:https://leetcode.com/contest/weekly-contest-332/ 1. 题目一…...
autox.js在vscode(win7)与雷神模拟器上的开发环境配置
目录 下载autox.js 安装autox.js? 在电脑上搭建autox.js开发环境 安装vscode 安装autox.js插件 雷神模拟器连接vscode 设置雷神模拟器IP 设置autox.js应用IP地址等 下载autox.js 大体来说,就是一个运行在Android平台上的JavaScript 运行环境 和…...
创建阿里云物联网平台
创建阿里云物联网平台 对云平台设备创建过程做记录,懒得再看视频 文章参考视频:https://www.bilibili.com/video/BV1jP4y1E7TJ?p26&vd_source50694678ae937a743c59db6b5ff46c31 阿里云:https://www.aliyun.com 1.物联网平…...
【链式二叉树】数据结构链式二叉树的(万字详解)
前言: 在上一篇博客中,我们已经详解学习了堆的基本知识,今天带大家进入的是二叉树的另外一种存储方式----“链式二叉树”的学习,主要用到的就是“递归思想”!! 本文目录1.链式二叉树的实现1.1前置说明1.2结…...
Koa2篇-简单介绍及使用
一.简介koa2是基于 Node.js 平台的下一代 web 开发框架, 致力于成为一个更小、更富有表现力、更健壮的 Web 框架。 可以避免异步嵌套. express中间件是异步回调,Koa2原生支持async/await二.async/awaitconst { rejects } require("assert"); const { resolve } req…...
Linux ALSA 之十一:ALSA ASOC Path 完整路径追踪
ALSA ASOC Path 完整路径追踪一、ASoc Path 简介二、ASoc Path 完整路径2.1 tinymix 设置2.2 完整路径 route一、ASoc Path 简介 如前面小节所描述,ASoc 中 Machine Driver 是 platform driver 和 codec driver 的粘合剂,audio path 离不开 FE/BE/DAI l…...
【Spring Cloud总结】1、服务提供者与服务消费者快速上手
目录 文件结构 代码 1、api 1.1实体类(Dept ) 1.2数据库 2、provider 2.1 DeptController 2.2 DeptDao 2.3 DeptService 2.4 DeptServiceImpl 2.5 application.yml 3、consumer 3.1 ConfigBean 3.2 DeptConsumerController 测试 1.启动…...
如何做同城信息网站/网站搭建需要什么
文章目录文章参考获取dom节点高宽的通用方法案例说明getBoundingClientRect() 获取DOM 的高度和宽度的办法?文章参考 原生js操作dom添加删除替换class你了解getBoundingClientRect()? 获取dom节点高宽的通用方法 dom.style.widt…...
山东省住房城乡建设厅查询网站/企业管理系统
新建 ctrl n格式化 ctrlshiftf导入包 ctrlshifto 注释 ctrl/,ctrlshift/,ctrlshift\代码上下移动 选中代码alt上/下箭头查看源码 选中类名(F3或者Ctrl鼠标点击)查找具体的类 ctrl shift t查找具体类的具体方法 ctrl o给建议 ctrl1,根据右边生成左边的数据类型,生成方法删除…...
wordpress高级插件/网址域名大全2345网址
我们在学习linux时一般都是在文字界面下操作的,那有时需要进入到图形界面,但是系统在安装时,并没有安装图形界面包。今天我们来学习下Linux图形界面的安装卸载。以下操作前提需要配好本地YUM源。详见《Linux运维工程师的第十天(配置本地YUM源…...
梅州网站建设/广告推广怎么做
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如: class CExample { public:int a;float b;//构造函数初始化列表CExample(): a(0),b(8.8){}//构造函数内部赋值CExampl…...
南宁网站制作-中国互联/优化设计官方电子版
安装前先关闭杀毒软件和360卫士,注意安装路径不能有中文,安装包路径也不要有中文。[安装环境]:Win7/Win8/Win101.鼠标右击【VMware 15.5.0】压缩包选择【解压到VMware 15.5.0】。2.双击打开解压后的【VMware 15.5.0】文件夹。3.鼠标右击【VMw…...
wordpress 国内优化/视频互联网推广选择隐迅推
程序中为了让更直观的反映命令执行的进度,考虑使用进度条,但是asp.net中没有专门的进度条控件,在网上搜了一下,实现方法都很复杂,就自己动手做了一个,实现起来其实也很简单。后来又想了个方法,加…...