UR10e Robots Twitching/Oscillating in Gazebo Immediately After Launch

Problem Description

I’m simulating two UR10e robots in Gazebo using PositionJointInterface and the JointTrajectoryController. The robots exhibit severe twitching and oscillation immediately after launching the simulation environment, even without any commanded motion. The robots are unstable at their initial configuration and continuously vibrate/shake. I was using EffortJointInterface earlier, but never encountered this problem.

Setup

ROS Environment: Gazebo simulation

Robots: 2x UR10e with separate namespaces

Control Interface: hardware_interface/PositionJointInterface

Controller: position_controllers/JointTrajectoryController

Spawn Configuration: One robot at origin (0, 0, 0), second at (1.3, 0, 0)

Configuration Details

URDF Transmission (per joint):

<transmission name="shoulder_pan_trans">
    <type>transmission_interface/SimpleTransmission</type>
    <joint name="shoulder_pan_joint">
         <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
    </joint>
    <actuator name="shoulder_pan_motor">
        <mechanicalReduction>1</mechanicalReduction>
        <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
    </actuator>
</transmission>

Controller YAML File

joint_state_controller:
type: joint_state_controller/JointStateController
publish_rate: &loop_hz 125  

pos_joint_traj_controller:
type: position_controllers/JointTrajectoryController
joints: &robot_joints
  - shoulder_pan_joint
  - shoulder_lift_joint
  - elbow_joint
  - wrist_1_joint
  - wrist_2_joint
  - wrist_3_joint

constraints:
  goal_time: 2.0  
  stopped_velocity_tolerance: 0.02  
  shoulder_pan_joint: {trajectory: 0.2, goal: 0.05}
  shoulder_lift_joint: {trajectory: 0.2, goal: 0.05}
  elbow_joint: {trajectory: 0.2, goal: 0.05}
  wrist_1_joint: {trajectory: 0.2, goal: 0.05}
  wrist_2_joint: {trajectory: 0.2, goal: 0.05}
  wrist_3_joint: {trajectory: 0.2, goal: 0.05}

stop_trajectory_duration: 0.5
state_publish_rate: *loop_hz
action_monitor_rate: 20

joint_group_pos_controller:
type: position_controllers/JointGroupPositionController
joints: *robot_joints

gazebo_ros_control:
pid_gains:
  shoulder_pan_joint:  {p: 15000, i: 50,  d: 500, i_clamp: 50}
  shoulder_lift_joint: {p: 15000, i: 50,  d: 500, i_clamp: 50}
  elbow_joint:         {p: 8000,  i: 30,  d: 300, i_clamp: 50}
  wrist_1_joint:       {p: 300,   i: 5,   d: 10,  i_clamp: 10}
  wrist_2_joint:       {p: 300,   i: 5,   d: 10,  i_clamp: 10}
  wrist_3_joint:       {p: 50,    i: 1,   d: 5,   i_clamp: 5}

Gazebo Plugin:

<gazebo>
    <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
        <robotNamespace>$(arg robot_name)</robotNamespace>
    </plugin>
</gazebo>

Launch Configuration:

  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="paused" value="$(arg paused)"/>
    <arg name="use_sim_time" value="$(arg use_sim_time)"/>
    <arg name="gui" value="$(arg gui)"/>
    <arg name="headless" value="$(arg headless)"/>
    <arg name="debug" value="$(arg debug)"/>
  </include>

Observed Issues

Immediate oscillation: Robots start twitching/vibrating as soon as Gazebo loads

No commanded motion: Issue occurs before any commands are sent to controllers

Continuous instability: Oscillation persists indefinitely at initial pose

Both robots affected: Issue occurs on both robot instances independently

Visual shaking: Links visibly shake and jitter in the Gazebo GUI

What I’ve Tried

Adjusted PID gains extensively (reduced P, increased D, adjusted I and i_clamp)

Reduced controller publish rate (500Hz → 125Hz)

Questions

Are my PID gains appropriate for UR10e position control in Gazebo?

Is there a known issue with PositionJointInterface stability at startup?

Should controllers be initialized with a specific hold position command?

Could this be related to Gazebo physics parameters (timestep, solver iterations)?

Is there a controller “warm-up” or initialization procedure I’m missing?

Additional Information

Controllers load successfully (confirmed via rosservice list and controller_manager)

No error messages in console or Gazebo logs

Any insights or suggestions would be greatly appreciated!