Force_mode, bouncing at contact!

I found that someone else got same issue as me, so I will link to that post.

We are working on peg-in-hole task, which involves holding a rigid object in the gripper and applying specific force on the surface where peg should be inserted. We experience the issue of bouncing as well.
When contact is made with the surface of the board/ hole the gripper jumps in the opposite direction instead of applying specified wrench.

  1. We did zero_ftsensor() before initiating force mode
  2. We did convert wrenches to appropriate (world frame) for the reading.
  3. force_mode_set_damping(damping) - increasing damping helps but doesnt solve the issue
  4. force_mode_set_gain_scaling(scaling)

From searching through the forum it seems to be an issue with how force_mode is implemented. Other users and I have been experiencing issues with that function, and it would be good to know if mine/ our usage of function is not correct or maybe it is implementation of force_mode itself.
I would appreciate if someone from the UR team could provide some insight regarding this topic.
@ajp

Hey @RobotNoob,

You have these two script functions at your disposal which might help deal with overshoot:

force_mode_set_damping(damping)
force_mode_set_gain_scaling(scaling)

Thank you @ajp ,
I forgot to add that I have tried those as well :smile:
They do help with the bouncing/ oscillation, especially if I increase damping but doesn’t resolve the issue.
From the linked post it seems like its force_mode limitation of some sort, and user decided to implement his own force_mode

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.

Assuming nothing can be done on the UR side to solve that issue, do you have any suggestion how would I go about implementing force_mode myself using the mentioned method?

I’m not sure if anything can be done to improve the behaviour of the force control command in that scenario.

To make your own version you could take the result of get_tcp_force() and use that as a scaled parameter for a speedl() command… adjusting the direction of movement based on the forces you are encountering. Start with just the linear Z direction first and then add in other DOF as required.

Does that make sense? In the other thread Tom said he was able to get decent results with proportional scaling alone without PID.

To make your own version you could take the result of get_tcp_force() and use that as a scaled parameter for a speedl() command… adjusting the direction of movement based on the forces you are encountering. Start with just the linear Z direction first and then add in other DOF as required.

@ajp
Could you elaborate a bit about implementation of such controller?
So far I have been using force_mode in the following way

  1. Calculate reference trajectory (position, orientation, velocity and angular velocity)
  2. Obtain current pose/ velocity etc.
  3. Calculate error: delta=desired-current
  4. force = P(delta_position) + D(delta_velocity) and moment = P(delta_orient) + D(delta_ang_vel)
  5. wrench = [force, momen]
  6. Apply wrench via force_mode

How do you suggest to implement the mentioned controller?

Also… isnt speedl() a blocking command?
From what I know servoj() and force_mode() allow for reading and sending a continues stream of values which allows for real time control, but I am not sure speedl() allows for that?

Hi @RobotNoob , sorry for big delay on following up on this. You can set the timeout for speedl to 0.002 so it will behave similarly to servoj. Did you make any progress on this? I would do something similar to what you have listed out in the steps above, but instead of commanding the force directly, you could adjust the position and monitory the change in force?