Skip to content

Commit

Permalink
Merge branch 'delta'
Browse files Browse the repository at this point in the history
  • Loading branch information
bencobley committed Jun 9, 2020
2 parents 197ba70 + cc50295 commit 4d6e620
Show file tree
Hide file tree
Showing 45 changed files with 1,283 additions and 765 deletions.
7 changes: 0 additions & 7 deletions .gitignore

This file was deleted.

89 changes: 46 additions & 43 deletions API.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
import os
import sys

from flask import Flask
from flask import request

from flask_cors import CORS

from main import OnionBot

import os
import sys

import logging

# Silence Flask werkzeug logger
logger = logging.getLogger("werkzeug")
logger.setLevel(logging.ERROR)
logger.setLevel(logging.ERROR) # Note! Set again below

# Initialise OnionBot
bot = OnionBot()
bot.run()

logger.info("Initialising web server")
# Initialise flask server
app = Flask(__name__)
CORS(app)

bot = OnionBot()

logger.info("Web server ready. Go to 0.0.0.0:8888/portal to connect")

bot.run()


@app.route("/", methods=["GET", "POST"])
def index():
"""Index is run automatically on init by flask"""
"""Access the OnionBot portal over the local network"""

if request.form["action"] == "start":
logger.debug("start called")
return bot.start(request.form["value"])
bot.start(request.form["value"])
return "1"

if request.form["action"] == "stop":
logger.debug("stop called")
Expand All @@ -45,25 +43,20 @@ def index():
logger.debug("get_thermal_history called")
return bot.get_thermal_history()

if request.form["action"] == "get_chosen_labels":
logger.debug("get_chosen_labels called")
return bot.get_chosen_labels()

if request.form["action"] == "set_chosen_labels":
logger.debug("set_chosen_labels called")
return bot.set_chosen_labels(request.form["value"])

if request.form["action"] == "set_label":
logger.debug("set_label called")
return bot.set_label(request.form["value"])
bot.set_label(request.form["value"])
return "1"

if request.form["action"] == "set_no_label":
logger.debug("set_no_label called")
return bot.set_no_label()
bot.set_no_label()
return "1"

if request.form["action"] == "set_active_model":
logger.debug("set_active_model called")
return bot.set_active_model(request.form["value"])
if request.form["action"] == "set_classifiers":
logger.debug("set_classifiers called")
bot.set_classifiers(request.form["value"])
return "1"

if request.form["action"] == "get_temperature_setpoint":
logger.debug("get_temperature_setpoint called")
Expand All @@ -75,60 +68,70 @@ def index():

if request.form["action"] == "set_fixed_setpoint":
logger.debug("set_fixed_setpoint called")
return bot.set_fixed_setpoint(request.form["value"])
bot.set_fixed_setpoint(request.form["value"])
return "1"

if request.form["action"] == "set_temperature_target":
logger.debug("set_temperature_target called")
return bot.set_temperature_target(request.form["value"])
bot.set_temperature_target(request.form["value"])
return "1"

if request.form["action"] == "set_temperature_hold":
logger.debug("set_temperature_hold called")
return bot.set_temperature_hold()
bot.set_temperature_hold()
return "1"

if request.form["action"] == "set_hob_off":
logger.debug("set_hob_off called")
return bot.set_hob_off()
bot.set_hob_off()
return "1"

if request.form["action"] == "set_pid_enabled":
logger.debug("set_pid_enabled called")
return bot.set_pid_enabled(request.form["value"])
bot.set_pid_enabled(request.form["value"])
return "1"

if request.form["action"] == "set_p_coefficient":
logger.debug("set_p_coefficient called")
return bot.set_p_coefficient(request.form["value"])
bot.set_p_coefficient(request.form["value"])
return "1"

if request.form["action"] == "set_i_coefficient":
logger.debug("set_i_coefficient called")
return bot.set_i_coefficient(request.form["value"])
bot.set_i_coefficient(request.form["value"])
return "1"

if request.form["action"] == "set_d_coefficient":
logger.debug("set_d_coefficient called")
return bot.set_d_coefficient(request.form["value"])
bot.set_d_coefficient(request.form["value"])
return "1"

if request.form["action"] == "set_pid_reset":
logger.debug("set_pid_reset called")
return bot.set_pid_reset()
bot.set_pid_reset()
return "1"

if request.form["action"] == "set_frame_interval":
logger.debug("set_frame_interval called")
return bot.set_frame_interval(request.form["value"])
bot.set_frame_interval(request.form["value"])
return "1"

if request.form["action"] == "get_all_labels":
logger.debug("get_all_labels called")
return bot.get_all_labels()

if request.form["action"] == "get_all_models":
logger.debug("get_all_models called")
return bot.get_all_models()
if request.form["action"] == "get_all_classifiers":
logger.debug("get_all_classifiers called")
return bot.get_all_classifiers()

if request.form["action"] == "pi-restart":
os.system("sudo reboot")
os.system("sudo reboot")

if request.form["action"] == "pi-shutdown":
os.system("sudo shutdown now")
os.system("sudo shutdown now")

if request.form["action"] == "restart":
os.system(". ~/onionbot/runonion")
os.system(". ~/onionbot/runonion")

if request.form["action"] == "quit":
bot.quit()
Expand Down
63 changes: 51 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
![alt text](https://github.com/bencobley/onionbot/blob/master/img/portal.png)
![hardware](https://user-images.githubusercontent.com/32883278/84203188-eb74a180-aaa0-11ea-9f77-fd6a6f6a2b2e.png)

# OnionBot

# OnionBot | An open source collaborative cooking robot
An assistive stove-top cooking device with machine vision - for domestic automation research
[See it in action](https://youtu.be/l-FsY-qU2Vw)
[See it in action](https://youtu.be/poE4O6JZY0E)

<p float="left">
<img src="https://www.raspberrypi.org/wp-content/uploads/2011/10/Raspi-PGB001.png" height="100"/>
<img src="https://www.nasuni.com/wp-content/uploads/2019/10/googleCloudPartner.png" height="100"/>
<img src="https://github.com/bencobley/onionbot/blob/master/img/automl.png" height="100"/>
<img src="https://miro.medium.com/max/400/0*xNxZokzztcgpPueM.png" height="100"/>
<img src="https://user-images.githubusercontent.com/32883278/84203339-32fb2d80-aaa1-11ea-843e-f7f69da66e53.png" height="50"/>
</p>


### To start the API
Script will run on boot. Otherwise SSH into Pi
1. `ssh pi@onionpi`
1. `ssh USER@YOUR_PI`
2. `cd onionbot`
3. `python3 API.py`
3. `. runonion`

### To use the web portal
1. Start a MAMP <mamp.info> local server environment
2. In your browser, navigate to `0.0.0.0:5000/portal`
3. Start collecting data!
### To connect to the web portal
1. Start your local web server of choice (we use Apache)
2. Point the server to `onionbot/portal`
3. Start cooking!

### Dependencies
1. `pip3 install pillow`
Expand All @@ -29,5 +31,42 @@ Script will run on boot. Otherwise SSH into Pi
4. [Tensorflow install guide](https://www.tensorflow.org/lite/models/image_classification/overview)
5. [Servo driver install](http://parallax.com/product/900-00008)

### Implementation
![alt text](https://github.com/bencobley/onionbot/blob/master/img/device.png)
### 3D Files
Visit [3d_files folder](https://github.com/bencobley/onionbot/tree/master/3d_files) to view 3D stls.

### System structure
![Screenshot 2020-06-09 at 21 40 54](https://user-images.githubusercontent.com/32883278/84198237-270c6d00-aa9b-11ea-9481-0a2cd971f2a7.png)

`API.py` Access the OnionBot portal over the local network

`camera.py` Control the camera using the Picamera module (threaded)

`classification.py` Classify images with TensorFlow and the Coral Edge TPU (threaded)

`cloud.py` Upload images to Google Cloud storage buckets (threaded)

`config.json` Configure settings, labels and models

`config.py` Interface with the `config.json` file

`control.py` Wrapper for PID module, manage control data structures for `main.py`

`data.py` Manage data structures and metadata for API

`knob.py` Wrapper for servo module to control hob temperature setting (threaded)

`launcher.py` Launch OnionBot software from the big red button

`lib_para_360_servo.py` Parallax 360 [servo drivers](http://parallax.com/product/900-00008)

`main.py` Main script (threaded)

`pid.py` Proportional Integral Derivative hob temperature controller (threaded)

`runlauncher` Launch big red button listener script

`runonion` Launch OnionBot software

`thermal_camera.py` Wrapper for the Adafruit MLX90640 thermal camera module (threaded)


4 changes: 3 additions & 1 deletion camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@


class Camera(object):
"""Control the camera using the Picamera module (threaded)"""

def __init__(self):
self.file_queue = JoinableQueue(1)

self.quit_event = Event()

def _worker(self):

logger.info("Initialising camera")
logger.info("Initialising camera...")

camera = PiCamera()
camera.rotation = 180
Expand Down
Loading

0 comments on commit 4d6e620

Please sign in to comment.