# Choosing the right controller

**URL:** <https://forum.universal-robots.com/t/choosing-the-right-controller/12389>\
**Category:** ROS\
**Created:** [February 17, 2021, 6:55pm UTC](https://forum.universal-robots.com/t/choosing-the-right-controller/12389 "2021-02-17T18:55:09Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![CaptainYoshi](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.universal-robots.com/captainyoshi/32/2396_2.png) [@CaptainYoshi](https://forum.universal-robots.com/u/CaptainYoshi)\
**Post date:** [February 17, 2021, 6:55pm UTC](https://forum.universal-robots.com/t/choosing-the-right-controller/12389/1 "2021-02-17T18:55:09Z")

</div>

These questions are related to ros\_controllers represented in the [ur3\_controllers.yaml](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/blob/master/ur_robot_driver/config/ur3_controllers.yaml) file. Specifically the `pos_joint_traj_controller`, `vel_joint_traj_controller` and `joint_group_vel_controller`.

In the first part I ask questions about the 3 controllers separatly. This is also to validated my comprehension of the controllers. In the last section, I ask a question about the difference between 2 controllers.

### position\_controllers/JointTrajectoryController

Per the joint\_trajectory\_controller [wiki](http://wiki.ros.org/joint_trajectory_controller#Controller_configuration_examples): For position-controlled joints, desired positions are simply forwarded to the joints.

Does this mean that this is just a feedforward controller (open-loop) from **ros\_control** perspective?

At the lower level, the servoj command is used which will do a little bit of interpolation ([comment](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/issues/279#issuecomment-707854515)). There is also a proportionnal gain for following target position (taken from the [URScript API Referrence](https://s3-eu-west-1.amazonaws.com/ur-support-site/18679/scriptmanual_en.pdf)).

So basically this controller is a joint trajectory controller with a P feedback loop where the loop closure is done with the internal UR controller, not with ros\_control framework?

### velocity\_controllers/JointTrajectoryController

Per the joint\_trajectory\_controller [wiki](http://wiki.ros.org/joint_trajectory_controller#Controller_configuration_examples): while for velocity (effort) joints, the position+velocity trajectory following error is mapped to velocity (effort) commands through a PID loop

> This is a joint trajectory controller which outputs velocities to reach a position ([comment](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/issues/206#issuecomment-693224121))

Is the servoj command used? If so the only valuable information used is the position. So the the robot is controlled via position.

Is this a feedforward + PID external feedback controller (image from the [free reprint](http://hades.mech.northwestern.edu/images/2/25/MR-v2.pdf) of Modern Robotics p.421) aimed for velocity inputs but is derived to feed positions instead? There would also be an internal P feedback loop from the servoj command.

 ![Untitled](https://us1.discourse-cdn.com/flex020/uploads/universal_robots/original/2X/b/b7a80b3e2ce8d5dff132f13e58c97227ca545cd2.png)

### velocity\_controllers/JointGroupVelocityController

> This is a forwarding-controller which takes in velocity setpoints and simply forwards it to the robot controller. ([comment](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/issues/206#issuecomment-693224121))

This simply forwards the velocity inputs through the speedj command as a feedforward controller. It is up to the person to close the loop to achieve what they want (Ex. to create an admittance controller).

### pos\_joint\_traj\_controller VS vel\_joint\_traj\_controller

What is the difference between these 2 controllers. Is one of them suppose to make trajectories smoother?

---

<div class="post-metadata">

**Author:** ![anon41625651](https://avatars.discourse-cdn.com/v4/letter/a/df788c/32.png) [@anon41625651](https://forum.universal-robots.com/u/anon41625651)\
**Post date:** [March 5, 2021, 3:41pm UTC](https://forum.universal-robots.com/t/choosing-the-right-controller/12389/2 "2021-03-05T15:41:00Z")

</div>

I am interested in this as well!

---

<div class="post-metadata">

**Author:** ![mauch](https://avatars.discourse-cdn.com/v4/letter/m/71e660/32.png) [@mauch](https://forum.universal-robots.com/u/mauch)\
**Post date:** [March 7, 2021, 9:46am UTC](https://forum.universal-robots.com/t/choosing-the-right-controller/12389/3 "2021-03-07T09:46:59Z")

</div>

I’ll try to explain things a bit further…

First of all, the driver supports both, commanding positions or velocities.

In case of positions a `servoj` command will be used [here](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/blob/master/ur_robot_driver/resources/ros_control.urscript#L43) where the servoj target will be updated by the ROS side.

In case of velocity commands, [`speedj` is used](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/blob/master/ur_robot_driver/resources/ros_control.urscript#L86) to set the robot’s joint speeds directly.

As `servoj` does an interpolation between the current state and the target command, it is a bit slower than `speedj` which (as far as I know) directly copies the setpoint into the target velocity in the next control cycle. For details, please see [this comment](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/pull/1#issuecomment-549894865)

Ontop if those interfaces, different ROS controllers can be started. As ROS-Control is designed in a way that all position- based controllers work as soon as a position interface is available and all velocity-based controllers will work with any velocity interface (given, we’re talking about joint space), there are loads of controllers available for the ROS driver.

As both, `servoj` and `speedj` as far as I know perform a low-level control (In case of `servoj` it is a bit more, including interpolation as mentioned in the OP), ROS-Control basically sits outside this inner control mechanism.

The **position-based JointTrajectoryController** of ROS-Control is indeed an open-loop controller. Position commands are forwarded to the hardware interface and the deviation is measured inside the controller’s feedback. If the path deviation gets too large, the action sent to the controller will simply fail, there won’t be any corrections.

This is one reason why we created the _scaled_ versions of controllers that will take the speed scaling done on the robot controller into account. Apart from that, they are identical to the normal, non-scaled versions.

In case of the **velocity-based JointTrajectoryController** there is a closed loop structure to reach the target setpoints using a PID controller. PID values inside the driver are currently not optimized as discussed in [#124](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/issues/124) and [#119](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/issues/119).

The JointGroupControllers indeed only do command-forwarding directly to the joints, so they are similar to writing the respective `servoj` or `speedj` commands into URScript directly.

> **pos\_joint\_traj\_controller VS vel\_joint\_traj\_controller**
> 
> What is the difference between these 2 controllers. Is one of them suppose to make trajectories smoother?

As mentioned above, the differences are:

- open-loop position commands vs. closed loop velocity commands on ROS side
- `servoj` vs. `speedj` implementation on URScript side

With the velocity-based implementation you might get a more responsive and maybe smoother trajectory execution, but I cannot guarantee that the default PID values will provide the best solution. Basically, with velocity control you move more of the actual control to the ROS side. You will loose one control cycle (2ms in case of an e-series robot) and an unknown (at least to me) amount of time to the control structure underneath.

I hope that this clarifies a lot of things, ideally we would get a document out of this, that we can add to the driver’s documentation. But I think, this would need some more elaboration. Please let me know, if there is anything unclear.

---

<div class="post-metadata">

**Author:** ![CaptainYoshi](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.universal-robots.com/captainyoshi/32/2396_2.png) [@CaptainYoshi](https://forum.universal-robots.com/u/CaptainYoshi)\
**Post date:** [March 19, 2021, 5:09pm UTC](https://forum.universal-robots.com/t/choosing-the-right-controller/12389/4 "2021-03-19T17:09:47Z")

</div>

Thank you for your great explanation!

Does the `speedj` implementation compensates for gravity with the payload mass and COG?

> I hope that this clarifies a lot of things, ideally we would get a document out of this, that we can add to the driver’s documentation.

That would be awesome!

---

<div class="post-metadata">

**Author:** ![mauch](https://avatars.discourse-cdn.com/v4/letter/m/71e660/32.png) [@mauch](https://forum.universal-robots.com/u/mauch)\
**Post date:** [March 21, 2021, 7:51pm UTC](https://forum.universal-robots.com/t/choosing-the-right-controller/12389/5 "2021-03-21T19:51:31Z")

</div>

> [@CaptainYoshi](#):
>
> Does the `speedj` implementation compensates for gravity with the payload mass and COG?

I would assume, it does, as it is controlling a joint speed. If the speed gets higher due to gravity pulling a joint down, currents should be reduced to achieve the desired velocity. But that’s just my understanding, as I don’t know the internals of `speedj`.

---

<div class="post-metadata">

**Author:** ![anon33549707](https://avatars.discourse-cdn.com/v4/letter/a/9fc348/32.png) [@anon33549707](https://forum.universal-robots.com/u/anon33549707)\
**Post date:** [May 13, 2021, 8:39am UTC](https://forum.universal-robots.com/t/choosing-the-right-controller/12389/6 "2021-05-13T08:39:10Z")

</div>

Hi,I have two questions.

I want to use the **vel\_joint\_traj\_controllerr** to control ur5 constant motion (the end link keep one speed).I send a string points with constant vel but i cannot get constant motion. what can i do, i need change the pid values or …?

I try use the joint\_group\_vel\_controller to control ur5 constant motion,but when i start this control,the ur5 urdf model falls in gazebo. I can not solve this problem

I need your help, thank you very much！

---

<div class="post-metadata">

**Author:** ![mauch](https://avatars.discourse-cdn.com/v4/letter/m/71e660/32.png) [@mauch](https://forum.universal-robots.com/u/mauch)\
**Post date:** [May 13, 2021, 2:47pm UTC](https://forum.universal-robots.com/t/choosing-the-right-controller/12389/7 "2021-05-13T14:47:30Z")

</div>

> [@anon33549707](#):
>
> h！

Answered inside [Ur5 constant motion](https://forum.universal-robots.com/t/ur5-constant-motion/14305)
