Esempio n. 1
0
    def gcode_pillar_idle_tool_bands(self, tool_id):
        # Generate vertices
        tokens = doublelinkedlist.DLList()

        for idle_tool_id in self.tools_idle:
            gcode_band = doublelinkedlist.DLList()
            for radius in self.prime_tower.get_pillar_bands(
                    self.layer_num, idle_tool_id):
                vertices = circle_generate_vertices(
                    conf.prime_tower_x, conf.prime_tower_y, radius,
                    conf.prime_tower_band_num_faces)
                gcode_band.append_nodes(
                    self.gcode_print_shape(vertices, tool_id))

            gcode_band.head.append_node(gcode_analyzer.GCode('G11'))
            gcode_band.head.append_node_left(gcode_analyzer.GCode('G10'))

            tokens.append_nodes(gcode_band)

        if conf.GCODE_VERBOSE:
            tokens.head.comment = "TC-PSPP - Prime tower idle tool infill for layer #{layer} - start".format(
                layer=self.layer_num)
            tokens.tail.comment = "TC-PSPP - Prime tower idle tool infill for layer #{layer} - end".format(
                layer=self.layer_num)

        return tokens
Esempio n. 2
0
    def gcode_prep_header(self):
        # Prepare gcode in the header
        gcode_init = doublelinkedlist.DLList()
        gcode_wait = doublelinkedlist.DLList()

        # Check the runtime estimate between TC_TEMP_INITIALIZE and first tool activation
        for tool_id, activation_seq in self.tool_activation_seq.items():
            tool_info = activation_seq[0]

            time_delta = 0.0
            token = self.temp_header.next
            while token != tool_info.tool_change:
                time_delta += token.runtime
                token = token.next

            if conf.DEBUG:
                print("(DEBUG) TempController: INIT -> T{tool} - runtime estimate: {delta:0.2f}".format(tool = tool_id, delta = time_delta))

            tool_temp = conf.tool_temperature(tool_info.tool_change.state_pre.layer_num, tool_id)
            # Check if should set idle temp or tool temp at INIT point
            # temp_idle = tool_temp - temp_idle_delta
            time_temp_idle2tool = float(conf.temp_idle_delta) / float(conf.temp_heating_rate)

            if time_temp_idle2tool < time_delta:
                # Find the inject point 
                acc_time = 0.0
                inject_point = tool_info.tool_change.prev
                while inject_point is not None:
                    acc_time += inject_point.runtime
                    if acc_time >= time_temp_idle2tool:
                        break
                    inject_point = inject_point.prev

                if conf.DEBUG:
                    print("(DEBUG) TempController: Inject point for T{tool} is before \"{token}\" - time diff: {delta:0.2f}s".format(tool = tool_id, token = str(inject_point), delta = acc_time))

                # Insert idle temp in TC_INIT
                # Insert ramp up at inject point
                # Insert temp wait before tool change
                gcode_init.append_node(gcode_analyzer.GCode('M104', {'S' : tool_temp - conf.temp_idle_delta, 'T' : tool_id}))
                gcode_wait.append_node(gcode_analyzer.GCode('M116', {'P' : tool_id, 'S' : 5}))

                inject_point.append_node(gcode_analyzer.GCode('M104', {'S' : tool_temp, 'T' : tool_id}))
                tool_info.tool_change.append_node_left(gcode_analyzer.GCode('M116', {'P' : tool_id, 'S' : 5}))
            else:
                if conf.DEBUG:
                    print("(DEBUG) TempController: Inject point for T{tool} at TC_INIT".format(tool = tool_id))

                # Insert target temp at TC_INIT
                # Insert temp wait at TC_INIT
                gcode_init.append_node(gcode_analyzer.GCode('M104', {'S' : tool_temp, 'T' : tool_id}))
                gcode_wait.append_node(gcode_analyzer.GCode('M116', {'P' : tool_id, 'S' : 5}))

        # Inject the gcode at TC_INIT
        self.temp_header.append_nodes_right(gcode_wait)
        self.temp_header.append_nodes_right(gcode_init)
Esempio n. 3
0
    def gcode_wipe_path(self, start_point, length, retract_length):
        path = []
        x0, y0, z0 = start_point.state_post.x, start_point.state_post.y, start_point.state_post.z
        previous_move = start_point

        accumulated_dist = 0.0
        while accumulated_dist < length:
            if previous_move.state_pre == None:
                break
            x1, y1, z1 = previous_move.state_pre.x, previous_move.state_pre.y, previous_move.state_pre.z

            if z1 != z0:
                break

            dist = math.sqrt((x1 - x0)**2 + (y1 - y0)**2)

            # If end
            if dist + accumulated_dist > length:
                # Check cutoff
                dist_corrected = length - accumulated_dist
                x1 = x0 + (x1 - x0) * (dist_corrected / dist)
                y1 = y0 + (y1 - y0) * (dist_corrected / dist)
                dist = dist_corrected

            if dist != 0.0:
                accumulated_dist += dist
                x0, y0 = x1, y1
                path.append((x1, y1, dist))

            if previous_move.prev is not None:
                previous_move = previous_move.prev

        if accumulated_dist < length:
            logger.warn(
                "Calculated wipe path {wipe_length:0.2f}[mm] less then configured {length:0.2f}[mm]"
                .format(wipe_length=accumulated_dist, length=length))

        # Generate GCodes
        gcode = doublelinkedlist.DLList()

        if len(path) > 2:
            for vertex in path:
                to_retract = -retract_length * (vertex[2]) / accumulated_dist
                gcode.append_node(
                    gcode_analyzer.GCode('G1', {
                        'X': vertex[0],
                        'Y': vertex[1],
                        'E': to_retract
                    }))
            logger.info("Calculated wipe path: {length}".format(
                length=accumulated_dist))
        else:
            # Just add retraction
            gcode.append_node(
                gcode_analyzer.GCode('G1', {'E', -retract_length}))

        gcode.head.comment = "wipe start"

        return gcode
    def __init__(self, gcode_file=None):
        if gcode_file is None:
            self.tokens = doublelinkedlist.DLList()
        else:
            self.parse(gcode_file)
        self.total_runtime = 0
        # total filament usage
        self.total_filament_usage = {}

        # cached list
        self.cached_tokens = []
Esempio n. 5
0
    def gcode_pillar_band(self, tool_id):
        band_gcode = doublelinkedlist.DLList()

        for radius in self.prime_tower.get_pillar_bands(self.layer_num, tool_id):
            # Start each circle at a different point to avoid weakening the tower
            circle_vertices = deque(circle_generate_vertices(conf.prime_tower_x, conf.prime_tower_y, radius, conf.prime_tower_band_num_faces))
            circle_vertices.rotate(self.layer_num)

            band_gcode.append_nodes(self.gcode_print_shape(circle_vertices, tool_id))

        if conf.GCODE_VERBOSE:
            band_gcode.head.comment = "TC-PSPP - T{tool} - Pillar - Start".format(tool = tool_id)
            band_gcode.tail.comment = "TC-PSPP - T{tool} - Pillar - End".format(tool = tool_id)
        
        return band_gcode
Esempio n. 6
0
    def gcode_print_shape(self,
                          vertices,
                          tool_id,
                          retract_on_move=True,
                          closed=True):
        tokens = doublelinkedlist.DLList()

        if tool_id not in self.tools_active:
            raise gcode_analyzer.GCodeSerializeException(
                "Tool {tool_id} not in active set of prime tower layer #{layer_num}"
                .format(tool_id=tool_id, layer_num=self.layer_num))

        tokens.append_node(
            gcode_analyzer.GCode('G1', {
                'X': vertices[0][0],
                'Y': vertices[0][1]
            }))
        tokens.append_node(
            gcode_analyzer.GCode('G1', {'F': conf.prime_tower_print_speed}))
        for v in range(1, len(vertices)):
            distance = math.sqrt((vertices[v][0] - vertices[v - 1][0])**2 +
                                 (vertices[v][1] - vertices[v - 1][1])**2)
            E = conf.calculate_E(tool_id, self.layer_height, distance)
            tokens.append_node(
                gcode_analyzer.GCode('G1', {
                    'X': vertices[v][0],
                    'Y': vertices[v][1],
                    'E': E
                }))

        if closed:
            distance = math.sqrt((vertices[-1][0] - vertices[0][0])**2 +
                                 (vertices[-1][1] - vertices[0][1])**2)
            E = conf.calculate_E(tool_id, self.layer_height, distance)
            tokens.append_node(
                gcode_analyzer.GCode('G1', {
                    'X': vertices[0][0],
                    'Y': vertices[0][1],
                    'E': E
                }))

        return tokens
    def parse(self, gcode_file):
        self.tokens = doublelinkedlist.DLList()

        # Read all the lines
        with open(gcode_file, mode='r', encoding='utf8') as gcode_in:
            # Track the tool
            current_tool_head = -1

            for line in gcode_in.readlines():
                line = line.strip()

                if len(line) == 0:
                    continue

                # Check if comment
                if line[0] == ';':
                    # Check if comment params - starts with ;;
                    if len(line) > 1 and line[1] == ';':
                        contents = line[2:]
                        # Check if has extra comment - strip
                        comment_pos = contents.find(';')
                        if comment_pos != -1:
                            contents = contents[0:comment_pos].strip()
                        # Check if has params
                        label = None
                        params = []

                        params_sep = contents.find(':')
                        if params_sep != -1:
                            label = contents[0:params_sep].strip()
                            params = contents[params_sep + 1:].split(',')
                        else:
                            label = contents.strip()

                        # Check if the label in params
                        if label not in valid_params_format.keys():
                            raise GCodeParseException(
                                "Param {label} not valid".format(label=label),
                                line)
                        if len(params) != len(valid_params_format[label]):
                            raise GCodeParseException(
                                "Param {label} has invalid number of arguments"
                                .format(label=label), line)

                        self.tokens.append_node(
                            Params(label=label,
                                   param=[
                                       valid_params_format[label][indx](
                                           params[indx])
                                       for indx in range(0, len(params))
                                   ]))
                        continue
                    # Check if normal comment - single ;
                    if len(line) > 1 and line[1] != ';':
                        text = line[1:]

                        self.tokens.append_node(Comment(text=text))
                        continue
                    # Empty comment - skip
                    if len(line) == 1:
                        continue

                # Check if GCODE
                if line[0] in ['G', 'M']:
                    contents = line
                    comment = ""
                    # Check if has extra comment - strip
                    comment_pos = line.find(';')
                    if comment_pos != -1:
                        contents = line[0:comment_pos].strip()
                        comment = line[comment_pos + 1:].strip()

                    # Split into params
                    args = contents.split()
                    gcode = args[0]
                    # # Check if omit the code
                    if len(args) == 1:
                        self.tokens.append_node(
                            GCode(gcode=gcode, comment=comment))
                    else:
                        self.tokens.append_node(
                            GCode(gcode=gcode,
                                  param=dict([(p[0], p[1:])
                                              for p in args[1:]]),
                                  comment=comment))
                    continue

                # Check if Toolchange
                if line[0] == 'T':
                    # Check if has extra comment - strip
                    contents = line
                    comment_pos = line.find(';')
                    if comment_pos != -1:
                        contents = line[0:comment_pos].strip()

                    previous_tool_head = current_tool_head
                    current_tool_head = int(contents[1:])

                    self.tokens.append_node(
                        ToolChange(prev_tool=previous_tool_head,
                                   next_tool=current_tool_head))
                    continue
Esempio n. 8
0
    def inject_prime_tower_move_in(self, inject_point, gcode):
        inject_state = inject_point.state_post

        gcode_pre = doublelinkedlist.DLList()
        gcode_post = doublelinkedlist.DLList()

        # If firmware retracts - it is quite simple
        if conf.retraction_firmware:
            # - if prime tower Z is higher then current Z - inject Z move before moving to brim XY
            # - if prime tower Z is lower then current Z - inject Z move after brim XY
            if inject_state.z == None or inject_state.z < self.layer_z:
                gcode.head.append_node_left(
                    gcode_analyzer.GCode('G1', {'Z': self.layer_z}))
            elif inject_state.z > self.layer_z:
                gcode.head.append_node(
                    gcode_analyzer.GCode('G1', {'Z': self.layer_z}))

            # - if was unretracted - add retraction/unretraction around the first move from gcode
            if not inject_state.is_retracted:
                gcode.head.append_node(
                    gcode_analyzer.GCode('G11', comment='move-in detract'))
                gcode.head.append_node_left(
                    gcode_analyzer.GCode('G10', comment='move-in retract'))

            # - if was retracted, just add unretraction after first move from gcode
            if inject_state.is_retracted:
                gcode.head.append_node(
                    gcode_analyzer.GCode('G11', comment='move-in detract'))
            gcode.head.append_node_left(
                gcode_analyzer.GCode('G1', {'F': conf.prime_tower_move_speed}))

        # If not firmware retract - do a move manually
        # If not retracted also do a wipe move (not longer then 1mm)
        if not conf.retraction_firmware:
            # If not retracted do a wipe move
            to_detract = 0.0
            if inject_state.is_retracted:
                to_detract = abs(inject_state.retraction)
            else:
                # We will need to detract same what retract in next step
                to_detract = conf.retraction_length[inject_state.tool_selected]

            # If retracted but we need to ajust the Z
            gcode_pre = doublelinkedlist.DLList()
            if inject_state.is_retracted:
                move_z = self.layer_z + conf.retraction_zhop[
                    inject_state.tool_selected]
                if move_z > inject_state.z:
                    gcode_pre.append_node(
                        gcode_analyzer.GCode(
                            'G1', {'F', conf.prime_tower_move_speed}))
                    gcode_pre.append_node(
                        gcode_analyzer.GCode('G1', {'Z', move_z}))
            else:
                # Need to retract and Z-hop
                move_z = max(inject_state.z,
                             self.layer_z) + conf.retraction_zhop[
                                 inject_state.tool_selected]

                gcode_pre.append_node(
                    gcode_analyzer.GCode('G1', {
                        'F':
                        conf.retraction_speed[inject_state.tool_selected]
                    }))
                # Add the wipe
                if conf.wipe_distance > 0.0:
                    wipe_gcode = self.gcode_wipe_path(
                        inject_point, conf.wipe_distance,
                        conf.retraction_length[inject_state.tool_selected] /
                        2.0)
                    gcode_pre.append_nodes(wipe_gcode)
                    gcode_pre.append_node(
                        gcode_analyzer.GCode(
                            'G1', {
                                'E':
                                -conf.retraction_length[
                                    inject_state.tool_selected] / 2.0
                            }))
                else:
                    gcode_pre.append_node(
                        gcode_analyzer.GCode(
                            'G1', {
                                'E':
                                -conf.retraction_length[
                                    inject_state.tool_selected]
                            }))

                gcode_pre.append_node(
                    gcode_analyzer.GCode('G1',
                                         {'F', conf.prime_tower_move_speed}))
                gcode_pre.append_node(gcode_analyzer.GCode(
                    'G1', {'Z', move_z}))

            # Add the speed
            gcode_pre.append_node(
                gcode_analyzer.GCode('G1', {'F', conf.prime_tower_move_speed}))

            gcode_post = doublelinkedlist.DLList()
            gcode_post.append_node(
                gcode_analyzer.GCode(
                    'G1', {
                        'Z': self.layer_z,
                        'E': conf.retraction_length[inject_state.tool_selected]
                    }))

            # Add to gcode
            gcode.head.append_nodes_right(gcode_post)
            gcode.head.append_nodes_left(gcode_pre)

        return gcode