ros-controls / gz_ros2_control

Connect the latest version of Gazebo with ros2_control.
https://gazebosim.org
Apache License 2.0
109 stars 83 forks source link

/odom is not published in diff_drive_example.launch.py #50

Open Kotochleb opened 2 years ago

Kotochleb commented 2 years ago

Environment

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.

destogl commented 2 years ago

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?

Kotochleb commented 2 years ago

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.

Michael-Liao commented 1 year ago

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

TatsukiNishimura commented 1 year ago

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

fantalukas commented 1 year ago

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

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:

image

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.

mbharatheesha commented 1 year ago

@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:

  1. odom tf/topic consistently get published if I set use_sim_time: True in the yaml files.
  2. 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, odom tf and topic may or may not get published.
  3. With the above fix as well, odom tf and topic publishing is also flaky with them being published sometimes and sometimes not.
  4. More consistent publication of odom tf and topic happens if I first create a subscriber to the odom tf using tf_echo fi, and then unpause the simulation. With this sequence, I see the odom tf 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.

Daviesss commented 1 year ago

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.

Daviesss commented 1 year ago

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.