开源改变世界!!

添加对螺旋切削/坡道插铣的支持 #590

推推 grbl 2年前 (2023-02-01) 129次浏览
关闭
Harvie 打开了这个问题 2017 年 5 月 14 日 · 13条评论
关闭

添加对螺旋切削/坡道插铣的支持#590

Harvie 打开了这个问题 2017 年 5 月 14 日 · 13条评论

注释

添加对螺旋切削/坡道插铣的支持 #590
合作者
哈维 评论了 2017 年 5 月 14 日  

在很多情况下,最好是在 X/Y 轴上切入时向下切入,这样可以防止铣削直接向下。对于某些工具,它甚至是唯一的选择…您能否将其添加为 CUT 操作的选项?

例如。当你切割圆圈时。你不会在 Z 中向下然后做 XY 圆然后再次在 Z 中向下。相反,您可以将最后一层作为唯一平坦的一层进行螺旋切割。

添加对螺旋切削/坡道插铣的支持 #590

添加对螺旋切削/坡道插铣的支持 #590 vlachoudis 添加了 增强 标签 2017 年 5 月 15 日
添加对螺旋切削/坡道插铣的支持 #590

这是你的 g 代码生成器的一个功能,使用 Fusion360,有很多!!!!像这样的功能

添加对螺旋切削/坡道插铣的支持 #590
合作者作者
哈维 评论了 2018 年 2 月 16 日  

@Fosforitoferch 我使用 bCNC 作为我的 g 代码生成器,所以我希望我能在 bCNC 中看到这个功能。Fusion360 不适用于 Linux。另外我想这太过时了。

添加对螺旋切削/坡道插铣的支持 #590
合作者作者

在我看来,相关代码位于./CNC.py以下方法的文件中:

def fromPath(
def cutPath(
def cut(
添加对螺旋切削/坡道插铣的支持 #590 哈维 提到了这个问题 2018 年 5 月 7 日
添加对螺旋切削/坡道插铣的支持 #590
合作者作者
哈维 评论了 2018 年 5 月 8 日  

我想所需要的只是计算要切割的路径的总长度(可能使用self.cnc.pathLength(block, xyz)Path.length()??? 不确定),然后对于该路径的每个段,降低 Z 与该段的长度成比例(Segment.length()???)。因此,切入在 XY 进给之间平均分配。

例如。:

我们将降压 (DOC) 设置为 20mm。
我们有矩形路径,它由以下长度的线段组成:20+30+20+30mm(= 100mm 路径总长度),
这意味着我们应该将这些线段的 Z 降低以下数量:-4-6-4-6mm (=-20mm 每层总步距)

计算弧的长度可能有点棘手,但也不应该太难。

添加对螺旋切削/坡道插铣的支持 #590
合作者作者
哈维 评论了 2018 年 6 月 27 日  

我不是真正的 python 专家,我也不太了解 bCNC 的内部工作原理,但我尝试修改这两个函数并获得了一些结果。这是螺旋切割矩形的图像。我刚刚从 DXF 中选择了矩形并单击了 bCNC 中的 CUT 按钮:

添加对螺旋切削/坡道插铣的支持 #590

这是我修改后的代码CNC.py

来自路径()

	#----------------------------------------------------------------------
	# create a block from Path
	#----------------------------------------------------------------------
	def fromPath(self, path, block=None, z=None, entry=True, exit=True, zinit=0):
		if block is None:
			if isinstance(path, Path):
				block = Block(path.name)
			else:
				block = Block(path[0].name)

		def addSegment(segment, z=None):
			x,y = segment.B
			if segment.type == Segment.LINE:
				x,y = segment.B
				#block.append("g1 %s %s"%(self.fmt("x",x,7),self.fmt("y",y,7)))
				if z is None: block.append("g1 %s %s"%(self.fmt("x",x,7),self.fmt("y",y,7)))
				else: block.append("g1 %s %s %s"%(self.fmt("x",x,7),self.fmt("y",y,7),self.fmt("z",z,7)))

			elif segment.type in (Segment.CW, Segment.CCW):
				ij = segment.C - segment.A
				if abs(ij[0])<1e-5: ij[0] = 0.
				if abs(ij[1])<1e-5: ij[1] = 0.
				block.append("g%d %s %s %s %s" % \
					(segment.type,
					 self.fmt("x",x,7), self.fmt("y",y,7),
					 self.fmt("i",ij[0],7),self.fmt("j",ij[1],7)))

		if isinstance(path, Path):
			x,y = path[0].A
			if z is None: z = self.cnc["surface"]
			if entry:
				block.append("g0 %s %s"%(self.fmt("x",x,7),self.fmt("y",y,7)))
			#zinit = 0;
			block.append(CNC.zenter(zinit))
			setfeed = True
			prevInside = None
			#print(path.length())
			print("");
			for segment in path:
				#print(segment.length())
				#print(100*segment.length()/path.length())
				if zinit is not None:
					zinit = zinit + (segment.length()/path.length())*z
					print(zinit)
				if prevInside is not segment._inside:
					if segment._inside is None:
						block.append(CNC.zenter(z))
						setfeed = True
					elif segment._inside.z > z:
						block.append(CNC.zexit(segment._inside.z))
						setfeed = True
					prevInside = segment._inside
				addSegment(segment, zinit)
#				x,y = segment.B
#				if segment.type == Segment.LINE:
#					x,y = segment.B
#					block.append("g1 %s %s"%(self.fmt("x",x,7),self.fmt("y",y,7)))
#				elif segment.type in (Segment.CW, Segment.CCW):
#					ij = segment.C - segment.A
#					if abs(ij[0])<1e-5: ij[0] = 0.
#					if abs(ij[1])<1e-5: ij[1] = 0.
#					block.append("g%d %s %s %s %s" % \
#						(segment.type,
#						 self.fmt("x",x,7), self.fmt("y",y,7),
#						 self.fmt("i",ij[0],7),self.fmt("j",ij[1],7)))

				if setfeed:
					block[-1] += " %s"%(self.fmt("f",self.cnc["cutfeed"]))
					setfeed = False
			if exit:
				block.append(CNC.zsafe())
		else:
			for p in path:
				self.fromPath(p, block)
		return block

切割路径()

	#----------------------------------------------------------------------
	# Perform a cut on a path an add it to block
	# @param newblock O	block to add the cut paths
	# @param block	I	existing block
	# @param path	I	path to cut
	# @param z	I	starting z surface
	# @param depth	I	ending depth
	# @param stepz	I	stepping in z
	#----------------------------------------------------------------------
	def cutPath(self, newblock, block, path, z, depth, stepz):
		closed = path.isClosed()
		entry  = True
		exit   = False

		# Mark in which tab we are inside
		if block.tabs:
			# Mark everything as outside
			for tab in block.tabs:
				tab.create(CNC.vars["diameter"])
				tab.split(path)

		zinit = 0
		while z > depth:
			z = max(z-stepz, depth)
			if not closed:
				# on open paths always enter exit
				entry = exit = True
			elif abs(z-depth)<1e-7:
				# last pass
				exit = True

			self.fromPath(path, newblock, z, entry, exit, zinit)
			zinit = z
			entry = False
		return newblock

zinit = zinit + (segment.length()/path.length())*z请注意为路径的每个段计算最终 Z的公式。这会根据长度在所有通道段之间均匀分布增量 Z 切入。而不是先切入到所需的 Z,然后在恒定 Z 平面中进行切割。(这有几个重要的影响)

我仍然遗漏了一些东西,生成的 g 代码存在重大问题。你能帮我改进这段代码以使其可用吗?

最大的问题是某些东西在通过之间将 Z 提升了一点,导致无意义的刀具路径。侧面图:

添加对螺旋切削/坡道插铣的支持 #590

当我手动删除这些 Z 移动时,它开始有意义:

添加对螺旋切削/坡道插铣的支持 #590

添加对螺旋切削/坡道插铣的支持 #590

我不太确定这对非线段的效果如何。(例如圆弧和圆)。但我很确定有些东西会坏掉。
更新:是的……它不适用于圈子:-(

问题是我真的不知道g代码。现在我用这个:
block.append("g1 %s %s %s"%(self.fmt("x",x,7),self.fmt("y",y,7),self.fmt("z",z,7)))

设置线段的最终 Z 高度,适用于线条。但是bpath.py库没有为段设置初始和最终 Z 的通用方法,比如它有 X 和 Y 的 startPhi 和 endPhi …

添加对螺旋切削/坡道插铣的支持 #590
合作者作者
哈维 评论了 2018 年 6 月 27 日  

当我手动添加z-2到圈子时,它似乎可以工作……我不确定为什么它不能使用block.append(). 有没有通用的方法来覆盖段的 Z 值?我想这是最大的问题。

任何想法如何在将任何段添加到块之前可靠地添加/修改 Z ?

添加对螺旋切削/坡道插铣的支持 #590
合作者作者
哈维 评论了 2018 年 6 月 29 日  

啊哈!终于让它工作了!

添加对螺旋切削/坡道插铣的支持 #590

还添加了最后一个平面通行证:

添加对螺旋切削/坡道插铣的支持 #590

这是一些代码:

来自路径()

	#----------------------------------------------------------------------
	# create a block from Path
	#----------------------------------------------------------------------
	def fromPath(self, path, block=None, z=None, entry=True, exit=True, stepz=0):
		if block is None:
			if isinstance(path, Path):
				block = Block(path.name)
			else:
				block = Block(path[0].name)

		def addSegment(segment, z=None):
			x,y = segment.B
			if segment.type == Segment.LINE:
				x,y = segment.B
				#block.append("g1 %s %s"%(self.fmt("x",x,7),self.fmt("y",y,7)))
				if z is None: block.append("g1 %s %s"%(self.fmt("x",x,7),self.fmt("y",y,7)))
				else: block.append("g1 %s %s %s"%(self.fmt("x",x,7),self.fmt("y",y,7),self.fmt("z",z,7)))

			elif segment.type in (Segment.CW, Segment.CCW):
				ij = segment.C - segment.A
				if abs(ij[0])<1e-5: ij[0] = 0.
				if abs(ij[1])<1e-5: ij[1] = 0.
				if z is None:
					block.append("g%d %s %s %s %s" % \
						(segment.type,
						 self.fmt("x",x,7), self.fmt("y",y,7),
						 self.fmt("i",ij[0],7),self.fmt("j",ij[1],7)))
				else:
					block.append("g%d %s %s %s %s %s" % \
						(segment.type,
						 self.fmt("x",x,7), self.fmt("y",y,7),
						 self.fmt("i",ij[0],7),self.fmt("j",ij[1],7),self.fmt("z",z,7)))

		if isinstance(path, Path):
			x,y = path[0].A
			if z is None: z = self.cnc["surface"]
			if entry:
				block.append("g0 %s %s"%(self.fmt("x",x,7),self.fmt("y",y,7)))
			#zinit = 0;
			#block.append(CNC.zenter(zinit))
			setfeed = True
			prevInside = None
			#print(path.length())
			print("");
			zh = z + stepz;
			for segment in path:
				#print(segment.length())
				#print(100*segment.length()/path.length())
				zh -= (segment.length()/path.length())*stepz
				print(zh)
				if prevInside is not segment._inside:
					if segment._inside is None:
						block.append(CNC.zenter(z))
						setfeed = True
					elif segment._inside.z > z:
						block.append(CNC.zexit(segment._inside.z))
						setfeed = True
					prevInside = segment._inside
				addSegment(segment, zh)
#				x,y = segment.B
#				if segment.type == Segment.LINE:
#					x,y = segment.B
#					block.append("g1 %s %s"%(self.fmt("x",x,7),self.fmt("y",y,7)))
#				elif segment.type in (Segment.CW, Segment.CCW):
#					ij = segment.C - segment.A
#					if abs(ij[0])<1e-5: ij[0] = 0.
#					if abs(ij[1])<1e-5: ij[1] = 0.
#					block.append("g%d %s %s %s %s" % \
#						(segment.type,
#						 self.fmt("x",x,7), self.fmt("y",y,7),
#						 self.fmt("i",ij[0],7),self.fmt("j",ij[1],7)))

				if setfeed:
					block[-1] += " %s"%(self.fmt("f",self.cnc["cutfeed"]))
					setfeed = False
			if exit:
				block.append(CNC.zsafe())
		else:
			for p in path:
				self.fromPath(p, block)
		return block

切割路径()

	#----------------------------------------------------------------------
	# Perform a cut on a path an add it to block
	# @param newblock O	block to add the cut paths
	# @param block	I	existing block
	# @param path	I	path to cut
	# @param z	I	starting z surface
	# @param depth	I	ending depth
	# @param stepz	I	stepping in z
	#----------------------------------------------------------------------
	def cutPath(self, newblock, block, path, z, depth, stepz):
		closed = path.isClosed()
		entry  = True
		exit   = False

		# Mark in which tab we are inside
		if block.tabs:
			# Mark everything as outside
			for tab in block.tabs:
				tab.create(CNC.vars["diameter"])
				tab.split(path)

		#zinit = 0
		while z > depth:
			z = max(z-stepz, depth)
			if not closed:
				# on open paths always enter exit
				entry = exit = True
			elif abs(z-depth)<1e-7:
				# last pass
				exit = False

			self.fromPath(path, newblock, z, entry, exit, stepz)
			#zinit = z
			entry = False
		self.fromPath(path, newblock, z, entry, exit, 0)
		return newblock
添加对螺旋切削/坡道插铣的支持 #590
合作者作者

现在最大的问题是它破坏了原始的 CUT 功能。我需要修改代码,这样我们就可以在螺旋切割和非螺旋切割之间切换……

添加对螺旋切削/坡道插铣的支持 #590
合作者作者

将它作为一个选项添加到 GUI 中!我现在正在处理拉取请求!:-)

添加对螺旋切削/坡道插铣的支持 #590

添加对螺旋切削/坡道插铣的支持 #590
合作者作者

出来了!:-)

添加对螺旋切削/坡道插铣的支持 #590
合作者作者

只是添加了正确的进入和退出路径以避免崩溃。

vlachoudis 添加了引用此问题的提交 2018 年 7 月 1 日

添加对螺旋切削/坡道插铣的支持 #590
合作者作者
哈维 评论了 2018 年 7 月 2 日  

标签现在可以在螺旋切割中使用!

我也有坡道切割工作!它就像螺旋线,但下降速度更快,然后像往常一样继续切割平整(以防止在第一次通过时摩擦):

添加对螺旋切削/坡道插铣的支持 #590

一切准备就绪#893

这孩子会撕裂一些铝!:-)

添加对螺旋切削/坡道插铣的支持 #590
合作者作者

我想现在已经实现了