Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5

Frame relative to linear track

#1
When generating the robot program with 3 robot's synced together. Is it possible to make the reference frames that are generated relative to a selected robot?

In the rdk I attached, I have the robot, linear track, and turntable synced together. When I generate the program the reference frame are generated relative to the turntable but I want it to be relative to the linear track instead.


Attached Files
.rdk   example_on_turntable.rdk (Size: 7.09 MB / Downloads: 40)
#2
Following the documents on creating the post processor, I was able to change the reference frames to be relative to the linear track. By enabling "Export External Axes Pose" and transforming the poses to be relative to the linear rail. Since the poses seems to be relative to the rail already. All I needed to do was take it out of the turntable's relative transform.

Code:
    def setFrame(self, pose, frame_id, frame_name, *args, **kwargs):
        """Defines a new reference frame with respect to the robot base frame."""
        # Taken from RoboDK's Post-Processor example where they are changing the relative pose of a movel
        # Reference: https://robodk.com/doc/en/PythonAPI/postprocessor.html#post-processor-example

        if self._PoseTrack or self._PoseTurntable:
            if self.POSE_TURNTABLE and self.POSE_RAIL:
                # Making Positioner relative pose to be relative to the Rail
                pose = self.POSE_TURNTABLE * self._PoseTurntable * pose
        elif self.POSE_TURNTABLE and self.POSE_RAIL:
            # The first frame that gets created doesn't provide the _PoseTrack nor _PoseTurntable.
            # So we're only checking if the POSE_TURNTABLE and POSE_RAIL was provided in the constructor
            # to get the frame's pose relative to the rail.
            frame_item = self.RDK.Item(frame_name, robolink.ITEM_TYPE_FRAME)
            pose = frame_item.PoseWrt(self.rail_base)

        self._frame_pose = pose
        self._frame_id = frame_id
        self._frame_name = frame_name

        # Convert the pose to KUKA's FRAME format
        frame_str = self.pose_2_str(pose)

        # Add the line to set the base directly
        self.addline('; ---- Setting reference: %s ----' % frame_name)
        self.addline('$BASE = {FRAME: %s}' % frame_str)
        self.addline('; --------------------------')

However, for some reason the first frame that gets created, doesn't provide the turntable or linear track poses.

Code:
r.RunMessage(r"""Program generated by RoboDK v5.8.0 for KUKA KR 20 R3100 1 on 31/03/2025 10:49:45""",True)
r.RunMessage(r"""Using nominal kinematics.""",True)
r.RunMessage(r"""INIT_PARAMS_START""",True)
r.RunMessage(r"""F8094 - M12127 - O1110""",True)
r.setZoneData(1.000)
r.setSpeed(30.000)
r.setFrame(p(159.352,89.885,-2604.75,-90,0,90),-1,r"""Part6279 Frame""")
r.setTool(p(19,-0.4,466.7,0,-40,0),3,r"""Fronius_Short 3""")


Setting another frame at the end of the program:
Code:
r._PoseTrack=p(-2400.000000,0.000000,0.000000,0.000000,0.000000,0.000000)
r._PoseTurntable=p(0.000000,0.000000,1280.000000,0.000000,90.000000,0.000000)
r.setFrame(p(-13.648,-106.115,-2604.75,90,0,-180),-1,r"""Action12127 Frame""")

Because of this I needed to get the frame and rail items directly from robodk to get the relative pose. Is there a reason why the first frame doesn't provide the poses? Or is there a better way of doing this?

Code:
    def __init__(self, robotpost='', robotname='', robot_axes=6, *args, **kwargs):
        # Optional constructor parameters (added later, backward compatibility)
        self.AXES_TYPE = None  # Optional, type of each axes of the robot ('R': Robot rotative, 'T': Robot translation, 'J': Ext. axis rotative, 'L': Ext. axis linear) (provided by RoboDK in the constructor)
        self.NATIVE_NAME = robotname  # Optional, native/original name of the robot (provided by RoboDK in the constructor)
        self.IP_COM = None  # Optional, IP address of the robot ("Connect" tab in RoboDK) (provided by RoboDK in the constructor)
        self.API_PORT = None  # Optional, RoboDK API port to the RoboDK instance (provided by RoboDK in the constructor)
        self.PROG_PTR = None  # Optional, RoboDK Item pointer to the program generated (provided by RoboDK in the constructor)
        self.ROBOT_PTR = None  # Optional, RoboDK Item pointer to the robot associated with the program generated (provided by RoboDK in the constructor)
        self.POSE_TURNTABLE = None  #  Optional, offset pose of the synchronized turn table (provided by RoboDK in the constructor)
        self.POSE_RAIL = None  # Optional, offset pose of the synchronized linear rail (provided by RoboDK in the constructor)
        self.MAX_LINES_X_PROG = None  # Optional, maximum number of lines per program (to generate multiple files). This setting can be overridden in RoboDK (Tools-Options-Program) (provided by RoboDK in the constructor)
        self.PULSES_X_DEG = None  # Optional, pulses per degree (provided in the robot parameters of RoboDK) (provided by RoboDK in the constructor)

        # Optional constructor parameters, you may or may not use those
        for k, v in kwargs.items():
            if k == 'axes_type':
                self.AXES_TYPE = v
            elif k == 'native_name':
                self.NATIVE_NAME = v
            elif k == 'ip_com':
                self.IP_COM = v
            elif k == 'api_port':
                self.API_PORT = v
            elif k == 'prog_ptr':
                self.PROG_PTR = v
            elif k == 'robot_ptr':
                self.ROBOT_PTR = v
            elif k == 'pose_turntable':
                self.POSE_TURNTABLE = v
            elif k == 'pose_rail':
                self.POSE_RAIL = v
            elif k == 'lines_x_prog':
                self.MAX_LINES_X_PROG = v
            elif k == 'pulses_x_deg':
                self.PULSES_X_DEG = v

        # Optional TEMP parameter (depends on RoboDK settings)
        self._TargetName = None  # Optional, target name (Tools->Options->Program->Export target names) (provided by RoboDK in the TEMP file)
        self._TargetNameVia = None  # Optional, intermediary target name (MoveC) (Tools->Options->Program->Export target names) (provided by RoboDK in the TEMP file)
        self._PoseTrack = None  # Optional, current pose of the synchronized linear axis (Tools->Options->Program->Export external axes poses) (provided by RoboDK in the TEMP file)
        self._PoseTurntable = None  # Optional, current pose of the synchronized turn table (Tools->Options->Program->Export external axes poses) (provided by RoboDK in the TEMP file)

        self.RDK = robolink.Robolink()
        robot_item = self.RDK.Item(robotname, robolink.ITEM_TYPE_ROBOT)

        if self.POSE_TURNTABLE and self.POSE_RAIL:
            links = robot_item.getLinks()
            self.rail_base = links[0].Parent()
#3
Sorry, I realized it was because some of the linear movements were getting removed but robodk still include the external poses so it looked like the frames as well were given external poses.
#4
Thank you for letting us know. I understand this issue is resolved. Let us know if it is not the case.
#5
It has been resolved by calling PoseWrt() to get the relative position of the frame to the rail's base. But according to the documents, it is advised to avoid creating instances of Robolink and Item. So I would like to avoid that as much as possible.

The only method I can think of if I want to completely avoid using Robolink and Item, is to follow the post processor example. Where I need to make the movel's pose relative to the rail's base then offset the pose from the frame.

I'll send an update when I get the chance to test it out.
#6
It is fine if you use an instance of Robolink in the post processor. The only drawback is performance, you may see a slowdown if you have to generate large robot programs (500000 lines or more for example).

If you believe your implementation is not optimal feel free to share it and we can help you better.
  




Users browsing this thread:
1 Guest(s)