1. 最终效果图
  2. 前期准备
  3. 基本思路
  4. 环境配置
  5. 分析 Gcode
  6. 在 MC 中填充方块
  7. 项目及使用方法

1. 最终效果图

2. 前期准备

要用到的几个库的关系

  1. mcpi 模块

    python 模块,用于 python 代码向服务器发送指令
    需要注意的是,mcpi 直接与服务器通信,而跳过客户端

  2. raspberry juice 插件

    Bukkit 服务器的插件,也可以运行在 spigot 服务器上
    mcpi 模块原本只能使用在树莓派版 MC 上,RJ 插件使得其他服务器也能使用 mcpi 模块

  3. Bukkit 服务器

    MC 的服务器结构有很多种,包括官方版和很多第三方版,Bukkit 就是其中之一
    spigot 是在 Bukkit 服务器上加以优化的,所以也能运行 Bukkit 服务器插件

  4. CraftBukkit 插件

    这是一个官方服务器插件,用于支持运行 Bukkit 插件

有趣的开源库列表

  1. MC 客户端模拟,可以用于连接 MC 服务器

    https://github.com/ammaraskar/pyCraft
    https://pycraft.readthedocs.io/en/latest/authentication.html

  2. MC 地图编辑器

    https://github.com/mcedit/mcedit2
    http://www.mcedit.net/

  3. 使用 mc 教 python 的教程仓库

    https://github.com/teachthenet/TeachCraft-Challenges

  4. 把高级语言编译成 MC 命令

    https://github.com/simon816/Command-Block-Assembly

  5. 相关视频

    https://www.bilibili.com/video/av19817395?from=search&seid=9331178628953866180

  6. MC 机器人设计项目

    https://github.com/dan200/ComputerCraft

3. 基本思路

  1. 使用 CAD 软件进行建模,获得 stl 模型文件
  2. 使用 Crua 软件解析 stl 文件,获取 gcode 文件(用于控制电机运动)
  3. 使用 python 根据 gcode 文件产生控制命令(保存为 json 格式)
  4. 使用 python 控制 MC 进行打印

4. 环境配置

  1. 下载并安装 Cura: https://github.com/Ultimaker/Cura/releases
  2. 下载 stl 模型(不会用 CAD 哈哈哈哈哈)
  3. 搭建 MC 和 pyhton 环境 https://blog.csdn.net/paulzhang/article/details/82916902

5. 分析 Gcode

最终将 Gcode 转换为 MC 命令

1. Gcode 分析

代码 作用
G0 Xnnn Ynnn Znnn Ennn Fnnn 快速直线移动
G1 Xnnn Ynnn Znnn Ennn Fnnn 直线移动
G28 X0 Y0 Z0 归零运动
G90/G91 设置坐标为绝对坐标/相对坐标
G92 Xnnn Ynnn Znnn Ennn 设置打印位置(通常用来设置步进电机)

其中 XYZ 表示坐标位置,Ennn 表示步进电机移动位置(控制挤出头),Fnnn 表示移动速度,示例片段如下

1
2
3
4
5
6
7
8
G1 F1500 E0
G1 F1800 X156.458 Y81.471 E0.00998
G1 X156.871 Y80.798 E0.02484
G1 X157.346 Y80.174 E0.03959
G1 X157.681 Y79.777 E0.04936
G1 X158.285 Y79.138 E0.0659
G1 X158.957 Y78.503 E0.08329
G1 X159.402 Y78.113 E0.09442

2. 转化为 MC 命令

使用 PLY 模块,通过编译的方式进行转化,仅转化 G1 命令就够了

词法分析

Token 作用
OPG0/1/28/92 操作码
POSX/Y/Z/E 坐标操作码
SPEED 速度参数

其中 POSX/Y/Z/E 处理成整数类型,因为 MC 中的方块放置是离散的

根据.gcode 文件中的注释选择处理方式:

高度每层 1mm,共 180 层,高度直接取整即可
X 范围为 23.823 ~ 182.76,区间为 158.940
Y 范围为 64.812 ~ 139.946,区间为 75.134

1
2
3
4
5
6
7
;Layer height: 1
;MINX:23.823
;MINY:64.812
;MINZ:0.3
;MAXX:182.76
;MAXY:139.946
;MAXZ:180.3

设置打印范围为 160×80×180 (最多放置一百多万个方块,其实远远不到)

X 的处理方法为取 1 位小数后减去 23,乘以 10,最终范围为 0 ~ 1600
Y 的处理方法位取 1 位小数后减去 60,乘以 10,最终范围为 0 ~ 800
Z 的处理方法是取整

语法分析

语法分析生成的是 json 文件,描述放置方块的坐标

第一版先直接在移动位置目标位置放置方块,先看效果,后续再改

  1. 参数合并
    首先多个参数(parameter)归约成一个参数(parameters),把多个参数合并成一个参数列表
  2. 合成操作
    操作码(OPCODE)与参数(parameters)结合成操作(instruction)
    同时把该操作的参数列表添加到全局的坐标 list 中
  3. 操作合并
    多个操作(instrucion)合并成一个操作(instructions)

生成的列表的基本元素是元组,(type,pos1,pos2)/(type,pos1,pos2,pos3)

type 作用 参数含义
0 移动喷头并放置方块 2 参数,移动路径终点
1 移动喷头但不放置方块 2 参数,新的喷头位置
2 在三维空间内移动喷头 3 参数,新的喷头位置
3 空指令 无意义

转换结果示例片段如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[2, 133, 22, 0],
[3, 0, 0],
[0, 133, 21],
[0, 134, 21],
[0, 134, 20],
[0, 135, 20],
[0, 135, 19],
[0, 136, 19],
[0, 136, 18],
[0, 137, 18],
[0, 137, 17],
[0, 138, 17],
[0, 138, 17],
[0, 139, 16],
[0, 140, 16],
[0, 141, 15],
[0, 142, 15],
[0, 142, 15],

6. 在 MC 中填充方块

本来想着只在移动路径的终点填充方块,结果效果不是很好

如果保留到整数位的话,整体精度会大幅下降,为此选择对两个运动终点之间进行整数的线性插值,方法类似于计算机图形学画直线

完善 gcode 转 json 程序,支持了 G0 指令和 Z 坐标变换指令

重新对比了一下模型,发现上面那个效果图仅仅只是杀手皇后左脚脚下那一个小片片… 好像整得有点大

重新制定计划,把插值改为修改坐标转换方法

新的坐标转换方法:

高度每层 1mm,共 180 层,高度直接取整即可
X 范围为 23.823 ~ 182.76,区间为 158.940
Y 范围为 64.812 ~ 139.946,区间为 75.134
X 的处理方法为取整后减去 23,最终范围为 0 ~ 160
Y 的处理方法位取整后减去 60,最终范围为 0 ~ 80
Z 的处理方法是取整

一切就绪了,但是发现了一个严重影响编译器速度的因素,前一些行很快就编译好了,后面的内容编译得很慢
猜想可能的原因是但元素过多的时候,list 类的性能会下降,可以通过减少单个 list 中元素个数来解决
为此把原文件分割成多个小文件,分别进行编译

7. 项目及使用方法

项目地址: https://github.com/yishiyu/3D-Printing-in-MC

项目中给出了分割好了的 Gcode,gcode 转 json 工具,打印脚本

需要的环境: MC 服务器,MC 客户端,python3 的 PLY 模块,python3 的 mcpi 模块