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.
Originally posted by Mike Scheutzow with karma: 4903 on 2022-01-13
This answer was ACCEPTED on the original site
Post score: 2
Original comments
Comment by gvdhoorn on 2022-01-13:
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)
Comment by willemstuijt on 2022-01-13:
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.
Comment by willemstuijt on 2022-01-13:
@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.
Comment by gvdhoorn on 2022-01-13:\
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
.
Comment by gvdhoorn on 2022-01-13:\
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.
Comment by willemstuijt on 2022-01-13:
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).
Comment by gvdhoorn on 2022-01-13:
So what was the solution in the end?
Comment by willemstuijt on 2022-01-13:
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.