Discussion - Writing a ros2_control hardware interface (Making a Mobile Robot Pt 20)

Blog post coming

This is the discussion topic for the video and blog post linked above. Please keep all replies relevant to the content, otherwise create a new topic.


Hi there, I’m looking to use this video to help me generate a hardware interface for the Robomaster (DJI) M2006 BLDC + C610 ESC’s that actuate my 3 DOF robotic arm (a ‘simple’ project to help me become more knowledgeable). I already hit a first snag when running colcon build --symlink-install after downloading both example_2 and example_6 from the ros2_control_demos repository. I get a ton of errors including the two below (I figured I’d start there):

  • In file included from /home/ubuntu/ros2_ws/src/example_2/hardware/diffbot_system.cpp:15: /home/ubuntu/ros2_ws/src/example_2/hardware/include/ros2_control_demo_example_2/diffbot_system.hpp:42:23: error: \u2018CallbackReturn\u2019 in namespace \u2018hardware_interface\u2019 does not name a type 42 | hardware_interface::CallbackReturn on_init(
  • /home/ubuntu/ros2_ws/src/example_2/hardware/diffbot_system.cpp: In member function \u2018hardware_interface::return_type ros2_control_demo_example_2::DiffBotSystemHardware::write(const rclcpp::Time&, const rclcpp::Duration&)\u2019: /home/ubuntu/ros2_ws/src/example_2/hardware/diffbot_system.cpp:227:7: error: \u2018info_\u2019 was not declared in this scope 227 | info_.joints[i].name.c_str());

I downloaded from the master branch on GitHub and am trying to build using Foxy in a docker container. I’ll admit that I’m very much NOT knowledgeable about C++, this might be something very silly. Much appreciated if someone can help me get started!

hi, joshnewans. i have issue with encoder dc motor. the two encoders wheels of my robot has different value of counter per second. how can I config ros2 control for each wheel. it is possible?

Hi, this usually means you haven’t installed ros2_control correctly, or haven’t “sourced” it.
Are you building ros2_control as well or just installing it through apt? I’d recommend the latter :slight_smile:

Hi, yeah a few people have raised this and I mentioned it briefly in the video. All you need to do is find where the shared value is used (XML, config struct, parameter reading) and duplicate it, name them appropriately for left/right, and set up the two wheel structs appropriately.
That probably sounds confusing but all in all it’s about 4 lines change.

1 Like

Hi, I installed ros2 control using apt. I ran source ~/ros2_ws/install/setup.bash but that did not improve things. In a Humble docker container I can build without issues. However, I’d like to use Foxy as I’ve haven’t been able to get Gazebo working on Humble on my M1 Mac. Also, when I ros2 launch ros2_control_demo_example_2 diffbot.launch.py on Humble, rviz is all black where the ‘world’ should be. Which is surprising as all other rviz GUI elements display correctly and there are no error messages in the terminal. Does the fact that I can compile on Humble, but not on Foxy trigger any thoughts?

Thanks Joshn for answering me. I followed your instructions . And I successfully colcon build my workplace. But I haven’t tried it in rviz2 yet. I’ll do it tomorrow. Because I’m very sleepy😅

1 Like

Yeah so the humble and foxy branches are different. Right now main is foxy and humble is humble, so make sure you are on the right branch (I should clarify those in the naming, and humble will eventually become the default probably).

Re the rviz thing, is that in the humble docker container? I started having that problem a little while back, there was an update to a system package that broke it. From memory I had to manually downgrade a package to fix it.

I just found a discussion on it [here] (Black Screen on version 11.2.5 · Issue #948 · ros2/rviz · GitHub), check out the last post.

Thanks, I got the demos working in both Foxy and Humble docker containers.

1 Like

Hi @JoshNewans How could i do if i am using Foxy ? i need your instruction .

Hi @JoshNewans,

I have been following your tutorial and tried making a 4wd robot. However after a lot of efforts, was not able to use on 4 wheels and kept it on hold. After this new ros2 control, trying my hands again.

I rewrote the code to control 4 motors. It compiled properly and when I try to run, no movement in the motors. However, mini term works and i am able to control the motors both in open loop and closed loop.

Request if you could check the code and direct me in the right direction.

I have updated to humble and all required plugins are installed.

Under arduino_comms, not sure if i am reading the encoder values correctly in read_encoder_values.

Lastly, is there a way to find out what code is really sent to serial? For example when we use teleop keyboard and press any key, how do we know what output did ros2_control send to serial port?

Best regards,

1 Like

HI team ,
I try to run ros2 launch articubot_one launch_robot.launch.py in humble . it was stuck in the
[INFO] [launch]: All log files can be found below /home/bbt/.ros/log/2023-06-26-09-28-56-513076-bbt-Lenovo-ideapad-330-15IKB-7387
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [robot_state_publisher-1]: process started with pid [7389]
[INFO] [twist_mux-2]: process started with pid [7391]
[twist_mux-2] [INFO] [1687751936.850835990] [twist_mux]: Topic handler ‘topics.joystick’ subscribed to topic ‘cmd_vel_joy’: timeout = 0.500000s , priority = 100.
[twist_mux-2] [INFO] [1687751936.851607150] [twist_mux]: Topic handler ‘topics.navigation’ subscribed to topic ‘cmd_vel’: timeout = 0.500000s , priority = 10.
[twist_mux-2] [INFO] [1687751936.851742080] [twist_mux]: Topic handler ‘topics.tracker’ subscribed to topic ‘cmd_vel_tracker’: timeout = 0.500000s , priority = 20.
[robot_state_publisher-1] [INFO] [1687751936.860714932] [robot_state_publisher]: got segment base_footprint
[robot_state_publisher-1] [INFO] [1687751936.861013227] [robot_state_publisher]: got segment base_link
[robot_state_publisher-1] [INFO] [1687751936.861049009] [robot_state_publisher]: got segment camera_link
[robot_state_publisher-1] [INFO] [1687751936.861069523] [robot_state_publisher]: got segment camera_link_optical
[robot_state_publisher-1] [INFO] [1687751936.861088282] [robot_state_publisher]: got segment caster_wheel
[robot_state_publisher-1] [INFO] [1687751936.861107717] [robot_state_publisher]: got segment chassis
[robot_state_publisher-1] [INFO] [1687751936.861128645] [robot_state_publisher]: got segment face_link
[robot_state_publisher-1] [INFO] [1687751936.861169860] [robot_state_publisher]: got segment laser_frame
[robot_state_publisher-1] [INFO] [1687751936.861196463] [robot_state_publisher]: got segment left_wheel
[robot_state_publisher-1] [INFO] [1687751936.861213810] [robot_state_publisher]: got segment right_wheel

After that no response. i have waited for more than 45 mins.

Hello everyone,

I hope you’re doing well. I have a query regarding the feasibility of controlling DC brushless motors and encoders without using serial communication. Here’s the situation:

I have a robot equipped with two DC brushless motors and two encoders. To drive the motors, I am currently employing an L298N motor driver. However, I would like to explore the possibility of controlling these motors and reading the encoder data without relying on serial communication methods. All of it is connected to a Raspberry Pi 4. I would like to write my custom ros_control, If any of you have prior experience or knowledge in this area, I would be grateful for your guidance. Specifically, I’m interested in exploring options that offer a balance between simplicity and effectiveness in controlling the DC brushless motors and reading encoder data using ROS 2 robot_control.

Thank you in advance for your time and assistance. I look forward to your valuable input and insights.

Hi there , I’m trial to launch diffdrive_arduino my result has some [ ERROR ]

pi@pi-desktop:~/control_ws$ ros2 launch diffdrive_arduino diffbot.launch.py
[INFO] [launch]: All log files can be found below /home/pi/.ros/log/2023-08-05-09-54-27-408669-pi-desktop-4676
[INFO] [launch]: Default logging verbosity is set to INFO
[ERROR] [launch]: Caught exception in launch (see debug for traceback): executed command failed. Command: /home/pi/.local/bin/xacro /home/pi/control_ws/install/diffdrive_arduino/share/diffdrive_arduino/urdf/diffbot.urdf.xacro
Captured stderr output: error: substitution args not supported: cannot import name ‘Log’ from ‘rosgraph_msgs.msg’ (/opt/ros/humble/local/lib/python3.10/dist-packages/rosgraph_msgs/msg/init.py)
when processing file: /home/pi/control_ws/install/diffdrive_arduino/share/diffdrive_arduino/urdf/diffbot.urdf.xacro


Please help, very thank you.

1 Like

@JoshNewans thanks so much for this video, I honestly don’t know how I would do this without your guidance. Detail question:

What are the values to expect from the command interfaces, setting the motor speed? Is there a known integer interval, for example [0, 255]?

If you want to free yourself from serial communication to the microcontroller you should be using, Micro-ROS is probably the answer.

I would consider the Teensy 4.1 on Platformio first, only with the downside of missing (?) hardware debugger.

Micro-ROS comes with its own (long) learning curve though.

Hey @JoshNewans thanks for the amazing video…i have been following your tutorial so far but my encoder readings are not reliable
You said that the encoders aren’t that important in this project

Is it possible to make the project without using an encoder?

And if yes,what are the changes i have to do to make it work?

Thanks in advance :slight_smile:

down load humble. 5 min installation

we using 2 control files:
For what each file is used?

Hi Josh,

I have a weird problem and couldnt figure out the reason for days. I wrote my own harware interface for dynamixel motors. When i am on dev pc (a laptop with an i5 cpu) the interface is working great. Motors are responding correctly to every command i send from teleop twist keyboard.

But as soon as i start to control the robot from rpi4 (8gb ram) with exact same code interesting stuff begins.

  • when i send commands to drive the robot forward, only left wheel turns
  • commands to drive bacwards turns only right wheel
  • but in the mean time my robot in rviz moves as it should be moving
  • as i mentioned earlier the same code works great when on dev pc
  • dynamixel example cpp scripts are working on rpi, i send commands to both motors synchronously and motors are responding.
  • i implemented logging and debugging messages in my hardware interface code, it seems;
    • teleop sending right commands
    • diff drive controller is sending right commands to motors as well
    • but only one of the motors is responding that commands

While I was checking my urdf file to solve the problem before, I noticed this; Even though I set the right_wheel_joints axis z parameter to 1 instead of -1 to make the motor turn in opposite direction when the same command received, the right wheel on the real robot still continues to rotate as it was instead of rotating in the opposite direction.

To push further, in the urdf file i rotate the right wheel joints orientation to different directions,even z axis looking downwards (wheel is turning around z axis) but nothing changed either in real robots behaviour or robots move in rviz. But only the tf visual axis of right wheel joint on rviz changed.

Is it normal urdf changes dont affect nothing on the robots movement both in rviz and on real robot?

i am using ubuntu jammy and ros2 humble on both pc

i can share the codes if needed.

thanks in advance.