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

External Rail programmation with the Python API

#1
Hi,

I experience issue while programming a path with robodk. My station looks like instation png. My code looks like this :

Code:
"""
       Control the robot via the RoboDK Python API

               Parameters
               ----------
                   htm = (n,4,4)
                       Homogeneous Transformation Matrices from the base to the tool holder of every positions
                   speed : (n-1) float
                       speed between each position
   """

   RDK = Robolink()
   copyfile("..\Ressources\RDKFiles\CTTLab.rdk", "..\Ressources\RDKFiles\Test.rdk")
   RDK.AddFile("..\Ressources\RDKFiles\Test.rdk")
   robot = RDK.Item('KUKA KR 100-2 P', ITEM_TYPE_ROBOT)
   if not robot.Valid():
       raise Exception('No robot selected or available')

   reference = robot.Parent().Parent()

   # Create a new program
   program = RDK.AddProgram("Test", robot)

   # Turn off automatic rendering
   RDK.Render(False)

   # Specify the reference frame you want to use
   program.setPoseFrame(reference)

   # Define a reference pose
   targetname = 'Target Home'
   target_home = RDK.AddTarget(targetname, reference, robot)
   target_home.setJoints(robot.SolveFK(robot.JointsHome()))
   program.MoveJ(target_home)

   targetname = 'Target 0'
   target = RDK.AddTarget(targetname, reference, robot)
   target.setAsCartesianTarget()
   target.setPose(htm[0])
   program.MoveJ(target)

   for i in range(htm.shape[0] - 1):
       targetname = 'Target %i' % (i + 1)
       target = RDK.AddTarget(targetname, reference, robot)
       target.setPose(htm[i+1])
       program.setSpeed(speed[i])
       program.MoveJ(target)

   program.RunProgram()
I get a error : AttributeError: 'numpy.ndarray' object has no attribute 'isHomogeneous'
I overcome this by remplacing htm[i] by KUKA_2_Pose(Pose_2_KUKA(htm[i+1])). But it doesn`t seems to be the proper way.
When running the corrected program, i get an error that the target is out of reach. as shown in the picture enclosed.

Do you have an idea of where it can come from ?

I tried another solution. Indeed, I added the following :
target.setAsJointTarget()
The rail finally move to reach the target but it doens't reach the proper target.

Thank you


Attached Files Thumbnail(s)
       
#2
I believe you are providing numpy matrices to the RoboDK API. RoboDK expects 4x4 matrices to be Mat objects. This Matrix object is defined in the robodk module:
https://robodk.com/doc/en/PythonAPI/robo...robodk.Mat

You could do something like:
reference = KUKA_2_Pose(list(xyzabc))

Where xyzabc is a 1D numpy array given X,Y,Z,A,B,C values. The list function will convert it to a list of 6 values and the KUKA_2_Pose will create a Mat pose that you can provide to RoboDK as a pose.
#3
Hi,
Thank you for your answer.
Unfortunately, it doesn't solve the "target out of reach" issue. What about it ?

I should precise that I acheive placing the targets. It just says that they are out of reach while obviously they are not.


Attached Files Thumbnail(s)
   
#4
Can you share the RoboDK project (RDK file)?
You may need to set a value for the external axis so targets can be reached.
#5
Actually, I answered my question by myself. I solved it this way :
Code:
target_name = 'Target %i' % (i + 1)
robot.MoveJ(robot.SolveIK(KUKA_2_Pose(Pose_2_KUKA(htm[i+1])), tool=RDK.Item('Tool 1', ITEM_TYPE_TOOL).PoseTool()))
target = RDK.AddTarget(target_name, reference, robot)
program.setSpeed(speed[i])
program.MoveL(target)
RDK.Update()

Thank you

Marc
#6
Hi,

I will reply to this subject again.

Indeed I did kind of solve the issue using the previous code however. I have a lot of point and it takes very long to generate using this mean. I use the MacOS version of RoboDK and the straight forward method to create target using the API works. However when back to the windows version, it still doesn't work.

The straight forward code I use is this one :

Code:
        RDK = Robolink()

        robot = RDK.Item('KUKA KR 100 HA', ITEM_TYPE_ROBOT)
        if not robot.Valid():
            raise Exception('No robot selected or available')

        world_base = RDK.Item('World Base', ITEM_TYPE_FRAME)
        camera_base = RDK.Item('Camera base', ITEM_TYPE_FRAME)
        tool = RDK.Item('Tool 1', ITEM_TYPE_TOOL)

        RDK.Render(False)


        # Specify the reference frame you want to use
        program = RDK.AddProgram("{} Picture Analysis".format(name_prog), robot)
        program.setPoseFrame(camera_base)
        program.setPoseTool(tool)

        program.setSpeed(speed, 200, 10000, 800)

        target_name = 'Approach target'
        pose = Mat(htm[0].tolist())
        target = RDK.AddTarget(target_name, camera_base, tool)
        target.setAsCartesianTarget()
        target.setPose(pose)
        program.MoveJ(target)



        for i in range(htm.shape[0] - 1):
            target_name = 'Target {}'.format(i)
            pose = Mat(htm[i + 1].tolist())
            target = RDK.AddTarget(target_name, camera_base, tool)
            target.setAsCartesianTarget()
            target.setPose(pose)
            program.MoveL(target)


It generates me the following file.

When launching the program it says that the target is not reachable.

Here is the file


Attached Files
.rdk   M301_01.rdk (Size: 1.86 MB / Downloads: 717)
#7
Hi Marc,

When you use external axes you need to provide the position of the external axes in your target (using setJoints). If the target is Cartesian you don't need to worry about the robot axes. Alternatively, you can load a robot machining file such as Gcode or APT and use a curve follow project or robot machining project. You'll then be able to optimization tools for external axes.

I was unable to test your file as it requires additional input data but this small script will allow you to update the position of the external axes to all targets in a station (for example, 5000 mm):

Code:
from robolink import *    # RoboDK API
from robodk import *      # Robot toolbox
RDK = Robolink()

targets = RDK.ItemList(ITEM_TYPE_TARGET)

RDK.Render(False)
for t in targets:
   # Set the value of the external axis
   e1 = 5000 # in mm
   t.setJoints([0,0,0,0,0,0, e1])

   # Recalculate the joint position based on the new position of the external axis
   # Robot joints are updated but not external axis
   t.setAsCartesianTarget()
   t.Joints()

   jnts = t.Joints()
   print(t.Name() + "-Joints: " + str(jnts.list()))

If you are looking for faster speed (I noticed you already disabled Render) I would recommend you to use the C++ API (slightly faster) or the plugin interface to create a plugin (much faster). The API's are almost the same in both cases.

Albert


Attached Files
.rdk   M301_01.rdk (Size: 1.86 MB / Downloads: 635)
#8
Thank you for your answer Albert. Actually, I don't know the external rail position, I want robodk to optimize this parameter. How can I manage it ?

Plus what's weird is that it totally works on MacOS this way.
#9
Hi Marc,

You can wrap the update of the external axis inside another loop to test different positions for the rail (programmatically).

The command program.Update will quickly tell you if the program is feasible so you can keep searching until you find a valid solution.

I updated your sample project to do so.

Albert

Code:
from robolink import *    # RoboDK API
from robodk import *      # Robot toolbox
RDK = Robolink()

# Retrieve all targets
targets = RDK.ItemList(ITEM_TYPE_TARGET)

# Select a program (automatic selection if you only have one program)
program = RDK.ItemUserPick('Select a program to check and update targets', ITEM_TYPE_PROGRAM)

# Turn off rendering (faster)
RDK.Render(False)

# List some candidates for the external axis (E1, in mm):
Test_E1 = [500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500]
#test_E1 = range(500, 5000, 500)

for e1 in Test_E1:
   print("Testing program feasibility for E1:" + str(e1))

   # Update all targets to desired e1
   for t in targets:
       # Set the value of the external axis
       # e1 = 5000 # in mm
       t.setJoints([0,0,0,0,0,0, e1])

       # Recalculate the joint position based on the new position of the external axis
       # Robot joints are updated but not external axis
       t.setAsCartesianTarget()
       t.Joints()

       jnts = t.Joints()
       print(t.Name() + "-Joints: " + str(jnts.list()))

   # Test the program and make sure it is 100% feasible
   valid_ins, prog_time, prog_len, valid_ratio, error_msg = program.Update()
   if valid_ratio < 1.0:
       print("  Unable to complete the program")
       print("  " + error_msg)

   else:
       print("  Program feasible!")
       # stop looking
       break

print("Done!")
program.RunProgram()


Attached Files
.rdk   M301_01 v3.rdk (Size: 1.86 MB / Downloads: 583)
#10
Thank you very much for your help. It works fine !
  




Users browsing this thread:
1 Guest(s)