【龙印】3d打印固件Marlin中bresenham算法注解
2016-08-29 16:54
537 查看
本文为在用龙芯1c做3D打印机过程中的笔记。龙芯1c做的3d打印机简称“龙印”
参考了以下两篇博文,再其基础上增加了对marlin源码的注解和我的一些理解。
http://blog.sina.com.cn/s/blog_6ad165790102vo09.html http://blog.sina.com.cn/s/blog_679933490102vv8z.html
先来看一下marlin中bresenham算法的相关代码。源码位于源文件“Marlin\stepper.cpp”中的函数ISR(TIMER1_COMPA_vect)内。如下
阅读这段代码的主要麻烦在宏STEP_ADD和STEP_IF_COUNTER。
符号“##”的作用是把前后的宏参数拼接在一起。
我们来分析“STEP_ADD(x,X)”
STEP_ADD(x,X)=_COUNTER(x) += current_block->steps[_AXIS(AXIS)]; \
if (_COUNTER(x) > 0) { _APPLY_STEP(X)(!_INVERT_STEP_PIN(X),0); }
其中,_COUNTER(x)=counter_x
_APPLY_STEP(X)=X_APPLY_STEP
_INVERT_STEP_PIN(X)=INVERT_X_STEP_PIN
_AXIS(AXIS)也类似,搜索源码会发现有“#define _AXIS(AXIS) AXIS ##_AXIS”。
宏STEP_IF_COUNTER也类似。
经过整理后bresenham算法可以表示为
这个代码很清晰了,可是怎么也看不出有个什么算法,哈哈。
bresenham算法是光栅化的画直线算法。直线光栅化是指用像素点来模拟直线,比如下图用蓝色的像素点来模拟红色的直线。
蓝色点是怎么得到的呢?取与理想中的红点最近的xy轴的交点作为蓝点。
算法是怎么与marlin源码结合的呢?
假设需要从点(0,0,0)到点(31,21,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;
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 = 16;
因为条件counter_x > 0为true, 所以X电机向前走一步
counter_x = counter_x - current_block->step_event_count = 16 - 31; = -15;
counter_y = counter_y + current_block->steps[Y_AXIS] = -15 + 21 = 6;
因为条件counter_y > 0为true,所以Y电机向前走一步
counter_y = counter_y - current_block->step_event_count = 6 - 31 = -25;
counter_z = counter_z + current_block->steps[Z_AXIS] = -15 + 5 = -10;
因为条件counter_z > 0为false,所以Z电机不动
counter_z = -10;
第二步
Counter_x = counter_x + current_block->steps[X_AXIS] = -15 + 31 = 16;
因为条件counter_x > 0为true, 所以X电机向前走一步
counter_x = counter_x - current_block->step_event_count = 16 - 31 = -15;
counter_y = counter_y + current_block->steps[Y_AXIS] = -25 + 21 = -4;
因为条件counter_y > 0为false,所以Y电机不动
counter_y = -4;
counter_z = counter_z + current_block->steps[Z_AXIS] = -10 + 5 = -5;
因为条件counter_z > 0为false,所以Z电机不动
counter_z = -10;
第三步
同理
……
参考了以下两篇博文,再其基础上增加了对marlin源码的注解和我的一些理解。
http://blog.sina.com.cn/s/blog_6ad165790102vo09.html http://blog.sina.com.cn/s/blog_679933490102vv8z.html
先来看一下marlin中bresenham算法的相关代码。源码位于源文件“Marlin\stepper.cpp”中的函数ISR(TIMER1_COMPA_vect)内。如下
// If there is no current block, attempt to pop one from the buffer if (!current_block) { // Anything in the buffer? current_block = plan_get_current_block(); if (current_block) { current_block->busy = true; trapezoid_generator_reset(); counter_x = -(current_block->step_event_count >> 1); counter_y = counter_z = counter_e = counter_x; step_events_completed = 0; #if ENABLED(Z_LATE_ENABLE) if (current_block->steps[Z_AXIS] > 0) { enable_z(); OCR1A = 2000; //1ms wait return; } #endif // #if ENABLED(ADVANCE) // e_steps[current_block->active_extruder] = 0; // #endif } else { OCR1A = 2000; // 1kHz. } } if (current_block != NULL) { // Update endstops state, if enabled #if ENABLED(HAS_Z_MIN_PROBE) if (check_endstops || z_probe_is_active) update_endstops(); #else if (check_endstops) update_endstops(); #endif // Take multiple steps per interrupt (For high speed moves) for (int8_t i = 0; i < step_loops; i++) { #ifndef USBCON customizedSerial.checkRx(); // Check for serial chars. #endif #if ENABLED(ADVANCE) counter_e += current_block->steps[E_AXIS]; if (counter_e > 0) { counter_e -= current_block->step_event_count; e_steps[current_block->active_extruder] += TEST(out_bits, E_AXIS) ? -1 : 1; } #endif //ADVANCE #define _COUNTER(axis) counter_## axis #define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP #define _INVERT_STEP_PIN(AXIS) INVERT_## AXIS ##_STEP_PIN #define STEP_ADD(axis, AXIS) \ _COUNTER(axis) += current_block->steps[_AXIS(AXIS)]; \ if (_COUNTER(axis) > 0) { _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS),0); } STEP_ADD(x,X); STEP_ADD(y,Y); STEP_ADD(z,Z); #if DISABLED(ADVANCE) STEP_ADD(e,E); #endif #define STEP_IF_COUNTER(axis, AXIS) \ if (_COUNTER(axis) > 0) { \ _COUNTER(axis) -= current_block->step_event_count; \ count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \ _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS),0); \ } STEP_IF_COUNTER(x, X); STEP_IF_COUNTER(y, Y); STEP_IF_COUNTER(z, Z); #if DISABLED(ADVANCE) STEP_IF_COUNTER(e, E); #endif step_events_completed++; if (step_events_completed >= current_block->step_event_count) break; }
阅读这段代码的主要麻烦在宏STEP_ADD和STEP_IF_COUNTER。
符号“##”的作用是把前后的宏参数拼接在一起。
我们来分析“STEP_ADD(x,X)”
STEP_ADD(x,X)=_COUNTER(x) += current_block->steps[_AXIS(AXIS)]; \
if (_COUNTER(x) > 0) { _APPLY_STEP(X)(!_INVERT_STEP_PIN(X),0); }
其中,_COUNTER(x)=counter_x
_APPLY_STEP(X)=X_APPLY_STEP
_INVERT_STEP_PIN(X)=INVERT_X_STEP_PIN
_AXIS(AXIS)也类似,搜索源码会发现有“#define _AXIS(AXIS) AXIS ##_AXIS”。
宏STEP_IF_COUNTER也类似。
经过整理后bresenham算法可以表示为
这个代码很清晰了,可是怎么也看不出有个什么算法,哈哈。
bresenham算法是光栅化的画直线算法。直线光栅化是指用像素点来模拟直线,比如下图用蓝色的像素点来模拟红色的直线。
蓝色点是怎么得到的呢?取与理想中的红点最近的xy轴的交点作为蓝点。
算法是怎么与marlin源码结合的呢?
假设需要从点(0,0,0)到点(31,21,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;
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 = 16;
因为条件counter_x > 0为true, 所以X电机向前走一步
counter_x = counter_x - current_block->step_event_count = 16 - 31; = -15;
counter_y = counter_y + current_block->steps[Y_AXIS] = -15 + 21 = 6;
因为条件counter_y > 0为true,所以Y电机向前走一步
counter_y = counter_y - current_block->step_event_count = 6 - 31 = -25;
counter_z = counter_z + current_block->steps[Z_AXIS] = -15 + 5 = -10;
因为条件counter_z > 0为false,所以Z电机不动
counter_z = -10;
第二步
Counter_x = counter_x + current_block->steps[X_AXIS] = -15 + 31 = 16;
因为条件counter_x > 0为true, 所以X电机向前走一步
counter_x = counter_x - current_block->step_event_count = 16 - 31 = -15;
counter_y = counter_y + current_block->steps[Y_AXIS] = -25 + 21 = -4;
因为条件counter_y > 0为false,所以Y电机不动
counter_y = -4;
counter_z = counter_z + current_block->steps[Z_AXIS] = -10 + 5 = -5;
因为条件counter_z > 0为false,所以Z电机不动
counter_z = -10;
第三步
同理
……
相关文章推荐
- 【龙印】3D打印固件Marlin中限位开关相关代码解读
- 【龙印】FDM 3d打印机常见打印质量问题和解决办法
- 用智能工作流和3D打印系统建设快速生产系统(RPS)的构想
- 电脑黑客用3D打印钥匙解开高安全性能手铐
- 3D打印的“神助手”上线 CADEX和它的CAD Exchanger软件
- java注解结合aspectj AOP进行日志打印
- 3D 打印的模型 告别手动添加支撑的方式 — 使用 Meshmixer 软件
- 3d 打印模型下载网站
- 3D打印指南(四)
- 3D 打印成功挽救婴儿生命
- Hugo注解方式打印信息(方便)
- 3D打印材料的发展现状(1)
- mybatis拦截器打印sql且通过自定义注解获取sql开发人信息
- 中国正沦为3D打印的配角?
- 揭秘3d惊人打印技术
- 3D打印机又一创意 打印情人脸棒棒糖
- Semslin 3D打印固件 项目日志节选(三)—— Marlin架构解析
- 3D打印机打印出空气单车
- 郭台铭看坏 3D 打印,微软 Windows 8.1 反而大推支持 3D 打印功能