Flask - quick web interface for robots

I have a project were I have to control a robot (Milo) with a tablet.
The simple idea is to make a website on the robot and to visualise the website on Chrome on the tablet.
I was looking for a tool to prototype quickly a website in Python with “real-time” features and I found Flask
"Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions."
This Python tool is very powerful to make a simple website in some minutes.
Moreover, it has some extensions such as socket IO signals, simple video streaming or TSL features.
The community is also very dynamic and lots of examples already exist in link with IoT.
And to learn the web technologies, it is very powerful (I started Javascript)

I am thinking about converting FIRE with Flask to avoid Qt (and the issues about multi-threads)

“Since I use Flask, it changed my life…”

3 Likes

Just for me to understand: why use python to control a website?
Is it more convenient than something based on a javascript frameworks served by http server ?

(by the way, Milo looks like a really important and useful project)

why use python to control a website?

You have to consider the backend and the front-end part of an application.
In @Thot’s case, html/js will control the website, not python; python is the website, html/js is a presentation for the browser.

The backend part can be made with any language - including javascript -, but we recommend using python since you can use our libraries without any effort. Using another language would limit the usage to the robot http rest api, unless somebody ports our libraries to another language.

The front-end part just consumes the backend, so it can be whatever you want : html/js if you intend on using the browser, swift/objective-c if you intend on doing an ios application, etc.

1 Like

@Thot, do you happen to have taken a look at the Django framework?
It is made with python, is pretty robust, and allows - rather - easy sharing and integration of 3rd party applications :wink:

We (@Theo @Pierre and I) intend to use it for the creature web interface so people can extend it as much as they like.

1 Like

The objective is to control a robot with a website. Two options :

  • control the robot with html/javascript (all is to create)
  • control the website with python

With Flask I did find the real-time feature. The objective is to control a joint with a website scroll bar for instance.

The other point is that I already developed lots of stuff in Python… And I really like Python.

For the Milo case, the control uses Java with 3 different oracle modules for the equivalent of Pypot. I did a gateway to Python using Zeromq. I need another gateway to the web…

Thanks @damien for Django, I saw a lot of topics about Django but I never identified it was for python and web… I am going to see if all the stuff I need is OK.

I finally chose Flask for my project. The reason is that Django is too complex for my project. I think Django is good for a clean and structured web site. I think it can be useful for collaborative. The formation to Django is also violent for a guy like me who just dived in the web. I think real-life formation on Django is needed.
While I looked at some tutorial on Django, I finished my project with Flask.
Django has a bigger community and much more contributions but Flask framework complexity is very small.

Here is an example of real-time web interface with Flask :
Folder
—>app.py
—>templates
------>index.html

The folder must have a ‘templates’ folder in which you have the following index.html file :

<!DOCTYPE HTML>
<html>
<head>
    <title>Flask-SocketIO Test</title>
    <script type="text/javascript" src="//code.jquery.com/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function(){
            namespace = '/test'; // change to an empty string to use the global namespace
            if(window.DeviceOrientationEvent) {
                window.addEventListener("deviceorientation", process, false);
            } else {
                // Le navigateur ne supporte pas l'événement deviceorientation
            }
            // the socket.io documentation recommends sending an explicit package upon connection
            // this is specially important when using the global namespace
            var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);

            // event handler for server sent data
            // the data is displayed in the "Received" section of the page
            socket.on('flow', function(msg) {
                $('#time').html(msg.data);
            });
            $('#slider').live('input', function() {
                socket.emit('robot', {motor: 'NECK_YAW',value: $(this).val()});
                return false;
            });
            function process(event) {
                var alpha = event.alpha;
                var beta = event.beta;
                var gamma = event.gamma;
                socket.emit('pad', {alpha: alpha,beta: beta,gamma: gamma});
            }
        });
    </script>
</head>
<body>
    <h1>Test</h1>
    <div id="time"></div>
    <h2>Orientation du regard</h2> <br>
    <input id="slider" type="range" min="0" max="1" value="0.5" step="0.01"/> <br>
</body>
</html>  

In the folder, create the app.py file in which :

#!/usr/bin/env python

# Set this variable to "threading", "eventlet" or "gevent" to test the
# different async modes, or leave it set to None for the application to choose
# the best option based on available packages.
async_mode = None

if async_mode is None:
    try:
        import eventlet
        async_mode = 'eventlet'
    except ImportError:
        pass

    if async_mode is None:
        try:
            from gevent import monkey
            async_mode = 'gevent'
        except ImportError:
            pass

    if async_mode is None:
        async_mode = 'threading'

    print('async_mode is ' + async_mode)

# monkey patching is necessary because this application uses a background
# thread
if async_mode == 'eventlet':
    import eventlet
    eventlet.monkey_patch()
elif async_mode == 'gevent':
    from gevent import monkey
    monkey.patch_all()

import time
from threading import Thread
from flask import Flask, render_template, url_for
from flask_socketio import SocketIO, emit
import csv

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode=async_mode)
thread = None

class Engine(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.flow = {}
    
    def run(self):
        display = ''
        while True:
            time.sleep(0.05)
            self.flow["t"] = time.time()
            flowstr = str(self.flow)
            flowstr = flowstr.replace(',','<br>')
            flowstr = flowstr.replace('{','')
            flowstr = flowstr.replace('}','')
            socketio.emit('flow',
                          {'data': flowstr},
                          namespace='/test')
            
@app.route('/')
def index():
    global thread
    if thread is None:
        thread = Engine()
        thread.daemon = True
        thread.start()
    return render_template('index.html')

@socketio.on('robot', namespace='/test')    
def handle_robot(message):
    thread.flow[message['motor']]=message['value']
    
@socketio.on('pad', namespace='/test')    
def handle_pad(message):
    thread.flow['alpha']=message['alpha']
    thread.flow['beta']=message['beta']
    thread.flow['gamma']=message['gamma']
    
if __name__ == '__main__':
    socketio.run(app,host='0.0.0.0',debug=True)

Then run the app.py script and open a web browser at http://127.0.0.1:5000

You will see this page :

The Thread Engine can synchronise the web page with the robot as wanted.
The small feature here is that the value of the slider is read and directed to the flow which can be accessed by the robot.
Passing by the javascript, if the robot is commanded by a tablet, you can get the orientation of the tablet (alpha, beta and gamma) here it is None because it is on my laptop which has no inertial measurement :slight_smile:

I think, having the equivalent of this example with Django could be much more complex.

BUT, I have to see now the robustness…

hey i also worked with flask,but i still cant get it how flask work actully.i build robot that can remotely control from a webpage using flask. i want to knw that how actully it works???

plz reply me soon its urgent

It is a HUGE question. I advise you to do the Flask tutorials : http://flask.pocoo.org/
You also need the Flask-socket-io python package to handle asynchronous web management.
Here is an example : https://github.com/miguelgrinberg/Flask-SocketIO-Chat
You need to have some understanding of Javascript also.

You will understand the script above then.

After, you can adapt to yur needs with pypot integrated or Zeromq if you use another architecture.

Finally, doing some Flask software helps you understand web design and helps you understand higher level frameworks like Django.