Пример #1
0
    def home(self):
        '''home() ... homes all axes'''
        status = self['status']
        command = self['command']

        if status and command:
            sequence = [[cmd] for cmd in MKUtils.taskModeManual(status)]
            toHome = [
                axis.index for axis in status['motion.axis'] if not axis.homed
            ]
            order = {}

            for axis in status['config.axis']:
                if axis.index in toHome:
                    batch = order.get(axis.home_sequence)
                    if batch is None:
                        batch = []
                    batch.append(axis.index)
                    order[axis.home_sequence] = batch

            for key in sorted(order):
                batch = order[key]
                sequence.append(
                    [MKCommandAxisHome(index, True) for index in batch])
                for index in batch:
                    sequence.append([
                        MKCommandWaitUntil(lambda index=index: status[
                            "motion.axis.%d.homed" % index])
                    ])

            sequence.append(MKUtils.taskModeMDI(self, True))
            sequence.append([MKCommandTaskExecute('G10 L20 P0 X0 Y0 Z0')])

            command.sendCommandSequence(sequence)
Пример #2
0
 def executeRun(self):
     sequence = MKUtils.taskModeMDI(self.mk)
     sequence.append(MKCommandTaskExecute('M6 T0'))
     sequence.append(
         MKCommandWaitUntil(lambda: self.mk['status.io.tool.nr'] <= 0))
     sequence.extend(MKUtils.taskModeAuto(self.mk, True))
     sequence.append(MKCommandTaskRun(False))
     self.mk['command'].sendCommands(sequence)
Пример #3
0
    def executeUpload(self):
        '''Post process the current Path.Job and upload the resulting g-code into MK.
        Tag the uploaded g-code with the job and a hash so we can determine if the uploaded
        version is consistent with what is currently in FC.'''

        job = self.job
        if job:
            currTool = None
            postlist = []
            for obj in job.Operations.Group:
                tc = PathUtil.toolControllerForOp(obj)
                if tc is not None:
                    if tc.ToolNumber != currTool:
                        postlist.append(tc)
                        currTool = tc.ToolNumber
                postlist.append(obj)

            post = PathPost.CommandPathPost()
            fail, gcode = post.exportObjectsWith(postlist, job, False)
            if not fail:
                print("POST: ", fail)
                preamble = "(FreeCAD.Job: %s)\n(FreeCAD.File: %s)\n(FreeCAD.Signature: %d)\n" % (
                    job.Name, job.Document.FileName,
                    MKUtils.pathSignature(job.Path))
                buf = io.BytesIO((preamble + gcode).encode())
                endpoint = self.mk.instance.endpoint.get('file')
                if endpoint:
                    ftp = ftplib.FTP()
                    ftp.connect(endpoint.address(), endpoint.port())
                    ftp.login()
                    ftp.storbinary("STOR %s" % self.mk.RemoteFilename, buf)
                    ftp.quit()
                    sequence = MKUtils.taskModeMDI(self.mk)
                    for tc in job.ToolController:
                        t = tc.Tool
                        radius = float(t.Diameter) / 2 if hasattr(
                            t, 'Diameter') else 0.
                        offset = t.LengthOffset if hasattr(
                            t, 'LengthOffset') else 0.
                        sequence.append(
                            MKCommandTaskExecute(
                                "G10 L1 P%d R%g Z%g" %
                                (tc.ToolNumber, radius, offset)))
                    sequence.extend(MKUtils.taskModeAuto(self.mk))
                    sequence.append(MKCommandTaskReset(False))
                    sequence.extend([
                        MKCommandOpenFile(self.mk.remoteFilePath(), True),
                        MKCommandOpenFile(self.mk.remoteFilePath(), False)
                    ])
                    sequence.append(MKCommandTaskRun(True))
                    self.mk['command'].sendCommands(sequence)
                else:
                    PathLog.error('No endpoint found')
            else:
                PathLog.error('Post processing failed')
Пример #4
0
 def mdi(self, cmd):
     '''mdi(cmd) ... send given g-code as MDI to MK (switch to MDI mode if necessary).'''
     command = self['command']
     if command:
         sequence = MKUtils.taskModeMDI(self)
         sequence.append(MKCommandTaskExecute(cmd))
         command.sendCommands(sequence)
    def addSelection(self, doc, obj, sub, pnt):
        '''FC callback if the selection in the 3d view changes - used to determine the destination
        when the user wants to jog the tool to a specific position.'''
        PathLog.track()
        if self.ui.jogGoto.isChecked() and self.mk[
                'status.motion.state'] == TYPES.RCS_DONE and not self.ui.jogGoto.visibleRegion(
                ).isEmpty():
            x = pnt[0]
            y = pnt[1]
            z = pnt[2]
            mkx = self.displayPos('x')
            mky = self.displayPos('y')
            mkz = self.displayPos('z')
            if PathGeom.isRoughly(x, mkx, Tolerance) and PathGeom.isRoughly(
                    y, mky, Tolerance):
                if not PathGeom.isRoughly(z, mkz, Tolerance):
                    # only jog the Z axis if XY already match
                    index, velocity = self.getJogIndexAndVelocity('z')
                    jog = [MKCommandAxisJog(index, velocity, mkz - z)]
                    PathLog.debug("jog z from %.2f to %.2f" % (mkz, z))
                else:
                    jog = None
                    PathLog.debug(
                        "z already aligned (%.2f), no jogging required" % z)
            else:
                # by default we just jog X & Y
                jog = self._jogXYCmdsFromTo(FreeCAD.Vector(mkx, mky, 0),
                                            FreeCAD.Vector(x, y, 0))

            sequence = [[cmd] for cmd in MKUtils.taskModeManual(self.mk)]
            sequence.append(jog)
            self.mk['command'].sendCommandSequence(sequence)
Пример #6
0
    def addSelection(self, doc, obj, sub, pnt):
        PathLog.track()
        if self.ui.jogGoto.isChecked(
        ) and self.mk['status.motion.state'] == TYPES.RCS_DONE:
            x = pnt[0]
            y = pnt[1]
            z = pnt[2]
            mkx = self.displayPos('x')
            mky = self.displayPos('y')
            mkz = self.displayPos('z')
            if PathGeom.isRoughly(x, mkx, Tolerance) and PathGeom.isRoughly(
                    y, mky, Tolerance):
                if not PathGeom.isRoughly(z, mkz, Tolerance):
                    # only jog the Z axis if XY already match
                    index, velocity = self.getJogIndexAndVelocity('z')
                    jog = [MKCommandAxisJog(index, velocity, mkz - z)]
                    PathLog.debug("jog z from %.2f to %.2f" % (mkz, z))
                else:
                    jog = None
                    PathLog.debug(
                        "z already aligned (%.2f), no jogging required" % z)
            else:
                # by default we just jog X & Y
                jog = self._jogXYCmdsFromTo(FreeCAD.Vector(mkx, mky, 0),
                                            FreeCAD.Vector(x, y, 0))

            sequence = [[cmd] for cmd in MKUtils.taskModeManual(self.mk)]
            sequence.append(jog)
            self.mk['command'].sendCommandSequence(sequence)
Пример #7
0
 def jogAxesStop(self):
     '''Explicitly stop all jog motions currently in progress.'''
     PathLog.track()
     sequence = [[cmd] for cmd in MKUtils.taskModeManual(self.mk)]
     sequence.append([MKCommandAxisAbort(i) for i in range(3)])
     self.mk['command'].abortCommandSequence()
     self.mk['command'].sendCommandSequence(sequence)
Пример #8
0
    def executeUpload(self):
        job = self.job
        if job:
            currTool = None
            postlist = []
            for obj in job.Operations.Group:
                tc = PathUtil.toolControllerForOp(obj)
                if tc is not None:
                    if tc.ToolNumber != currTool:
                        postlist.append(tc)
                        currTool = tc.ToolNumber
                postlist.append(obj)

            post = PathPost.CommandPathPost()
            fail, gcode = post.exportObjectsWith(postlist, job, False)
            if not fail:
                print("POST: ", fail)
                preamble = "(FreeCAD.Job: %s)\n(FreeCAD.File: %s)\n(FreeCAD.Signature: %d)\n" % (
                    job.Name, job.Document.FileName,
                    MKUtils.pathSignature(job.Path))
                buf = io.BytesIO((preamble + gcode).encode())
                endpoint = self.mk.instance.endpoint.get('file')
                if endpoint:
                    ftp = ftplib.FTP()
                    ftp.connect(endpoint.address(), endpoint.port())
                    ftp.login()
                    ftp.storbinary("STOR %s" % self.mk.RemoteFilename, buf)
                    ftp.quit()
                    sequence = MKUtils.taskModeMDI(self.mk)
                    for tc in job.ToolController:
                        t = tc.Tool
                        sequence.append(
                            MKCommandTaskExecute("G10 L1 P%d R%g Z%g" %
                                                 (tc.ToolNumber, t.Diameter /
                                                  2., t.LengthOffset)))
                    sequence.extend(MKUtils.taskModeAuto(self.mk))
                    sequence.append(MKCommandTaskReset(False))
                    sequence.append(
                        MKCommandOpenFile(self.mk.remoteFilePath(), False))
                    self.mk['command'].sendCommands(sequence)
                else:
                    PathLog.error('No endpoint found')
            else:
                PathLog.error('Post processing failed')
Пример #9
0
 def jogAxesEnd(self, axes):
     PathLog.track(axes)
     if self.jogContinuously():
         jog = []
         for axis in axes:
             index, velocity = self.getJogIndexAndVelocity(axis)
             jog.append(MKCommandAxisAbort(index))
         if jog:
             sequence = [[cmd] for cmd in MKUtils.taskModeManual(self.mk)]
             sequence.append(jog)
             self.mk['command'].sendCommandSequence(sequence)
 def toggleHomed(self):
     if self.mk.isHomed():
         sequence = [[cmd]
                     for cmd in MKUtils.taskModeManual(self.mk['status'])]
         commands = []
         for axis in self.mk['status.config.axis']:
             commands.append(MKCommandAxisHome(axis.index, False))
         sequence.append(commands)
         self.mk['command'].sendCommandSequence(sequence)
     else:
         self.mk.home()
Пример #11
0
 def jogAxesZero(self, axes):
     PathLog.track()
     PathLog.track(axes)
     jog = []
     for axis in (['x', 'y'] if axes[0] == '-' else ['z']):
         distance = self.displayPos(axis)
         if distance != 0.0:
             index, velocity = self.getJogIndexAndVelocity(axis)
             jog.append(MKCommandAxisJog(index, velocity, distance))
     if jog:
         sequence = [[cmd] for cmd in MKUtils.taskModeManual(self.mk)]
         sequence.append(jog)
         self.mk['command'].sendCommandSequence(sequence)
Пример #12
0
 def jogAxesEnd(self, axes):
     '''Calback when the user releases one of the jog buttons - if continuous jogging
     is configured this ends the jog.'''
     PathLog.track(axes)
     if self.jogContinuously():
         jog = []
         for axis in axes:
             index, velocity = self.getJogIndexAndVelocity(axis)
             jog.append(MKCommandAxisAbort(index))
         if jog:
             sequence = [[cmd] for cmd in MKUtils.taskModeManual(self.mk)]
             sequence.append(jog)
             self.mk['command'].sendCommandSequence(sequence)
Пример #13
0
 def jogAxes(self, axes):
     PathLog.track(axes)
     if not self.jogContinuously():
         jog = []
         for axis in axes:
             index, velocity = self.getJogIndexAndVelocity(axis)
             units = EmcLinearUnits[self.mk['status.config.units.linear']]
             distance = FreeCAD.Units.Quantity(
                 self.ui.jogDistance.currentItem().text()).getValueAs(units)
             jog.append(MKCommandAxisJog(index, velocity, distance))
         if jog:
             sequence = [[cmd] for cmd in MKUtils.taskModeManual(self.mk)]
             sequence.append(jog)
             self.mk['command'].sendCommandSequence(sequence)
Пример #14
0
    def updateJob(self):
        '''Download the g-code currently loaded into MK, check if it could be a FC Path.Job.
        If the Path.Job is currently loaded trigger an update to everyone caring about these
        things.'''
        job = None
        path = self['status.task.file']
        rpath = self.remoteFilePath()
        endpoint = self.instance.endpoint.get('file')
        PathLog.info("%s, %s, %s" % (path, rpath, endpoint))
        if path is None or rpath is None or endpoint is None:
            self.needUpdateJob = True
        else:
            self.needUpdateJob = False
            if rpath == path:
                buf = io.BytesIO()
                ftp = ftplib.FTP()
                ftp.connect(endpoint.address(), endpoint.port())
                ftp.login()
                ftp.retrbinary("RETR %s" % self.RemoteFilename, buf.write)
                ftp.quit()
                buf.seek(0)
                line1 = buf.readline().decode()
                line2 = buf.readline().decode()
                line3 = buf.readline().decode()
                if line1.startswith('(FreeCAD.Job: ') and line2.startswith(
                        '(FreeCAD.File: ') and line3.startswith(
                            '(FreeCAD.Signature: '):
                    title = line1[14:-2]
                    filename = line2[15:-2]
                    signature = line3[20:-2]
                    PathLog.debug("Loaded document: '%s' - '%s'" %
                                  (filename, title))
                    for docName, doc in FreeCAD.listDocuments().items():
                        PathLog.debug("Document: '%s' - '%s'" %
                                      (docName, doc.FileName))
                        if doc.FileName == filename:
                            job = doc.getObject(title)
                            if job:
                                sign = MKUtils.pathSignature(job.Path)
                                if str(sign) == signature:
                                    PathLog.info(
                                        "Job %s.%s loaded." %
                                        (job.Document.Label, job.Label))
                                else:
                                    PathLog.warning(
                                        "Job %s.%s is out of date!" %
                                        (job.Document.Label, job.Label))

        self.setJob(job)
Пример #15
0
    def setPosition(self, label, widget):
        PathLog.track()
        commands = MKUtils.taskModeMDI(self.mk)

        cmds = ['G10', 'L20', 'P0']
        for l in label:
            value = 0 if widget is None else widget.value()
            offset = self.mk["status.motion.offset.g5x.%s" % l]
            PathLog.debug("set pos[%s]=%.2f  (%.2f)" % (l, value, offset))
            cmds.append("%s%g" % (l, value))
        code = ' '.join(cmds)
        PathLog.debug("set pos-%s: '%s'" % (label, code))
        commands.append(MKCommandTaskExecute(code))

        self.mk['command'].sendCommands(commands)
Пример #16
0
 def jogAxesZero(self, axes):
     '''jogAxesZero(axes) ... jog each of the specified axes to its 0 position.
     Note that no velocity adaption is going on so if two or more axis are specified
     each will reach its destination in its own time regardless of the progress of
     the other axes.'''
     PathLog.track()
     PathLog.track(axes)
     jog = []
     for axis in (['x', 'y'] if axes[0] == '-' else ['z']):
         distance = self.displayPos(axis)
         if distance != 0.0:
             index, velocity = self.getJogIndexAndVelocity(axis)
             jog.append(MKCommandAxisJog(index, velocity, distance))
     if jog:
         sequence = [[cmd] for cmd in MKUtils.taskModeManual(self.mk)]
         sequence.append(jog)
         self.mk['command'].sendCommandSequence(sequence)
Пример #17
0
 def executeStep(self):
     sequence = MKUtils.taskModeAuto(self.mk)
     sequence.append(MKCommandTaskStep())
     self.mk['command'].sendCommands(sequence)
Пример #18
0
 def jogAxesStop(self):
     PathLog.track()
     sequence = [[cmd] for cmd in MKUtils.taskModeManual(self.mk)]
     sequence.append([MKCommandAxisAbort(i) for i in range(3)])
     self.mk['command'].abortCommandSequence()
     self.mk['command'].sendCommandSequence(sequence)
Пример #19
0
 def executeStep(self):
     '''Perform a single step of the uploaded g-code.'''
     sequence = MKUtils.taskModeAuto(self.mk)
     sequence.append(MKCommandTaskStep())
     self.mk['command'].sendCommands(sequence)
Пример #20
0
    def scanJob(self, forward):
        PathLog.track()
        job = self.mk.getJob()
        if job and hasattr(job, 'Path') and job.Path:
            bb = job.Path.BoundBox
            if bb.isValid():
                off = self.mk['status.motion.offset.g5x']
                bb.move(FreeCAD.Vector(off['x'], off['y'], off['z']))
                if self.mk.boundBox().isInside(bb):
                    mkx = self.displayPos('x')
                    mky = self.displayPos('y')
                    begin = FreeCAD.Vector(mkx, mky, 0)
                    pts = []
                    bb = job.Path.BoundBox
                    if forward:
                        pts.append(FreeCAD.Vector(bb.XMin, bb.YMin, 0))
                        pts.append(FreeCAD.Vector(bb.XMax, bb.YMin, 0))
                        pts.append(FreeCAD.Vector(bb.XMax, bb.YMax, 0))
                        pts.append(FreeCAD.Vector(bb.XMin, bb.YMax, 0))
                    else:
                        pts.append(FreeCAD.Vector(bb.XMin, bb.YMin, 0))
                        pts.append(FreeCAD.Vector(bb.XMin, bb.YMax, 0))
                        pts.append(FreeCAD.Vector(bb.XMax, bb.YMax, 0))
                        pts.append(FreeCAD.Vector(bb.XMax, bb.YMin, 0))

                    dist = [begin.distanceToPoint(p) for p in pts]
                    rot = dist.index(min(dist))
                    pts = pts[rot:] + pts[:rot]
                    pts.append(pts[0])
                    PathLog.info(" begin = (%5.2f, %5.2f)" %
                                 (begin.x, begin.y))
                    for i, p in enumerate(pts):
                        PathLog.info(" pts[%d] = (%5.2f, %5.2f)" %
                                     (i, p.x, p.y))

                    jog = []
                    if not PathGeom.pointsCoincide(begin, pts[0]):
                        PathLog.info("Move to start point (%.2f, %.2f)" %
                                     (pts[0].x, pts[0].y))
                        jog.append(self._jogXYCmdsFromTo(begin, pts[0]))
                    for i, j in zip(pts, pts[1:]):
                        jog.append(self._jogXYCmdsFromTo(i, j))

                    sequence = [[cmd]
                                for cmd in MKUtils.taskModeManual(self.mk)]
                    sequence.extend(jog)
                    self.mk['command'].sendCommandSequence(sequence)
                else:
                    mbb = self.mk.boundBox()
                    msg = ["Cannot scan job!"]
                    if mbb.XMin > bb.XMin:
                        msg.append("X limit min exceeded by: %.2f" %
                                   (mbb.XMin - bb.XMin))
                    if mbb.XMax < bb.XMax:
                        msg.append("X limit max exceeded by: %.2f" %
                                   (bb.XMax - mbb.XMax))
                    if mbb.YMin > bb.YMin:
                        msg.append("Y limit min exceeded by: %.2f" %
                                   (mbb.YMin - bb.YMin))
                    if mbb.YMax < bb.YMax:
                        msg.append("Y limit max exceeded by: %.2f" %
                                   (bb.YMax - mbb.YMax))
                    if mbb.ZMin > bb.ZMin:
                        msg.append("Z limit min exceeded by: %.2f" %
                                   (mbb.ZMin - bb.ZMin))
                    if mbb.ZMax < bb.ZMax:
                        msg.append("Z limit max exceeded by: %.2f" %
                                   (bb.ZMax - mbb.ZMax))

                    mb = PySide.QtGui.QMessageBox()
                    mb.setWindowIcon(
                        machinekit.IconResource('machinekiticon.png'))
                    mb.setWindowTitle('Machinekit')
                    mb.setTextFormat(PySide.QtCore.Qt.TextFormat.RichText)
                    mb.setText("<div align='center'>%s</div>" %
                               '<br/>'.join(msg))
                    mb.setIcon(PySide.QtGui.QMessageBox.Critical)
                    mb.setStandardButtons(PySide.QtGui.QMessageBox.Ok)
                    mb.exec_()
            else:
                PathLog.error("BoundBox of job %s is not valid" % job.Label)
        else:
            PathLog.error('No job uploaded for scanning')
 def mdi(self, cmd):
     command = self['command']
     if command:
         sequence = MKUtils.taskModeMDI(self)
         sequence.append(MKCommandTaskExecute(cmd))
         command.sendCommands(sequence)