Post Processor pour l’impression 3D par robot

Cette section montre comment modifier un post-processeur de robot pour calculer la vitesse de l’extrudeur avant d’exécuter une instruction de mouvement pour l’impression 3D. Ces opérations peuvent être faites sur le contrôleur de robot avec l’appel de programme Extruder (commande par défaut pour piloter l’extrudeur).

En personnalisant un post-processeur de robot, il est possible de faciliter l’intégration d’un extrudeur pour l’impression 3D avant d’envoyer le programme au robot. Pour accomplir cette tâche, quelques calculs et du code personnalisé doivent être prévu lorsque le programme est généré dans le post processeur du robot.

La première étape consiste à intercepter les appels d’extrudeur et à lire les nouvelles valeurs d’extrudeur (valeurs E) dans la section Runcode du post-processeur. La section suivante traite tous les appels de programme générés pour un programme :

    def RunCode(self, code, is_function_call = False):

        if is_function_call:

            if code.startswith("Extruder("):

                # Intercept the extruder command.

                # if the program call is Extruder(123.56)

                # we extract the number as a string

                # and convert it to a number

                self.PRINT_E_NEW = float(code[9:-1])

                # Skip the program call generation

                return

            else:

                self.addline(code + "()")

        else:

            # Output program code

            self.addline(code)

La valeur Extruder (longueur/E) est enregistrée comme variable PRINT_E_NEW dans le post processeur du robot.

Un appel de fonction nommé new_move doit être déclenché à chaque nouvelle instruction de mouvement linéaire. Cet appel est ajouté au début de la commande MoveL :

    def MoveL(self, pose, joints, conf_RLF=None):

        """Add a linear movement"""

        # Handle 3D printing Extruder integration

        self.new_move(pose)    

       ...

Les variables suivantes doivent être ajoutées dans l’en-tête du post-processeur pour calculer les incréments d’extrudeur :

    # 3D Printing Extruder Setup Parameters:

    PRINT_E_AO = 5 # Analog Output ID to command the extruder flow

    PRINT_SPEED_2_SIGNAL = 0.10 # Ratio to convert the speed/flow to an analog output signal

    PRINT_FLOW_MAX_SIGNAL = 24 # Maximum signal to provide to the Extruder

    PRINT_ACCEL_MMSS = -1 # Acceleration, -1 assumes constant speed if we use rounding/blending

  

    # Internal 3D Printing Parameters

    PRINT_POSE_LAST = None # Last pose printed

    PRINT_E_LAST = 0 # Last Extruder length

    PRINT_E_NEW = None # New Extruder Length

    PRINT_LAST_SIGNAL = None # Last extruder signal

Enfin, une nouvelle procédure doit être définie pour générer les commandes d’alimentation d’extrudeur appropriées en fonction de la distance entre les mouvements, la vitesse du robot et l’accélération du robot. Cela suppose que l’alimentation de l’extrudeur est entraînée par une sortie analogique spécifique ou un appel de programme personnalisé.

Le code suivant doit être ajouté avant la définition du programme def MoveL.

    def calculate_time(self, distance, Vmax, Amax=-1):

        """Calculate the time to move a distance with Amax acceleration and Vmax speed"""

        if Amax < 0:

            # Assume constant speed (appropriate smoothing/rounding parameter must be set)

            Ttot = distance/Vmax

        else:

            # Assume we accelerate and decelerate

            tacc = Vmax/Amax;

            Xacc = 0.5*Amax*tacc*tacc;

            if distance <= 2*Xacc:

                # Vmax is not reached

                tacc = sqrt(distance/Amax)

                Ttot = tacc*2

            else:

                # Vmax is reached

                Xvmax = distance - 2*Xacc

                Tvmax = Xvmax/Vmax

                Ttot = 2*tacc + Tvmax

        return Ttot

           

    def new_move(self, new_pose):                       

        """Implement the action on the extruder for 3D printing, if applicable"""

        if self.PRINT_E_NEW is Noneor new_pose isNone:

            return

           

        # Skip the first move and remember the pose

        if self.PRINT_POSE_LAST is None:

            self.PRINT_POSE_LAST = new_pose

            return         

 

        # Calculate the increase of material for the next movement

        add_material = self.PRINT_E_NEW - self.PRINT_E_LAST

        self.PRINT_E_LAST = self.PRINT_E_NEW

       

        # Calculate the robot speed and Extruder signal

        extruder_signal = 0

        if add_material > 0:

            distance_mm = norm(subs3(self.PRINT_POSE_LAST.Pos(), new_pose.Pos()))

            # Calculate movement time in seconds

            time_s = self.calculate_time(distance_mm, self.SPEED_MMS, self.PRINT_ACCEL_MMSS)

           

            # Avoid division by 0

            if time_s > 0:

                # This may look redundant but it allows you to account for accelerations and we can apply small speed adjustments

                speed_mms = distance_mm / time_s

               

                # Calculate the extruder speed in RPM*Ratio (PRINT_SPEED_2_SIGNAL)

                extruder_signal = speed_mms * self.PRINT_SPEED_2_SIGNAL

       

        # Make sure the signal is within the accepted values

        extruder_signal = max(0,min(self.PRINT_FLOW_MAX_SIGNAL, extruder_signal))

       

        # Update the extruder speed when required

        if self.PRINT_LAST_SIGNAL is Noneor abs(extruder_signal - self.PRINT_LAST_SIGNAL) > 1e-6:

            self.PRINT_LAST_SIGNAL = extruder_signal

            # Use the built-in setDO function to set an analog output

            self.setDO(self.PRINT_E_AO, "%.3f" % extruder_signal)

            # Alternatively, provoke a program call and handle the integration with the robot controller

            #self.addline('ExtruderSpeed(%.3f)' % extruder_signal)

       

        # Remember the last pose

        self.PRINT_POSE_LAST = new_pose