Exemplo n.º 1
0
    def makeListOfCmds(self):
        rectPath = RectPath(self.point0, self.point1, plane=self.plane)
        x0, y0 = self.point0
        x1, y1 = self.point1
        xMid = 0.5 * (x0 + x1)
        yMid = 0.5 * (y0 + y1)
        kx, ky = PLANE_COORD[self.plane]

        self.listOfCmds = []
        for i, cmd in enumerate(rectPath.listOfCmds):
            self.listOfCmds.append(cmd)
            if i > 0:
                cornerStr = self.numToCornerStr[i]
                if self.cornerCutDict[cornerStr]:
                    x = cmd.motionDict[kx]
                    y = cmd.motionDict[ky]
                    normConst = math.sqrt((x - xMid)**2 + (y - yMid)**2)
                    u = (x - xMid) / abs(x - xMid)
                    v = (y - yMid) / abs(y - yMid)
                    xCut = x + self.cornerCutLen * u / math.sqrt(2.0)
                    yCut = y + self.cornerCutLen * v / math.sqrt(2.0)
                    cmd = gcode_cmd.LinearFeed(**{kx: xCut, ky: yCut})
                    self.listOfCmds.append(cmd)
                    cmd = gcode_cmd.LinearFeed(**{kx: x, ky: y})
                    self.listOfCmds.append(cmd)
Exemplo n.º 2
0
 def makeListOfCmds(self):
     kx, ky = PLANE_COORD[self.plane]
     kz = PLANE_NORM_COORD[self.plane]
     pointList = self.getPathPointList()
     if self.radius is None:
         if self.helix is None:
             self.listOfCmds = [
                 gcode_cmd.LinearFeed(**{
                     kx: x,
                     ky: y
                 }) for x, y in pointList
             ]
         else:
             self.listOfCmds = [
                 gcode_cmd.LinearFeed(**{
                     kx: x,
                     ky: y,
                     kz: z
                 }) for x, y, z in pointList
             ]
     else:
         ki, kj = HELICAL_OFFSETS[self.plane]
         cornerArcClass = PLANE_TO_HELIX_MOTION[self.plane]
         arcDir = getDirFromPts(pointList[0][:2], pointList[1][:2],
                                pointList[2][:2])
         self.listOfCmds = []
         for i in range(0, len(pointList) - 1):
             # Create linear feed
             x0, y0 = pointList[i][:2]
             linearFeedDict = {kx: x0, ky: y0}
             if self.helix is not None:
                 z0 = pointList[i][2]
                 linearFeedDict[kz] = z0
             linearFeed = gcode_cmd.LinearFeed(**linearFeedDict)
             self.listOfCmds.append(linearFeed)
             # Create corner arc feed
             if (i - 1) % 2 == 0:
                 x1, y1 = pointList[i + 1][:2]
                 if arcDir == 'ccw':
                     cx = 0.5 * (y0 - y1 + x0 + x1)
                     cy = 0.5 * (y0 + y1 - x0 + x1)
                 else:
                     cx = 0.5 * (-y0 + y1 + x0 + x1)
                     cy = 0.5 * (y0 + y1 + x0 - x1)
                 offsetx = cx - x0
                 offsety = cy - y0
                 cornerArcDict = {
                     ki: offsetx,
                     kj: offsety,
                     kx: x1,
                     ky: y1,
                     'd': arcDir
                 }
                 if self.helix is not None:
                     z1 = pointList[i + 1][2]
                     cornerArcDict[kz] = z1
                 cornerArcFeed = cornerArcClass(**cornerArcDict)
                 self.listOfCmds.append(cornerArcFeed)
Exemplo n.º 3
0
def getUniDirRasterRect(point0, point1, step, cutZ, retZ,
                        keys=('x', 'y', 'z')):
    """
    Generates a uni-directional rastered rectangle path.

    Details: ...
    """
    x0, y0 = point0
    x1, y1 = point1
    cmdList = []
    # Get step size and raster completion function
    if y0 < y1:
        dy = step

        def outOfBounds(y):
            return y > y1
    else:
        dy = -step

        def outOfBounds(y):
            return y < y1

    # Get function for alternating x direction
    def getAlternateX(xLast):
        if xLast == x0:
            return x1
        else:
            return x0

    # Generate raster
    x, y = x0, y0
    kx, ky, kz = keys
    isFirst = True
    isLast = False
    cmdList.append(gcode_cmd.LinearFeed(**{kx: x, ky: y, kz: cutZ}))
    while 1:
        x = getAlternateX(x)
        if x == x0:
            cmdList.append(gcode_cmd.LinearFeed(**{kz: retZ}))
            cmdList.append(gcode_cmd.RapidMotion(**{kx: x, ky: y}))
        else:
            cmdList.append(gcode_cmd.LinearFeed(**{kz: cutZ}))
            if isFirst:
                isFirst = False
            else:
                y += dy
                if outOfBounds(y):
                    y = y1
                    isLast = True
                cmdList.append(gcode_cmd.LinearFeed(**{ky: y}))
            cmdList.append(gcode_cmd.LinearFeed(**{kx: x, ky: y}))
        if isLast:
            break
    return cmdList
Exemplo n.º 4
0
    def makeListOfCmds(self):
        kx, ky = PLANE_COORD[self.plane]
        ki, kj = HELICAL_OFFSETS[self.plane]
        kz = PLANE_NORM_COORD[self.plane]
        cx, cy = self.center
        x0, y0 = self.getStartPoint()[:2]
        x1, y1 = self.getStopPoint()[:2]
        turns = self.getNumTurns()

        # Get helix motion class based on plane
        helixMotionClass = PLANE_TO_HELIX_MOTION[self.plane]

        self.listOfCmds = []

        # Add linear feed to start position
        if self.includeFeedToStart:
            linearFeedArgs = {kx: x0, ky: y0}
            if self.helix is not None:
                linearFeedArgs[kz] = self.helix[0]
            self.listOfCmds.append(gcode_cmd.LinearFeed(**linearFeedArgs))

        # Add helical motion feed
        helixFeedArgs = {
            kx: x1,
            ky: y1,
            ki: cx - x0,
            kj: cy - y0,
            'd': self.direction
        }
        if self.helix is not None:
            helixFeedArgs[kz] = self.helix[1]
        if turns > 1:
            helixFeedArgs['p'] = turns
        self.listOfCmds.append(helixMotionClass(**helixFeedArgs))
Exemplo n.º 5
0
def getBiDirRasterRect(point0, point1, step, keys=('x', 'y')):
    """
    Generates a bi-directional rastered rectangle  path defined by
    point0=(x0,y0) and point1=(x1,y1). The raster scan is in the direction of
    the 1st coordinate and path starts by initially cutting from x0 to x1.  The
    spacing between rows in is determined by step. 
    """
    x0, y0 = point0
    x1, y1 = point1
    cmdList = []
    # Get step size and raster completion function
    if y0 < y1:
        dy = step

        def rasterDone(y):
            return (y + dy) > y1
    else:
        dy = -step

        def rasterDone(y):
            return (y + dy) < y1

    # Get function for alternating x direction
    def getAlternateX(xLast):
        if xLast == x0:
            return x1
        else:
            return x0

    # Generate raster
    x, y = x0, y0
    kx, ky = keys
    cmdList.append(gcode_cmd.LinearFeed(**{kx: x, ky: y}))
    while 1:
        x = getAlternateX(x)
        cmdList.append(gcode_cmd.LinearFeed(**{kx: x, ky: y}))
        if rasterDone(y):
            break
        y += dy
        cmdList.append(gcode_cmd.LinearFeed(**{kx: x, ky: y}))
    if y != y1:
        y = y1
        cmdList.append(gcode_cmd.LinearFeed(**{kx: x, ky: y}))
        x = getAlternateX(x)
        cmdList.append(gcode_cmd.LinearFeed(**{kx: x, ky: y}))
    return cmdList
Exemplo n.º 6
0
 def getLinearFeedFromPt(self, p):
     kx, ky = PLANE_COORD[self.plane]
     if len(p) == 2:
         feedArgs = {kx: p[0], ky: p[1]}
     else:
         kz = PLANE_NORM_COORD[self.plane]
         feedArgs = {kx: p[0], ky: p[1], kz: p[2]}
     return gcode_cmd.LinearFeed(**feedArgs)
Exemplo n.º 7
0
    def makeListOfCmds(self):

        # Retreive numerical parameters and convert to float 
        cx = float(self.param['centerX'])
        cy = float(self.param['centerY'])
        width = abs(float(self.param['width']))
        height = abs(float(self.param['height']))
        depth = abs(float(self.param['depth']))
        startZ = float(self.param['startZ'])
        overlap = float(self.param['overlap'])
        try:
            overlapFinish = self.param['overlapFinish']
        except KeyError:
            overlapFinish = overlap
        overlapFinish = float(overlapFinish)
        maxCutDepth = float(self.param['maxCutDepth'])
        toolDiam = abs(float(self.param['toolDiam']))
        try:
            startDwell = self.param['startDwell']
        except KeyError:
            startDwell = 0.0
        startDwell = abs(float(startDwell))
        try:
            cornerMargin = self.param['cornerMargin']
        except KeyError:
            cornerMargin = 0.0
        cornerMargin = float(cornerMargin)
        try:
            coolingPause = self.param['coolingPause']
        except KeyError:
            coolingPause = None

        # Check params
        checkRectPocketOverlap(overlap)
        checkRectPocketOverlap(overlapFinish)

        # Get rectangular path parameters
        if self.param['direction'] == 'cw':
            sgnDir = 1.0
        else:
            sgnDir = -1.0
        x0 = cx + 0.5*(-width + toolDiam)
        x1 = cx + 0.5*( width - toolDiam)
        y0 = cy + 0.5*sgnDir*(-height + toolDiam)
        y1 = cy + 0.5*sgnDir*( height - toolDiam)
        point0 = x0,y0
        point1 = x1,y1

        # Move to safe height, then to start x,y and then to start z
        self.addStartComment()
        self.addRapidMoveToSafeZ()
        self.addRapidMoveToPos(x=x0,y=y0,comment='start x,y')
        self.addDwell(startDwell)
        self.addMoveToStartZ()

        # Get z cutting parameters 
        stopZ = startZ - depth
        prevZ = startZ
        currZ = max([startZ - maxCutDepth, stopZ])

        done = False
        passCnt = 0

        while not done:

            passCnt+=1

            # Lead-in to cut depth
            self.addComment('pass {0} lead-in'.format(passCnt))
            leadInRect = cnc_path.RectPath(
                    point0,
                    point1,
                    plane='xy', 
                    helix=(prevZ,currZ)
                    )
            self.listOfCmds.extend(leadInRect.listOfCmds)

            # Cut filled rectangular path
            self.addComment('pass {0} filled rectangle'.format(passCnt))
            if currZ == stopZ:
                passOverlap = overlapFinish
            else:
                passOverlap = overlap

            stepSize = toolDiam - passOverlap*toolDiam
            stepSize = min([stepSize, abs(x1-x0), abs(y1-y0)])
            numStepX = int(math.ceil(0.5*width/stepSize))
            numStepY = int(math.ceil(0.5*height/stepSize))
            numStep = min([numStepX, numStepY])
            if not self.param['cornerCut']:
                rectPath = cnc_path.FilledRectPath(
                        point0,
                        point1,
                        stepSize,
                        numStep,
                        plane='xy'
                        )
            else:
                cutLen = 0.5*toolDiam*(math.sqrt(2.0) - 1.0) + cornerMargin
                rectPath = cnc_path.FilledRectWithCornerCutPath(
                        point0,
                        point1,
                        stepSize,
                        numStep,
                        cutLen,
                        plane='xy'
                        )
            self.listOfCmds.extend(rectPath.listOfCmds)

            # Get next z position
            if currZ <= stopZ:
                done = True
            else:
                if coolingPause is not None:
                    self.addRapidMoveToSafeZ()
                    self.listOfCmds.append(gcode_cmd.Dwell(coolingPause))
                    self.listOfCmds.append(gcode_cmd.LinearFeed(z=currZ))
            prevZ = currZ
            currZ = max([currZ - maxCutDepth, stopZ])

        self.addRapidMoveToSafeZ()
        self.addEndComment()
Exemplo n.º 8
0
    def makeListOfCmds(self):
        # Retreive numerical parameters and convert to float 
        cx = float(self.param['centerX'])
        cy = float(self.param['centerY'])
        radius = abs(float(self.param['radius']))
        thickness = abs(float(self.param['thickness']))
        depth = abs(float(self.param['depth']))
        startZ = float(self.param['startZ'])
        overlap = float(self.param['overlap'])
        try:
            overlapFinish = self.param['overlapFinish']
        except KeyError:
            overlapFinish = overlap
        overlapFinish = float(overlapFinish)
        maxCutDepth = float(self.param['maxCutDepth'])
        toolDiam = abs(float(self.param['toolDiam']))
        try:
            startDwell = self.param['startDwell']
        except KeyError:
            startDwell = 0.0
        startDwell = abs(float(startDwell))

        # Check params
        if overlap < 0.0 or overlap >= 1.0: 
            raise ValueError('overlap must >=0 and < 1')
        if 2*radius <= toolDiam: 
            raise ValueError('circle diameter must be > tool diameter')
        if thickness > radius:
            raise ValueError('thickness must be <= radius')
        if toolDiam > thickness:
            raise ValueError('toolDiam must be <= thickness')

        # Get circle cutting parameters  - assumes startAngle=0
        adjustedRadius = radius - 0.5*toolDiam
        x0 = cx + adjustedRadius
        y0 = cy

        # Move to safe height, then to start x,y and then to start z
        self.addStartComment()
        self.addRapidMoveToSafeZ()
        self.addRapidMoveToPos(x=x0,y=y0,comment='start x,y')
        self.addDwell(startDwell)
        self.addMoveToStartZ()

        # Get z cutting parameters 
        stopZ = startZ - depth
        prevZ = startZ
        currZ = max([startZ - maxCutDepth, stopZ])

        done = False
        passCnt = 0

        while not done:
            passCnt+=1

            # Add lead-in
            self.addComment('pass {0} lead-in'.format(passCnt))
            moveToStartCmd = gcode_cmd.LinearFeed(x=x0,y=y0)
            self.listOfCmds.append(moveToStartCmd)
            leadInPath = cnc_path.CircPath(
                    (cx,cy),
                    adjustedRadius,
                    startAng=0,
                    plane='xy',
                    direction=self.param['direction'],
                    turns=1,
                    helix=(prevZ,currZ)
                    )
            self.listOfCmds.extend(leadInPath.listOfCmds)

            # Add filled circle
            self.addComment('pass {0} filled circle'.format(passCnt))
            if currZ == stopZ:
                passOverlap = overlapFinish
            else:
                passOverlap = overlap

            if abs(toolDiam - thickness) <= FLOAT_TOLERANCE:
                numStep = 0
                stepSize = 0.0
            else:
                stepSizePrelim = toolDiam - passOverlap*toolDiam
                numStep = int(math.floor((thickness - toolDiam)/stepSizePrelim)) + 1
                stepSize = (thickness -toolDiam)/float(numStep)
              
            circPath = cnc_path.FilledCircPath(
                    (cx,cy),
                    adjustedRadius,
                    stepSize,
                    numStep,
                    startAng=0,
                    plane='xy',
                    direction=self.param['direction'],
                    turns=1
                    )
            self.listOfCmds.extend(circPath.listOfCmds)


            # Get next z position
            if currZ <= stopZ:
                done = True

            prevZ = currZ
            currZ = max([currZ - maxCutDepth, stopZ])


        # Move to safe z and add end comment
        self.addRapidMoveToSafeZ()
        self.addEndComment()
Exemplo n.º 9
0
 def getFeedToStartCmd(self, plane='xy'):
     kx, ky = tuple(plane)
     feedArgs = {kx: self.startPoint[0], ky: self.startPoint[1]}
     return gcode_cmd.LinearFeed(**feedArgs)
Exemplo n.º 10
0
 def addMoveToStartZ(self):
     startZ = float(self.param['startZ'])
     self.listOfCmds.append(gcode_cmd.Space())
     commentStr = '{0}: move to start z'.format(self.__class__.__name__)
     self.listOfCmds.append(gcode_cmd.Comment(commentStr))
     self.listOfCmds.append(gcode_cmd.LinearFeed(z=startZ))