Force mode bounces on contact with rigid body


I’m currently running a very simple program on a UR10e, where the robot placed in force mode and instructed to apply 10N in the base frame x-axis. The robot has a screwdriver attachment on the end of the flange, pointing straight out and aligned with the base frame x-axis. The robot is positioned so that when the script runs, the tool collides with a rigid body (a thick piece of wood held firmly in a vice).

In force mode, I would expect the robot to move until it collides with the block, where it would settle at a position where the block is applying the required 10N of normal force. However, upon the collision, the tool slowly bounces on and off the block. I have played back the positions of the robot and forces recorded by the force transducer (recorded using the python ur_rtde module, accessed via RTDEReceiveInterface.getActualTCPForce() ), and it has shown that the robot moves into the block beyond a normal force of 10N, and then retreats back to a normal force much less than 10N, and continues to oscillate in this way as it overcompensates in each direction.

Is there a solution for this? Increasing the force damping coefficient helps slightly, but does not eradicate the problem, even after many “damped” oscillations. It feels as if the force mode control loop is just not running fast enough.

Thank you

Edit: For reference also, I have set the tool weight and COG to be correct for the attachment, and zero the force transducers at the beginning of the script.

Are you using the force template in polyscope or the force_mode() script function? Can you supply the example of whichever it is? Also have you tried reducing the speed limit?

Hi bba,
Thank you for the response. I am using the RTDEControllerInterface.forceMode() function in the ur_rtde python module, which maps to the force_mode() script function. Here is my code:

force_frame = np.zeros(6) # Use base frame
frame_type = 2

# Allow only translations, with maximum speed of 0.2m/s and angular drift of 0.1rad
compliance = np.array([1, 1, 1, 0, 0, 0], dtype=int)
limits = np.array([0,.2, 0.2, 0.2, 0.1, 0.1, 0.1])

applied_force = 10
wrench = applied_force * np.array([-1, 0, 0, 0, 0, 0])
self.slave_ctrl.forceMode(force_frame.tolist(), compliance.tolist(), wrench.tolist(), frame_type, limits.tolist())
while True:
    time.sleep(1)  # Just waiting for ^C

I have tried reducing the speed limit, down to 0.05m/s, and to no avail.

If you “NEED” 10N of force you might have to find another way, maybe play with the payload / COG.

I use force mode a lot (the template inside polyscope) to hold parts in down in a vise while it closes. My experience has been very random. What works today may not work next month when I run the same program with the same parts.

Biggest thing that helps me is playing with the level of force. Try 5N or try 15N and see if the amount of bouncing changes. You should be able to dial it in from there if you notice a difference.

As an aside, the Force mode is pretty reliable when you get it dialed in correctly. It will never have the feel of a human hand but I’ve been able to get the 'bots here to do some pretty complicated loads.

I ended up just writing my own force mode, using the TCP forces and speedL command. Now it responds nicely and is very stable - I imagine that UR designed a force mode that worked generally well but just performed poorly in my specific context (low forces applied to very rigid bodies). I recommend this approach to anybody experiencing a similar issue, takes a little tuning to get right but in the end I managed it without even using PID control, just proportional scaling of TCP force to applied velocity.

Thanks all for the suggestions.

1 Like

Haven’t used force mode yet, but what if you did a DIRECTION MoveL until contact, then applied the 10N force?

I’ve tried that in my applications. Not sure I can explain this accurately but the bouncing is not created from the TCP making contact with whatever surface then recoiling from the inertia.

It’s how the logic interprets the values as movements.

If the payload or speed or force is not correct the robot will undulate slowly trying to keep moving forward but getting to a certain point and having to stop pushing in that direction and moving away.

The result is the appearance of lowly bouncing.

I’m not saying you don’t get a dead-cat-bounce if you hit the surface, but that bouncing will only last a second. The bouncing we experience using force is perpetual.

very good to know! Thanks for sharing.

I am about a week away from programming my first ‘Force’ Application

On top of fuknrekd’s comment, moveL just isn’t great for real time control of the robots - it’s more designed for path following. MoveL includes acceleration out of and deceleration into waypoints that makes the robot very jittery if you try to stream it a series of nearby moveL commands (as you would in this appication). SpeedL provides much smoother motion at higher update rates