Featured image of post R2D2 Flask GUI

R2D2 Flask GUI

Using Flask and HTML to control my R2D2.

Flask GUI

The code is written in Python so I can utilize ROS in the future. I wanted to use a GUI that I can use in the web browser, so it will work on any platform including mobile. The RPI3 in my R2D2 will have an wifi connection. So I can connect Ad-Hoc directly to the RPI3 and use the browser to control some of the accessories in my R2D2. I still feel radio control is most important for the movements right now. Going to large events, I find Bluetooth, Zigbee and Wifi connections get a little flakey and I do not want my R2D2 to run away. But if the accessories do not function through user controls, it will be fine.

I created a quick page just for the head right now. I used HTML image mapping to surround the arms as button clicks. The button clicks will then call the Flask API. The API will then determine which API call (link) and run the python function. I mainly work with classes in Python. So I created an Arm Object and the Flask API has access to the object so it can make the function calls.

All this code is available on my Github page. https://github.com/artoo-ai/R2D2/

R2D2 Flask GUI Interface for Arms

Video

RPI3 Running the Servos using Flask GUI

Code

Flask API code and HTML page.

Flask API

https://github.com/artoo-ai/R2D2/blob/master/r2d2_main.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#!/usr/bin/env python

import time
from frame.arms import Arms
from flask import Flask, render_template, Response, request, redirect, url_for
from threading import Thread
import os


class R2D2:

    def __init__(self):
        """
        Initialize the R2D2.
        """
        # Init the Arms
        self.arms = Arms(0, 1)

        # Init the web server for the GUI
        #self.web_thread = Thread(target=self.init_web_server)
        #self.web_thread.start()
        self.init_web_server()

    def shutdown(self):
        """
        Shutdown the R2D2
        :return:
        """
        self.arms.shutdown()

    def init_web_server(self):
        template_dir =os.path.dirname(os.path.realpath(__file__))
        template_dir = os.path.join(template_dir, 'web')
        print(template_dir)

        app = Flask(__name__, template_folder=template_dir, static_url_path='/static')

        @app.route("/")
        def index():
            return render_template('index.html')
            #return "Hello World!"

        @app.route("/test_arms/", methods=['GET', 'POST'])
        def test_arms():
            self.test_arms()
            #return "Test Arms"
            return render_template('index.html')

        @app.route("/open_top_arm/", methods=['GET', 'POST'])
        def open_top_arm():
            self.arms.open_top_arm()
            time.sleep(0.5)
            self.arms.close_top_arm()
            return render_template('index.html')

        @app.route("/open_bottom_arm/", methods=['GET', 'POST'])
        def open_bottom_arm():
            self.arms.open_bottom_arm()
            time.sleep(0.5)
            self.arms.close_bottom_arm()
            return render_template('index.html')

        app.run(host='0.0.0.0')

    def test_arms(self):
        """
        Test the arms.
        :return:
        """
        self.arms.test_arms()


if __name__ == '__main__':
    r2d2 = R2D2()
    #r2d2.test_arms()
    #r2d2.shutdown()

Webpage

https://github.com/artoo-ai/R2D2/blob/master/web/index.html

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<!DOCTYPE html>
<html>
  <head>
    <title>R2D2 Controls</title>
      <style>
.button {
  display: inline-block;
  border-radius: 4px;
  border: none;
  position: relative;
  background-color: #4CAF50;
  border: none;
  font-size: 28px;
  color: #FFFFFF;
  padding: 20px;
  width: 200px;
  text-align: center;
  -webkit-transition-duration: 0.4s; /* Safari */
  transition: all 0.5s;
  transition-duration: 0.4s;
  text-decoration: none;
  overflow: hidden;
  cursor: pointer;
  margin: 5px;
}
.button:after {
  content: "";
  background: #f1f1f1;
  display: block;
  position: absolute;
  padding-top: 300%;
  padding-left: 350%;
  margin-left: -20px !important;
  margin-top: -120%;
  opacity: 0;
  transition: all 0.8s
}
.button:active:after {
  padding: 0;
  margin: 0;
  opacity: 1;
  transition: 0s
}
.button span {
  cursor: pointer;
  display: inline-block;
  position: relative;
  transition: 0.5s;
}
.button span:after {
  content: '\00bb';
  position: absolute;
  opacity: 0;
  top: 0;
  right: -20px;
  transition: 0.5s;
}
.button:hover span {
  padding-right: 25px;
}
.button:hover span:after {
  opacity: 1;
  right: 0;
}
* {
  box-sizing: border-box;
}
/* Create two unequal columns that floats next to each other */
.column {
  float: left;
  padding: 10px;
  height: 300px; /* Should be removed. Only for demonstration */
}
.left {
  width: 25%;
}
.right {
  width: 75%;
}
/* Clear floats after the columns */
.row:after {
  content: "";
  display: table;
  clear: both;
}
</style>
  </head>

  <body>
<div class="row">
  <div class="column">
        <form action="/test_arms/" method="get">
            <button class="button" style="vertical-align:middle" name="testArmsBtn" type="submit"><span>Test Arms</span></button>
        </form>

        <form action="/open_top_arm/" method="get">
            <button class="button" style="vertical-align:middle" name="openTopArmBtn" type="submit"><span>Open Top Arm</span></button>
        </form>

        <form action="/open_bottom_arm/" method="get">
            <button class="button" style="vertical-align:middle" name="openBottomArmBtn" type="submit"><span>Open Bottom Arm</span></button>
        </form>
    </div>

    <div class="column">
        <img src="/static/r2d2.png" alt="Workplace" usemap="#workmap">

        <map name="workmap">
          <area shape="rect" coords="34,44,270,350" alt="TestArms" href="/test_arms/">
          <area shape="rect" coords="360,600,800,700" alt="TopArm" href="/open_top_arm/">
          <area shape="rect" coords="350,720,820,800" alt="BottomArm" href="/open_bottom_arm/">
        </map>
    </div>
  </div>
  </body>
</html>
comments powered by Disqus