diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 9d46dd55..aaf248b4 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -357,6 +357,7 @@ class App(QtCore.QObject): "excellon_toolchangez": self.excellon_defaults_form.excellon_opt_group.toolchangez_entry, "excellon_toolchangexy": self.excellon_defaults_form.excellon_opt_group.toolchangexy_entry, "excellon_ppname_e": self.excellon_defaults_form.excellon_opt_group.pp_excellon_name_cb, + "excellon_z_pdepth": self.excellon_defaults_form.excellon_opt_group.pdepth_entry, "excellon_f_plunge": self.excellon_defaults_form.excellon_opt_group.fplunge_cb, "excellon_startz": self.excellon_defaults_form.excellon_opt_group.estartz_entry, "excellon_endz": self.excellon_defaults_form.excellon_opt_group.eendz_entry, @@ -379,6 +380,7 @@ class App(QtCore.QObject): "geometry_dwell": self.geometry_defaults_form.geometry_opt_group.dwell_cb, "geometry_dwelltime": self.geometry_defaults_form.geometry_opt_group.dwelltime_entry, "geometry_ppname_g": self.geometry_defaults_form.geometry_opt_group.pp_geometry_name_cb, + "geometry_z_pdepth": self.geometry_defaults_form.geometry_opt_group.pdepth_entry, "geometry_f_plunge": self.geometry_defaults_form.geometry_opt_group.fplunge_cb, "geometry_toolchange": self.geometry_defaults_form.geometry_opt_group.toolchange_cb, "geometry_toolchangez": self.geometry_defaults_form.geometry_opt_group.toolchangez_entry, @@ -544,6 +546,7 @@ class App(QtCore.QObject): "excellon_startz": None, "excellon_endz": 2.0, "excellon_ppname_e": 'default', + "excellon_z_pdepth": -0.02, "excellon_f_plunge": False, "excellon_gcode_type": "drills", @@ -565,6 +568,7 @@ class App(QtCore.QObject): "geometry_dwell": False, "geometry_dwelltime": 1, "geometry_ppname_g": 'default', + "geometry_z_pdepth": -0.02, "geometry_f_plunge": False, "geometry_depthperpass": 0.002, "geometry_multidepth": False, diff --git a/FlatCAMGUI.py b/FlatCAMGUI.py index a8907eac..8a679904 100644 --- a/FlatCAMGUI.py +++ b/FlatCAMGUI.py @@ -2687,6 +2687,16 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.pp_excellon_name_cb.setFocusPolicy(Qt.StrongFocus) grid2.addWidget(self.pp_excellon_name_cb, 12, 1) + # Probe depth + self.pdepth_label = QtWidgets.QLabel("Probe Z depth:") + self.pdepth_label.setToolTip( + "The maximum depth that the probe is allowed\n" + "to probe. Negative value, in current units." + ) + grid2.addWidget(self.pdepth_label, 13, 0) + self.pdepth_entry = FCEntry() + grid2.addWidget(self.pdepth_entry, 13, 1) + fplungelabel = QtWidgets.QLabel('Fast Plunge:') fplungelabel.setToolTip( "By checking this, the vertical move from\n" @@ -2695,8 +2705,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): "WARNING: the move is done at Toolchange X,Y coords." ) self.fplunge_cb = FCCheckBox() - grid2.addWidget(fplungelabel, 13, 0) - grid2.addWidget(self.fplunge_cb, 13, 1) + grid2.addWidget(fplungelabel, 14, 0) + grid2.addWidget(self.fplunge_cb, 14, 1) #### Choose what to use for Gcode creation: Drills, Slots or Both excellon_gcode_type_label = QtWidgets.QLabel('Gcode: ') @@ -2709,8 +2719,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.excellon_gcode_type_radio = RadioSet([{'label': 'Drills', 'value': 'drills'}, {'label': 'Slots', 'value': 'slots'}, {'label': 'Both', 'value': 'both'}]) - grid2.addWidget(excellon_gcode_type_label, 14, 0) - grid2.addWidget(self.excellon_gcode_type_radio, 14, 1) + grid2.addWidget(excellon_gcode_type_label, 15, 0) + grid2.addWidget(self.excellon_gcode_type_radio, 15, 1) # until I decide to implement this feature those remain disabled excellon_gcode_type_label.setDisabled(True) @@ -2994,6 +3004,16 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): self.pp_geometry_name_cb.setFocusPolicy(Qt.StrongFocus) grid1.addWidget(self.pp_geometry_name_cb, 16, 1) + # Probe depth + self.pdepth_label = QtWidgets.QLabel("Probe Z depth:") + self.pdepth_label.setToolTip( + "The maximum depth that the probe is allowed\n" + "to probe. Negative value, in current units." + ) + grid1.addWidget(self.pdepth_label, 17, 0) + self.pdepth_entry = FCEntry() + grid1.addWidget(self.pdepth_entry, 17, 1) + # Fast Move from Z Toolchange fplungelabel = QtWidgets.QLabel('Fast Plunge:') fplungelabel.setToolTip( @@ -3003,8 +3023,8 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): "WARNING: the move is done at Toolchange X,Y coords." ) self.fplunge_cb = FCCheckBox() - grid1.addWidget(fplungelabel, 17, 0) - grid1.addWidget(self.fplunge_cb, 17, 1) + grid1.addWidget(fplungelabel, 18, 0) + grid1.addWidget(self.fplunge_cb, 18, 1) # Size of trace segment on X axis segx_label = QtWidgets.QLabel("Seg. X size:") @@ -3013,9 +3033,9 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): "Useful for auto-leveling.\n" "A value of 0 means no segmentation on the X axis." ) - grid1.addWidget(segx_label, 18, 0) + grid1.addWidget(segx_label, 19, 0) self.segx_entry = FCEntry() - grid1.addWidget(self.segx_entry, 18, 1) + grid1.addWidget(self.segx_entry, 19, 1) # Size of trace segment on Y axis segy_label = QtWidgets.QLabel("Seg. Y size:") @@ -3024,9 +3044,9 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): "Useful for auto-leveling.\n" "A value of 0 means no segmentation on the Y axis." ) - grid1.addWidget(segy_label, 19, 0) + grid1.addWidget(segy_label, 20, 0) self.segy_entry = FCEntry() - grid1.addWidget(self.segy_entry, 19, 1) + grid1.addWidget(self.segy_entry, 21, 1) self.layout.addStretch() diff --git a/FlatCAMObj.py b/FlatCAMObj.py index d11bf51c..d9f9ae04 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -856,6 +856,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "dwell": True, "dwelltime": 1000, "ppname_e": 'defaults', + "z_pdepth": -0.02, "optimization_type": "R", "gcode_type": "drills" }) @@ -1238,6 +1239,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "startz": self.ui.estartz_entry, "endz": self.ui.eendz_entry, "ppname_e": self.ui.pp_excellon_name_cb, + "z_pdepth": self.ui.pdepth_entry, "gcode_type": self.ui.excellon_gcode_type_radio }) @@ -1258,6 +1260,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.generate_milling_button.clicked.connect(self.on_generate_milling_button_click) self.ui.generate_milling_slots_button.clicked.connect(self.on_generate_milling_slots_button_click) + self.ui.pp_excellon_name_cb.activated.connect(self.on_pp_changed) + def get_selected_tools_list(self): """ Returns the keys to the self.tools dictionary corresponding @@ -1627,6 +1631,16 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.generate_milling_slots(use_thread=False) + def on_pp_changed(self): + current_pp = self.ui.pp_excellon_name_cb.get_value() + + if "toolchange_probe" in current_pp.lower(): + self.ui.pdepth_entry.setVisible(True) + self.ui.pdepth_label.show() + else: + self.ui.pdepth_entry.setVisible(False) + self.ui.pdepth_label.hide() + def on_create_cncjob_button_click(self, *args): self.app.report_usage("excellon_on_create_cncjob_button") self.read_form() @@ -1680,6 +1694,16 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): job_obj.options['xmax'] = xmax job_obj.options['ymax'] = ymax + try: + job_obj.z_pdepth = float(self.options["z_pdepth"]) + except ValueError: + # try to convert comma to decimal point. if it's still not working error message and return + try: + job_obj.z_pdepth = float(self.options["z_pdepth"].replace(',', '.')) + except ValueError: + self.app.inform.emit( + '[ERROR_NOTCL]Wrong value format for self.defaults["z_pdepth"] or self.options["z_pdepth"]') + # There could be more than one drill size... # job_obj.tooldia = # TODO: duplicate variable! # job_obj.options["tooldia"] = @@ -1948,6 +1972,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "toolchangexy": "0.0, 0.0", "startz": None, "ppname_g": 'default', + "z_pdepth": -0.02, }) if "cnctooldia" not in self.options: @@ -2160,6 +2185,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "dwelltime": self.ui.dwelltime_entry, "multidepth": self.ui.mpass_cb, "ppname_g": self.ui.pp_geometry_name_cb, + "z_pdepth": self.ui.pdepth_entry, "depthperpass": self.ui.maxdepth_entry, "extracut": self.ui.extracut_cb, "toolchange": self.ui.toolchangeg_cb, @@ -3007,6 +3033,13 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.ui.toolchangeg_cb.set_value(self.old_toolchangeg_state) self.ui.toolchangeg_cb.setDisabled(False) + if "toolchange_probe" in current_pp.lower(): + self.ui.pdepth_entry.setVisible(True) + self.ui.pdepth_label.show() + else: + self.ui.pdepth_entry.setVisible(False) + self.ui.pdepth_label.hide() + def on_generatecnc_button_click(self, *args): self.app.report_usage("geometry_on_generatecnc_button") @@ -3090,6 +3123,16 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): job_obj.segx = segx job_obj.segy = segy + try: + job_obj.z_pdepth = float(self.options["z_pdepth"]) + except ValueError: + # try to convert comma to decimal point. if it's still not working error message and return + try: + job_obj.z_pdepth = float(self.options["z_pdepth"].replace(',', '.')) + except ValueError: + self.app.inform.emit( + '[ERROR_NOTCL]Wrong value format for self.defaults["z_pdepth"] or self.options["z_pdepth"]') + for tooluid_key in self.sel_tools: tool_cnt += 1 app_obj.progress.emit(20) @@ -3267,6 +3310,16 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): job_obj.multigeo = True job_obj.cnc_tools.clear() + try: + job_obj.z_pdepth = float(self.options["z_pdepth"]) + except ValueError: + # try to convert comma to decimal point. if it's still not working error message and return + try: + job_obj.z_pdepth = float(self.options["z_pdepth"].replace(',', '.')) + except ValueError: + self.app.inform.emit( + '[ERROR_NOTCL]Wrong value format for self.defaults["z_pdepth"] or self.options["z_pdepth"]') + for tooluid_key in self.sel_tools: tool_cnt += 1 app_obj.progress.emit(20) @@ -3541,6 +3594,16 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): job_obj.segx = segx job_obj.segy = segy + try: + job_obj.z_pdepth = float(self.options["z_pdepth"]) + except ValueError: + # try to convert comma to decimal point. if it's still not working error message and return + try: + job_obj.z_pdepth = float(self.options["z_pdepth"].replace(',', '.')) + except ValueError: + self.app.inform.emit( + '[ERROR_NOTCL]Wrong value format for self.defaults["z_pdepth"] or self.options["z_pdepth"]') + # TODO: The tolerance should not be hard coded. Just for testing. job_obj.generate_from_geometry_2(self, tooldia=tooldia, offset=offset, tolerance=0.0005, z_cut=z_cut, z_move=z_move, diff --git a/ObjectUI.py b/ObjectUI.py index eb53edcf..9fd69b9f 100644 --- a/ObjectUI.py +++ b/ObjectUI.py @@ -561,10 +561,22 @@ class ExcellonObjectUI(ObjectUI): "The json file that dictates\n" "gcode output." ) - self.tools_box.addWidget(pp_excellon_label) self.pp_excellon_name_cb = FCComboBox() self.pp_excellon_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) - self.tools_box.addWidget(self.pp_excellon_name_cb) + grid1.addWidget(pp_excellon_label, 10, 0) + grid1.addWidget(self.pp_excellon_name_cb, 10, 1) + + # Probe depth + self.pdepth_label = QtWidgets.QLabel("Probe Z depth:") + self.pdepth_label.setToolTip( + "The maximum depth that the probe is allowed\n" + "to probe. Negative value, in current units." + ) + grid1.addWidget(self.pdepth_label, 11, 0) + self.pdepth_entry = FCEntry() + grid1.addWidget(self.pdepth_entry, 11, 1) + self.pdepth_label.hide() + self.pdepth_entry.setVisible(False) choose_tools_label = QtWidgets.QLabel( "Select from the Tools Table above\n" @@ -1006,11 +1018,23 @@ class GeometryObjectUI(ObjectUI): self.pp_geometry_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) self.grid3.addWidget(self.pp_geometry_name_cb, 16, 1) + # Probe depth + self.pdepth_label = QtWidgets.QLabel("Probe Z depth:") + self.pdepth_label.setToolTip( + "The maximum depth that the probe is allowed\n" + "to probe. Negative value, in current units." + ) + self.grid3.addWidget(self.pdepth_label, 17, 0) + self.pdepth_entry = FCEntry() + self.grid3.addWidget(self.pdepth_entry, 17, 1) + self.pdepth_label.hide() + self.pdepth_entry.setVisible(False) + warning_lbl = QtWidgets.QLabel( "Add at least one tool in the tool-table.\n" "Click the header to select all, or Ctrl + LMB\n" "for custom selection of tools.") - self.grid3.addWidget(warning_lbl, 17, 0, 1, 2) + self.grid3.addWidget(warning_lbl, 18, 0, 1, 2) # Button self.generate_cnc_button = QtWidgets.QPushButton('Generate') diff --git a/README.md b/README.md index d80c1777..32c5968a 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ CAD program, and create G-Code for Isolation routing. - added a text in the Selected Tab which is showed whenever the Selected Tab is selected but without having an object selected to display it's properties - added an initial text in the Tools tab - added possibility to use the shortcut key for shortcut list in the Notebook tabs +- added a way to set the Probe depth if Toolchange_Probe postprocessors are selected +- finished the postprocessor file for MACH3 tool probing on toolchange event 4.02.2019 diff --git a/camlib.py b/camlib.py index 552daa0f..b50138b7 100644 --- a/camlib.py +++ b/camlib.py @@ -4372,7 +4372,7 @@ class CNCjob(Geometry): z_cut=-0.002, z_move=0.1, feedrate=3.0, feedrate_z=3.0, feedrate_rapid=3.0, pp_geometry_name='default', pp_excellon_name='default', - depthpercut = 0.1, + depthpercut=0.1,z_pdepth=-0.02, spindlespeed=None, dwell=True, dwelltime=1000, toolchangez=0.787402, toolchange_xy=[0.0, 0.0], endz=2.0, @@ -4422,6 +4422,9 @@ class CNCjob(Geometry): # Controls if the move from Z_Toolchange to Z_Move is done fast with G0 or normally with G1 self.f_plunge = None + # how much depth the probe can probe before error + self.z_pdepth = z_pdepth if z_pdepth else None + self.spindlespeed = spindlespeed self.dwell = dwell self.dwelltime = dwelltime @@ -4565,6 +4568,9 @@ class CNCjob(Geometry): self.startz = startz self.endz = endz + self.pp_excellon = self.app.postprocessors[self.pp_excellon_name] + p = self.pp_excellon + log.debug("Creating CNC Job from Excellon...") # Tools @@ -4602,9 +4608,6 @@ class CNCjob(Geometry): self.gcode = [] - self.pp_excellon = self.app.postprocessors[self.pp_excellon_name] - p = self.pp_excellon - self.f_plunge = self.app.defaults["excellon_f_plunge"] # Initialization diff --git a/postprocessors/Toolchange_Probe_MACH3.py b/postprocessors/Toolchange_Probe_MACH3.py index 08d57413..e1aa35df 100644 --- a/postprocessors/Toolchange_Probe_MACH3.py +++ b/postprocessors/Toolchange_Probe_MACH3.py @@ -56,6 +56,7 @@ class Toolchange_Probe_MACH3(FlatCAMPostProc): gcode += ('G20\n' if p.units.upper() == 'IN' else 'G21\n') gcode += 'G90\n' + gcode += 'G17\n' gcode += 'G94\n' return gcode @@ -95,59 +96,122 @@ class Toolchange_Probe_MACH3(FlatCAMPostProc): no_drills = i[2] if toolchangexy is not None: - gcode = """ -G00 X{toolchangex} Y{toolchangey} + gcode = """ T{tool} M5 -M6 -(MSG, Change to Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills}) +G00 Z{toolchangez} +G00 X{toolchangex} Y{toolchangey} +(MSG, Change to Tool Dia = {toolC} ||| Drills for this tool = {t_drills} ||| Tool Probing MACH3) M0 +G00 Z{z_move} +F{fr} +G31 Z{z_pdepth} +G92 Z0 +G00 Z{z_move} +F{fr_slow} +G31 Z{z_pdepth} +G92 Z0 +(MSG, Remove any clips or other devices used for probing. CNC work is resuming ...) +M0 +G00 Z{z_move} """.format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex), - toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey), - tool=int(p.tool), - t_drills=no_drills, - toolC=toolC_formatted) - gcode += 'M0' + toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey), + toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez), + z_move=self.coordinate_format % (p.coords_decimals, p.z_move), + fr=str(self.feedrate_format %(p.fr_decimals, p.feedrate)), + fr_slow=str(self.feedrate_format % (p.fr_decimals, (p.feedrate / 2))), + z_pdepth=self.coordinate_format % (p.coords_decimals, p.z_pdepth), + tool=int(p.tool), + t_drills=no_drills, + toolC=toolC_formatted) else: gcode = """ T{tool} M5 -M6 -(MSG, Change to Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills}) -M0""".format(tool=int(p.tool), - t_drills=no_drills, - toolC=toolC_formatted) - gcode += 'M0' +G00 Z{toolchangez} +(MSG, Change to Tool Dia = {toolC} ||| Drills for this tool = {t_drills} ||| Tool Probing MACH3) +M0 +G00 Z{z_move} +F{fr} +G31 Z{z_pdepth} +G92 Z0 +G00 Z{z_move} +F{fr_slow} +G31 Z{z_pdepth} +G92 Z0 +(MSG, Remove any clips or other devices used for probing. CNC work is resuming ...) +M0 +G00 Z{z_move} +""".format(toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez), + z_move=self.coordinate_format % (p.coords_decimals, p.z_move), + fr=str(self.feedrate_format %(p.fr_decimals, p.feedrate)), + fr_slow=str(self.feedrate_format % (p.fr_decimals, (p.feedrate / 2))), + z_pdepth=self.coordinate_format % (p.coords_decimals, p.z_pdepth), + tool=int(p.tool), + t_drills=no_drills, + toolC=toolC_formatted) - if f_plunge is True: - gcode += '\nG00 Z%.*f' % (p.coords_decimals, p.z_move) + # if f_plunge is True: + # gcode += '\nG00 Z%.*f' % (p.coords_decimals, p.z_move) return gcode else: if toolchangexy is not None: gcode = """ -G00 X{toolchangex} Y{toolchangey} T{tool} M5 -M6 -(MSG, Change to Tool Dia = {toolC}) -M0""".format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex), - toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey), - tool=int(p.tool), - toolC=toolC_formatted) - gcode += 'M0' +G00 Z{toolchangez} +G00 X{toolchangex} Y{toolchangey} +(MSG, Change to Tool Dia = {toolC} ||| Tool Probing MACH3) +M0 +G00 Z{z_move} +F{fr} +G31 Z{z_pdepth} +G92 Z0 +G00 Z{z_move} +F{fr_slow} +G31 Z{z_pdepth} +G92 Z0 +(MSG, Remove any clips or other devices used for probing. CNC work is resuming ...) +M0 +G00 Z{z_move} +""".format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex), + toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey), + toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez), + z_move=self.coordinate_format % (p.coords_decimals, p.z_move), + fr=str(self.feedrate_format % (p.fr_decimals, p.feedrate)), + fr_slow=str(self.feedrate_format % (p.fr_decimals, (p.feedrate / 2))), + z_pdepth=self.coordinate_format % (p.coords_decimals, p.z_pdepth), + tool=int(p.tool), + toolC=toolC_formatted) else: gcode = """ T{tool} M5 -M6 -(MSG, Change to Tool Dia = {toolC}) -M0""".format(tool=int(p.tool), - toolC=toolC_formatted) - gcode += 'M0' +G00 Z{toolchangez} +(MSG, Change to Tool Dia = {toolC} ||| Tool Probing MACH3) +M0 +G00 Z{z_move} +F{fr} +G31 Z{z_pdepth} +G92 Z0 +G00 Z{z_move} +F{fr_slow} +G31 Z{z_pdepth} +G92 Z0 +(MSG, Remove any clips or other devices used for probing. CNC work is resuming ...) +M0 +G00 Z{z_move} +""".format(toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez), + z_move=self.coordinate_format % (p.coords_decimals, p.z_move), + fr=str(self.feedrate_format %(p.fr_decimals, p.feedrate)), + fr_slow=str(self.feedrate_format % (p.fr_decimals, (p.feedrate / 2))), + z_pdepth=self.coordinate_format % (p.coords_decimals, p.z_pdepth), + tool=int(p.tool), + toolC=toolC_formatted) - if f_plunge is True: - gcode += '\nG00 Z%.*f' % (p.coords_decimals, p.z_move) + # if f_plunge is True: + # gcode += '\nG00 Z%.*f' % (p.coords_decimals, p.z_move) return gcode def up_to_zero_code(self, p): diff --git a/postprocessors/Toolchange_Probe_general.py b/postprocessors/Toolchange_Probe_general.py index 6e240ebd..b1342718 100644 --- a/postprocessors/Toolchange_Probe_general.py +++ b/postprocessors/Toolchange_Probe_general.py @@ -56,6 +56,7 @@ class Toolchange_Probe_general(FlatCAMPostProc): gcode += ('G20\n' if p.units.upper() == 'IN' else 'G21\n') gcode += 'G90\n' + gcode += 'G17\n' gcode += 'G94\n' return gcode