diff --git a/pygcode/__init__.py b/pygcode/__init__.py index bfffe04..5a3d921 100644 --- a/pygcode/__init__.py +++ b/pygcode/__init__.py @@ -11,67 +11,84 @@ __all__ = [ 'Word', 'text2words', 'str2word', 'words2dict', # GCodes - 'GCode', 'words2gcodes', + 'words2gcodes', 'text2gcodes', 'split_gcodes', + 'GCode', + 'GCodeAbsoluteArcDistanceMode', + 'GCodeAbsoluteDistanceMode', + 'GCodeAdaptiveFeed', + 'GCodeAddToolLengthOffset', + 'GCodeAnalogOutput', + 'GCodeAnalogOutputImmediate', + 'GCodeAnalogOutputSyncd', + 'GCodeArcMove', + 'GCodeArcMoveCCW', + 'GCodeArcMoveCW', 'GCodeBoringCycleDwellFeedOut', 'GCodeBoringCycleFeedOut', - 'GCodeDrillingCycle', - 'GCodeDrillingCycleChipBreaking', - 'GCodeDrillingCycleDwell', - 'GCodeDrillingCyclePeck', - 'GCodeThreadingCycle', + 'GCodeCancelCannedCycle', + 'GCodeCancelToolLengthOffset', + 'GCodeCannedCycle', 'GCodeCannedCycleReturnLevel', + 'GCodeCannedReturnMode', + 'GCodeCoolant', 'GCodeCoolantFloodOn', 'GCodeCoolantMistOn', 'GCodeCoolantOff', + 'GCodeCoordSystemOffset', + 'GCodeCublcSpline', 'GCodeCutterCompLeft', 'GCodeCutterCompRight', + 'GCodeCutterRadiusComp', 'GCodeCutterRadiusCompOff', - 'GCodeDynamicCutterCompLeft', - 'GCodeDynamicCutterCompRight', - 'GCodeAbsoluteArcDistanceMode', - 'GCodeAbsoluteDistanceMode', - 'GCodeIncrementalArcDistanceMode', - 'GCodeIncrementalDistanceMode', - 'GCodeLatheDiameterMode', - 'GCodeLatheRadiusMode', - 'GCodeInverseTimeMode', - 'GCodeUnitsPerMinuteMode', - 'GCodeUnitsPerRevolution', - 'GCodeAnalogOutputImmediate', - 'GCodeAnalogOutputSyncd', + 'GCodeDigitalOutput', 'GCodeDigitalOutputOff', 'GCodeDigitalOutputOffSyncd', 'GCodeDigitalOutputOn', 'GCodeDigitalOutputOnSyncd', - 'GCodeWaitOnInput', - 'GCodeArcMove', - 'GCodeArcMoveCCW', - 'GCodeArcMoveCW', - 'GCodeCancelCannedCycle', - 'GCodeCublcSpline', + 'GCodeDistanceMode', + 'GCodeDrillingCycle', + 'GCodeDrillingCycleChipBreaking', + 'GCodeDrillingCycleDwell', + 'GCodeDrillingCyclePeck', 'GCodeDwell', - 'GCodeLinearMove', - 'GCodeNURBS', - 'GCodeNURBSEnd', - 'GCodeQuadraticSpline', - 'GCodeRapidMove', - 'GCodeRigidTapping', - 'GCodeSpindleSyncMotion', - 'GCodeStraightProbe', - 'GCodeCoordSystemOffset', - 'GCodeGotoPredefinedPosition', - 'GCodeMoveInMachineCoords', - 'GCodeResetCoordSystemOffset', - 'GCodeRestoreCoordSystemOffset', - 'GCodeSet', - 'GCodeSetPredefinedPosition', - 'GCodeToolChange', - 'GCodeToolSetCurrent', - 'GCodeUserDefined', - 'GCodeAdaptiveFeed', + 'GCodeDynamicCutterCompLeft', + 'GCodeDynamicCutterCompRight', + 'GCodeDynamicToolLengthOffset', + 'GCodeEndProgram', + 'GCodeEndProgramPalletShuttle', + 'GCodeExactPathMode', + 'GCodeExactStopMode', 'GCodeFeedOverride', 'GCodeFeedRate', + 'GCodeFeedRateMode', 'GCodeFeedStop', + 'GCodeGotoPredefinedPosition', + 'GCodeIO', + 'GCodeIncrementalArcDistanceMode', + 'GCodeIncrementalDistanceMode', + 'GCodeInverseTimeMode', + 'GCodeLatheDiameterMode', + 'GCodeLatheRadiusMode', + 'GCodeLinearMove', + 'GCodeMotion', + 'GCodeMoveInMachineCoords', + 'GCodeNURBS', + 'GCodeNURBSEnd', + 'GCodeNonModal', + 'GCodeOrientSpindle', + 'GCodeOtherModal', + 'GCodePalletChangePause', + 'GCodePathBlendingMode', + 'GCodePathControlMode', + 'GCodePauseProgram', + 'GCodePauseProgramOptional', + 'GCodePlaneSelect', + 'GCodeProgramControl', + 'GCodeQuadraticSpline', + 'GCodeRapidMove', + 'GCodeResetCoordSystemOffset', + 'GCodeRestoreCoordSystemOffset', + 'GCodeRigidTapping', 'GCodeSelectCoordinateSystem', 'GCodeSelectCoordinateSystem1', 'GCodeSelectCoordinateSystem2', @@ -83,36 +100,40 @@ __all__ = [ 'GCodeSelectCoordinateSystem8', 'GCodeSelectCoordinateSystem9', 'GCodeSelectTool', - 'GCodeSpeedAndFeedOverrideOff', - 'GCodeSpeedAndFeedOverrideOn', - 'GCodeSpindleSpeed', - 'GCodeSpindleSpeedOverride', - 'GCodeExactPathMode', - 'GCodeExactStopMode', - 'GCodePathBlendingMode', 'GCodeSelectUVPlane', 'GCodeSelectVWPlane', 'GCodeSelectWUPlane', 'GCodeSelectXYPlane', 'GCodeSelectYZPlane', 'GCodeSelectZXPlane', - 'GCodeEndProgram', - 'GCodeEndProgramPalletShuttle', - 'GCodePalletChangePause', - 'GCodePauseProgram', - 'GCodePauseProgramOptional', - 'GCodeOrientSpindle', + 'GCodeSet', + 'GCodeSetPredefinedPosition', + 'GCodeSpeedAndFeedOverrideOff', + 'GCodeSpeedAndFeedOverrideOn', + 'GCodeSpindle', 'GCodeSpindleConstantSurfaceSpeedMode', 'GCodeSpindleRPMMode', + 'GCodeSpindleSpeed', + 'GCodeSpindleSpeedMode', + 'GCodeSpindleSpeedOverride', + 'GCodeSpindleSyncMotion', + 'GCodeStartSpindle', 'GCodeStartSpindleCCW', 'GCodeStartSpindleCW', 'GCodeStopSpindle', - 'GCodeAddToolLengthOffset', - 'GCodeCancelToolLengthOffset', - 'GCodeDynamicToolLengthOffset', + 'GCodeStraightProbe', + 'GCodeThreadingCycle', + 'GCodeToolChange', + 'GCodeToolLength', 'GCodeToolLengthOffset', + 'GCodeToolSetCurrent', + 'GCodeUnit', + 'GCodeUnitsPerMinuteMode', + 'GCodeUnitsPerRevolution', 'GCodeUseInches', 'GCodeUseMillimeters', + 'GCodeUserDefined', + 'GCodeWaitOnInput', ] # Machine @@ -139,190 +160,210 @@ from .words import ( # GCode from .gcodes import ( - GCode, words2gcodes, + words2gcodes, text2gcodes, split_gcodes, # $ python -c "from pygcode.gcodes import _gcode_class_infostr; print(_gcode_class_infostr())" - # - GCode: - # - GCodeCannedCycle: - # G89 - GCodeBoringCycleDwellFeedOut: G89: Boring Cycle, Dwell, Feed Out - # G85 - GCodeBoringCycleFeedOut: G85: Boring Cycle, Feed Out - # G81 - GCodeDrillingCycle: G81: Drilling Cycle - # G73 - GCodeDrillingCycleChipBreaking: G73: Drilling Cycle, ChipBreaking - # G82 - GCodeDrillingCycleDwell: G82: Drilling Cycle, Dwell - # G83 - GCodeDrillingCyclePeck: G83: Drilling Cycle, Peck - # G76 - GCodeThreadingCycle: G76: Threading Cycle - # - GCodeCannedReturnMode: - # G98 - GCodeCannedCycleReturnLevel: G98: Canned Cycle Return Level - # - GCodeCoolant: - # M08 - GCodeCoolantFloodOn: M8: turn flood coolant on - # M07 - GCodeCoolantMistOn: M7: turn mist coolant on - # M09 - GCodeCoolantOff: M9: turn all coolant off - # - GCodeCutterRadiusComp: - # G41 - GCodeCutterCompLeft: G41: Cutter Radius Compensation (left) - # G42 - GCodeCutterCompRight: G42: Cutter Radius Compensation (right) - # G40 - GCodeCutterRadiusCompOff: G40: Cutter Radius Compensation Off - # G41.1 - GCodeDynamicCutterCompLeft: G41.1: Dynamic Cutter Radius Compensation (left) - # G42.1 - GCodeDynamicCutterCompRight: G42.1: Dynamic Cutter Radius Compensation (right) - # - GCodeDistanceMode: - # G90.1 - GCodeAbsoluteArcDistanceMode: G90.1: Absolute Distance Mode for Arc IJK Parameters - # G90 - GCodeAbsoluteDistanceMode: G90: Absolute Distance Mode - # G91.1 - GCodeIncrementalArcDistanceMode: G91.1: Incremental Distance Mode for Arc IJK Parameters - # G91 - GCodeIncrementalDistanceMode: G91: Incremental Distance Mode - # G07 - GCodeLatheDiameterMode: G7: Lathe Diameter Mode - # G08 - GCodeLatheRadiusMode: G8: Lathe Radius Mode - # - GCodeFeedRateMode: - # G93 - GCodeInverseTimeMode: G93: Inverse Time Mode - # G94 - GCodeUnitsPerMinuteMode: G94: Units Per MinuteMode - # G95 - GCodeUnitsPerRevolution: G95: Units Per Revolution - # - GCodeIO: - # - GCodeAnalogOutput: Analog Output - # M68 - GCodeAnalogOutputImmediate: M68: Analog Output, Immediate - # M67 - GCodeAnalogOutputSyncd: M67: Analog Output, Synchronized - # - GCodeDigitalOutput: Digital Output Control - # M65 - GCodeDigitalOutputOff: M65: turn off digital output immediately - # M63 - GCodeDigitalOutputOffSyncd: M63: turn off digital output synchronized with motion - # M64 - GCodeDigitalOutputOn: M64: turn on digital output immediately - # M62 - GCodeDigitalOutputOnSyncd: M62: turn on digital output synchronized with motion - # M66 - GCodeWaitOnInput: M66: Wait on Input - # - GCodeMotion: - # - GCodeArcMove: Arc Move - # G03 - GCodeArcMoveCCW: G3: Arc Move (counter-clockwise) - # G02 - GCodeArcMoveCW: G2: Arc Move (clockwise) - # G80 - GCodeCancelCannedCycle: G80: Cancel Canned Cycle - # G05 - GCodeCublcSpline: G5: Cubic Spline - # G04 - GCodeDwell: G4: Dwell - # G01 - GCodeLinearMove: G1: Linear Move - # G05.2 - GCodeNURBS: G5.2: Non-uniform rational basis spline (NURBS) - # G05.3 - GCodeNURBSEnd: G5.3: end NURBS mode - # G05.1 - GCodeQuadraticSpline: G5.1: Quadratic Spline - # G00 - GCodeRapidMove: G0: Rapid Move - # G33.1 - GCodeRigidTapping: G33.1: Rigid Tapping - # G33 - GCodeSpindleSyncMotion: G33: Spindle Synchronized Motion - # - GCodeStraightProbe: G38.2-G38.5: Straight Probe - # - GCodeNonModal: - # G92 - GCodeCoordSystemOffset: G92: Coordinate System Offset - # - GCodeGotoPredefinedPosition: G28,G30: Goto Predefined Position (rapid movement) - # G53 - GCodeMoveInMachineCoords: G53: Move in Machine Coordinates - # - GCodeResetCoordSystemOffset: G92.1,G92.2: Reset Coordinate System Offset - # G92.3 - GCodeRestoreCoordSystemOffset: G92.3: Restore Coordinate System Offset - # G10 - GCodeSet: G10: Set stuff - # - GCodeSetPredefinedPosition: G28.1,G30.1: Set Predefined Position - # M06 - GCodeToolChange: M6: Tool Change - # M61 - GCodeToolSetCurrent: M61: Set Current Tool - # - GCodeUserDefined: M101-M199: User Defined Commands - # - GCodeOtherModal: - # M52 - GCodeAdaptiveFeed: M52: Adaptive Feed Control - # M50 - GCodeFeedOverride: M50: Feed Override Control - # - GCodeFeedRate: F: Set Feed Rate - # M53 - GCodeFeedStop: M53: Feed Stop Control - # - GCodeSelectCoordinateSystem: Select Coordinate System - # G54 - GCodeSelectCoordinateSystem1: Select Coordinate System 1 - # G55 - GCodeSelectCoordinateSystem2: Select Coordinate System 2 - # G56 - GCodeSelectCoordinateSystem3: Select Coordinate System 3 - # G57 - GCodeSelectCoordinateSystem4: Select Coordinate System 4 - # G58 - GCodeSelectCoordinateSystem5: Select Coordinate System 5 - # G59 - GCodeSelectCoordinateSystem6: Select Coordinate System 6 - # G59.1 - GCodeSelectCoordinateSystem7: Select Coordinate System 7 - # G59.2 - GCodeSelectCoordinateSystem8: Select Coordinate System 8 - # G59.3 - GCodeSelectCoordinateSystem9: Select Coordinate System 9 - # - GCodeSelectTool: T: Select Tool - # M49 - GCodeSpeedAndFeedOverrideOff: M49: Speed and Feed Override Control Off - # M48 - GCodeSpeedAndFeedOverrideOn: M48: Speed and Feed Override Control On - # - GCodeSpindleSpeed: S: Set Spindle Speed - # M51 - GCodeSpindleSpeedOverride: M51: Spindle Speed Override Control - # - GCodePathControlMode: - # G61 - GCodeExactPathMode: G61: Exact path mode - # G61.1 - GCodeExactStopMode: G61.1: Exact stop mode - # G64 - GCodePathBlendingMode: G64: Path Blending - # - GCodePlaneSelect: - # G17.1 - GCodeSelectUVPlane: G17.1: select UV plane - # G19.1 - GCodeSelectVWPlane: G19.1: select VW plane - # G18.1 - GCodeSelectWUPlane: G18.1: select WU plane - # G17 - GCodeSelectXYPlane: G17: select XY plane (default) - # G19 - GCodeSelectYZPlane: G19: select YZ plane - # G18 - GCodeSelectZXPlane: G18: select ZX plane - # - GCodeProgramControl: - # M02 - GCodeEndProgram: M2: Program End - # M30 - GCodeEndProgramPalletShuttle: M30: exchange pallet shuttles and end the program - # M60 - GCodePalletChangePause: M60: Pallet Change Pause - # M00 - GCodePauseProgram: M0: Program Pause - # M01 - GCodePauseProgramOptional: M1: Program Pause (optional) - # - GCodeSpindle: - # M19 - GCodeOrientSpindle: M19: Orient Spindle - # G96 - GCodeSpindleConstantSurfaceSpeedMode: G96: Spindle Constant Surface Speed - # G97 - GCodeSpindleRPMMode: G97: Spindle RPM Speed - # M04 - GCodeStartSpindleCCW: M4: Start Spindle Counter-Clockwise - # M03 - GCodeStartSpindleCW: M3: Start Spindle Clockwise - # M05 - GCodeStopSpindle: M5: Stop Spindle - # - GCodeToolLength: - # G43.2 - GCodeAddToolLengthOffset: G43.2: Appkly Additional Tool Length Offset - # G49 - GCodeCancelToolLengthOffset: G49: Cancel Tool Length Compensation - # G43.1 - GCodeDynamicToolLengthOffset: G43.1: Dynamic Tool Length Offset - # G43 - GCodeToolLengthOffset: G43: Tool Length Offset - # - GCodeUnit: - # G20 - GCodeUseInches: G20: use inches for length units - # G21 - GCodeUseMillimeters: G21: use millimeters for length units + # - GCode: + # - GCodeCannedCycle: + # G89 - GCodeBoringCycleDwellFeedOut: G89: Boring Cycle, Dwell, Feed Out + # G85 - GCodeBoringCycleFeedOut: G85: Boring Cycle, Feed Out + # G81 - GCodeDrillingCycle: G81: Drilling Cycle + # G73 - GCodeDrillingCycleChipBreaking: G73: Drilling Cycle, ChipBreaking + # G82 - GCodeDrillingCycleDwell: G82: Drilling Cycle, Dwell + # G83 - GCodeDrillingCyclePeck: G83: Drilling Cycle, Peck + # G76 - GCodeThreadingCycle: G76: Threading Cycle + # - GCodeCannedReturnMode: + # G98 - GCodeCannedCycleReturnLevel: G98: Canned Cycle Return Level + # - GCodeCoolant: + # M08 - GCodeCoolantFloodOn: M8: turn flood coolant on + # M07 - GCodeCoolantMistOn: M7: turn mist coolant on + # M09 - GCodeCoolantOff: M9: turn all coolant off + # - GCodeCutterRadiusComp: + # G41 - GCodeCutterCompLeft: G41: Cutter Radius Compensation (left) + # G42 - GCodeCutterCompRight: G42: Cutter Radius Compensation (right) + # G40 - GCodeCutterRadiusCompOff: G40: Cutter Radius Compensation Off + # G41.1 - GCodeDynamicCutterCompLeft: G41.1: Dynamic Cutter Radius Compensation (left) + # G42.1 - GCodeDynamicCutterCompRight: G42.1: Dynamic Cutter Radius Compensation (right) + # - GCodeDistanceMode: + # G90.1 - GCodeAbsoluteArcDistanceMode: G90.1: Absolute Distance Mode for Arc IJK Parameters + # G90 - GCodeAbsoluteDistanceMode: G90: Absolute Distance Mode + # G91.1 - GCodeIncrementalArcDistanceMode: G91.1: Incremental Distance Mode for Arc IJK Parameters + # G91 - GCodeIncrementalDistanceMode: G91: Incremental Distance Mode + # G07 - GCodeLatheDiameterMode: G7: Lathe Diameter Mode + # G08 - GCodeLatheRadiusMode: G8: Lathe Radius Mode + # - GCodeFeedRateMode: + # G93 - GCodeInverseTimeMode: G93: Inverse Time Mode + # G94 - GCodeUnitsPerMinuteMode: G94: Units Per MinuteMode + # G95 - GCodeUnitsPerRevolution: G95: Units Per Revolution + # - GCodeIO: + # - GCodeAnalogOutput: Analog Output + # M68 - GCodeAnalogOutputImmediate: M68: Analog Output, Immediate + # M67 - GCodeAnalogOutputSyncd: M67: Analog Output, Synchronized + # - GCodeDigitalOutput: Digital Output Control + # M65 - GCodeDigitalOutputOff: M65: turn off digital output immediately + # M63 - GCodeDigitalOutputOffSyncd: M63: turn off digital output synchronized with motion + # M64 - GCodeDigitalOutputOn: M64: turn on digital output immediately + # M62 - GCodeDigitalOutputOnSyncd: M62: turn on digital output synchronized with motion + # M66 - GCodeWaitOnInput: M66: Wait on Input + # - GCodeMotion: + # - GCodeArcMove: Arc Move + # G03 - GCodeArcMoveCCW: G3: Arc Move (counter-clockwise) + # G02 - GCodeArcMoveCW: G2: Arc Move (clockwise) + # G80 - GCodeCancelCannedCycle: G80: Cancel Canned Cycle + # G05 - GCodeCublcSpline: G5: Cubic Spline + # G04 - GCodeDwell: G4: Dwell + # G01 - GCodeLinearMove: G1: Linear Move + # G05.2 - GCodeNURBS: G5.2: Non-uniform rational basis spline (NURBS) + # G05.3 - GCodeNURBSEnd: G5.3: end NURBS mode + # G05.1 - GCodeQuadraticSpline: G5.1: Quadratic Spline + # G00 - GCodeRapidMove: G0: Rapid Move + # G33.1 - GCodeRigidTapping: G33.1: Rigid Tapping + # G33 - GCodeSpindleSyncMotion: G33: Spindle Synchronized Motion + # - GCodeStraightProbe: G38.2-G38.5: Straight Probe + # - GCodeNonModal: + # G92 - GCodeCoordSystemOffset: G92: Coordinate System Offset + # - GCodeGotoPredefinedPosition: G28,G30: Goto Predefined Position (rapid movement) + # G53 - GCodeMoveInMachineCoords: G53: Move in Machine Coordinates + # - GCodeResetCoordSystemOffset: G92.1,G92.2: Reset Coordinate System Offset + # G92.3 - GCodeRestoreCoordSystemOffset: G92.3: Restore Coordinate System Offset + # G10 - GCodeSet: G10: Set stuff + # - GCodeSetPredefinedPosition: G28.1,G30.1: Set Predefined Position + # M06 - GCodeToolChange: M6: Tool Change + # M61 - GCodeToolSetCurrent: M61: Set Current Tool + # - GCodeUserDefined: M101-M199: User Defined Commands + # - GCodeOtherModal: + # M52 - GCodeAdaptiveFeed: M52: Adaptive Feed Control + # M50 - GCodeFeedOverride: M50: Feed Override Control + # - GCodeFeedRate: F: Set Feed Rate + # M53 - GCodeFeedStop: M53: Feed Stop Control + # - GCodeSelectCoordinateSystem: Select Coordinate System + # G54 - GCodeSelectCoordinateSystem1: Select Coordinate System 1 + # G55 - GCodeSelectCoordinateSystem2: Select Coordinate System 2 + # G56 - GCodeSelectCoordinateSystem3: Select Coordinate System 3 + # G57 - GCodeSelectCoordinateSystem4: Select Coordinate System 4 + # G58 - GCodeSelectCoordinateSystem5: Select Coordinate System 5 + # G59 - GCodeSelectCoordinateSystem6: Select Coordinate System 6 + # G59.1 - GCodeSelectCoordinateSystem7: Select Coordinate System 7 + # G59.2 - GCodeSelectCoordinateSystem8: Select Coordinate System 8 + # G59.3 - GCodeSelectCoordinateSystem9: Select Coordinate System 9 + # - GCodeSelectTool: T: Select Tool + # M49 - GCodeSpeedAndFeedOverrideOff: M49: Speed and Feed Override Control Off + # M48 - GCodeSpeedAndFeedOverrideOn: M48: Speed and Feed Override Control On + # - GCodeSpindleSpeed: S: Set Spindle Speed + # M51 - GCodeSpindleSpeedOverride: M51: Spindle Speed Override Control + # - GCodePathControlMode: + # G61 - GCodeExactPathMode: G61: Exact path mode + # G61.1 - GCodeExactStopMode: G61.1: Exact stop mode + # G64 - GCodePathBlendingMode: G64: Path Blending + # - GCodePlaneSelect: + # G17.1 - GCodeSelectUVPlane: G17.1: select UV plane + # G19.1 - GCodeSelectVWPlane: G19.1: select VW plane + # G18.1 - GCodeSelectWUPlane: G18.1: select WU plane + # G17 - GCodeSelectXYPlane: G17: select XY plane (default) + # G19 - GCodeSelectYZPlane: G19: select YZ plane + # G18 - GCodeSelectZXPlane: G18: select ZX plane + # - GCodeProgramControl: + # M02 - GCodeEndProgram: M2: Program End + # M30 - GCodeEndProgramPalletShuttle: M30: exchange pallet shuttles and end the program + # M60 - GCodePalletChangePause: M60: Pallet Change Pause + # M00 - GCodePauseProgram: M0: Program Pause + # M01 - GCodePauseProgramOptional: M1: Program Pause (optional) + # - GCodeSpindle: + # M19 - GCodeOrientSpindle: M19: Orient Spindle + # - GCodeSpindleSpeedMode: + # G96 - GCodeSpindleConstantSurfaceSpeedMode: G96: Spindle Constant Surface Speed + # G97 - GCodeSpindleRPMMode: G97: Spindle RPM Speed + # - GCodeStartSpindle: M3,M4: Start Spindle Clockwise + # M04 - GCodeStartSpindleCCW: M4: Start Spindle Counter-Clockwise + # M03 - GCodeStartSpindleCW: M3: Start Spindle Clockwise + # M05 - GCodeStopSpindle: M5: Stop Spindle + # - GCodeToolLength: + # G43.2 - GCodeAddToolLengthOffset: G43.2: Appkly Additional Tool Length Offset + # G49 - GCodeCancelToolLengthOffset: G49: Cancel Tool Length Compensation + # G43.1 - GCodeDynamicToolLengthOffset: G43.1: Dynamic Tool Length Offset + # G43 - GCodeToolLengthOffset: G43: Tool Length Offset + # - GCodeUnit: + # G20 - GCodeUseInches: G20: use inches for length units + # G21 - GCodeUseMillimeters: G21: use millimeters for length units + # $ python -c "from pygcode.gcodes import GCode, _subclasses; print(',\\n'.join(sorted(g.__name__ for g in _subclasses(GCode))))"python -c "from pygcode.gcodes import GCode, _subclasses; print(',\\n'.join(sorted(g.__name__ for g in _subclasses(GCode))))" + GCode, + GCodeAbsoluteArcDistanceMode, + GCodeAbsoluteDistanceMode, + GCodeAdaptiveFeed, + GCodeAddToolLengthOffset, + GCodeAnalogOutput, + GCodeAnalogOutputImmediate, + GCodeAnalogOutputSyncd, + GCodeArcMove, + GCodeArcMoveCCW, + GCodeArcMoveCW, GCodeBoringCycleDwellFeedOut, GCodeBoringCycleFeedOut, - GCodeDrillingCycle, - GCodeDrillingCycleChipBreaking, - GCodeDrillingCycleDwell, - GCodeDrillingCyclePeck, - GCodeThreadingCycle, + GCodeCancelCannedCycle, + GCodeCancelToolLengthOffset, + GCodeCannedCycle, GCodeCannedCycleReturnLevel, + GCodeCannedReturnMode, + GCodeCoolant, GCodeCoolantFloodOn, GCodeCoolantMistOn, GCodeCoolantOff, + GCodeCoordSystemOffset, + GCodeCublcSpline, GCodeCutterCompLeft, GCodeCutterCompRight, + GCodeCutterRadiusComp, GCodeCutterRadiusCompOff, - GCodeDynamicCutterCompLeft, - GCodeDynamicCutterCompRight, - GCodeAbsoluteArcDistanceMode, - GCodeAbsoluteDistanceMode, - GCodeIncrementalArcDistanceMode, - GCodeIncrementalDistanceMode, - GCodeLatheDiameterMode, - GCodeLatheRadiusMode, - GCodeInverseTimeMode, - GCodeUnitsPerMinuteMode, - GCodeUnitsPerRevolution, - GCodeAnalogOutputImmediate, - GCodeAnalogOutputSyncd, + GCodeDigitalOutput, GCodeDigitalOutputOff, GCodeDigitalOutputOffSyncd, GCodeDigitalOutputOn, GCodeDigitalOutputOnSyncd, - GCodeWaitOnInput, - GCodeArcMove, - GCodeArcMoveCCW, - GCodeArcMoveCW, - GCodeCancelCannedCycle, - GCodeCublcSpline, + GCodeDistanceMode, + GCodeDrillingCycle, + GCodeDrillingCycleChipBreaking, + GCodeDrillingCycleDwell, + GCodeDrillingCyclePeck, GCodeDwell, - GCodeLinearMove, - GCodeNURBS, - GCodeNURBSEnd, - GCodeQuadraticSpline, - GCodeRapidMove, - GCodeRigidTapping, - GCodeSpindleSyncMotion, - GCodeStraightProbe, - GCodeCoordSystemOffset, - GCodeGotoPredefinedPosition, - GCodeMoveInMachineCoords, - GCodeResetCoordSystemOffset, - GCodeRestoreCoordSystemOffset, - GCodeSet, - GCodeSetPredefinedPosition, - GCodeToolChange, - GCodeToolSetCurrent, - GCodeUserDefined, - GCodeAdaptiveFeed, + GCodeDynamicCutterCompLeft, + GCodeDynamicCutterCompRight, + GCodeDynamicToolLengthOffset, + GCodeEndProgram, + GCodeEndProgramPalletShuttle, + GCodeExactPathMode, + GCodeExactStopMode, GCodeFeedOverride, GCodeFeedRate, + GCodeFeedRateMode, GCodeFeedStop, + GCodeGotoPredefinedPosition, + GCodeIO, + GCodeIncrementalArcDistanceMode, + GCodeIncrementalDistanceMode, + GCodeInverseTimeMode, + GCodeLatheDiameterMode, + GCodeLatheRadiusMode, + GCodeLinearMove, + GCodeMotion, + GCodeMoveInMachineCoords, + GCodeNURBS, + GCodeNURBSEnd, + GCodeNonModal, + GCodeOrientSpindle, + GCodeOtherModal, + GCodePalletChangePause, + GCodePathBlendingMode, + GCodePathControlMode, + GCodePauseProgram, + GCodePauseProgramOptional, + GCodePlaneSelect, + GCodeProgramControl, + GCodeQuadraticSpline, + GCodeRapidMove, + GCodeResetCoordSystemOffset, + GCodeRestoreCoordSystemOffset, + GCodeRigidTapping, GCodeSelectCoordinateSystem, GCodeSelectCoordinateSystem1, GCodeSelectCoordinateSystem2, @@ -334,34 +375,38 @@ from .gcodes import ( GCodeSelectCoordinateSystem8, GCodeSelectCoordinateSystem9, GCodeSelectTool, - GCodeSpeedAndFeedOverrideOff, - GCodeSpeedAndFeedOverrideOn, - GCodeSpindleSpeed, - GCodeSpindleSpeedOverride, - GCodeExactPathMode, - GCodeExactStopMode, - GCodePathBlendingMode, GCodeSelectUVPlane, GCodeSelectVWPlane, GCodeSelectWUPlane, GCodeSelectXYPlane, GCodeSelectYZPlane, GCodeSelectZXPlane, - GCodeEndProgram, - GCodeEndProgramPalletShuttle, - GCodePalletChangePause, - GCodePauseProgram, - GCodePauseProgramOptional, - GCodeOrientSpindle, + GCodeSet, + GCodeSetPredefinedPosition, + GCodeSpeedAndFeedOverrideOff, + GCodeSpeedAndFeedOverrideOn, + GCodeSpindle, GCodeSpindleConstantSurfaceSpeedMode, GCodeSpindleRPMMode, + GCodeSpindleSpeed, + GCodeSpindleSpeedMode, + GCodeSpindleSpeedOverride, + GCodeSpindleSyncMotion, + GCodeStartSpindle, GCodeStartSpindleCCW, GCodeStartSpindleCW, GCodeStopSpindle, - GCodeAddToolLengthOffset, - GCodeCancelToolLengthOffset, - GCodeDynamicToolLengthOffset, + GCodeStraightProbe, + GCodeThreadingCycle, + GCodeToolChange, + GCodeToolLength, GCodeToolLengthOffset, + GCodeToolSetCurrent, + GCodeUnit, + GCodeUnitsPerMinuteMode, + GCodeUnitsPerRevolution, GCodeUseInches, GCodeUseMillimeters, + GCodeUserDefined, + GCodeWaitOnInput, ) diff --git a/pygcode/gcodes.py b/pygcode/gcodes.py index 6b20d9e..167aea2 100644 --- a/pygcode/gcodes.py +++ b/pygcode/gcodes.py @@ -1,9 +1,9 @@ from collections import defaultdict from copy import copy -from .words import Word +from .words import Word, text2words -from .exceptions import GCodeParameterError +from .exceptions import GCodeParameterError, GCodeWordStrError # Terminology of a "G-Code" # For the purposes of this library, so-called "G" codes do not necessarily @@ -138,6 +138,7 @@ class GCode(object): # Defining Word word_key = None # Word instance to use in lookup word_matches = None # function (secondary) + default_word = None # Parameters associated to this gcode param_letters = set() @@ -149,18 +150,24 @@ class GCode(object): # Execution Order exec_order = 999 # if not otherwise specified, run last - def __init__(self, word, *params): + def __init__(self, *words): """ :param word: Word instance defining gcode (eg: Word('G0') for rapid movement) :param params: list of Word instances (eg: Word('X-1.2') as x-coordinate) """ - assert isinstance(word, Word), "invalid gcode word %r" % code_word - self.word = word + gcode_word_list = words[:1] + param_words = words[1:] + if gcode_word_list: + gcode_word = gcode_word_list[0] + else: + gcode_word = self._default_word() + assert isinstance(gcode_word, Word), "invalid gcode word %r" % gcode_word + self.word = gcode_word self.params = {} # Add Given Parameters - for param in params: - self.add_parameter(param) + for param_word in param_words: + self.add_parameter(param_word) def __repr__(self): param_str = '' @@ -188,10 +195,23 @@ class GCode(object): parameters=param_str, ) - # Sort by exec_order + def _default_word(self): + if self.default_word: + return copy(self.default_word) + elif self.word_key: + return copy(self.word_key) + raise AssertionError("class %r has no default word" % self.__class__) + + # Comparisons def __lt__(self, other): + """Sort by execution order""" return self.exec_order < other.exec_order + def __gt__(self, other): + """Sort by execution order""" + return self.exec_order > other.exec_order + + # Parameters def add_parameter(self, word): """ Add given word as a parameter for this gcode @@ -355,6 +375,7 @@ class GCodeStraightProbe(GCodeMotion): @classmethod def word_matches(cls, w): return (w.letter == 'G') and (38.2 <= w.value <= 38.5) + default_word = Word('G', 38.2) class GCodeSpindleSyncMotion(GCodeMotion): @@ -512,17 +533,20 @@ class GCodeSpindle(GCode): exec_order = 90 -class GCodeStartSpindleCW(GCodeSpindle): +class GCodeStartSpindle(GCodeSpindle): + """M3,M4: Start Spindle Clockwise""" + modal_group = MODAL_GROUP_MAP['spindle'] + + +class GCodeStartSpindleCW(GCodeStartSpindle): """M3: Start Spindle Clockwise""" #param_letters = set('S') # S is it's own gcode, makes no sense to be here word_key = Word('M', 3) - modal_group = MODAL_GROUP_MAP['spindle'] -class GCodeStartSpindleCCW(GCodeSpindle): +class GCodeStartSpindleCCW(GCodeStartSpindle): """M4: Start Spindle Counter-Clockwise""" #param_letters = set('S') # S is it's own gcode, makes no sense to be here word_key = Word('M', 4) - modal_group = MODAL_GROUP_MAP['spindle'] class GCodeStopSpindle(GCodeSpindle): @@ -537,18 +561,20 @@ class GCodeOrientSpindle(GCodeSpindle): word_key = Word('M', 19) -class GCodeSpindleConstantSurfaceSpeedMode(GCodeSpindle): +class GCodeSpindleSpeedMode(GCodeSpindle): + modal_group = MODAL_GROUP_MAP['spindle_speed_mode'] + + +class GCodeSpindleConstantSurfaceSpeedMode(GCodeSpindleSpeedMode): """G96: Spindle Constant Surface Speed""" param_letters = set('DS') word_key = Word('G', 96) - modal_group = MODAL_GROUP_MAP['spindle_speed_mode'] -class GCodeSpindleRPMMode(GCodeSpindle): +class GCodeSpindleRPMMode(GCodeSpindleSpeedMode): """G97: Spindle RPM Speed""" param_letters = set('D') word_key = Word('G', 97) - modal_group = MODAL_GROUP_MAP['spindle_speed_mode'] @@ -807,6 +833,7 @@ class GCodeFeedRate(GCodeOtherModal): @classmethod def word_matches(cls, w): return w.letter == 'F' + default_word = Word('F', 0) modal_group = MODAL_GROUP_MAP['feed_rate'] exec_order = 40 @@ -816,6 +843,7 @@ class GCodeSpindleSpeed(GCodeOtherModal): @classmethod def word_matches(cls, w): return w.letter == 'S' + default_word = Word('S', 0) # Modal Group: (see description in GCodeFeedRate) modal_group = MODAL_GROUP_MAP['spindle_speed'] exec_order = 50 @@ -826,6 +854,7 @@ class GCodeSelectTool(GCodeOtherModal): @classmethod def word_matches(cls, w): return w.letter == 'T' + default_word = Word('T', 0) # Modal Group: (see description in GCodeFeedRate) modal_group = MODAL_GROUP_MAP['tool'] exec_order = 60 @@ -1052,6 +1081,7 @@ class GCodeGotoPredefinedPosition(GCodeNonModal): @classmethod def word_matches(cls, w): return (w.letter == 'G') and (w.value in [28, 30]) + default_word = Word('G', 28) exec_order = 230 @@ -1060,6 +1090,7 @@ class GCodeSetPredefinedPosition(GCodeNonModal): @classmethod def word_matches(cls, w): return (w.letter == 'G') and (w.value in [28.1, 30.1]) + default_word = Word('G', 28.1) exec_order = 230 @@ -1080,6 +1111,7 @@ class GCodeResetCoordSystemOffset(GCodeNonModal): @classmethod def word_matches(cls, w): return (w.letter == 'G') and (w.value in [92.1, 92.2]) + default_word = Word('G', 92.1) exec_order = 230 # TODO: machine.state.offset *= 0 @@ -1098,6 +1130,7 @@ class GCodeUserDefined(GCodeNonModal): #@classmethod #def word_matches(cls, w): # return (w.letter == 'M') and (101 <= w.value <= 199) + #default_word = Word('M', 101) exec_order = 130 modal_group = MODAL_GROUP_MAP['user_defined'] @@ -1171,6 +1204,7 @@ def build_maps(): _gcode_maps_created = True +# ======================= Words -> GCodes ======================= def word_gcode_class(word, exhaustive=False): """ Map word to corresponding GCode class @@ -1179,7 +1213,7 @@ def word_gcode_class(word, exhaustive=False): :return: class inheriting GCode """ - if _gcode_maps_created is False: + if not _gcode_maps_created: build_maps() # quickly eliminate parameters @@ -1197,6 +1231,7 @@ def word_gcode_class(word, exhaustive=False): return None + def words2gcodes(words): """ Group words into g-codes (includes both G & M codes) @@ -1257,3 +1292,51 @@ def words2gcodes(words): gcodes.append(gcode) return (gcodes, parameter_map[None]) + + +def text2gcodes(text): + """ + Convert text to GCode instances (must be fully formed; no modal parameters) + :param text: line from a g-code file + :return: tuple([, , ...], list()) + """ + words = list(text2words(text)) + (gcodes, modal_words) = words2gcodes(words) + if modal_words: + raise GCodeWordStrError("gcode text not fully formed, unassigned parameters: %r" % modal_words) + return gcodes + + +# ======================= Utilities ======================= + +def split_gcodes(gcode_list, splitter_class, sort_list=True): + """ + Splits a list of GCode instances into 3, the center list containing the splitter_class gcode + :param gcode_list: list of GCode instances to split + :param splitter_class: class of gcode identifying split from left to right + :return: list of: [[], [], []] + """ + # for example: + # g_list = sorted([g1, g2, g3, g4]) + # split_gcodes(g_list, type(g2)) == [[g1], [g2], [g3, g4]] + # 3 lists are always returned, even if empty; if 2nd list is empty, + # then the 3rd will be as well. + if sort_list: # sort by execution order first + gcode_list = sorted(gcode_list) + + split = [gcode_list, [], []] # default (if no splitter can be found) + + # Find splitter index (only one can be found) + split_index = None + for (i, gcode) in enumerate(gcode_list): + if isinstance(gcode, splitter_class): + split_index = i + break + + # Form split: pivoting around split_index + if split_index is not None: + split[0] = gcode_list[:split_index] + split[1] = [gcode_list[split_index]] + split[2] = gcode_list[split_index+1:] + + return split diff --git a/pygcode/line.py b/pygcode/line.py index a1bd290..881b5f1 100644 --- a/pygcode/line.py +++ b/pygcode/line.py @@ -12,8 +12,7 @@ class Line(object): # Split line into block text, and comments if text is not None: (block_str, comment) = split_line(text) - if block_str: - self.block = Block(block_str) + self.block = Block(block_str) if comment: self.comment = comment @@ -23,5 +22,10 @@ class Line(object): return str(self) return self._text + @property + def gcodes(self): + """self.block.gcodes passthrough""" + return self.block.gcodes + def __str__(self): return ' '.join([str(x) for x in [self.block, self.comment] if x]) diff --git a/pygcode/machine.py b/pygcode/machine.py index 8dc1db8..9ff7300 100644 --- a/pygcode/machine.py +++ b/pygcode/machine.py @@ -253,7 +253,7 @@ class Mode(object): def set_mode(self, *gcode_list): """ - Set machine mode from given gcodes + Set machine mode from given gcodes (will not be processed) :param gcode_list: list of GCode instances (given as individual parameters) :return: dict of form: {: , ...} """ @@ -291,12 +291,17 @@ class Mode(object): else: self.__dict__[key] = value - def __str__(self): + @property + def gcodes(self): + """List of modal gcodes""" gcode_list = [] for modal_group in sorted(MODAL_GROUP_MAP.values()): if self.modal_groups[modal_group]: gcode_list.append(self.modal_groups[modal_group]) - return ' '.join(str(g) for g in gcode_list) + return gcode_list + + def __str__(self): + return ' '.join(str(g) for g in self.gcodes) def __repr__(self): return "<{class_name}: {gcodes}>".format( @@ -318,9 +323,10 @@ class Machine(object): self.state = self.STATE_CLASS(axes=self.axes) # Position type (with default axes the same as this machine) + units_mode = getattr(self.mode, 'units', None) self.Position = type('Position', (Position,), { 'default_axes': self.axes, - 'default_unit': self.mode.units.unit_id, + 'default_unit': units_mode.unit_id if units_mode else UNIT_METRIC, }) # Absolute machine position @@ -335,6 +341,7 @@ class Machine(object): self.state.cur_coord_sys = coord_sys_mode.coord_system_id def modal_gcode(self, modal_params): + if not modal_params: return None if self.mode.motion is None: @@ -349,7 +356,7 @@ class Machine(object): return modal_gcodes[0] return None - def process(self, *gcode_list, **kwargs): + def process_gcodes(self, *gcode_list, **kwargs): """ Process gcodes :param gcode_list: list of GCode instances @@ -377,7 +384,11 @@ class Machine(object): # - Crop a file (eg: resume half way through) def process_block(self, block): - self.process(*block.gcodes, modal_params=block.modal_params) + self.process_gcodes(*block.gcodes, modal_params=block.modal_params) + + def process_str(self, block_str): + line = Line(block_str) + self.process_block(line.block) @property def pos(self): diff --git a/tests/test_gcodes.py b/tests/test_gcodes.py index ef3374a..34e4a22 100644 --- a/tests/test_gcodes.py +++ b/tests/test_gcodes.py @@ -11,7 +11,10 @@ add_pygcode_to_path() # Units under test from pygcode import gcodes from pygcode import words -class TestGCodeWordMapping(unittest.TestCase): + +from pygcode.exceptions import GCodeWordStrError + +class GCodeWordMappingTests(unittest.TestCase): def test_word_map_integrity(self): gcodes.build_maps() @@ -24,7 +27,7 @@ class TestGCodeWordMapping(unittest.TestCase): "conflict with %s and %s" % (fn_class, key_class) ) -class TestGCodeModalGroups(unittest.TestCase): +class GCodeModalGroupTests(unittest.TestCase): def test_modal_groups(self): # Modal groups taken (and slightly modified) from LinuxCNC documentation: # link: http://linuxcnc.org/docs/html/gcode/overview.html#_modal_groups @@ -80,7 +83,7 @@ class TestGCodeModalGroups(unittest.TestCase): ) -class TestWordsToGCodes(unittest.TestCase): +class Words2GCodesTests(unittest.TestCase): def test_stuff(self): # FIXME: function name line = 'G1 X82.6892 Y-38.6339 F1500' word_list = list(words.text2words(line)) @@ -99,3 +102,40 @@ class TestWordsToGCodes(unittest.TestCase): self.assertEqual(gcode_list[0].Y, -38.6339) # F1500 self.assertEqual(gcode_list[1].word, words.Word('F', 1500)) + + +class Text2GCodesTests(unittest.TestCase): + def test_basic(self): + gcs = gcodes.text2gcodes('G1 X1 Y2 G90') + self.assertEqual(len(gcs), 2) + # G1 X1 Y2 + self.assertEqual(gcs[0].word, words.Word('G', 1)) + self.assertEqual(gcs[0].X, 1) + self.assertEqual(gcs[0].Y, 2) + # G90 + self.assertEqual(gcs[1].word, words.Word('G', 90)) + + def test_modal_params(self): + with self.assertRaises(GCodeWordStrError): + gcodes.text2gcodes('X1 Y2') + + +class GCodeSplitTests(unittest.TestCase): + + def test_split(self): + g_list = gcodes.text2gcodes('G91 S1000 G1 X1 Y2 M3') + split = gcodes.split_gcodes(g_list, gcodes.GCodeStartSpindle) + self.assertEqual([len(x) for x in split], [1, 1, 2]) + self.assertTrue(any(isinstance(g, gcodes.GCodeSpindleSpeed) for g in split[0])) + self.assertTrue(isinstance(split[1][0], gcodes.GCodeStartSpindle)) + self.assertTrue(any(isinstance(g, gcodes.GCodeDistanceMode) for g in split[2])) + self.assertTrue(any(isinstance(g, gcodes.GCodeMotion) for g in split[2])) + + def test_split_unsorted(self): + g_list = gcodes.text2gcodes('G91 G1 X1 Y2 M3 S1000') + split = gcodes.split_gcodes(g_list, gcodes.GCodeStartSpindle, sort_list=False) + self.assertEqual([len(x) for x in split], [2, 1, 1]) + self.assertTrue(any(isinstance(g, gcodes.GCodeDistanceMode) for g in split[0])) + self.assertTrue(any(isinstance(g, gcodes.GCodeMotion) for g in split[0])) + self.assertTrue(isinstance(split[1][0], gcodes.GCodeStartSpindle)) + self.assertTrue(any(isinstance(g, gcodes.GCodeSpindleSpeed) for g in split[2]))