Developing Web Interfaces For ROS Robots #3 – Building a web joystick to control the robot

Written by Marco Arruda

21/02/2020

Hello ROS Developers,

This is the 3rd of 4 posts of the series Developing web interfaces for ROS Robots.

In this post, we are going to create a “joystick” to send velocity commands to a robot from the webpage.


1 – Creating the HTML

First we are going to create the buttons that the user will click on to move the robot.

Just after the logs section, let’s add the following:

                    ...
                    ...
	            <h3>Log messages</h3>
                    <div>
                        <p v-for="log of logs">{{ log }}</p>
                    </div>
		</div>
	</div>

        <hr>

        <div class="row">
            <div class="col-md-12 text-center">
                <h5>Commands</h5>
            </div>

            <!-- 1st row -->
            <div class="col-md-12 text-center">
                <button class="btn btn-primary">Go forward</button>
                <br><br>
            </div>

            <!-- 2nd row -->
            <div class="col-md-4 text-center">
                <button class="btn btn-primary">Turn left</button>
            </div>
            <div class="col-md-4 text-center">
                <button class="btn btn-danger">Stop</button>
                <br><br>
            </div>
            <div class="col-md-4 text-center">
                <button class="btn btn-primary">Turn right</button>
            </div>

            <!-- 3rd row -->
            <div class="col-md-12 text-center">
                <button class="btn btn-primary">Go backward</button>
            </div>
        </div>

This must provide an interface like below:


2 – Code to send the commands

Now, in our main.js file, let’s create some new methods to perform the actions we have just idealized. Inside the methods attribute we already have 2 functions. Let’s create the ones below:

        setTopic: function() {
            this.topic = new ROSLIB.Topic({
                ros: this.ros,
                name: '/cmd_vel',
                messageType: 'geometry_msgs/Twist'
            })
        },
        forward: function() {
            this.message = new ROSLIB.Message({
                linear: { x: 1, y: 0, z: 0, },
                angular: { x: 0, y: 0, z: 0, },
            })
            this.setTopic()
            this.topic.publish(this.message)
        },
        stop: function() {
            this.message = new ROSLIB.Message({
                linear: { x: 0, y: 0, z: 0, },
                angular: { x: 0, y: 0, z: 0, },
            })
            this.setTopic()
            this.topic.publish(this.message)
        },
        backward: function() {
            this.message = new ROSLIB.Message({
                linear: { x: -1, y: 0, z: 0, },
                angular: { x: 0, y: 0, z: 0, },
            })
            this.setTopic()
            this.topic.publish(this.message)
        },
        turnLeft: function() {
            this.message = new ROSLIB.Message({
                linear: { x: 0.5, y: 0, z: 0, },
                angular: { x: 0, y: 0, z: 0.5, },
            })
            this.setTopic()
            this.topic.publish(this.message)
        },
        turnRight: function() {
            this.message = new ROSLIB.Message({
                linear: { x: 0.5, y: 0, z: 0, },
                angular: { x: 0, y: 0, z: -0.5, },
            })
            this.setTopic()
            this.topic.publish(this.message)
        },

We have defined a common method setTopic that is used by the others: forwardbackward, stop, turnLeft and turnRight.

The task inside of each one is always the same. Define a message to send, set the topic and publish the message.

The only thing that changes from one to another are the values of the Twist message.


3 – Integrating HTML and JavaScript

Now that we have the elements in our page and the methods that perform the actions, let’s make them work together.

In order to do so, we need to assign the methods to the “click” events of each button. It goes like this:

            <!-- 1st row -->
            <div class="col-md-12 text-center">
                <button @click="forward" :disabled="loading || !connected" class="btn btn-primary">Go forward</button>
                <br><br>
            </div>

            <!-- 2nd row -->
            <div class="col-md-4 text-center">
                <button @click="turnLeft" :disabled="loading || !connected" class="btn btn-primary">Turn left</button>
            </div>
            <div class="col-md-4 text-center">
                <button @click="stop" :disabled="loading || !connected" class="btn btn-danger">Stop</button>
                <br><br>
            </div>
            <div class="col-md-4 text-center">
                <button @click="turnRight" :disabled="loading || !connected" class="btn btn-primary">Turn right</button>
            </div>

            <!-- 3rd row -->
            <div class="col-md-12 text-center">
                <button @click="backward" :disabled="loading || !connected" class="btn btn-primary">Go backward</button>
            </div>

Notice that we are not only defining the @click attribute, but also the “:disabled”. It means that the button will be disabled if one of the conditions are true: Loading or not connected.


4 – Final result

At this point, you must have the following result with your webpage:


ROSJect created along with the post:

http://www.rosject.io/l/ddbab4e/

Topics:
Masterclass 2023 batch2 blog banner

Check Out These Related Posts

129. ros2ai

129. ros2ai

I would like to dedicate this episode to all the ROS Developers who believe that ChatGPT or...

read more

0 Comments

Submit a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Pin It on Pinterest

Share This