ros-mobile-robots / diffbot

DiffBot is an autonomous 2wd differential drive robot using ROS Noetic on a Raspberry Pi 4 B. With its SLAMTEC Lidar and the ROS Control hardware interface it's capable of navigating in an environment using the ROS Navigation stack and making use of SLAM algorithms to create maps of unknown environments.
https://ros-mobile-robots.com
BSD 3-Clause "New" or "Revised" License
275 stars 82 forks source link

No output for wheel_cmd_velocities? [Question - Closed] #74

Closed Doctor-N0 closed 1 year ago

Doctor-N0 commented 1 year ago

First of all: amazing repo! Absolutely great work!

I was launching the navigation and base via

roslaunch diffbot_base  diffbot.launch
roslaunch diffbot_navigation diffbot.launch

to get a more in-depth understanding of ros_control, specifically the hardware_interface's write function. Luckily, the functions published the diff_drive_controller's output (which it received via the joint_velocitycommands)

When I assign a drive command (e.g. angular velocity), the Gazebo Simulation works perfectly fine and the robot is spinning. However, the /diffbot/wheel_cmd_velocities yield only zero.

As seen in the screenshot below, only zeros are yielded if I run both (which makes sense, since the base is not connected to the cmd velocity, as seen in the node graph)

Screenshot from 2023-02-13 15-10-14

Edit: if I run diffbot_base diffbot.launch (without diffbot_navigation diffbot.launch), I receive the expected output)

Screenshot from 2023-02-13 16-03-07

Therefore, my question: Is it even POSSIBLE to run both, the navigation in gazebo AND the hardware_interface?

fjp commented 1 year ago

Hi @Doctor-N0, the diffbot.launch from diffbot_base package is intended to be used by minimal.launch:

https://github.com/ros-mobile-robots/diffbot/blob/75a24b8d1da33ab600ccac45a713b667797a10ac/diffbot_bringup/launch/minimal.launch#L25-L31

This is used for running the real robot hardware. However usually a user shouldn't have to deal with those launch files from diffbot_base package. Instead you can find the recommended bringup launch files for the real robot hardware in this readme section, the launch files are part of diffbot_bringup package.

Sorry, the documentation here is not up to date. Please refer to the readme usage section in this case.

For simulation (navigation) you just can use this lauch file command:

roslaunch diffbot_navigation diffbot.launch

Or you can also do it with two separate launch commands like it is done for SLAM:

  1. First launch Gazebo

    roslaunch diffbot_gazebo diffbot.launch 
  2. Decide between SLAM or Navigation:

    roslaunch diffbot_slam diffbot_slam.launch slam_method:=gmapping

    In my most recent commit you can now also use navigation instead of slam with this command:

    roslaunch diffbot_navigation diffbot_navigation.launch

Therefore, my question: Is it even POSSIBLE to run both, the navigation in gazebo AND the hardware_interface?

I think it should work and I tried and documented to some extent here: https://ros-mobile-robots.com/packages/diffbot_base/high-level/#simulation but you have to be careful to not launch two different controller managers and then loading the diff_drive_controller and others multiple times. So beware that this is not tested thoroughly and is for sure something that could be improved.

Doctor-N0 commented 1 year ago

Thanks for the detailed answer, that explains a lot!

Regarding Gazebo AND hardware_interface: My aim would be to run both in parallel, whereby in the write() function an OPC-UA connection is called. This way I can control a PLC, which in the first phase will only run virtually on another computer until it is finally transferred to the actual hardware.

If I get additional information concerning this topic, I will post it here.

fjp commented 1 year ago

I would suggest to use RViz instead of "Gazebo AND the real robot hardware". RVIz is to visualize what the robot sees. Gazebo is to simulate your robot if you don't have the real robot hardware or want to do some testing without real hardware. To see the issue in more detail keep this image in mind:

image

For simulation with gazebo, diffbot uses the gazebo_ros_control package that works exclusively with ros control.

In case you try to run both, the real hardware and simulation (gazebo_ros_control package) will interfere with each other, because usually both receive the commands and then try to update the JointStateInterface. Then you would basically be running two diffbot's at the same time (one real, one simulated). So I guess you would have to tell gazebo not to listen to the joint commands and only update the current robot pose using for example the pose that amcl from the navigation package publishes. Or it might be possible to create your own plugin that listens to the joint states and implements the differential drive equations to update the robot pose accordingly. However, it seems not so straight forward to achieve. RViz is probably the right choice to see what the robot is actually doing.

To simulate your PLC, a simple node could do it if you don't need a visualization.

Depending on what you want to achive / which state variables you need, you could also think of adding a new function/class and use/instantiate it in the main of the diffbot base and then call whatever you want periodically in the control loop code (where diffbot.write() is called periodically). If you need some state of the robot joints (e.g joint angles, velocity) you could also think of adding a new node that subscribes to those topics and then sends something to the PLC.

Of course it is also possible to put some logic directly in the write() method of the hardware interface but this method is anyway already doing two things (publishing a wheel_cmd_msg and a motor commands). This is something I plan to refactor as it shouldn't do more than one thing.

Doctor-N0 commented 1 year ago

Thank you very much for this helpful reply. The idea to use rviz instead of gazebo is great. The other points are also very helpful, I will implement it that way. Thanks again!