Beispiel #1
0
def initParser(args, mode=None, gui=None):

    printerProfileName = "UM2" # xxx todo: get from commandline args

    # Create printer profile singleton instance
    printerProfile = PrinterProfile(printerProfileName)
    # Create material profile singleton instance
    mat = MatProfile(args.mat, args.smat)

    # Overwrite settings from printer profile with command line arguments:
    if args.retractLength:
        printerProfile.override("RetractLength", args.retractLength)

    # Overwrite settings from material profile with command line arguments:
    if args.t0:
        mat.override("bedTemp", args.t0)
    if args.t1:
        mat.override("hotendStartTemp", args.t1)

    nozzle = NozzleProfile(args.nozzle)

    # Create the Printer singleton instance
    printer = Printer(gui)

    # Create the planner singleton instance
    planner = Planner(args, gui)

    # Create parser singleton instance
    parser = gcodeparser.UM2GcodeParser()

    return (parser, planner, printer)
Beispiel #2
0
    def printStat(self):

        # Extrusion adjust
        adjustedExtrusion = self.maxRate + pow(self.maxRate, 2) * NozzleProfile.getExtrusionAdjustFactor()

        if self.maxRate:
            print "Maximal net Extrusion Rate (Extruder A): %.1f mm³/s, adjusted/gross: %.1f mm³/s, move:" % (self.maxRate, adjustedExtrusion)
            self.move.pprint("Max. extrusion Move")
            print "Net Max10: ", self.max10
            print "Maximal Extrusion Rate (Extruder A) 5 second average: %.1f" % self.maxAvgRate, "mm³/s\n"
Beispiel #3
0
def genTempTable(printer):

    baseTemp = MatProfile.getHotendBaseTemp()

    area04 = pow(0.4, 2)*math.pi/4
    extrusionLow = MatProfile.getBaseExtrusionRate() * (NozzleProfile.getArea() / area04)

    f = MatProfile.getAutoTempFactor()

    mmpermm3 = 1 / MatProfile.getMatArea()
    spm = PrinterProfile.getStepsPerMM(A_AXIS)

    of = open("/tmp/temptable0.txt", "w")
    of.write("# xxx mat, nozzle, settings...\n")
    of.write("# basetemp: %d, autoTempFactor: %f\n" % (baseTemp, f))
    of.write("# temp rate steprate timer\n")

    print "TempTable (basetemp: %d):" % baseTemp
    table = []
    for i in range(NExtrusionLimit):

        t = baseTemp + i*2

        dspeed = i*2 / f
        speed = extrusionLow + dspeed

        steprate = speed * mmpermm3 * spm
        tvs = 1.0/steprate
        timerValue = int(fTimer / steprate)

        print "    Temp: %d, max extrusion: %.1f mm³/s, steps/s: %d, steprate: %d us, timervalue: %d" % (t, speed, int(steprate), int(tvs*1000000), timerValue)
        table.append(timerValue)

        of.write("%d %4.1f %d %d\n" % (t, speed, int(steprate), timerValue))

    of.close()

    return (baseTemp, table)
Beispiel #4
0
    def doAutoTemp(self, moves):

        # Sum up path time and extrusion volume of moves
        tsum = 0
        vsum = 0
        for move in moves:
            tsum += move.accelData.getTime()
            vsum += move.getExtrusionVolume(MatProfile.get())

        avgERate = vsum / tsum

        print "Average extrusion rate: ", avgERate, "mm³/s", "layer 0 increase: ", self.planner.l0TempIncrease

        # Compute temperature for this segment and add tempcommand into the stream.
        newTemp = \
            MatProfile.getTempForFlowrate(avgERate * (1.0+AutotempSafetyMargin), PrinterProfile.getHwVersion(), NozzleProfile.getSize()) + \
            self.planner.l0TempIncrease

        # Don't go below startTemp from material profile
        newTemp = max(newTemp, MatProfile.getHotendStartTemp())
        # Don't go above max temp from material profile
        newTemp = min(newTemp, MatProfile.getHotendMaxTemp())

        if newTemp != self.lastTemp:  #  and self.mode != "pre":

            print "Newtemp:", avgERate, newTemp

            # Schedule target temp command
            self.planner.addSynchronizedCommand(
                CmdSyncTargetTemp,
                p1=packedvalue.uint8_t(HeaterEx1),
                p2=packedvalue.uint16_t(newTemp),
                moveNumber=move.moveNumber)

            self.lastTemp = int(newTemp)

        if debugAutoTemp:
            print "AutoTemp: collected moves with %.2f s duration." % tsum
            print "AutoTemp: max. extrusion rate: %.2f mm³/s." % avgERate
            print "AutoTemp: new temp: %d." % newTemp
Beispiel #5
0
    def __init__(self,
                 comment,
                 # stepped_point,
                 displacement_vector,
                 displacement_vector_steps,
                 feedrate, # mm/s
                 ):

        self.comment=comment
        self.displacement_vector3=displacement_vector[:3]
        self.displacement_vector_steps3=displacement_vector_steps[:3]
        self.extrusion_displacement_raw = displacement_vector[3:]
        self.extrusion_displacement_steps_raw = displacement_vector_steps[3:]

        #
        # Move distance in XYZAB plane
        #
        self.distance = displacement_vector.len5()
        #
        # Move distance in XYZ plane
        #
        self.distance3 = displacement_vector.len3()

        # self.eOnly = self.displacement_vector3 == 3*[0]
        self.eOnly = self.distance3 == 0

        #
        # Limit feedrate by maximum extrusion rate
        #
        self.feedrateS = feedrate # mm/s
        # Do not count very small moves, the computation of the extrusion rate is inaccurate because of the
        # discretization in the gcodeparser (map float values to discrete stepper values).
        if self.distance3 >= 0.1 and self.isExtrudingMove(A_AXIS) or self.isExtrudingMove(B_AXIS):
            matArea = MatProfile.getMatArea()

            assert(not self.eOnly)
            t = self.distance3 / feedrate

            extrusionVolume = displacement_vector[A_AXIS] * matArea
            extrusionRate = extrusionVolume / t
            # print "extrusionRate:", displacement_vector[A_AXIS], t, extrusionRate

            if extrusionRate > NozzleProfile.getNetMaxExtrusionRate():

                print "Warning, extrusion rate to high: %.1f mm³/s, Move: '%s', len: %.3f., extrusionVolume: %.5f" % (extrusionRate, comment, self.distance3, extrusionVolume)
                # xxx feedrate adjust disabled
                ### print "Warning, extrusion rate to high: %.1f mm³/s, reducing to %.1f mm³/s, Move: '%s', len: %.3f., extrusionVolume: %.5f" % (extrusionRate, NozzleProfile.getNetMaxExtrusionRate(), comment, self.distance3, extrusionVolume)
                ### self.feedrateS = feedrate * (NozzleProfile.getNetMaxExtrusionRate() / extrusionRate)
                # print "Adjusted feedrate: ", feedrate, self.feedrateS

        self.trueStartSpeed = self.nominalStartSpeed = None
        self.trueEndSpeed = self.nominalEndSpeed = None

        self.accelData = AccelData()

        self.stepData = StepData()

        self.lastMove = None
        self.nextMove = None

        self.moveNumber = 0

        # debug
        self.state = 0 # 1: joined, 2: accel planned, 3: steps planned
        self.streamed = False

        # Time for the three phases of this move
        self.accelTime = 0
        self.linearTime = 0
        self.deccelTime = 0
Beispiel #6
0
def measureTempFlowrateCurve(args, parser):

    def writeDataSet(f, dataSet):
        for dataStr in dataSet:
            f.write(dataStr)
            f.write("\n")
        f.write("E\n")

    fssteps_per_mm = 265.0 # xxx hardcoded, get from profile or printer...

    planner = parser.planner
    printer = planner.printer

    printer.commandInit(args)

    ddhome.home(parser, args.fakeendstop)

    # Disable flowrate limit
    printer.sendCommandParamV(CmdEnableFRLimit, [packedvalue.uint8_t(0)])

    # Move to mid-position
    printer.sendPrinterInit()
    feedrate = PrinterProfile.getMaxFeedrate(X_AXIS)
    parser.execute_line("G0 F%d X%f Y%f" % (feedrate*60, planner.MAX_POS[X_AXIS]/2, planner.MAX_POS[Y_AXIS]/2))

    planner.finishMoves()

    printer.sendCommandParamV(CmdMove, [MoveTypeNormal])
    printer.sendCommand(CmdEOT)

    printer.waitForState(StateIdle)

    current_position = parser.getRealPos()
    apos = current_position[A_AXIS]

    t1 = MatProfile.getHotendBaseTemp() # start temperature
    area04 = pow(0.4, 2)*math.pi/4
    flowrate = MatProfile.getBaseExtrusionRate() * (NozzleProfile.getArea() / area04)
    aFilament = MatProfile.getMatArea()

    print "t1: ", t1
    print "flowrate: ", flowrate
    print "aFilament: ", aFilament
    print "feedrate: ", flowrate / aFilament

    # xxx todo if using small nozzles
    assert(flowrate > 2)

    f = open("temp-flowrate-curve.gnuplot", "w")

    f.write("""

set grid
set yrange [0:35]

# Startwert steigung
a=0.5

# Startwert y-achse
b=5
f(x)=b+a*(x-%d)

fit f(x) "-" using 1:3 noerror via a,b\n""" % t1)

    
    dataSet = []

    printer.sendCommandParamV(CmdFanSpeed, [packedvalue.uint8_t(100)])

    retracted = False

    while t1 <= MatProfile.getHotendMaxTemp():

        print "Heating:", t1
        printer.heatUp(HeaterEx1, t1, wait=t1)

        # time.sleep(10) # temp settle
        wait = 5
        while wait:
            time.sleep(1)
            temps = printer.getTemps()
            if abs(t1 - int(temps[HeaterEx1])) <= 1:
                wait -= 1
            else:
                wait = 5
            print "temp wait: ", wait

        flowrate -= 1

        ratio = 1.0

        while ratio >= 0.9:

            feedrate = flowrate / aFilament
            # distance = 5 * feedrate # xxx
            distance = 50

            apos += distance

            print "Feedrate for flowrate:", feedrate, flowrate

            printer.sendPrinterInit()

            if retracted:
                parser.execute_line("G11")
            parser.execute_line("G0 F%d %s%f" % (feedrate*60, dimNames[A_AXIS], apos))
            parser.execute_line("G10")
            planner.finishMoves()
            printer.sendCommand(CmdEOT)
            printer.sendCommandParamV(CmdMove, [MoveTypeNormal])
            printer.waitForState(StateIdle)

            time.sleep(0.25)

            fssteps = printer.getFilSensor()
            fsdist = fssteps / fssteps_per_mm

            ratio = fsdist / distance

            actualFlowrate = flowrate * ratio

            print "t1, flowrate, fsdist, distance, ratio:",  t1, flowrate, fsdist, distance, ratio

            flowrate += 1
            retracted = True

        print "Feeder grip:",  t1, flowrate-1, ratio
        dataStr = "%f %f %.2f %.3f" % (t1, flowrate - 1, actualFlowrate, ratio)
        f.write(dataStr + "\n")
        f.flush()

        dataSet.append(dataStr)

        t1 += 2 # next temp

    f.write("E\n")

    f.write("""
plot "-" using 1:2 with linespoints title "Target Flowrate", \\
     "-" using 1:3 with linespoints title "Actual Flowrate", \\
     "-" using 1:3 with linespoints smooth bezier title "Actual Flowrate smooth", \\
     f(x) title sprintf("y=B+A*x, A=%.2f, B=%.1f, TempFactor 1/A: %.2f", a, b, 1/a)\n""")

    writeDataSet(f, dataSet)
    writeDataSet(f, dataSet)
    writeDataSet(f, dataSet)

    f.close()

    printer.coolDown(HeaterEx1)
    # Enable flowrate limit
    printer.sendCommandParamV(CmdEnableFRLimit, [packedvalue.uint8_t(1)])
Beispiel #7
0
    def __init__(self, args, gui=None):

        if Planner.__single:
            raise RuntimeError('A Planner already exists')

        Planner.__single = self

        if gui:
            self.gui = gui
        else:
            self.gui = dddumbui.DumbGui()

        self.args = args

        self.printer = Printer.get()
        # self.parser = UM2GcodeParser.get()

        jerk = []
        for dim in dimNames:
            jerk.append(PrinterProfile.getValues()['axes'][dim]['jerk'])

        self.jerk = VVector(jerk)
        self.gui.log("Jerk vector: ", self.jerk)

        self.zeroPos = util.MyPoint()

        # Lowest allowed speed in mm/s for every dimension
        self.min_speeds = 5 * [0]
        for dim in range(5):
            # vmin = (fTimer / maxTimerValue) / steps_per_mm
            if PrinterProfile.getStepsPerMM(dim):
                self.min_speeds[dim] = float(fTimer) / (maxTimerValue24 * PrinterProfile.getStepsPerMM(dim))

        self.gui.log( "min speeds: ", self.min_speeds)

        #
        # Constants, xxx todo: query from printer and/or profile
        #
        self.HOMING_FEEDRATE = [100, 100, 40]  # set the homing speeds (mm/s) 
        self.HOME_RETRACT_MM = 7               # [mm]


        # ENDSTOP SETTINGS:
        # Sets direction of endstops when homing; 1=MAX, -1=MIN
        self.X_HOME_DIR = -1
        self.Y_HOME_DIR = 1
        self.Z_HOME_DIR = 1
        self.HOME_DIR = (self.X_HOME_DIR, self.Y_HOME_DIR, self.Z_HOME_DIR)

        # XXX defined in profile !!!
        # Travel limits after homing
        self.X_MIN_POS = 0
        self.X_MAX_POS = 225.0 # 230.0
        # X_MIN_POS = 0
        self.Y_MAX_POS = 225.0 # 230.0
        # Y_MIN_POS = 0
        # self.Z_MAX_POS = 229.0 # 230.0 // Dauerdruckplatte hat 5mm im vergleich zur glassplatte 4mm
        self.Z_MAX_POS = 212.25 # solex nozzle
        # Z_MIN_POS = 0
        self.MAX_POS = (self.X_MAX_POS, self.Y_MAX_POS, self.Z_MAX_POS)

        # Bed leveling constants
        self.LEVELING_OFFSET = 0.1                   # Assumed thickness of feeler gauge/paper used in leveling (mm)
        # self.HEAD_HEIGHT = 35.0                      # Let enough room for the head, XXX UM2 specific !!!
        self.HEAD_HEIGHT = 15.0                      # Let enough room for the head, XXX UM2 specific !!!

        # Homing
        self.X_HOME_POS = self.X_MIN_POS
        self.Y_HOME_POS = self.Y_MAX_POS
        self.Z_HOME_POS = self.Z_MAX_POS                  # XXX + add_homeing_z
        #
        # End Constants
        #

        self.plotfile = None

        # Headspeed/extrusionspeed where autotemp increase starts
        self.ExtrusionAmountLow = 30 # [mm/s] for a 1mm nozzle
        if UseExtrusionAutoTemp:
            # self.ExtrusionAmountLow = 7.5 # [mm³/s] for a 1mm nozzle
            area04 = pow(0.4, 2)*math.pi/4
            self.ExtrusionAmountLow = MatProfile.getBaseExtrusionRate() * (NozzleProfile.getArea() / area04)

        self.reset()