i am writing a urcap to generate waypoints using RDTE and createFixedPositionConfig method. Made some tests without a tcp in the simulation and everthing is working fine. Now i wanted to test everthing on a robot. There i was a bit puzzled sometimes the robot decides to sort its joints different than expect. As example:
The values above are from the waypointconfiguration.
What puzzles me the most, that the most times it will be solved the right way but sometimes not. As we all know sometimes, not is not acceptable in robotics . Does someone have an idea why this is happing? I am using the sdk 1.13 and polyscope 5.12⌠There must be something i am missing here :-/.
There seems to be some issues with the qnear related to API created waypoints. It should not be an issue if you choose a fixed TCP instead of the active one.
For reference there is created a ticket ER-829 around the issue.
Hi @Ebbe . My team have been struggling with this issue the past weeks too. When you say that we need to choose a fixed TCP, do mean that we need to add a zero array as TcpOffset to createFixedPositionConfig and add the offset to the pose itself?
Can we use TCPSelection createIgnoreActiveTCPSelection to set fixed TCP?
That might also solve the qnear challenge, but introducer other as you say. My suggestion is to utilize createTCPSelection(TCP tcp) where you can select the TCP the match your setup.
Thank you for your reply @Ebbe. Can you please be more specific on how to get around this issue? Just as the thread starter we are trying to generate waypoints using the createFixedPositionConfig method based on some teached points. But simulation in Polyscope and the real robot produces different results in joint configurations.
Teach point:
You say " It should not be an issue if you choose a fixed TCP instead of the active one". I thought active TCP is just one of the available TCP configurations that have been saved to the installation? I donât see any âfixedâ option?
We have tried using Active, IgnoreActive, Waypoint with and without offset input(see image in previous post), and the overload based on PositionParameters directly from teachpoint. No success.
Here I have collected the relevant methods for the issue at hand. Would you mind pointing out to us what we need to do differently:
// The teach button
private JButton createTeachButton(Rectangle bounds, final ContributionProvider<ProgramNodeContribution> provider) {
JButton button = new JButton("Teach point");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
provider.get().addTeachPoint();
}
});
button.setBounds(bounds);
return button;
}
// calls the correct methods for user input
public void addTeachPoint() {
switch(getCurrentTeachRing()) {
case NO_RING:
this.view.debug("Select a ring to teach first.");
break;
case INNER_RING:
if (numInnerTeachPoints() >= 8) {
this.view.debug("addTeachPoint(): Inner circle allready has 8 teach points.");
} else {
askUserToTeachPoint(this.innerTeachPointsContainerNode);
}
break;
case OUTER_RING:
if (numOuterTeachPoints() >= 8) {
this.view.debug("addTeachPoint(): Outer circle allready have 8 teach points.");
} else {
askUserToTeachPoint(this.outerTeachPointsContainerNode);
}
break;
default:
}
}
// directs the user to add teachpoint
public void askUserToTeachPoint(final TreeNode containerNode) {
final UserInterfaceAPI uiapi = apiProvider.getUserInterfaceAPI();
this.apiProvider.getProgramAPI().getUndoRedoManager().recordChanges(new UndoableChanges() {
@Override
public void executeChanges() {
uiapi.getUserInteraction().getUserDefinedRobotPosition(new RobotPositionCallback2() {
@Override
public void onOk(PositionParameters parameters) {
WaypointNode waypoint = createWaypointNode(parameters, "TeachPoint_" + (numTeachPointsIn(containerNode) + 1)); // +1 because waypoint is not added yet
addChild(containerNode, waypoint);
}
});
}
});
}
// method that creates WaypointNode
private WaypointNode createWaypointNode(final PositionParameters posParams, String name) {
WaypointNode node = this.programNodeFactory.createWaypointNode(name);
BlendParameters blendParameters = this.waypointNodeConfigFactory.createNoBlendParameters();
WaypointNodeConfig waypointConfig = this.waypointNodeConfigFactory.createFixedPositionConfig(
posParams,
blendParameters,
this.waypointNodeConfigFactory.createSharedMotionParameters()
);
node.setConfig(waypointConfig);
return node;
}
Apparently, there is a quite long-lived bug in the way API generated waypoints have their inverse kinematics solution calculated. It only seems to happen when the relevant tcp-offset has some specified rotation. And the effect is that the joint angles of the generated waypoint does not match the configuration of the qNear parameter. Here is a way to recreate the bug: PositionParameters / Wrong Pose using WaypointNodeFactory with specific TCP Rotation - #7 by m.birkholz
@jbmâs solution above involves adding a MoveNode configured to use a defined TCP rather than âActive TCPâ or âIgnore TCPâ. Here is an example of some code to fetch one of the defined TCPâs from the installation API:
This bug was super annoying for us to work with and it set us back a couple of weeks of development. In my opinion, it should have been fixed a long time ago, or an official workaround should have been released so that it was easier to find.
@db11 The funny thing is, that nearly everybody creates the same functionality.
In my case, the customer shipped the robot to their customer already, and I could not verify my solution at the exact same robot. But it worked on another one. I created my parent move node like this:
I meant to refer only to the last post in the thread by m.birkholz, where he describes how to recreate a bug in the inverse kinematics calculation for API generated waypoints.
@db11 Yes. The Workaround of jbm should work. You can use the code provided by @ka1 as reference. He is cycling through the Collection of TCP to choose a âfixedâ TCP for that MoveNode. The term âfixedâ just means that you select a certain TCP in the MoveNode instead of creating the MoveNode with âActiveTCPâ where PolyScope will use the chosen active tcp.