Contoller Spawner and transform problem in RViz

asked 2020-07-17 21:56:01 -0500

moshahin gravatar image

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 ...
(more)
edit retag flag offensive close merge delete

Comments

1

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

Orhan gravatar image Orhan  ( 2020-07-18 18:55:29 -0500 )edit
1

Hi, @moshahin

You may want to load your controllers in the harware_interface, try to instantiate the trasnmission like this:

<transmission name="tran1">
  <type>transmission_interface/SimpleTransmission</type>
  <joint name="joint_1">
    <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
  </joint>
  <actuator name="motor1">
    <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
    <mechanicalReduction>1</mechanicalReduction>
  </actuator>
</transmission>

And remember that you do not need the joint_state_publisher node since you already have the joint_state_controller loaded in ros_control.

Weasfas gravatar image Weasfas  ( 2020-07-19 05:49:27 -0500 )edit

@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 gravatar image moshahin  ( 2020-07-19 15:25:02 -0500 )edit

@moshahin, that is probably because you have a broken tf_tree, you can check this by running rosrun 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 individual ns to each launch nodes you may use the group tag to be sure all that you need is in the same namespace.

Weasfas gravatar image Weasfas  ( 2020-07-20 05:12:07 -0500 )edit

@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 the robot_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 gravatar image moshahin  ( 2020-07-20 11:19:20 -0500 )edit

@moshahin Glad I helped you but remember that if your tf_tree is fine you just need to set the Rviz fixed_frame to odom/world/map frame or whatever frame you have in which you reflect the platform movement.

Weasfas gravatar image Weasfas  ( 2020-07-20 14:25:50 -0500 )edit

@Weasfas In the launch file I posted, I created a static transform /world that the base_link is connected to. I made sure to set the fixed_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:

<include file="$(find gazebo_ros)/launch/empty_world.launch">

Do I need to connect the Gazebo world to Rviz so that the robot can move around?

moshahin gravatar image moshahin  ( 2020-07-20 14:35:09 -0500 )edit

Ok, to be more precise. The standard mobile robot tf frames should be:

World->Map->Odom->Base_footprint->Base_link

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 your base_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.

Weasfas gravatar image Weasfas  ( 2020-07-20 15:17:01 -0500 )edit