def cutFingers(self, order_int): """ One full pass. Assumes it's already at its starting position in XYZ. """ bit_diameter = self.machine_params['bit_diameter'] bit_radius = bit_diameter / 2 distribution = self.getDistribution() path_num = 1 file_text = G.set_INCR_mode() file_text += G.G1_XY((0, bit_radius)) # Start _remCut with bit center at edge of stock. file_text += self._remCut() while path_num <= distribution['num_fingers']: if path_num % 2 == order_int: file_text += self._leftwardsPath() else: file_text += self._rightwardsPath() path_num += 1 file_text += self._remCut() file_text += G.G1_XY((0, bit_radius)) return file_text
def returnToHome(self): file_text = self.machine.moveToSafeZ() file_text += G.set_INCR_mode() file_text += G.G0_XY(( \ - self.startRefs['x_starting_ref'], \ - self.startRefs['y_starting_ref'], \ )) return file_text
def _getInstructions(self, sequence): """Climb cutting ?""" side_X, side_Y = self.getGrooveAdjustments() file_text = addDebugFrame(inspect.currentframe()) file_text += self.machine.setMode('INCR') file_text += G.G1_XY((0, side_Y)) file_text += G.G1_XY((side_X, 0)) file_text += G.G1_XY((0, - side_Y)) file_text += G.G1_XY((- side_X, 0)) return file_text
def _rightwardsPath(self): """ Each of these paths is the full width of one finger. """ distribution = self.getDistribution() finger_width = distribution['finger_width'] x_straight_cut = distribution['x_straight_cut'] file_text = G.comment(' => _rightwardsPath') file_text += G.G2XY((finger_width, finger_width), (finger_width, 0)) file_text += G.G1_XY((x_straight_cut, 0)) return file_text
def _getInstructions(self, sequence): assert self.at_start is not None, 'moveToStart not yet called' params = self.getParams() delta_X = params['delta_X'] delta_Y = params['delta_Y'] file_text = self.machine.setMode('INCR') if self.at_start: file_text += G.G1_XY((delta_X, delta_Y)) else: file_text += G.G1_XY((-delta_X, -delta_Y)) self.at_start = not self.at_start return file_text
def getGCode(self): file_text = addDebugFrame(inspect.currentframe()) params = self.getParams() file_text += self.machine.moveToSafeZ() file_text += self.moveToReference() file_text += addDebugFrame(inspect.currentframe()) file_text += self.machine.setMode('ABS') file_text += G.G0_Z(params['stock_height']) file_text += self.machine.setMode('INCR') file_text += G.G1_Z(-params['cut_depth']) file_text += G.set_dwell(0.5) file_text += self.machine.moveToSafeZ() file_text += self.returnFromReference() return file_text
def setMode(self, mode): file_text = '' if mode.lower() == 'abs': if self.mode != 'abs': self.mode = 'abs' file_text = G.set_ABS_mode() elif mode.lower() == 'incr': if self.mode != 'incr': self.mode = 'incr' file_text = G.set_INCR_mode() else: raise ValueError('"%s" mode is not handled by SimpleMachine' % (mode)) return file_text
def returnToHome(self): """Reference position is the center, return from corner.""" side_X, side_Y = self.getGrooveAdjustments() file_text = addDebugFrame(inspect.currentframe()) file_text += self.machine.setMode('INCR') file_text += G.G0_XY((side_X / 2, side_Y / 2)) return file_text
def moveToStart(self): """Where does it start ?""" side_X, side_Y, corner_radius = self.getGrooveAdjustments() file_text = addDebugFrame(inspect.currentframe()) file_text += self.machine.setMode('INCR') file_text += G.G0_XY((-side_X / 2, corner_radius - (side_Y / 2))) return file_text
def _getInstructions(self, sequence): params = self.getParams() bit_diameter = params['bit_diameter'] current_side_X = params['side_X'] current_side_Y = params['side_Y'] step_increment = bit_diameter - self.getOverlap() child = self.child_features[RectangularGroove] file_text = addDebugFrame(inspect.currentframe()) # do the full size outline first file_text += child.getGCode() while current_side_X >= (2 * bit_diameter) and current_side_Y >= ( 2 * bit_diameter): starting_side_X = current_side_X starting_side_Y = current_side_Y current_side_X = max(current_side_X - (2 * step_increment), 2 * step_increment) current_side_Y = max(current_side_Y - (2 * step_increment), 2 * step_increment) file_text += self.machine.setMode('INCR') file_text += G.G1_XY(((starting_side_X - current_side_X) / 2, (starting_side_Y - current_side_Y) / 2)) self.setUpRectangularGroove(current_side_X, current_side_Y) file_text += child.getGCode() file_text += addDebugFrame(inspect.currentframe()) if sequence not in ['last', 'only']: # returns to center of pocket, for file_text += self.returnToHome() file_text += self.moveToStart() return file_text
def returnToHome(self): """Where does it finish ?""" side_X, side_Y, corner_radius = self.getGrooveAdjustments() file_text = addDebugFrame(inspect.currentframe()) file_text += self.machine.setMode('INCR') file_text += G.G0_XY((side_X / 2, -corner_radius + (side_Y / 2))) return file_text
def returnToHome(self): log('LinearDistribution returnToHome: %s' % (self.__repr__())) delta_X = self.option_queries[DeltaXQuery].getValue() delta_Y = self.option_queries[DeltaYQuery].getValue() num_repeats = self.option_queries[NumRepeatQuery].getValue() - 1 file_text = self.machine.setMode('INCR') file_text += G.G0_XY( (-(delta_X * num_repeats), -(delta_Y * num_repeats))) return file_text
def returnFromReference(self): """Core interface.""" file_text = addDebugFrame(inspect.currentframe()) ref_X = self.option_queries[ReferenceXQuery].getValue() ref_Y = self.option_queries[ReferenceYQuery].getValue() file_text += self.returnToHome() file_text += self.machine.setMode('INCR') file_text += G.G0_XY((-ref_X, -ref_Y)) return file_text
def returnToHome(self): # for starting point reference point params = self.getParams() delta_X = params['delta_X'] delta_Y = params['delta_Y'] file_text = '' if not self.at_start: file_text = self.machine.setMode('INCR') file_text += G.G0_XY((-delta_X, -delta_Y)) self.at_start = True return file_text
def _getGCode(self, order_int): file_text = self._startProgram() # move to start, at safe-Z, in INCR mode file_text += G.set_INCR_mode() file_text += G.G0_XY(( \ self.startRefs['x_starting_ref'], \ self.startRefs['y_starting_ref'] \ )) height_to_cut = self.workpiece_params['stock_height'] while height_to_cut > 0: # move down to top of stock file_text += G.set_ABS_mode() file_text += G.G0_Z(height_to_cut) # get to cutting height height_to_cut = max( height_to_cut - self.cutting_params['cut_per_pass'], 0) file_text += G.set_ABS_mode() file_text += G.G1_Z( height_to_cut) # could be G0 here, but it's good practice # This is other magic for A/B: special order of paths. file_text += self.cutFingers(order_int) file_text += self.returnToStart(order_int) file_text += self.returnToHome() file_text += self._endProgram() return file_text
def distributeChildFeature(self): log('LinearDistribution distributeChildFeature: %s' % (self.__repr__())) log('LinearDistribution feature: %s' % (self.features[0].__repr__())) file_text = self.features[0].getGCode() delta_X = self.option_queries[DeltaXQuery].getValue() delta_Y = self.option_queries[DeltaYQuery].getValue() for _ in xrange(self.option_queries[NumRepeatQuery].getValue() - 1): log('LinearDistribution REPEAT: %s' % (self.__repr__())) file_text += self.machine.setMode('INCR') file_text += G.G0_XY((delta_X, delta_Y)) file_text += self.features[0].getGCode() return file_text
def returnToStart(self, order_int): distribution = self.getDistribution() stock_span = self.workpiece_params[ 'stock_width'] + self.machine_params['bit_diameter'] file_text = self.machine.moveToSafeZ() file_text += G.set_INCR_mode() if distribution['num_fingers'] % 2 == 0: file_text += G.G0_XY(( \ 0, \ - stock_span \ )) else: if order_int == 1: file_text += G.G0_XY((\ - self.cutting_params['finger_depth'], \ - stock_span \ )) else: file_text += G.G0_XY((\ self.cutting_params['finger_depth'], \ - stock_span \ )) return file_text
def _getInstructions(self, sequence): """CW direction ATM""" side_X, side_Y, corner_radius = self.getGrooveAdjustments() file_text = addDebugFrame(inspect.currentframe()) file_text += self.machine.setMode('INCR') file_text += G.G1_XY((0, side_Y - (2 * corner_radius))) file_text += G.G2XY((corner_radius, corner_radius), (corner_radius, 0)) file_text += G.G1_XY((side_X - (2 * corner_radius), 0)) file_text += G.G2XY((corner_radius, -corner_radius), (0, -corner_radius)) file_text += G.G1_XY((0, -side_Y + (2 * corner_radius))) file_text += G.G2XY((-corner_radius, -corner_radius), (-corner_radius, 0)) file_text += G.G1_XY((-side_X + (2 * corner_radius), 0)) file_text += G.G2XY((-corner_radius, corner_radius), (0, corner_radius)) return file_text
def _getInstructions(self, sequence): file_text = addDebugFrame(inspect.currentframe()) params = self.getParams() diameter = params['diameter'] current_od = params['bit_diameter'] od_feature = self.child_features[CircularGroove] while current_od < diameter: # increase current_od starting_od = current_od current_od = min( current_od + (2 * (params['bit_diameter'] - self.getOverlap())), diameter ) file_text += self.machine.setMode('INCR') file_text += G.G1_XY((- (current_od - starting_od) / 2, 0)) self.setUpCircularGroove(current_od) file_text += od_feature.getGCode() file_text += addDebugFrame(inspect.currentframe()) if sequence not in ['last', 'only']: # returns to center of pocket file_text += od_feature.returnToHome() return file_text
def getGCode(self, instruction_callback, to_start_callback, return_callback): file_text = addDebugFrame(inspect.currentframe()) basic_params, cut_per_pass, cut_depth = self.getParams() stock_height = basic_params['stock_height'] target_depth = stock_height - cut_depth multipass = cut_depth > cut_per_pass sequence = 'first' # pre-amble # Z-axis move to starting point from Z-safe file_text += self.machine.moveToSafeZ() file_text += to_start_callback() file_text += addDebugFrame(inspect.currentframe()) file_text += self.machine.setMode('ABS') file_text += G.G0_Z(stock_height) if multipass: while stock_height > target_depth: stock_height -= cut_per_pass if stock_height <= target_depth: stock_height = target_depth sequence = 'last' # Z-axis move file_text += self.machine.setMode('ABS') file_text += G.G1_Z(stock_height) file_text += G.set_dwell(0.5) file_text += G.comment('# ' + sequence) file_text += instruction_callback(sequence) file_text += addDebugFrame(inspect.currentframe()) sequence = 'next' else: sequence = 'only' file_text += G.G1_Z(target_depth) file_text += G.set_dwell(0.5) file_text += instruction_callback(sequence) file_text += addDebugFrame(inspect.currentframe()) # post-amble file_text += self.machine.moveToSafeZ() file_text += return_callback() file_text += addDebugFrame(inspect.currentframe()) file_text += self.machine.setMode('ABS') return file_text
def returnToHome(self): """Assumes reference point at center.""" diameter = self._getAdjustedDiameter() file_text = self.machine.setMode('INCR') file_text += G.G0_XY((diameter / 2, 0)) return file_text
def _startProgram(self): file_text = G.F_rate(self.machine_params['feed_rate']) file_text += self.machine.moveToSafeZ() return file_text
def _getInstructions(self, sequence): diameter = self._getAdjustedDiameter() file_text = self.machine.setMode('INCR') file_text += G.G2XY((0, 0), (diameter / 2, 0)) return file_text
def _endProgram(self): file_text = self.machine.moveToSafeZ() file_text += G.end_program() return file_text
def _remCut(self): distribution = self.getDistribution() file_text = G.comment(' => _remCut') file_text += G.G1_XY((0, distribution['remainder'] / 2)) return file_text
def setUpProgram(self): feed_rate = self.option_queries[FeedRateQuery].getValue() file_text = G.F_rate(feed_rate) return file_text
def endProgram(self): file_text = self.setMode('ABS') file_text += G.end_program() return file_text
def moveToSafeZ(self): if self.params is None: self.params = self.getParams() file_text = self.setMode('ABS') file_text += G.G0_Z(self.params['safe_z']) return file_text