Create stunning UIs for ROS2 using the newly released QML ROS2 plugin

Greetings fellow robotics enthusiasts,
I am back and brought a new public repo with me:

This is a plugin for QML which allows communicating with ROS2 nodes directly from QML.
No compilation or modification necessary!

If you don’t know it, QML is a markup language by the Qt people which is a lot nicer than the QWidget stuff (both in terms of looks and writing code) and comes with hardware acceleration already integrated.
Since pictures speak more than words, here’s a bunch of those put in sequence:

This shows a short snippet of the start of Team Hector’s finals run in the DRZ challenge at the RoboCup German Open 2022 hosted at the German Rescue Robotics Center (DRZ).
The user interface you see here is built using QML and the QML ROS Plugin which is the ROS 1 version of this plugin since our robots are still running on ROS 1.
However, you could build the same interface for ROS 2 (if you port the hector_rviz_overlay for rviz2 that is :wink: ).

Of course, the package also comes with some small examples and documentation to help you get started.
Please note that as described in the topic for the release of ROS2 BabelFish which is used for the communication under the hood, the examples for service and action clients currently do not work and will print a helpful error message on the console with a link to the PR that needs to be merged for the implementation to work.

Also, it should work with any middleware but I’ve only tested it with the default RMW of foxy and galactic.

Here’s also a small code example:

import QtQuick 2.2
import QtQuick.Controls 2.5
import QtMultimedia 5.10
import Ros2 1.0

Item {
  Component.onCompleted: Ros2.init('qml_example_node')
  ImageTransportSubscription {
    id: imageSubscription
    topic: "/image_raw"
  VideoOutput { anchors.fill: parent; source: imageSubscription }
  Rectangle {
    anchors.horizontalCenter: parent.horizontalCenter
    anchors.bottom: parent.bottom
    width: 120; height: 120
    radius: 60
    color: '#aaaaaa' // a ghost! :O
    MouseArea {
      anchors.fill: parent
      property var pub: Ros2.createPublisher("/cmd_vel",
                                             "geometry_msgs/Twist", 1)
      onPositionChanged: {
        var x = -mouse.x / (width / 2) + 1
        var y = -mouse.y / (height / 2) + 1
        pub.publish({linear: {x: y}, angular: {z: x}})
  Button {
    anchors.bottom: parent.bottom
    property bool isOn: true
    property var flashlightClient: Ros2.createServiceClient('/flashlight', 'std_srvs/srv/SetBool')
    text: 'Flashlight: ' + (isOn ? 'On' : 'Off')
    onClicked: {
        {data: !isOn},
        function (result) {
          if (result === false) {
            Ros2.error("Failed to toggle flashlight!")
          isOn = !isOn

These roughly 50 lines of code are all it takes to create a minimal interface with a camera stream, a steering joypad area and a button to toggle a flashlight using a service call.

That’s all, I hope it may be of use to some of you.
If you’ve built something cool with it, feel free to shoot me a message or email :slight_smile:


Great work. I’ve used QML in other projects and it is impressive what can be done with very little effort. I’m very new to ROS but got it working with Galactic. I also tried with Humble but got compile errors on ros2_babel_fish. Haven’t spent too much time trying to figure it out but do you see any issues moving to Humble since the default RMW is FastDDS?

I haven’t looked at it yet but the issue is probably not the changed default RMW but that there were changes in the RMW abstraction.
Unfortunately, I can’t tell you when I’ll have the time to set up a humble environment and look into what needs to be addressed.
Feel free to open an issue in the GitHub repo and I will update that once I start looking into it.

OK! I’ll read it to find whether i can start my work and thank your generous!
and do you have a wechat? i want to communicate to you if i had a problem.

I managed to make a few changes to get it to build on Humble and run the pub/sub qml examples. I’ll put together a pull request.