gz_ros2_control
gz_ros2_control copied to clipboard
/odom is not published in diff_drive_example.launch.py
Environment
- OS Version: Ubuntu 20.04 (osrf/ros:galactic-desktop docker)
- Source build
- Branch
galactic - Ignition Fortress
Description
I've adapted this package to my URDF and so far, publishing /cmd_vel and feedback from /joint_states and /tf is working. On the other hand, for some reason, /odom is not being published by ros2 control even though the same config for a diff_drive_controller is working on a real hardware.
To ensure that, the problem is not related only to my configuration, I checked examples and the same thing happens in diff_drive_example.launch.py while running inside docker also from examples. Basically, publishing odometry does not work, no matter if the URDF from examples is or isn't modified. I am confused since from what I understand, if joint_state_broadcaster has data to publish diff_drive_controller should as well.
Is this behavior only inside docker or also on a native machine? I didn't get that from your comment.
Does /odom topic simply doesn't exist when using simulation?
This behavior was present inside the Docker. I assumed, if it is happening purely within docker without Ignition on the host machine, it should behave the same way everywhere.
I tried to once again recreate the behavior, and it still does not work.
You can try it by adding this compose to the Dockerfile directory in the repository and running it with docker compose up.
services:
gz_ros2_control_test:
build: .
environment:
- DISPLAY
- QT_X11_NO_MITSHM=1
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
command: ros2 launch ign_ros2_control_demos diff_drive_example.launch.py gui:=true
As a /odom topic, I really meant /diff_drive_base_controller/odom. It does exist, but it is empty.
The simulation is reacting to messages on /diff_drive_base_controller/cmd_vel_unstamped and TFs seem to be correct in the Rviz2.
The issue started with the controller not running on osrf/ros:galactic-desktop image, but currently I tested it on humble using your example Dockerfile.
I am experiencing the same issue. Still couldn't find what is wrong though.
I'm using Ubuntu 22.04 with docker image osrf/ros:humble-desktop-full-jammy with extra packages.
The humble branch does not work with my setup but the master branch can successfully load the controllers with /joint_states and /tf working properly but /<controller_name>/odom is empty
I use gazebo 11 and I was experiencing the same issue when I run diff_drive.lauch in gazebo_ros2_control_demos.
Then I set use_sim_time parameter of /controller_manager node to true when it starts up.
set_contoller_manager_use_sim_time = ExecuteProcess(
cmd=['ros2', 'param', 'set', '/controller_manager', 'use_sim_time', 'true'],
output='screen')
return LaunchDescription([
RegisterEventHandler(
event_handler=OnProcessExit(
target_action=spawn_entity,
on_exit=[load_joint_state_controller,
set_contoller_manager_use_sim_time
],
)
),
Then, /odomtopic and /tf between /odom and /base_link starts to publish data.
My environment
- Ubuntu 20.04
- ROS2 galactic
- gazebo 11
- not using docker
I was facing the same issue and tried solution proposed by @TatsukiNishimura.
And I agree with @TatsukiNishimura by setting use_sim_time parameter to true, the controller diff_drive_base_controller start publishing odometry (topic /diff_drive_base_controller/odom) together with transformation (topic /tf) between /odom and /base_link. BUT diff_drive_base_controller controller stops reacting on cmd_vel data (topic /diff_drive_base_controller/cmd_vel_unstamped).
So either odometry together with tf is published BUT robot does not react on cmd_vel command in gazebo ignition simulation by setting use_sim_time parameter of diff_drive_base_controller to true OR odometry together with tf is NOT published BUT robot reacts on cmd_vel command in gazebo ignition simulation by setting use_sim_time parameter of diff_drive_base_controller to false.
My environment
- Ubuntu 22.04
- ROS2 rolling
- gazebo ignition 6 (fortress version)
- not using docker
Additional notes: how to set use_sim time in a different way:
Parameter use_sim_time can be set simply in corresponding yaml file. Here in diff drive controller example it would be in diff_drive_controller_velocity.yaml file by adding use_sim_time:=True into ros__parameters of diff_drive_base_controller and controller_manager
Additional problem with gazebo ignition:
I was facing a problem connected to process of setting use_sim_time parameter of controller manager.
When I set use_sim_time to True in controller_manager I got sometimes (NOT always) segmentation fault:
[ign gazebo-1] [INFO] [1668597588.440030931] [controller_manager]: Loading controller 'joint_state_broadcaster'
[ign gazebo-1] [INFO] [1668597588.451786885] [controller_manager]: Setting use_sim_time=True for joint_state_broadcaster to match controller manager (see ros2_control#325 for details)
[ign gazebo-1] terminate called after throwing an instance of 'std::system_error'
[ign gazebo-1] what(): Invalid argument
I temporarily fixed the problem by setting use_sim_time to True only in diff_drive_base_controller like this:

When the controller_manager has the parameter use_sim_time set to False, the segmentation fault in gazebo ignition did not occur at all.
BUT I think that all components related to ros2 control (/controller_manager, /robot_state_publisher, /diff_drive_base_controller and /joint_state_broadcaster) and gazebo ignition plugin (/ignition_ros_control) should have use_sim_time parameter set to True during simulation.
@fantalukas I think so too that use_sim_time should consistently be set to True for all components used when using Gazebo plugin.
It seems the necessary fix to make sure /controller_manager has use_sim_time set to True when using the plugin has been fixed on master. See here. I am not sure if this change (along with renaming ign to gz) will be backported to humble. Because, the recently released ros-humble-ign-ros2-control seems to use the sources from release tag 0.4.3 which uses ign and does not have the aforementioned fix for controller_manager.
With the above fix included, I can confirm that, /controller_manager starts with use_sim_time set to True. However, /gz_ros_control still has use_sim_time set to False. In the tests I did, I found out the following behaviors:
odomtf/topic consistently get published if I setuse_sim_time: Truein the yaml files.- Without the above fix, if I use
ros2 param set /controller_manager use_sim_time 'true'before unpausing the Gazebo simulation, the behavior is flaky, as in,odomtf and topic may or may not get published. - With the above fix as well,
odomtf and topic publishing is also flaky with them being published sometimes and sometimes not. - More consistent publication of
odomtf and topic happens if I first create a subscriber to theodomtf usingtf_echofi, and then unpause the simulation. With this sequence, I see theodomtf and topic getting published 8/10 times.
Note that in all the above scenarios, use_sim_time parameter for the /gz_ros_control node remains False. Changing that True with ros2 param set doesn't improve the consistency.
I also have this issue when simulating my robot . The problem is i can see the topic /odom , but when i echo the topic .I see nothing displaying.
I also have this issue when simulating my robot . The problem is i can see the topic /odom , but when i echo the topic .I see nothing displaying.
I was able to get this solved , for some reason my robot tf wasn't well aligned. The odom topic was missing. But once i get my laser_frame attached to the tf tree ..I was able to echo the "odom" topic.