Discussion - Ros2_Control Overview & Simulation (Making a Mobile Robot Pt 12)

Try:

ros2 run controller_manager spawner -h

ros2 run controller_manager spawner diff_cont

No .py

Hi Josh,

@Josh: As many have said, much thanks for your great tutorials on ROS!

Iā€™m building a robot based on your Articubot robot using 2 motors and a (ultrasound) sonar sensor (HCSR04). I am able to control the motors and drive around. But Iā€™m stuck on how to correctly integrate the sonar sensor into ROS.

Iā€™ve integrated the sonar sensor in joshnewans/ros_arduino_bridge example exposing distance information via the serial interface (via a ā€œhā€ command, the distance as reported by the sonar sensor is returned)

Now Iā€™m trying to create a hardware interface that publishes this sonar distance information in a ROS Topic sensor_msg/Range message. I followed the tutorial ā€˜12. Solving the problem EVERY robot has (with ros2_control)ā€™ and concluded that I need to create another State Interface (see https://articulatedrobotics.xyz/media/assets/posts/mobile-robot/12-ros2-control/controllers.png)

I tried to update joshnewans/diffdrive_arduino example to publishing the sensor_msg/Range message in diffdrive_arduino.cpp. But I am unable to do this since I cannot access ROS publish functions. Also reading further on the concepts of ROS, it seems not the correct way to do since diffdrive_arduino is for controlling the diff drive motors and NOT exposing a sonar sensor.

Then I tried to create another node that reads the serial information and publishes the Range message. But then I have the problem that you cannot use 1 serial interface by 2 nodes that each run as separate process.

So my question is:
How do you create 2 controllers exposing 2 hardware_interfaces (System & Sensor) that uses the same serial interface? Is there a way to share 1 serial inteface between ROS nodes?

Regards,

Huub

Hi Josh,
At first, your tutorials are helping in a great course for my career and thanks for your tutorials.

I am trying to understand this ros2_control thing. but I am having the following issue when I am trying to load the controllers. btw I am using ros2-humble distro.

nisat@nt:~/mangobee_robot$ ros2 run controller_manager spawner diff_cont
[INFO] [1706769460.539068927] [spawner_diff_cont]: Waiting for '/controller_manager' node to exist
[INFO] [1706769462.551452191] [spawner_diff_cont]: Waiting for '/controller_manager' node to exist
[INFO] [1706769464.564305671] [spawner_diff_cont]: Waiting for '/controller_manager' node to exist
[INFO] [1706769466.575603025] [spawner_diff_cont]: Waiting for '/controller_manager' node to exist
[ERROR] [1706769468.585726734] [spawner_diff_cont]: Controller manager not available
[ros2run]: Process exited with failure 1

my_controllers.yaml file as follows:

controller_manager:
  ros__parameters:
    update_rate: 30
    use_sim_time: true

    diff_cont:
      type: diff_drive_controller/DiffDriveController
    
    joint_broad:
      type: joint_state_broadcaster/JointStateBroadcaster

diff_cont:
  ros__parameters:

    publish_rate: 100.0 
    base_frame_id: base_link

    left_wheel_names: ['left_wheel_joint']
    right_wheel_names: ['right_wheel_joint']
    wheel_separation: 0.35
    wheel_radius: 0.05

    use_stamped_vel: false

ros2_control.xacro file as follows,

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">

    <ros2_control name="GazeboSystem" type="system">
        <hardware>
            <plugin>gazebo_ros2_control/GazeboSystem</plugin>
        </hardware>

        <joint name="left_wheel_joint">
            <command_interface name="velocity">
                <param name="min">-10</param>
                <param name="max">10</param>
            </command_interface>
            <state_interface name="position" />
            <state_interface name="velocity" />
        </joint>

        <joint name="right_wheel_joint">
            <command_interface name="velocity">
                <param name="min">-10</param>
                <param name="max">10</param>
            </command_interface>
            <state_interface name="velocity" />
            <state_interface name="position" />
        </joint>

        <gazebo>
            <plugin filename="libgazebo_ros2_control.so" name="gazebo_ros2_control">
                <parameters>$(find Mangobee_DifferentialDriveWheel_Robot)/config/my_controllers.yaml</parameters>
            </plugin>
        </gazebo>

    </ros2_control>

</robot>

Please help me solve this issue.

Thank you
Nisath

I am using ros2 iron and have ā€œContorller manager not availableā€ errors. To make sure its not something I did, I downloaded articubot_one and it has the same issue.

First i fixed the .py issue to get this far:

diff_drive_spawner = Node(
        package="controller_manager",
        executable="spawner",
        arguments=["diff_cont"],
    )

    joint_broad_spawner = Node(
        package="controller_manager",
        executable="spawner",
        arguments=["joint_broad"],
    )

Now when I enter
ros2 launch articubot_one launch_sim.launch.py world:=./src/my_bot/worlds/obstacles.world

Looks like I get two errors:

[ERROR] [gzserver-4]: process has died [pid 35946, exit code 255, cmd 'gzserver ./src/my_bot/worlds/obstacles.world -slibgazebo_ros_init.so -slibgazebo_ros_factory.so -slibgazebo_ros_force_system.so --ros-args --params-file /home/willi/shared/dev_ws/install/articubot_one/share/articubot_one/config/gazebo_params.yaml'].

Either the result or the real problem is the following:

[spawn_entity.py-4] [INFO] [1706795144.454419682] [spawn_entity]: Waiting for entity xml on robot_description
[spawn_entity.py-4] [INFO] [1706795144.465585204] [spawn_entity]: Waiting for service /spawn_entity, timeout = 30
[spawn_entity.py-4] [INFO] [1706795144.465941557] [spawn_entity]: Waiting for service /spawn_entity
[spawner-6] [INFO] [1706795146.204682358] [spawner_joint_broad]: Waiting for '/controller_manager' node to exist
[spawner-5] [INFO] [1706795146.405621127] [spawner_diff_cont]: Waiting for '/controller_manager' node to exist
[spawner-6] [INFO] [1706795148.218729921] [spawner_joint_broad]: Waiting for '/controller_manager' node to exist
[spawner-5] [INFO] [1706795148.418687173] [spawner_diff_cont]: Waiting for '/controller_manager' node to exist
[spawner-6] [INFO] [1706795150.234781109] [spawner_joint_broad]: Waiting for '/controller_manager' node to exist
[spawner-5] [INFO] [1706795150.429329085] [spawner_diff_cont]: Waiting for '/controller_manager' node to exist
[spawner-6] [INFO] [1706795152.248062370] [spawner_joint_broad]: Waiting for '/controller_manager' node to exist
[spawner-5] [INFO] [1706795152.447229883] [spawner_diff_cont]: Waiting for '/controller_manager' node to exist
[spawner-6] [ERROR] [1706795154.261474129] [spawner_joint_broad]: Controller manager not available
[spawner-5] [ERROR] [1706795154.459666959] [spawner_diff_cont]: Controller manager not available
[ERROR] [spawner-6]: process has died [pid 34051, exit code 1, cmd '/opt/ros/iron/lib/controller_manager/spawner joint_broad --ros-args'].
[ERROR] [spawner-5]: process has died [pid 34042, exit code 1, cmd '/opt/ros/iron/lib/controller_manager/spawner diff_cont --ros-args'].
[spawn_entity.py-4] [ERROR] [1706795174.516724938] [spawn_entity]: Service %s/spawn_entity unavailable. Was Gazebo started with GazeboRosFactory?
[spawn_entity.py-4] [ERROR] [1706795174.517468743] [spawn_entity]: Spawn service failed. Exiting.

help

Soā€¦ I couldnā€™t get past this error smurffin the innernut yielded notta. I then blew my package away and downloaded joshes to the same resultā€¦ I then download an unrelated Ros2 to package from some other unrelated github and YIKES SAME sameā€¦ Then I completely removed ros2-iron and installed ros2-humble and now everything is fine. It all works as specified. There is some issue/change in iron

Hi Ziad, I am facing the same issue. Did you find the solution?

how would you solve this issue please explain clearly

you can solve this issues, how would you solve this issue please explain clearly

Hi @JoshNewans
Thank you so much for the hardwork.
I have been following and developing a physical robot as well.
I am facing an issue that:
When I shifted to ros2 control, the robot is driving in the opposite direction (in the Gazebo simulation), but when I was working with Gazebo diff_drive, it was running perfectly fine. Can anyone please guide me? I have been struggling with this for 2 days now.
I checked your response to another similar question, so I have similarly used the axis orientations for the wheels, it works good with joint_state_publisher and when working with gazebo_diff_drive, but when I use ros2 control, the wheels rotate inversely.

Can you please shed some light?
Thank you so much!
Thank you

Hi @JoshNewans: I ran into the same underscore problem and had to troubleshoot it too. But you should know the error is actually your code. Please refer to the page https://articulatedrobotics.xyz/tutorials/mobile-robot/applications/ros2_control-concepts#controller-config. and search for ā€œros_parametersā€. Thanks for all the great work you do!

To change ā€œl298ā€ to ā€œbts,7960bā€ what modifications are needed in the code?

I donā€™t know if itā€™s the same issue. I was having the same error message: ā€œCould not contact service /controller_manager/list_hardware_interfaces.ā€

After some troubleshooting, I found that there was a mistake in my ros2_control.xacro file:

I had put the <gazebo> tag with its plugin inside the <ros2_control> tag when it needed to be placed separately.

@JoshNewans Hello Josh. Thank you for all these tutorials. You may be aware of the issue where the controller_manager is apparently not available. Specifically, the output when launching is this:

[INFO] [launch]: All log files can be found below /home/flamethrower/.ros/log/2024-08-04-18-35-28-656714-robot-3619
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [robot_state_publisher-1]: process started with pid [3621]
[INFO] [gzserver-2]: process started with pid [3623]
[INFO] [gzclient   -3]: process started with pid [3625]
[INFO] [spawn_entity.py-4]: process started with pid [3628]
[INFO] [spawner.py-5]: process started with pid [3631]
[INFO] [spawner.py-6]: process started with pid [3633]
[robot_state_publisher-1] Parsing robot urdf xml string.
[robot_state_publisher-1] Link FL_wheel had 0 children
[robot_state_publisher-1] Link FR_wheel had 0 children
[robot_state_publisher-1] Link RL_wheel had 0 children
[robot_state_publisher-1] Link RR_wheel had 0 children
[robot_state_publisher-1] Link chassis had 1 children
[robot_state_publisher-1] Link laser_frame had 0 children
[robot_state_publisher-1] [INFO] [1722789331.093667060] [robot_state_publisher]: got segment FL_wheel
[robot_state_publisher-1] [INFO] [1722789331.098568099] [robot_state_publisher]: got segment FR_wheel
[robot_state_publisher-1] [INFO] [1722789331.098785080] [robot_state_publisher]: got segment RL_wheel
[robot_state_publisher-1] [INFO] [1722789331.098873561] [robot_state_publisher]: got segment RR_wheel
[robot_state_publisher-1] [INFO] [1722789331.098906653] [robot_state_publisher]: got segment base_link
[robot_state_publisher-1] [INFO] [1722789331.098934339] [robot_state_publisher]: got segment chassis
[robot_state_publisher-1] [INFO] [1722789331.098960764] [robot_state_publisher]: got segment laser_frame
[spawner.py-5] [INFO] [1722789332.642764464] [spawner_diff_cont]: Waiting for /controller_manager services
[spawner.py-6] [INFO] [1722789332.753680821] [spawner_joint_broad]: Waiting for /controller_manager services
[spawn_entity.py-4] [INFO] [1722789333.814943066] [spawn_entity]: Spawn Entity started
[spawn_entity.py-4] [INFO] [1722789333.817251300] [spawn_entity]: Loading entity published on topic robot_description
[spawn_entity.py-4] [INFO] [1722789333.824613498] [spawn_entity]: Waiting for entity xml on robot_description
[spawn_entity.py-4] [INFO] [1722789333.840584852] [spawn_entity]: Waiting for service /spawn_entity, timeout = 30
[spawn_entity.py-4] [INFO] [1722789333.842771012] [spawn_entity]: Waiting for service /spawn_entity
[spawner.py-5] [INFO] [1722789334.688257733] [spawner_diff_cont]: Waiting for /controller_manager services
[spawner.py-6] [INFO] [1722789334.793537609] [spawner_joint_broad]: Waiting for /controller_manager services
[spawner.py-5] [INFO] [1722789336.754853755] [spawner_diff_cont]: Waiting for /controller_manager services
[spawner.py-6] [INFO] [1722789336.890463941] [spawner_joint_broad]: Waiting for /controller_manager services
[spawner.py-5] [INFO] [1722789338.799318653] [spawner_diff_cont]: Waiting for /controller_manager services
[spawner.py-6] [INFO] [1722789338.942930759] [spawner_joint_broad]: Waiting for /controller_manager services
[spawn_entity.py-4] [INFO] [1722789339.373300524] [spawn_entity]: Calling service /spawn_entity
[spawn_entity.py-4] [INFO] [1722789340.397202490] [spawn_entity]: Spawn status: SpawnEntity: Successfully spawned entity [robot]
[gzserver-2] [WARN] [1722789340.508036852] [rcl]: Found remap rule '~/out:=scan'. This syntax is deprecated. Use '--ros-args --remap ~/out:=scan' instead.
[gzserver-2] [WARN] [1722789340.586504745] [rcl]: Found remap rule '~/out:=scan'. This syntax is deprecated. Use '--ros-args --remap ~/out:=scan' instead.
[INFO] [spawn_entity.py-4]: process has finished cleanly [pid 3628]
[gzserver-2] [INFO] [1722789340.836605840] [gazebo_ros2_control]: Loading gazebo_ros2_control plugin
[gzserver-2] [INFO] [1722789340.856579331] [gazebo_ros2_control]: Starting gazebo_ros2_control plugin in namespace: /
[gzserver-2] [INFO] [1722789340.860006190] [gazebo_ros2_control]: Starting gazebo_ros2_control plugin in ros 2 node: gazebo_ros2_control
[gzserver-2] [INFO] [1722789340.860619318] [gazebo_ros2_control]: Loading parameter files /home/flamethrower/robot_ws/install/robot/share/robot/config/my_controllers.yaml
[spawner.py-5] [INFO] [1722789340.877581837] [spawner_diff_cont]: Waiting for /controller_manager services
[gzserver-2] [INFO] [1722789340.884953905] [gazebo_ros2_control]: connected to service!! robot_state_publisher
[gzserver-2] [INFO] [1722789340.893442322] [gazebo_ros2_control]: Recieved urdf from param server, parsing...
[gzserver-2] [INFO] [1722789340.948132774] [gazebo_ros2_control]: Loading joint: FL_wheel_joint
[gzserver-2] [INFO] [1722789340.948472162] [gazebo_ros2_control]:   State:
[gzserver-2] [INFO] [1722789340.948567995] [gazebo_ros2_control]:        velocity
[gzserver-2] [INFO] [1722789340.948771920] [gazebo_ros2_control]:        position
[gzserver-2] [INFO] [1722789340.948853605] [gazebo_ros2_control]:   Command:
[gzserver-2] [INFO] [1722789340.948888198] [gazebo_ros2_control]:        velocity
[gzserver-2] [INFO] [1722789340.949095438] [gazebo_ros2_control]: Loading joint: FR_wheel_joint
[gzserver-2] [INFO] [1722789340.949171771] [gazebo_ros2_control]:   State:
[gzserver-2] [INFO] [1722789340.949207993] [gazebo_ros2_control]:        velocity
[gzserver-2] [INFO] [1722789340.949243345] [gazebo_ros2_control]:        position
[gzserver-2] [INFO] [1722789340.949275752] [gazebo_ros2_control]:   Command:
[gzserver-2] [INFO] [1722789340.949304863] [gazebo_ros2_control]:        velocity
[gzserver-2] [INFO] [1722789340.949344659] [gazebo_ros2_control]: Loading joint: RL_wheel_joint
[gzserver-2] [INFO] [1722789340.949382381] [gazebo_ros2_control]:   State:
[gzserver-2] [INFO] [1722789340.949414789] [gazebo_ros2_control]:        velocity
[gzserver-2] [INFO] [1722789340.949445659] [gazebo_ros2_control]:        position
[gzserver-2] [INFO] [1722789340.949479307] [gazebo_ros2_control]:   Command:
[gzserver-2] [INFO] [1722789340.949507511] [gazebo_ros2_control]:        velocity
[gzserver-2] [INFO] [1722789340.949543029] [gazebo_ros2_control]: Loading joint: RR_wheel_joint
[gzserver-2] [INFO] [1722789340.949577140] [gazebo_ros2_control]:   State:
[gzserver-2] [INFO] [1722789340.949608121] [gazebo_ros2_control]:        velocity
[gzserver-2] [INFO] [1722789340.949638640] [gazebo_ros2_control]:        position
[gzserver-2] [INFO] [1722789340.949670269] [gazebo_ros2_control]:   Command:
[gzserver-2] [INFO] [1722789340.949699621] [gazebo_ros2_control]:        velocity
[gzserver-2] [INFO] [1722789340.951049691] [gazebo_ros2_control]: Loading controller_manager
[gzserver-2] terminate called after throwing an instance of 'std::system_error'
[gzserver-2]   what():  Invalid argument
[gzserver-2] Aborted (core dumped)
[ERROR] [gzserver-2]: process has died [pid 3623, exit code 134, cmd 'gzserver                                                                       -s libgazebo_ros_init.so   -s libgazebo_ros_factory.so   -s libgazebo_ros_force_system.so       '].

I have tested this by downloading the project folder off of GitHub and the error persists. Iā€™m pretty sure Iā€™ve downloaded all of the necessary packages, so what might be the problem here? Thanks in advance.

What ROS2 distro are you using?

Also, there seam to be an issue with starting the controller manager