Skip to content

prepare 4.1 #161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Jul 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ba975a5
tf 2.7
previ Jan 21, 2022
e437748
revert tf 2.1
previ Jan 22, 2022
9d5fdf4
bump numpy ver
previ Jan 23, 2022
7c7ee87
bump requirements_stub
previ Jan 24, 2022
ba9729e
bump requirements_stub
previ Jan 24, 2022
80c3b6f
led ws2812b
previ Jan 25, 2022
e14de56
led ws2812b
previ Jan 25, 2022
bcbba45
led ws2812b
previ Jan 25, 2022
f2c224a
led ws2812b
previ Jan 26, 2022
140285d
add listMusicPackages api
previ Jan 29, 2022
d88b342
fix musicPackage export
previ Jan 30, 2022
cfab93b
remove coderbot-copy.py
previ Jan 30, 2022
c90ccf8
fix music package removal
previ Feb 1, 2022
db7bfde
Merge branch 'develop' of https://github.com/CoderBotOrg/backend into…
previ Feb 1, 2022
1c69018
v1 feature parity
previ Feb 1, 2022
0cefff7
fix #155
previ Feb 6, 2022
a6eec09
fix program status and log with v2
previ Feb 7, 2022
d1d3882
update ci
previ Feb 8, 2022
55023d5
add default activity init
previ Mar 6, 2022
5763bc8
add default activity init
previ Mar 7, 2022
a3f291b
add default activity
previ Mar 9, 2022
ca1b990
activity default parameters
previ Mar 12, 2022
c096602
bullseye wip
previ May 28, 2022
fa63bb4
bullseye wip
previ May 29, 2022
5d50a5e
Update audioControls.py
previ May 29, 2022
0f3e5f6
bullseye wip
previ May 29, 2022
1266d83
Update audio.py
previ Jun 8, 2022
e032049
update stock activities
previ Jun 8, 2022
d58a6d8
Update program.py
previ Jun 11, 2022
94e2c76
Update activity_default.json
previ Jun 12, 2022
a1ec6ac
Update coderbot.py
previ Jun 18, 2022
ea027ed
no longer init_activities
previ Jun 28, 2022
c71cfc7
move init_activities on frontend for i18n
previ Jun 28, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
build:
docker:
# specify the version you desire here
- image: coderbot/python-gpac:3.7
- image: coderbot/coderbot-ci:3.9-bullseye-ffmpeg

working_directory: ~/repo

Expand Down
45 changes: 45 additions & 0 deletions activity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from tinydb import TinyDB, Query
from tinydb.operations import delete
import json

# Programs and Activities databases
class Activities():
_instance = None

@classmethod
def get_instance(cls):
if cls._instance == None:
cls._instance = Activities()
return cls._instance

def __init__(self):
self.activities = TinyDB("data/activities.json")
self.query = Query()

def load(self, name, default):
if name:
return self.activities.search(self.query.name == name)[0]
elif default is not None:
default_Activities = self.activities.search(self.query.default == True)
if len(self.activities.search(self.query.default == True)) > 0:
return self.activities.search(self.query.default == True)[0]
else:
return None

def save(self, activity):
if self.activities.search(self.query.name == activity["name"]) == []:
self.activities.insert(activity)
else:
if activity.get("default", False) == True:
self.activities.update({'default': False})
self.activities.update(activity, self.query.name == activity["name"])

def delete(self, activity):
activity = self.activities.search(self.query.name == activity["name"])[0]
if activity.get("default", False) == True:
self.activities.update({'default': True}, self.query.stock == True)
self.activities.remove(self.query.name == activity["name"])

def list(self):
return self.activities.all()

65 changes: 41 additions & 24 deletions api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
import os
import subprocess
import json
import logging
import connexion
from tinydb import TinyDB, Query
from tinydb.operations import delete
import pigpio
from cachetools import cached, TTLCache
from coderbot import CoderBot
from program import ProgramEngine, Program
from config import Config
from activity import Activities
from coderbotTestUnit import run_test as runCoderbotTestUnit
import pigpio
from cnn_manager import CNNManager
from musicPackages import MusicPackageManager

BUTTON_PIN = 16
Expand All @@ -25,8 +26,6 @@
encoder=bool(bot_config.get("encoder"))
)

query = Query()

def get_serial():
"""
Extract serial from cpuinfo file
Expand Down Expand Up @@ -108,8 +107,7 @@ def get_info():
prog = None
prog_engine = ProgramEngine.get_instance()

# Programs and Activities databases
activities = TinyDB("data/activities.json")
activities = Activities.get_instance()

## Robot control

Expand All @@ -133,7 +131,8 @@ def turn(data):

def exec(data):
program = prog_engine.create(data["name"], data["code"])
return json.dumps(program.execute())
options = data["options"]
return json.dumps(program.execute(options))

## System

Expand Down Expand Up @@ -173,14 +172,23 @@ def restoreSettings():
Config.get()
return "ok"


def updateFromPackage():
os.system('sudo bash /home/pi/clean-update.sh')
file_to_upload = connexion.request.files['file_to_upload']
file_to_upload.save(os.path.join('/home/pi/', 'update.tar'))
os.system('sudo reboot')
return 200

def updatePackages():
def listMusicPackages():
"""
list available music packages
"""
musicPkg = MusicPackageManager.get_instance()
response = musicPkg.listPackages()
return json.dumps(response)

def updateMusicPackages():
"""
Add a musical package an save the list of available packages on disk
also add sounds and directory
Expand All @@ -196,14 +204,23 @@ def updatePackages():
if response == 1:
return 200
elif response == 2:
return 2
return 400
elif response == 3:
return 3
return 400

def deleteMusicPackage(package_data):
"""
Delete a musical package an save the list of available packages on disk
also delete package sounds and directory
"""
musicPkg = MusicPackageManager.get_instance()
musicPkg.deletePackage(package_data['package_name'])
return 200

## Programs

def saveProgram(data, overwrite):
def saveProgram(data):
overwrite = data["overwrite"]
existing_program = prog_engine.load(data["name"])
if existing_program and not overwrite:
return "askOverwrite"
Expand All @@ -227,23 +244,17 @@ def listPrograms():
## Activities

def saveActivity(data):
data = data["activity"]
if activities.search(query.name == data["name"]) == []:
activities.insert(data)
return 200
else:
activities.update(data, query.name == data["name"])
return 200
activity = data["activity"]
activities.save(activity)

def loadActivity(name):
return activities.search(query.name == name)[0], 200
def loadActivity(name=None, default=None):
return activities.load(name, default)

def deleteActivity(data):
activities.remove(query.name == data["name"])

activities.delete(data), 200

def listActivities():
return activities.all()
return activities.list()

def resetDefaultPrograms():
"""
Expand Down Expand Up @@ -273,3 +284,9 @@ def testCoderbot(data):
# taking first JSON key value (varargin)
tests_state = runCoderbotTestUnit(data[list(data.keys())[0]])
return tests_state

def list_cnn_models():
cnn = CNNManager.get_instance()
logging.info("cnn_models_list")
return json.dumps(cnn.get_models())

21 changes: 20 additions & 1 deletion atmega328p.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
CMD_RESET = 0x00
CMD_SET_DATA = 0x01
CMD_GET_DATA = 0x02
CMD_SET_MODE = 0x03
CMD_SET_LED = 0x04

ADDR_AI_FIRST = 0x00
ADDR_AI_LAST = 0x01
Expand All @@ -35,7 +37,7 @@ def get_instance(cls):
return cls._instance

def __init__(self):
#Initialze the SPI
# Initialze the SPI
self.spi = spidev.SpiDev()
self.spi.open(0,0)
self.spi.max_speed_hz = BAUDRATE_MAX
Expand All @@ -54,6 +56,23 @@ def analogRead(self, addr):
resp = self.spi.xfer([START, CMD_GET_DATA, addr, 0, 0], BAUDRATE)
return resp[3]

def setLed(self, begin_led, end_led, red, green, blue):
resp = self.spi.xfer([START, CMD_SET_LED,
min(max(begin_led, 0), 60),
min(max(end_led, 0), 60),
min(max(red, 0), 254),
min(max(green, 0), 254),
min(max(blue, 0), 254)], BAUDRATE)
return resp[3]

def set_led(self, begin_led, end_led, red, green, blue):
begin = begin_led - 1
end = end_led - 1
red = int(red * 255 / 100)
green = int(green * 255 / 100)
blue = int(blue * 255 / 100)
return self.setLed(begin, end, red, green, blue)

def get_input(self, addr):
if addr >= ADDR_AI_FIRST and addr <= ADDR_AI_LAST:
return self.analogRead(addr)
Expand Down
2 changes: 1 addition & 1 deletion audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
# [END import_libraries]

# Audio recording parameters
RATE = 16000
RATE = 44100
CHUNK = int(RATE / 10) # 100ms
FORMAT = pyaudio.paInt16

Expand Down
7 changes: 3 additions & 4 deletions audioControls.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ def getVolume(self):
def setVolume(self,valueVolume):
self.mixer.setvolume(valueVolume)

if __name__ == "__main__":
a = AudioCtrl()
a.setVolume(20)
#a.setVolume(100)
# if __name__ == "__main__":
# a = AudioCtrl()
# a.setVolume(20)
13 changes: 10 additions & 3 deletions cnn_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,23 @@
import logging

import numpy as np
from tensorflow.lite.python.interpreter import Interpreter
try:
from tensorflow.lite.python.interpreter import Interpreter
except:
logging.warning("tensorflow not available (for inference)")
try:
from tflite_runtime.interpreter import Interpreter
except:
logging.warning("tflite not available")

import cv2

logger = logging.getLogger(__name__)

class CNNClassifier(object):
def __init__(self, model_file, label_file):
logger.info(model_file)
self._interpreter = Interpreter(model_path=model_file)
self._interpreter.set_num_threads(4)
self._interpreter = Interpreter(model_path=model_file, num_threads=4)
self._interpreter.allocate_tensors()
self._labels = self.load_labels(label_file)
self._input_details = self._interpreter.get_input_details()
Expand Down
7 changes: 6 additions & 1 deletion cnn_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@
import json
import threading

from cnn_train import CNNTrainer
try:
from cnn_train import CNNTrainer
except:
logging.warning("tensorflow not available (for training)")

from cnn_classifier import CNNClassifier

MODEL_PATH = "./cnn_models"
Expand Down Expand Up @@ -117,6 +121,7 @@ def load_model(self, model_name):
return CNNClassifier(model_file=MODEL_PATH + "/" + model_name + ".tflite",
label_file=MODEL_PATH + "/" + model_name + ".txt")
return None

class TrainThread(threading.Thread):

def __init__(self, manager, model_name, architecture, image_tags, photos_metadata, training_steps, learning_rate):
Expand Down
Loading