Hi Florent. I just went through something similar wanting to rotate around a Z Axis in a specific direction until Wrist3 reached a position. My first attempts showed that Move commands appear to always be shortest-path (as mentioned above). --Leland (placing signature here since this post is a bit long)
The solution is to use a “direct drive” command. UR currently has two:
- speedl(), which directly drives linear motion and rotation
- speedj(), which directly drives joints.
The commands above are only accessible in a script instruction (line or file, but they don’t appear in the Polyscope “Function” list). A single-line script instruction works well for this in Polyscope.
I put a test program together that makes the motion you’re looking for, although the current study is in BaseFRAME. I’m working on a ToolfRAME solution but am posting my initial results here so you can follow the progression. The ToolFRAME solution might be a bit complex (like taking a snapshot of the TCP, converting that into a FeaturePOINT or FeaturePLANE, and then using that as the FRAME for the speedl() solution posted here; this is fine as long as it works but something simpler is better). I’ll report back in once I have some results using the ToolFRAME.
Lines in bold are the core speedn() logic. Note that I use a thread to continuously monitor the arm’s position in both joint and cartesian space. This allows the “Loop Until” condition to operate.
Indents in this forum platform are squirrelly and HTML strips out multiple spaces and multiple ellipses (…), so I had to create home-made indents.
InitRBT is a folder.
:Robot Program
–Wait: 0.004
----InitRBT
----…Wait: 0.01
----…Call ZeroJ6
----…MoveJ
----…-…Perch
–Loop
–Loop ActvCPOS[2] > 0.350
–…speedl([0,0,-0.250,0,0,20],2,10)
–Call ZeroJ6
–MoveL
–…Perch
:ZeroJ6
–TgtJPOS≔get_joint_positions()
–TgtJPOS[5]=d2r(0)
–MoveJ
–…TgtJPOS
:Thread_1
–Wait: 0.001
–…ActvJPOS≔get_target_joint_positions()
–…ActvCPOS≔get_actual_tcp_pose()
This solution is based on a comprehensive answer to a slightly different question HERE: (Move (JOG) along Base or Tool axis - #2 by ajp).
Some usage notes plus the entry from the UScript manual:
- The [xyz, Rxyz] argument is a vector array/list. It MUST be enclosed in square brackets. If you get an error saying that speedl or speedj “only take 4 arguments”, then you’ve left out the square brackets.
- You have to nest the speedn() command in a loop.
- condition the loop on your stop condition, such as having traveled a certain distance in Z (you’ll need to add code to compare your start position and to your stop position).
- You MUST check “Check expression contunually” on the Loop instruction configuration page. The loop will execute up to the first speedn() instruction and the “Loop while” condition breaks execution out of the loop at that first speedn() instruction. Nothing in the loop after the first speedn() will execute.
- Much of the “non-core” code is for convenience in testing, making the robot reset itself automatically and return to the start point.
===============
USCRIPT MANUAL
speedl(xd, a, t, aRot=’a’)
[Controls Tool speed]
DESCRIPTION: Accelerate linearly in Cartesian space and continue with constant tool speed. The time ‘t’ is optional; if provided the function will return after time ‘t’, regardless of the target speed has been reached. If the time ‘t’ is not provided, the function will return when the target speed is reached.
PARAMETERS
xd: tool speed [xyz (m/s), Rxyz (rad/sec)] (spatial vector)
a: tool position acceleration [m/s^2]
t: time [s] before function returns (optional)
aRot: tool acceleration [rad/s^2] (optional), if not defined
a, position acceleration, is used
EXAMPLE COMMAND: speedl([0.5,0.4,0,1.57,0,0], 0.5, 0.5)
EXAMPLE PARAMETERS:
– xd → Tool speeds of: x=500 mm/s, y=400 mm/s, rx=90 deg/s, Ry and Rz=0 mm/s
– a = 0.5 rad/s^2 → acceleration of the leading axis (shoulder is this case)
– t = 0.5 s → time before the function returns