Intro

Control GUI v1

picture 1
The set up for the first iteration of the RobotX control GUI is described.

The web GUI interfaces with ROS2 backend using rosbridge_server over WebSockets for continuous tasks such as Scan the Code light sequence monitoring. Mouse-clicked waypoints on the map are sent as POST HTTP requests to a flask server, which publishes them to ROS. The virtual joystick’s movements are published to \cmd_vel topic as Twist messages for manual control of the robot.

Resources

greenhorn_gui package

Package Creation and Structure

The greenhorn_gui package was created with the following steps:

  • Create/checkout rosbridge_gui branch
cd mrg/robotx_ws/src/greenhorn
git checkout -b rosbridge_gui
  • Generate the greenhorn_gui package:
ros2 pkg create greenhorn_gui 
  • Add additional files in the following structure:

greenhorn_gui structure

  • CMakeLists.txt: Handles the build system for the package.
  • package.xml: Defines package metadata and dependencies.
  • gui/: Contains the front-end files (HTML, JavaScript, CSS) that make up the user interface.
  • launch/: Includes launch files to start the simulation and set up the WebSocket connection.
  • light_buoy_sim/: The ROS2 node for simulating light buoy data.
  • server/: Contains the backend logic (app.py), which acts as both a Flask API and a ROS2 publisher.

CMakeLists.txt

package.xml

package.xml: Defines package metadata and dependencies.

Build the package

Ensure all necessary packages are present before building the greenhorn_gui package

  • Install all required dependencies from the root of the workspace
cd ../..
sudo apt update
rosdep install --from-paths src --ignore-src -r -y
  • Build the workspace
colcon build --packages-select greenhorn_gui

Rosbridge Server

websocket.launch.py

Note: this file should be renamed as it launches both the rosbridge server node and the flask node

  • Launch the websocket and flask server
source install/setup.bash
ros2 launch greenhorn_gui websocket_launch.py
[INFO] [launch]: All log files can be found below /home/chxtio/.ros/log/2024-09-24-07-01-23-452406-172.20225150-1507
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [rosbridge_websocket-1]: process started with pid [1509]
[rosbridge_websocket-1] [INFO] [1727186484.038599832] [rosbridge_websocket]: Rosbridge WebSocket server started on port 9090

Web GUI

gui/: Contains the front-end files (HTML, JavaScript, CSS) that make up the user interface.

picture 0

index.html

  • Global map added using maplibre

style.css

index.js


Light Tower Simulator

picture 2

light_buoy_sim_launch.py

  • Launch the light buoy simulator
source install/setup.bash
ros2 launch greenhorn_gui light_buoy_sim_launch.py

Flask REST API with ROS Integration

server/: Contains app.py, which acts as both a Flask API for http endpoints and a ROS2 publisher

app.py

Note

The Flask node is launched via websocket.launch.py

  • To see a demonstration (table of waypoints) of how the GUI can be served using Python with Flask and templating (as opposed to using javascript and rosbridge), visit the URL:
http://127.0.0.1:5000/

Publish waypoints to ROS

  • Test publisher by either clicking points on the map or sending a POST request to /waypoints topic via the terminal:
curl -X POST http://localhost:5000/waypoints -H "Content-Type: application/json" -d '{"lng": 1.0, "lat": 2.0}'
  • Subscribe to /waypoints topic to listen to the messages
ros2 topic echo /waypoints
 ros2 topic echo /waypoints
layout:
  dim: []
  data_offset: 0
data:
- -82.44391607402257
- 27.37299715058211
---
layout:
  dim: []
  data_offset: 0
data:
- -82.45082544444473
- 27.376884323360812
---
layout:
  dim: []
  data_offset: 0
data:
- -82.449237576709
- 27.370100736993308

Virtual Joystick

  • See virtual-joystick for more info

  • The move function takes in 2 arguments: linear and angular speed in m/s and publishes it as Twist messages on cmd_vel topic through the cmd_vel_listener object

// Publish command velocity
cmd_vel_listener = new ROSLIB.Topic({
    ros : ros,
    name : "/cmd_vel",
    messageType : 'geometry_msgs/Twist'
  });
   
  move = function (linear, angular) {
    var twist = new ROSLIB.Message({
      linear: {
        x: linear,  // forward/backward
        y: 0,       // side-to-side 
        z: 0        // up/down 
      },
      angular: {
        x: 0,       // roll (rotation around x-axis)
        y: 0,       // pitch (rotation around y-axis)
        z: angular  // yaw (rotation around z-axis)
      }
    });
    cmd_vel_listener.publish(twist);
  }

Note: Name should be changed to reflect the Topic object as a publisher


GUI v1 fixes

Load dependencies locally for offline use

    <script type="text/javascript" src="libs/roslib.min.js"></script>
    <link href="libs/maplibre-gl.css" rel="stylesheet" />
    <script src="libs/maplibre-gl.js"></script>
    <script type="text/javascript" src="libs/nipplejs.js"></script>