Contoller Spawner and transform problem in RViz
I am building my own 4WD model and I am trying to implement 4 velocity controllers (one for each motor). The issue arises when I execute my launch file (which contains the controller_spawner node), the transforms between the base_link and the 4 wheels are non-existent. I have tried the joint_state_publisher node with the GUI (instead of the controller_spawner) and it works. However when I implement the controller_spawner node, the transforms disappear. I have made sure to download all necessary packages for ros_control. I have used the ros_control plugin in my URDF and even made sure the namespaces are all correct in the YAML, URDF and launch file. Every time I execute the launch file, I get the error: "Controller Spawner couldn't find the expected controller_manager ROS interface."
Then I get the error within Rviz that there are no transforms between the base_link and the wheels. When I run rospack list | grep control I get:
control_msgs /opt/ros/melodic/share/control_msgs
control_toolbox /opt/ros/melodic/share/control_toolbox
controller_interface /opt/ros/melodic/share/controller_interface
controller_manager /opt/ros/melodic/share/controller_manager
controller_manager_msgs /opt/ros/melodic/share/controller_manager_msgs
diff_drive_controller /opt/ros/melodic/share/diff_drive_controller
effort_controllers /opt/ros/melodic/share/effort_controllers
force_torque_sensor_controller /opt/ros/melodic/share/force_torque_sensor_controller
forward_command_controller /opt/ros/melodic/share/forward_command_controller
gazebo_ros_control /opt/ros/melodic/share/gazebo_ros_control
gripper_action_controller /opt/ros/melodic/share/gripper_action_controller
imu_sensor_controller /opt/ros/melodic/share/imu_sensor_controller
joint_state_controller /opt/ros/melodic/share/joint_state_controller
joint_trajectory_controller /opt/ros/melodic/share/joint_trajectory_controller
position_controllers /opt/ros/melodic/share/position_controllers
velocity_controllers /opt/ros/melodic/share/velocity_controllers
My launch file is:
<launch>
<!--Load the URDF file -->
<param name="robot_description" command="cat $(find monsterborg_description)/urdf/monsterborg.urdf"/>
<!-- Launch the robot_state_publisher to broadcast transforms to '/tf' -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen">
<!-- remap from="/joint_states" to="/monsterborg/joint_states"/-->
</node>
<!-- Load the configuration of the joint controllers -->
<rosparam file='$(find monsterborg_description)/config/monsterborg_controllers.yaml' command='load'/>
<!-- Load the joint controllers -->
<node name='controller_spawner' pkg='controller_manager' type='spawner' respawn='false' output='screen' ns='/monsterborg'
args='rf_wheel_velocity_controller rb_wheel_velocity_controller lf_wheel_velocity_controller lb_wheel_velocity_controller joint_state_controller'/>
<!-- Loads the 'world' static frame -->
<node pkg='tf' type='static_transform_publisher' name='world_frame' args='0 0 0 0 0 0 /world /base_link 100'/>
<!-- Open Rviz with specific configuration -->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find monsterborg_description)/rviz_config/monsterborg.rviz"/>
</launch>
My YAML:
monsterborg:
joint_state_controller:
type: joint_state_controller/JointStateController
publish_rate: 50
rf_wheel_velocity_controller:
type: effort_controllers/JointVelocityController
joint: base_to_rf_wheel
pid: {p: 1.0, i: 1.0, d: 1.0}
lf_wheel_velocity_controller:
type: effort_controllers/JointVelocityController
joint: base_to_lf_wheel
pid: {p: 1.0, i: 1.0, d: 1.0}
rb_wheel_velocity_controller:
type: effort_controllers/JointVelocityController
joint: base_to_rb_wheel
pid: {p: 1.0, i: 1.0, d: 1.0}
lb_wheel_velocity_controller:
type: effort_controllers/JointVelocityController
joint: base_to_lb_wheel
pid: {p: 1.0, i: 1.0, d: 1.0}
Here is a small snippet of the URDF file for the base_link, one wheel and motor:
<robot name="monsterborg">
<link name="base_link">
<visual>
<origin xyz="0 0 0 ...
Yes you have to spawn the robot and controllers must be up and running first before checking anything in Rviz. Also don't forget to set fixed frame in rviz to the correct one
Hi, @moshahin
You may want to load your controllers in the harware_interface, try to instantiate the trasnmission like this:
And remember that you do not need the
joint_state_publisher
node since you already have thejoint_state_controller
loaded inros_control
.@Orhan thank you, that seemed to do the trick! @Weasfas thank you for your response. With regards to the joint_state_publisher, when I don't include the joint_state_publisher in the launch file, Rviz can't find the transform between the base_link and the wheels. What seems to be the problem there? Could this be why the model moves in Gazebo but not in Rviz?
@moshahin, that is probably because you have a broken
tf_tree
, you can check this by runningrosrun rqt_tf_tree rqt_tf_tree
. If that is the case, it means that, either your description is not being parsed correctly with respect its joints or that the ROS controller interface is unable to find the joint in its namespace. To be more precise I will need to look on your full description. Finally I will recommend you to, instead of adding individualns
to each launch nodes you may use the group tag to be sure all that you need is in the same namespace.@Weasfas I figured out why the
tf_tree
was broken. I wasn't aware that the gazebo node published to the topic/monsterborg/joint_states
and the whole time therobot_state_publisher
node was subscribing to the topic/joint_states
. All I had to do was uncomment the remapping in the launch file,remap from="/joint_states" to="/monsterborg/joint_states
,which I originally commented as I thought it was only a remapping done for convenience rather then necessity. Now the model is simulated in both Rviz and Gazebo however, the model moves around in Gazebo while in Rviz it moves on the spot. The coordinate frames of the wheels are moving in Rviz but the model itself is stationary (If that makes sense). I'm going to try figure out how to simulate complete movement from Gazebo to Rviz as I need that for navigation purposes. Once again thank you for your help!@moshahin Glad I helped you but remember that if your
tf_tree
is fine you just need to set the Rvizfixed_frame
toodom
/world
/map
frame or whatever frame you have in which you reflect the platform movement.@Weasfas In the launch file I posted, I created a static transform
/world
that thebase_link
is connected to. I made sure to set thefixed_frame
as/world
but the same thing happened. Has it maybe something to do with the fact that when I created a launch file (other than the one posted) to spawn the model in gazebo I have included:Do I need to connect the Gazebo world to Rviz so that the robot can move around?
Ok, to be more precise. The standard mobile robot tf frames should be:
I think the fact that the robot is not moving in Rviz but Gazebo is because you are not publishing a tf between your odom and the
base_link
/base_footprint
. The only thing that rviz does is reading from the/tf
topic and compute the relative position of each link with respect the fixed frame; but if you are only publishing a static transform Rviz does not know if the robot moved so what you need is something to publish the tf between yourbase_link
/base_footprint
and your robot odometry to reflect that the robot is moving.You can check odom tf broadcaster here. But that can be done with multiple tools like
AMCL
,robot_localization
or even a model plugin since you are working with Gazebo.