Thank you for your suggestions.
Our aim is to use simulation to train a machine learning agent and then apply the results to a real robot. We would like to avoid changing the stiffness parameters as this could create discrepancies between the simulated and real robot.
During my experimentation, I adjusted the articulation controller gain and was able to decrease the positional error slightly, from 1.1mm to 0.33mm, by multiplying the gain by a factor of 6. However, higher gain values resulted in strange robot behavior.
articulation_controller = my_robot.get_articulation_controller()
bad_proportional_gains = articulation_controller.get_gains()*6
articulation_controller.set_gains(kps = bad_proportional_gains)
I was not happy with these results and therefore implemented a PID controller to compensate the target position error:
Here are the parameters I used for the controller:
# parameters for position controller
self.pos_controller_error_sum = np.array([0.0, 0.0, 0.0])
self.pos_controller_last_error = np.array([0.0, 0.0, 0.0])
self.pos_controller_windup_limit = np.array([0.05, 0.05, 0.05])
self.pos_controller_Kp = np.array([0.1, 0.1, 0.1])
self.pos_controller_Ki = np.array([0.05, 0.05, 0.05])
self.pos_controller_Kd = np.array([0.05, 0.05, 0.05])
And this is the controller:
def pid_controller(self, target_pos, current_position):
Kp = self.pos_controller_Kp
Ki = self.pos_controller_Ki
Kd = self.pos_controller_Kd
windup_limit = self.pos_controller_windup_limit
error = target_pos - current_position
error_rate = error - self.pos_controller_last_error
self.pos_controller_error_sum += error
# Anti-windup: Limit the integrator sum
self.pos_controller_error_sum = np.clip(self.pos_controller_error_sum, a_max=windup_limit, a_min=-windup_limit)
controller_offset = Kp * error + Ki * self.pos_controller_error_sum + Kd * error_rate
self.pos_controller_last_error = error
Integrating a controller into the individual robot joint drives would likely yield the best results. The ability to add a PID controller to joint drives would also be an interesting feature for Omniverse, since many actuators (in the real world) have integrated controllers.