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

MoveJ(..., blocking=False) queues all poses for execution by robot

#1
I am trying to get a robot arm to dynamically follow an object that I have the position of at a fairly high rate (125 Hz). However, when I call MoveJ(..., blocking=False) at 125 Hz, it seems to queue the positions in the robot and falls behind almost immediately.

Is there a way to call MoveJ(..., blocking=False) where all previous actions are discarded and it simply focuses on executing the current action?
#2
I'm trying to do the same thing, move the robot using data from a Kinect sensor or LeapMotion. If a C# solution works for you, I'll send it when I get it working. Async await magic...
#3
That would be very helpful! If I get it working with Python in the meantime, I'll send you what I have.

So, one thing I did already is to wrap the MoveJ(..., blocking=False) statement in two lines that will measure the elapsed time. When I reduce the rate that I call MoveJ(..., blocking=False) at (e.g., every 50th time instead of every time), I get time elapsed measurements something like:

0.02692437171936035
0.02892446517944336
0.02849864959716797
0.030916213989257812
0.03730583190917969
0.032895565032958984
0.03286123275756836
0.033863067626953125
0.04114723205566406
0.0465848445892334
0.020911693572998047

So, on average, 33 milliseconds.

However, when I call MoveJ(..., blocking=False) at the desired rate (in my case, 125 Hz), the numbers seem to go up quite a bit:

0.05566143989562988
0.03397536277770996
0.052632808685302734
0.03386187553405762
0.03390979766845703
0.0668799877166748
0.03586983680725098
0.04915642738342285
0.04779958724975586
0.046747446060180664
0.05224156379699707
0.04627823829650879
0.0688173770904541
0.04802346229553223
0.05086350440979004
0.031949520111083984
0.031914710998535156
0.05627083778381348

So, on average, 47 milliseconds.

This could be because my computer is unable to keep up...? The code I am timing is simply Fanuc_2_Pose(...) and MoveJ(..., blocking=False).

In fact, this actually seems to indicate what at least one of the problems is... At 125 Hz, this code needs to be executed in 8 ms or less in order to keep up. But, it takes more time than that.

On the flip side, if all the positions weren't queued in the robot controller, then I think it would matter less because it would simply execute the latest, latent command I give it.

You may want to time your code as well.

The next step I will try is to use RTDE instead of RoboDK to control the robot and see if that makes a difference:

https://www.universal-robots.com/article...tde-guide/
https://pypi.org/project/ur-rtde/
#4
Those rates seem pretty good, the api is just a socket communication between your python/c#/c++ program and robodk so there's overhead there but windows does a pretty good job at reducing that. The other overhead comes from robodk communicating with the robot, we use the RTDE interface in our driver for UR so you may be disappointed by the performance gains of any language changes or communicating directly with the robot.

The update rate also depends on the robot as you observed, asking the robot to move less often causes it to respond faster as the robot seems to queue the positions sent to it. This exact behavior is depends a lot on the exact robot and driver your using, the robot has acceleration and speed limits in addition to protocol overhead that might be causing it to not move fast enough. If your only reading the position of the robot and not asking it to move you can get better much better performance but 30ms is about the best you'll be able to get with the UR driver when moving.
#5
Phillip, thank you for your input!

After further thought, I agree that the rates aren't the reason for the problem I'm observing.

When you say, "as the robot seems to queue the positions sent to it", are you aware of a way to make the robot not queue the positions? My preference is that the robot simply follows the latest command I give it and get rid of anything else that preceded the latest command in the queue.

I realize this may be atypical operation, but it seems like it should be possible...
#6
Hey guys, here's what I have so far. I created 2 threads, one for getting pose data from TouchDesigner via OSC and pushing it into a ConcurrentStack (thread safe LIFO in C#) and one for popping the data out of the stack and sending it to RoboDK with the option of clearing the stack after each pop. That way I can ensure that the robot only gets the latest data and ignores the rest.
In simulation mode everything works fine:
https://youtu.be/V2APL5nr6I8
The slight delay is due to filtering applied in TouchDesigner.

The problem, however, is with the communication with the actual robot (Kuka KR250 with KRC2 Cabinet).
What happens is that it takes roughly 30ms for the OSC thread to update the stack (which corresponds to 30FPS), but somewhere around 300ms to 400ms for the robot communication to take place. This happens when I send a constant pose. When I make changes to the pose and the robot has to actually perform a movement I get longer times and there is no continuity between the positions. I assume this is an issue on the driver side that I'm failing to properly configure. Here's a sketch of what happens:
https://photos.app.goo.gl/YRryYAAQHh3CXwoA8
#7
I implemented something very similar, except in Python, and got very similar results. I am using a UR5.

In my case, the latency is around 400 ms.

I updated my UR5 to the latest software and the latency has not changed.

To be honest, I'm not sure it's a driver issue. It seems nobody has focused on solving this problem yet.

I'm wondering if the latencies would be reduced if instead of using MoveJ(...), that the joint angles for the robot arm are calculated on the PC we're running the programs on, then we use setJoints(...) and MoveJ(...) instead.
  




Users browsing this thread:
2 Guest(s)