ros-controls / gazebo_ros2_control

Wrappers, tools and additional API's for using ros2_control with Gazebo Classic
Apache License 2.0
195 stars 125 forks source link

Thoughts on supporting position and velocity PID control with Gazebo API #133

Open ksotebeer opened 2 years ago

ksotebeer commented 2 years ago

Hello! I saw some discussion about position and velocity PID control being removed from gazebo_ros2_control. I’m assuming this was to consolidate control logic in ros2_controllers effort_controllers/joint_position_controller and effort_controllers/joint_velocity_control?

The issue I’m running into is that using position or velocity interface with gazebo_ros2_control results in kinematic teleportation rather than simulated physics to move the joints. My guess is that the recommended solution is to use the effort controllers mentioned above (once they are ported to ros2_controllers).

However, I’m curious to hear what people think about adding support in gazebo_ros2_control to push the control logic to the simulation by using Gazebo’s JointController class in the GazeboSystem::write method? The advantage to this is that from an application level, it allows a direct swap between simulation and physical hardware by simply loading a different hardware interface plugin.

In my experience it is common to have motor controllers with position and velocity command interfaces so the ros2_controllers I typically use are joint_trajectory_controller (with position and/or velocity command interface), position_controllers/joint_group_position_controller, and velocity_controllers/joint_group_velocity_controller. By pushing the control logic to Gazebo, it would more directly mirror the physical hardware where joint-level control is handled by the motor controllers instead of at the robot application level. Then I could keep using the same ros2 controllers between simulation and hardware instead of having a ros2 control effort controller just for simulation.

Thoughts?

christophfroehlich commented 1 year ago

It took me a while to realize what you describe as "kinematic teleportation", see https://github.com/ros-controls/gazebo_ros2_control/pull/172 :smile:

What you propose makes sense to me and is the way that velocity interface is implemented with, e.g., Isaac Sim. Also, the position interface of gz_ros2_control has a proportional gain using velocity interface then, but I'm not sure if there happens still the "kinematic teleportation" from the velocity command.

I had the same problem as you describe (velocity-controlled real hardware). I solved this by creating a fork of gazebo_ros2_control::GazeboSystem implementing a PID controller from the control_toolbox in combination with the simulation of actuator dynamics (hydraulics in my case). How did you solve it in the end?

ksotebeer commented 1 year ago

I'm glad you deciphered "kinematic teleportation" :laughing: . I think I actually found that phrase in the Gazebo API docs and I kind of like it.

I also made a fork and implemented PID control in GazeboSystem at first. But eventually I actually ended up writing a separate Gazebo plugin to take the place of gazebo_ros2_control. My plugin just subscribes to joint position and velocity command topics then uses Gazebo's JointController class as described to move the joints.

What ultimately led me to writing a new plugin was that I didn't love how gazebo_ros2_control creates the controller manager and controller nodes for you from the urdf and yaml files. I preferred to start those nodes separately in a launch file so I could pass additional arguments and parameters to them. Looks like there's an issue for this here: https://github.com/ros-controls/gazebo_ros2_control/issues/70. I didn't try to tackle it because it seemed like some pretty big changes that would be difficult to keep backwards compatibility.

christophfroehlich commented 1 year ago

I don't know why gazebo_ros2_control was designed like this, I'll ask and comment on #70

If you'd like to create a PR with your velocity-controlled joints, I'm happy to review 😉