Once the robot has been calibrated, you have two options to generate programs using the absolute accuracy of the calibrated robot:
● Filter existing programs: all the robot targets inside a program are modified to improve the accuracy of the robot. It can be done manually or using the API.
● Use RoboDK for Offline Programming to generate accurate programs (generated programs are already filtered, including programs generated using the API).
To filter an existing program manually: drag & drop the robot program file into RoboDK’s main screen (or select File➔Open) and select Filter only. The program will be filtered and saved in the same folder. The filter summary will mention if there were any problems using the filtering algorithm. You also have the option to import a program if you want to simulate it inside RoboDK. If the program has any dependencies (tool frame or base frame definitions, subprograms, ...) they must be located in the same directory where the first program is imported.
Once you import the program inside RoboDK you can regenerate it with or without absolute accuracy. In the main accuracy settings of RoboDK (Tools➔Options➔Accuracy) you can decide if you want to always generate the programs using accurate kinematics, if you want to ask every time or if you want to use the current robot kinematics. The current robot kinematics can be changed by right clicking the robot and activating/deactivating the “Use accurate kinematics” tag. If it is active you will see a green dot, if it is not active, you will see a red dot.
It is possible to filter a complete program using RoboDK given a calibrated robot and the robot program using the FilterProgram call:
robot.FilterProgram(file_program)
A macro example called FilterProgram is available in the Macros section of the library. The following code is an example Python script that uses the RoboDK API to filter a program.
from robolink import * # API to communicate with RoboDK
from robodk import * # basic matrix operations
import os # Path operations
# Get the current working directory
CWD = os.path.dirname(os.path.realpath(__file__))
# Start RoboDK if it is not running and link to the API
RDK = Robolink()
# optional: provide the following arguments to run behind the scenes
#RDK = Robolink(args='/NOSPLASH /NOSHOW /HIDDEN')
# Get the calibrated station (.rdk file) or robot file (.robot):
# Tip: after calibration, right click a robot and select "Save as .robot"
calibration_file = CWD + '/KUKA-KR6.rdk'
# Get the program file:
file_program = CWD + '/Prog1.src'
# Load the RDK file or the robot file:
calib_item = RDK.AddFile(calibration_file)
if not calib_item.Valid():
raise Exception("Something went wrong loading " + calibration_file)
# Retrieve the robot (no popup if there is only one robot):
robot = RDK.ItemUserPick('Select a robot to filter', ITEM_TYPE_ROBOT)
if not robot.Valid():
raise Exception("Robot not selected or not available")
# Activate accuracy
robot.setAccuracyActive(1)
# Filter program: this will automatically save a program copy
# with a renamed file depending on the robot brand
status, summary = robot.FilterProgram(file_program)
if status == 0:
print("Program filtering succeeded")
print(summary)
calib_item.Delete()
RDK.CloseRoboDK()
else:
print("Program filtering failed! Error code: %i" % status)
print(summary)
RDK.ShowRoboDK()
The following code is an example Python script that uses the RoboDK API to filter a target (pose target or joint target), using the FilterTarget command:
pose_filt, joints = robot.FilterTarget(nominal_pose, estimated_joints)
This example is useful if a 3rd party application (other than RoboDK) generates the robot program using pose targets.
from robolink import * # API to communicate with RoboDK
from robodk import * # basic matrix operations
def XYZWPR_2_Pose(xyzwpr):
return KUKA_2_Pose(xyzwpr) # Convert X,Y,Z,A,B,C to a pose
def Pose_2_XYZWPR(pose):
return Pose_2_KUKA(pose) # Convert a pose to X,Y,Z,A,B,C
# Start the RoboDK API and retrieve the robot:
RDK = Robolink()
robot = RDK.Item('', ITEM_TYPE_ROBOT)
if not robot.Valid():
raise Exception("Robot not available")
pose_tcp = XYZWPR_2_Pose([0, 0, 200, 0, 0, 0]) # Define the TCP
pose_ref = XYZWPR_2_Pose([400, 0, 0, 0, 0, 0]) # Define the Ref Frame
# Update the robot TCP and reference frame
robot.setTool(pose_tcp)
robot.setFrame(pose_ref)
# Very important for SolveFK and SolveIK (Forward/Inverse kinematics)
robot.setAccuracyActive(False) # Accuracy can be ON or OFF
# Define a nominal target in the joint space:
joints = [0, 0, 90, 0, 90, 0]
# Calculate the nominal robot position for the joint target:
pose_rob = robot.SolveFK(joints) # robot flange wrt the robot base
# Calculate pose_target: the TCP with respect to the reference frame
pose_target = invH(pose_ref)*pose_rob*pose_tcp
print('Target not filtered:')
print(Pose_2_XYZWPR(pose_target))
joints_approx = joints # joints_approx must be within 20 deg
pose_target_filt, real_joints = robot.FilterTarget(pose_target, joints)
print('Target filtered:')
print(real_joints.tolist())
print(Pose_2_XYZWPR(pose_target_filt))