ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

How to retrieve the desired.velocities from JointTrajectoryController

asked 2022-01-12 09:48:43 -0600

willemstuijt gravatar image

updated 2022-01-13 08:14:36 -0600

I am trying to connect my robot with actuators. I am using MoveIt and ros_control. My controller is of type position_controllers/JointTrajectoryController. My actuators need velocities. If I check the "/joint_controller/state" topic I can see 3 different types of values: desired, actual and error.

When I issue a trajectory, the desired joint values for position, velocity and acceleration are automatically computed. So from this I assumed that I could simply use these computed desired velocities to command my actuators. So I implemented my own hardware interface with a JointStateInterface, PositionJointInterface and VelocityJointInterface.

In the read/write loop of the hardware interface I see that if I change the position array registered with the JointStateInterface the "actual.positions" value in the "/joint_controller/state" topic changes accordingly, so that works well.

If I read the position_cmd array registered with the PositionJointInterface I see that it corresponds to the "desired.positions" value in the "/joint_controller/state" topic, so that also works as I expected.

But when I read the velocity_cmd array registered with the VelocityJointInterface, all the values are always 0. I thought I could read the "desired.velocities" value from this interface but it seems I was wrong. I guess it has something to do with how I am using position_controllers, but then where are these "desired.velocities" coming from? How are they being calculated and how can I make use of them within my hardware interface? I know I could simply subscribe to the "/joint_controller/state" topic and access the "desired.velocities" value from there but that doesn't feel like the right way of doing this.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2022-01-13 08:12:34 -0600

Mike Scheutzow gravatar image

You seem to misunderstand how hardware_interface::RobotHW is designed to work. With ros_control, the user chooses one of many different JointControllers to sit on top of the RobotHW software layer. A "position_controller" will write a position goal to RobotHW, a "velocity_controller" will write a velocity goal to RobotHW, etc. The RobotHW layer gets to choose which types of JointControllers it wants to support.

For RobotHW, in the typical case, the "write a command goal" and the "read joint state from sensor" parts of the code are completely independent of each other. The standard higher-level software layers of ros_control will send commands down to RobotHW to resolve any error between the joint goal and the current joint state; the author of RobotHW is not responsible for handling this.

But when I try to access the desired values only the position_cmd gets updated on my hardware interface,

This is expected since you have a position_controller sitting on top of RobotHW.

edit flag offensive delete link more

Comments

1

In addition to what Mike writes here, I noticed this:

My actuators need velocities

if that's the case, then I'm wondering why any position interfaces have been registered -- unless the actuators support both position and velocity control modes. If the latter, the type of controller would indeed determine which type of actuation signals your RobotHW will receive.

Note that there is also support for PosVelJointInterface, which would be used for joints which require both a position and a velocity.

And to clarify:

My controller is of type position_controllers/JointTrajectoryController.

this is a JointTrajectoryController which outputs position commands.

The velocity_controllers/JointTrajectoryController is the same JointTrajectoryController, but this one only outputs velocity commands.

(and for completeness: there is also a pos_vel_controllers variant, and some closed-loop versions)

gvdhoorn gravatar image gvdhoorn  ( 2022-01-13 08:18:24 -0600 )edit

Yes I also think I misunderstand how hardware_interface works. I think the documentation is not really beginner friendly. Anyways.

I also thought I was just going to get position commands since I was just using position_controllers. What confuses me the most is the values I get from "desired.velocities" in the controller state topic. ros_control seems to be calculating some desired velocities. Where are these velocities coming from? And how do I access these?

I updated my question a little bit to provide better context.

willemstuijt gravatar image willemstuijt  ( 2022-01-13 08:20:03 -0600 )edit

@gvdhoorn I thought MoveIt was only meant to be used with position_controllers/JointTrajectoryController. I tried getting velocity controllers to work with MoveIt but I was unable to.

willemstuijt gravatar image willemstuijt  ( 2022-01-13 08:21:52 -0600 )edit
1

I also thought I was just going to get position commands since I was just using position_controllers.

well, you are, aren't you? You write yourself:

If I read the position_cmd array registered with the PositionJointInterface I see that it corresponds to the "desired.positions" value in the "/joint_controller/state" topic

The values you find in the state topic are for debugging only. They provide insight into internal state of the JointTrajectoryController. The 'type' of the controller determines what it will output to your hw iface.

if you register both position and velocity interfaces, you can run either position or velocity based controllers on top of your hw iface. But position controllers are not going to give you velocity commands (as you already observed).

If in fact, you only require / support velocity commands, remove the position interface from your hw iface, and load the velocity_controllers/JointTrajectoryController.

gvdhoorn gravatar image gvdhoorn  ( 2022-01-13 08:24:26 -0600 )edit

I thought MoveIt was only meant to be used with position_controllers/JointTrajectoryController. I tried getting velocity controllers to work with MoveIt but I was unable to.

MoveIt is not involved here.

MoveIt controllers != ros_control controllers.

All variants of the JointTrajectoryController expose a FollowJointTrajectoryAction interface, which is what MoveIt can use.

Changing your ros_control configuration does not need updates on the MoveIt side (in this case).

I tried getting velocity controllers to work with MoveIt but I was unable to.

you may be confusing input with output.

MoveIt cannot generate "velocity trajectories" for you, so you cannot use a ros_control controller which only takes velocity input.

MoveIt can generate trajectories with positions for you, so you pass those to a controller which accepts position inputs.

MoveIt doesn't care whether that position controller then outputs positions, velocities or something else.

gvdhoorn gravatar image gvdhoorn  ( 2022-01-13 08:25:58 -0600 )edit

Thanks. I managed to get it working. My head was all over the place with Gazebo, ros_control, MoveIt. I think I finally understand how everything comes together (kind off).

willemstuijt gravatar image willemstuijt  ( 2022-01-13 10:03:09 -0600 )edit

So what was the solution in the end?

gvdhoorn gravatar image gvdhoorn  ( 2022-01-13 10:42:11 -0600 )edit

I switched to velocity_controllers/JointTrajectoryController. I had to make sure to add pid gain values for the controller configuration which the gazebo controller didn't previously need. Embarassingly simple to fix haha. It just confused me why, despite using position_controllers, I could still see desired velocities being calculated. But now I think I understand.

willemstuijt gravatar image willemstuijt  ( 2022-01-13 12:47:59 -0600 )edit

Question Tools

3 followers

Stats

Asked: 2022-01-12 09:22:49 -0600

Seen: 186 times

Last updated: Jan 13 '22