Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
When calling PoseWrt() between two reference frames, if one frame is attached to a robot, then a TargetReachError is thrown.

The attached .py and .rdk files are able to reliably reproduce this problem.

Note: I believe that even when no target reach error occurs, PoseWrt() does not return the expected coordinates when the calling Item is nested under a robot. I was actually investigating that issue when I uncovered the TargetReachError problem.

Update: I found a workaround (below). This works great for now, but I would like to go back to using the API in the future.
def pose_wrt(child, parent):
   childPose = child.PoseAbs()
   parentPose = parent.PoseAbs()
   return parentPose.inv() * childPose

Attached Files
.rdk   poseWrtBug.rdk (Size: 2.18 MB / Downloads: 13)
.py (Size: 274 bytes / Downloads: 12)
You are absolutely right!

For the target reach error, I think the robot was synchronized but not moved yet, as the joint value for the linear axis is at 0 mm while the lower range limit is 5 mm (even if 5 is displayed in the menu).
Moving the linear axis to 10 then back to 5, then running the script, removed the exception.

However, it is true that PoseWrt with synchronized axis is not working properly. In fact, it should throw an input error.
PoseWrt adds the ability to get the tool pose wrt to another item anywhere in the tree, which your code will not allow.
Try pose_wrt(robot, frame2) or pose_wrt(tool, frame2) while the active frame is Frame 1.
This is because robot.Pose() returns the pose (including the tool) wrt to the ACTIVE reference frame, not the robot base!

As only robots and tools have an odd behaviour with .Pose() and .PoseAbs(), I have changed the code so that two frames skips this whole process and returns the pose without a problem when using two frames (like your code).

As for PoseWrt with synchronized axis, the behaviour is changing a bit when you have a turn table and a linear rail synchronized, and the generic solution no longer applies. For now, it will still throw if you use the robot or tool Items.

Here's the test code:

from robodk import *
from robodk.robolink import *

RDK = robolink.Robolink()
frame1 = RDK.Item('Frame 1', ITEM_TYPE_FRAME)
frame2 = RDK.Item('Frame 2', ITEM_TYPE_FRAME)
robot = RDK.Item('robot', ITEM_TYPE_ROBOT)

pose = robot.Pose()
pose_abs = robot.PoseAbs()
while True:

   # below will throw unless you unsync the ext. axis
   # it will also throw as the current axis value of the linear rail is lower than the lower limit (0 vs 5). Move it back to 5, it will work.

You can retrieve the latest version of robolinkutils with the link below, or wait for the next update.
Please read the Forum Guidelines before posting!
Find useful information about RoboDK by visiting our Online Documentation.
Hi Jeremy, thanks for taking care of that!

It seems that calling PoseAbs() from a tool is possible, but behaves differently than other objects by returning the position of flange, even though it was called from a tool. I think many (most?) users would expect that PoseAbs() called from a tool would return TCP.

I would recommend adding a note into the documentation for PoseAbs() (and maybe also PoseWrt()) to prevent others from falling victim to the behaviors we discussed.
Indeed, it should be better documented. In fact, I added PoseWrt to ensure we have an easy way to retrieve the pose without the need to think about these conditions.

By the way, I'm Sam :)
Please read the Forum Guidelines before posting!
Find useful information about RoboDK by visiting our Online Documentation.
Sorry, was talking to Jeremy previously!

Thanks, Sam.

Users browsing this thread:
1 Guest(s)