From 51f034694d73fb5578a8025e9bba4bfadd43e475 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 10 Apr 2023 23:37:54 +0100 Subject: [PATCH 01/60] sync setting, activities --- coderbot/cloud/__init__.py | 171 +++++++++++++++++++++++++++++++++++++ coderbot/config.py | 3 + coderbot/main.py | 4 + coderbot/program.py | 18 +++- 4 files changed, 192 insertions(+), 4 deletions(-) create mode 100644 coderbot/cloud/__init__.py diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py new file mode 100644 index 00000000..ec93640c --- /dev/null +++ b/coderbot/cloud/__init__.py @@ -0,0 +1,171 @@ +# Sync CoderBot configuration with remote Cloud configuration +# +# For all configuration entities (settings, activities, programs): +# check sync mode (upstream, downstream, both) +# if up: +# compare entity, if different, push changes +# if down: +# compare entity, if different, pull changes +# if both: +# compare entity, if different, take most recent and push/pull changes +# + +import threading +from datetime import datetime, timezone +import logging +import json +from time import sleep + +from config import Config +from activity import Activities +from program import ProgramEngine + +import cloud_api_robot_client +from cloud_api_robot_client.apis.tags import robot_sync_api +from cloud_api_robot_client.model.activity import Activity +from cloud_api_robot_client.model.program import Program +from cloud_api_robot_client.model.robot_data import RobotData +from cloud_api_robot_client.model.setting import Setting + +class CloudManager(threading.Thread): + _instance = None + + @classmethod + def get_instance(cls): + if cls._instance is None: + cls._instance = CloudManager() + return cls._instance + + def __init__(self): + threading.Thread.__init__(self) + # Defining the host is optional and defaults to https://api.coderbot.org/api/v1 + # See configuration.py for a list of all supported configuration parameters. + self.configuration = cloud_api_robot_client.Configuration( + host = "http://192.168.1.8:8090/api/v1", + # Configure Bearer authorization: coderbot_auth + ) + self.configuration.access_token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkNaMVFtVGM1WGZIV2NfQ1dPVG9kcm1QaXZFNFJ2ckFXaFZ3T28yTm85eDAifQ.eyJpc3MiOiJDb2RlckJvdCBDbG91ZCBBUEkiLCJpYXQiOjE2Nzc3MDI4NjIsImV4cCI6MTcwOTIzODg2MiwiYXVkIjoic3QtYXBpLmNvZGVyYm90Lm9yZyIsInN1YiI6InRwWkpYNFlsNElZd21QSzhEd2JmIiwiZW1haWwiOiJ0cFpKWDRZbDRJWXdtUEs4RHdiZkBib3RzLmNvZGVyYm90Lm9yZyIsInBpY3R1cmUiOiJodHRwczovL3N0LWFwcC5jb2RlcmJvdC5vcmcvcGljdHVyZXMvbm9waWMifQ.WlrYd-n6-WWHUxlz1kqnGl8TkjspVWn1UhKK_RIWyIJVlczD1GkqT4uqkHl2aGnp9I_E2SETUvC3dWkkUBG7qHvUIIZVaVhGpfiQy7WMekEdMnXtsPxK8NsWjHYUTbqz2dyz2Z1eQi5Ydhj4niEWsKCAT2BG-nwTIDxu-uxKrah6AtCGGyGKCQu0qje-qUNCxT5S1Y5RT10XS4Ewl2ROsMr1M6P3EVa0VoSJ26QZlh5jIz-8fhyGspxBHFEnZF-p95vEGCQp6M7epwoesDGVlX4AxEEpPk7c_Pd4c2gNLx1nhpkV26sT_c_NESNTM42tVyH9ZjQ5fxCUOEi_ELJ2vQ' + + self.start() + + def run(self): + while(True): + logging.info("run.begin") + settings = Config.read() + syncmodes = settings.get("syncmodes", {"settings": "n", "activities": "n", "programs": "n"}) + # Enter a context with an instance of the API client + with cloud_api_robot_client.ApiClient(self.configuration) as api_client: + # Create an instance of the API class + api_instance = robot_sync_api.RobotSyncApi(api_client) + + self.sync_settings(api_instance, syncmodes["settings"]) + + self.sync_activities(api_instance, syncmodes["activities"]) + + self.sync_programs(api_instance, syncmodes["programs"]) + + sleep(10) + logging.info("run.end") + + def sync_settings(self, api_instance, syncmode): + try: + # Create an instance of the API class + api_response = api_instance.get_robot_setting() + cloud_setting_object = api_response.body + cloud_setting = json.loads(cloud_setting_object.get('data')) + local_setting = Config.read() + local_most_recent = datetime.fromisoformat(cloud_setting_object["modified"]).timestamp() < Config.modified() + if cloud_setting != local_setting: + if syncmode == "u" or (syncmode == "b" and local_most_recen): + body = Setting( + id=api_response.body.get('id'), + org_id=api_response.body.get('org_id'), + name=api_response.body.get('name'), + description=api_response.body.get('description'), + data=json.dumps(setting), + modified=datetime.now().isoformat(), + status=api_response.body.get('status'), + ) + api_response = api_instance.set_robot_setting(body) + logging.info("run.4") + if syncmode == 'd': # setting, down + logging.info("cloud_setting: ", str(cloud_setting.data.setting)) + Config.write(cloud_setting.data.setting) + except cloud_api_robot_client.ApiException as e: + logging.warn("Exception when calling RobotSyncApi: %s\n" % e) + + def sync_activities(self, api_instance, syncmode): + activities = Activities.get_instance().list() + try: + # Get robot activities + api_response = api_instance.get_robot_activities() + cloud_activities = api_response.body + logging.info("run.activities.cloud" + str(cloud_activities)) + # cloud activities + a_c_m = {} # activities_cloud_map + for a in cloud_activities: + a_c_m[a.get("id")] = a + + a_l_m = {} # activities_local_map + # local activities no id + for a in activities: + if a.get("id") is not None: + a_l_m[a.get("id")] = a + + # loop through local + for al in activities: + logging.info("syncing: " + str(al.get("id"))) + ac = a_c_m.get(al.get("id")) + if ac is not None: + al["modified"] = al.get("modified", datetime.now(tz=timezone.utc).isoformat()) + local_activity_more_recent = datetime.fromisoformat(ac.get("modified")).timestamp() < datetime.fromisoformat(al.get("modified")).timestamp() + if syncmode == "u" or (local_activity_more_recent and syncmode == 'b'): + ac["data"] = al.get("data") + ac["modified"] = al.get("modified") + body = Activity( + id=ac.get("id"), + org_id=ac.get("org_id"), + name=al.get("name"), + description=al.get("description"), + data=json.dumps(al.get("data")), + modified=al.get("modified").isoformat(), + status='active', + ) + #logging.info("run.activities.cloud.saving") + api_response = api_instance.set_robot_activity(ac.get("id"), body) + #logging.info("run.activities.cloud.saved") + elif syncmode == "d" or (not local_activity_more_recent and syncmode == 'b'): + al["data"] = ac.get("data") + al["modified"] = ac.get("modified") + Activities.get_instance().save(al.get("name"), al) + logging.info("run.activities.local.saved: " + ac.get("name")) + elif ac is None and syncmode in ['u', 'b']: + #logging.info("activity:" + str(al)) + body = Activity( + id="", + org_id="", + name=al.get("name"), + description=al.get("description"), + data=json.dumps(al), + modified=al.get("modified", datetime.now(tz=timezone.utc).isoformat()), + status="active", + ) + api_response = api_instance.create_robot_activity(body=body) + logging.info("run.activities.cloud.created: " + str(api_response.body["id"])) + al["id"] = api_response.body["id"] + al["org_id"] = api_response.body["org_id"] + logging.info("run.activities.saving_local: " + al.get("name")) + Activities.get_instance().save(al.get("name"), al) + elif ac is None and syncmode in ['d']: + logging.info("run.activities.deleting_local: " + al.get("name")) + Activities.get_instance().delete(al.get("name")) + for ac, k in a_c_m.items(): + if a_l_m.get(k) is None and syncmode in ['d', 'b']: + Activities.get_instance().save(ac.get("name"), ac) + logging.info("run.activities.local.saved: " + ac.get("name")) + + except cloud_api_robot_client.ApiException as e: + logging.warn("Exception when calling RobotSyncApi: %s\n" % e) + + def sync_programs(self, api_client, syncmode): + pass diff --git a/coderbot/config.py b/coderbot/config.py index 071dd7da..a2098973 100644 --- a/coderbot/config.py +++ b/coderbot/config.py @@ -52,3 +52,6 @@ def restore(cls): with open(CONFIG_DEFAULT_FILE) as f: cls.write(json.loads(f.read())) + @classmethod + def modified(cls): + return os.stat(CONFIG_FILE).st_mtime \ No newline at end of file diff --git a/coderbot/main.py b/coderbot/main.py index edcb53d6..61bb1b24 100644 --- a/coderbot/main.py +++ b/coderbot/main.py @@ -18,6 +18,7 @@ from cnn.cnn_manager import CNNManager from event import EventManager from coderbot import CoderBot +from cloud import CloudManager # Logging configuration logger = logging.getLogger() @@ -89,6 +90,9 @@ def run_server(): if app.bot_config.get('load_at_start') and app.bot_config.get('load_at_start'): prog = app.prog_engine.load(app.bot_config.get('load_at_start')) prog.execute() + + CloudManager.get_instance() + except ValueError as e: app.bot_config = {} logging.error(e) diff --git a/coderbot/program.py b/coderbot/program.py index d76395fd..6e41afee 100644 --- a/coderbot/program.py +++ b/coderbot/program.py @@ -22,8 +22,9 @@ import json import shutil import logging - +from datetime import datetime import math + from tinydb import TinyDB, Query from threading import Lock @@ -159,12 +160,14 @@ class Program: def dom_code(self): return self._dom_code - def __init__(self, name, code=None, dom_code=None, default=False): + def __init__(self, name, code=None, dom_code=None, default=False, id=None, modified=None): self._thread = None self.name = name self._dom_code = dom_code self._code = code self._default = default + self._id = id + self._modified = modified def execute(self, options={}): if self._running: @@ -242,8 +245,15 @@ def as_dict(self): return {'name': self.name, 'dom_code': self._dom_code, 'code': self._code, - 'default': self._default} + 'default': self._default, + 'id': self._id, + 'modified': self._modified.isoformat()} @classmethod def from_dict(cls, amap): - return Program(name=amap['name'], dom_code=amap['dom_code'], code=amap['code'], default=amap.get('default', False)) + return Program(name=amap['name'], + dom_code=amap['dom_code'], + code=amap['code'], + default=amap.get('default', False), + id=amap.get('id', None), + modified=datetime.fromisoformat(amap.get('modified', datetime.now().isoformat()))) From c857b1a7299c35de6bcc044798affb63fb6f4efe Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Tue, 18 Apr 2023 23:38:23 +0100 Subject: [PATCH 02/60] wip --- coderbot/api.py | 7 +- coderbot/cloud/__init__.py | 182 ++++++++++++++---- coderbot/program.py | 56 ++++-- defaults/programs/program_demo_ar_tags.json | 2 +- .../programs/program_demo_cat_follower.json | 2 +- .../programs/program_demo_color_seeker.json | 2 +- defaults/programs/program_demo_io_ext.json | 2 +- .../programs/program_demo_line_follower.json | 2 +- .../programs/program_demo_roboetologist.json | 2 +- .../program_demo_sound_clap_control.json | 2 +- defaults/programs/program_test_find_code.json | 2 +- .../programs/program_test_find_color.json | 2 +- defaults/programs/program_test_find_face.json | 2 +- .../program_test_find_path_ahead.json | 2 +- .../programs/program_test_img_average.json | 2 +- .../programs/program_test_sound_hear.json | 2 +- defaults/programs/program_test_sound_rec.json | 2 +- 17 files changed, 200 insertions(+), 73 deletions(-) diff --git a/coderbot/api.py b/coderbot/api.py index 88052aff..a5fe50f5 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -7,6 +7,7 @@ import os import subprocess import urllib +from datetime import datetime import connexion import picamera @@ -295,7 +296,7 @@ def saveProgram(name, body): return "askOverwrite" elif existing_program is not None and existing_program.is_default() == True: return "defaultCannotOverwrite", 400 - program = Program(name=body.get("name"), code=body.get("code"), dom_code=body.get("dom_code")) + program = Program(name=body.get("name"), code=body.get("code"), dom_code=body.get("dom_code"), modified=datetime.now(), status="active") prog_engine.save(program) return 200 @@ -307,10 +308,10 @@ def loadProgram(name): return 404 def deleteProgram(name): - prog_engine.delete(name) + prog_engine.delete(name, logical=True) def listPrograms(): - return prog_engine.prog_list() + return prog_engine.prog_list(active_only=True) def runProgram(name, body): """ diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index ec93640c..7f583fcf 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -19,6 +19,7 @@ from config import Config from activity import Activities from program import ProgramEngine +import program import cloud_api_robot_client from cloud_api_robot_client.apis.tags import robot_sync_api @@ -27,6 +28,10 @@ from cloud_api_robot_client.model.robot_data import RobotData from cloud_api_robot_client.model.setting import Setting +SYNC_UPSTREAM = 'u' +SYNC_DOWNSTREAM = 'd' +SYNC_BIDIRECTIONAL = 'b' + class CloudManager(threading.Thread): _instance = None @@ -41,31 +46,30 @@ def __init__(self): # Defining the host is optional and defaults to https://api.coderbot.org/api/v1 # See configuration.py for a list of all supported configuration parameters. self.configuration = cloud_api_robot_client.Configuration( - host = "http://192.168.1.8:8090/api/v1", - # Configure Bearer authorization: coderbot_auth + host = "http://192.168.1.7:8090/api/v1", ) + # Configure Bearer authorization: coderbot_auth self.configuration.access_token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkNaMVFtVGM1WGZIV2NfQ1dPVG9kcm1QaXZFNFJ2ckFXaFZ3T28yTm85eDAifQ.eyJpc3MiOiJDb2RlckJvdCBDbG91ZCBBUEkiLCJpYXQiOjE2Nzc3MDI4NjIsImV4cCI6MTcwOTIzODg2MiwiYXVkIjoic3QtYXBpLmNvZGVyYm90Lm9yZyIsInN1YiI6InRwWkpYNFlsNElZd21QSzhEd2JmIiwiZW1haWwiOiJ0cFpKWDRZbDRJWXdtUEs4RHdiZkBib3RzLmNvZGVyYm90Lm9yZyIsInBpY3R1cmUiOiJodHRwczovL3N0LWFwcC5jb2RlcmJvdC5vcmcvcGljdHVyZXMvbm9waWMifQ.WlrYd-n6-WWHUxlz1kqnGl8TkjspVWn1UhKK_RIWyIJVlczD1GkqT4uqkHl2aGnp9I_E2SETUvC3dWkkUBG7qHvUIIZVaVhGpfiQy7WMekEdMnXtsPxK8NsWjHYUTbqz2dyz2Z1eQi5Ydhj4niEWsKCAT2BG-nwTIDxu-uxKrah6AtCGGyGKCQu0qje-qUNCxT5S1Y5RT10XS4Ewl2ROsMr1M6P3EVa0VoSJ26QZlh5jIz-8fhyGspxBHFEnZF-p95vEGCQp6M7epwoesDGVlX4AxEEpPk7c_Pd4c2gNLx1nhpkV26sT_c_NESNTM42tVyH9ZjQ5fxCUOEi_ELJ2vQ' - self.start() def run(self): while(True): - logging.info("run.begin") + logging.info("run.sync.begin") settings = Config.read() syncmodes = settings.get("syncmodes", {"settings": "n", "activities": "n", "programs": "n"}) + sync_period = settings.get("sync_period", 10) + # Enter a context with an instance of the API client with cloud_api_robot_client.ApiClient(self.configuration) as api_client: # Create an instance of the API class api_instance = robot_sync_api.RobotSyncApi(api_client) self.sync_settings(api_instance, syncmodes["settings"]) - self.sync_activities(api_instance, syncmodes["activities"]) - self.sync_programs(api_instance, syncmodes["programs"]) - sleep(10) - logging.info("run.end") + sleep(sync_period) + logging.info("run.sync.end") def sync_settings(self, api_instance, syncmode): try: @@ -75,24 +79,25 @@ def sync_settings(self, api_instance, syncmode): cloud_setting = json.loads(cloud_setting_object.get('data')) local_setting = Config.read() local_most_recent = datetime.fromisoformat(cloud_setting_object["modified"]).timestamp() < Config.modified() + logging.info("settings.syncing: " + cloud_setting_object.get("id") + " name: " + cloud_setting_object.get("id")) if cloud_setting != local_setting: - if syncmode == "u" or (syncmode == "b" and local_most_recen): + if syncmode == SYNC_UPSTREAM or (syncmode == SYNC_BIDIRECTIONAL and local_most_recent): body = Setting( - id=api_response.body.get('id'), - org_id=api_response.body.get('org_id'), - name=api_response.body.get('name'), - description=api_response.body.get('description'), - data=json.dumps(setting), - modified=datetime.now().isoformat(), - status=api_response.body.get('status'), + id = cloud_setting_object.get('id'), + org_id = cloud_setting_object.get('org_id'), + name = cloud_setting_object.get('name'), + description = cloud_setting_object.get('description'), + data = json.dumps(local_setting), + modified = datetime.now().isoformat(), + status = cloud_setting_object.get('status'), ) api_response = api_instance.set_robot_setting(body) - logging.info("run.4") - if syncmode == 'd': # setting, down - logging.info("cloud_setting: ", str(cloud_setting.data.setting)) + logging.info("settings.upstream") + if syncmode == SYNC_DOWNSTREAM: # setting, down Config.write(cloud_setting.data.setting) + logging.info("settings.downstream") except cloud_api_robot_client.ApiException as e: - logging.warn("Exception when calling RobotSyncApi: %s\n" % e) + logging.warn("Exception when calling settings RobotSyncApi: %s\n" % e) def sync_activities(self, api_instance, syncmode): activities = Activities.get_instance().list() @@ -100,7 +105,6 @@ def sync_activities(self, api_instance, syncmode): # Get robot activities api_response = api_instance.get_robot_activities() cloud_activities = api_response.body - logging.info("run.activities.cloud" + str(cloud_activities)) # cloud activities a_c_m = {} # activities_cloud_map for a in cloud_activities: @@ -114,12 +118,12 @@ def sync_activities(self, api_instance, syncmode): # loop through local for al in activities: - logging.info("syncing: " + str(al.get("id"))) + logging.info("activities.syncing: " + str(al.get("id")) + " name: " + str(al.get("name"))) ac = a_c_m.get(al.get("id")) - if ac is not None: + if ac is not None and ac.get("data") != al.get("data"): al["modified"] = al.get("modified", datetime.now(tz=timezone.utc).isoformat()) local_activity_more_recent = datetime.fromisoformat(ac.get("modified")).timestamp() < datetime.fromisoformat(al.get("modified")).timestamp() - if syncmode == "u" or (local_activity_more_recent and syncmode == 'b'): + if syncmode == SYNC_UPSTREAM or (local_activity_more_recent and syncmode == SYNC_BIDIRECTIONAL): ac["data"] = al.get("data") ac["modified"] = al.get("modified") body = Activity( @@ -133,14 +137,13 @@ def sync_activities(self, api_instance, syncmode): ) #logging.info("run.activities.cloud.saving") api_response = api_instance.set_robot_activity(ac.get("id"), body) - #logging.info("run.activities.cloud.saved") - elif syncmode == "d" or (not local_activity_more_recent and syncmode == 'b'): + logging.info("activities.update.upstream: " + al.get("name")) + elif syncmode == "d" or (not local_activity_more_recent and syncmode == SYNC_BIDIRECTIONAL): al["data"] = ac.get("data") al["modified"] = ac.get("modified") Activities.get_instance().save(al.get("name"), al) - logging.info("run.activities.local.saved: " + ac.get("name")) - elif ac is None and syncmode in ['u', 'b']: - #logging.info("activity:" + str(al)) + logging.info("activities.update.downstream: " + al.get("name")) + elif ac is None and syncmode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: body = Activity( id="", org_id="", @@ -151,21 +154,122 @@ def sync_activities(self, api_instance, syncmode): status="active", ) api_response = api_instance.create_robot_activity(body=body) - logging.info("run.activities.cloud.created: " + str(api_response.body["id"])) al["id"] = api_response.body["id"] al["org_id"] = api_response.body["org_id"] - logging.info("run.activities.saving_local: " + al.get("name")) Activities.get_instance().save(al.get("name"), al) - elif ac is None and syncmode in ['d']: - logging.info("run.activities.deleting_local: " + al.get("name")) + logging.info("activities.create.upstream: " + al.get("name")) + elif ac is None and syncmode in [SYNC_DOWNSTREAM]: Activities.get_instance().delete(al.get("name")) - for ac, k in a_c_m.items(): - if a_l_m.get(k) is None and syncmode in ['d', 'b']: + logging.info("activities.delete.downstream: " + al.get("name")) + for k, ac in a_c_m.items(): + if a_l_m.get(k) is None and syncmode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: Activities.get_instance().save(ac.get("name"), ac) - logging.info("run.activities.local.saved: " + ac.get("name")) + logging.info("activities.create.downstream: " + ac.get("name")) except cloud_api_robot_client.ApiException as e: - logging.warn("Exception when calling RobotSyncApi: %s\n" % e) + logging.warn("Exception when calling activities RobotSyncApi: %s\n" % e) + + def sync_programs(self, api_instance, syncmode): + programs = list() + programs_to_be_deleted = list() + for p in ProgramEngine.get_instance().prog_list(active_only=False): + if not p.get("default"): + if p.get("status") == program.PROGRAM_STATUS_ACTIVE: + programs.append(p) + elif p.get("status") == program.PROGRAM_STATUS_DELETED: + programs_to_be_deleted.append(p) + + try: + # Get robot activities + api_response = api_instance.get_robot_programs() + cloud_programs = api_response.body + # cloud activities + p_c_m = {} # activities_cloud_map + for p in cloud_programs: + if p.get("status") == program.PROGRAM_STATUS_ACTIVE: + p_c_m[p.get("id")] = p + + p_l_m = {} # activities_local_map + # local activities no id + for p in programs: + #logging.info("programs.local: " + str(p.get("id")) + " name: " + p.get("name")) + if p.get("id") is not None: + p_l_m[p.get("id")] = p - def sync_programs(self, api_client, syncmode): - pass + # manage programs present locally and in "active" status + for pl in programs: + pc = p_c_m.get(pl.get("id")) + pc_pl_equals = (pc is not None and + pc.get("name") == pl.get("name") and + pc.get("code") == pl.get("code") and + pc.get("dom_code") == pl.get("dom_code") and + pc.get("status") == pl.get("status")) + logging.info("programs.syncing: " + str(pl.get("id")) + " name: " + pl.get("name")) + + if pc is not None and not pc_pl_equals: + pl["modified"] = pl.get("modified", datetime.now(tz=timezone.utc).isoformat()) + local_program_more_recent = datetime.fromisoformat(pc.get("modified")).timestamp() < datetime.fromisoformat(pl.get("modified")).timestamp() + if syncmode == SYNC_UPSTREAM or (local_program_more_recent and syncmode == SYNC_BIDIRECTIONAL) and not to_be_deleted: + pc["data"] = pl.get("data") + pc["modified"] = pl.get("modified") + body = Program( + id=pc.get("id"), + org_id=pc.get("org_id"), + name=pl.get("name"), + description=pl.get("description"), + code=pl.get("code"), + dom_code=pl.get("dom_code"), + modified=pl.get("modified").isoformat(), + status='active', + ) + #logging.info("run.activities.cloud.saving") + api_response = api_instance.set_robot_program(pc.get("id"), body) + logging.info("programs.update.upstream: " + pl.get("name")) + elif syncmode == "d" or (not local_program_more_recent and syncmode == SYNC_BIDIRECTIONAL): + pl["data"] = pc.get("data") + pl["modified"] = pc.get("modified") + ProgramEngine.get_instance().save(program.Program.from_dict(pl)) + logging.info("programs.update.downstream: " + pl.get("name")) + elif pc is None and syncmode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: + body = Program( + id="", + org_id="", + name=pl.get("name"), + description=pl.get("description", ""), + code=pl.get("code"), + dom_code=pl.get("dom_code"), + modified=pl.get("modified", datetime.now(tz=timezone.utc).isoformat()), + status="active", + ) + api_response = api_instance.create_robot_program(body=body) + pl["id"] = api_response.body["id"] + pl["org_id"] = api_response.body["org_id"] + ProgramEngine.get_instance().save(program.Program.from_dict(pl)) + logging.info("programs.create.upstream: " + pl.get("name")) + elif pc is None and syncmode in [SYNC_DOWNSTREAM]: + ProgramEngine.get_instance().delete(pl.get("name")) + logging.info("programs.delete.downstream: " + pl.get("name")) + + # manage programs not present locally in "active" status + for k, pc in p_c_m.items(): + if p_l_m.get(k) is None and syncmode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: + pl = program.Program(name=pc.get("name"), + code=pc.get("code"), + dom_code=pc.get("dom_code"), + default=False, + id=pc.get("id"), + modified=datetime.fromisoformat(pc.get("modified")), + status=pc.get("status")) + ProgramEngine.get_instance().save(pl) + logging.info("programs.create.downstream: " + pc.get("name")) + + # manage programs to be deleted locally and upstream + for pl in programs_to_be_deleted: + if p.get("id") is not None: + logging.info("programs.delete.upstream: " + pl.get("name")) + api_response = api_instance.delete_robot_program(path_params={"program_id":pl.get("id")}) + # delete locally permanently + ProgramEngine.get_instance().delete(pl.get("name"), logical=False) + + except cloud_api_robot_client.ApiException as e: + logging.warn("Exception when calling programs RobotSyncApi: %s\n" % e) \ No newline at end of file diff --git a/coderbot/program.py b/coderbot/program.py index 6e41afee..ce787bbf 100644 --- a/coderbot/program.py +++ b/coderbot/program.py @@ -43,6 +43,8 @@ PROGRAM_SUFFIX = ".json" PROGRAMS_DB = "data/programs.json" PROGRAMS_PATH_DEFAULTS = "defaults/programs/" +PROGRAM_STATUS_ACTIVE = "active" +PROGRAM_STATUS_DELETED = "deleted" musicPackageManager = musicPackages.MusicPackageManager.get_instance() @@ -80,20 +82,22 @@ def __init__(self): self._program = None self._log = "" self._programs = TinyDB(PROGRAMS_DB) + # initialise DB from default programs query = Query() self.lock = Lock() for dirname, dirnames, filenames, in os.walk(PROGRAMS_PATH_DEFAULTS): - dirnames for filename in filenames: if PROGRAM_PREFIX in filename: program_name = filename[len(PROGRAM_PREFIX):-len(PROGRAM_SUFFIX)] - logging.info("adding program %s in path %s as default %r", program_name, dirname, ("default" in dirname)) - with open(os.path.join(dirname, filename), "r") as f: - program_dict = json.load(f) - program_dict["default"] = "default" in dirname - program = Program.from_dict(program_dict) - self.save(program) + if self.load(program_name) is None: + logging.info("adding program %s in path %s as default %r", program_name, dirname, ("default" in dirname)) + with open(os.path.join(dirname, filename), "r") as f: + program_dict = json.load(f) + program_dict["default"] = "default" in dirname + program_dict["status"] = PROGRAM_STATUS_ACTIVE + program = Program.from_dict(program_dict) + self.save(program) @classmethod def get_instance(cls): @@ -101,12 +105,19 @@ def get_instance(cls): cls._instance = ProgramEngine() return cls._instance - def prog_list(self): - return self._programs.all() + def prog_list(self, active_only = True): + programs = None + query = Query() + if active_only: + programs = self._programs.search(query.status == PROGRAM_STATUS_ACTIVE) + else: + programs = self._programs.all() + return programs def save(self, program): with self.lock: query = Query() + program._modified = datetime.now() self._program = program program_db_entry = self._program.as_dict() if self._programs.search(query.name == program.name) != []: @@ -120,19 +131,27 @@ def load(self, name): program_db_entries = self._programs.search(query.name == name) if len(program_db_entries) > 0: prog_db_entry = program_db_entries[0] - logging.debug(prog_db_entry) + #logging.debug(prog_db_entry) self._program = Program.from_dict(prog_db_entry) return self._program return None - def delete(self, name): + def delete(self, name, logical = True): with self.lock: query = Query() - program_db_entries = self._programs.search(query.name == name) - self._programs.remove(query.name == name) + program_db_entries = self._programs.search((query.name == name) & (query.default == False) & (query.status == PROGRAM_STATUS_ACTIVE)) + if len(program_db_entries) > 0: + program_db_entry = program_db_entries[0] + if logical: + program_db_entry["status"] = PROGRAM_STATUS_DELETED + program_db_entry["modified"] = datetime.now().isoformat() + self._programs.update(program_db_entry, query.name == name) + else: + self._programs.remove(query.name == name) + return None def create(self, name, code): - self._program = Program(name, code) + self._program = Program(name, code, modified=datetime.now()) return self._program def is_running(self, name): @@ -160,7 +179,7 @@ class Program: def dom_code(self): return self._dom_code - def __init__(self, name, code=None, dom_code=None, default=False, id=None, modified=None): + def __init__(self, name, code=None, dom_code=None, default=False, id=None, modified=None, status=None): self._thread = None self.name = name self._dom_code = dom_code @@ -168,6 +187,7 @@ def __init__(self, name, code=None, dom_code=None, default=False, id=None, modif self._default = default self._id = id self._modified = modified + self._status = status def execute(self, options={}): if self._running: @@ -247,7 +267,8 @@ def as_dict(self): 'code': self._code, 'default': self._default, 'id': self._id, - 'modified': self._modified.isoformat()} + 'modified': self._modified.isoformat(), + 'status': self._status} @classmethod def from_dict(cls, amap): @@ -256,4 +277,5 @@ def from_dict(cls, amap): code=amap['code'], default=amap.get('default', False), id=amap.get('id', None), - modified=datetime.fromisoformat(amap.get('modified', datetime.now().isoformat()))) + modified=datetime.fromisoformat(amap.get('modified', datetime.now().isoformat())), + status=amap.get('status', None),) diff --git a/defaults/programs/program_demo_ar_tags.json b/defaults/programs/program_demo_ar_tags.json index 329f45d9..86699bac 100644 --- a/defaults/programs/program_demo_ar_tags.json +++ b/defaults/programs/program_demo_ar_tags.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"t0%]}C@b{,qd7|sPe9zc\">tag_map</variable><variable type=\"\" id=\"6J?]Su~9cMcJ?1k)5D+=\">code</variable><variable type=\"\" id=\"w5)*3TcHccLvv^WOkh`c\">lista</variable><variable type=\"\" id=\"1J4H~VmQG*H$]$Q_:B__\">codes</variable><variable type=\"\" id=\"NC[lQ:--CtUITd)_|c$p\">positions</variable></variables><block type=\"controls_whileUntil\" id=\"@h-]#0?:MKRG}h:8:^x9\" x=\"-30\" y=\"144\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"#`fvr:O?_:Ttu0Bf{!]|\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"=^-j5Ga1MVnuBee97Y@C\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field><value name=\"VALUE\"><block type=\"coderbot_adv_findARCode\" id=\"s#f+e.r41WtcACO*8E@R\"></block></value><next><block type=\"variables_set\" id=\"#WGMDf[e(XBFiFV~%T{/\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"8n882RO_@|$b|*I#O`vD\"><value name=\"key\"><block type=\"text\" id=\"o)iJvT6q3wE1n$|w?}@W\"><field name=\"TEXT\">codes</field></block></value><value name=\"map\"><block type=\"variables_get\" id=\"jCx{KU9(=6P@.|peNlXN\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field></block></value></block></value><next><block type=\"variables_set\" id=\"bD=(HSHU48zl0{-/~noc\"><field name=\"VAR\" id=\"NC[lQ:--CtUITd)_|c$p\" variabletype=\"\">positions</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"#vbA+ig3tU@xSb1A|_w2\"><value name=\"key\"><block type=\"text\" id=\"i9_5n1O#`=t.~U,8FpGw\"><field name=\"TEXT\">positions</field></block></value><value name=\"map\"><block type=\"variables_get\" id=\"_JBza([QOX!qv/3VdYg9\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field></block></value></block></value><next><block type=\"controls_if\" id=\"OGk43S34JND/,jXGeVxz\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"0JLvc%7rD_C|!6cqFw-$\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"lists_length\" id=\"J_lY]]zCbQ[u!MMD-Id2\"><value name=\"VALUE\"><block type=\"variables_get\" id=\"kD{*,b/[9X1eU%FDp-mJ\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"EL*s.|ZMPGGbeVRYLFL8\"><field name=\"NUM\">0</field></block></value></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\"}|0Q`9cnLb|W)A4rACn(\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"SCm%!EpAerkyxrIF#P,5\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"lists_getIndex\" id=\"0NuaF,a-Mq%n]0F5yO71\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">LAST</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"h*z9nE!]v$fkNq=L9Z1~\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"TufaIZ~qb|Vm:zW)ks^F\"><field name=\"VAR\" id=\"NC[lQ:--CtUITd)_|c$p\" variabletype=\"\">positions</field></block></value></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"PCV}Dn!d_nmNHl([4UL8\"><field name=\"NUM\">150</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"k,p,V2i8b9cLa+XvIA1(\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\":+(Y+3IFohgd9%TmK,~h\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"@3wq8S#-um/Akpz8P@)N\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value></block></value><next><block type=\"text_print\" id=\"{9n*QwIw`Xz2rr%]!||i\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"g(BLm4y~J!I]Is)_+e.G\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value><next><block type=\"controls_if\" id=\"a-*{EC|T*!~|Jy1T;ky#\"><mutation elseif=\"4\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"vBhZBNkW2fzfWPMBh7PA\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"|hM?o_^1/MjiZMk9f-Hi\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"T)cl7En!l}Tz;C{RAQmS\"><field name=\"NUM\">1</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"Qf$Tb:D7*.]1HC0#SV-w\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"),wc.^}!FuO^[.fR5q+.\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"LvWv=:PuvKwdQKUqC!?Y\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_adv_move\" id=\"ks-wQ/9rha8HgY/5D7h8\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"QC$[#;#k/{[cXjT9|rFM\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"r7k/daFIIP-h9r4]b*[I\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"1Bn+v{5X{t^w6~QWeM49\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"eortt4PGO/b|wmiM5W[m\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"lmmlOegf8o|uu},4OJNW\"><field name=\"NUM\">2</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"w$$-?Uh:1Rl@;`E*Av6C\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"F:8LVYpTX]{Ox!iCa[U*\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"O)?`ZH~wDS@v!2JAwVA8\"><field name=\"NUM\">3</field></block></value></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\";I.JQ{LcQebMq+Nm7o?I\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"|/1VTr97/4/eDb~hP?{g\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"{/N?L?9p9,Vpq9+JpM+}\"><field name=\"NUM\">3</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_move\" id=\"[.uLTR$Q5eNd8!6wtvt=\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"Qzrz#P^X_/TaN@zz_wv`\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"XLk{ic:(6Z=]u-mXr$5#\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_adv_move\" id=\"VbCuoNCr6`._jSHeX}u%\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"fuihEymc@dwWL(CFQTX#\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"sm0p34bg|Tw%*:JTUF_i\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF3\"><block type=\"logic_compare\" id=\"Ma(^bi?_`^YErYgp4h,P\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"r@fO;U{M?YQ=Fj9rJJtD\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"F./nuSmkfx;j=a.Xb||H\"><field name=\"NUM\">4</field></block></value></block></value><statement name=\"DO3\"><block type=\"controls_repeat_ext\" id=\"!*8%}BA^?C8ncHv`O=y;\"><value name=\"TIMES\"><block type=\"math_number\" id=\"mmRw*r1VW@9EOf*~U`(:\"><field name=\"NUM\">2</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"h|=HGhp,p%JLZ6SjVA]d\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"ZM(/`ez$r4zl0JJXT(4v\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"7j.A;~YcadM%5QQe2n{R\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_adv_move\" id=\"YI6yNSOV`Zs^(Ys}w{A4\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"Co1AlC0ej9L8xK:DuSzB\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"E3tV*]cN%|8g@UilswEz\"><field name=\"NUM\">0.5</field></block></value></block></next></block></statement><next><block type=\"coderbot_audio_say\" id=\"6IK2cc.l8ZX7+=V*IFjT\"><field name=\"LOCALE\">it</field><value name=\"TEXT\"><block type=\"text\" id=\"+%T8MdX}|,B;r,=+S|Nj\"><field name=\"TEXT\">Sono arrivato!</field></block></value></block></next></block></statement><value name=\"IF4\"><block type=\"logic_compare\" id=\"unM/bY{:-`/BAwdbil*~\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\")HXZ]{NR`iX]-+gBKya6\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"MTJWF/*U[,/Aq=)gUK~@\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO4\"><block type=\"coderbot_audio_say\" id=\"$WB=k8dnPq;7!6KtgGSL\"><field name=\"LOCALE\">it</field><value name=\"TEXT\"><block type=\"text\" id=\"KuYp/v**F!_(?,!?~rQp\"><field name=\"TEXT\">Attenzione!</field></block></value></block></statement></block></next></block></next></block></statement></block></statement><next><block type=\"text_print\" id=\"7BYNgrmH0+*5Apcu|R[%\"><value name=\"TEXT\"><block type=\"text\" id=\"YMLXch,ZSheJiLbJ]h~f\"><field name=\"TEXT\"></field></block></value></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "tag_map = None\ncode = None\nlista = None\ncodes = None\npositions = None\n\n\nwhile True:\n get_prog_eng().check_end()\n tag_map = get_cam().find_ar_code()\n codes = tag_map.get('codes')\n positions = tag_map.get('positions')\n if len(codes) > 0:\n if positions[0][-1] > 150:\n code = codes[0]\n get_cam().set_text(codes)\n if code == 1:\n get_bot().forward(speed=100, elapse=1)\n get_bot().left(speed=100, elapse=1)\n elif code == 2:\n get_bot().forward(speed=100, elapse=3)\n elif code == 3:\n get_bot().forward(speed=100, elapse=1)\n get_bot().right(speed=100, elapse=1)\n elif code == 4:\n for count in range(2):\n get_prog_eng().check_end()\n get_bot().right(speed=100, elapse=0.5)\n get_bot().left(speed=100, elapse=0.5)\n get_audio().say('Sono arrivato!', locale=\"it\")\n elif code == 5:\n get_audio().say('Attenzione!', locale=\"it\")\n get_cam().set_text('')\n", "name": "ar_bot"} \ No newline at end of file +{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"t0%]}C@b{,qd7|sPe9zc\">tag_map</variable><variable type=\"\" id=\"6J?]Su~9cMcJ?1k)5D+=\">code</variable><variable type=\"\" id=\"w5)*3TcHccLvv^WOkh`c\">lista</variable><variable type=\"\" id=\"1J4H~VmQG*H$]$Q_:B__\">codes</variable><variable type=\"\" id=\"NC[lQ:--CtUITd)_|c$p\">positions</variable></variables><block type=\"controls_whileUntil\" id=\"@h-]#0?:MKRG}h:8:^x9\" x=\"-30\" y=\"144\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"#`fvr:O?_:Ttu0Bf{!]|\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"=^-j5Ga1MVnuBee97Y@C\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field><value name=\"VALUE\"><block type=\"coderbot_adv_findARCode\" id=\"s#f+e.r41WtcACO*8E@R\"></block></value><next><block type=\"variables_set\" id=\"#WGMDf[e(XBFiFV~%T{/\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"8n882RO_@|$b|*I#O`vD\"><value name=\"key\"><block type=\"text\" id=\"o)iJvT6q3wE1n$|w?}@W\"><field name=\"TEXT\">codes</field></block></value><value name=\"map\"><block type=\"variables_get\" id=\"jCx{KU9(=6P@.|peNlXN\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field></block></value></block></value><next><block type=\"variables_set\" id=\"bD=(HSHU48zl0{-/~noc\"><field name=\"VAR\" id=\"NC[lQ:--CtUITd)_|c$p\" variabletype=\"\">positions</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"#vbA+ig3tU@xSb1A|_w2\"><value name=\"key\"><block type=\"text\" id=\"i9_5n1O#`=t.~U,8FpGw\"><field name=\"TEXT\">positions</field></block></value><value name=\"map\"><block type=\"variables_get\" id=\"_JBza([QOX!qv/3VdYg9\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field></block></value></block></value><next><block type=\"controls_if\" id=\"OGk43S34JND/,jXGeVxz\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"0JLvc%7rD_C|!6cqFw-$\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"lists_length\" id=\"J_lY]]zCbQ[u!MMD-Id2\"><value name=\"VALUE\"><block type=\"variables_get\" id=\"kD{*,b/[9X1eU%FDp-mJ\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"EL*s.|ZMPGGbeVRYLFL8\"><field name=\"NUM\">0</field></block></value></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\"}|0Q`9cnLb|W)A4rACn(\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"SCm%!EpAerkyxrIF#P,5\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"lists_getIndex\" id=\"0NuaF,a-Mq%n]0F5yO71\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">LAST</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"h*z9nE!]v$fkNq=L9Z1~\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"TufaIZ~qb|Vm:zW)ks^F\"><field name=\"VAR\" id=\"NC[lQ:--CtUITd)_|c$p\" variabletype=\"\">positions</field></block></value></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"PCV}Dn!d_nmNHl([4UL8\"><field name=\"NUM\">150</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"k,p,V2i8b9cLa+XvIA1(\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\":+(Y+3IFohgd9%TmK,~h\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"@3wq8S#-um/Akpz8P@)N\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value></block></value><next><block type=\"text_print\" id=\"{9n*QwIw`Xz2rr%]!||i\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"g(BLm4y~J!I]Is)_+e.G\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value><next><block type=\"controls_if\" id=\"a-*{EC|T*!~|Jy1T;ky#\"><mutation elseif=\"4\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"vBhZBNkW2fzfWPMBh7PA\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"|hM?o_^1/MjiZMk9f-Hi\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"T)cl7En!l}Tz;C{RAQmS\"><field name=\"NUM\">1</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"Qf$Tb:D7*.]1HC0#SV-w\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"),wc.^}!FuO^[.fR5q+.\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"LvWv=:PuvKwdQKUqC!?Y\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_adv_move\" id=\"ks-wQ/9rha8HgY/5D7h8\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"QC$[#;#k/{[cXjT9|rFM\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"r7k/daFIIP-h9r4]b*[I\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"1Bn+v{5X{t^w6~QWeM49\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"eortt4PGO/b|wmiM5W[m\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"lmmlOegf8o|uu},4OJNW\"><field name=\"NUM\">2</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"w$$-?Uh:1Rl@;`E*Av6C\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"F:8LVYpTX]{Ox!iCa[U*\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"O)?`ZH~wDS@v!2JAwVA8\"><field name=\"NUM\">3</field></block></value></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\";I.JQ{LcQebMq+Nm7o?I\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"|/1VTr97/4/eDb~hP?{g\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"{/N?L?9p9,Vpq9+JpM+}\"><field name=\"NUM\">3</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_move\" id=\"[.uLTR$Q5eNd8!6wtvt=\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"Qzrz#P^X_/TaN@zz_wv`\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"XLk{ic:(6Z=]u-mXr$5#\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_adv_move\" id=\"VbCuoNCr6`._jSHeX}u%\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"fuihEymc@dwWL(CFQTX#\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"sm0p34bg|Tw%*:JTUF_i\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF3\"><block type=\"logic_compare\" id=\"Ma(^bi?_`^YErYgp4h,P\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"r@fO;U{M?YQ=Fj9rJJtD\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"F./nuSmkfx;j=a.Xb||H\"><field name=\"NUM\">4</field></block></value></block></value><statement name=\"DO3\"><block type=\"controls_repeat_ext\" id=\"!*8%}BA^?C8ncHv`O=y;\"><value name=\"TIMES\"><block type=\"math_number\" id=\"mmRw*r1VW@9EOf*~U`(:\"><field name=\"NUM\">2</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"h|=HGhp,p%JLZ6SjVA]d\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"ZM(/`ez$r4zl0JJXT(4v\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"7j.A;~YcadM%5QQe2n{R\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_adv_move\" id=\"YI6yNSOV`Zs^(Ys}w{A4\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"Co1AlC0ej9L8xK:DuSzB\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"E3tV*]cN%|8g@UilswEz\"><field name=\"NUM\">0.5</field></block></value></block></next></block></statement><next><block type=\"coderbot_audio_say\" id=\"6IK2cc.l8ZX7+=V*IFjT\"><field name=\"LOCALE\">it</field><value name=\"TEXT\"><block type=\"text\" id=\"+%T8MdX}|,B;r,=+S|Nj\"><field name=\"TEXT\">Sono arrivato!</field></block></value></block></next></block></statement><value name=\"IF4\"><block type=\"logic_compare\" id=\"unM/bY{:-`/BAwdbil*~\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\")HXZ]{NR`iX]-+gBKya6\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"MTJWF/*U[,/Aq=)gUK~@\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO4\"><block type=\"coderbot_audio_say\" id=\"$WB=k8dnPq;7!6KtgGSL\"><field name=\"LOCALE\">it</field><value name=\"TEXT\"><block type=\"text\" id=\"KuYp/v**F!_(?,!?~rQp\"><field name=\"TEXT\">Attenzione!</field></block></value></block></statement></block></next></block></next></block></statement></block></statement><next><block type=\"text_print\" id=\"7BYNgrmH0+*5Apcu|R[%\"><value name=\"TEXT\"><block type=\"text\" id=\"YMLXch,ZSheJiLbJ]h~f\"><field name=\"TEXT\"></field></block></value></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "tag_map = None\ncode = None\nlista = None\ncodes = None\npositions = None\n\n\nwhile True:\n get_prog_eng().check_end()\n tag_map = get_cam().find_ar_code()\n codes = tag_map.get('codes')\n positions = tag_map.get('positions')\n if len(codes) > 0:\n if positions[0][-1] > 150:\n code = codes[0]\n get_cam().set_text(codes)\n if code == 1:\n get_bot().forward(speed=100, elapse=1)\n get_bot().left(speed=100, elapse=1)\n elif code == 2:\n get_bot().forward(speed=100, elapse=3)\n elif code == 3:\n get_bot().forward(speed=100, elapse=1)\n get_bot().right(speed=100, elapse=1)\n elif code == 4:\n for count in range(2):\n get_prog_eng().check_end()\n get_bot().right(speed=100, elapse=0.5)\n get_bot().left(speed=100, elapse=0.5)\n get_audio().say('Sono arrivato!', locale=\"it\")\n elif code == 5:\n get_audio().say('Attenzione!', locale=\"it\")\n get_cam().set_text('')\n", "name": "demo_ar_tags"} \ No newline at end of file diff --git a/defaults/programs/program_demo_cat_follower.json b/defaults/programs/program_demo_cat_follower.json index 2c744cc5..905374e6 100644 --- a/defaults/programs/program_demo_cat_follower.json +++ b/defaults/programs/program_demo_cat_follower.json @@ -1 +1 @@ -{"name": "cat_follower", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\",?YI{f}$o~t3-v%!oOh`\">object</variable><variable id=\"9layCHw;-1P!)]pX+m2W\">class</variable><variable id=\"80w]HhW?e7QM%yfJ*[BS\">position</variable><variable id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</variable></variables><block type=\"controls_whileUntil\" id=\"[^a!+/Zsc!iXdJ*Z-Go#\" x=\"43\" y=\"19\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"2Qi5#s+x(vg-{l2glVGI\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"0Y_GS_fw!h^YTb,XeKz#\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"_GYqAA5bQtVd@ICQGW(U\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"coderbot_adv_cnn_detect_objects\" id=\"m(x+AUHK}k[f:xAb;!iH\"><field name=\"MODEL\">generic_object_detect</field></block></value></block></value><next><block type=\"variables_set\" id=\":mq1jiC7D(V_yjV]p+bj\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"gg?Rm?i]1V[@Sk0~,6}U\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"jWBE:9@+HD)M5w(R6-+R\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value></block></value><next><block type=\"controls_if\" id=\"SoONo/Qzd^PSRs3kDLW4\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"girWO4BMe2k@24#mK9W|\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"9oEqGs$i`cb!|tDMGcUs\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field></block></value><value name=\"B\"><block type=\"text\" id=\"57hUIBHt5-};Ur^Ym(`p\"><field name=\"TEXT\">cat</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\":krqJ`zM+j//B~motZ@5\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"n*i|7Ey@DqvX+8X;^2fb\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"$p#z76Ff-*8z$I:6(%:F\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"?s]?2J@-Pc6i1f-y{[09\"><field name=\"NUM\">3</field></block></value></block></value><next><block type=\"variables_set\" id=\"[:tR1VyS6qeSU?!D)`sN\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field><value name=\"VALUE\"><block type=\"math_arithmetic\" id=\"*U,nQR1[HxPKn8W%pkCz\"><field name=\"OP\">DIVIDE</field><value name=\"A\"><block type=\"math_arithmetic\" id=\"uc.~ggYr?xqXV/.F7s1u\"><field name=\"OP\">ADD</field><value name=\"A\"><block type=\"lists_getIndex\" id=\"kuISxM{Klu36vQ]Jo+P@\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"?gyq($9~Uq.~3XY8_J9)\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"(1G%d4(*1Vqq?1xk.^{t\"><field name=\"NUM\">1</field></block></value></block></value><value name=\"B\"><block type=\"lists_getIndex\" id=\".Xk?/{p+tLXc=}|OA82n\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"|IdyV?|5py+=3,0!:z_A\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\",Me8:/`3uBpfuBZrA)sp\"><field name=\"NUM\">3</field></block></value></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"m~K8F`G6T$ha/a^LdD5Z\"><field name=\"NUM\">2</field></block></value></block></value><next><block type=\"text_print\" id=\"|,^zQ|VUQq/(lt,K`8y0\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"#QdSbUp(4Hn;Xk(4xe0G\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field></block></value><next><block type=\"controls_if\" id=\"}1i(Om9l5~9.WOIq!=W`\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"~.k].tdW8FF4#-(AeXsM\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\")KUmL+N6#~?rM~GnqH[G\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"l*=6l=SR/g6%(|]$i;}C\"><field name=\"NUM\">40</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\":YSGyu*XL_u{)zQBD:{X\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"de??^JX,i_mkb$RsmNXs\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"zs-Cre_[w%5@VNoMwi;l\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"+S5!K$WfFhj@QhRSokhV\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"J%|{#:u3(!lcF4.B~gQt\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"[gg?3(+hO-?.%qW,`@t~\"><field name=\"NUM\">60</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"vA*_d?-Bwh55o,{*%v:G\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"W}pFMYn/}2RnG+E86e~v\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"as/ZY,XwrTw`@Z~O9B`$\"><field name=\"NUM\">0.1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\"Xs:ewoKw*Fg3UK*sRCNm\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"qSFO9:h}?s~cD:hj(r:(\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"Nh^fXOiu1$x8[$i1C2IV\"><field name=\"NUM\">0.2</field></block></value></block></statement></block></next></block></next></block></next></block></statement><statement name=\"ELSE\"><block type=\"text_print\" id=\"PAYJ[1S)`0Gl#=M`cX=g\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"2nPmKkqF|Y:u3?r=5y|n\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "object2 = None\nclass2 = None\nposition = None\npos_x = None\n\n\nwhile True:\n get_prog_eng().check_end()\n object2 = get_cam().cnn_detect_objects(\"generic_object_detect\")[0]\n class2 = object2[0]\n if class2 == 'cat':\n position = object2[2]\n pos_x = (position[0] + position[2]) / 2\n get_cam().set_text(class2)\n if pos_x < 40:\n get_bot().left(speed=60, elapse=0.1)\n elif pos_x > 60:\n get_bot().right(speed=60, elapse=0.1)\n else:\n get_bot().forward(speed=100, elapse=0.2)\n else:\n get_cam().set_text(object2)\n"} \ No newline at end of file +{"name": "demo_cat_follower", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\",?YI{f}$o~t3-v%!oOh`\">object</variable><variable id=\"9layCHw;-1P!)]pX+m2W\">class</variable><variable id=\"80w]HhW?e7QM%yfJ*[BS\">position</variable><variable id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</variable></variables><block type=\"controls_whileUntil\" id=\"[^a!+/Zsc!iXdJ*Z-Go#\" x=\"43\" y=\"19\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"2Qi5#s+x(vg-{l2glVGI\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"0Y_GS_fw!h^YTb,XeKz#\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"_GYqAA5bQtVd@ICQGW(U\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"coderbot_adv_cnn_detect_objects\" id=\"m(x+AUHK}k[f:xAb;!iH\"><field name=\"MODEL\">generic_object_detect</field></block></value></block></value><next><block type=\"variables_set\" id=\":mq1jiC7D(V_yjV]p+bj\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"gg?Rm?i]1V[@Sk0~,6}U\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"jWBE:9@+HD)M5w(R6-+R\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value></block></value><next><block type=\"controls_if\" id=\"SoONo/Qzd^PSRs3kDLW4\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"girWO4BMe2k@24#mK9W|\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"9oEqGs$i`cb!|tDMGcUs\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field></block></value><value name=\"B\"><block type=\"text\" id=\"57hUIBHt5-};Ur^Ym(`p\"><field name=\"TEXT\">cat</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\":krqJ`zM+j//B~motZ@5\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"n*i|7Ey@DqvX+8X;^2fb\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"$p#z76Ff-*8z$I:6(%:F\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"?s]?2J@-Pc6i1f-y{[09\"><field name=\"NUM\">3</field></block></value></block></value><next><block type=\"variables_set\" id=\"[:tR1VyS6qeSU?!D)`sN\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field><value name=\"VALUE\"><block type=\"math_arithmetic\" id=\"*U,nQR1[HxPKn8W%pkCz\"><field name=\"OP\">DIVIDE</field><value name=\"A\"><block type=\"math_arithmetic\" id=\"uc.~ggYr?xqXV/.F7s1u\"><field name=\"OP\">ADD</field><value name=\"A\"><block type=\"lists_getIndex\" id=\"kuISxM{Klu36vQ]Jo+P@\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"?gyq($9~Uq.~3XY8_J9)\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"(1G%d4(*1Vqq?1xk.^{t\"><field name=\"NUM\">1</field></block></value></block></value><value name=\"B\"><block type=\"lists_getIndex\" id=\".Xk?/{p+tLXc=}|OA82n\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"|IdyV?|5py+=3,0!:z_A\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\",Me8:/`3uBpfuBZrA)sp\"><field name=\"NUM\">3</field></block></value></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"m~K8F`G6T$ha/a^LdD5Z\"><field name=\"NUM\">2</field></block></value></block></value><next><block type=\"text_print\" id=\"|,^zQ|VUQq/(lt,K`8y0\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"#QdSbUp(4Hn;Xk(4xe0G\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field></block></value><next><block type=\"controls_if\" id=\"}1i(Om9l5~9.WOIq!=W`\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"~.k].tdW8FF4#-(AeXsM\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\")KUmL+N6#~?rM~GnqH[G\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"l*=6l=SR/g6%(|]$i;}C\"><field name=\"NUM\">40</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\":YSGyu*XL_u{)zQBD:{X\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"de??^JX,i_mkb$RsmNXs\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"zs-Cre_[w%5@VNoMwi;l\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"+S5!K$WfFhj@QhRSokhV\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"J%|{#:u3(!lcF4.B~gQt\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"[gg?3(+hO-?.%qW,`@t~\"><field name=\"NUM\">60</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"vA*_d?-Bwh55o,{*%v:G\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"W}pFMYn/}2RnG+E86e~v\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"as/ZY,XwrTw`@Z~O9B`$\"><field name=\"NUM\">0.1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\"Xs:ewoKw*Fg3UK*sRCNm\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"qSFO9:h}?s~cD:hj(r:(\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"Nh^fXOiu1$x8[$i1C2IV\"><field name=\"NUM\">0.2</field></block></value></block></statement></block></next></block></next></block></next></block></statement><statement name=\"ELSE\"><block type=\"text_print\" id=\"PAYJ[1S)`0Gl#=M`cX=g\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"2nPmKkqF|Y:u3?r=5y|n\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "object2 = None\nclass2 = None\nposition = None\npos_x = None\n\n\nwhile True:\n get_prog_eng().check_end()\n object2 = get_cam().cnn_detect_objects(\"generic_object_detect\")[0]\n class2 = object2[0]\n if class2 == 'cat':\n position = object2[2]\n pos_x = (position[0] + position[2]) / 2\n get_cam().set_text(class2)\n if pos_x < 40:\n get_bot().left(speed=60, elapse=0.1)\n elif pos_x > 60:\n get_bot().right(speed=60, elapse=0.1)\n else:\n get_bot().forward(speed=100, elapse=0.2)\n else:\n get_cam().set_text(object2)\n"} \ No newline at end of file diff --git a/defaults/programs/program_demo_color_seeker.json b/defaults/programs/program_demo_color_seeker.json index 75c14d28..5c6e53ae 100644 --- a/defaults/programs/program_demo_color_seeker.json +++ b/defaults/programs/program_demo_color_seeker.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"1\" y=\"90\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">dist</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">DIST</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"variables_set\"><field name=\"VAR\">angle</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">ANGLE</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"text_join\"><mutation items=\"4\"></mutation><value name=\"ADD0\"><block type=\"text\"><field name=\"TEXT\">Distance: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"ADD2\"><block type=\"text\"><field name=\"TEXT\"> angle: </field></block></value><value name=\"ADD3\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value></block></value><next><block type=\"controls_if\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">32</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_operation\"><field name=\"OP\">AND</field><value name=\"A\"><block type=\"logic_compare\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">28</field></block></value></block></value><value name=\"B\"><block type=\"logic_compare\"><field name=\"OP\">GTE</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">0</field></block></value></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><next><block type=\"controls_if\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">30</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">-5</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">30</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "dist = None\nangle = None\n\n\nwhile True:\n get_prog_eng().check_end()\n dist = get_cam().find_color('#96b73c')[0]\n angle = get_cam().find_color('#96b73c')[1]\n get_cam().set_text(''.join([str(temp_value) for temp_value in ['Distance: ', dist, ' angle: ', angle]]))\n if dist > 32:\n get_bot().forward(speed=100, elapse=0.1)\n elif dist < 28 and dist >= 0:\n get_bot().backward(speed=100, elapse=0.1)\n if angle > 5:\n get_bot().right(speed=30, elapse=0.1)\n elif angle < -5:\n get_bot().left(speed=30, elapse=0.1)\n", "name": "colour_seeker"} \ No newline at end of file +{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"1\" y=\"90\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">dist</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">DIST</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"variables_set\"><field name=\"VAR\">angle</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">ANGLE</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"text_join\"><mutation items=\"4\"></mutation><value name=\"ADD0\"><block type=\"text\"><field name=\"TEXT\">Distance: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"ADD2\"><block type=\"text\"><field name=\"TEXT\"> angle: </field></block></value><value name=\"ADD3\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value></block></value><next><block type=\"controls_if\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">32</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_operation\"><field name=\"OP\">AND</field><value name=\"A\"><block type=\"logic_compare\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">28</field></block></value></block></value><value name=\"B\"><block type=\"logic_compare\"><field name=\"OP\">GTE</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">0</field></block></value></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><next><block type=\"controls_if\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">30</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">-5</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">30</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "dist = None\nangle = None\n\n\nwhile True:\n get_prog_eng().check_end()\n dist = get_cam().find_color('#96b73c')[0]\n angle = get_cam().find_color('#96b73c')[1]\n get_cam().set_text(''.join([str(temp_value) for temp_value in ['Distance: ', dist, ' angle: ', angle]]))\n if dist > 32:\n get_bot().forward(speed=100, elapse=0.1)\n elif dist < 28 and dist >= 0:\n get_bot().backward(speed=100, elapse=0.1)\n if angle > 5:\n get_bot().right(speed=30, elapse=0.1)\n elif angle < -5:\n get_bot().left(speed=30, elapse=0.1)\n", "name": "demo_color_seeker"} \ No newline at end of file diff --git a/defaults/programs/program_demo_io_ext.json b/defaults/programs/program_demo_io_ext.json index 3265bfcb..315d167b 100644 --- a/defaults/programs/program_demo_io_ext.json +++ b/defaults/programs/program_demo_io_ext.json @@ -1 +1 @@ -{"name": "test_io_ext", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</variable></variables><block type=\"controls_whileUntil\" id=\"Dl?:_j0SBuhadu{w@UF.\" x=\"228\" y=\"37\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"pJCxtUhR_b%x:dTqn9md\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"+v#-(`(Qm]QpW/]^kj=k\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field><value name=\"VALUE\"><block type=\"coderbot_atmega_get_input\" id=\"ai)*,59_NZc9svsP|JM:\"><field name=\"INPUT\">0</field></block></value><next><block type=\"text_print\" id=\"QtWQNQO[-l[BZ~e`Qmh$\"><value name=\"TEXT\"><block type=\"text_join\" id=\"1Ukw}Lu=x]S?%jKwDJJV\"><mutation items=\"2\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\"Y9wE(=ZJTe,Y=7yA$1+2\"><field name=\"TEXT\">Analog Input 1: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\" id=\"4QrPsC2-~_VL]6GoH_*O\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field></block></value></block></value><next><block type=\"controls_if\" id=\"le3Rmn/8;oI#ps$J,7la\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"pm_-a@W30t?pU$DT9!sX\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"IrfeoxR,w1!`9%NW+elg\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"R4b=e-`S!g*H6T7B1nel\"><field name=\"NUM\">100</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_atmega_set_output\" id=\"yvJ,i1lZv!^Q~}#Co+-i\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"Peb+]}4!:tv}p4J_B9]z\"><field name=\"BOOL\">TRUE</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_atmega_set_output\" id=\"z/@VGWnrW3D(x,d1SZ^y\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"$yU!z^ZFMBh!(m7s,9*:\"><field name=\"BOOL\">FALSE</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "Analog_Input_1 = None\n\n\nwhile True:\n get_prog_eng().check_end()\n Analog_Input_1 = get_atmega().get_input(0)\n get_cam().set_text('Analog Input 1: ' + str(Analog_Input_1))\n if Analog_Input_1 > 100:\n get_atmega().set_output(0, True)\n else:\n get_atmega().set_output(0, False)\n"} \ No newline at end of file +{"name": "demo_io_ext", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</variable></variables><block type=\"controls_whileUntil\" id=\"Dl?:_j0SBuhadu{w@UF.\" x=\"228\" y=\"37\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"pJCxtUhR_b%x:dTqn9md\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"+v#-(`(Qm]QpW/]^kj=k\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field><value name=\"VALUE\"><block type=\"coderbot_atmega_get_input\" id=\"ai)*,59_NZc9svsP|JM:\"><field name=\"INPUT\">0</field></block></value><next><block type=\"text_print\" id=\"QtWQNQO[-l[BZ~e`Qmh$\"><value name=\"TEXT\"><block type=\"text_join\" id=\"1Ukw}Lu=x]S?%jKwDJJV\"><mutation items=\"2\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\"Y9wE(=ZJTe,Y=7yA$1+2\"><field name=\"TEXT\">Analog Input 1: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\" id=\"4QrPsC2-~_VL]6GoH_*O\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field></block></value></block></value><next><block type=\"controls_if\" id=\"le3Rmn/8;oI#ps$J,7la\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"pm_-a@W30t?pU$DT9!sX\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"IrfeoxR,w1!`9%NW+elg\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"R4b=e-`S!g*H6T7B1nel\"><field name=\"NUM\">100</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_atmega_set_output\" id=\"yvJ,i1lZv!^Q~}#Co+-i\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"Peb+]}4!:tv}p4J_B9]z\"><field name=\"BOOL\">TRUE</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_atmega_set_output\" id=\"z/@VGWnrW3D(x,d1SZ^y\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"$yU!z^ZFMBh!(m7s,9*:\"><field name=\"BOOL\">FALSE</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "Analog_Input_1 = None\n\n\nwhile True:\n get_prog_eng().check_end()\n Analog_Input_1 = get_atmega().get_input(0)\n get_cam().set_text('Analog Input 1: ' + str(Analog_Input_1))\n if Analog_Input_1 > 100:\n get_atmega().set_output(0, True)\n else:\n get_atmega().set_output(0, False)\n"} \ No newline at end of file diff --git a/defaults/programs/program_demo_line_follower.json b/defaults/programs/program_demo_line_follower.json index da7ba861..2ad8fb82 100644 --- a/defaults/programs/program_demo_line_follower.json +++ b/defaults/programs/program_demo_line_follower.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"44C`F*i%?EbRAm0f[}XQ\">line_x_1</variable><variable type=\"\" id=\"BShIh7Dye|p!AtQ`p8wj\">lista</variable><variable type=\"\" id=\"(`T?t~cnldIn9}cU!6P3\">line_x_list</variable><variable type=\"\" id=\"+9O~W5dFyMgb4R9?j?2j\">line_x_2</variable><variable type=\"\" id=\"G;b/=HFbfhuxT|0?~S[r\">ar_code</variable><variable type=\"\" id=\"kOrv]Wo^Y7{4+#7gA`K;\">ar_code_list</variable></variables><block type=\"controls_whileUntil\" id=\"`]WZt9m4:b-6v?sR0a{6\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"?g7Pi#[#{_)~?7~!MUL]\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"n/Jg4jt-?ANdJFh!U#R}\"><field name=\"VAR\" id=\"(`T?t~cnldIn9}cU!6P3\" variabletype=\"\">line_x_list</field><value name=\"VALUE\"><block type=\"coderbot_adv_findLine\" id=\"|O16NyeI_GMcWz}e#ht9\"></block></value><next><block type=\"variables_set\" id=\"d:T;q-q)7$dJ(@9w7DF=\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"oA1x#4CMYuz}p|KK8e~S\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"CIJd6?@63y$}V34}.bC-\"><field name=\"VAR\" id=\"(`T?t~cnldIn9}cU!6P3\" variabletype=\"\">line_x_list</field></block></value></block></value><next><block type=\"variables_set\" id=\"S2ieOivJB5(|7?}~us@M\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"tgJS~3PX=0SJTSMlsaVv\"><value name=\"key\"><block type=\"text\" id=\"Wz#h:CVLwyX,^(^kc{B`\"><field name=\"TEXT\">codes</field></block></value><value name=\"map\"><block type=\"coderbot_adv_findARCode\" id=\"9$MM{KjS8lUj}A;=Pr(z\"></block></value></block></value><next><block type=\"controls_if\" id=\"IL@9S#Xl-hRa#LwNvh.g\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_negate\" id=\"XQTF1;SNhjc#]4#_}9wU\"><value name=\"BOOL\"><block type=\"lists_isEmpty\" id=\"b^36mV09/]tRws|?BYoK\"><value name=\"VALUE\"><block type=\"variables_get\" id=\";qp!b+zbymPr{3WAvNrG\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field></block></value></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"uv4pqKisw(|c:|d/Do%J\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"a0JACY?SyTgO21=or@D6\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"ySld:`sc3M4=IjeN*RuO\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field></block></value></block></value></block></statement><statement name=\"ELSE\"><block type=\"variables_set\" id=\"/f{XE@50=WxbI;,=TeW]\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field><value name=\"VALUE\"><block type=\"math_number\" id=\"@XV^(en_.lQ0_#rZkz}#\"><field name=\"NUM\">0</field></block></value></block></statement><next><block type=\"text_print\" id=\"{f1ctd/iW#D,le1V(Cy-\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"5VI:=npMdg$L|=e0/Okn\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><next><block type=\"controls_if\" id=\"GvDQg$7WT=Qq6HBCexdf\"><mutation elseif=\"2\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\")M6ls=nOUTB^J;|3-Q@=\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"Y9PB[dJ*r*.*=2([@JT:\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"e`kkA/p8dDJT4Iu`PtP|\"><field name=\"NUM\">1</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_motor\" id=\"mM!-gOyoBb8xLuEK}:PY\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"MV9CvsB9cK7#oJv5M+Gy\"><field name=\"NUM\">80</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"@I!w63)Db*b!^mzk?7b-\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"xz=GX~R6!L1Lz?RO%xSE\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"nSLX(4#c?i({f6gx}h$b\"><field name=\"NUM\">1000</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"3C{Tr^vc`K1K7@whf0+#\"><field name=\"NUM\">1000</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"0[pEKb#+c1ukccsj-HGU\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"!.x!ti5!Jl_Qyi_98vP:\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\":Omnr1TfVKRT,{x+CErC\"><field name=\"NUM\">2</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_motor\" id=\"^@Y|H7}/,1f%m;D)rsqN\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"tpQfUU_t1N9uX9DDLpNK\"><field name=\"NUM\">60</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"X__|/-/MQqilOsxKk.Vn\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"sUK%h7;p?NFy6ej0G@ad\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"55Q_(wsMzLOOTn,AJ*=o\"><field name=\"NUM\">2000</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"Q(U)4jCVk5tml,K%_m3X\"><field name=\"NUM\">1550</field></block></value></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\"-.]jhYzu{)[`q?J|G*@i\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"TYK1ggBo;v^8(fzNK!PO\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"D2;EP}Ok0vx,}R7Te.[g\"><field name=\"NUM\">6</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_motor\" id=\"FWt]Cn.Gx+x%y|4TMq*/\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"PN3gP4:wymcc7g[G,=JC\"><field name=\"NUM\">60</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"$svZ(tsG{Q]%-=QakU@7\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"IxJ8gaf@V.5xrl3X3yu0\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"1hpVYp0#go4@HCi%[MZ`\"><field name=\"NUM\">1550</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"ZuV9iU47evPA,S7J?s+@\"><field name=\"NUM\">2000</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"controls_if\" id=\"]Xst$#BXb%U~.5?C5fN1\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"PD.BkyibEtTX2,VtMdsc\"><field name=\"OP\">GTE</field><value name=\"A\"><block type=\"variables_get\" id=\"UWRm7PH[oi_n9oQsRDGd\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"V1b;v7$b+m#/u;2dm6H$\"><field name=\"NUM\">0</field></block></value></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\",?`$EcLs;XYj{O%B$A~o\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"0WmrG/knZBBpiHSDmLBJ\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"%amYL^tWO^t8nX`JBAEF\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"hIduK@,Vwz{H?bp[WPjj\"><field name=\"NUM\">60</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_motor\" id=\";vD-YiW9)qU8sg-}vcm1\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"((}~wa#@9K8b}RS#DSq?\"><field name=\"NUM\">40</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\":,f0J=^9v|J$I;5Ahy|K\"><field name=\"NUM\">-40</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"L48OY[hxw|)quL7-vkb^\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_arithmetic\" id=\"Upl0F:r{a0y5cdS.crj)\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"variables_get\" id=\"oS=EnUt$f^C5Vj!8|9C8\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"7~z_5vl91w!1jP(k.(Qd\"><field name=\"NUM\">50</field></block></value></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_arithmetic\" id=\"A~(#(]O_(kSZBIc4,yw@\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"variables_get\" id=\"Vuwafvcd/K_ph5^FX:%!\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"x$bmhmC2RW9ZOLL7FWHF\"><field name=\"NUM\">50</field></block></value></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"I)Gu5YQYkX.:()}l^{xg\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\"zCKv1.|-Rios8@h5ilIg\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"vJw^%jvK#eR95btK#CeU\"><field name=\"NUM\">40</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_motor\" id=\"w(zj/fW0HsEnX1*u!4O?\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"y+F~@jqeyB9bS]M=9}J}\"><field name=\"NUM\">-40</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"1/(])B%ubDAdndUnXxg-\"><field name=\"NUM\">40</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"{?IB?(nV;5%Nm_F$1rMX\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_arithmetic\" id=\";dV0cDAx~my3rojA^G|4\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"math_number\" id=\"o/=rp-ECY@EVjB8FV/0~\"><field name=\"NUM\">50</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"W;jmAc*0%%;8cx.}*jQL\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_arithmetic\" id=\"hYIe9z|NuF;9Um0Fk)mu\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"math_number\" id=\"b-Ei9$@yv*bVNNAauA+o\"><field name=\"NUM\">50</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"c?]Gby*%LO[jc{jaa%-9\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_motor\" id=\"O.;G[S8aWfdf|`/h*59@\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"I6+d!/%ONX{B=e8{n0kx\"><field name=\"NUM\">50</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"C*9^tnhIr1`.e{Ts56$Z\"><field name=\"NUM\">50</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"(0,tpOtURC`/@~c2LSVs\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"Ka-C|%Y8;GO(qa1sH:XG\"><field name=\"NUM\">150</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"xLy*EHb!}4NrV0`Z-_yZ\"><field name=\"NUM\">150</field></block></value></block></statement></block></statement></block></statement></block></next></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "line_x_1 = None\nlista = None\nline_x_list = None\nline_x_2 = None\nar_code = None\nar_code_list = None\n\n\nwhile True:\n get_prog_eng().check_end()\n line_x_list = get_cam().find_line()\n line_x_1 = line_x_list[0]\n ar_code_list = get_cam().find_ar_code().get('codes')\n if not not len(ar_code_list):\n ar_code = ar_code_list[0]\n else:\n ar_code = 0\n get_cam().set_text(ar_code)\n if ar_code == 1:\n get_bot().motor_control(speed_left=80, speed_right=80, elapse=-1, steps_left=1000, steps_right=1000)\n elif ar_code == 2:\n get_bot().motor_control(speed_left=60, speed_right=60, elapse=-1, steps_left=2000, steps_right=1550)\n elif ar_code == 6:\n get_bot().motor_control(speed_left=60, speed_right=60, elapse=-1, steps_left=1550, steps_right=2000)\n else:\n if line_x_1 >= 0:\n if line_x_1 > 60:\n get_bot().motor_control(speed_left=40, speed_right=-40, elapse=-1, steps_left=line_x_1 - 50, steps_right=line_x_1 - 50)\n elif line_x_1 < 40:\n get_bot().motor_control(speed_left=-40, speed_right=40, elapse=-1, steps_left=50 - line_x_1, steps_right=50 - line_x_1)\n else:\n get_bot().motor_control(speed_left=50, speed_right=50, elapse=-1, steps_left=150, steps_right=150)\n", "name": "line_follower"} \ No newline at end of file +{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"44C`F*i%?EbRAm0f[}XQ\">line_x_1</variable><variable type=\"\" id=\"BShIh7Dye|p!AtQ`p8wj\">lista</variable><variable type=\"\" id=\"(`T?t~cnldIn9}cU!6P3\">line_x_list</variable><variable type=\"\" id=\"+9O~W5dFyMgb4R9?j?2j\">line_x_2</variable><variable type=\"\" id=\"G;b/=HFbfhuxT|0?~S[r\">ar_code</variable><variable type=\"\" id=\"kOrv]Wo^Y7{4+#7gA`K;\">ar_code_list</variable></variables><block type=\"controls_whileUntil\" id=\"`]WZt9m4:b-6v?sR0a{6\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"?g7Pi#[#{_)~?7~!MUL]\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"n/Jg4jt-?ANdJFh!U#R}\"><field name=\"VAR\" id=\"(`T?t~cnldIn9}cU!6P3\" variabletype=\"\">line_x_list</field><value name=\"VALUE\"><block type=\"coderbot_adv_findLine\" id=\"|O16NyeI_GMcWz}e#ht9\"></block></value><next><block type=\"variables_set\" id=\"d:T;q-q)7$dJ(@9w7DF=\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"oA1x#4CMYuz}p|KK8e~S\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"CIJd6?@63y$}V34}.bC-\"><field name=\"VAR\" id=\"(`T?t~cnldIn9}cU!6P3\" variabletype=\"\">line_x_list</field></block></value></block></value><next><block type=\"variables_set\" id=\"S2ieOivJB5(|7?}~us@M\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"tgJS~3PX=0SJTSMlsaVv\"><value name=\"key\"><block type=\"text\" id=\"Wz#h:CVLwyX,^(^kc{B`\"><field name=\"TEXT\">codes</field></block></value><value name=\"map\"><block type=\"coderbot_adv_findARCode\" id=\"9$MM{KjS8lUj}A;=Pr(z\"></block></value></block></value><next><block type=\"controls_if\" id=\"IL@9S#Xl-hRa#LwNvh.g\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_negate\" id=\"XQTF1;SNhjc#]4#_}9wU\"><value name=\"BOOL\"><block type=\"lists_isEmpty\" id=\"b^36mV09/]tRws|?BYoK\"><value name=\"VALUE\"><block type=\"variables_get\" id=\";qp!b+zbymPr{3WAvNrG\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field></block></value></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"uv4pqKisw(|c:|d/Do%J\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"a0JACY?SyTgO21=or@D6\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"ySld:`sc3M4=IjeN*RuO\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field></block></value></block></value></block></statement><statement name=\"ELSE\"><block type=\"variables_set\" id=\"/f{XE@50=WxbI;,=TeW]\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field><value name=\"VALUE\"><block type=\"math_number\" id=\"@XV^(en_.lQ0_#rZkz}#\"><field name=\"NUM\">0</field></block></value></block></statement><next><block type=\"text_print\" id=\"{f1ctd/iW#D,le1V(Cy-\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"5VI:=npMdg$L|=e0/Okn\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><next><block type=\"controls_if\" id=\"GvDQg$7WT=Qq6HBCexdf\"><mutation elseif=\"2\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\")M6ls=nOUTB^J;|3-Q@=\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"Y9PB[dJ*r*.*=2([@JT:\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"e`kkA/p8dDJT4Iu`PtP|\"><field name=\"NUM\">1</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_motor\" id=\"mM!-gOyoBb8xLuEK}:PY\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"MV9CvsB9cK7#oJv5M+Gy\"><field name=\"NUM\">80</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"@I!w63)Db*b!^mzk?7b-\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"xz=GX~R6!L1Lz?RO%xSE\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"nSLX(4#c?i({f6gx}h$b\"><field name=\"NUM\">1000</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"3C{Tr^vc`K1K7@whf0+#\"><field name=\"NUM\">1000</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"0[pEKb#+c1ukccsj-HGU\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"!.x!ti5!Jl_Qyi_98vP:\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\":Omnr1TfVKRT,{x+CErC\"><field name=\"NUM\">2</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_motor\" id=\"^@Y|H7}/,1f%m;D)rsqN\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"tpQfUU_t1N9uX9DDLpNK\"><field name=\"NUM\">60</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"X__|/-/MQqilOsxKk.Vn\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"sUK%h7;p?NFy6ej0G@ad\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"55Q_(wsMzLOOTn,AJ*=o\"><field name=\"NUM\">2000</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"Q(U)4jCVk5tml,K%_m3X\"><field name=\"NUM\">1550</field></block></value></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\"-.]jhYzu{)[`q?J|G*@i\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"TYK1ggBo;v^8(fzNK!PO\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"D2;EP}Ok0vx,}R7Te.[g\"><field name=\"NUM\">6</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_motor\" id=\"FWt]Cn.Gx+x%y|4TMq*/\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"PN3gP4:wymcc7g[G,=JC\"><field name=\"NUM\">60</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"$svZ(tsG{Q]%-=QakU@7\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"IxJ8gaf@V.5xrl3X3yu0\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"1hpVYp0#go4@HCi%[MZ`\"><field name=\"NUM\">1550</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"ZuV9iU47evPA,S7J?s+@\"><field name=\"NUM\">2000</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"controls_if\" id=\"]Xst$#BXb%U~.5?C5fN1\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"PD.BkyibEtTX2,VtMdsc\"><field name=\"OP\">GTE</field><value name=\"A\"><block type=\"variables_get\" id=\"UWRm7PH[oi_n9oQsRDGd\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"V1b;v7$b+m#/u;2dm6H$\"><field name=\"NUM\">0</field></block></value></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\",?`$EcLs;XYj{O%B$A~o\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"0WmrG/knZBBpiHSDmLBJ\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"%amYL^tWO^t8nX`JBAEF\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"hIduK@,Vwz{H?bp[WPjj\"><field name=\"NUM\">60</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_motor\" id=\";vD-YiW9)qU8sg-}vcm1\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"((}~wa#@9K8b}RS#DSq?\"><field name=\"NUM\">40</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\":,f0J=^9v|J$I;5Ahy|K\"><field name=\"NUM\">-40</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"L48OY[hxw|)quL7-vkb^\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_arithmetic\" id=\"Upl0F:r{a0y5cdS.crj)\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"variables_get\" id=\"oS=EnUt$f^C5Vj!8|9C8\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"7~z_5vl91w!1jP(k.(Qd\"><field name=\"NUM\">50</field></block></value></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_arithmetic\" id=\"A~(#(]O_(kSZBIc4,yw@\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"variables_get\" id=\"Vuwafvcd/K_ph5^FX:%!\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"x$bmhmC2RW9ZOLL7FWHF\"><field name=\"NUM\">50</field></block></value></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"I)Gu5YQYkX.:()}l^{xg\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\"zCKv1.|-Rios8@h5ilIg\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"vJw^%jvK#eR95btK#CeU\"><field name=\"NUM\">40</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_motor\" id=\"w(zj/fW0HsEnX1*u!4O?\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"y+F~@jqeyB9bS]M=9}J}\"><field name=\"NUM\">-40</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"1/(])B%ubDAdndUnXxg-\"><field name=\"NUM\">40</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"{?IB?(nV;5%Nm_F$1rMX\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_arithmetic\" id=\";dV0cDAx~my3rojA^G|4\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"math_number\" id=\"o/=rp-ECY@EVjB8FV/0~\"><field name=\"NUM\">50</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"W;jmAc*0%%;8cx.}*jQL\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_arithmetic\" id=\"hYIe9z|NuF;9Um0Fk)mu\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"math_number\" id=\"b-Ei9$@yv*bVNNAauA+o\"><field name=\"NUM\">50</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"c?]Gby*%LO[jc{jaa%-9\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_motor\" id=\"O.;G[S8aWfdf|`/h*59@\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"I6+d!/%ONX{B=e8{n0kx\"><field name=\"NUM\">50</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"C*9^tnhIr1`.e{Ts56$Z\"><field name=\"NUM\">50</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"(0,tpOtURC`/@~c2LSVs\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"Ka-C|%Y8;GO(qa1sH:XG\"><field name=\"NUM\">150</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"xLy*EHb!}4NrV0`Z-_yZ\"><field name=\"NUM\">150</field></block></value></block></statement></block></statement></block></statement></block></next></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "line_x_1 = None\nlista = None\nline_x_list = None\nline_x_2 = None\nar_code = None\nar_code_list = None\n\n\nwhile True:\n get_prog_eng().check_end()\n line_x_list = get_cam().find_line()\n line_x_1 = line_x_list[0]\n ar_code_list = get_cam().find_ar_code().get('codes')\n if not not len(ar_code_list):\n ar_code = ar_code_list[0]\n else:\n ar_code = 0\n get_cam().set_text(ar_code)\n if ar_code == 1:\n get_bot().motor_control(speed_left=80, speed_right=80, elapse=-1, steps_left=1000, steps_right=1000)\n elif ar_code == 2:\n get_bot().motor_control(speed_left=60, speed_right=60, elapse=-1, steps_left=2000, steps_right=1550)\n elif ar_code == 6:\n get_bot().motor_control(speed_left=60, speed_right=60, elapse=-1, steps_left=1550, steps_right=2000)\n else:\n if line_x_1 >= 0:\n if line_x_1 > 60:\n get_bot().motor_control(speed_left=40, speed_right=-40, elapse=-1, steps_left=line_x_1 - 50, steps_right=line_x_1 - 50)\n elif line_x_1 < 40:\n get_bot().motor_control(speed_left=-40, speed_right=40, elapse=-1, steps_left=50 - line_x_1, steps_right=50 - line_x_1)\n else:\n get_bot().motor_control(speed_left=50, speed_right=50, elapse=-1, steps_left=150, steps_right=150)\n", "name": "demo_line_follower"} \ No newline at end of file diff --git a/defaults/programs/program_demo_roboetologist.json b/defaults/programs/program_demo_roboetologist.json index b53ba7e2..71f717b8 100644 --- a/defaults/programs/program_demo_roboetologist.json +++ b/defaults/programs/program_demo_roboetologist.json @@ -1 +1 @@ -{"name":"roboetologia","dom_code":"<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</variable><variable id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</variable><variable id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</variable><variable id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</variable><variable id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</variable><variable id=\"}Amjkrp!.(7[D41[a^{6\">velocita</variable><variable id=\";M|:6*RIcl{fLp+^(S~p\">stanco</variable></variables><block type=\"procedures_defnoreturn\" id=\"!]5:R,96H,d*lP5TdKtv\" x=\"32\" y=\"-248\"><field name=\"NAME\">Scodinzola</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"$@148i!0XDrE)=/74E,F\"><value name=\"TIMES\"><block type=\"math_number\" id=\"Z|tRJT3et)`/%nF;x|BX\"><field name=\"NUM\">3</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"ICVMx1}4##d{B2;1_0yw\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"YOER#;}9h-EjO#NWK$-r\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"c)2=ZX:s9Pu=6_!gAznZ\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"OkO@z~w=AGqzQZu357hr\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"`1Tkh_x5G03,$gK8[7`W\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"6k^]W@IDw;E{I)B2[vF[\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"r3grvcve;,ycs9O{$Z(`\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"KIT-F0Ks@@7mYljTMX}a\"><field name=\"NUM\">0.3</field></block></value><next><block type=\"coderbot_sleep\" id=\"8HSK*.y3si%z:5X:X}Cf\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"_JMB)UTj(N=+rh}WJ1gM\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"I!%c5zbo7`I8H8pPUGmi\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"=G4VJm2R._wOHz%QTKGH\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"sE)S[)9b8GYNM/}A?Q?a\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"th7m{buvj!fXr2[L}rdj\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"tD5onaW9m}8|$[!eMBlT\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"UI8*HDp}`l@z/mNCX#%h\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"?;j;(@*sHEBLK;FT9Snq\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"xm4O$9/uD/DtLEFUuc:H\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"C.gRCR/O:%1W,h%jxJQz\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"P@A2tlSC:EM}cZ{1qJOm\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"4^Vbi3$0bgFj([_q#a)!\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"gfVNt(aQi}BuKUSFJ.3:\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"s@*_u8JqM`F^;vK{O*_0\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"obZReNmla70EZtJwNI$8\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"IEU%gc|cb25NDN1pDPM*\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"{*bj!1W#x3tx!SeWj:kT\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"DaVdvC(WkUw{D:y*?4F6\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\".$SS=6=p56*%bV+0d!UP\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"~~F31]H,M#iZIBu-hpHt\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"S6tUIN@%q%t{Hz2ddE-{\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\".dOMH{.fxW#:}@%b#)JX\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"ZGo9-9/V=n8K.l-Ukk@h\"><field name=\"NUM\">0.3</field></block></value><next><block type=\"coderbot_sleep\" id=\"NK1usFSpUZ,JP33u=3#d\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"?f-Y1{[eyW,FRqS=Wjo$\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"]yMj3IsqdH!-7(8Cvk[U\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></next></block></next></block></statement></block></statement></block><block type=\"procedures_defnoreturn\" id=\"eAhV_z+X]idI9Y2#)$n(\" x=\"1037\" y=\"-296\"><field name=\"NAME\">Evita_Ostacoli</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"@c#NwB$D7537*F7m=!(7\"><value name=\"TIMES\"><shadow type=\"math_number\" id=\"YMSS!*wG*F@i;BhUmTE`\"><field name=\"NUM\">15</field></shadow></value><statement name=\"DO\"><block type=\"controls_if\" id=\"X*#hoa)#P0K0YxbKTgIs\"><mutation elseif=\"2\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"Otlt5#y}Bm[e5ta5;YxY\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"ssLQq~!Drc._YB6B-d3S\"><field name=\"SONAR\">0</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"eH-VJ17iCGoZyj+UEq:}\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"trpdU@xT,u;^uH#kGc;f\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"HcmX([S/=AKRH4R8$I0B\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"/rWP6rW9R]E3-naWqgJb\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\".t[s{j8IX2vxW-3BN:mY\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Fb`JpvO.k6Tc7[f,$O$v\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"$l?U4w3[2%qk..:nTePo\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"8Ifz1evG3eDtpQLtQGl9\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"iS!-;G+snS)ML@1l1*P%\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"/vCSdFhWoJq}Z~+GZv@B\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"x)rjS0}jg(awX7.?Vw6}\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"nkX`O8.7pQ/nRXu}}SJ=\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"lzJKDW53E#N;!A;c=C@_\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"PA|Q|jw0.1~mrO$9Q%P;\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"G|iI)YzX$qKo3I+17OnJ\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"I.S?k*]?]8:ux2At*LJ1\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"CXKnQkB)^Mp8+FB%/Kq}\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"Xe+Rt?_8u.vO?W@ZWs2-\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"j4=;9]Ka!u+7?MAJPGh?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"YTc?Tsq{XFq({Kc.X:l2\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"~D0glLe($lFOxGCVt({`\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"k=7sJ/UX#,{!dlpX;H`6\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"6%wD3wHrc$f(?}Bq)28s\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"i374]E^am-M6uyS?-gKC\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"Xp?Z4ev2ys-O`aN-$WNL\"><field name=\"SONAR\">1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\",2c5e_Y3:j:T[liXjo{l\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"Am`s@r3LgvQtrS1TL57q\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"~prj;Zl(AJ|,`oeCCf-,\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"DcI1#yBE~@moiU6YAv#x\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"j`G2K]gZRIV)]2.7dzG9\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"]wDU`;H3W8![o1a2fzk1\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"3/hwsno_gvMwqLT_mgV!\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"/5eh,CVTRpqcb/s5{R5H\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"8t@}mCD~^YNfqoRxQJl%\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"]/3=*vM9ken$o-O1f~fV\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"*SfrgoD6pBdYTZcV!|0b\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"WPe.SW;HHIq|eAB`,BJ`\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\"Oi)HJ7[XQLUo?9Ja,p{i\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"VX/j*WrI[j^f/|ei-f:(\"><field name=\"SONAR\">2</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"J=/3jvhaq=%R42539s$D\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_move\" id=\"Yw+`{06m}q=Xy[hpZc--\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"/^l1V(M*RdBL=xaqy1tq\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"m_d8qZ${$Q]1dgRC9kg1\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"P1aDE;avAT65i|PhY=-2\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"rv=.e$[u+4J|wpmE!WWc\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"=72b0Fu=xSqlre+0P==V\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\",=w/soAS//gtuY7.MR1L\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"HM%|wVB7+V~p-IL[*AR^\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"yJFCwyQPE5=?0r/~vamL\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"5W!KOp9GS.b=}L5otZuU\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"^omY,%{F`GV!pDo}yZrv\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\":l(I1S51$*1Y1BPm^@/w\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"SHq.(.XcZ}7M,l8RC_c@\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"w7#zA8o]]XpeNtS=VD-:\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"J9Igw@@/VH.K__Yl)@~p\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Uo@*[cy$0q1dgsf#Q^z-\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"tb~[WgJ9A+?zO!3y}p;U\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"`}JdE]gqQ@ZY1w]uW%5C\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"GHLs)siSUy|OQqqr3dIo\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"LcaW`EM+]Jb=X?I[;JSB\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"`tVVItwfg.HfaD1gzB=:\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"aBw0-LWH!FA$beTy(Zhv\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement></block></statement></block></statement></block><block type=\"variables_set\" id=\"i9a!EM@s`-6hUdv$sr@3\" x=\"-546\" y=\"-188\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field><value name=\"VALUE\"><block type=\"math_number\" id=\"^=8DhFn=]2Efwc(|OkiD\"><field name=\"NUM\">0.2</field></block></value><next><block type=\"variables_set\" id=\"zjzJg@NAQU,k/!!@n5,*\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field><value name=\"VALUE\"><block type=\"math_number\" id=\"nDs=tH{gKK+fBi0-bA/_\"><field name=\"NUM\">80</field></block></value><next><block type=\"variables_set\" id=\"uD3I^ll~9L#obOA^SI!0\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"VALUE\"><block type=\"math_number\" id=\"~G:^Vj.oE0(OO]ZP3Vcn\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"Obn8q0fElL9mB(i|1]5[\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"VALUE\"><block type=\"math_number\" id=\"H!=muFCqUw/I?)IGAUt|\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"I/mn7F@$p-}4[H4_SBqY\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"VALUE\"><block type=\"math_number\" id=\"*azH8=DJtBx-pQwu4|V6\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"tEC)Up7J)~4{(Dz1[lCj\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"VALUE\"><block type=\"math_number\" id=\"E%Tw$~W4?sv.fNIxv0Ma\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"x4jFKBKS^fdsk#T.U7Z!\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"6ZiB~3h3aO3z5)_kg[zG\"><field name=\"NUM\">1</field></block></value><next><block type=\"controls_whileUntil\" id=\"-yfR%N=ZA:dr/vf[$_Y+\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"H@,=TqL*XM3|6M}Z:3+C\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"math_change\" id=\"1%fq4KBED@gkjP~jlRMk\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"DELTA\"><block type=\"math_number\" id=\";S+Wfd9n5g26eOE9EngY\"><field name=\"NUM\">1</field></block></value><next><block type=\"math_change\" id=\"f-`F7YcK2uSF1[N^tPM{\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"{gD@*ayDq5d6tMw(2Kbc\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"math_change\" id=\"dS?rG_[64b{_2vBnB^QM\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"dkbf0gA|c8o0Cm=!@gQT\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"math_change\" id=\"`)S8h1qAw*?jy*ixY}u+\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"1L=-j:W;2d`s1`:q.su~\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"controls_if\" id=\"S!3#D%1@0YM^;{sm}Q.k\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"/dnfv--t9_A=(06arGX$\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"/}JP!cseKId$umH4~#!d\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"9WL24mxLME}qFQWRype$\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"~_/s2uIq9S6k56j~CVA#\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"VALUE\"><block type=\"math_number\" id=\"YjfWxc5Q+w#]Da0z;@@s\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"@Z/po(O(J`O{*FUL?#%K\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"jmeKZm8wIKG-As_[L%t4\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"E@jRA2fJ},Gr}awmmspH\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"|RNUw6)n!:kvhSz]2of^\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"Q@W~I[!UTRLrFCi:+4D4\"><field name=\"NUM\">3</field></block></value></block></value><statement name=\"DO1\"><block type=\"variables_set\" id=\"TX2klHO#QS96(-b;oxdw\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"}5,MJoA8{Gp/tD?@oBQq\"><field name=\"NUM\">0.5</field></block></value></block></statement><next><block type=\"procedures_callnoreturn\" id=\"k`=DiML{Ev{}a{|`u#r^\"><mutation name=\"Scodinzola\"></mutation><next><block type=\"procedures_callnoreturn\" id=\":ye0=GgRvJ|3|S7-:50(\"><mutation name=\"Evita_Ostacoli\"></mutation><next><block type=\"procedures_callnoreturn\" id=\"`QMv)mRAiqx$_MAPiJ#(\"><mutation name=\"Patugliamento\"></mutation><next><block type=\"controls_if\" id=\"BlK3e^r83~^p3h*QJQB(\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"N`FCfoA4|6B]gmd@$Dno\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"9ryL2^n0LI=Njn!yDEHO\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"-FitrZK{v?e%Bl96c?t[\"><field name=\"NUM\">4</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"oE:q?4%-V6J,QS}AjzFy\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"VALUE\"><block type=\"math_number\" id=\"b775EElpGb*z4nrauX3b\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"`hI(00uN;R!C0:4FyTci\"><mutation name=\"Ritirata_e_fuga\"></mutation></block></next></block></statement><next><block type=\"controls_if\" id=\"?p]@;Dl*R1%(/PQ!=dWJ\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"@MV6{HWJdTLo1usYNV2W\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"G56lN%n(%*qfMbha3fjO\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"@]`ZuP~Ps,dfw9u7_/]~\"><field name=\"NUM\">8</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\")Q=MM=wJix8:e}3t!6p8\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"VALUE\"><block type=\"math_number\" id=\"x7=CztX|VrM#X=PCQA2[\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"DTy{!1~CoWr@ee?Sa;-@\"><mutation name=\"Giravolte\"></mutation></block></next></block></statement><next><block type=\"coderbot_sleep\" id=\"88T*(,r#Vj@:5zDE9tEO\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"42a6{m0y}CCt=]AHjj`6\"><field name=\"NUM\">5</field></block></value><next><block type=\"controls_if\" id=\"?5V^l6nIq)IysusCwzDR\"><value name=\"IF0\"><block type=\"logic_compare\" id=\",Fqr6N)B(p0}6{`5cj@!\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"pOVIS4*1q_5EkuSnmj5O\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"V_L}xISG;/(yv+LDAq?C\"><field name=\"NUM\">6</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"!rUQPht{;fn5,B39fxcB\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"VALUE\"><block type=\"math_number\" id=\"3KIWSuuWoCFaux|K`2GK\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"=}BrOn/{1I*_k%*4~pC+\"><mutation name=\"MarciaIndietro_e_Scarto\"></mutation></block></next></block></statement></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></statement></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block><block type=\"procedures_defnoreturn\" id=\"Wph:,`b9y/Qr@m#qVKh8\" x=\"105\" y=\"236\"><field name=\"NAME\">Giravolte</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"){(:UQ%yk$)1o1Pguk9S\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"c5hzzlx2+eA%touCb]1`\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"lydvF$Ej,y;~N7Po7)o*\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"]9^qO6wW.}1C+h$MbiDE\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"|HP$c2sw0L^tzXq-fLy(\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"#wD6$fKI/W:^T0,9*{8.\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"i*Zleg*v;rpIcG.i7(J:\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"]EVJ2A)5rU){Yqlll0@p\"><field name=\"NUM\">2</field></block></value><next><block type=\"coderbot_sleep\" id=\"d.86;#zvChlP=wxiRYK{\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"wHB]k#o@Np$i#8^9apv!\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"Rde:F#~+L06azq2tVyD-\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement></block><block type=\"procedures_defnoreturn\" id=\"#Lt]PDTBgL/]Mr,,RwFk\" x=\"31\" y=\"400\"><field name=\"NAME\">Patugliamento</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"zU:(eaKOX8bwg|@q)l/x\"><value name=\"TIMES\"><block type=\"math_number\" id=\"yzK?W9/:u/?TIb)n`E{l\"><field name=\"NUM\">3</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"%k|)9QK~_+#YJ[i]f(^|\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"~_wpvFs,tj:4ZSU!6cmI\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"!qKX^lFR%49P+$0r%N;6\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"W0F$EFUx8!vMe|8,m`e)\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"8TVs2lFlm;#yzBe6_g9]\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"YHo$W[}K#~s[ir9kNv)_\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"u)Hj]9kY}4_a.DRL@rG?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"y4w)^60I$wv3fB6T@Gbj\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"5Bfgw2kcW($A8vSHtir.\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"*!VdE}A-vb2YZ-a^p06D\"><field name=\"NUM\">0.5</field></shadow></value></block></next></block></statement></block></statement></block><block type=\"procedures_defnoreturn\" id=\"k).IYZ!#sHk(8noL0i@l\" x=\"-93\" y=\"642\"><field name=\"NAME\">Ritirata_e_fuga</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"[~BG$Oi=L4ZH@MEvOEtV\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"?RuLhTzie::^EqgHxS)x\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"{o8]MWs*L7Xm(10NerE`\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"%F|VO,DV~}UHb:@|C2p-\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"c[;21(SABvfs)G)|4x^Z\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"Lb_3Nu2HTBW9gtaA8D+`\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"yst;fA`Z%rps/:1!a:v?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"a_?(=WI*yG|Qw@p0#tcq\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"Pp)@[psXrpWB%/nL5}Vc\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"rEx#9(2@Z%N`|DnWh+an\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"o7B~om;.tZrb6@p)?EKY\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"PR|@J[;x$lCEM(4:.S(~\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"f)~FYQvG=f/)C9n|kusd\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"^O.!+5/K#K!T#OZds3gz\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"v|f3Q5~D0I.k*to]}=vH\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"~egc|sz;b2=r#9h;O:F/\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"qRJL!80G9IL_?@PGQV$r\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"pfLThV)s=gML_k3{I5jV\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"]}Uj)tHeUYGo]lc^$yL+\"><field name=\"NUM\">3</field></block></value><next><block type=\"coderbot_sleep\" id=\"=%5988mlKNB(RjC0Ua^d\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"E~M696!a~}o-oXq1E]3x\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\":.J$pq2!m5|F4+^*qXiF\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\",5-k}T[BoGUuJt=#q8y/\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"Gw-[#MNK.kb(Pk+@oyR}\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"$:{Ytk.}NMv*^1k:*j+d\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"gMg4F/eD[6_*An+0N#1Y\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"IGeI6gf.7_tJ;uxoau+V\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"^yf:cE[2SnCjF6M7rKU~\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"mTnh,E_(RE`3L)j2;|s3\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"l+Ck2grV#HM3.7N!xIzk\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"D|Zu+_W_#Hecykew]HjB\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"Y(D;RDGx-_?vUoP@{E|S\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"_J~jub1fQ$0.7h}aRX9#\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></next></block></next></block></statement></block><block type=\"procedures_defnoreturn\" id=\"C2,|x88yVW6)$C|.Z[fn\" x=\"869\" y=\"650\"><field name=\"NAME\">MarciaIndietro_e_Scarto</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"io(!A$V*Tw58pI}^6_YY\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\":[u[8j)-^u#O^k`vIU9L\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"q2_I$}9a~5hZ4}@#`$^_\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"Y.`7b`52G9cmcxW?%3wl\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"hCC*}yGz5:h}h6dMwS!y\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"|m-nKgik@#(Y#zPfqU=,\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"`v-dkUixI3E=wr_G(!Ps\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"rRihLI!yF)H~N-qDFQz`\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"f)]lI*iZwr2k$/-,OJ09\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"S#Y;lv?GQsDc7Za1uD^+\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"%~G.hJ0_bq{H8p(^LE-1\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"n[LcL!+Xt9y6roV{2Z*[\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"QS=:BWqYG)%$)mU78~kQ\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"3||`T0aFosR5VFJaXS#I\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"LsMIWEV,WsfUY5KF]PVY\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Q@KPVYLIp2/|i/R/4?EZ\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"XdKC2u$Zz`AzvrUT/3]z\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"wu#EubUV3Ic$jo)%{UzR\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"53`z:pDpu+~Sv3~`N-G~\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"!rX}?uvL2bjbK+8xT_QY\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"/2aHV}CkHtI*dAV{sSM/\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"BOQ!ur6NR+#^~sk}YB)D\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></statement></block></xml>","code":"from numbers import Number\n\nattesa = None\nvelocita_max = None\nvar_marciaIndietro = None\nvar_giravolte = None\nvar_ritirata = None\nvelocita = None\nstanco = None\n\n# Descrivi questa funzione...\ndef Scodinzola():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count in range(3):\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.3)\n get_bot().sleep(attesa)\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.3)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Evita_Ostacoli():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count2 in range(15):\n get_prog_eng().check_end()\n if get_bot().get_sonar_distance(0) < 20:\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n elif get_bot().get_sonar_distance(1) < 20:\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n elif get_bot().get_sonar_distance(2) < 20:\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n else:\n get_bot().forward(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Giravolte():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=2)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Patugliamento():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count3 in range(3):\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(0.5)\n\n# Descrivi questa funzione...\ndef Ritirata_e_fuga():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=3)\n get_bot().sleep(attesa)\n get_bot().forward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef MarciaIndietro_e_Scarto():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n\n\nattesa = 0.2\nvelocita_max = 80\nvar_marciaIndietro = 0\nvar_giravolte = 0\nvar_ritirata = 0\nstanco = 0\nvelocita = 1\nwhile True:\n get_prog_eng().check_end()\n stanco = (stanco if isinstance(stanco, Number) else 0) + 1\n var_marciaIndietro = (var_marciaIndietro if isinstance(var_marciaIndietro, Number) else 0) + 1\n var_giravolte = (var_giravolte if isinstance(var_giravolte, Number) else 0) + 1\n var_ritirata = (var_ritirata if isinstance(var_ritirata, Number) else 0) + 1\n if stanco == 5:\n stanco = 0\n velocita = 1\n elif stanco > 3:\n velocita = 0.5\n Scodinzola()\n Evita_Ostacoli()\n Patugliamento()\n if var_ritirata == 4:\n var_ritirata = 0\n Ritirata_e_fuga()\n if var_giravolte == 8:\n var_giravolte = 0\n Giravolte()\n get_bot().sleep(5)\n if var_marciaIndietro == 6:\n var_marciaIndietro = 0\n MarciaIndietro_e_Scarto()\n","default":""} \ No newline at end of file +{"name":"demo_roboetologist","dom_code":"<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</variable><variable id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</variable><variable id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</variable><variable id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</variable><variable id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</variable><variable id=\"}Amjkrp!.(7[D41[a^{6\">velocita</variable><variable id=\";M|:6*RIcl{fLp+^(S~p\">stanco</variable></variables><block type=\"procedures_defnoreturn\" id=\"!]5:R,96H,d*lP5TdKtv\" x=\"32\" y=\"-248\"><field name=\"NAME\">Scodinzola</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"$@148i!0XDrE)=/74E,F\"><value name=\"TIMES\"><block type=\"math_number\" id=\"Z|tRJT3et)`/%nF;x|BX\"><field name=\"NUM\">3</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"ICVMx1}4##d{B2;1_0yw\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"YOER#;}9h-EjO#NWK$-r\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"c)2=ZX:s9Pu=6_!gAznZ\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"OkO@z~w=AGqzQZu357hr\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"`1Tkh_x5G03,$gK8[7`W\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"6k^]W@IDw;E{I)B2[vF[\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"r3grvcve;,ycs9O{$Z(`\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"KIT-F0Ks@@7mYljTMX}a\"><field name=\"NUM\">0.3</field></block></value><next><block type=\"coderbot_sleep\" id=\"8HSK*.y3si%z:5X:X}Cf\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"_JMB)UTj(N=+rh}WJ1gM\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"I!%c5zbo7`I8H8pPUGmi\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"=G4VJm2R._wOHz%QTKGH\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"sE)S[)9b8GYNM/}A?Q?a\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"th7m{buvj!fXr2[L}rdj\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"tD5onaW9m}8|$[!eMBlT\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"UI8*HDp}`l@z/mNCX#%h\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"?;j;(@*sHEBLK;FT9Snq\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"xm4O$9/uD/DtLEFUuc:H\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"C.gRCR/O:%1W,h%jxJQz\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"P@A2tlSC:EM}cZ{1qJOm\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"4^Vbi3$0bgFj([_q#a)!\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"gfVNt(aQi}BuKUSFJ.3:\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"s@*_u8JqM`F^;vK{O*_0\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"obZReNmla70EZtJwNI$8\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"IEU%gc|cb25NDN1pDPM*\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"{*bj!1W#x3tx!SeWj:kT\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"DaVdvC(WkUw{D:y*?4F6\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\".$SS=6=p56*%bV+0d!UP\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"~~F31]H,M#iZIBu-hpHt\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"S6tUIN@%q%t{Hz2ddE-{\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\".dOMH{.fxW#:}@%b#)JX\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"ZGo9-9/V=n8K.l-Ukk@h\"><field name=\"NUM\">0.3</field></block></value><next><block type=\"coderbot_sleep\" id=\"NK1usFSpUZ,JP33u=3#d\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"?f-Y1{[eyW,FRqS=Wjo$\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"]yMj3IsqdH!-7(8Cvk[U\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></next></block></next></block></statement></block></statement></block><block type=\"procedures_defnoreturn\" id=\"eAhV_z+X]idI9Y2#)$n(\" x=\"1037\" y=\"-296\"><field name=\"NAME\">Evita_Ostacoli</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"@c#NwB$D7537*F7m=!(7\"><value name=\"TIMES\"><shadow type=\"math_number\" id=\"YMSS!*wG*F@i;BhUmTE`\"><field name=\"NUM\">15</field></shadow></value><statement name=\"DO\"><block type=\"controls_if\" id=\"X*#hoa)#P0K0YxbKTgIs\"><mutation elseif=\"2\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"Otlt5#y}Bm[e5ta5;YxY\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"ssLQq~!Drc._YB6B-d3S\"><field name=\"SONAR\">0</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"eH-VJ17iCGoZyj+UEq:}\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"trpdU@xT,u;^uH#kGc;f\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"HcmX([S/=AKRH4R8$I0B\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"/rWP6rW9R]E3-naWqgJb\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\".t[s{j8IX2vxW-3BN:mY\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Fb`JpvO.k6Tc7[f,$O$v\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"$l?U4w3[2%qk..:nTePo\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"8Ifz1evG3eDtpQLtQGl9\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"iS!-;G+snS)ML@1l1*P%\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"/vCSdFhWoJq}Z~+GZv@B\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"x)rjS0}jg(awX7.?Vw6}\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"nkX`O8.7pQ/nRXu}}SJ=\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"lzJKDW53E#N;!A;c=C@_\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"PA|Q|jw0.1~mrO$9Q%P;\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"G|iI)YzX$qKo3I+17OnJ\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"I.S?k*]?]8:ux2At*LJ1\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"CXKnQkB)^Mp8+FB%/Kq}\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"Xe+Rt?_8u.vO?W@ZWs2-\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"j4=;9]Ka!u+7?MAJPGh?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"YTc?Tsq{XFq({Kc.X:l2\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"~D0glLe($lFOxGCVt({`\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"k=7sJ/UX#,{!dlpX;H`6\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"6%wD3wHrc$f(?}Bq)28s\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"i374]E^am-M6uyS?-gKC\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"Xp?Z4ev2ys-O`aN-$WNL\"><field name=\"SONAR\">1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\",2c5e_Y3:j:T[liXjo{l\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"Am`s@r3LgvQtrS1TL57q\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"~prj;Zl(AJ|,`oeCCf-,\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"DcI1#yBE~@moiU6YAv#x\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"j`G2K]gZRIV)]2.7dzG9\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"]wDU`;H3W8![o1a2fzk1\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"3/hwsno_gvMwqLT_mgV!\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"/5eh,CVTRpqcb/s5{R5H\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"8t@}mCD~^YNfqoRxQJl%\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"]/3=*vM9ken$o-O1f~fV\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"*SfrgoD6pBdYTZcV!|0b\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"WPe.SW;HHIq|eAB`,BJ`\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\"Oi)HJ7[XQLUo?9Ja,p{i\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"VX/j*WrI[j^f/|ei-f:(\"><field name=\"SONAR\">2</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"J=/3jvhaq=%R42539s$D\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_move\" id=\"Yw+`{06m}q=Xy[hpZc--\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"/^l1V(M*RdBL=xaqy1tq\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"m_d8qZ${$Q]1dgRC9kg1\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"P1aDE;avAT65i|PhY=-2\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"rv=.e$[u+4J|wpmE!WWc\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"=72b0Fu=xSqlre+0P==V\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\",=w/soAS//gtuY7.MR1L\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"HM%|wVB7+V~p-IL[*AR^\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"yJFCwyQPE5=?0r/~vamL\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"5W!KOp9GS.b=}L5otZuU\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"^omY,%{F`GV!pDo}yZrv\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\":l(I1S51$*1Y1BPm^@/w\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"SHq.(.XcZ}7M,l8RC_c@\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"w7#zA8o]]XpeNtS=VD-:\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"J9Igw@@/VH.K__Yl)@~p\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Uo@*[cy$0q1dgsf#Q^z-\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"tb~[WgJ9A+?zO!3y}p;U\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"`}JdE]gqQ@ZY1w]uW%5C\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"GHLs)siSUy|OQqqr3dIo\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"LcaW`EM+]Jb=X?I[;JSB\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"`tVVItwfg.HfaD1gzB=:\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"aBw0-LWH!FA$beTy(Zhv\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement></block></statement></block></statement></block><block type=\"variables_set\" id=\"i9a!EM@s`-6hUdv$sr@3\" x=\"-546\" y=\"-188\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field><value name=\"VALUE\"><block type=\"math_number\" id=\"^=8DhFn=]2Efwc(|OkiD\"><field name=\"NUM\">0.2</field></block></value><next><block type=\"variables_set\" id=\"zjzJg@NAQU,k/!!@n5,*\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field><value name=\"VALUE\"><block type=\"math_number\" id=\"nDs=tH{gKK+fBi0-bA/_\"><field name=\"NUM\">80</field></block></value><next><block type=\"variables_set\" id=\"uD3I^ll~9L#obOA^SI!0\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"VALUE\"><block type=\"math_number\" id=\"~G:^Vj.oE0(OO]ZP3Vcn\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"Obn8q0fElL9mB(i|1]5[\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"VALUE\"><block type=\"math_number\" id=\"H!=muFCqUw/I?)IGAUt|\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"I/mn7F@$p-}4[H4_SBqY\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"VALUE\"><block type=\"math_number\" id=\"*azH8=DJtBx-pQwu4|V6\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"tEC)Up7J)~4{(Dz1[lCj\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"VALUE\"><block type=\"math_number\" id=\"E%Tw$~W4?sv.fNIxv0Ma\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"x4jFKBKS^fdsk#T.U7Z!\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"6ZiB~3h3aO3z5)_kg[zG\"><field name=\"NUM\">1</field></block></value><next><block type=\"controls_whileUntil\" id=\"-yfR%N=ZA:dr/vf[$_Y+\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"H@,=TqL*XM3|6M}Z:3+C\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"math_change\" id=\"1%fq4KBED@gkjP~jlRMk\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"DELTA\"><block type=\"math_number\" id=\";S+Wfd9n5g26eOE9EngY\"><field name=\"NUM\">1</field></block></value><next><block type=\"math_change\" id=\"f-`F7YcK2uSF1[N^tPM{\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"{gD@*ayDq5d6tMw(2Kbc\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"math_change\" id=\"dS?rG_[64b{_2vBnB^QM\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"dkbf0gA|c8o0Cm=!@gQT\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"math_change\" id=\"`)S8h1qAw*?jy*ixY}u+\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"1L=-j:W;2d`s1`:q.su~\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"controls_if\" id=\"S!3#D%1@0YM^;{sm}Q.k\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"/dnfv--t9_A=(06arGX$\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"/}JP!cseKId$umH4~#!d\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"9WL24mxLME}qFQWRype$\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"~_/s2uIq9S6k56j~CVA#\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"VALUE\"><block type=\"math_number\" id=\"YjfWxc5Q+w#]Da0z;@@s\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"@Z/po(O(J`O{*FUL?#%K\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"jmeKZm8wIKG-As_[L%t4\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"E@jRA2fJ},Gr}awmmspH\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"|RNUw6)n!:kvhSz]2of^\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"Q@W~I[!UTRLrFCi:+4D4\"><field name=\"NUM\">3</field></block></value></block></value><statement name=\"DO1\"><block type=\"variables_set\" id=\"TX2klHO#QS96(-b;oxdw\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"}5,MJoA8{Gp/tD?@oBQq\"><field name=\"NUM\">0.5</field></block></value></block></statement><next><block type=\"procedures_callnoreturn\" id=\"k`=DiML{Ev{}a{|`u#r^\"><mutation name=\"Scodinzola\"></mutation><next><block type=\"procedures_callnoreturn\" id=\":ye0=GgRvJ|3|S7-:50(\"><mutation name=\"Evita_Ostacoli\"></mutation><next><block type=\"procedures_callnoreturn\" id=\"`QMv)mRAiqx$_MAPiJ#(\"><mutation name=\"Patugliamento\"></mutation><next><block type=\"controls_if\" id=\"BlK3e^r83~^p3h*QJQB(\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"N`FCfoA4|6B]gmd@$Dno\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"9ryL2^n0LI=Njn!yDEHO\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"-FitrZK{v?e%Bl96c?t[\"><field name=\"NUM\">4</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"oE:q?4%-V6J,QS}AjzFy\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"VALUE\"><block type=\"math_number\" id=\"b775EElpGb*z4nrauX3b\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"`hI(00uN;R!C0:4FyTci\"><mutation name=\"Ritirata_e_fuga\"></mutation></block></next></block></statement><next><block type=\"controls_if\" id=\"?p]@;Dl*R1%(/PQ!=dWJ\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"@MV6{HWJdTLo1usYNV2W\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"G56lN%n(%*qfMbha3fjO\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"@]`ZuP~Ps,dfw9u7_/]~\"><field name=\"NUM\">8</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\")Q=MM=wJix8:e}3t!6p8\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"VALUE\"><block type=\"math_number\" id=\"x7=CztX|VrM#X=PCQA2[\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"DTy{!1~CoWr@ee?Sa;-@\"><mutation name=\"Giravolte\"></mutation></block></next></block></statement><next><block type=\"coderbot_sleep\" id=\"88T*(,r#Vj@:5zDE9tEO\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"42a6{m0y}CCt=]AHjj`6\"><field name=\"NUM\">5</field></block></value><next><block type=\"controls_if\" id=\"?5V^l6nIq)IysusCwzDR\"><value name=\"IF0\"><block type=\"logic_compare\" id=\",Fqr6N)B(p0}6{`5cj@!\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"pOVIS4*1q_5EkuSnmj5O\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"V_L}xISG;/(yv+LDAq?C\"><field name=\"NUM\">6</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"!rUQPht{;fn5,B39fxcB\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"VALUE\"><block type=\"math_number\" id=\"3KIWSuuWoCFaux|K`2GK\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"=}BrOn/{1I*_k%*4~pC+\"><mutation name=\"MarciaIndietro_e_Scarto\"></mutation></block></next></block></statement></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></statement></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block><block type=\"procedures_defnoreturn\" id=\"Wph:,`b9y/Qr@m#qVKh8\" x=\"105\" y=\"236\"><field name=\"NAME\">Giravolte</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"){(:UQ%yk$)1o1Pguk9S\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"c5hzzlx2+eA%touCb]1`\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"lydvF$Ej,y;~N7Po7)o*\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"]9^qO6wW.}1C+h$MbiDE\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"|HP$c2sw0L^tzXq-fLy(\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"#wD6$fKI/W:^T0,9*{8.\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"i*Zleg*v;rpIcG.i7(J:\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"]EVJ2A)5rU){Yqlll0@p\"><field name=\"NUM\">2</field></block></value><next><block type=\"coderbot_sleep\" id=\"d.86;#zvChlP=wxiRYK{\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"wHB]k#o@Np$i#8^9apv!\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"Rde:F#~+L06azq2tVyD-\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement></block><block type=\"procedures_defnoreturn\" id=\"#Lt]PDTBgL/]Mr,,RwFk\" x=\"31\" y=\"400\"><field name=\"NAME\">Patugliamento</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"zU:(eaKOX8bwg|@q)l/x\"><value name=\"TIMES\"><block type=\"math_number\" id=\"yzK?W9/:u/?TIb)n`E{l\"><field name=\"NUM\">3</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"%k|)9QK~_+#YJ[i]f(^|\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"~_wpvFs,tj:4ZSU!6cmI\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"!qKX^lFR%49P+$0r%N;6\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"W0F$EFUx8!vMe|8,m`e)\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"8TVs2lFlm;#yzBe6_g9]\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"YHo$W[}K#~s[ir9kNv)_\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"u)Hj]9kY}4_a.DRL@rG?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"y4w)^60I$wv3fB6T@Gbj\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"5Bfgw2kcW($A8vSHtir.\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"*!VdE}A-vb2YZ-a^p06D\"><field name=\"NUM\">0.5</field></shadow></value></block></next></block></statement></block></statement></block><block type=\"procedures_defnoreturn\" id=\"k).IYZ!#sHk(8noL0i@l\" x=\"-93\" y=\"642\"><field name=\"NAME\">Ritirata_e_fuga</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"[~BG$Oi=L4ZH@MEvOEtV\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"?RuLhTzie::^EqgHxS)x\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"{o8]MWs*L7Xm(10NerE`\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"%F|VO,DV~}UHb:@|C2p-\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"c[;21(SABvfs)G)|4x^Z\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"Lb_3Nu2HTBW9gtaA8D+`\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"yst;fA`Z%rps/:1!a:v?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"a_?(=WI*yG|Qw@p0#tcq\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"Pp)@[psXrpWB%/nL5}Vc\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"rEx#9(2@Z%N`|DnWh+an\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"o7B~om;.tZrb6@p)?EKY\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"PR|@J[;x$lCEM(4:.S(~\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"f)~FYQvG=f/)C9n|kusd\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"^O.!+5/K#K!T#OZds3gz\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"v|f3Q5~D0I.k*to]}=vH\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"~egc|sz;b2=r#9h;O:F/\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"qRJL!80G9IL_?@PGQV$r\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"pfLThV)s=gML_k3{I5jV\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"]}Uj)tHeUYGo]lc^$yL+\"><field name=\"NUM\">3</field></block></value><next><block type=\"coderbot_sleep\" id=\"=%5988mlKNB(RjC0Ua^d\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"E~M696!a~}o-oXq1E]3x\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\":.J$pq2!m5|F4+^*qXiF\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\",5-k}T[BoGUuJt=#q8y/\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"Gw-[#MNK.kb(Pk+@oyR}\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"$:{Ytk.}NMv*^1k:*j+d\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"gMg4F/eD[6_*An+0N#1Y\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"IGeI6gf.7_tJ;uxoau+V\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"^yf:cE[2SnCjF6M7rKU~\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"mTnh,E_(RE`3L)j2;|s3\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"l+Ck2grV#HM3.7N!xIzk\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"D|Zu+_W_#Hecykew]HjB\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"Y(D;RDGx-_?vUoP@{E|S\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"_J~jub1fQ$0.7h}aRX9#\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></next></block></next></block></statement></block><block type=\"procedures_defnoreturn\" id=\"C2,|x88yVW6)$C|.Z[fn\" x=\"869\" y=\"650\"><field name=\"NAME\">MarciaIndietro_e_Scarto</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"io(!A$V*Tw58pI}^6_YY\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\":[u[8j)-^u#O^k`vIU9L\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"q2_I$}9a~5hZ4}@#`$^_\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"Y.`7b`52G9cmcxW?%3wl\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"hCC*}yGz5:h}h6dMwS!y\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"|m-nKgik@#(Y#zPfqU=,\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"`v-dkUixI3E=wr_G(!Ps\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"rRihLI!yF)H~N-qDFQz`\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"f)]lI*iZwr2k$/-,OJ09\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"S#Y;lv?GQsDc7Za1uD^+\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"%~G.hJ0_bq{H8p(^LE-1\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"n[LcL!+Xt9y6roV{2Z*[\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"QS=:BWqYG)%$)mU78~kQ\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"3||`T0aFosR5VFJaXS#I\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"LsMIWEV,WsfUY5KF]PVY\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Q@KPVYLIp2/|i/R/4?EZ\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"XdKC2u$Zz`AzvrUT/3]z\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"wu#EubUV3Ic$jo)%{UzR\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"53`z:pDpu+~Sv3~`N-G~\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"!rX}?uvL2bjbK+8xT_QY\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"/2aHV}CkHtI*dAV{sSM/\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"BOQ!ur6NR+#^~sk}YB)D\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></statement></block></xml>","code":"from numbers import Number\n\nattesa = None\nvelocita_max = None\nvar_marciaIndietro = None\nvar_giravolte = None\nvar_ritirata = None\nvelocita = None\nstanco = None\n\n# Descrivi questa funzione...\ndef Scodinzola():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count in range(3):\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.3)\n get_bot().sleep(attesa)\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.3)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Evita_Ostacoli():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count2 in range(15):\n get_prog_eng().check_end()\n if get_bot().get_sonar_distance(0) < 20:\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n elif get_bot().get_sonar_distance(1) < 20:\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n elif get_bot().get_sonar_distance(2) < 20:\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n else:\n get_bot().forward(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Giravolte():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=2)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Patugliamento():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count3 in range(3):\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(0.5)\n\n# Descrivi questa funzione...\ndef Ritirata_e_fuga():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=3)\n get_bot().sleep(attesa)\n get_bot().forward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef MarciaIndietro_e_Scarto():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n\n\nattesa = 0.2\nvelocita_max = 80\nvar_marciaIndietro = 0\nvar_giravolte = 0\nvar_ritirata = 0\nstanco = 0\nvelocita = 1\nwhile True:\n get_prog_eng().check_end()\n stanco = (stanco if isinstance(stanco, Number) else 0) + 1\n var_marciaIndietro = (var_marciaIndietro if isinstance(var_marciaIndietro, Number) else 0) + 1\n var_giravolte = (var_giravolte if isinstance(var_giravolte, Number) else 0) + 1\n var_ritirata = (var_ritirata if isinstance(var_ritirata, Number) else 0) + 1\n if stanco == 5:\n stanco = 0\n velocita = 1\n elif stanco > 3:\n velocita = 0.5\n Scodinzola()\n Evita_Ostacoli()\n Patugliamento()\n if var_ritirata == 4:\n var_ritirata = 0\n Ritirata_e_fuga()\n if var_giravolte == 8:\n var_giravolte = 0\n Giravolte()\n get_bot().sleep(5)\n if var_marciaIndietro == 6:\n var_marciaIndietro = 0\n MarciaIndietro_e_Scarto()\n","default":""} \ No newline at end of file diff --git a/defaults/programs/program_demo_sound_clap_control.json b/defaults/programs/program_demo_sound_clap_control.json index 29f377f3..a735de15 100644 --- a/defaults/programs/program_demo_sound_clap_control.json +++ b/defaults/programs/program_demo_sound_clap_control.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"-43\" y=\"126\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">noise</field><value name=\"VALUE\"><block type=\"coderbot_audio_hear\"><value name=\"LEVEL\"><block type=\"math_number\"><field name=\"NUM\">1000</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.2</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"variables_get\"><field name=\"VAR\">noise</field></block></value><next><block type=\"controls_if\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">noise</field></block></value><value name=\"B\"><block type=\"logic_boolean\"><field name=\"BOOL\">FALSE</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">-1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.5</field></block></value></block></statement></block></next></block></next></block></statement><next><block type=\"coderbot_adv_stop\"></block></next></block></xml>", "code": "noise = None\n\n\nwhile True:\n get_prog_eng().check_end()\n noise = get_audio().hear(level=1000, elapse=0.2)\n get_cam().set_text(noise)\n if noise == False:\n get_bot().forward(speed=100, elapse=-1)\n else:\n get_bot().right(speed=100, elapse=0.5)\nget_bot().stop()\n", "name": "clap_control"} \ No newline at end of file +{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"-43\" y=\"126\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">noise</field><value name=\"VALUE\"><block type=\"coderbot_audio_hear\"><value name=\"LEVEL\"><block type=\"math_number\"><field name=\"NUM\">1000</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.2</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"variables_get\"><field name=\"VAR\">noise</field></block></value><next><block type=\"controls_if\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">noise</field></block></value><value name=\"B\"><block type=\"logic_boolean\"><field name=\"BOOL\">FALSE</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">-1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.5</field></block></value></block></statement></block></next></block></next></block></statement><next><block type=\"coderbot_adv_stop\"></block></next></block></xml>", "code": "noise = None\n\n\nwhile True:\n get_prog_eng().check_end()\n noise = get_audio().hear(level=1000, elapse=0.2)\n get_cam().set_text(noise)\n if noise == False:\n get_bot().forward(speed=100, elapse=-1)\n else:\n get_bot().right(speed=100, elapse=0.5)\nget_bot().stop()\n", "name": "demo_sound_clap_control"} \ No newline at end of file diff --git a/defaults/programs/program_test_find_code.json b/defaults/programs/program_test_find_code.json index 0f16e779..37b1b610 100644 --- a/defaults/programs/program_test_find_code.json +++ b/defaults/programs/program_test_find_code.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables></variables><block type=\"controls_whileUntil\" id=\"0Mx[mSKoV~Gk1qbv5Wrn\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"q8(wB97}Y)d71cgy$yo#\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"0fGi]QOF@I*b$5x^?f#A\"><value name=\"TEXT\"><block type=\"coderbot_adv_findQRCode\" id=\"zG.;=ZyX~k=YR$T(6JF*\"></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().find_qr_code())\n", "name": "find_code_test"} \ No newline at end of file +{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables></variables><block type=\"controls_whileUntil\" id=\"0Mx[mSKoV~Gk1qbv5Wrn\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"q8(wB97}Y)d71cgy$yo#\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"0fGi]QOF@I*b$5x^?f#A\"><value name=\"TEXT\"><block type=\"coderbot_adv_findQRCode\" id=\"zG.;=ZyX~k=YR$T(6JF*\"></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().find_qr_code())\n", "name": "test_find_code"} \ No newline at end of file diff --git a/defaults/programs/program_test_find_color.json b/defaults/programs/program_test_find_color.json index 68bc4586..293735b1 100644 --- a/defaults/programs/program_test_find_color.json +++ b/defaults/programs/program_test_find_color.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"1\" y=\"90\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">dist</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">DIST</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"variables_set\"><field name=\"VAR\">angle</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">ANGLE</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"text_join\"><mutation items=\"4\"></mutation><value name=\"ADD0\"><block type=\"text\"><field name=\"TEXT\">Distance: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"ADD2\"><block type=\"text\"><field name=\"TEXT\"> angle: </field></block></value><value name=\"ADD3\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value></block></value></block></next></block></next></block></statement></block></xml>", "code": "dist = None\nangle = None\n\n\nwhile True:\n get_prog_eng().check_end()\n dist = get_cam().find_color('#96b73c')[0]\n angle = get_cam().find_color('#96b73c')[1]\n get_cam().set_text(''.join([str(temp_value) for temp_value in ['Distance: ', dist, ' angle: ', angle]]))\n", "name": "find_color"} \ No newline at end of file +{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"1\" y=\"90\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">dist</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">DIST</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"variables_set\"><field name=\"VAR\">angle</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">ANGLE</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"text_join\"><mutation items=\"4\"></mutation><value name=\"ADD0\"><block type=\"text\"><field name=\"TEXT\">Distance: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"ADD2\"><block type=\"text\"><field name=\"TEXT\"> angle: </field></block></value><value name=\"ADD3\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value></block></value></block></next></block></next></block></statement></block></xml>", "code": "dist = None\nangle = None\n\n\nwhile True:\n get_prog_eng().check_end()\n dist = get_cam().find_color('#96b73c')[0]\n angle = get_cam().find_color('#96b73c')[1]\n get_cam().set_text(''.join([str(temp_value) for temp_value in ['Distance: ', dist, ' angle: ', angle]]))\n", "name": "test_find_color"} \ No newline at end of file diff --git a/defaults/programs/program_test_find_face.json b/defaults/programs/program_test_find_face.json index ace65032..4320243b 100644 --- a/defaults/programs/program_test_find_face.json +++ b/defaults/programs/program_test_find_face.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"G`ooSD^IjFl@q`VRXz`M\">face</variable><variable type=\"\" id=\"JU]w:x,u6R_]KGB{:XP:\">face_x</variable><variable type=\"\" id=\"YdZ|nz8=@UwR53L{5(Te\">face_size</variable></variables><block type=\"controls_whileUntil\" id=\"CoP0+krwBNk-W]8d*90A\" x=\"32\" y=\"26\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"fi_0^7$bm]/5xQ|Zpg=(\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"f$?dr|af|Ac.xwmgSA%J\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field><value name=\"VALUE\"><block type=\"coderbot_adv_findFace\" id=\"H`#u_,_?;x,73RZ}}gR{\"><field name=\"RETVAL\">ALL</field></block></value><next><block type=\"variables_set\" id=\"{o9)u+=V]D]h(5aygd~M\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"dAqQ+k+Lsv!1N7zj4(4^\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"65Q5x52oC~jam{#uHnFe\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"^aod?Rq):AVnd02Or|!L\"><field name=\"NUM\">1</field></block></value></block></value><next><block type=\"variables_set\" id=\"I{^(8GT:UL9{7jdNlg[w\"><field name=\"VAR\" id=\"YdZ|nz8=@UwR53L{5(Te\" variabletype=\"\">face_size</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"2}fQ04Qws48,xb!?z1pW\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"hmZQMGjZ94)AhuZ6JUYa\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"=LbR3.00CDs*hnk()Y^-\"><field name=\"NUM\">2</field></block></value></block></value><next><block type=\"text_print\" id=\"O}.LG0(E@nzN,p;l%v2{\"><value name=\"TEXT\"><block type=\"text_join\" id=\"mRJtt8foB.;Gpq0fM,4D\"><mutation items=\"2\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\",=O:[=q5SBb`1$S,-R,:\"><field name=\"TEXT\">face: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\" id=\"UEwJl:.puwUq)R!zo@Z7\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value></block></value><next><block type=\"controls_if\" id=\"9tGk|M6u455Nu1(SI}{K\"><value name=\"IF0\"><block type=\"variables_get\" id=\"9}[hrA3rOFo0n+BAsX-f\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\"1-%~}MODhI#*$?^aB_tS\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"`rz$_58rWb#ufStSd](T\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\"O}zML^tGL7t3C*mWsEMo\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"gdx{O}:M_*b|FpvgG_~h\"><field name=\"NUM\">-10</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"@[^uw~TU^Vti#)6HZC?K\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"vt6%MV@vkT*tB]%2:7vQ\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"d3[F3QtIG#jb=1IPOem)\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"/zef{/F+:n[eI1@+MIKR\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"dh8opiswQU13wjT![yV[\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"2RVlzW2}AG#ywuHP6N=+\"><field name=\"NUM\">10</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"4`Z7%j+MV5(5,BM!RRBA\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"v`ab`#qs7J5]2XaOp]s[\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"A_y%A@DITmnWACnr0]zK\"><field name=\"NUM\">0.1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_stop\" id=\"B/$XZ_Giuo_h#Q?JM{w}\"></block></statement></block></statement></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "face = None\nface_x = None\nface_size = None\n\n\nwhile True:\n get_prog_eng().check_end()\n face = get_cam().find_face()\n face_x = face[0]\n face_size = face[1]\n get_cam().set_text(str('face: ') + str(face_x))\n if face_x:\n if face_x < -10:\n get_bot().left(speed=80, elapse=0.1)\n elif face_x > 10:\n get_bot().right(speed=80, elapse=0.1)\n else:\n get_bot().stop()\n", "name": "face_find"} \ No newline at end of file +{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"G`ooSD^IjFl@q`VRXz`M\">face</variable><variable type=\"\" id=\"JU]w:x,u6R_]KGB{:XP:\">face_x</variable><variable type=\"\" id=\"YdZ|nz8=@UwR53L{5(Te\">face_size</variable></variables><block type=\"controls_whileUntil\" id=\"CoP0+krwBNk-W]8d*90A\" x=\"32\" y=\"26\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"fi_0^7$bm]/5xQ|Zpg=(\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"f$?dr|af|Ac.xwmgSA%J\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field><value name=\"VALUE\"><block type=\"coderbot_adv_findFace\" id=\"H`#u_,_?;x,73RZ}}gR{\"><field name=\"RETVAL\">ALL</field></block></value><next><block type=\"variables_set\" id=\"{o9)u+=V]D]h(5aygd~M\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"dAqQ+k+Lsv!1N7zj4(4^\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"65Q5x52oC~jam{#uHnFe\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"^aod?Rq):AVnd02Or|!L\"><field name=\"NUM\">1</field></block></value></block></value><next><block type=\"variables_set\" id=\"I{^(8GT:UL9{7jdNlg[w\"><field name=\"VAR\" id=\"YdZ|nz8=@UwR53L{5(Te\" variabletype=\"\">face_size</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"2}fQ04Qws48,xb!?z1pW\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"hmZQMGjZ94)AhuZ6JUYa\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"=LbR3.00CDs*hnk()Y^-\"><field name=\"NUM\">2</field></block></value></block></value><next><block type=\"text_print\" id=\"O}.LG0(E@nzN,p;l%v2{\"><value name=\"TEXT\"><block type=\"text_join\" id=\"mRJtt8foB.;Gpq0fM,4D\"><mutation items=\"2\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\",=O:[=q5SBb`1$S,-R,:\"><field name=\"TEXT\">face: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\" id=\"UEwJl:.puwUq)R!zo@Z7\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value></block></value><next><block type=\"controls_if\" id=\"9tGk|M6u455Nu1(SI}{K\"><value name=\"IF0\"><block type=\"variables_get\" id=\"9}[hrA3rOFo0n+BAsX-f\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\"1-%~}MODhI#*$?^aB_tS\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"`rz$_58rWb#ufStSd](T\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\"O}zML^tGL7t3C*mWsEMo\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"gdx{O}:M_*b|FpvgG_~h\"><field name=\"NUM\">-10</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"@[^uw~TU^Vti#)6HZC?K\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"vt6%MV@vkT*tB]%2:7vQ\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"d3[F3QtIG#jb=1IPOem)\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"/zef{/F+:n[eI1@+MIKR\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"dh8opiswQU13wjT![yV[\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"2RVlzW2}AG#ywuHP6N=+\"><field name=\"NUM\">10</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"4`Z7%j+MV5(5,BM!RRBA\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"v`ab`#qs7J5]2XaOp]s[\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"A_y%A@DITmnWACnr0]zK\"><field name=\"NUM\">0.1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_stop\" id=\"B/$XZ_Giuo_h#Q?JM{w}\"></block></statement></block></statement></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "face = None\nface_x = None\nface_size = None\n\n\nwhile True:\n get_prog_eng().check_end()\n face = get_cam().find_face()\n face_x = face[0]\n face_size = face[1]\n get_cam().set_text(str('face: ') + str(face_x))\n if face_x:\n if face_x < -10:\n get_bot().left(speed=80, elapse=0.1)\n elif face_x > 10:\n get_bot().right(speed=80, elapse=0.1)\n else:\n get_bot().stop()\n", "name": "test_find_face"} \ No newline at end of file diff --git a/defaults/programs/program_test_find_path_ahead.json b/defaults/programs/program_test_find_path_ahead.json index c494a2d2..703325e2 100644 --- a/defaults/programs/program_test_find_path_ahead.json +++ b/defaults/programs/program_test_find_path_ahead.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\",46fU~j08oojjbw,kof`\">spazio_libero</variable></variables><block type=\"controls_whileUntil\" id=\"18\" x=\"-6\" y=\"95\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"8\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"+.ndl3CthRQ~=B/JKR^u\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field><value name=\"VALUE\"><block type=\"coderbot_adv_pathAhead\" id=\"43\"></block></value><next><block type=\"text_print\" id=\"34\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"HvuukI#y0|2p~0G!J^1,\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><next><block type=\"controls_if\" id=\"j2kyA19rSa;+oDM_|TW1\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_operation\" id=\".h3ecm+6-QkNKadH^K^x\"><field name=\"OP\">AND</field><value name=\"A\"><block type=\"logic_compare\" id=\"?y*$N(f@|9rhe.mOI}Tw\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"j(v,2aQSE^A_2Um!%r%j\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"]@VPRw![OoT^Q6^@}+W]\"><field name=\"NUM\">30</field></block></value></block></value><value name=\"B\"><block type=\"logic_compare\" id=\"!E.x/E#B,Eqe=[6!!UpQ\"><field name=\"OP\">NEQ</field><value name=\"A\"><block type=\"variables_get\" id=\"1|EJ6P/9-k+=y!xD!n59\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"!3n*B?S(XK~u$1}#F:~N\"><field name=\"NUM\">60</field></block></value></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"#SW!Qq8M:4),17-S5HXx\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"ZIc[_OhSH1e.mz]:tL,?\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"-j(8o/#PiEQEY5L2zbT:\"><field name=\"NUM\">0.2</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\"e#qON.)K9J9!}_W`xlWx\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\")C53Vd7c_sC*PsSn0VCM\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"E3zjXN1SRNL5~IQJ|aRQ\"><field name=\"NUM\">0.2</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "spazio_libero = None\n\n\nwhile True:\n get_prog_eng().check_end()\n spazio_libero = get_cam().path_ahead()\n get_cam().set_text(spazio_libero)\n if spazio_libero > 30 and spazio_libero != 60:\n get_bot().forward(speed=100, elapse=0.2)\n else:\n get_bot().right(speed=100, elapse=0.2)\n", "name": "path_ahead"} \ No newline at end of file +{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\",46fU~j08oojjbw,kof`\">spazio_libero</variable></variables><block type=\"controls_whileUntil\" id=\"18\" x=\"-6\" y=\"95\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"8\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"+.ndl3CthRQ~=B/JKR^u\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field><value name=\"VALUE\"><block type=\"coderbot_adv_pathAhead\" id=\"43\"></block></value><next><block type=\"text_print\" id=\"34\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"HvuukI#y0|2p~0G!J^1,\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><next><block type=\"controls_if\" id=\"j2kyA19rSa;+oDM_|TW1\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_operation\" id=\".h3ecm+6-QkNKadH^K^x\"><field name=\"OP\">AND</field><value name=\"A\"><block type=\"logic_compare\" id=\"?y*$N(f@|9rhe.mOI}Tw\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"j(v,2aQSE^A_2Um!%r%j\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"]@VPRw![OoT^Q6^@}+W]\"><field name=\"NUM\">30</field></block></value></block></value><value name=\"B\"><block type=\"logic_compare\" id=\"!E.x/E#B,Eqe=[6!!UpQ\"><field name=\"OP\">NEQ</field><value name=\"A\"><block type=\"variables_get\" id=\"1|EJ6P/9-k+=y!xD!n59\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"!3n*B?S(XK~u$1}#F:~N\"><field name=\"NUM\">60</field></block></value></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"#SW!Qq8M:4),17-S5HXx\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"ZIc[_OhSH1e.mz]:tL,?\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"-j(8o/#PiEQEY5L2zbT:\"><field name=\"NUM\">0.2</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\"e#qON.)K9J9!}_W`xlWx\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\")C53Vd7c_sC*PsSn0VCM\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"E3zjXN1SRNL5~IQJ|aRQ\"><field name=\"NUM\">0.2</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "spazio_libero = None\n\n\nwhile True:\n get_prog_eng().check_end()\n spazio_libero = get_cam().path_ahead()\n get_cam().set_text(spazio_libero)\n if spazio_libero > 30 and spazio_libero != 60:\n get_bot().forward(speed=100, elapse=0.2)\n else:\n get_bot().right(speed=100, elapse=0.2)\n", "name": "test_find_path_ahead"} \ No newline at end of file diff --git a/defaults/programs/program_test_img_average.json b/defaults/programs/program_test_img_average.json index 90bacb94..0112e6cb 100644 --- a/defaults/programs/program_test_img_average.json +++ b/defaults/programs/program_test_img_average.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\"><value name=\"TEXT\"><block type=\"coderbot_cam_average\"><field name=\"RETVAL\">V</field></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().get_average()[2])\n", "name": "img_average_test"} \ No newline at end of file +{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\"><value name=\"TEXT\"><block type=\"coderbot_cam_average\"><field name=\"RETVAL\">V</field></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().get_average()[2])\n", "name": "test_img_average"} \ No newline at end of file diff --git a/defaults/programs/program_test_sound_hear.json b/defaults/programs/program_test_sound_hear.json index 31ff1247..6d9026d6 100644 --- a/defaults/programs/program_test_sound_hear.json +++ b/defaults/programs/program_test_sound_hear.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"-68\" y=\"108\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\"><value name=\"TEXT\"><block type=\"coderbot_audio_hear\"><value name=\"LEVEL\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">1.0</field></block></value></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_audio().hear(level=100, elapse=1))\n", "name": "hear_test"} \ No newline at end of file +{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"-68\" y=\"108\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\"><value name=\"TEXT\"><block type=\"coderbot_audio_hear\"><value name=\"LEVEL\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">1.0</field></block></value></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_audio().hear(level=100, elapse=1))\n", "name": "test_sound_hear"} \ No newline at end of file diff --git a/defaults/programs/program_test_sound_rec.json b/defaults/programs/program_test_sound_rec.json index de267400..d6740905 100644 --- a/defaults/programs/program_test_sound_rec.json +++ b/defaults/programs/program_test_sound_rec.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables></variables><block type=\"coderbot_audio_record\" id=\"LAC_$g%]@y$*]*==lpr=\" x=\"9\" y=\"56\"><value name=\"FILENAME\"><block type=\"text\" id=\"E2o@Zpp|6ZDTxst,*K%+\"><field name=\"TEXT\">test01.wav</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"_Ru290cPp#|Il6+AK[34\"><field name=\"NUM\">5</field></block></value></block></xml>", "code": "get_audio().record_to_file(filename='test01.wav', elapse=5)\n", "name": "sound_rec_test"} \ No newline at end of file +{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables></variables><block type=\"coderbot_audio_record\" id=\"LAC_$g%]@y$*]*==lpr=\" x=\"9\" y=\"56\"><value name=\"FILENAME\"><block type=\"text\" id=\"E2o@Zpp|6ZDTxst,*K%+\"><field name=\"TEXT\">test01.wav</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"_Ru290cPp#|Il6+AK[34\"><field name=\"NUM\">5</field></block></value></block></xml>", "code": "get_audio().record_to_file(filename='test01.wav', elapse=5)\n", "name": "test_sound_rec"} \ No newline at end of file From a2e6f39d9fe2ebbe69be79d1b593e973ca1a4d94 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Tue, 25 Apr 2023 01:05:04 +0100 Subject: [PATCH 03/60] wip --- coderbot/cloud/__init__.py | 2 +- defaults/config.json | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index 7f583fcf..1dc318f8 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -57,7 +57,7 @@ def run(self): logging.info("run.sync.begin") settings = Config.read() syncmodes = settings.get("syncmodes", {"settings": "n", "activities": "n", "programs": "n"}) - sync_period = settings.get("sync_period", 10) + sync_period = int(settings.get("sync_period", "60")) # Enter a context with an instance of the API client with cloud_api_robot_client.ApiClient(self.configuration) as api_client: diff --git a/defaults/config.json b/defaults/config.json index c206cc0a..ab8459d0 100644 --- a/defaults/config.json +++ b/defaults/config.json @@ -50,5 +50,11 @@ "pid_sample_time":"0.05", "movement_use_mpu": "false", "movement_use_motion": "false", - "movement_use_encoder": "true" + "movement_use_encoder": "true", + "sync_modes": { + "activities":"b", + "programs":"b", + "settings":"b" + }, + "sync_period":"60" } From e17230de49bcaf5fae555007b521602bf3999d0a Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 8 May 2023 00:03:53 +0100 Subject: [PATCH 04/60] wip --- coderbot/cloud/__init__.py | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index 1dc318f8..78f15356 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -56,7 +56,7 @@ def run(self): while(True): logging.info("run.sync.begin") settings = Config.read() - syncmodes = settings.get("syncmodes", {"settings": "n", "activities": "n", "programs": "n"}) + sync_modes = settings.get("sync_modes", {"settings": "n", "activities": "n", "programs": "n"}) sync_period = int(settings.get("sync_period", "60")) # Enter a context with an instance of the API client @@ -64,14 +64,14 @@ def run(self): # Create an instance of the API class api_instance = robot_sync_api.RobotSyncApi(api_client) - self.sync_settings(api_instance, syncmodes["settings"]) - self.sync_activities(api_instance, syncmodes["activities"]) - self.sync_programs(api_instance, syncmodes["programs"]) + self.sync_settings(api_instance, sync_modes["settings"]) + self.sync_activities(api_instance, sync_modes["activities"]) + self.sync_programs(api_instance, sync_modes["programs"]) sleep(sync_period) logging.info("run.sync.end") - def sync_settings(self, api_instance, syncmode): + def sync_settings(self, api_instance, sync_mode): try: # Create an instance of the API class api_response = api_instance.get_robot_setting() @@ -81,7 +81,7 @@ def sync_settings(self, api_instance, syncmode): local_most_recent = datetime.fromisoformat(cloud_setting_object["modified"]).timestamp() < Config.modified() logging.info("settings.syncing: " + cloud_setting_object.get("id") + " name: " + cloud_setting_object.get("id")) if cloud_setting != local_setting: - if syncmode == SYNC_UPSTREAM or (syncmode == SYNC_BIDIRECTIONAL and local_most_recent): + if sync_mode == SYNC_UPSTREAM or (sync_mode == SYNC_BIDIRECTIONAL and local_most_recent): body = Setting( id = cloud_setting_object.get('id'), org_id = cloud_setting_object.get('org_id'), @@ -93,13 +93,13 @@ def sync_settings(self, api_instance, syncmode): ) api_response = api_instance.set_robot_setting(body) logging.info("settings.upstream") - if syncmode == SYNC_DOWNSTREAM: # setting, down + if sync_mode == SYNC_DOWNSTREAM: # setting, down Config.write(cloud_setting.data.setting) logging.info("settings.downstream") except cloud_api_robot_client.ApiException as e: logging.warn("Exception when calling settings RobotSyncApi: %s\n" % e) - def sync_activities(self, api_instance, syncmode): + def sync_activities(self, api_instance, sync_mode): activities = Activities.get_instance().list() try: # Get robot activities @@ -123,7 +123,7 @@ def sync_activities(self, api_instance, syncmode): if ac is not None and ac.get("data") != al.get("data"): al["modified"] = al.get("modified", datetime.now(tz=timezone.utc).isoformat()) local_activity_more_recent = datetime.fromisoformat(ac.get("modified")).timestamp() < datetime.fromisoformat(al.get("modified")).timestamp() - if syncmode == SYNC_UPSTREAM or (local_activity_more_recent and syncmode == SYNC_BIDIRECTIONAL): + if sync_mode == SYNC_UPSTREAM or (local_activity_more_recent and sync_mode == SYNC_BIDIRECTIONAL): ac["data"] = al.get("data") ac["modified"] = al.get("modified") body = Activity( @@ -138,12 +138,12 @@ def sync_activities(self, api_instance, syncmode): #logging.info("run.activities.cloud.saving") api_response = api_instance.set_robot_activity(ac.get("id"), body) logging.info("activities.update.upstream: " + al.get("name")) - elif syncmode == "d" or (not local_activity_more_recent and syncmode == SYNC_BIDIRECTIONAL): + elif sync_mode == "d" or (not local_activity_more_recent and sync_mode == SYNC_BIDIRECTIONAL): al["data"] = ac.get("data") al["modified"] = ac.get("modified") Activities.get_instance().save(al.get("name"), al) logging.info("activities.update.downstream: " + al.get("name")) - elif ac is None and syncmode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: + elif ac is None and sync_mode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: body = Activity( id="", org_id="", @@ -158,18 +158,18 @@ def sync_activities(self, api_instance, syncmode): al["org_id"] = api_response.body["org_id"] Activities.get_instance().save(al.get("name"), al) logging.info("activities.create.upstream: " + al.get("name")) - elif ac is None and syncmode in [SYNC_DOWNSTREAM]: + elif ac is None and sync_mode in [SYNC_DOWNSTREAM]: Activities.get_instance().delete(al.get("name")) logging.info("activities.delete.downstream: " + al.get("name")) for k, ac in a_c_m.items(): - if a_l_m.get(k) is None and syncmode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: + if a_l_m.get(k) is None and sync_mode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: Activities.get_instance().save(ac.get("name"), ac) logging.info("activities.create.downstream: " + ac.get("name")) except cloud_api_robot_client.ApiException as e: logging.warn("Exception when calling activities RobotSyncApi: %s\n" % e) - def sync_programs(self, api_instance, syncmode): + def sync_programs(self, api_instance, sync_mode): programs = list() programs_to_be_deleted = list() for p in ProgramEngine.get_instance().prog_list(active_only=False): @@ -204,12 +204,12 @@ def sync_programs(self, api_instance, syncmode): pc.get("code") == pl.get("code") and pc.get("dom_code") == pl.get("dom_code") and pc.get("status") == pl.get("status")) - logging.info("programs.syncing: " + str(pl.get("id")) + " name: " + pl.get("name")) + logging.info("programs.syncing: " + str(pl.get("id")) + " name: " + pl.get("name") + " sync_mode: " + sync_mode + " pc: " + str(pc)) if pc is not None and not pc_pl_equals: pl["modified"] = pl.get("modified", datetime.now(tz=timezone.utc).isoformat()) local_program_more_recent = datetime.fromisoformat(pc.get("modified")).timestamp() < datetime.fromisoformat(pl.get("modified")).timestamp() - if syncmode == SYNC_UPSTREAM or (local_program_more_recent and syncmode == SYNC_BIDIRECTIONAL) and not to_be_deleted: + if sync_mode == SYNC_UPSTREAM or (local_program_more_recent and sync_mode == SYNC_BIDIRECTIONAL) and not to_be_deleted: pc["data"] = pl.get("data") pc["modified"] = pl.get("modified") body = Program( @@ -225,12 +225,12 @@ def sync_programs(self, api_instance, syncmode): #logging.info("run.activities.cloud.saving") api_response = api_instance.set_robot_program(pc.get("id"), body) logging.info("programs.update.upstream: " + pl.get("name")) - elif syncmode == "d" or (not local_program_more_recent and syncmode == SYNC_BIDIRECTIONAL): + elif sync_mode == SYNC_DOWNSTREAM or (not local_program_more_recent and sync_mode == SYNC_BIDIRECTIONAL): pl["data"] = pc.get("data") pl["modified"] = pc.get("modified") ProgramEngine.get_instance().save(program.Program.from_dict(pl)) logging.info("programs.update.downstream: " + pl.get("name")) - elif pc is None and syncmode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: + elif pc is None and sync_mode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: body = Program( id="", org_id="", @@ -246,13 +246,13 @@ def sync_programs(self, api_instance, syncmode): pl["org_id"] = api_response.body["org_id"] ProgramEngine.get_instance().save(program.Program.from_dict(pl)) logging.info("programs.create.upstream: " + pl.get("name")) - elif pc is None and syncmode in [SYNC_DOWNSTREAM]: + elif pc is None and sync_mode in [SYNC_DOWNSTREAM]: ProgramEngine.get_instance().delete(pl.get("name")) logging.info("programs.delete.downstream: " + pl.get("name")) # manage programs not present locally in "active" status for k, pc in p_c_m.items(): - if p_l_m.get(k) is None and syncmode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: + if p_l_m.get(k) is None and sync_mode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: pl = program.Program(name=pc.get("name"), code=pc.get("code"), dom_code=pc.get("dom_code"), From 29b0dc4a0d4e870dbce32c202a201645bce3844a Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 21 May 2023 23:44:30 +0100 Subject: [PATCH 05/60] wip --- coderbot/cloud/__init__.py | 62 ++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index 78f15356..13fd93c9 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -27,14 +27,38 @@ from cloud_api_robot_client.model.program import Program from cloud_api_robot_client.model.robot_data import RobotData from cloud_api_robot_client.model.setting import Setting +from cloud_api_robot_client.model.robot_register_data import RobotRegisterData +from cloud_api_robot_client.model.robot_credentials import RobotCredentials SYNC_UPSTREAM = 'u' SYNC_DOWNSTREAM = 'd' SYNC_BIDIRECTIONAL = 'b' +AUTH_FILE = "data/auth.json" + class CloudManager(threading.Thread): _instance = None + _auth = {} + + @classmethod + def get_auth(cls): + return cls._auth + + @classmethod + def read_auth(cls): + with open(AUTH_FILE, 'r') as f: + cls._auth = json.load(f) + f.close() + return cls._auth + + @classmethod + def write_auth(cls, auth): + cls._auth = auth + f = open(AUTH_FILE, 'w') + json.dump(cls._auth, f) + return cls._auth + @classmethod def get_instance(cls): if cls._instance is None: @@ -48,17 +72,22 @@ def __init__(self): self.configuration = cloud_api_robot_client.Configuration( host = "http://192.168.1.7:8090/api/v1", ) - # Configure Bearer authorization: coderbot_auth - self.configuration.access_token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkNaMVFtVGM1WGZIV2NfQ1dPVG9kcm1QaXZFNFJ2ckFXaFZ3T28yTm85eDAifQ.eyJpc3MiOiJDb2RlckJvdCBDbG91ZCBBUEkiLCJpYXQiOjE2Nzc3MDI4NjIsImV4cCI6MTcwOTIzODg2MiwiYXVkIjoic3QtYXBpLmNvZGVyYm90Lm9yZyIsInN1YiI6InRwWkpYNFlsNElZd21QSzhEd2JmIiwiZW1haWwiOiJ0cFpKWDRZbDRJWXdtUEs4RHdiZkBib3RzLmNvZGVyYm90Lm9yZyIsInBpY3R1cmUiOiJodHRwczovL3N0LWFwcC5jb2RlcmJvdC5vcmcvcGljdHVyZXMvbm9waWMifQ.WlrYd-n6-WWHUxlz1kqnGl8TkjspVWn1UhKK_RIWyIJVlczD1GkqT4uqkHl2aGnp9I_E2SETUvC3dWkkUBG7qHvUIIZVaVhGpfiQy7WMekEdMnXtsPxK8NsWjHYUTbqz2dyz2Z1eQi5Ydhj4niEWsKCAT2BG-nwTIDxu-uxKrah6AtCGGyGKCQu0qje-qUNCxT5S1Y5RT10XS4Ewl2ROsMr1M6P3EVa0VoSJ26QZlh5jIz-8fhyGspxBHFEnZF-p95vEGCQp6M7epwoesDGVlX4AxEEpPk7c_Pd4c2gNLx1nhpkV26sT_c_NESNTM42tVyH9ZjQ5fxCUOEi_ELJ2vQ' + try: + self.read_auth() + except FileNotFoundError: + self.write_auth({}) self.start() def run(self): while(True): - logging.info("run.sync.begin") settings = Config.read() + logging.info("run.sync.begin") sync_modes = settings.get("sync_modes", {"settings": "n", "activities": "n", "programs": "n"}) sync_period = int(settings.get("sync_period", "60")) + token = self.get_token_or_register(settings) + self.configuration.access_token = token + # Enter a context with an instance of the API client with cloud_api_robot_client.ApiClient(self.configuration) as api_client: # Create an instance of the API class @@ -71,15 +100,36 @@ def run(self): sleep(sync_period) logging.info("run.sync.end") + def get_token_or_register(self, settings): + logging.info("run.check.token") + token = self.get_auth().get("token") + reg_otp = settings.get("reg_otp") + logging.info("otp_reg:" + reg_otp) + try: + if token is None and reg_otp is not None: + with cloud_api_robot_client.ApiClient(self.configuration) as api_client: + api_instance = robot_sync_api.RobotSyncApi(api_client) + body = RobotRegisterData( + otp=reg_otp, + ) + api_response = api_instance.register_robot(body=body) + logging.info(api_response.body) + token = api_response.body.get("token") + self.write_auth({"token":token}) + return token + except cloud_api_robot_client.ApiException as e: + logging.warn("Exception when calling register_robot RobotSyncApi: %s\n" % e) + def sync_settings(self, api_instance, sync_mode): try: # Create an instance of the API class api_response = api_instance.get_robot_setting() cloud_setting_object = api_response.body cloud_setting = json.loads(cloud_setting_object.get('data')) + local_setting = Config.read() - local_most_recent = datetime.fromisoformat(cloud_setting_object["modified"]).timestamp() < Config.modified() - logging.info("settings.syncing: " + cloud_setting_object.get("id") + " name: " + cloud_setting_object.get("id")) + local_most_recent = datetime.fromisoformat(cloud_setting_object.get("modified", "2000-01-01T00:00:00.000000")).timestamp() < Config.modified() + logging.info("settings.syncing: " + cloud_setting_object.get("id", "") + " name: " + cloud_setting_object.get("name", "")) if cloud_setting != local_setting: if sync_mode == SYNC_UPSTREAM or (sync_mode == SYNC_BIDIRECTIONAL and local_most_recent): body = Setting( @@ -184,7 +234,7 @@ def sync_programs(self, api_instance, sync_mode): api_response = api_instance.get_robot_programs() cloud_programs = api_response.body # cloud activities - p_c_m = {} # activities_cloud_map + p_c_m = {} # programs_cloud_map for p in cloud_programs: if p.get("status") == program.PROGRAM_STATUS_ACTIVE: p_c_m[p.get("id")] = p From 15d215dd1efdbc9def2e6bf238b5cee0874207ef Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 29 May 2023 00:15:53 +0100 Subject: [PATCH 06/60] wip --- coderbot/cloud/__init__.py | 67 +++++++++++++++++++++++++------------- coderbot/program.py | 18 +++++----- 2 files changed, 54 insertions(+), 31 deletions(-) diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index 13fd93c9..76aac01f 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -93,8 +93,8 @@ def run(self): # Create an instance of the API class api_instance = robot_sync_api.RobotSyncApi(api_client) - self.sync_settings(api_instance, sync_modes["settings"]) - self.sync_activities(api_instance, sync_modes["activities"]) + #self.sync_settings(api_instance, sync_modes["settings"]) + #self.sync_activities(api_instance, sync_modes["activities"]) self.sync_programs(api_instance, sync_modes["programs"]) sleep(sync_period) @@ -138,6 +138,7 @@ def sync_settings(self, api_instance, sync_mode): name = cloud_setting_object.get('name'), description = cloud_setting_object.get('description'), data = json.dumps(local_setting), + kind = local_setting.get("kind", "stock"), modified = datetime.now().isoformat(), status = cloud_setting_object.get('status'), ) @@ -182,6 +183,7 @@ def sync_activities(self, api_instance, sync_mode): name=al.get("name"), description=al.get("description"), data=json.dumps(al.get("data")), + kind = al.get("kind", "stock"), modified=al.get("modified").isoformat(), status='active', ) @@ -200,6 +202,7 @@ def sync_activities(self, api_instance, sync_mode): name=al.get("name"), description=al.get("description"), data=json.dumps(al), + kind=al.get("kind", "stock"), modified=al.get("modified", datetime.now(tz=timezone.utc).isoformat()), status="active", ) @@ -220,35 +223,38 @@ def sync_activities(self, api_instance, sync_mode): logging.warn("Exception when calling activities RobotSyncApi: %s\n" % e) def sync_programs(self, api_instance, sync_mode): - programs = list() - programs_to_be_deleted = list() + programs_local_user = list() + programs_local_stock = list() + programs_local_to_be_deleted = list() for p in ProgramEngine.get_instance().prog_list(active_only=False): - if not p.get("default"): + if p.get("kind") == program.PROGRAM_KIND_USER: if p.get("status") == program.PROGRAM_STATUS_ACTIVE: - programs.append(p) + programs_local_user.append(p) elif p.get("status") == program.PROGRAM_STATUS_DELETED: - programs_to_be_deleted.append(p) - + programs_local_to_be_deleted.append(p) + else: + programs_local_stock.append(p) + try: - # Get robot activities + # Get robot programs api_response = api_instance.get_robot_programs() cloud_programs = api_response.body - # cloud activities - p_c_m = {} # programs_cloud_map + # cloud programs + programs_cloud_map = {} # programs_cloud_map for p in cloud_programs: if p.get("status") == program.PROGRAM_STATUS_ACTIVE: - p_c_m[p.get("id")] = p + programs_cloud_map[p.get("id")] = p - p_l_m = {} # activities_local_map + programs_local_stock_map = {} # activities_local_map # local activities no id - for p in programs: + for p in programs_local_stock: #logging.info("programs.local: " + str(p.get("id")) + " name: " + p.get("name")) if p.get("id") is not None: - p_l_m[p.get("id")] = p + programs_local_stock_map[p.get("id")] = p - # manage programs present locally and in "active" status - for pl in programs: - pc = p_c_m.get(pl.get("id")) + # manage user programs present locally and in "active" status + for pl in programs_local_user: + pc = programs_cloud_map.get(pl.get("id")) pc_pl_equals = (pc is not None and pc.get("name") == pl.get("name") and pc.get("code") == pl.get("code") and @@ -257,9 +263,11 @@ def sync_programs(self, api_instance, sync_mode): logging.info("programs.syncing: " + str(pl.get("id")) + " name: " + pl.get("name") + " sync_mode: " + sync_mode + " pc: " + str(pc)) if pc is not None and not pc_pl_equals: + # cloud program exists and is different pl["modified"] = pl.get("modified", datetime.now(tz=timezone.utc).isoformat()) local_program_more_recent = datetime.fromisoformat(pc.get("modified")).timestamp() < datetime.fromisoformat(pl.get("modified")).timestamp() if sync_mode == SYNC_UPSTREAM or (local_program_more_recent and sync_mode == SYNC_BIDIRECTIONAL) and not to_be_deleted: + # cloud program exists and is less recent pc["data"] = pl.get("data") pc["modified"] = pl.get("modified") body = Program( @@ -269,6 +277,7 @@ def sync_programs(self, api_instance, sync_mode): description=pl.get("description"), code=pl.get("code"), dom_code=pl.get("dom_code"), + kind=pl.get("kind"), modified=pl.get("modified").isoformat(), status='active', ) @@ -276,11 +285,13 @@ def sync_programs(self, api_instance, sync_mode): api_response = api_instance.set_robot_program(pc.get("id"), body) logging.info("programs.update.upstream: " + pl.get("name")) elif sync_mode == SYNC_DOWNSTREAM or (not local_program_more_recent and sync_mode == SYNC_BIDIRECTIONAL): + # cloud program exists and is more recent pl["data"] = pc.get("data") pl["modified"] = pc.get("modified") ProgramEngine.get_instance().save(program.Program.from_dict(pl)) logging.info("programs.update.downstream: " + pl.get("name")) elif pc is None and sync_mode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: + # cloud program does not exist body = Program( id="", org_id="", @@ -288,6 +299,7 @@ def sync_programs(self, api_instance, sync_mode): description=pl.get("description", ""), code=pl.get("code"), dom_code=pl.get("dom_code"), + kind=pl.get("kind"), modified=pl.get("modified", datetime.now(tz=timezone.utc).isoformat()), status="active", ) @@ -297,16 +309,17 @@ def sync_programs(self, api_instance, sync_mode): ProgramEngine.get_instance().save(program.Program.from_dict(pl)) logging.info("programs.create.upstream: " + pl.get("name")) elif pc is None and sync_mode in [SYNC_DOWNSTREAM]: + # cloud program does not exist, delete locally since sync_mode is downstream ProgramEngine.get_instance().delete(pl.get("name")) logging.info("programs.delete.downstream: " + pl.get("name")) - # manage programs not present locally in "active" status - for k, pc in p_c_m.items(): - if p_l_m.get(k) is None and sync_mode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: + # manage user or stock programs not present locally in "active" status + for k, pc in programs_cloud_map.items(): + if programs_local_stock_map.get(k) is None and sync_mode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: pl = program.Program(name=pc.get("name"), code=pc.get("code"), dom_code=pc.get("dom_code"), - default=False, + kind=pc.get("kind"), id=pc.get("id"), modified=datetime.fromisoformat(pc.get("modified")), status=pc.get("status")) @@ -314,12 +327,20 @@ def sync_programs(self, api_instance, sync_mode): logging.info("programs.create.downstream: " + pc.get("name")) # manage programs to be deleted locally and upstream - for pl in programs_to_be_deleted: + for pl in programs_local_to_be_deleted: if p.get("id") is not None: logging.info("programs.delete.upstream: " + pl.get("name")) api_response = api_instance.delete_robot_program(path_params={"program_id":pl.get("id")}) # delete locally permanently ProgramEngine.get_instance().delete(pl.get("name"), logical=False) + # manage stock programs to be deleted locally + for pl in programs_local_stock: + ##logging.info("programs.check.stock.locally: " + pl.get("name") + " id: " + str(pl.get("id"))) + if pl.get("id") is not None and programs_cloud_map.get(pl.get("id")) is None: + logging.info("programs.delete.stock.locally: " + pl.get("name")) + # delete locally permanently + ProgramEngine.get_instance().delete(pl.get("name"), logical=False) + except cloud_api_robot_client.ApiException as e: logging.warn("Exception when calling programs RobotSyncApi: %s\n" % e) \ No newline at end of file diff --git a/coderbot/program.py b/coderbot/program.py index ce787bbf..cc6abed4 100644 --- a/coderbot/program.py +++ b/coderbot/program.py @@ -45,6 +45,8 @@ PROGRAMS_PATH_DEFAULTS = "defaults/programs/" PROGRAM_STATUS_ACTIVE = "active" PROGRAM_STATUS_DELETED = "deleted" +PROGRAM_KIND_STOCK = "stock" +PROGRAM_KIND_USER = "user" musicPackageManager = musicPackages.MusicPackageManager.get_instance() @@ -94,7 +96,7 @@ def __init__(self): logging.info("adding program %s in path %s as default %r", program_name, dirname, ("default" in dirname)) with open(os.path.join(dirname, filename), "r") as f: program_dict = json.load(f) - program_dict["default"] = "default" in dirname + program_dict["kind"] = PROGRAM_KIND_STOCK program_dict["status"] = PROGRAM_STATUS_ACTIVE program = Program.from_dict(program_dict) self.save(program) @@ -139,7 +141,7 @@ def load(self, name): def delete(self, name, logical = True): with self.lock: query = Query() - program_db_entries = self._programs.search((query.name == name) & (query.default == False) & (query.status == PROGRAM_STATUS_ACTIVE)) + program_db_entries = self._programs.search(query.name == name) if len(program_db_entries) > 0: program_db_entry = program_db_entries[0] if logical: @@ -179,12 +181,12 @@ class Program: def dom_code(self): return self._dom_code - def __init__(self, name, code=None, dom_code=None, default=False, id=None, modified=None, status=None): + def __init__(self, name, code=None, dom_code=None, kind=PROGRAM_KIND_USER, id=None, modified=None, status=None): self._thread = None self.name = name self._dom_code = dom_code self._code = code - self._default = default + self._kind = kind self._id = id self._modified = modified self._status = status @@ -218,8 +220,8 @@ def check_end(self): def is_running(self): return self._running - def is_default(self): - return self._default + def is_stock(self): + return self._kind == PROGRAM_KIND_STOCK def run(self, *args): options = args[0] @@ -265,7 +267,7 @@ def as_dict(self): return {'name': self.name, 'dom_code': self._dom_code, 'code': self._code, - 'default': self._default, + 'kind': self._kind, 'id': self._id, 'modified': self._modified.isoformat(), 'status': self._status} @@ -275,7 +277,7 @@ def from_dict(cls, amap): return Program(name=amap['name'], dom_code=amap['dom_code'], code=amap['code'], - default=amap.get('default', False), + kind=amap.get('kind', PROGRAM_KIND_USER), id=amap.get('id', None), modified=datetime.fromisoformat(amap.get('modified', datetime.now().isoformat())), status=amap.get('status', None),) From f5a439515ec2a31e9805f4981b84c27c2f79cd98 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Tue, 30 May 2023 00:17:25 +0100 Subject: [PATCH 07/60] wip --- coderbot/activity.py | 18 ++++++++-- coderbot/cloud/__init__.py | 67 ++++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index 19e3d102..7b810ccf 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -1,6 +1,12 @@ from tinydb import TinyDB, Query from threading import Lock # Programs and Activities databases + +ACTIVITY_STATUS_DELETED = "deleted" +ACTIVITY_STATUS_ACTIVE = "active" +ACTIVITY_KIND_STOCK = "stock" +ACTIVITY_KIND_USER = "user" + class Activities(): _instance = None @@ -37,15 +43,21 @@ def save(self, name, activity): else: self.activities.update(activity, self.query.name == activity["name"]) - def delete(self, name): + def delete(self, name, logical = True): with self.lock: activities = self.activities.search(self.query.name == name) if len(activities) > 0: activity = activities[0] if activity.get("default", False) is True: self.activities.update({'default': True}, self.query.stock == True) - self.activities.remove(self.query.name == activity["name"]) + if logical: + activity["status"] = ACTIVITY_STATUS_DELETED + activity["modified"] = datetime.now().isoformat() + self.activities.update(activity, query.name == name) + else: + self.activities.remove(self.query.name == activity["name"]) + - def list(self): + def list(self, active_only = True): with self.lock: return self.activities.all() diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index 76aac01f..ecb3b359 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -20,6 +20,7 @@ from activity import Activities from program import ProgramEngine import program +import activity import cloud_api_robot_client from cloud_api_robot_client.apis.tags import robot_sync_api @@ -94,7 +95,7 @@ def run(self): api_instance = robot_sync_api.RobotSyncApi(api_client) #self.sync_settings(api_instance, sync_modes["settings"]) - #self.sync_activities(api_instance, sync_modes["activities"]) + self.sync_activities(api_instance, sync_modes["activities"]) self.sync_programs(api_instance, sync_modes["programs"]) sleep(sync_period) @@ -151,26 +152,37 @@ def sync_settings(self, api_instance, sync_mode): logging.warn("Exception when calling settings RobotSyncApi: %s\n" % e) def sync_activities(self, api_instance, sync_mode): - activities = Activities.get_instance().list() + activities_local_user = list() + activities_local_stock = list() + activities_local_to_be_deleted = list() + for p in Activities.get_instance().list(active_only=False): + if p.get("kind") == activity.ACTIVITY_KIND_USER: + if p.get("status") == activity.ACTIVITY_STATUS_ACTIVE: + activities_local_user.append(p) + elif p.get("status") == activity.ACTIVITY_STATUS_ACTIVE: + activities_local_to_be_deleted.append(p) + else: + activities_local_stock.append(p) try: # Get robot activities api_response = api_instance.get_robot_activities() cloud_activities = api_response.body # cloud activities - a_c_m = {} # activities_cloud_map + activities_cloud_map = {} for a in cloud_activities: - a_c_m[a.get("id")] = a + if a.get("status") == activity.ACTIVITY_STATUS_ACTIVE: + activities_cloud_map[a.get("id")] = a - a_l_m = {} # activities_local_map + activities_local_map = {} # local activities no id - for a in activities: + for a in activities_local_user: if a.get("id") is not None: - a_l_m[a.get("id")] = a + activities_local_map[a.get("id")] = a # loop through local - for al in activities: + for al in activities_local_user: logging.info("activities.syncing: " + str(al.get("id")) + " name: " + str(al.get("name"))) - ac = a_c_m.get(al.get("id")) + ac = activities_cloud_map.get(al.get("id")) if ac is not None and ac.get("data") != al.get("data"): al["modified"] = al.get("modified", datetime.now(tz=timezone.utc).isoformat()) local_activity_more_recent = datetime.fromisoformat(ac.get("modified")).timestamp() < datetime.fromisoformat(al.get("modified")).timestamp() @@ -214,11 +226,28 @@ def sync_activities(self, api_instance, sync_mode): elif ac is None and sync_mode in [SYNC_DOWNSTREAM]: Activities.get_instance().delete(al.get("name")) logging.info("activities.delete.downstream: " + al.get("name")) - for k, ac in a_c_m.items(): - if a_l_m.get(k) is None and sync_mode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: + + for k, ac in activities_cloud_map.items(): + if activities_local_map.get(k) is None and sync_mode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: Activities.get_instance().save(ac.get("name"), ac) logging.info("activities.create.downstream: " + ac.get("name")) + # manage local user activities to be deleted locally and upstream + for al in activities_local_to_be_deleted: + if al.get("id") is not None: + logging.info("activities.delete.upstream: " + al.get("name")) + api_response = api_instance.delete_robot_program(path_params={"activity_id":al.get("id")}) + # delete locally permanently + Activities.get_instance().delete(al.get("name"), logical=False) + + # manage local stock activities to be deleted locally + for al in activities_local_stock: + # logging.info("programs.check.stock.locally: " + pl.get("name") + " id: " + str(pl.get("id"))) + if al.get("id") is not None and activities_cloud_map.get(al.get("id")) is None: + logging.info("activities.delete.stock.locally: " + al.get("name")) + # delete locally permanently + Activities.get_instance().delete(al.get("name"), logical=False) + except cloud_api_robot_client.ApiException as e: logging.warn("Exception when calling activities RobotSyncApi: %s\n" % e) @@ -236,15 +265,16 @@ def sync_programs(self, api_instance, sync_mode): programs_local_stock.append(p) try: - # Get robot programs + # Get cloud programs api_response = api_instance.get_robot_programs() cloud_programs = api_response.body - # cloud programs + # cloud programs in a map id : program programs_cloud_map = {} # programs_cloud_map for p in cloud_programs: if p.get("status") == program.PROGRAM_STATUS_ACTIVE: programs_cloud_map[p.get("id")] = p + # local programs, stock, in a map id : program programs_local_stock_map = {} # activities_local_map # local activities no id for p in programs_local_stock: @@ -252,6 +282,7 @@ def sync_programs(self, api_instance, sync_mode): if p.get("id") is not None: programs_local_stock_map[p.get("id")] = p + # sync local user programs # manage user programs present locally and in "active" status for pl in programs_local_user: pc = programs_cloud_map.get(pl.get("id")) @@ -263,7 +294,7 @@ def sync_programs(self, api_instance, sync_mode): logging.info("programs.syncing: " + str(pl.get("id")) + " name: " + pl.get("name") + " sync_mode: " + sync_mode + " pc: " + str(pc)) if pc is not None and not pc_pl_equals: - # cloud program exists and is different + # cloud program exists and is different from local pl["modified"] = pl.get("modified", datetime.now(tz=timezone.utc).isoformat()) local_program_more_recent = datetime.fromisoformat(pc.get("modified")).timestamp() < datetime.fromisoformat(pl.get("modified")).timestamp() if sync_mode == SYNC_UPSTREAM or (local_program_more_recent and sync_mode == SYNC_BIDIRECTIONAL) and not to_be_deleted: @@ -313,7 +344,7 @@ def sync_programs(self, api_instance, sync_mode): ProgramEngine.get_instance().delete(pl.get("name")) logging.info("programs.delete.downstream: " + pl.get("name")) - # manage user or stock programs not present locally in "active" status + # manage cloud programs not present locally in "active" status for k, pc in programs_cloud_map.items(): if programs_local_stock_map.get(k) is None and sync_mode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: pl = program.Program(name=pc.get("name"), @@ -326,15 +357,15 @@ def sync_programs(self, api_instance, sync_mode): ProgramEngine.get_instance().save(pl) logging.info("programs.create.downstream: " + pc.get("name")) - # manage programs to be deleted locally and upstream + # manage local user programs to be deleted locally and upstream for pl in programs_local_to_be_deleted: - if p.get("id") is not None: + if pl.get("id") is not None: logging.info("programs.delete.upstream: " + pl.get("name")) api_response = api_instance.delete_robot_program(path_params={"program_id":pl.get("id")}) # delete locally permanently ProgramEngine.get_instance().delete(pl.get("name"), logical=False) - # manage stock programs to be deleted locally + # manage local stock programs to be deleted locally for pl in programs_local_stock: ##logging.info("programs.check.stock.locally: " + pl.get("name") + " id: " + str(pl.get("id"))) if pl.get("id") is not None and programs_cloud_map.get(pl.get("id")) is None: From 57b2f03fc05dc6b48463683adc85bcbfd658c049 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Fri, 2 Jun 2023 00:35:37 +0100 Subject: [PATCH 08/60] wip --- coderbot/activity.py | 8 +++++ coderbot/cloud/__init__.py | 66 ++++++++++++++++++++------------------ coderbot/program.py | 15 +++++---- coderbot/v1.yml | 6 ++-- 4 files changed, 54 insertions(+), 41 deletions(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index 7b810ccf..d3be07a2 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -7,6 +7,14 @@ ACTIVITY_KIND_STOCK = "stock" ACTIVITY_KIND_USER = "user" +class Activity(): + def __init__(self, name, description, data, kind, status): + self._name = name + self._description = description + self._data = data + self._kind = kind + self._status = status + class Activities(): _instance = None diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index ecb3b359..39e85079 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -17,7 +17,7 @@ from time import sleep from config import Config -from activity import Activities +from activity import Activities, ACTIVITY_KIND_USER, ACTIVITY_KIND_STOCK, ACTIVITY_STATUS_ACTIVE, ACTIVITY_STATUS_DELETED from program import ProgramEngine import program import activity @@ -94,7 +94,7 @@ def run(self): # Create an instance of the API class api_instance = robot_sync_api.RobotSyncApi(api_client) - #self.sync_settings(api_instance, sync_modes["settings"]) + self.sync_settings(api_instance, sync_modes["settings"]) self.sync_activities(api_instance, sync_modes["activities"]) self.sync_programs(api_instance, sync_modes["programs"]) @@ -130,7 +130,7 @@ def sync_settings(self, api_instance, sync_mode): local_setting = Config.read() local_most_recent = datetime.fromisoformat(cloud_setting_object.get("modified", "2000-01-01T00:00:00.000000")).timestamp() < Config.modified() - logging.info("settings.syncing: " + cloud_setting_object.get("id", "") + " name: " + cloud_setting_object.get("name", "")) + # logging.info("settings.syncing: " + cloud_setting_object.get("id", "") + " name: " + cloud_setting_object.get("name", "")) if cloud_setting != local_setting: if sync_mode == SYNC_UPSTREAM or (sync_mode == SYNC_BIDIRECTIONAL and local_most_recent): body = Setting( @@ -155,14 +155,19 @@ def sync_activities(self, api_instance, sync_mode): activities_local_user = list() activities_local_stock = list() activities_local_to_be_deleted = list() - for p in Activities.get_instance().list(active_only=False): - if p.get("kind") == activity.ACTIVITY_KIND_USER: - if p.get("status") == activity.ACTIVITY_STATUS_ACTIVE: - activities_local_user.append(p) - elif p.get("status") == activity.ACTIVITY_STATUS_ACTIVE: - activities_local_to_be_deleted.append(p) + activities_local_map = {} + for a in Activities.get_instance().list(active_only=False): + if a.get("kind") == ACTIVITY_KIND_USER: + if a.get("status") == ACTIVITY_STATUS_ACTIVE: + activities_local_user.append(a) + if a.get("id") is not None: + activities_local_map[a.get("id")] = a + elif a.get("status") == ACTIVITY_STATUS_DELETED: + activities_local_to_be_deleted.append(a) else: - activities_local_stock.append(p) + activities_local_stock.append(a) + if a.get("id") is not None: + activities_local_map[a.get("id")] = a try: # Get robot activities api_response = api_instance.get_robot_activities() @@ -170,20 +175,15 @@ def sync_activities(self, api_instance, sync_mode): # cloud activities activities_cloud_map = {} for a in cloud_activities: - if a.get("status") == activity.ACTIVITY_STATUS_ACTIVE: + if a.get("status") == ACTIVITY_STATUS_ACTIVE: activities_cloud_map[a.get("id")] = a - activities_local_map = {} - # local activities no id - for a in activities_local_user: - if a.get("id") is not None: - activities_local_map[a.get("id")] = a - # loop through local for al in activities_local_user: logging.info("activities.syncing: " + str(al.get("id")) + " name: " + str(al.get("name"))) ac = activities_cloud_map.get(al.get("id")) - if ac is not None and ac.get("data") != al.get("data"): + ac_al_equals = (ac is not None and ac.get("data") == al.get("data")) + if ac is not None and not ac_al_equals: al["modified"] = al.get("modified", datetime.now(tz=timezone.utc).isoformat()) local_activity_more_recent = datetime.fromisoformat(ac.get("modified")).timestamp() < datetime.fromisoformat(al.get("modified")).timestamp() if sync_mode == SYNC_UPSTREAM or (local_activity_more_recent and sync_mode == SYNC_BIDIRECTIONAL): @@ -229,8 +229,15 @@ def sync_activities(self, api_instance, sync_mode): for k, ac in activities_cloud_map.items(): if activities_local_map.get(k) is None and sync_mode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: - Activities.get_instance().save(ac.get("name"), ac) logging.info("activities.create.downstream: " + ac.get("name")) + activity = json.loads(ac.get("data")) + activity["id"] = ac.get("id") + activity["org_id"] = ac.get("org_id") + activity["name"] = ac.get("name") + activity["description"] = ac.get("description") + activity["kind"] = ac.get("kind") + activity["status"] = ac.get("status") + Activities.get_instance().save(ac.get("name"), activity) # manage local user activities to be deleted locally and upstream for al in activities_local_to_be_deleted: @@ -242,7 +249,7 @@ def sync_activities(self, api_instance, sync_mode): # manage local stock activities to be deleted locally for al in activities_local_stock: - # logging.info("programs.check.stock.locally: " + pl.get("name") + " id: " + str(pl.get("id"))) + # logging.info("activities.check.stock.locally: " + al.get("name") + " id: " + str(al.get("id"))) if al.get("id") is not None and activities_cloud_map.get(al.get("id")) is None: logging.info("activities.delete.stock.locally: " + al.get("name")) # delete locally permanently @@ -254,15 +261,20 @@ def sync_activities(self, api_instance, sync_mode): def sync_programs(self, api_instance, sync_mode): programs_local_user = list() programs_local_stock = list() + programs_local_map = {} programs_local_to_be_deleted = list() for p in ProgramEngine.get_instance().prog_list(active_only=False): if p.get("kind") == program.PROGRAM_KIND_USER: if p.get("status") == program.PROGRAM_STATUS_ACTIVE: programs_local_user.append(p) + if p.get("id") is not None: + programs_local_map[p.get("id")] = p elif p.get("status") == program.PROGRAM_STATUS_DELETED: programs_local_to_be_deleted.append(p) else: programs_local_stock.append(p) + if p.get("id") is not None: + programs_local_map[p.get("id")] = p try: # Get cloud programs @@ -274,14 +286,6 @@ def sync_programs(self, api_instance, sync_mode): if p.get("status") == program.PROGRAM_STATUS_ACTIVE: programs_cloud_map[p.get("id")] = p - # local programs, stock, in a map id : program - programs_local_stock_map = {} # activities_local_map - # local activities no id - for p in programs_local_stock: - #logging.info("programs.local: " + str(p.get("id")) + " name: " + p.get("name")) - if p.get("id") is not None: - programs_local_stock_map[p.get("id")] = p - # sync local user programs # manage user programs present locally and in "active" status for pl in programs_local_user: @@ -291,7 +295,7 @@ def sync_programs(self, api_instance, sync_mode): pc.get("code") == pl.get("code") and pc.get("dom_code") == pl.get("dom_code") and pc.get("status") == pl.get("status")) - logging.info("programs.syncing: " + str(pl.get("id")) + " name: " + pl.get("name") + " sync_mode: " + sync_mode + " pc: " + str(pc)) + logging.info("programs.syncing: " + str(pl.get("id")) + " name: " + pl.get("name")) if pc is not None and not pc_pl_equals: # cloud program exists and is different from local @@ -346,7 +350,7 @@ def sync_programs(self, api_instance, sync_mode): # manage cloud programs not present locally in "active" status for k, pc in programs_cloud_map.items(): - if programs_local_stock_map.get(k) is None and sync_mode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: + if programs_local_map.get(k) is None and sync_mode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: pl = program.Program(name=pc.get("name"), code=pc.get("code"), dom_code=pc.get("dom_code"), @@ -367,7 +371,7 @@ def sync_programs(self, api_instance, sync_mode): # manage local stock programs to be deleted locally for pl in programs_local_stock: - ##logging.info("programs.check.stock.locally: " + pl.get("name") + " id: " + str(pl.get("id"))) + # logging.info("programs.check.stock.locally: " + pl.get("name") + " id: " + str(pl.get("id"))) if pl.get("id") is not None and programs_cloud_map.get(pl.get("id")) is None: logging.info("programs.delete.stock.locally: " + pl.get("name")) # delete locally permanently diff --git a/coderbot/program.py b/coderbot/program.py index cc6abed4..14fa8858 100644 --- a/coderbot/program.py +++ b/coderbot/program.py @@ -122,8 +122,8 @@ def save(self, program): program._modified = datetime.now() self._program = program program_db_entry = self._program.as_dict() - if self._programs.search(query.name == program.name) != []: - self._programs.update(program_db_entry, query.name == program.name) + if self._programs.search(query.name == program._name) != []: + self._programs.update(program_db_entry, query.name == program._name) else: self._programs.insert(program_db_entry) @@ -157,7 +157,7 @@ def create(self, name, code): return self._program def is_running(self, name): - return self._program.is_running() and self._program.name == name + return self._program.is_running() and self._program._name == name def check_end(self): return self._program.check_end() @@ -181,9 +181,10 @@ class Program: def dom_code(self): return self._dom_code - def __init__(self, name, code=None, dom_code=None, kind=PROGRAM_KIND_USER, id=None, modified=None, status=None): + def __init__(self, name, description=None, code=None, dom_code=None, kind=PROGRAM_KIND_USER, id=None, modified=None, status=None): self._thread = None - self.name = name + self._name = name + self._description = description self._dom_code = dom_code self._code = code self._kind = kind @@ -229,7 +230,7 @@ def run(self, *args): program = self try: if options.get("autoRecVideo") == True: - get_cam().video_rec(program.name.replace(" ", "_")) + get_cam().video_rec(program._name.replace(" ", "_")) logging.debug("starting video") except Exception as e: logging.error("Camera not available: " + str(e)) @@ -264,7 +265,7 @@ def run(self, *args): def as_dict(self): - return {'name': self.name, + return {'name': self._name, 'dom_code': self._dom_code, 'code': self._code, 'kind': self._kind, diff --git a/coderbot/v1.yml b/coderbot/v1.yml index a3c8872f..787053d1 100644 --- a/coderbot/v1.yml +++ b/coderbot/v1.yml @@ -715,11 +715,11 @@ components: maxLength: 256 default: type: boolean - stock: - type: boolean + kind: + type: string required: - name - description - default - - stock + - kind From 19a4398bfcac4794d76f337fd822d83f61c09d18 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sat, 3 Jun 2023 00:24:52 +0100 Subject: [PATCH 09/60] wip --- coderbot/cloud/__init__.py | 73 +++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index 39e85079..e5f79e80 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -35,6 +35,9 @@ SYNC_DOWNSTREAM = 'd' SYNC_BIDIRECTIONAL = 'b' +ENTITY_KIND_USER = "user" +ENTITY_KIND_STOCK = "stock" + AUTH_FILE = "data/auth.json" class CloudManager(threading.Thread): @@ -86,17 +89,20 @@ def run(self): sync_modes = settings.get("sync_modes", {"settings": "n", "activities": "n", "programs": "n"}) sync_period = int(settings.get("sync_period", "60")) - token = self.get_token_or_register(settings) - self.configuration.access_token = token + try: + token = self.get_token_or_register(settings) + self.configuration.access_token = token - # Enter a context with an instance of the API client - with cloud_api_robot_client.ApiClient(self.configuration) as api_client: - # Create an instance of the API class - api_instance = robot_sync_api.RobotSyncApi(api_client) - - self.sync_settings(api_instance, sync_modes["settings"]) - self.sync_activities(api_instance, sync_modes["activities"]) - self.sync_programs(api_instance, sync_modes["programs"]) + # Enter a context with an instance of the API client + with cloud_api_robot_client.ApiClient(self.configuration) as api_client: + # Create an instance of the API class + api_instance = robot_sync_api.RobotSyncApi(api_client) + + self.sync_settings(api_instance, sync_modes["settings"]) + self.sync_activities(api_instance, sync_modes["activities"]) + self.sync_programs(api_instance, sync_modes["programs"]) + except Exception as e: + logging.warn("run.sync.api_not_available: " + str(e)) sleep(sync_period) logging.info("run.sync.end") @@ -105,9 +111,9 @@ def get_token_or_register(self, settings): logging.info("run.check.token") token = self.get_auth().get("token") reg_otp = settings.get("reg_otp") - logging.info("otp_reg:" + reg_otp) try: if token is None and reg_otp is not None: + logging.info("run.get_token_or_register.get_token") with cloud_api_robot_client.ApiClient(self.configuration) as api_client: api_instance = robot_sync_api.RobotSyncApi(api_client) body = RobotRegisterData( @@ -121,33 +127,36 @@ def get_token_or_register(self, settings): except cloud_api_robot_client.ApiException as e: logging.warn("Exception when calling register_robot RobotSyncApi: %s\n" % e) + # sync settings def sync_settings(self, api_instance, sync_mode): + # Sync settings is different from syncing other entities, like activities and programs, since there can only + # be a single entity for each robot (both device and cloud twin). + # So the algo is simpler and favorites the "stock" entity over the "user" entity, if available. try: - # Create an instance of the API class api_response = api_instance.get_robot_setting() cloud_setting_object = api_response.body cloud_setting = json.loads(cloud_setting_object.get('data')) local_setting = Config.read() - local_most_recent = datetime.fromisoformat(cloud_setting_object.get("modified", "2000-01-01T00:00:00.000000")).timestamp() < Config.modified() + local_most_recent = datetime.fromisoformat(cloud_setting_object.get("modified")).timestamp() < Config.modified() + cloud_kind_user = cloud_setting_object.get("kind") == ENTITY_KIND_USER # logging.info("settings.syncing: " + cloud_setting_object.get("id", "") + " name: " + cloud_setting_object.get("name", "")) - if cloud_setting != local_setting: - if sync_mode == SYNC_UPSTREAM or (sync_mode == SYNC_BIDIRECTIONAL and local_most_recent): - body = Setting( - id = cloud_setting_object.get('id'), - org_id = cloud_setting_object.get('org_id'), - name = cloud_setting_object.get('name'), - description = cloud_setting_object.get('description'), - data = json.dumps(local_setting), - kind = local_setting.get("kind", "stock"), - modified = datetime.now().isoformat(), - status = cloud_setting_object.get('status'), - ) - api_response = api_instance.set_robot_setting(body) - logging.info("settings.upstream") - if sync_mode == SYNC_DOWNSTREAM: # setting, down - Config.write(cloud_setting.data.setting) - logging.info("settings.downstream") + if cloud_kind_user and cloud_setting != local_setting and local_most_recent: + body = Setting( + id = cloud_setting_object.get('id'), + org_id = cloud_setting_object.get('org_id'), + name = cloud_setting_object.get('name'), + description = cloud_setting_object.get('description'), + data = json.dumps(local_setting), + kind = local_setting.get("kind", ENTITY_KIND_STOCK), + modified = datetime.now().isoformat(), + status = cloud_setting_object.get('status'), + ) + api_response = api_instance.set_robot_setting(body) + logging.info("settings.upstream") + elif cloud_setting != local_setting: # setting, down + Config.write(cloud_setting.data.setting) + logging.info("settings.downstream") except cloud_api_robot_client.ApiException as e: logging.warn("Exception when calling settings RobotSyncApi: %s\n" % e) @@ -195,7 +204,7 @@ def sync_activities(self, api_instance, sync_mode): name=al.get("name"), description=al.get("description"), data=json.dumps(al.get("data")), - kind = al.get("kind", "stock"), + kind = al.get("kind", ENTITY_KIND_STOCK), modified=al.get("modified").isoformat(), status='active', ) @@ -214,7 +223,7 @@ def sync_activities(self, api_instance, sync_mode): name=al.get("name"), description=al.get("description"), data=json.dumps(al), - kind=al.get("kind", "stock"), + kind=al.get("kind", ENTITY_KIND_STOCK), modified=al.get("modified", datetime.now(tz=timezone.utc).isoformat()), status="active", ) From 9377a573d922ffb97259dcb785ef5677dfc0a530 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 00:04:27 +0100 Subject: [PATCH 10/60] wip --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 35aad39d..6734cd58 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ Flask==2.2.3 Flask-Cors==3.0.10 tinydb==4.7.1 Werkzeug==2.2.3 +cloud_api_robot_client @ git+https://github.com/CoderBotOrg/cloud_api_robot_client.git # Misc utils setuptools==67.4.0 From 1cf11aaa6b1ea87ebbe38e754c28161b92747eff Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 00:09:13 +0100 Subject: [PATCH 11/60] wip --- .github/workflows/build_backend.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index 0331b4c8..cdd253c5 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -22,7 +22,7 @@ jobs: - run: | export PYTHONPATH=./stub:./coderbot:./test python3 coderbot/main.py > coderbot.log & - sleep 30 + sleep 60 apt-get install -y python3-venv mkdir -p schemathesis python3 -m venv schemathesis From 8f0e3774b7e6f8a6116ff4a0aa83b09d0a075cde Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 00:10:22 +0100 Subject: [PATCH 12/60] wip --- docker/stub/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/stub/requirements.txt b/docker/stub/requirements.txt index 81c1bc21..a758a746 100644 --- a/docker/stub/requirements.txt +++ b/docker/stub/requirements.txt @@ -4,6 +4,7 @@ Flask==2.2.3 Flask-Cors==3.0.10 tinydb==4.7.1 Werkzeug==2.2.3 +cloud_api_robot_client @ git+https://github.com/CoderBotOrg/cloud_api_robot_client.git # Misc utils setuptools==67.4.0 From 060707607f7cf6ec73a207454751b2840e26f2e5 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 22:26:11 +0100 Subject: [PATCH 13/60] wip --- .github/workflows/build_backend.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index cdd253c5..cd4fdff6 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -8,7 +8,7 @@ on: push jobs: test: runs-on: ubuntu-latest - container: coderbot/coderbot-ci:3.9-bullseye-slim + container: ghcr.io/coderbotorg/coderbot-ci:stub-latest steps: - uses: actions/checkout@v3 # Checking out the repo - run: pip install -r docker/stub/requirements.txt From fba1635434e43a710e89364b50e63d1bbd3e2ea2 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 22:30:54 +0100 Subject: [PATCH 14/60] wip --- .github/workflows/build_backend.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index cd4fdff6..fe547f74 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -8,7 +8,11 @@ on: push jobs: test: runs-on: ubuntu-latest - container: ghcr.io/coderbotorg/coderbot-ci:stub-latest + container: + image: ghcr.io/coderbotorg/coderbot-ci:stub-latest + credentials: + username: ${{ github.actor }} + password: ${{ secrets.github_token }} steps: - uses: actions/checkout@v3 # Checking out the repo - run: pip install -r docker/stub/requirements.txt From e5a259292e082b15e7998d758a445e43b638d931 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 22:38:32 +0100 Subject: [PATCH 15/60] wip --- .github/workflows/build_backend.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index fe547f74..37dc3a9a 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -12,7 +12,7 @@ jobs: image: ghcr.io/coderbotorg/coderbot-ci:stub-latest credentials: username: ${{ github.actor }} - password: ${{ secrets.github_token }} + password: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v3 # Checking out the repo - run: pip install -r docker/stub/requirements.txt From 870ea4bfe8da96f75729e8a9d9a0222b53a4add7 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 23:44:43 +0200 Subject: [PATCH 16/60] wip --- .github/workflows/build_backend.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index 37dc3a9a..9cec776a 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -13,6 +13,7 @@ jobs: credentials: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + steps: - uses: actions/checkout@v3 # Checking out the repo - run: pip install -r docker/stub/requirements.txt From ab771592ba38652fac19afe2f1e03e112aea5db6 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 23:51:13 +0200 Subject: [PATCH 17/60] wip --- .github/workflows/build_backend.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index 9cec776a..3b26c239 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -12,8 +12,8 @@ jobs: image: ghcr.io/coderbotorg/coderbot-ci:stub-latest credentials: username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - + password: ${{ secrets.GHCR_READ }} + steps: - uses: actions/checkout@v3 # Checking out the repo - run: pip install -r docker/stub/requirements.txt From 0b84abb0e64ac186ae9956baba12c4e15d678b06 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 22:55:25 +0100 Subject: [PATCH 18/60] wip --- .github/workflows/build_backend.yml | 1 - coderbot/activity.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index 3b26c239..189d0835 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -13,7 +13,6 @@ jobs: credentials: username: ${{ github.actor }} password: ${{ secrets.GHCR_READ }} - steps: - uses: actions/checkout@v3 # Checking out the repo - run: pip install -r docker/stub/requirements.txt diff --git a/coderbot/activity.py b/coderbot/activity.py index d3be07a2..3d4f13f7 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -1,5 +1,6 @@ from tinydb import TinyDB, Query from threading import Lock +from datetime import datetime # Programs and Activities databases ACTIVITY_STATUS_DELETED = "deleted" From cb8f7f9456e33470d7b6e9ab9d82cd2136121693 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 23:05:32 +0100 Subject: [PATCH 19/60] wip --- coderbot/activity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index 3d4f13f7..b44bd777 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -62,7 +62,7 @@ def delete(self, name, logical = True): if logical: activity["status"] = ACTIVITY_STATUS_DELETED activity["modified"] = datetime.now().isoformat() - self.activities.update(activity, query.name == name) + self.activities.update(activity, self.query.name == name) else: self.activities.remove(self.query.name == activity["name"]) From 064517271e08abe2bd74fac6f1a387cbbf4820a2 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 23:15:13 +0100 Subject: [PATCH 20/60] wip --- coderbot/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderbot/api.py b/coderbot/api.py index a5fe50f5..12d13f23 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -340,7 +340,7 @@ def statusProgram(name): prog = prog_engine.get_current_program() if prog is None: prog = Program("") - return {'name': prog.name, "running": prog.is_running(), "log": prog_engine.get_log()} + return {'name': prog._name, "running": prog.is_running(), "log": prog_engine.get_log()} ## Activities From 304f2210154ba3158ec780a3aca4bf82e25099c6 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 23:33:21 +0100 Subject: [PATCH 21/60] wip --- docker/Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 6b88fce8..7f305ebe 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM coderbot/rpi-debian:bullseye-20220923 +FROM coderbot/rpi-debian:bullseye-20230530 ENV QEMU_CPU=max ENV DEBIAN_FRONTEND=noninteractive @@ -19,7 +19,8 @@ RUN install_packages \ libatlas-base-dev \ libhdf5-dev \ alsa-utils \ - espeak + espeak \ + git RUN install_packages \ libharfbuzz-bin \ libwebp6 \ From affa7264f6c455133e238cf23b7988f80c1c038f Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Mon, 5 Jun 2023 23:46:03 +0100 Subject: [PATCH 22/60] wip --- coderbot/api.py | 2 +- coderbot/program.py | 12 ++++++++---- docker/stub/Dockerfile | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/coderbot/api.py b/coderbot/api.py index 12d13f23..a5fe50f5 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -340,7 +340,7 @@ def statusProgram(name): prog = prog_engine.get_current_program() if prog is None: prog = Program("") - return {'name': prog._name, "running": prog.is_running(), "log": prog_engine.get_log()} + return {'name': prog.name, "running": prog.is_running(), "log": prog_engine.get_log()} ## Activities diff --git a/coderbot/program.py b/coderbot/program.py index 14fa8858..a892950e 100644 --- a/coderbot/program.py +++ b/coderbot/program.py @@ -122,8 +122,8 @@ def save(self, program): program._modified = datetime.now() self._program = program program_db_entry = self._program.as_dict() - if self._programs.search(query.name == program._name) != []: - self._programs.update(program_db_entry, query.name == program._name) + if self._programs.search(query.name == program.name) != []: + self._programs.update(program_db_entry, query.name == program.name) else: self._programs.insert(program_db_entry) @@ -157,7 +157,7 @@ def create(self, name, code): return self._program def is_running(self, name): - return self._program.is_running() and self._program._name == name + return self._program.is_running() and self._program.name == name def check_end(self): return self._program.check_end() @@ -230,7 +230,7 @@ def run(self, *args): program = self try: if options.get("autoRecVideo") == True: - get_cam().video_rec(program._name.replace(" ", "_")) + get_cam().video_rec(program.name.replace(" ", "_")) logging.debug("starting video") except Exception as e: logging.error("Camera not available: " + str(e)) @@ -264,6 +264,10 @@ def run(self, *args): self._running = False + @property + def name(self): + return self._name + def as_dict(self): return {'name': self._name, 'dom_code': self._dom_code, diff --git a/docker/stub/Dockerfile b/docker/stub/Dockerfile index aaf42d81..43180a2a 100644 --- a/docker/stub/Dockerfile +++ b/docker/stub/Dockerfile @@ -18,6 +18,7 @@ RUN apt-get update -y && apt-get install -y \ libhdf5-dev \ alsa-utils \ espeak \ + git \ libharfbuzz-bin \ libwebp6 \ libilmbase25 \ From b2999aa6ca1828ef6986be618cbb261d6b412162 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Wed, 7 Jun 2023 00:20:31 +0100 Subject: [PATCH 23/60] wip --- coderbot/api.py | 10 ++- coderbot/cloud/__init__.py | 133 ++++++++++++++++++++++--------------- coderbot/v1.yml | 31 +++++++++ 3 files changed, 120 insertions(+), 54 deletions(-) diff --git a/coderbot/api.py b/coderbot/api.py index a5fe50f5..c413f8b6 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -22,6 +22,7 @@ from runtime_test import run_test from musicPackages import MusicPackageManager from program import Program, ProgramEngine +from cloud import CloudManager from balena import Balena from coderbot import CoderBot @@ -404,4 +405,11 @@ def deleteCNNModel(name): cnn = CNNManager.get_instance() model_status = cnn.delete_model(model_name=name) - return model_status \ No newline at end of file + return model_status + +def cloudSyncRequest(): + CloudManager.get_instance().sync() + return 200 + +def cloudSyncStatus(): + return CloudManager.get_instance().sync_status() \ No newline at end of file diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index e5f79e80..e5b353ce 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -70,6 +70,12 @@ def get_instance(cls): return cls._instance def __init__(self): + self._syncing = False + self._sync_status = { + "settings": "", + "activities": "", + "programs": "" + } threading.Thread.__init__(self) # Defining the host is optional and defaults to https://api.coderbot.org/api/v1 # See configuration.py for a list of all supported configuration parameters. @@ -84,28 +90,42 @@ def __init__(self): def run(self): while(True): - settings = Config.read() - logging.info("run.sync.begin") - sync_modes = settings.get("sync_modes", {"settings": "n", "activities": "n", "programs": "n"}) - sync_period = int(settings.get("sync_period", "60")) + sync_period = int(Config.read().get("sync_period", "60")) + self.sync() + sleep(sync_period) - try: - token = self.get_token_or_register(settings) - self.configuration.access_token = token + def syncing(self): + return self._syncing - # Enter a context with an instance of the API client - with cloud_api_robot_client.ApiClient(self.configuration) as api_client: - # Create an instance of the API class - api_instance = robot_sync_api.RobotSyncApi(api_client) - - self.sync_settings(api_instance, sync_modes["settings"]) - self.sync_activities(api_instance, sync_modes["activities"]) - self.sync_programs(api_instance, sync_modes["programs"]) - except Exception as e: - logging.warn("run.sync.api_not_available: " + str(e)) + def sync_status(self): + return self._sync_status - sleep(sync_period) - logging.info("run.sync.end") + def sync(self): + if self._syncing == True: + return + self._syncing = True + + settings = Config.read() + logging.info("run.sync.begin") + sync_modes = settings.get("sync_modes", {"settings": "n", "activities": "n", "programs": "n"}) + + try: + token = self.get_token_or_register(settings) + self.configuration.access_token = token + + # Enter a context with an instance of the API client + with cloud_api_robot_client.ApiClient(self.configuration) as api_client: + # Create an instance of the API class + api_instance = robot_sync_api.RobotSyncApi(api_client) + + self.sync_settings(api_instance, sync_modes["settings"]) + self.sync_activities(api_instance, sync_modes["activities"]) + self.sync_programs(api_instance, sync_modes["programs"]) + except Exception as e: + logging.warn("run.sync.api_not_available: " + str(e)) + + logging.info("run.sync.end") + self._syncing = False def get_token_or_register(self, settings): logging.info("run.check.token") @@ -133,6 +153,7 @@ def sync_settings(self, api_instance, sync_mode): # be a single entity for each robot (both device and cloud twin). # So the algo is simpler and favorites the "stock" entity over the "user" entity, if available. try: + self._sync_status["settings"] = "syncing" api_response = api_instance.get_robot_setting() cloud_setting_object = api_response.body cloud_setting = json.loads(cloud_setting_object.get('data')) @@ -155,29 +176,31 @@ def sync_settings(self, api_instance, sync_mode): api_response = api_instance.set_robot_setting(body) logging.info("settings.upstream") elif cloud_setting != local_setting: # setting, down - Config.write(cloud_setting.data.setting) + Config.write(cloud_setting) logging.info("settings.downstream") + self._sync_status["settings"] = "synced" except cloud_api_robot_client.ApiException as e: logging.warn("Exception when calling settings RobotSyncApi: %s\n" % e) def sync_activities(self, api_instance, sync_mode): - activities_local_user = list() - activities_local_stock = list() - activities_local_to_be_deleted = list() - activities_local_map = {} - for a in Activities.get_instance().list(active_only=False): - if a.get("kind") == ACTIVITY_KIND_USER: - if a.get("status") == ACTIVITY_STATUS_ACTIVE: - activities_local_user.append(a) + try: + self._sync_status["activities"] = "syncing" + activities_local_user = list() + activities_local_stock = list() + activities_local_to_be_deleted = list() + activities_local_map = {} + for a in Activities.get_instance().list(active_only=False): + if a.get("kind") == ACTIVITY_KIND_USER: + if a.get("status") == ACTIVITY_STATUS_ACTIVE: + activities_local_user.append(a) + if a.get("id") is not None: + activities_local_map[a.get("id")] = a + elif a.get("status") == ACTIVITY_STATUS_DELETED: + activities_local_to_be_deleted.append(a) + else: + activities_local_stock.append(a) if a.get("id") is not None: activities_local_map[a.get("id")] = a - elif a.get("status") == ACTIVITY_STATUS_DELETED: - activities_local_to_be_deleted.append(a) - else: - activities_local_stock.append(a) - if a.get("id") is not None: - activities_local_map[a.get("id")] = a - try: # Get robot activities api_response = api_instance.get_robot_activities() cloud_activities = api_response.body @@ -264,28 +287,31 @@ def sync_activities(self, api_instance, sync_mode): # delete locally permanently Activities.get_instance().delete(al.get("name"), logical=False) + self._sync_status["activities"] = "synced" except cloud_api_robot_client.ApiException as e: logging.warn("Exception when calling activities RobotSyncApi: %s\n" % e) + self._sync_status["activities"] = "failed" def sync_programs(self, api_instance, sync_mode): - programs_local_user = list() - programs_local_stock = list() - programs_local_map = {} - programs_local_to_be_deleted = list() - for p in ProgramEngine.get_instance().prog_list(active_only=False): - if p.get("kind") == program.PROGRAM_KIND_USER: - if p.get("status") == program.PROGRAM_STATUS_ACTIVE: - programs_local_user.append(p) + try: + self._sync_status["programs"] = "syncing" + programs_local_user = list() + programs_local_stock = list() + programs_local_map = {} + programs_local_to_be_deleted = list() + for p in ProgramEngine.get_instance().prog_list(active_only=False): + if p.get("kind") == program.PROGRAM_KIND_USER: + if p.get("status") == program.PROGRAM_STATUS_ACTIVE: + programs_local_user.append(p) + if p.get("id") is not None: + programs_local_map[p.get("id")] = p + elif p.get("status") == program.PROGRAM_STATUS_DELETED: + programs_local_to_be_deleted.append(p) + else: + programs_local_stock.append(p) if p.get("id") is not None: programs_local_map[p.get("id")] = p - elif p.get("status") == program.PROGRAM_STATUS_DELETED: - programs_local_to_be_deleted.append(p) - else: - programs_local_stock.append(p) - if p.get("id") is not None: - programs_local_map[p.get("id")] = p - - try: + # Get cloud programs api_response = api_instance.get_robot_programs() cloud_programs = api_response.body @@ -385,6 +411,7 @@ def sync_programs(self, api_instance, sync_mode): logging.info("programs.delete.stock.locally: " + pl.get("name")) # delete locally permanently ProgramEngine.get_instance().delete(pl.get("name"), logical=False) - + self._sync_status["programs"] = "synced" except cloud_api_robot_client.ApiException as e: - logging.warn("Exception when calling programs RobotSyncApi: %s\n" % e) \ No newline at end of file + logging.warn("Exception when calling programs RobotSyncApi: %s\n" % e) + self._sync_status["programs"] = "failed" \ No newline at end of file diff --git a/coderbot/v1.yml b/coderbot/v1.yml index 787053d1..01af71e8 100644 --- a/coderbot/v1.yml +++ b/coderbot/v1.yml @@ -605,6 +605,27 @@ paths: responses: 200: description: "CNN Model deleted" + /cloud/sync: + post: + operationId: "api.cloudSyncRequest" + summary: "request a Sync activity" + tags: + - Cloud Sync + responses: + 200: + description: "Cloud Sync request" + get: + operationId: "api.cloudSyncStatus" + summary: "request a Sync activity" + tags: + - Cloud Sync + responses: + 200: + description: "Cloud Sync request" + content: + application/json: + schema: + $ref: '#/components/schemas/CloudSyncStatus' components: schemas: @@ -723,3 +744,13 @@ components: - default - kind + CloudSyncStatus: + type: object + properties: + settings: + type: string + activities: + type: string + programs: + type: string + From a430f2ad334e1dcafe7c18bcb1aad30afc71c7fa Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 11 Jun 2023 23:14:20 +0100 Subject: [PATCH 24/60] wip --- coderbot/api.py | 20 +++++++++- coderbot/cloud/__init__.py | 60 ++++++++++++++++++++++------- coderbot/v1.yml | 79 +++++++++++++++++++++++++++++++++++++- 3 files changed, 144 insertions(+), 15 deletions(-) diff --git a/coderbot/api.py b/coderbot/api.py index c413f8b6..e1a3470b 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -412,4 +412,22 @@ def cloudSyncRequest(): return 200 def cloudSyncStatus(): - return CloudManager.get_instance().sync_status() \ No newline at end of file + return CloudManager.get_instance().sync_status() + +def cloudRegistrationRequest(): + CloudManager.get_instance().register() + return 200 + +def cloudRegistrationDelete(): + CloudManager.get_instance().unregister() + return 200 + +def cloudRegistrationStatus(): + return { + "registered": CloudManager.get_instance().registration_status(), + "name": config.get('coderbot_name', ""), + "description": config.get('coderbot_description', ""), + "org_id": config.get('org_id', ""), + "org_name": config.get('org_name', ""), + "org_description": config.get('org_description', "") + } diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index e5b353ce..3e5e5c96 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -88,6 +88,36 @@ def __init__(self): self.write_auth({}) self.start() + def register(self, registration_request): + logging.info("register.check.token") + token = self.get_auth().get("token") + if token: + logging.warn("register.check.token_already_there") + return + reg_otp = registration_request.get("otp") + try: + self._sync_status["registration"] = "registering" + logging.info("register.get_token") + with cloud_api_robot_client.ApiClient(self.configuration) as api_client: + api_instance = robot_sync_api.RobotSyncApi(api_client) + body = RobotRegisterData( + otp=reg_otp, + ) + api_response = api_instance.register_robot(body=body) + logging.info(api_response.body) + token = api_response.body.get("token") + self.write_auth({"token":token}) + self._sync_status["registration"] = "registered" + except cloud_api_robot_client.ApiException as e: + logging.warn("Exception when calling register_robot RobotSyncApi: %s\n" % e) + raise + + def unregister(self): + self.write_auth({ "token": None }) + + def registration_status(self): + return self._auth.get("token") is not None + def run(self): while(True): sync_period = int(Config.read().get("sync_period", "60")) @@ -109,20 +139,21 @@ def sync(self): logging.info("run.sync.begin") sync_modes = settings.get("sync_modes", {"settings": "n", "activities": "n", "programs": "n"}) - try: - token = self.get_token_or_register(settings) - self.configuration.access_token = token + token = self.get_auth().get("token") + if token is not None: + try: + self.configuration.access_token = token - # Enter a context with an instance of the API client - with cloud_api_robot_client.ApiClient(self.configuration) as api_client: - # Create an instance of the API class - api_instance = robot_sync_api.RobotSyncApi(api_client) - - self.sync_settings(api_instance, sync_modes["settings"]) - self.sync_activities(api_instance, sync_modes["activities"]) - self.sync_programs(api_instance, sync_modes["programs"]) - except Exception as e: - logging.warn("run.sync.api_not_available: " + str(e)) + # Enter a context with an instance of the API client + with cloud_api_robot_client.ApiClient(self.configuration) as api_client: + # Create an instance of the API class + api_instance = robot_sync_api.RobotSyncApi(api_client) + + self.sync_settings(api_instance, sync_modes["settings"]) + self.sync_activities(api_instance, sync_modes["activities"]) + self.sync_programs(api_instance, sync_modes["programs"]) + except Exception as e: + logging.warn("run.sync.api_not_available: " + str(e)) logging.info("run.sync.end") self._syncing = False @@ -133,6 +164,7 @@ def get_token_or_register(self, settings): reg_otp = settings.get("reg_otp") try: if token is None and reg_otp is not None: + self._sync_status["registration"] = "registering" logging.info("run.get_token_or_register.get_token") with cloud_api_robot_client.ApiClient(self.configuration) as api_client: api_instance = robot_sync_api.RobotSyncApi(api_client) @@ -143,6 +175,7 @@ def get_token_or_register(self, settings): logging.info(api_response.body) token = api_response.body.get("token") self.write_auth({"token":token}) + self._sync_status["registration"] = "registered" return token except cloud_api_robot_client.ApiException as e: logging.warn("Exception when calling register_robot RobotSyncApi: %s\n" % e) @@ -181,6 +214,7 @@ def sync_settings(self, api_instance, sync_mode): self._sync_status["settings"] = "synced" except cloud_api_robot_client.ApiException as e: logging.warn("Exception when calling settings RobotSyncApi: %s\n" % e) + self._sync_status["registration"] = "failed" def sync_activities(self, api_instance, sync_mode): try: diff --git a/coderbot/v1.yml b/coderbot/v1.yml index 01af71e8..8539dbb5 100644 --- a/coderbot/v1.yml +++ b/coderbot/v1.yml @@ -605,6 +605,49 @@ paths: responses: 200: description: "CNN Model deleted" + + /cloud/registration: + post: + operationId: "api.cloudRegistrationRequest" + summary: "request a Registration activity" + tags: + - Cloud Sync + requestBody: + description: Registration Request parameters + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CloudRegistrationRequest' + responses: + 200: + description: "Cloud Sync request" + get: + operationId: "api.cloudRegistrationStatus" + summary: "get status of a Registration activity" + tags: + - Cloud Sync + responses: + 200: + description: "Cloud Sync request" + content: + application/json: + schema: + $ref: '#/components/schemas/CloudRegistrationStatus' + + delete: + operationId: "api.cloudRegistrationDelete" + summary: "get status of a Registration activity" + tags: + - Cloud Sync + responses: + 200: + description: "Cloud Sync request" + content: + application/json: + schema: + $ref: '#/components/schemas/CloudRegistrationStatus' + /cloud/sync: post: operationId: "api.cloudSyncRequest" @@ -743,7 +786,41 @@ components: - description - default - kind - + + CloudRegistrationRequest: + type: object + properties: + name: + type: string + minLength: 4 + maxLength: 64 + description: + type: string + minLength: 4 + maxLength: 256 + otp: + type: string + minLength: 8 + maxLength: 8 + + CloudRegistrationStatus: + type: object + properties: + name: + type: string + minLength: 1 + maxLength: 64 + description: + type: string + minLength: 0 + maxLength: 256 + org_id: + type: string + org_name: + type: string + org_description: + type: string + CloudSyncStatus: type: object properties: From 639d4b930e8adbc276e773256d8cbc45f84f14d1 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Wed, 16 Aug 2023 16:58:12 +0100 Subject: [PATCH 25/60] wip --- coderbot/api.py | 52 +++++++++++++++++--------------- coderbot/audio.py | 6 ++-- coderbot/camera.py | 30 +++++++++---------- coderbot/cloud/__init__.py | 59 +++++++++++++++++++++---------------- coderbot/cnn/cnn_manager.py | 6 ++-- coderbot/coderbot.py | 6 ++-- coderbot/main.py | 16 +++++----- coderbot/motion.py | 21 +++++++------ coderbot/music.py | 19 ++++++------ coderbot/musicPackages.py | 8 ++--- coderbot/program.py | 6 ++-- 11 files changed, 121 insertions(+), 108 deletions(-) diff --git a/coderbot/api.py b/coderbot/api.py index e1a3470b..2dc48efa 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -22,6 +22,7 @@ from runtime_test import run_test from musicPackages import MusicPackageManager from program import Program, ProgramEngine +from motion import Motion from cloud import CloudManager from balena import Balena @@ -29,18 +30,20 @@ BUTTON_PIN = 16 -config = Config.read() -bot = CoderBot.get_instance(motor_trim_factor=float(config.get('move_motor_trim', 1.0)), - motor_max_power=int(config.get('motor_max_power', 100)), - motor_min_power=int(config.get('motor_min_power', 0)), - hw_version=config.get('hardware_version'), - pid_params=(float(config.get('pid_kp', 1.0)), - float(config.get('pid_kd', 0.1)), - float(config.get('pid_ki', 0.01)), - float(config.get('pid_max_speed', 200)), - float(config.get('pid_sample_time', 0.01)))) -audio_device = Audio.get_instance() -cam = Camera.get_instance() +settings = Config.read().get("settings") +bot = CoderBot.get_instance(settings=settings, motor_trim_factor=float(settings.get('move_motor_trim', 1.0)), + motor_max_power=int(settings.get('motor_max_power', 100)), + motor_min_power=int(settings.get('motor_min_power', 0)), + hw_version=settings.get('hardware_version'), + pid_params=(float(settings.get('pid_kp', 1.0)), + float(settings.get('pid_kd', 0.1)), + float(settings.get('pid_ki', 0.01)), + float(settings.get('pid_max_speed', 200)), + float(settings.get('pid_sample_time', 0.01)))) +audio_device = Audio.get_instance(settings) +cam = Camera.get_instance(settings) +Motion.get_instance(settings) +CNNManager.get_instance(settings) def get_serial(): """ @@ -140,7 +143,7 @@ def turn(body): def takePhoto(): try: cam.photo_take() - audio_device.say(config.get("sound_shutter")) + audio_device.say(settings.get("sound_shutter")) return 200 except Exception as e: logging.warning("Error: %s", e) @@ -148,7 +151,7 @@ def takePhoto(): def recVideo(): try: cam.video_rec() - audio_device.say(config.get("sound_shutter")) + audio_device.say(settings.get("sound_shutter")) return 200 except Exception as e: logging.warning("Error: %s", e) @@ -156,7 +159,7 @@ def recVideo(): def stopVideo(): try: cam.video_stop() - audio_device.say(config.get("sound_shutter")) + audio_device.say(settings.get("sound_shutter")) return 200 except Exception as e: logging.warning("Error: %s", e) @@ -173,7 +176,7 @@ def reset(): return 200 def halt(): - audio_device.say(what=config.get("sound_stop")) + audio_device.say(what=settings.get("sound_stop")) Balena.get_instance().shutdown() return 200 @@ -181,7 +184,7 @@ def restart(): Balena.get_instance().restart() def reboot(): - audio_device.say(what=config.get("sound_stop")) + audio_device.say(what=settings.get("sound_stop")) Balena.get_instance().reboot() return 200 @@ -414,8 +417,8 @@ def cloudSyncRequest(): def cloudSyncStatus(): return CloudManager.get_instance().sync_status() -def cloudRegistrationRequest(): - CloudManager.get_instance().register() +def cloudRegistrationRequest(body): + CloudManager.get_instance().register(body) return 200 def cloudRegistrationDelete(): @@ -423,11 +426,12 @@ def cloudRegistrationDelete(): return 200 def cloudRegistrationStatus(): + registration = settings.get('cloud_registration', {}) return { "registered": CloudManager.get_instance().registration_status(), - "name": config.get('coderbot_name', ""), - "description": config.get('coderbot_description', ""), - "org_id": config.get('org_id', ""), - "org_name": config.get('org_name', ""), - "org_description": config.get('org_description', "") + "name": registration.get('name', {}), + "description": registration.get('description', ""), + "org_id": registration.get('org_id', ""), + "org_name": registration.get('org_name', ""), + "org_description": registration.get('org_description', "") } diff --git a/coderbot/audio.py b/coderbot/audio.py index ed1a469e..f67f99ff 100644 --- a/coderbot/audio.py +++ b/coderbot/audio.py @@ -46,12 +46,12 @@ class Audio: _instance = None @classmethod - def get_instance(cls): + def get_instance(cls, settings=None): if cls._instance is None: - cls._instance = Audio() + cls._instance = Audio(settings) return cls._instance - def __init__(self): + def __init__(self, settings): self.pa = pyaudio.PyAudio() try: self.stream_in = self.MicrophoneStream(FORMAT, RATE, CHUNK) diff --git a/coderbot/camera.py b/coderbot/camera.py index 8866b9fd..5247206e 100644 --- a/coderbot/camera.py +++ b/coderbot/camera.py @@ -52,30 +52,30 @@ class Camera(object): _instance = None @classmethod - def get_instance(cls): + def get_instance(cls, settings=None): if cls._instance is None: - cls._instance = Camera() + cls._instance = Camera(settings) #cls._instance.start() return cls._instance - def __init__(self): + def __init__(self, settings): logging.info("starting camera") cam_props = {"width":640, "height":512, - "cv_image_factor": config.Config.get().get("cv_image_factor"), - "exposure_mode": config.Config.get().get("camera_exposure_mode"), - "framerate": config.Config.get().get("camera_framerate"), - "bitrate": config.Config.get().get("camera_jpeg_bitrate"), - "jpeg_quality": int(config.Config.get().get("camera_jpeg_quality"))} + "cv_image_factor": settings.get("cv_image_factor"), + "exposure_mode": settings.get("camera_exposure_mode"), + "framerate": settings.get("camera_framerate"), + "bitrate": settings.get("camera_jpeg_bitrate"), + "jpeg_quality": int(settings.get("camera_jpeg_quality"))} self._camera = camera.Camera(props=cam_props) self.recording = False self.video_start_time = time.time() + 8640000 self._image_time = 0 - self._cv_image_factor = int(config.Config.get().get("cv_image_factor", 4)) - self._image_refresh_timeout = float(config.Config.get().get("camera_refresh_timeout", 0.1)) - self._color_object_size_min = int(config.Config.get().get("camera_color_object_size_min", 80)) / (self._cv_image_factor * self._cv_image_factor) - self._color_object_size_max = int(config.Config.get().get("camera_color_object_size_max", 32000)) / (self._cv_image_factor * self._cv_image_factor) - self._path_object_size_min = int(config.Config.get().get("camera_path_object_size_min", 80)) / (self._cv_image_factor * self._cv_image_factor) - self._path_object_size_max = int(config.Config.get().get("camera_path_object_size_max", 32000)) / (self._cv_image_factor * self._cv_image_factor) + self._cv_image_factor = int(settings.get("cv_image_factor", 4)) + self._image_refresh_timeout = float(settings.get("camera_refresh_timeout", 0.1)) + self._color_object_size_min = int(settings.get("camera_color_object_size_min", 80)) / (self._cv_image_factor * self._cv_image_factor) + self._color_object_size_max = int(settings.get("camera_color_object_size_max", 32000)) / (self._cv_image_factor * self._cv_image_factor) + self._path_object_size_min = int(settings.get("camera_path_object_size_min", 80)) / (self._cv_image_factor * self._cv_image_factor) + self._path_object_size_max = int(settings.get("camera_path_object_size_max", 32000)) / (self._cv_image_factor * self._cv_image_factor) self.load_photo_metadata() if not self._photos: self._photos = [] @@ -86,7 +86,7 @@ def __init__(self): self.save_photo_metadata() self._cnn_classifiers = {} - cnn_model = config.Config.get().get("cnn_default_model", "") + cnn_model = settings.get("cnn_default_model", "") if cnn_model != "": try: self._cnn_classifiers[cnn_model] = CNNManager.get_instance().load_model(cnn_model) diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index 3e5e5c96..40a600a3 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -10,6 +10,7 @@ # compare entity, if different, take most recent and push/pull changes # +import os import threading from datetime import datetime, timezone import logging @@ -80,7 +81,7 @@ def __init__(self): # Defining the host is optional and defaults to https://api.coderbot.org/api/v1 # See configuration.py for a list of all supported configuration parameters. self.configuration = cloud_api_robot_client.Configuration( - host = "http://192.168.1.7:8090/api/v1", + host = os.getenv("CODERBOT_CLOUD_API_ENDPOINT") + "/api/v1", ) try: self.read_auth() @@ -136,8 +137,9 @@ def sync(self): self._syncing = True settings = Config.read() + cloud_settings = settings.get("cloud") logging.info("run.sync.begin") - sync_modes = settings.get("sync_modes", {"settings": "n", "activities": "n", "programs": "n"}) + sync_modes = cloud_settings.get("sync_modes", {"settings": "n", "activities": "n", "programs": "n"}) token = self.get_auth().get("token") if token is not None: @@ -158,27 +160,27 @@ def sync(self): logging.info("run.sync.end") self._syncing = False - def get_token_or_register(self, settings): - logging.info("run.check.token") - token = self.get_auth().get("token") - reg_otp = settings.get("reg_otp") - try: - if token is None and reg_otp is not None: - self._sync_status["registration"] = "registering" - logging.info("run.get_token_or_register.get_token") - with cloud_api_robot_client.ApiClient(self.configuration) as api_client: - api_instance = robot_sync_api.RobotSyncApi(api_client) - body = RobotRegisterData( - otp=reg_otp, - ) - api_response = api_instance.register_robot(body=body) - logging.info(api_response.body) - token = api_response.body.get("token") - self.write_auth({"token":token}) - self._sync_status["registration"] = "registered" - return token - except cloud_api_robot_client.ApiException as e: - logging.warn("Exception when calling register_robot RobotSyncApi: %s\n" % e) + # def get_token_or_register(self, cloud_settings): + # logging.info("run.check.token") + # token = self.get_auth().get("token") + # reg_otp = cloud_settings.get("reg_otp") + # try: + # if token is None and reg_otp is not None: + # self._sync_status["registration"] = "registering" + # logging.info("run.get_token_or_register.get_token") + # with cloud_api_robßot_client.ApiClient(self.configuration) as api_client: + # api_instance = robot_sync_api.RobotSyncApi(api_client) + # body = RobotRegisterData( + # otp=reg_otp, + # ) + # api_response = api_instance.register_robot(body=body) + # logging.info(api_response.body) + # token = api_response.body.get("token") + # self.write_auth({"token":token}) + # self._sync_status["registration"] = "registered" + # return token + # except cloud_api_robot_client.ApiException as e: + # logging.warn("Exception when calling register_robot RobotSyncApi: %s\n" % e) # sync settings def sync_settings(self, api_instance, sync_mode): @@ -191,7 +193,12 @@ def sync_settings(self, api_instance, sync_mode): cloud_setting_object = api_response.body cloud_setting = json.loads(cloud_setting_object.get('data')) - local_setting = Config.read() + # sync only the "settings" and "cloud" sections, do not sync "network" + config = Config.read() + local_setting = { + "settings": config.get("settings"), + "cloud": config.get("cloud") + } local_most_recent = datetime.fromisoformat(cloud_setting_object.get("modified")).timestamp() < Config.modified() cloud_kind_user = cloud_setting_object.get("kind") == ENTITY_KIND_USER # logging.info("settings.syncing: " + cloud_setting_object.get("id", "") + " name: " + cloud_setting_object.get("name", "")) @@ -209,7 +216,9 @@ def sync_settings(self, api_instance, sync_mode): api_response = api_instance.set_robot_setting(body) logging.info("settings.upstream") elif cloud_setting != local_setting: # setting, down - Config.write(cloud_setting) + config["settings"] = cloud_setting["settings"] + config["cloud"] = cloud_setting["cloud"] + Config.write(config) logging.info("settings.downstream") self._sync_status["settings"] = "synced" except cloud_api_robot_client.ApiException as e: diff --git a/coderbot/cnn/cnn_manager.py b/coderbot/cnn/cnn_manager.py index 5ed012d2..6bd16db6 100644 --- a/coderbot/cnn/cnn_manager.py +++ b/coderbot/cnn/cnn_manager.py @@ -44,13 +44,13 @@ class CNNManager(object): instance = None @classmethod - def get_instance(cls): + def get_instance(cls, settings=None): if cls.instance is None: - cls.instance = CNNManager() + cls.instance = CNNManager(settings) return cls.instance - def __init__(self): + def __init__(self, settings): try: f = open(MODEL_METADATA, "r") self._models = json.load(f) diff --git a/coderbot/coderbot.py b/coderbot/coderbot.py index 37877506..44d4d31b 100644 --- a/coderbot/coderbot.py +++ b/coderbot/coderbot.py @@ -101,7 +101,7 @@ class CoderBot(object): # pylint: disable=too-many-instance-attributes - def __init__(self, motor_trim_factor=1.0, motor_min_power=0, motor_max_power=100, hw_version="5", pid_params=(0.8, 0.1, 0.01, 200, 0.01)): + def __init__(self, settings, motor_trim_factor=1.0, motor_min_power=0, motor_max_power=100, hw_version="5", pid_params=(0.8, 0.1, 0.01, 200, 0.01)): try: self._mpu = mpu.AccelGyroMag() logging.info("MPU available") @@ -157,9 +157,9 @@ def exit(self): s.cancel() @classmethod - def get_instance(cls, motor_trim_factor=1.0, motor_max_power=100, motor_min_power=0, hw_version="5", pid_params=(0.8, 0.1, 0.01, 200, 0.01)): + def get_instance(cls, settings=None, motor_trim_factor=1.0, motor_max_power=100, motor_min_power=0, hw_version="5", pid_params=(0.8, 0.1, 0.01, 200, 0.01)): if not cls.the_bot: - cls.the_bot = CoderBot(motor_trim_factor=motor_trim_factor, motor_max_power= motor_max_power, motor_min_power=motor_min_power, hw_version=hw_version, pid_params=pid_params) + cls.the_bot = CoderBot(settings=settings, motor_trim_factor=motor_trim_factor, motor_max_power= motor_max_power, motor_min_power=motor_min_power, hw_version=hw_version, pid_params=pid_params) return cls.the_bot def get_motor_power(self, speed): diff --git a/coderbot/main.py b/coderbot/main.py index 61bb1b24..f6b6f9b5 100644 --- a/coderbot/main.py +++ b/coderbot/main.py @@ -48,7 +48,7 @@ connexionApp.add_api('v1.yml') def button_pushed(): - if app.bot_config.get('button_func') == "startstop": + if app.settings.get('button_func') == "startstop": prog = app.prog_engine.get_current_prog() if prog and prog.is_running(): prog.end() @@ -67,14 +67,14 @@ def run_server(): cam = None try: try: - app.bot_config = Config.read() + app.settings = Config.read().get("settings") bot = CoderBot.get_instance() try: audio_device = Audio.get_instance() - audio_device.set_volume(int(app.bot_config.get('audio_volume_level')), 100) - audio_device.say(app.bot_config.get("sound_start")) + audio_device.set_volume(int(app.settings.get('audio_volume_level')), 100) + audio_device.say(app.settings.get("sound_start")) except Exception: logging.warning("Audio not present") @@ -84,17 +84,17 @@ def run_server(): except picamera.exc.PiCameraError: logging.warning("Camera not present") - CNNManager.get_instance() + CNNManager.get_instance(app.settings) EventManager.get_instance("coderbot") - if app.bot_config.get('load_at_start') and app.bot_config.get('load_at_start'): - prog = app.prog_engine.load(app.bot_config.get('load_at_start')) + if app.settings.get('load_at_start') and app.settings.get('load_at_start'): + prog = app.prog_engine.load(app.settings.get('load_at_start')) prog.execute() CloudManager.get_instance() except ValueError as e: - app.bot_config = {} + app.settings = {} logging.error(e) bot.set_callback(bot.GPIOS.PIN_PUSHBUTTON, button_pushed, 100) diff --git a/coderbot/motion.py b/coderbot/motion.py index 95d66563..8fa5c14d 100644 --- a/coderbot/motion.py +++ b/coderbot/motion.py @@ -43,9 +43,9 @@ class Motion: # pylint: disable=too-many-instance-attributes - def __init__(self): - self.bot = CoderBot.get_instance() - self.cam = Camera.get_instance() + def __init__(self, settings): + self.bot = CoderBot.get_instance(settings) + self.cam = Camera.get_instance(settings) self.track_len = 2 self.detect_interval = 5 self.tracks = [] @@ -59,20 +59,19 @@ def __init__(self): self.target_dist = 0.0 self.delta_angle = 0.0 self.target_angle = 0.0 - cfg = Config.get() - self.power_angles = [[15, (int(cfg.get("move_power_angle_1")), -1)], - [4, (int(cfg.get("move_power_angle_2")), 0.05)], - [1, (int(cfg.get("move_power_angle_3")), 0.02)], + self.power_angles = [[15, (int(settings.get("move_power_angle_1")), -1)], + [4, (int(settings.get("move_power_angle_2")), 0.05)], + [1, (int(settings.get("move_power_angle_3")), 0.02)], [0, (0, 0)]] - self.image_width = 640 / int(cfg.get("cv_image_factor")) - self.image_heigth = 480 / int(cfg.get("cv_image_factor")) + self.image_width = 640 / int(settings.get("cv_image_factor")) + self.image_heigth = 480 / int(settings.get("cv_image_factor")) self.transform = image.Image.get_transform(self.image_width) _motion = None @classmethod - def get_instance(cls): + def get_instance(cls, settings=None): if not cls._motion: - cls._motion = Motion() + cls._motion = Motion(settings) return cls._motion def move(self, dist): diff --git a/coderbot/music.py b/coderbot/music.py index 0544b468..be1ac222 100644 --- a/coderbot/music.py +++ b/coderbot/music.py @@ -29,6 +29,7 @@ import os import sox import time +import logging class Music: _instance = None @@ -42,17 +43,17 @@ class Music: @classmethod - def get_instance(cls,managerPackage): + def get_instance(cls, managerPackage, settings=None): if cls._instance is None: - cls._instance = Music(managerPackage) + cls._instance = Music(managerPackage, settings) return cls._instance - def __init__(self,managerPackage): + def __init__(self, managerPackage, settings): #os.putenv('AUDIODRIVER', 'alsa') #os.putenv('AUDIODEV', 'hw:1,0') self.managerPackage = managerPackage - print("We have create a class: MUSICAL") + logging.info("We have created a class: MUSICAL") def test(self): tfm = sox.Transformer() @@ -71,7 +72,7 @@ def play_pause(self, duration): # @para alteration: if it is a diesis or a bemolle # @param time: duration of the note in seconds def play_note(self, note, instrument='piano', alteration='none', duration=1.0): - print(note) + logging.info("play_note: %s", note) tfm = sox.Transformer() duration = float(duration) @@ -85,7 +86,7 @@ def play_note(self, note, instrument='piano', alteration='none', duration=1.0): if note in self.noteDict : shift = self.noteDict[note]+ alt else: - print('note not exist') + logging.error('note does not exist') return tfm.pitch(shift, quick=False) @@ -93,7 +94,7 @@ def play_note(self, note, instrument='piano', alteration='none', duration=1.0): if self.managerPackage.isPackageAvailable(instrument): tfm.preview('./sounds/notes/' + instrument + '/audio.wav') else: - print("no instrument:"+str(instrument)+" present in this coderbot!") + logging.error("no instrument:"+str(instrument)+" present in this coderbot!") def play_animal(self, instrument, note='G2', alteration='none', duration=1.0): tfm = sox.Transformer() @@ -138,13 +139,13 @@ def play_animal(self, instrument, note='G2', alteration='none', duration=1.0): if note in self.noteDict : shift = self.noteDict[note]+ alt else: - print('note not exist') + logging.error('note does not exist') return if self.managerPackage.isPackageAvailable(instrument): tfm.preview('./sounds/notes/' + instrument + '/audio.wav') else: - print("no animal verse:"+str(instrument)+" present in this coderbot!") + logging.error("no animal verse:"+str(instrument)+" present in this coderbot!") return tfm.pitch(shift, quick=False) tfm.trim(0.0, end_time=0.5*duration) diff --git a/coderbot/musicPackages.py b/coderbot/musicPackages.py index e671b7e7..a96c9ba3 100644 --- a/coderbot/musicPackages.py +++ b/coderbot/musicPackages.py @@ -68,7 +68,7 @@ def addInterface(self, musicPackageInterface): class MusicPackageInterface: - def __init__(self,interfaceName,available,icon): + def __init__(self, interfaceName, available,icon): self.interfaceName = interfaceName self.available = available self.icon = icon @@ -86,12 +86,12 @@ class MusicPackageManager: _instance = None @classmethod - def get_instance(cls): + def get_instance(cls, settings=None): if cls._instance is None: - cls._instance = MusicPackageManager() + cls._instance = MusicPackageManager(settings) return cls._instance - def __init__(self): + def __init__(self, settings): self.packages = dict() with open('./sounds/notes/music_package.json') as json_file: data = json.load(json_file) diff --git a/coderbot/program.py b/coderbot/program.py index a892950e..388a6da9 100644 --- a/coderbot/program.py +++ b/coderbot/program.py @@ -80,7 +80,7 @@ class ProgramEngine: _instance = None - def __init__(self): + def __init__(self, settings): self._program = None self._log = "" self._programs = TinyDB(PROGRAMS_DB) @@ -102,9 +102,9 @@ def __init__(self): self.save(program) @classmethod - def get_instance(cls): + def get_instance(cls, settings=None): if not cls._instance: - cls._instance = ProgramEngine() + cls._instance = ProgramEngine(settings) return cls._instance def prog_list(self, active_only = True): From f23d78f3e42efa8b6c5898bf53500b0dfb35580e Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Wed, 16 Aug 2023 23:38:36 +0100 Subject: [PATCH 26/60] wip --- coderbot/api.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/coderbot/api.py b/coderbot/api.py index 2dc48efa..17e4e9cb 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -31,6 +31,9 @@ BUTTON_PIN = 16 settings = Config.read().get("settings") +network_settings = Config.read().get("network") +cloud_settings = Config.read().get("cloud") + bot = CoderBot.get_instance(settings=settings, motor_trim_factor=float(settings.get('move_motor_trim', 1.0)), motor_max_power=int(settings.get('motor_max_power', 100)), motor_min_power=int(settings.get('motor_min_power', 0)), @@ -426,10 +429,10 @@ def cloudRegistrationDelete(): return 200 def cloudRegistrationStatus(): - registration = settings.get('cloud_registration', {}) + registration = cloud_settings.get('registration', {}) return { "registered": CloudManager.get_instance().registration_status(), - "name": registration.get('name', {}), + "name": registration.get('name', ""), "description": registration.get('description', ""), "org_id": registration.get('org_id', ""), "org_name": registration.get('org_name', ""), From 1ba04562693a3e9a6ad3e05eaedf117f9e45ea37 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 14:12:24 +0100 Subject: [PATCH 27/60] update default config.json --- defaults/config.json | 118 ++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/defaults/config.json b/defaults/config.json index ab8459d0..518c66fc 100644 --- a/defaults/config.json +++ b/defaults/config.json @@ -1,60 +1,62 @@ { - "move_power_angle_3":"60", - "cnn_default_model":"generic_fast_low", - "prog_maxblocks":"-1", - "camera_jpeg_quality":"5", - "show_page_control":"true", - "camera_framerate":"30", - "prog_scrollbars":"true", - "move_fw_speed":"100", - "motor_min_power":"0", - "motor_max_power":"100", - "prog_level":"adv", - "move_motor_trim":"1", - "cv_image_factor":"2", - "move_power_angle_1":"45", - "camera_path_object_size_min":"4000", - "button_func":"none", - "camera_color_object_size_min":"4000", - "camera_jpeg_bitrate":"1000000", - "move_fw_elapse":"1", - "show_control_move_commands":"true", - "camera_color_object_size_max":"160000", - "show_page_prefs":"true", - "camera_exposure_mode":"auto", - "ctrl_tr_elapse":"-1", - "show_page_program":"true", - "move_tr_elapse":"0.5", - "camera_path_object_size_max":"160000", - "sound_shutter":"$shutter", - "ctrl_fw_elapse":"-1", - "sound_stop":"$shutdown", - "ctrl_tr_speed":"80", - "ctrl_fw_speed":"100", - "move_tr_speed":"85", - "move_power_angle_2":"60", - "ctrl_hud_image":"", - "load_at_start":"", - "sound_start":"$startup", - "hardware_version":"5", - "audio_volume_level":"100", - "wifi_mode":"ap", - "wifi_ssid":"coderbot", - "wifi_psk":"coderbot", - "packages_installed":"", - "admin_password":"", - "pid_kp":"8.0", - "pid_kd":"0.0", - "pid_ki":"0.0", - "pid_max_speed":"200", - "pid_sample_time":"0.05", - "movement_use_mpu": "false", - "movement_use_motion": "false", - "movement_use_encoder": "true", - "sync_modes": { - "activities":"b", - "programs":"b", - "settings":"b" + "settings":{ + "ctrl_hud_image":"", + "cv_image_factor":"2", + "camera_color_object_size_max":"160000", + "camera_color_object_size_min":"4000", + "camera_exposure_mode":"auto", + "camera_framerate":"30", + "camera_jpeg_bitrate":"1000000", + "camera_jpeg_quality":"5", + "camera_path_object_size_max":"160000", + "camera_path_object_size_min":"4000", + "cnn_default_model":"generic_fast_low", + "move_power_angle_1":"45", + "move_power_angle_2":"60", + "move_power_angle_3":"60", + "button_func":"none", + "move_motor_trim":"1", + "motor_min_power":"0", + "motor_max_power":"100", + "sound_start":"$startup", + "sound_stop":"$shutdown", + "sound_shutter":"$shutter", + "load_at_start":"", + "prog_level":"adv", + "move_fw_elapse":"1", + "move_fw_speed":"100", + "move_tr_elapse":"0.5", + "move_tr_speed":"85", + "pid_kp":"8.0", + "pid_kd":"0.0", + "pid_ki":"0.0", + "pid_max_speed":"200", + "pid_sample_time":"0.05", + "ctrl_fw_elapse":"-1", + "ctrl_fw_speed":"100", + "ctrl_tr_elapse":"-1", + "ctrl_tr_speed":"80", + "audio_volume_level":"100", + "admin_password":"", + "hardware_version":"5", + "prog_scrollbars":"true", + "movement_use_mpu":"false", + "movement_use_motion":"false", + "movement_use_encoder":"true", + "locale":"browser" }, - "sync_period":"60" -} + "network":{ + "wifi_mode":"ap", + "wifi_ssid":"coderbot", + "wifi_psk":"coderbot" + }, + "cloud":{ + "sync_modes":{ + "activities":"b", + "programs":"b", + "settings":"b" + }, + "sync_period":"10", + "reg_otp":"AB1234CD" + } +} \ No newline at end of file From bd2ee94fd9ef5ed70889ebef133adf4556855c79 Mon Sep 17 00:00:00 2001 From: Roberto <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 16:26:03 +0200 Subject: [PATCH 28/60] increase initial delay for testing --- .github/workflows/build_backend.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index 189d0835..ca2364e8 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -26,7 +26,7 @@ jobs: - run: | export PYTHONPATH=./stub:./coderbot:./test python3 coderbot/main.py > coderbot.log & - sleep 60 + sleep 120 apt-get install -y python3-venv mkdir -p schemathesis python3 -m venv schemathesis From f1817f8dfa8a7370e7a7e6c034d52a50f03ef0d5 Mon Sep 17 00:00:00 2001 From: Roberto <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 16:41:53 +0200 Subject: [PATCH 29/60] debug test api --- .github/workflows/build_backend.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index ca2364e8..95b15017 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -26,18 +26,20 @@ jobs: - run: | export PYTHONPATH=./stub:./coderbot:./test python3 coderbot/main.py > coderbot.log & - sleep 120 + sleep 60 + cat coderbot.log + curl http://localhost:5000/api/v1/openapi.json apt-get install -y python3-venv mkdir -p schemathesis python3 -m venv schemathesis . schemathesis/bin/activate pip install schemathesis - st run --endpoint 'activities' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json + #st run --endpoint 'activities' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json #st run --endpoint 'media' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json - st run --endpoint 'control/speak' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json - st run --endpoint 'control/stop' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json - st run --endpoint 'music' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json - st run --endpoint 'programs' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json + #st run --endpoint 'control/speak' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json + #st run --endpoint 'control/stop' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json + #st run --endpoint 'music' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json + #st run --endpoint 'programs' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json echo "openapi test complete" release-backend: From 16ffbadc87f05a79d88ad2a32e2a9010e7cfc101 Mon Sep 17 00:00:00 2001 From: Roberto <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 16:45:47 +0200 Subject: [PATCH 30/60] debug tests --- .github/workflows/build_backend.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index 95b15017..b69d2109 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -25,6 +25,7 @@ jobs: echo "test complete" - run: | export PYTHONPATH=./stub:./coderbot:./test + export CODERBOT_CLOUD_API_ENDPOINT=http://localhost:5000 python3 coderbot/main.py > coderbot.log & sleep 60 cat coderbot.log @@ -34,7 +35,7 @@ jobs: python3 -m venv schemathesis . schemathesis/bin/activate pip install schemathesis - #st run --endpoint 'activities' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json + st run --endpoint 'activities' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json #st run --endpoint 'media' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json #st run --endpoint 'control/speak' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json #st run --endpoint 'control/stop' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json From b49c58d3102170b9f0bf317ece22f15717a692f4 Mon Sep 17 00:00:00 2001 From: Roberto <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 16:50:04 +0200 Subject: [PATCH 31/60] debug tests --- .github/workflows/build_backend.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index b69d2109..41ea5341 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -37,10 +37,10 @@ jobs: pip install schemathesis st run --endpoint 'activities' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json #st run --endpoint 'media' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json - #st run --endpoint 'control/speak' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json - #st run --endpoint 'control/stop' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json - #st run --endpoint 'music' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json - #st run --endpoint 'programs' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json + st run --endpoint 'control/speak' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json + st run --endpoint 'control/stop' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json + st run --endpoint 'music' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json + st run --endpoint 'programs' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json echo "openapi test complete" release-backend: From 24ef531e7dd322b502f7cc0130d214c23dfc590c Mon Sep 17 00:00:00 2001 From: Roberto <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 16:51:42 +0200 Subject: [PATCH 32/60] Update camera_test.py - fix tests --- test/camera_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/camera_test.py b/test/camera_test.py index 523f2c4b..90fa07d4 100755 --- a/test/camera_test.py +++ b/test/camera_test.py @@ -10,7 +10,7 @@ class CameraTest(unittest.TestCase): def setUp(self): config.Config.read() picamera.PiCamera = picamera_mock.PiCameraMock - self.cam = camera.Camera.get_instance() + self.cam = camera.Camera.get_instance(config.get('settings')) def tearDown(self): self.cam.exit() From 52f5dd1e73709f3bc1230a228cb90065c452ec53 Mon Sep 17 00:00:00 2001 From: Roberto <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 16:56:05 +0200 Subject: [PATCH 33/60] Update coderbot_test.py - fix --- test/coderbot_test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/coderbot_test.py b/test/coderbot_test.py index dbbd6ee0..e655e34c 100755 --- a/test/coderbot_test.py +++ b/test/coderbot_test.py @@ -1,6 +1,7 @@ import unittest import test.pigpio_mock import coderbot +import config import logging logger = logging.getLogger() @@ -17,7 +18,8 @@ class CoderBotDCMotorTestCase(unittest.TestCase): def setUp(self): coderbot.pigpio.pi = test.pigpio_mock.PIGPIOMock coderbot.CoderBot._instance = None - self.bot = coderbot.CoderBot.get_instance() + settings = config.Config.read().get('settings') + self.bot = coderbot.CoderBot.get_instance(settings) def test_motor_forward(self): self.bot.forward(speed=100, elapse=0.1) From f65bc87c7302c51d3dbf6cdd26a6faed07923307 Mon Sep 17 00:00:00 2001 From: Roberto <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 16:56:27 +0200 Subject: [PATCH 34/60] Update camera_test.py fix --- test/camera_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/camera_test.py b/test/camera_test.py index 90fa07d4..b074aff4 100755 --- a/test/camera_test.py +++ b/test/camera_test.py @@ -8,9 +8,9 @@ class CameraTest(unittest.TestCase): def setUp(self): - config.Config.read() + settings = config.Config.read().get('settings') picamera.PiCamera = picamera_mock.PiCameraMock - self.cam = camera.Camera.get_instance(config.get('settings')) + self.cam = camera.Camera.get_instance(settings) def tearDown(self): self.cam.exit() From 7c13bb3e5a6af97c830bbef0d6209233f0aa850f Mon Sep 17 00:00:00 2001 From: Roberto <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 17:04:05 +0200 Subject: [PATCH 35/60] Update coderbot_test.py fix --- test/coderbot_test.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/coderbot_test.py b/test/coderbot_test.py index e655e34c..04285b93 100755 --- a/test/coderbot_test.py +++ b/test/coderbot_test.py @@ -45,7 +45,8 @@ class CoderBotServoMotorTestCase(unittest.TestCase): def setUp(self): coderbot.pigpio.pi = test.pigpio_mock.PIGPIOMock coderbot.CoderBot._instance = None - self.bot = coderbot.CoderBot.get_instance(servo=True) + settings = config.Config.read().get('settings') + self.bot = coderbot.CoderBot.get_instance(settings, Servo=True) def test_motor_forward(self): self.bot.forward(speed=100, elapse=0.1) @@ -72,7 +73,8 @@ class CoderBotSonarTestCase(unittest.TestCase): def setUp(self): coderbot.pigpio.pi = test.pigpio_mock.PIGPIOMock coderbot.CoderBot._instance = None - self.bot = coderbot.CoderBot.get_instance() + settings = config.Config.read().get('settings') + self.bot = coderbot.CoderBot.get_instance(settings) def test_sonar(self): for i in range(0, 3): From 7070b18622e21bf3395c887ed9187b6f3b318cd9 Mon Sep 17 00:00:00 2001 From: Roberto <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 17:08:00 +0200 Subject: [PATCH 36/60] Update coderbot_test.py -fix --- test/coderbot_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/coderbot_test.py b/test/coderbot_test.py index 04285b93..69562831 100755 --- a/test/coderbot_test.py +++ b/test/coderbot_test.py @@ -46,7 +46,7 @@ def setUp(self): coderbot.pigpio.pi = test.pigpio_mock.PIGPIOMock coderbot.CoderBot._instance = None settings = config.Config.read().get('settings') - self.bot = coderbot.CoderBot.get_instance(settings, Servo=True) + self.bot = coderbot.CoderBot.get_instance(settings, servo=True) def test_motor_forward(self): self.bot.forward(speed=100, elapse=0.1) From 14f6478c2e350cef0c494df406ca9bd4748ca4b6 Mon Sep 17 00:00:00 2001 From: Roberto <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 17:23:04 +0200 Subject: [PATCH 37/60] Update coderbot_test.py fix servo test --- test/coderbot_test.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/test/coderbot_test.py b/test/coderbot_test.py index 69562831..d8a651f2 100755 --- a/test/coderbot_test.py +++ b/test/coderbot_test.py @@ -46,27 +46,25 @@ def setUp(self): coderbot.pigpio.pi = test.pigpio_mock.PIGPIOMock coderbot.CoderBot._instance = None settings = config.Config.read().get('settings') - self.bot = coderbot.CoderBot.get_instance(settings, servo=True) + self.bot = coderbot.CoderBot.get_instance(settings) - def test_motor_forward(self): - self.bot.forward(speed=100, elapse=0.1) + def servo_0_0(self): + self.bot.forward(servo=0, angle=0) - def test_motor_backward(self): - self.bot.backward(speed=100, elapse=0.1) + def servo_0_90(self): + self.bot.forward(servo=0, angle=90) - def test_motor_left(self): - self.bot.left(speed=100, elapse=0.1) + def servo_0_180(self): + self.bot.forward(servo=0, angle=180) - def test_motor_right(self): - self.bot.left(speed=100, elapse=0.1) + def servo_1_0(self): + self.bot.forward(servo=1, angle=0) - def test_motor_move(self): - self.bot.move(speed=100, elapse=0.1) - self.bot.move(speed=-100, elapse=0.1) + def servo_1_90(self): + self.bot.forward(servo=1, angle=90) - def test_motor_turn(self): - self.bot.turn(speed=100, elapse=0.1) - self.bot.turn(speed=-100, elapse=0.1) + def servo_1_180(self): + self.bot.forward(servo=1, angle=180) class CoderBotSonarTestCase(unittest.TestCase): From 164da91ce1f485a7038b4d9a4ac62355b427e747 Mon Sep 17 00:00:00 2001 From: Roberto <roberto.previtera@gmail.com> Date: Sat, 19 Aug 2023 17:28:54 +0200 Subject: [PATCH 38/60] Update Dockerfile stub add CODERBOT_CLOUD_API_ENDPOINT --- docker/stub/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/stub/Dockerfile b/docker/stub/Dockerfile index 43180a2a..2cd2fd2d 100644 --- a/docker/stub/Dockerfile +++ b/docker/stub/Dockerfile @@ -62,5 +62,6 @@ ADD docker/stub/start.sh /coderbot/. ARG CODERBOT_VERSION ENV CODERBOT_VERSION=${CODERBOT_VERSION} +ENV CODERBOT_CLOUD_API_ENDPOINT=http://localhost:5000 ENTRYPOINT /coderbot/start.sh From 45e0bcebc41751e1a0f185fd85518d1f461adfd4 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 27 Aug 2023 00:48:36 +0100 Subject: [PATCH 39/60] fixes --- coderbot/activity.py | 2 +- coderbot/api.py | 2 +- coderbot/program.py | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index b44bd777..0477447b 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -69,4 +69,4 @@ def delete(self, name, logical = True): def list(self, active_only = True): with self.lock: - return self.activities.all() + return self.activities.search(self.query.status == ACTIVITY_STATUS_ACTIVE) diff --git a/coderbot/api.py b/coderbot/api.py index 17e4e9cb..0f377c64 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -301,7 +301,7 @@ def saveProgram(name, body): logging.info("saving - name: %s, body: %s", name, str(existing_program)) if existing_program is not None and not overwrite: return "askOverwrite" - elif existing_program is not None and existing_program.is_default() == True: + elif existing_program is not None and existing_program.is_stock() == True: return "defaultCannotOverwrite", 400 program = Program(name=body.get("name"), code=body.get("code"), dom_code=body.get("dom_code"), modified=datetime.now(), status="active") prog_engine.save(program) diff --git a/coderbot/program.py b/coderbot/program.py index 388a6da9..76dd7900 100644 --- a/coderbot/program.py +++ b/coderbot/program.py @@ -127,10 +127,14 @@ def save(self, program): else: self._programs.insert(program_db_entry) - def load(self, name): + def load(self, name, active_only=True): with self.lock: query = Query() - program_db_entries = self._programs.search(query.name == name) + program_db_entries = None + if active_only: + program_db_entries = self._programs.search((query.name == name) & (query.status == PROGRAM_STATUS_ACTIVE)) + else: + program_db_entries = self._programs.search(query.name == name) if len(program_db_entries) > 0: prog_db_entry = program_db_entries[0] #logging.debug(prog_db_entry) From 8198e097068aed7e2c0a2a5b451c43f93dadd6b6 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 27 Aug 2023 11:51:43 +0100 Subject: [PATCH 40/60] fix --- coderbot/activity.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index 0477447b..5e92a830 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -1,3 +1,4 @@ +import logging from tinydb import TinyDB, Query from threading import Lock from datetime import datetime @@ -29,11 +30,16 @@ def __init__(self): self.activities = TinyDB("data/activities.json") self.query = Query() self.lock = Lock() + self.permanentlyRemoveDeletedActivities() - def load(self, name, default): + def load(self, name, default, active_only=True): with self.lock: if name and default is None: - activities = self.activities.search(self.query.name == name) + activities = [] + if active_only: + self.activities.search((self.query.name == name) & (self.query.status == ACTIVITY_STATUS_ACTIVE)) + else: + self.activities.search(self.query.name == name) if len(activities) > 0: return activities[0] elif default is not None: @@ -66,7 +72,16 @@ def delete(self, name, logical = True): else: self.activities.remove(self.query.name == activity["name"]) + def permanentlyRemoveDeletedActivities(self): + for a in self.list(active_only=False): + logging.info("checking: " + a["name"]) + if a["status"] == ACTIVITY_STATUS_DELETED: + logging.info("deleting: " + a["name"]) + self.delete(a["name"], logical=False) def list(self, active_only = True): with self.lock: - return self.activities.search(self.query.status == ACTIVITY_STATUS_ACTIVE) + if active_only: + return self.activities.search(self.query.status == ACTIVITY_STATUS_ACTIVE) + else: + return self.activities.all() From bfaa25874225a290cbf67bc851ed08477fd61e5d Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 27 Aug 2023 17:33:58 +0100 Subject: [PATCH 41/60] fix --- coderbot/activity.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index 5e92a830..68b30d8b 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -37,9 +37,9 @@ def load(self, name, default, active_only=True): if name and default is None: activities = [] if active_only: - self.activities.search((self.query.name == name) & (self.query.status == ACTIVITY_STATUS_ACTIVE)) + activities = self.activities.search((self.query.name == name) & (self.query.status == ACTIVITY_STATUS_ACTIVE)) else: - self.activities.search(self.query.name == name) + activities = self.activities.search(self.query.name == name) if len(activities) > 0: return activities[0] elif default is not None: @@ -51,26 +51,26 @@ def load(self, name, default, active_only=True): def save(self, name, activity): with self.lock: # if saved activity is "default", reset existing default activity to "non-default" - if activity.get("default", False) is True: + if self.query.get("default", False) is True: self.activities.update({'default': False}) if self.activities.search(self.query.name == name) == []: self.activities.insert(activity) else: - self.activities.update(activity, self.query.name == activity["name"]) + self.activities.update(activity, self.query.name == self.query._name) def delete(self, name, logical = True): with self.lock: activities = self.activities.search(self.query.name == name) if len(activities) > 0: activity = activities[0] - if activity.get("default", False) is True: + if self.query.get("default", False) is True: self.activities.update({'default': True}, self.query.stock == True) if logical: - activity["status"] = ACTIVITY_STATUS_DELETED + self.query._status = ACTIVITY_STATUS_DELETED activity["modified"] = datetime.now().isoformat() - self.activities.update(activity, self.query.name == name) + self.activities.update(activity, self.self.query.name == name) else: - self.activities.remove(self.query.name == activity["name"]) + self.activities.remove(self.query.name == self.query._name) def permanentlyRemoveDeletedActivities(self): for a in self.list(active_only=False): From 6969fea8c4c3578d40022c3842044843a2231c59 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 27 Aug 2023 17:44:37 +0100 Subject: [PATCH 42/60] fix --- coderbot/activity.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index 68b30d8b..1c48b3e7 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -56,7 +56,7 @@ def save(self, name, activity): if self.activities.search(self.query.name == name) == []: self.activities.insert(activity) else: - self.activities.update(activity, self.query.name == self.query._name) + self.activities.update(activity, self.query.name == name) def delete(self, name, logical = True): with self.lock: @@ -70,7 +70,7 @@ def delete(self, name, logical = True): activity["modified"] = datetime.now().isoformat() self.activities.update(activity, self.self.query.name == name) else: - self.activities.remove(self.query.name == self.query._name) + self.activities.remove(self.query.name == name) def permanentlyRemoveDeletedActivities(self): for a in self.list(active_only=False): From f63918411dbbab2655aeeb7e67ea3689f10e804d Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 27 Aug 2023 17:55:33 +0100 Subject: [PATCH 43/60] fix --- coderbot/activity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index 1c48b3e7..3935566c 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -51,7 +51,7 @@ def load(self, name, default, active_only=True): def save(self, name, activity): with self.lock: # if saved activity is "default", reset existing default activity to "non-default" - if self.query.get("default", False) is True: + if activity.get("default", False) is True: self.activities.update({'default': False}) if self.activities.search(self.query.name == name) == []: self.activities.insert(activity) From 24dde58a51f5b99c5d9c080eef814ab2617ada72 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 27 Aug 2023 19:07:46 +0100 Subject: [PATCH 44/60] fix --- coderbot/activity.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index 3935566c..b0906e12 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -63,12 +63,12 @@ def delete(self, name, logical = True): activities = self.activities.search(self.query.name == name) if len(activities) > 0: activity = activities[0] - if self.query.get("default", False) is True: + if activity.get("default", False) is True: self.activities.update({'default': True}, self.query.stock == True) if logical: - self.query._status = ACTIVITY_STATUS_DELETED + activity["status"] = ACTIVITY_STATUS_DELETED activity["modified"] = datetime.now().isoformat() - self.activities.update(activity, self.self.query.name == name) + self.activities.update(activity, self.query.name == name) else: self.activities.remove(self.query.name == name) From f50165b60feea193ded918a31870b1c872564017 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sat, 23 Dec 2023 17:33:25 +0000 Subject: [PATCH 45/60] wip --- coderbot/activity.py | 2 +- coderbot/api.py | 48 ++++++++++++++++++++++---------------------- coderbot/main.py | 2 +- coderbot/v1.yml | 4 ++++ 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index b0906e12..18f24c3c 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -64,7 +64,7 @@ def delete(self, name, logical = True): if len(activities) > 0: activity = activities[0] if activity.get("default", False) is True: - self.activities.update({'default': True}, self.query.stock == True) + self.activities.update({'default': True}, self.query.kind == ACTIVITY_KIND_STOCK) if logical: activity["status"] = ACTIVITY_STATUS_DELETED activity["modified"] = datetime.now().isoformat() diff --git a/coderbot/api.py b/coderbot/api.py index 0f377c64..91b73624 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -123,31 +123,31 @@ def get_info(): def stop(): bot.stop() - return 200 + return {} def move(body): speed=body.get("speed") elapse=body.get("elapse") distance=body.get("distance") if (speed is None or speed == 0) or (elapse is not None and distance is not None): - return 400 + return None, 400 bot.move(speed=speed, elapse=elapse, distance=distance) - return 200 + return {} def turn(body): speed=body.get("speed") elapse=body.get("elapse") distance=body.get("distance") if (speed is None or speed == 0) or (elapse is not None and distance is not None): - return 400 + return None, 400 bot.turn(speed=speed, elapse=elapse, distance=distance) - return 200 + return {} def takePhoto(): try: cam.photo_take() audio_device.say(settings.get("sound_shutter")) - return 200 + return {} except Exception as e: logging.warning("Error: %s", e) @@ -155,7 +155,7 @@ def recVideo(): try: cam.video_rec() audio_device.say(settings.get("sound_shutter")) - return 200 + return {} except Exception as e: logging.warning("Error: %s", e) @@ -163,7 +163,7 @@ def stopVideo(): try: cam.video_stop() audio_device.say(settings.get("sound_shutter")) - return 200 + return {} except Exception as e: logging.warning("Error: %s", e) @@ -172,16 +172,16 @@ def speak(body): locale = body.get("locale", "") logging.debug("say: " + text + " in: " + locale) audio_device.say(text, locale) - return 200 + return {} def reset(): Balena.get_instance().purge() - return 200 + return {} def halt(): audio_device.say(what=settings.get("sound_stop")) Balena.get_instance().shutdown() - return 200 + return {} def restart(): Balena.get_instance().restart() @@ -189,7 +189,7 @@ def restart(): def reboot(): audio_device.say(what=settings.get("sound_stop")) Balena.get_instance().reboot() - return 200 + return {} def video_stream(a_cam): while True: @@ -223,22 +223,22 @@ def getPhoto(name): return send_file(media_file, mimetype=mimetype.get(name[:-3], 'image/jpeg'), max_age=0) except picamera.exc.PiCameraError as e: logging.error("Error: %s", str(e)) - return 503 + return {"exception": str(e)}, 503 except FileNotFoundError: - return 404 + return None, 404 def savePhoto(name, body): try: cam.update_photo({"name": name, "tag": body.get("tag")}) except FileNotFoundError: - return 404 + return None, 404 def deletePhoto(name): logging.debug("photo delete") try: cam.delete_photo(name) except FileNotFoundError: - return 404 + return None, 404 def restoreSettings(): Config.restore() @@ -249,14 +249,14 @@ def loadSettings(): def saveSettings(body): Config.write(body) - return 200 + return Config.write(body) 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 + return {} def listMusicPackages(): """ @@ -291,7 +291,7 @@ def deleteMusicPackage(name): """ musicPkg = MusicPackageManager.get_instance() musicPkg.deletePackage(name) - return 200 + return {} ## Programs @@ -305,14 +305,14 @@ def saveProgram(name, body): return "defaultCannotOverwrite", 400 program = Program(name=body.get("name"), code=body.get("code"), dom_code=body.get("dom_code"), modified=datetime.now(), status="active") prog_engine.save(program) - return 200 + return {} def loadProgram(name): existing_program = prog_engine.load(name) if existing_program: return existing_program.as_dict(), 200 else: - return 404 + return None, 404 def deleteProgram(name): prog_engine.delete(name, logical=True) @@ -415,18 +415,18 @@ def deleteCNNModel(name): def cloudSyncRequest(): CloudManager.get_instance().sync() - return 200 + return {} def cloudSyncStatus(): return CloudManager.get_instance().sync_status() def cloudRegistrationRequest(body): CloudManager.get_instance().register(body) - return 200 + return {} def cloudRegistrationDelete(): CloudManager.get_instance().unregister() - return 200 + return {} def cloudRegistrationStatus(): registration = cloud_settings.get('registration', {}) diff --git a/coderbot/main.py b/coderbot/main.py index f6b6f9b5..43b85144 100644 --- a/coderbot/main.py +++ b/coderbot/main.py @@ -32,7 +32,7 @@ # Serve a custom version of the swagger ui (Jinja2 templates) based on the default one # from the folder 'swagger-ui'. Clone the 'swagger-ui' repository inside the backend folder -options = {"swagger_ui": False} +options = {"swagger_ui": True} connexionApp = connexion.App(__name__, options=options) # Connexion wraps FlaskApp, so app becomes connexionApp.app diff --git a/coderbot/v1.yml b/coderbot/v1.yml index 8539dbb5..8bb36c5e 100644 --- a/coderbot/v1.yml +++ b/coderbot/v1.yml @@ -30,6 +30,10 @@ paths: responses: 200: description: "ok" + content: + application/json: + schema: + $ref: '#/components/schemas/Settings' tags: - CoderBot configuration /settings/restore: From 4967d4d734bb93c55e6fabff0106957f3b795ab3 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 24 Dec 2023 10:14:16 +0000 Subject: [PATCH 46/60] bumo deps --- coderbot/api.py | 18 ------------- coderbot/main.py | 69 ++++++++++++++++++++++++++---------------------- requirements.txt | 27 +++++++++---------- 3 files changed, 50 insertions(+), 64 deletions(-) diff --git a/coderbot/api.py b/coderbot/api.py index 91b73624..f41723fe 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -30,24 +30,6 @@ BUTTON_PIN = 16 -settings = Config.read().get("settings") -network_settings = Config.read().get("network") -cloud_settings = Config.read().get("cloud") - -bot = CoderBot.get_instance(settings=settings, motor_trim_factor=float(settings.get('move_motor_trim', 1.0)), - motor_max_power=int(settings.get('motor_max_power', 100)), - motor_min_power=int(settings.get('motor_min_power', 0)), - hw_version=settings.get('hardware_version'), - pid_params=(float(settings.get('pid_kp', 1.0)), - float(settings.get('pid_kd', 0.1)), - float(settings.get('pid_ki', 0.01)), - float(settings.get('pid_max_speed', 200)), - float(settings.get('pid_sample_time', 0.01)))) -audio_device = Audio.get_instance(settings) -cam = Camera.get_instance(settings) -Motion.get_instance(settings) -CNNManager.get_instance(settings) - def get_serial(): """ Extract serial from cpuinfo file diff --git a/coderbot/main.py b/coderbot/main.py index 43b85144..681f18c4 100644 --- a/coderbot/main.py +++ b/coderbot/main.py @@ -7,8 +7,9 @@ import logging.handlers import picamera import connexion - -from flask_cors import CORS +from connexion.options import SwaggerUIOptions +from connexion.middleware import MiddlewarePosition +from starlette.middleware.cors import CORSMiddleware from camera import Camera from motion import Motion @@ -23,29 +24,26 @@ # Logging configuration logger = logging.getLogger() logger.setLevel(os.environ.get("LOGLEVEL", "INFO")) -# sh = logging.StreamHandler() -# formatter = logging.Formatter('%(message)s') -# sh.setFormatter(formatter) -# logger.addHandler(sh) ## (Connexion) Flask app configuration - # Serve a custom version of the swagger ui (Jinja2 templates) based on the default one # from the folder 'swagger-ui'. Clone the 'swagger-ui' repository inside the backend folder -options = {"swagger_ui": True} -connexionApp = connexion.App(__name__, options=options) - -# Connexion wraps FlaskApp, so app becomes connexionApp.app -app = connexionApp.app -# Access-Control-Allow-Origin -CORS(app) -app.debug = False +swagger_ui_options = SwaggerUIOptions(swagger_ui=True) +app = connexion.App(__name__, swagger_ui_options=swagger_ui_options) +app.add_middleware( + CORSMiddleware, + position=MiddlewarePosition.BEFORE_EXCEPTION, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) app.prog_engine = ProgramEngine.get_instance() ## New API and web application # API v1 is defined in v1.yml and its methods are in api.py -connexionApp.add_api('v1.yml') +app.add_api('v1.yml') def button_pushed(): if app.settings.get('button_func') == "startstop": @@ -67,41 +65,50 @@ def run_server(): cam = None try: try: - app.settings = Config.read().get("settings") - - bot = CoderBot.get_instance() - + settings = Config.read().get("settings") + app.settings = settings + network_settings = Config.read().get("network") + cloud_settings = Config.read().get("cloud") + + bot = CoderBot.get_instance(settings=settings, motor_trim_factor=float(settings.get('move_motor_trim', 1.0)), + motor_max_power=int(settings.get('motor_max_power', 100)), + motor_min_power=int(settings.get('motor_min_power', 0)), + hw_version=settings.get('hardware_version'), + pid_params=(float(settings.get('pid_kp', 1.0)), + float(settings.get('pid_kd', 0.1)), + float(settings.get('pid_ki', 0.01)), + float(settings.get('pid_max_speed', 200)), + float(settings.get('pid_sample_time', 0.01)))) try: - audio_device = Audio.get_instance() - audio_device.set_volume(int(app.settings.get('audio_volume_level')), 100) - audio_device.say(app.settings.get("sound_start")) + audio_device = Audio.get_instance(settings) + audio_device.set_volume(int(settings.get('audio_volume_level')), 100) + audio_device.say(settings.get("sound_start")) except Exception: logging.warning("Audio not present") - try: - cam = Camera.get_instance() - Motion.get_instance() + cam = Camera.get_instance(settings) + Motion.get_instance(settings) except picamera.exc.PiCameraError: logging.warning("Camera not present") - CNNManager.get_instance(app.settings) + CNNManager.get_instance(settings) EventManager.get_instance("coderbot") - if app.settings.get('load_at_start') and app.settings.get('load_at_start'): - prog = app.prog_engine.load(app.settings.get('load_at_start')) + if settings.get('load_at_start') and settings.get('load_at_start'): + prog = app.prog_engine.load(settings.get('load_at_start')) prog.execute() CloudManager.get_instance() except ValueError as e: - app.settings = {} + settings = {} logging.error(e) bot.set_callback(bot.GPIOS.PIN_PUSHBUTTON, button_pushed, 100) remove_doreset_file() - app.run(host="0.0.0.0", port=5000, debug=False, use_reloader=False, threaded=True) + app.run(host="0.0.0.0", port=5000) finally: if cam: cam.exit() diff --git a/requirements.txt b/requirements.txt index 6734cd58..6f8eae55 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,32 +1,29 @@ # API framework -connexion==2.14.2 -Flask==2.2.3 -Flask-Cors==3.0.10 -tinydb==4.7.1 -Werkzeug==2.2.3 +connexion[uvicorn,swagger-ui]==3.0.5 +tinydb==4.8.0 cloud_api_robot_client @ git+https://github.com/CoderBotOrg/cloud_api_robot_client.git # Misc utils -setuptools==67.4.0 +setuptools==69.0.3 event-channel==0.4.3 # IO extensions pigpio==1.78 -smbus2==0.4.2 -spidev==3.5 +smbus2==0.4.3 +spidev==3.6 # Audio sox==1.4.1 -PyAudio==0.2.12 -pyalsaaudio==0.9.2 +PyAudio==0.2.14 +pyalsaaudio==0.10.0 # Computer Vision -grpcio==1.48.1 -numpy==1.24.2 -Pillow==9.4.0 -protobuf==4.22.0 +grpcio==1.60.0 +numpy==1.24.3 +Pillow==10.1.0 +protobuf==4.25.1 opencv-contrib-python==4.5.5.62 -tflite-runtime==2.11.0 +tflite-runtime==2.12.0 pytesseract==0.3.10 picamera==1.13 pyzbar==0.1.9 From ffcb801f86890784b473daf70f96a8c25d78e39d Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 24 Dec 2023 10:21:11 +0000 Subject: [PATCH 47/60] bump deps --- docker/stub/requirements.txt | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/docker/stub/requirements.txt b/docker/stub/requirements.txt index a758a746..7913b788 100644 --- a/docker/stub/requirements.txt +++ b/docker/stub/requirements.txt @@ -1,27 +1,24 @@ # API framework -connexion==2.14.2 -Flask==2.2.3 -Flask-Cors==3.0.10 -tinydb==4.7.1 -Werkzeug==2.2.3 +connexion[uvicorn,swagger-ui]==3.0.5 +tinydb==4.8.0 cloud_api_robot_client @ git+https://github.com/CoderBotOrg/cloud_api_robot_client.git # Misc utils -setuptools==67.4.0 +setuptools==69.0.3 event-channel==0.4.3 # IO extensions -spidev==3.5 +spidev==3.6 # Audio sox==1.4.1 # Computer Vision -grpcio==1.48.1 -numpy==1.24.2 -Pillow==9.4.0 -protobuf==4.22.0 +grpcio==1.60.0 +numpy==1.24.3 +Pillow==10.1.0 +protobuf==4.25.1 opencv-contrib-python==4.5.5.62 -tflite-runtime==2.11.0 +tflite-runtime==2.12.0 pytesseract==0.3.10 pyzbar==0.1.9 From b6a4401e42f5d4e60671226322ec530bac185b02 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 24 Dec 2023 10:29:48 +0000 Subject: [PATCH 48/60] bump deps --- docker/stub/requirements.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/stub/requirements.txt b/docker/stub/requirements.txt index 7913b788..662a4dc3 100644 --- a/docker/stub/requirements.txt +++ b/docker/stub/requirements.txt @@ -1,5 +1,5 @@ # API framework -connexion[uvicorn,swagger-ui]==3.0.5 +connexion[uvicorn,flask,swagger-ui]==3.0.5 tinydb==4.8.0 cloud_api_robot_client @ git+https://github.com/CoderBotOrg/cloud_api_robot_client.git diff --git a/requirements.txt b/requirements.txt index 6f8eae55..dc2210a3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # API framework -connexion[uvicorn,swagger-ui]==3.0.5 +connexion[uvicorn,flask,swagger-ui]==3.0.5 tinydb==4.8.0 cloud_api_robot_client @ git+https://github.com/CoderBotOrg/cloud_api_robot_client.git From d8ef62223eda29e67e8539922273b2bfbdb1a126 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 24 Dec 2023 14:39:21 +0000 Subject: [PATCH 49/60] fix audio_devide --- coderbot/api.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/coderbot/api.py b/coderbot/api.py index f41723fe..f82d7e03 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -128,7 +128,7 @@ def turn(body): def takePhoto(): try: cam.photo_take() - audio_device.say(settings.get("sound_shutter")) + Audio.get_instance().say(settings.get("sound_shutter")) return {} except Exception as e: logging.warning("Error: %s", e) @@ -136,7 +136,7 @@ def takePhoto(): def recVideo(): try: cam.video_rec() - audio_device.say(settings.get("sound_shutter")) + Audio.get_instance().say(settings.get("sound_shutter")) return {} except Exception as e: logging.warning("Error: %s", e) @@ -144,7 +144,7 @@ def recVideo(): def stopVideo(): try: cam.video_stop() - audio_device.say(settings.get("sound_shutter")) + Audio.get_instance().say(settings.get("sound_shutter")) return {} except Exception as e: logging.warning("Error: %s", e) @@ -153,7 +153,7 @@ def speak(body): text = body.get("text", "") locale = body.get("locale", "") logging.debug("say: " + text + " in: " + locale) - audio_device.say(text, locale) + Audio.get_instance().say(text, locale) return {} def reset(): @@ -161,7 +161,7 @@ def reset(): return {} def halt(): - audio_device.say(what=settings.get("sound_stop")) + Audio.get_instance().say(what=settings.get("sound_stop")) Balena.get_instance().shutdown() return {} @@ -169,7 +169,7 @@ def restart(): Balena.get_instance().restart() def reboot(): - audio_device.say(what=settings.get("sound_stop")) + Audio.get_instance().say(what=settings.get("sound_stop")) Balena.get_instance().reboot() return {} From e929c0e960644b138d45cb07156d0a929aa5054e Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 24 Dec 2023 14:44:36 +0000 Subject: [PATCH 50/60] fix bot, cam --- coderbot/api.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/coderbot/api.py b/coderbot/api.py index f82d7e03..6344bdd7 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -67,7 +67,7 @@ def get_status(): internet_status = False try: - urllib.request.urlopen("https://coderbot.org") + urllib.request.urlopen("https://coderCoderBot.get_instance().org") internet_status = True except Exception: pass @@ -104,7 +104,7 @@ def get_info(): ## Robot control def stop(): - bot.stop() + CoderBot.get_instance().stop() return {} def move(body): @@ -113,7 +113,7 @@ def move(body): distance=body.get("distance") if (speed is None or speed == 0) or (elapse is not None and distance is not None): return None, 400 - bot.move(speed=speed, elapse=elapse, distance=distance) + CoderBot.get_instance().move(speed=speed, elapse=elapse, distance=distance) return {} def turn(body): @@ -122,12 +122,12 @@ def turn(body): distance=body.get("distance") if (speed is None or speed == 0) or (elapse is not None and distance is not None): return None, 400 - bot.turn(speed=speed, elapse=elapse, distance=distance) + CoderBot.get_instance().turn(speed=speed, elapse=elapse, distance=distance) return {} def takePhoto(): try: - cam.photo_take() + Camera.get_instance().photo_take() Audio.get_instance().say(settings.get("sound_shutter")) return {} except Exception as e: @@ -135,7 +135,7 @@ def takePhoto(): def recVideo(): try: - cam.video_rec() + Camera.get_instance().video_rec() Audio.get_instance().say(settings.get("sound_shutter")) return {} except Exception as e: @@ -143,7 +143,7 @@ def recVideo(): def stopVideo(): try: - cam.video_stop() + Camera.get_instance().video_stop() Audio.get_instance().say(settings.get("sound_shutter")) return {} except Exception as e: @@ -196,12 +196,12 @@ def listPhotos(): """ Expose the list of taken photos """ - return cam.get_photo_list() + return Camera.get_instance().get_photo_list() def getPhoto(name): mimetype = {'jpg': 'image/jpeg', 'mp4': 'video/mp4'} try: - media_file = cam.get_photo_file(name) + media_file = Camera.get_instance().get_photo_file(name) return send_file(media_file, mimetype=mimetype.get(name[:-3], 'image/jpeg'), max_age=0) except picamera.exc.PiCameraError as e: logging.error("Error: %s", str(e)) @@ -211,14 +211,14 @@ def getPhoto(name): def savePhoto(name, body): try: - cam.update_photo({"name": name, "tag": body.get("tag")}) + Camera.get_instance().update_photo({"name": name, "tag": body.get("tag")}) except FileNotFoundError: return None, 404 def deletePhoto(name): logging.debug("photo delete") try: - cam.delete_photo(name) + Camera.get_instance().delete_photo(name) except FileNotFoundError: return None, 404 @@ -377,7 +377,7 @@ def trainCNNModel(body): cnn.train_new_model(model_name=body.get("model_name"), architecture=body.get("architecture"), image_tags=body.get("image_tags"), - photos_meta=cam.get_photo_list(), + photos_meta=Camera.get_instance().get_photo_list(), training_steps=body.get("training_steps"), learning_rate=body.get("learning_rate")) From c89f25c835d203665bb7ea6924339bc3ed13cd6b Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 24 Dec 2023 19:36:21 +0000 Subject: [PATCH 51/60] fix video stream --- coderbot/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderbot/api.py b/coderbot/api.py index 6344bdd7..3487fb69 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -188,7 +188,7 @@ def streamVideo(): h.add('Age', 0) h.add('Cache-Control', 'no-cache, private') h.add('Pragma', 'no-cache') - return Response(video_stream(cam), headers=h, mimetype="multipart/x-mixed-replace; boundary=--BOUNDARYSTRING") + return Response(video_stream(Camera.get_instance()), headers=h, mimetype="multipart/x-mixed-replace; boundary=--BOUNDARYSTRING") except Exception: pass From 9ad105105a7a3d1ea4d377bbfd56d1b99794e91e Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Thu, 28 Dec 2023 22:30:20 +0000 Subject: [PATCH 52/60] add uuid --- coderbot/activity.py | 41 +++++---- coderbot/api.py | 58 +++++++----- coderbot/cloud/__init__.py | 18 ++-- coderbot/main.py | 1 - coderbot/program.py | 43 +++++---- coderbot/v1.yml | 89 ++++++++++++++----- defaults/config.json | 6 +- defaults/programs/program_demo_ar_tags.json | 2 +- .../programs/program_demo_cat_follower.json | 2 +- .../programs/program_demo_color_seeker.json | 2 +- defaults/programs/program_demo_io_ext.json | 2 +- .../programs/program_demo_line_follower.json | 2 +- .../program_demo_obstacle_avoidance.json | 2 +- .../programs/program_demo_roboetologist.json | 2 +- .../program_demo_sound_clap_control.json | 2 +- .../programs/program_test_cnn_classifier.json | 2 +- .../program_test_cnn_object_detect.json | 2 +- defaults/programs/program_test_find_code.json | 2 +- .../programs/program_test_find_color.json | 2 +- defaults/programs/program_test_find_face.json | 2 +- .../program_test_find_path_ahead.json | 2 +- .../programs/program_test_img_average.json | 2 +- defaults/programs/program_test_input.json | 2 +- defaults/programs/program_test_led.json | 2 +- defaults/programs/program_test_music.json | 2 +- defaults/programs/program_test_output.json | 2 +- defaults/programs/program_test_sonars.json | 2 +- .../programs/program_test_sound_hear.json | 2 +- defaults/programs/program_test_sound_rec.json | 2 +- 29 files changed, 185 insertions(+), 115 deletions(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index 18f24c3c..b7e8ab73 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -1,4 +1,5 @@ import logging +import uuid from tinydb import TinyDB, Query from threading import Lock from datetime import datetime @@ -9,13 +10,6 @@ ACTIVITY_KIND_STOCK = "stock" ACTIVITY_KIND_USER = "user" -class Activity(): - def __init__(self, name, description, data, kind, status): - self._name = name - self._description = description - self._data = data - self._kind = kind - self._status = status class Activities(): _instance = None @@ -32,14 +26,14 @@ def __init__(self): self.lock = Lock() self.permanentlyRemoveDeletedActivities() - def load(self, name, default, active_only=True): + def load(self, id, default, active_only=True): with self.lock: - if name and default is None: + if id and default is None: activities = [] if active_only: - activities = self.activities.search((self.query.name == name) & (self.query.status == ACTIVITY_STATUS_ACTIVE)) + activities = self.activities.search((self.query.id == id) & (self.query.status == ACTIVITY_STATUS_ACTIVE)) else: - activities = self.activities.search(self.query.name == name) + activities = self.activities.search(self.query.id == id) if len(activities) > 0: return activities[0] elif default is not None: @@ -48,19 +42,24 @@ def load(self, name, default, active_only=True): return None return None - def save(self, name, activity): + def save(self, activity): + if activity.get("id") is None: + activity["id"] = str(uuid.uuid4()) with self.lock: # if saved activity is "default", reset existing default activity to "non-default" if activity.get("default", False) is True: self.activities.update({'default': False}) - if self.activities.search(self.query.name == name) == []: - self.activities.insert(activity) + if self.activities.search(self.query.id == activity.get("id")) == []: + activity = self.activities.insert(activity) else: - self.activities.update(activity, self.query.name == name) + self.activities.update(activity, self.query.id == activity.get("id")) + activity = self.activities.search(self.query.id == activity.get("id"))[0] + logging.info("updating/creating activity: %s", str(activity)) + return activity - def delete(self, name, logical = True): + def delete(self, id, logical = True): with self.lock: - activities = self.activities.search(self.query.name == name) + activities = self.activities.search(self.query.id == id) if len(activities) > 0: activity = activities[0] if activity.get("default", False) is True: @@ -68,16 +67,16 @@ def delete(self, name, logical = True): if logical: activity["status"] = ACTIVITY_STATUS_DELETED activity["modified"] = datetime.now().isoformat() - self.activities.update(activity, self.query.name == name) + self.activities.update(activity, self.query.id == id) else: - self.activities.remove(self.query.name == name) + self.activities.remove(self.query.id == id) def permanentlyRemoveDeletedActivities(self): for a in self.list(active_only=False): - logging.info("checking: " + a["name"]) + logging.info("checking: " + a["id"]) if a["status"] == ACTIVITY_STATUS_DELETED: logging.info("deleting: " + a["name"]) - self.delete(a["name"], logical=False) + self.delete(a["id"], logical=False) def list(self, active_only = True): with self.lock: diff --git a/coderbot/api.py b/coderbot/api.py index 3487fb69..9b381f6c 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -277,41 +277,58 @@ def deleteMusicPackage(name): ## Programs -def saveProgram(name, body): +def saveNewProgram(body): overwrite = body.get("overwrite") - existing_program = prog_engine.load(name) + name = body["name"] + existing_program = prog_engine.load_by_name(name) logging.info("saving - name: %s, body: %s", name, str(existing_program)) if existing_program is not None and not overwrite: return "askOverwrite" elif existing_program is not None and existing_program.is_stock() == True: return "defaultCannotOverwrite", 400 program = Program(name=body.get("name"), code=body.get("code"), dom_code=body.get("dom_code"), modified=datetime.now(), status="active") + program_db_entry = prog_engine.save(program) + return program_db_entry + +def saveProgram(id, body): + overwrite = body.get("overwrite") + name = body["name"] + existing_program = prog_engine.load(id) + logging.info("saving - id: %s - name: %s - existing: %s", id, name, str(existing_program is not None)) + if existing_program is not None and existing_program.is_stock() == True: + return "defaultCannotOverwrite", 400 + program = Program( + id=existing_program._id, + name=existing_program._name, + code=body.get("code"), + dom_code=body.get("dom_code"), + modified=datetime.now(), + status="active") prog_engine.save(program) - return {} + return program.as_dict() -def loadProgram(name): - existing_program = prog_engine.load(name) +def loadProgram(id): + existing_program = prog_engine.load(id) if existing_program: return existing_program.as_dict(), 200 else: return None, 404 -def deleteProgram(name): - prog_engine.delete(name, logical=True) +def deleteProgram(id): + prog_engine.delete(id, logical=True) def listPrograms(): return prog_engine.prog_list(active_only=True) -def runProgram(name, body): +def runProgram(id): """ Execute the given program """ logging.debug("program_exec") - code = body.get('code') - prog = prog_engine.create(name, code) + prog = prog_engine.load(id) return prog.execute() -def stopProgram(name): +def stopProgram(id): """ Stop the program execution """ @@ -321,7 +338,7 @@ def stopProgram(name): prog.stop() return "ok" -def statusProgram(name): +def statusProgram(id): """ Expose the program status """ @@ -334,19 +351,20 @@ def statusProgram(name): ## Activities -def saveActivity(name, body): +def saveActivity(id, body): activity = body - activities.save(activity.get("name"), activity) + activity["id"] = id + return activities.save(activity) def saveAsNewActivity(body): activity = body - activities.save(activity.get("name"), activity) + return activities.save(activity) -def loadActivity(name=None, default=None): - return activities.load(name, default) +def loadActivity(id=None, default=None): + return activities.load(id, default) -def deleteActivity(name): - activities.delete(name), 200 +def deleteActivity(id): + activities.delete(id), 200 def listActivities(): return activities.list() @@ -411,7 +429,7 @@ def cloudRegistrationDelete(): return {} def cloudRegistrationStatus(): - registration = cloud_settings.get('registration', {}) + registration = Config.read().get("cloud").get('registration', {}) return { "registered": CloudManager.get_instance().registration_status(), "name": registration.get('name', ""), diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index 40a600a3..7d767859 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -35,6 +35,7 @@ SYNC_UPSTREAM = 'u' SYNC_DOWNSTREAM = 'd' SYNC_BIDIRECTIONAL = 'b' +SYNC_DISABLED = 'n' ENTITY_KIND_USER = "user" ENTITY_KIND_STOCK = "stock" @@ -197,7 +198,7 @@ def sync_settings(self, api_instance, sync_mode): config = Config.read() local_setting = { "settings": config.get("settings"), - "cloud": config.get("cloud") + #"cloud": config.get("cloud") } local_most_recent = datetime.fromisoformat(cloud_setting_object.get("modified")).timestamp() < Config.modified() cloud_kind_user = cloud_setting_object.get("kind") == ENTITY_KIND_USER @@ -217,7 +218,7 @@ def sync_settings(self, api_instance, sync_mode): logging.info("settings.upstream") elif cloud_setting != local_setting: # setting, down config["settings"] = cloud_setting["settings"] - config["cloud"] = cloud_setting["cloud"] + #config["cloud"] = cloud_setting["cloud"] Config.write(config) logging.info("settings.downstream") self._sync_status["settings"] = "synced" @@ -280,8 +281,8 @@ def sync_activities(self, api_instance, sync_mode): elif sync_mode == "d" or (not local_activity_more_recent and sync_mode == SYNC_BIDIRECTIONAL): al["data"] = ac.get("data") al["modified"] = ac.get("modified") - Activities.get_instance().save(al.get("name"), al) - logging.info("activities.update.downstream: " + al.get("name")) + Activities.get_instance().save(al) + logging.info("activities.update.downstream: " + al.get("id")) elif ac is None and sync_mode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: body = Activity( id="", @@ -296,7 +297,7 @@ def sync_activities(self, api_instance, sync_mode): api_response = api_instance.create_robot_activity(body=body) al["id"] = api_response.body["id"] al["org_id"] = api_response.body["org_id"] - Activities.get_instance().save(al.get("name"), al) + Activities.get_instance().save(al) logging.info("activities.create.upstream: " + al.get("name")) elif ac is None and sync_mode in [SYNC_DOWNSTREAM]: Activities.get_instance().delete(al.get("name")) @@ -312,7 +313,7 @@ def sync_activities(self, api_instance, sync_mode): activity["description"] = ac.get("description") activity["kind"] = ac.get("kind") activity["status"] = ac.get("status") - Activities.get_instance().save(ac.get("name"), activity) + Activities.get_instance().save(activity) # manage local user activities to be deleted locally and upstream for al in activities_local_to_be_deleted: @@ -320,7 +321,7 @@ def sync_activities(self, api_instance, sync_mode): logging.info("activities.delete.upstream: " + al.get("name")) api_response = api_instance.delete_robot_program(path_params={"activity_id":al.get("id")}) # delete locally permanently - Activities.get_instance().delete(al.get("name"), logical=False) + Activities.get_instance().delete(al.get("id"), logical=False) # manage local stock activities to be deleted locally for al in activities_local_stock: @@ -328,7 +329,7 @@ def sync_activities(self, api_instance, sync_mode): if al.get("id") is not None and activities_cloud_map.get(al.get("id")) is None: logging.info("activities.delete.stock.locally: " + al.get("name")) # delete locally permanently - Activities.get_instance().delete(al.get("name"), logical=False) + Activities.get_instance().delete(al.get("id"), logical=False) self._sync_status["activities"] = "synced" except cloud_api_robot_client.ApiException as e: @@ -369,6 +370,7 @@ def sync_programs(self, api_instance, sync_mode): for pl in programs_local_user: pc = programs_cloud_map.get(pl.get("id")) pc_pl_equals = (pc is not None and + pc.get("id") == pl.get("id") and pc.get("name") == pl.get("name") and pc.get("code") == pl.get("code") and pc.get("dom_code") == pl.get("dom_code") and diff --git a/coderbot/main.py b/coderbot/main.py index 681f18c4..9a715aa6 100644 --- a/coderbot/main.py +++ b/coderbot/main.py @@ -68,7 +68,6 @@ def run_server(): settings = Config.read().get("settings") app.settings = settings network_settings = Config.read().get("network") - cloud_settings = Config.read().get("cloud") bot = CoderBot.get_instance(settings=settings, motor_trim_factor=float(settings.get('move_motor_trim', 1.0)), motor_max_power=int(settings.get('motor_max_power', 100)), diff --git a/coderbot/program.py b/coderbot/program.py index 76dd7900..d78e9d4d 100644 --- a/coderbot/program.py +++ b/coderbot/program.py @@ -20,6 +20,7 @@ import os import threading import json +import uuid import shutil import logging from datetime import datetime @@ -92,7 +93,7 @@ def __init__(self, settings): for filename in filenames: if PROGRAM_PREFIX in filename: program_name = filename[len(PROGRAM_PREFIX):-len(PROGRAM_SUFFIX)] - if self.load(program_name) is None: + if self.load_by_name(program_name) is None: logging.info("adding program %s in path %s as default %r", program_name, dirname, ("default" in dirname)) with open(os.path.join(dirname, filename), "r") as f: program_dict = json.load(f) @@ -122,19 +123,20 @@ def save(self, program): program._modified = datetime.now() self._program = program program_db_entry = self._program.as_dict() - if self._programs.search(query.name == program.name) != []: - self._programs.update(program_db_entry, query.name == program.name) + if self._programs.search(query.id == program._id) != []: + self._programs.update(program_db_entry, query.id == program._id) else: self._programs.insert(program_db_entry) + return program_db_entry - def load(self, name, active_only=True): + def load(self, id, active_only=True): with self.lock: query = Query() program_db_entries = None if active_only: - program_db_entries = self._programs.search((query.name == name) & (query.status == PROGRAM_STATUS_ACTIVE)) + program_db_entries = self._programs.search((query.id == id) & (query.status == PROGRAM_STATUS_ACTIVE)) else: - program_db_entries = self._programs.search(query.name == name) + program_db_entries = self._programs.search(query.id == id) if len(program_db_entries) > 0: prog_db_entry = program_db_entries[0] #logging.debug(prog_db_entry) @@ -142,26 +144,31 @@ def load(self, name, active_only=True): return self._program return None - def delete(self, name, logical = True): + def load_by_name(self, name): + with self.lock: + program = None + query = Query() + programs = self._programs.search((query.name == name) & (query.status == PROGRAM_STATUS_ACTIVE)) + if len(programs) > 0: + program = Program.from_dict(programs[0]) + return program + + def delete(self, id, logical = True): with self.lock: query = Query() - program_db_entries = self._programs.search(query.name == name) + program_db_entries = self._programs.search(query.id == id) if len(program_db_entries) > 0: program_db_entry = program_db_entries[0] if logical: program_db_entry["status"] = PROGRAM_STATUS_DELETED program_db_entry["modified"] = datetime.now().isoformat() - self._programs.update(program_db_entry, query.name == name) + self._programs.update(program_db_entry, query.id == id) else: - self._programs.remove(query.name == name) + self._programs.remove(query.id == id) return None - def create(self, name, code): - self._program = Program(name, code, modified=datetime.now()) - return self._program - - def is_running(self, name): - return self._program.is_running() and self._program.name == name + def is_running(self, id): + return self._program.is_running() and self._program.id == id def check_end(self): return self._program.check_end() @@ -185,14 +192,14 @@ class Program: def dom_code(self): return self._dom_code - def __init__(self, name, description=None, code=None, dom_code=None, kind=PROGRAM_KIND_USER, id=None, modified=None, status=None): + def __init__(self, name, id=str(uuid.uuid4()), description=None, code=None, dom_code=None, kind=PROGRAM_KIND_USER, modified=None, status=None): self._thread = None + self._id = id self._name = name self._description = description self._dom_code = dom_code self._code = code self._kind = kind - self._id = id self._modified = modified self._status = status diff --git a/coderbot/v1.yml b/coderbot/v1.yml index 8bb36c5e..86677cdd 100644 --- a/coderbot/v1.yml +++ b/coderbot/v1.yml @@ -155,6 +155,27 @@ paths: description: "ok" /programs: + post: + operationId: "api.saveNewProgram" + summary: "Save a new program" + tags: + - Program management + requestBody: + description: Program object + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Program' + responses: + 200: + description: "ok" + content: + application/json: + schema: + $ref: '#/components/schemas/Program' + 400: + description: "Failed to save the program" get: operationId: "api.listPrograms" summary: "Get the list of all the saved programs" @@ -164,12 +185,12 @@ paths: 200: description: "ok" - /programs/{name}: + /programs/{id}: get: operationId: "api.loadProgram" summary: "Get the program with the specified name" parameters: - - name: name + - name: id in: path required: true schema: @@ -183,7 +204,7 @@ paths: operationId: "api.deleteProgram" summary: "Delete a program" parameters: - - name: name + - name: id in: path required: true schema: @@ -199,7 +220,7 @@ paths: tags: - Program management parameters: - - name: name + - name: id in: path required: true schema: @@ -217,37 +238,30 @@ paths: 400: description: "Failed to save the program" - /programs/{name}/run: + /programs/{id}/run: post: operationId: "api.runProgram" summary: "Execute the given program" tags: - Program management parameters: - - name: name + - name: id in: path required: true schema: type: string - requestBody: - description: Program object - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Program' responses: 200: description: "ok" - /programs/{name}/status: + /programs/{id}/status: get: operationId: "api.statusProgram" summary: "Get the status of the given program" tags: - Program management parameters: - - name: name + - name: id in: path required: true schema: @@ -256,14 +270,14 @@ paths: 200: description: "ok" - /programs/{name}/stop: + /programs/{id}/stop: patch: operationId: "api.stopProgram" summary: "Stop the given program" tags: - Program management parameters: - - name: name + - name: id in: path required: true schema: @@ -281,6 +295,13 @@ paths: responses: 200: description: "ok" + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Activity' + post: operationId: "api.saveAsNewActivity" summary: "Save a new activity" @@ -296,14 +317,18 @@ paths: responses: 200: description: "ok" + content: + application/json: + schema: + $ref: '#/components/schemas/Activity' 400: description: "Failed to save the activity" - /activities/{name}: + /activities/{id}: get: operationId: "api.loadActivity" summary: "Get the activity with the specified name" parameters: - - name: name + - name: id in: path required: true schema: @@ -318,11 +343,16 @@ paths: responses: 200: description: "ok" + content: + application/json: + schema: + $ref: '#/components/schemas/Activity' + put: operationId: "api.saveActivity" - summary: "Save the activity with the specified name" + summary: "Save the activity with the specified id" parameters: - - name: name + - name: id in: path required: true schema: @@ -339,13 +369,18 @@ paths: responses: 200: description: "ok" + content: + application/json: + schema: + $ref: '#/components/schemas/Activity' + delete: operationId: "api.deleteActivity" summary: "Delete an activity" tags: - Activity management parameters: - - name: name + - name: id in: path required: true schema: @@ -752,6 +787,11 @@ components: Program: type: object properties: + id: + type: string + #pattern: '^[[:xdigit:]]{8}(?:\-[[:xdigit:]]{4}){3}\-[[:xdigit:]]{12}$' + minLength: 36 + maxLength: 36 name: type: string pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' @@ -773,6 +813,11 @@ components: Activity: type: object properties: + id: + type: string + #pattern: '^[[:xdigit:]]{8}(?:\-[[:xdigit:]]{4}){3}\-[[:xdigit:]]{12}$/ + minLength: 36 + maxLength: 36 name: type: string minLength: 1 diff --git a/defaults/config.json b/defaults/config.json index 518c66fc..6c43815a 100644 --- a/defaults/config.json +++ b/defaults/config.json @@ -52,9 +52,9 @@ }, "cloud":{ "sync_modes":{ - "activities":"b", - "programs":"b", - "settings":"b" + "activities":"n", + "programs":"n", + "settings":"n" }, "sync_period":"10", "reg_otp":"AB1234CD" diff --git a/defaults/programs/program_demo_ar_tags.json b/defaults/programs/program_demo_ar_tags.json index 86699bac..901ff1bc 100644 --- a/defaults/programs/program_demo_ar_tags.json +++ b/defaults/programs/program_demo_ar_tags.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"t0%]}C@b{,qd7|sPe9zc\">tag_map</variable><variable type=\"\" id=\"6J?]Su~9cMcJ?1k)5D+=\">code</variable><variable type=\"\" id=\"w5)*3TcHccLvv^WOkh`c\">lista</variable><variable type=\"\" id=\"1J4H~VmQG*H$]$Q_:B__\">codes</variable><variable type=\"\" id=\"NC[lQ:--CtUITd)_|c$p\">positions</variable></variables><block type=\"controls_whileUntil\" id=\"@h-]#0?:MKRG}h:8:^x9\" x=\"-30\" y=\"144\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"#`fvr:O?_:Ttu0Bf{!]|\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"=^-j5Ga1MVnuBee97Y@C\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field><value name=\"VALUE\"><block type=\"coderbot_adv_findARCode\" id=\"s#f+e.r41WtcACO*8E@R\"></block></value><next><block type=\"variables_set\" id=\"#WGMDf[e(XBFiFV~%T{/\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"8n882RO_@|$b|*I#O`vD\"><value name=\"key\"><block type=\"text\" id=\"o)iJvT6q3wE1n$|w?}@W\"><field name=\"TEXT\">codes</field></block></value><value name=\"map\"><block type=\"variables_get\" id=\"jCx{KU9(=6P@.|peNlXN\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field></block></value></block></value><next><block type=\"variables_set\" id=\"bD=(HSHU48zl0{-/~noc\"><field name=\"VAR\" id=\"NC[lQ:--CtUITd)_|c$p\" variabletype=\"\">positions</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"#vbA+ig3tU@xSb1A|_w2\"><value name=\"key\"><block type=\"text\" id=\"i9_5n1O#`=t.~U,8FpGw\"><field name=\"TEXT\">positions</field></block></value><value name=\"map\"><block type=\"variables_get\" id=\"_JBza([QOX!qv/3VdYg9\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field></block></value></block></value><next><block type=\"controls_if\" id=\"OGk43S34JND/,jXGeVxz\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"0JLvc%7rD_C|!6cqFw-$\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"lists_length\" id=\"J_lY]]zCbQ[u!MMD-Id2\"><value name=\"VALUE\"><block type=\"variables_get\" id=\"kD{*,b/[9X1eU%FDp-mJ\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"EL*s.|ZMPGGbeVRYLFL8\"><field name=\"NUM\">0</field></block></value></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\"}|0Q`9cnLb|W)A4rACn(\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"SCm%!EpAerkyxrIF#P,5\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"lists_getIndex\" id=\"0NuaF,a-Mq%n]0F5yO71\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">LAST</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"h*z9nE!]v$fkNq=L9Z1~\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"TufaIZ~qb|Vm:zW)ks^F\"><field name=\"VAR\" id=\"NC[lQ:--CtUITd)_|c$p\" variabletype=\"\">positions</field></block></value></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"PCV}Dn!d_nmNHl([4UL8\"><field name=\"NUM\">150</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"k,p,V2i8b9cLa+XvIA1(\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\":+(Y+3IFohgd9%TmK,~h\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"@3wq8S#-um/Akpz8P@)N\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value></block></value><next><block type=\"text_print\" id=\"{9n*QwIw`Xz2rr%]!||i\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"g(BLm4y~J!I]Is)_+e.G\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value><next><block type=\"controls_if\" id=\"a-*{EC|T*!~|Jy1T;ky#\"><mutation elseif=\"4\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"vBhZBNkW2fzfWPMBh7PA\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"|hM?o_^1/MjiZMk9f-Hi\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"T)cl7En!l}Tz;C{RAQmS\"><field name=\"NUM\">1</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"Qf$Tb:D7*.]1HC0#SV-w\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"),wc.^}!FuO^[.fR5q+.\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"LvWv=:PuvKwdQKUqC!?Y\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_adv_move\" id=\"ks-wQ/9rha8HgY/5D7h8\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"QC$[#;#k/{[cXjT9|rFM\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"r7k/daFIIP-h9r4]b*[I\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"1Bn+v{5X{t^w6~QWeM49\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"eortt4PGO/b|wmiM5W[m\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"lmmlOegf8o|uu},4OJNW\"><field name=\"NUM\">2</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"w$$-?Uh:1Rl@;`E*Av6C\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"F:8LVYpTX]{Ox!iCa[U*\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"O)?`ZH~wDS@v!2JAwVA8\"><field name=\"NUM\">3</field></block></value></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\";I.JQ{LcQebMq+Nm7o?I\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"|/1VTr97/4/eDb~hP?{g\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"{/N?L?9p9,Vpq9+JpM+}\"><field name=\"NUM\">3</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_move\" id=\"[.uLTR$Q5eNd8!6wtvt=\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"Qzrz#P^X_/TaN@zz_wv`\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"XLk{ic:(6Z=]u-mXr$5#\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_adv_move\" id=\"VbCuoNCr6`._jSHeX}u%\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"fuihEymc@dwWL(CFQTX#\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"sm0p34bg|Tw%*:JTUF_i\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF3\"><block type=\"logic_compare\" id=\"Ma(^bi?_`^YErYgp4h,P\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"r@fO;U{M?YQ=Fj9rJJtD\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"F./nuSmkfx;j=a.Xb||H\"><field name=\"NUM\">4</field></block></value></block></value><statement name=\"DO3\"><block type=\"controls_repeat_ext\" id=\"!*8%}BA^?C8ncHv`O=y;\"><value name=\"TIMES\"><block type=\"math_number\" id=\"mmRw*r1VW@9EOf*~U`(:\"><field name=\"NUM\">2</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"h|=HGhp,p%JLZ6SjVA]d\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"ZM(/`ez$r4zl0JJXT(4v\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"7j.A;~YcadM%5QQe2n{R\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_adv_move\" id=\"YI6yNSOV`Zs^(Ys}w{A4\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"Co1AlC0ej9L8xK:DuSzB\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"E3tV*]cN%|8g@UilswEz\"><field name=\"NUM\">0.5</field></block></value></block></next></block></statement><next><block type=\"coderbot_audio_say\" id=\"6IK2cc.l8ZX7+=V*IFjT\"><field name=\"LOCALE\">it</field><value name=\"TEXT\"><block type=\"text\" id=\"+%T8MdX}|,B;r,=+S|Nj\"><field name=\"TEXT\">Sono arrivato!</field></block></value></block></next></block></statement><value name=\"IF4\"><block type=\"logic_compare\" id=\"unM/bY{:-`/BAwdbil*~\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\")HXZ]{NR`iX]-+gBKya6\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"MTJWF/*U[,/Aq=)gUK~@\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO4\"><block type=\"coderbot_audio_say\" id=\"$WB=k8dnPq;7!6KtgGSL\"><field name=\"LOCALE\">it</field><value name=\"TEXT\"><block type=\"text\" id=\"KuYp/v**F!_(?,!?~rQp\"><field name=\"TEXT\">Attenzione!</field></block></value></block></statement></block></next></block></next></block></statement></block></statement><next><block type=\"text_print\" id=\"7BYNgrmH0+*5Apcu|R[%\"><value name=\"TEXT\"><block type=\"text\" id=\"YMLXch,ZSheJiLbJ]h~f\"><field name=\"TEXT\"></field></block></value></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "tag_map = None\ncode = None\nlista = None\ncodes = None\npositions = None\n\n\nwhile True:\n get_prog_eng().check_end()\n tag_map = get_cam().find_ar_code()\n codes = tag_map.get('codes')\n positions = tag_map.get('positions')\n if len(codes) > 0:\n if positions[0][-1] > 150:\n code = codes[0]\n get_cam().set_text(codes)\n if code == 1:\n get_bot().forward(speed=100, elapse=1)\n get_bot().left(speed=100, elapse=1)\n elif code == 2:\n get_bot().forward(speed=100, elapse=3)\n elif code == 3:\n get_bot().forward(speed=100, elapse=1)\n get_bot().right(speed=100, elapse=1)\n elif code == 4:\n for count in range(2):\n get_prog_eng().check_end()\n get_bot().right(speed=100, elapse=0.5)\n get_bot().left(speed=100, elapse=0.5)\n get_audio().say('Sono arrivato!', locale=\"it\")\n elif code == 5:\n get_audio().say('Attenzione!', locale=\"it\")\n get_cam().set_text('')\n", "name": "demo_ar_tags"} \ No newline at end of file +{"id": "5b4cf283-1666-4ada-87c8-234ff0ed37e8", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"t0%]}C@b{,qd7|sPe9zc\">tag_map</variable><variable type=\"\" id=\"6J?]Su~9cMcJ?1k)5D+=\">code</variable><variable type=\"\" id=\"w5)*3TcHccLvv^WOkh`c\">lista</variable><variable type=\"\" id=\"1J4H~VmQG*H$]$Q_:B__\">codes</variable><variable type=\"\" id=\"NC[lQ:--CtUITd)_|c$p\">positions</variable></variables><block type=\"controls_whileUntil\" id=\"@h-]#0?:MKRG}h:8:^x9\" x=\"-30\" y=\"144\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"#`fvr:O?_:Ttu0Bf{!]|\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"=^-j5Ga1MVnuBee97Y@C\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field><value name=\"VALUE\"><block type=\"coderbot_adv_findARCode\" id=\"s#f+e.r41WtcACO*8E@R\"></block></value><next><block type=\"variables_set\" id=\"#WGMDf[e(XBFiFV~%T{/\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"8n882RO_@|$b|*I#O`vD\"><value name=\"key\"><block type=\"text\" id=\"o)iJvT6q3wE1n$|w?}@W\"><field name=\"TEXT\">codes</field></block></value><value name=\"map\"><block type=\"variables_get\" id=\"jCx{KU9(=6P@.|peNlXN\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field></block></value></block></value><next><block type=\"variables_set\" id=\"bD=(HSHU48zl0{-/~noc\"><field name=\"VAR\" id=\"NC[lQ:--CtUITd)_|c$p\" variabletype=\"\">positions</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"#vbA+ig3tU@xSb1A|_w2\"><value name=\"key\"><block type=\"text\" id=\"i9_5n1O#`=t.~U,8FpGw\"><field name=\"TEXT\">positions</field></block></value><value name=\"map\"><block type=\"variables_get\" id=\"_JBza([QOX!qv/3VdYg9\"><field name=\"VAR\" id=\"t0%]}C@b{,qd7|sPe9zc\" variabletype=\"\">tag_map</field></block></value></block></value><next><block type=\"controls_if\" id=\"OGk43S34JND/,jXGeVxz\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"0JLvc%7rD_C|!6cqFw-$\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"lists_length\" id=\"J_lY]]zCbQ[u!MMD-Id2\"><value name=\"VALUE\"><block type=\"variables_get\" id=\"kD{*,b/[9X1eU%FDp-mJ\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"EL*s.|ZMPGGbeVRYLFL8\"><field name=\"NUM\">0</field></block></value></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\"}|0Q`9cnLb|W)A4rACn(\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"SCm%!EpAerkyxrIF#P,5\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"lists_getIndex\" id=\"0NuaF,a-Mq%n]0F5yO71\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">LAST</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"h*z9nE!]v$fkNq=L9Z1~\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"TufaIZ~qb|Vm:zW)ks^F\"><field name=\"VAR\" id=\"NC[lQ:--CtUITd)_|c$p\" variabletype=\"\">positions</field></block></value></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"PCV}Dn!d_nmNHl([4UL8\"><field name=\"NUM\">150</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"k,p,V2i8b9cLa+XvIA1(\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\":+(Y+3IFohgd9%TmK,~h\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"@3wq8S#-um/Akpz8P@)N\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value></block></value><next><block type=\"text_print\" id=\"{9n*QwIw`Xz2rr%]!||i\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"g(BLm4y~J!I]Is)_+e.G\"><field name=\"VAR\" id=\"1J4H~VmQG*H$]$Q_:B__\" variabletype=\"\">codes</field></block></value><next><block type=\"controls_if\" id=\"a-*{EC|T*!~|Jy1T;ky#\"><mutation elseif=\"4\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"vBhZBNkW2fzfWPMBh7PA\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"|hM?o_^1/MjiZMk9f-Hi\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"T)cl7En!l}Tz;C{RAQmS\"><field name=\"NUM\">1</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"Qf$Tb:D7*.]1HC0#SV-w\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"),wc.^}!FuO^[.fR5q+.\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"LvWv=:PuvKwdQKUqC!?Y\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_adv_move\" id=\"ks-wQ/9rha8HgY/5D7h8\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"QC$[#;#k/{[cXjT9|rFM\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"r7k/daFIIP-h9r4]b*[I\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"1Bn+v{5X{t^w6~QWeM49\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"eortt4PGO/b|wmiM5W[m\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"lmmlOegf8o|uu},4OJNW\"><field name=\"NUM\">2</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"w$$-?Uh:1Rl@;`E*Av6C\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"F:8LVYpTX]{Ox!iCa[U*\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"O)?`ZH~wDS@v!2JAwVA8\"><field name=\"NUM\">3</field></block></value></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\";I.JQ{LcQebMq+Nm7o?I\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"|/1VTr97/4/eDb~hP?{g\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"{/N?L?9p9,Vpq9+JpM+}\"><field name=\"NUM\">3</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_move\" id=\"[.uLTR$Q5eNd8!6wtvt=\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"Qzrz#P^X_/TaN@zz_wv`\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"XLk{ic:(6Z=]u-mXr$5#\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_adv_move\" id=\"VbCuoNCr6`._jSHeX}u%\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"fuihEymc@dwWL(CFQTX#\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"sm0p34bg|Tw%*:JTUF_i\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF3\"><block type=\"logic_compare\" id=\"Ma(^bi?_`^YErYgp4h,P\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"r@fO;U{M?YQ=Fj9rJJtD\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"F./nuSmkfx;j=a.Xb||H\"><field name=\"NUM\">4</field></block></value></block></value><statement name=\"DO3\"><block type=\"controls_repeat_ext\" id=\"!*8%}BA^?C8ncHv`O=y;\"><value name=\"TIMES\"><block type=\"math_number\" id=\"mmRw*r1VW@9EOf*~U`(:\"><field name=\"NUM\">2</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"h|=HGhp,p%JLZ6SjVA]d\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"ZM(/`ez$r4zl0JJXT(4v\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"7j.A;~YcadM%5QQe2n{R\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_adv_move\" id=\"YI6yNSOV`Zs^(Ys}w{A4\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"Co1AlC0ej9L8xK:DuSzB\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"E3tV*]cN%|8g@UilswEz\"><field name=\"NUM\">0.5</field></block></value></block></next></block></statement><next><block type=\"coderbot_audio_say\" id=\"6IK2cc.l8ZX7+=V*IFjT\"><field name=\"LOCALE\">it</field><value name=\"TEXT\"><block type=\"text\" id=\"+%T8MdX}|,B;r,=+S|Nj\"><field name=\"TEXT\">Sono arrivato!</field></block></value></block></next></block></statement><value name=\"IF4\"><block type=\"logic_compare\" id=\"unM/bY{:-`/BAwdbil*~\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\")HXZ]{NR`iX]-+gBKya6\"><field name=\"VAR\" id=\"6J?]Su~9cMcJ?1k)5D+=\" variabletype=\"\">code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"MTJWF/*U[,/Aq=)gUK~@\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO4\"><block type=\"coderbot_audio_say\" id=\"$WB=k8dnPq;7!6KtgGSL\"><field name=\"LOCALE\">it</field><value name=\"TEXT\"><block type=\"text\" id=\"KuYp/v**F!_(?,!?~rQp\"><field name=\"TEXT\">Attenzione!</field></block></value></block></statement></block></next></block></next></block></statement></block></statement><next><block type=\"text_print\" id=\"7BYNgrmH0+*5Apcu|R[%\"><value name=\"TEXT\"><block type=\"text\" id=\"YMLXch,ZSheJiLbJ]h~f\"><field name=\"TEXT\"></field></block></value></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "tag_map = None\ncode = None\nlista = None\ncodes = None\npositions = None\n\n\nwhile True:\n get_prog_eng().check_end()\n tag_map = get_cam().find_ar_code()\n codes = tag_map.get('codes')\n positions = tag_map.get('positions')\n if len(codes) > 0:\n if positions[0][-1] > 150:\n code = codes[0]\n get_cam().set_text(codes)\n if code == 1:\n get_bot().forward(speed=100, elapse=1)\n get_bot().left(speed=100, elapse=1)\n elif code == 2:\n get_bot().forward(speed=100, elapse=3)\n elif code == 3:\n get_bot().forward(speed=100, elapse=1)\n get_bot().right(speed=100, elapse=1)\n elif code == 4:\n for count in range(2):\n get_prog_eng().check_end()\n get_bot().right(speed=100, elapse=0.5)\n get_bot().left(speed=100, elapse=0.5)\n get_audio().say('Sono arrivato!', locale=\"it\")\n elif code == 5:\n get_audio().say('Attenzione!', locale=\"it\")\n get_cam().set_text('')\n", "name": "demo_ar_tags"} \ No newline at end of file diff --git a/defaults/programs/program_demo_cat_follower.json b/defaults/programs/program_demo_cat_follower.json index 905374e6..bf72dae0 100644 --- a/defaults/programs/program_demo_cat_follower.json +++ b/defaults/programs/program_demo_cat_follower.json @@ -1 +1 @@ -{"name": "demo_cat_follower", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\",?YI{f}$o~t3-v%!oOh`\">object</variable><variable id=\"9layCHw;-1P!)]pX+m2W\">class</variable><variable id=\"80w]HhW?e7QM%yfJ*[BS\">position</variable><variable id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</variable></variables><block type=\"controls_whileUntil\" id=\"[^a!+/Zsc!iXdJ*Z-Go#\" x=\"43\" y=\"19\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"2Qi5#s+x(vg-{l2glVGI\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"0Y_GS_fw!h^YTb,XeKz#\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"_GYqAA5bQtVd@ICQGW(U\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"coderbot_adv_cnn_detect_objects\" id=\"m(x+AUHK}k[f:xAb;!iH\"><field name=\"MODEL\">generic_object_detect</field></block></value></block></value><next><block type=\"variables_set\" id=\":mq1jiC7D(V_yjV]p+bj\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"gg?Rm?i]1V[@Sk0~,6}U\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"jWBE:9@+HD)M5w(R6-+R\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value></block></value><next><block type=\"controls_if\" id=\"SoONo/Qzd^PSRs3kDLW4\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"girWO4BMe2k@24#mK9W|\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"9oEqGs$i`cb!|tDMGcUs\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field></block></value><value name=\"B\"><block type=\"text\" id=\"57hUIBHt5-};Ur^Ym(`p\"><field name=\"TEXT\">cat</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\":krqJ`zM+j//B~motZ@5\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"n*i|7Ey@DqvX+8X;^2fb\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"$p#z76Ff-*8z$I:6(%:F\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"?s]?2J@-Pc6i1f-y{[09\"><field name=\"NUM\">3</field></block></value></block></value><next><block type=\"variables_set\" id=\"[:tR1VyS6qeSU?!D)`sN\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field><value name=\"VALUE\"><block type=\"math_arithmetic\" id=\"*U,nQR1[HxPKn8W%pkCz\"><field name=\"OP\">DIVIDE</field><value name=\"A\"><block type=\"math_arithmetic\" id=\"uc.~ggYr?xqXV/.F7s1u\"><field name=\"OP\">ADD</field><value name=\"A\"><block type=\"lists_getIndex\" id=\"kuISxM{Klu36vQ]Jo+P@\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"?gyq($9~Uq.~3XY8_J9)\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"(1G%d4(*1Vqq?1xk.^{t\"><field name=\"NUM\">1</field></block></value></block></value><value name=\"B\"><block type=\"lists_getIndex\" id=\".Xk?/{p+tLXc=}|OA82n\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"|IdyV?|5py+=3,0!:z_A\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\",Me8:/`3uBpfuBZrA)sp\"><field name=\"NUM\">3</field></block></value></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"m~K8F`G6T$ha/a^LdD5Z\"><field name=\"NUM\">2</field></block></value></block></value><next><block type=\"text_print\" id=\"|,^zQ|VUQq/(lt,K`8y0\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"#QdSbUp(4Hn;Xk(4xe0G\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field></block></value><next><block type=\"controls_if\" id=\"}1i(Om9l5~9.WOIq!=W`\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"~.k].tdW8FF4#-(AeXsM\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\")KUmL+N6#~?rM~GnqH[G\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"l*=6l=SR/g6%(|]$i;}C\"><field name=\"NUM\">40</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\":YSGyu*XL_u{)zQBD:{X\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"de??^JX,i_mkb$RsmNXs\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"zs-Cre_[w%5@VNoMwi;l\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"+S5!K$WfFhj@QhRSokhV\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"J%|{#:u3(!lcF4.B~gQt\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"[gg?3(+hO-?.%qW,`@t~\"><field name=\"NUM\">60</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"vA*_d?-Bwh55o,{*%v:G\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"W}pFMYn/}2RnG+E86e~v\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"as/ZY,XwrTw`@Z~O9B`$\"><field name=\"NUM\">0.1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\"Xs:ewoKw*Fg3UK*sRCNm\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"qSFO9:h}?s~cD:hj(r:(\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"Nh^fXOiu1$x8[$i1C2IV\"><field name=\"NUM\">0.2</field></block></value></block></statement></block></next></block></next></block></next></block></statement><statement name=\"ELSE\"><block type=\"text_print\" id=\"PAYJ[1S)`0Gl#=M`cX=g\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"2nPmKkqF|Y:u3?r=5y|n\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "object2 = None\nclass2 = None\nposition = None\npos_x = None\n\n\nwhile True:\n get_prog_eng().check_end()\n object2 = get_cam().cnn_detect_objects(\"generic_object_detect\")[0]\n class2 = object2[0]\n if class2 == 'cat':\n position = object2[2]\n pos_x = (position[0] + position[2]) / 2\n get_cam().set_text(class2)\n if pos_x < 40:\n get_bot().left(speed=60, elapse=0.1)\n elif pos_x > 60:\n get_bot().right(speed=60, elapse=0.1)\n else:\n get_bot().forward(speed=100, elapse=0.2)\n else:\n get_cam().set_text(object2)\n"} \ No newline at end of file +{"id": "a4e429dd-b5b4-4f5f-8c2e-5e5f5d557aff", "name": "demo_cat_follower", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\",?YI{f}$o~t3-v%!oOh`\">object</variable><variable id=\"9layCHw;-1P!)]pX+m2W\">class</variable><variable id=\"80w]HhW?e7QM%yfJ*[BS\">position</variable><variable id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</variable></variables><block type=\"controls_whileUntil\" id=\"[^a!+/Zsc!iXdJ*Z-Go#\" x=\"43\" y=\"19\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"2Qi5#s+x(vg-{l2glVGI\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"0Y_GS_fw!h^YTb,XeKz#\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"_GYqAA5bQtVd@ICQGW(U\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"coderbot_adv_cnn_detect_objects\" id=\"m(x+AUHK}k[f:xAb;!iH\"><field name=\"MODEL\">generic_object_detect</field></block></value></block></value><next><block type=\"variables_set\" id=\":mq1jiC7D(V_yjV]p+bj\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"gg?Rm?i]1V[@Sk0~,6}U\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"jWBE:9@+HD)M5w(R6-+R\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value></block></value><next><block type=\"controls_if\" id=\"SoONo/Qzd^PSRs3kDLW4\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"girWO4BMe2k@24#mK9W|\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"9oEqGs$i`cb!|tDMGcUs\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field></block></value><value name=\"B\"><block type=\"text\" id=\"57hUIBHt5-};Ur^Ym(`p\"><field name=\"TEXT\">cat</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\":krqJ`zM+j//B~motZ@5\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"n*i|7Ey@DqvX+8X;^2fb\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"$p#z76Ff-*8z$I:6(%:F\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"?s]?2J@-Pc6i1f-y{[09\"><field name=\"NUM\">3</field></block></value></block></value><next><block type=\"variables_set\" id=\"[:tR1VyS6qeSU?!D)`sN\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field><value name=\"VALUE\"><block type=\"math_arithmetic\" id=\"*U,nQR1[HxPKn8W%pkCz\"><field name=\"OP\">DIVIDE</field><value name=\"A\"><block type=\"math_arithmetic\" id=\"uc.~ggYr?xqXV/.F7s1u\"><field name=\"OP\">ADD</field><value name=\"A\"><block type=\"lists_getIndex\" id=\"kuISxM{Klu36vQ]Jo+P@\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"?gyq($9~Uq.~3XY8_J9)\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"(1G%d4(*1Vqq?1xk.^{t\"><field name=\"NUM\">1</field></block></value></block></value><value name=\"B\"><block type=\"lists_getIndex\" id=\".Xk?/{p+tLXc=}|OA82n\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"|IdyV?|5py+=3,0!:z_A\"><field name=\"VAR\" id=\"80w]HhW?e7QM%yfJ*[BS\">position</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\",Me8:/`3uBpfuBZrA)sp\"><field name=\"NUM\">3</field></block></value></block></value></block></value><value name=\"B\"><block type=\"math_number\" id=\"m~K8F`G6T$ha/a^LdD5Z\"><field name=\"NUM\">2</field></block></value></block></value><next><block type=\"text_print\" id=\"|,^zQ|VUQq/(lt,K`8y0\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"#QdSbUp(4Hn;Xk(4xe0G\"><field name=\"VAR\" id=\"9layCHw;-1P!)]pX+m2W\">class</field></block></value><next><block type=\"controls_if\" id=\"}1i(Om9l5~9.WOIq!=W`\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"~.k].tdW8FF4#-(AeXsM\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\")KUmL+N6#~?rM~GnqH[G\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"l*=6l=SR/g6%(|]$i;}C\"><field name=\"NUM\">40</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\":YSGyu*XL_u{)zQBD:{X\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"de??^JX,i_mkb$RsmNXs\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"zs-Cre_[w%5@VNoMwi;l\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"+S5!K$WfFhj@QhRSokhV\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"J%|{#:u3(!lcF4.B~gQt\"><field name=\"VAR\" id=\"fRn/=2s}a[[jcCloxlyH\">pos_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"[gg?3(+hO-?.%qW,`@t~\"><field name=\"NUM\">60</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"vA*_d?-Bwh55o,{*%v:G\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"W}pFMYn/}2RnG+E86e~v\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"as/ZY,XwrTw`@Z~O9B`$\"><field name=\"NUM\">0.1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\"Xs:ewoKw*Fg3UK*sRCNm\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"qSFO9:h}?s~cD:hj(r:(\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"Nh^fXOiu1$x8[$i1C2IV\"><field name=\"NUM\">0.2</field></block></value></block></statement></block></next></block></next></block></next></block></statement><statement name=\"ELSE\"><block type=\"text_print\" id=\"PAYJ[1S)`0Gl#=M`cX=g\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"2nPmKkqF|Y:u3?r=5y|n\"><field name=\"VAR\" id=\",?YI{f}$o~t3-v%!oOh`\">object</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "object2 = None\nclass2 = None\nposition = None\npos_x = None\n\n\nwhile True:\n get_prog_eng().check_end()\n object2 = get_cam().cnn_detect_objects(\"generic_object_detect\")[0]\n class2 = object2[0]\n if class2 == 'cat':\n position = object2[2]\n pos_x = (position[0] + position[2]) / 2\n get_cam().set_text(class2)\n if pos_x < 40:\n get_bot().left(speed=60, elapse=0.1)\n elif pos_x > 60:\n get_bot().right(speed=60, elapse=0.1)\n else:\n get_bot().forward(speed=100, elapse=0.2)\n else:\n get_cam().set_text(object2)\n"} \ No newline at end of file diff --git a/defaults/programs/program_demo_color_seeker.json b/defaults/programs/program_demo_color_seeker.json index 5c6e53ae..c5eae413 100644 --- a/defaults/programs/program_demo_color_seeker.json +++ b/defaults/programs/program_demo_color_seeker.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"1\" y=\"90\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">dist</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">DIST</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"variables_set\"><field name=\"VAR\">angle</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">ANGLE</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"text_join\"><mutation items=\"4\"></mutation><value name=\"ADD0\"><block type=\"text\"><field name=\"TEXT\">Distance: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"ADD2\"><block type=\"text\"><field name=\"TEXT\"> angle: </field></block></value><value name=\"ADD3\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value></block></value><next><block type=\"controls_if\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">32</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_operation\"><field name=\"OP\">AND</field><value name=\"A\"><block type=\"logic_compare\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">28</field></block></value></block></value><value name=\"B\"><block type=\"logic_compare\"><field name=\"OP\">GTE</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">0</field></block></value></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><next><block type=\"controls_if\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">30</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">-5</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">30</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "dist = None\nangle = None\n\n\nwhile True:\n get_prog_eng().check_end()\n dist = get_cam().find_color('#96b73c')[0]\n angle = get_cam().find_color('#96b73c')[1]\n get_cam().set_text(''.join([str(temp_value) for temp_value in ['Distance: ', dist, ' angle: ', angle]]))\n if dist > 32:\n get_bot().forward(speed=100, elapse=0.1)\n elif dist < 28 and dist >= 0:\n get_bot().backward(speed=100, elapse=0.1)\n if angle > 5:\n get_bot().right(speed=30, elapse=0.1)\n elif angle < -5:\n get_bot().left(speed=30, elapse=0.1)\n", "name": "demo_color_seeker"} \ No newline at end of file +{"id": "d1601ee4-bc8c-49f4-a79e-0015b7c7b1d7", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"1\" y=\"90\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">dist</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">DIST</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"variables_set\"><field name=\"VAR\">angle</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">ANGLE</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"text_join\"><mutation items=\"4\"></mutation><value name=\"ADD0\"><block type=\"text\"><field name=\"TEXT\">Distance: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"ADD2\"><block type=\"text\"><field name=\"TEXT\"> angle: </field></block></value><value name=\"ADD3\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value></block></value><next><block type=\"controls_if\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">32</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_operation\"><field name=\"OP\">AND</field><value name=\"A\"><block type=\"logic_compare\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">28</field></block></value></block></value><value name=\"B\"><block type=\"logic_compare\"><field name=\"OP\">GTE</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">0</field></block></value></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><next><block type=\"controls_if\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">30</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value><value name=\"B\"><block type=\"math_number\"><field name=\"NUM\">-5</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">30</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.1</field></block></value></block></statement></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "dist = None\nangle = None\n\n\nwhile True:\n get_prog_eng().check_end()\n dist = get_cam().find_color('#96b73c')[0]\n angle = get_cam().find_color('#96b73c')[1]\n get_cam().set_text(''.join([str(temp_value) for temp_value in ['Distance: ', dist, ' angle: ', angle]]))\n if dist > 32:\n get_bot().forward(speed=100, elapse=0.1)\n elif dist < 28 and dist >= 0:\n get_bot().backward(speed=100, elapse=0.1)\n if angle > 5:\n get_bot().right(speed=30, elapse=0.1)\n elif angle < -5:\n get_bot().left(speed=30, elapse=0.1)\n", "name": "demo_color_seeker"} \ No newline at end of file diff --git a/defaults/programs/program_demo_io_ext.json b/defaults/programs/program_demo_io_ext.json index 315d167b..91632161 100644 --- a/defaults/programs/program_demo_io_ext.json +++ b/defaults/programs/program_demo_io_ext.json @@ -1 +1 @@ -{"name": "demo_io_ext", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</variable></variables><block type=\"controls_whileUntil\" id=\"Dl?:_j0SBuhadu{w@UF.\" x=\"228\" y=\"37\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"pJCxtUhR_b%x:dTqn9md\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"+v#-(`(Qm]QpW/]^kj=k\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field><value name=\"VALUE\"><block type=\"coderbot_atmega_get_input\" id=\"ai)*,59_NZc9svsP|JM:\"><field name=\"INPUT\">0</field></block></value><next><block type=\"text_print\" id=\"QtWQNQO[-l[BZ~e`Qmh$\"><value name=\"TEXT\"><block type=\"text_join\" id=\"1Ukw}Lu=x]S?%jKwDJJV\"><mutation items=\"2\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\"Y9wE(=ZJTe,Y=7yA$1+2\"><field name=\"TEXT\">Analog Input 1: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\" id=\"4QrPsC2-~_VL]6GoH_*O\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field></block></value></block></value><next><block type=\"controls_if\" id=\"le3Rmn/8;oI#ps$J,7la\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"pm_-a@W30t?pU$DT9!sX\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"IrfeoxR,w1!`9%NW+elg\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"R4b=e-`S!g*H6T7B1nel\"><field name=\"NUM\">100</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_atmega_set_output\" id=\"yvJ,i1lZv!^Q~}#Co+-i\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"Peb+]}4!:tv}p4J_B9]z\"><field name=\"BOOL\">TRUE</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_atmega_set_output\" id=\"z/@VGWnrW3D(x,d1SZ^y\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"$yU!z^ZFMBh!(m7s,9*:\"><field name=\"BOOL\">FALSE</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "Analog_Input_1 = None\n\n\nwhile True:\n get_prog_eng().check_end()\n Analog_Input_1 = get_atmega().get_input(0)\n get_cam().set_text('Analog Input 1: ' + str(Analog_Input_1))\n if Analog_Input_1 > 100:\n get_atmega().set_output(0, True)\n else:\n get_atmega().set_output(0, False)\n"} \ No newline at end of file +{"id": "30e8ea4b-967d-41bb-8d6a-67e12f7f0008", "name": "demo_io_ext", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</variable></variables><block type=\"controls_whileUntil\" id=\"Dl?:_j0SBuhadu{w@UF.\" x=\"228\" y=\"37\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"pJCxtUhR_b%x:dTqn9md\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"+v#-(`(Qm]QpW/]^kj=k\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field><value name=\"VALUE\"><block type=\"coderbot_atmega_get_input\" id=\"ai)*,59_NZc9svsP|JM:\"><field name=\"INPUT\">0</field></block></value><next><block type=\"text_print\" id=\"QtWQNQO[-l[BZ~e`Qmh$\"><value name=\"TEXT\"><block type=\"text_join\" id=\"1Ukw}Lu=x]S?%jKwDJJV\"><mutation items=\"2\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\"Y9wE(=ZJTe,Y=7yA$1+2\"><field name=\"TEXT\">Analog Input 1: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\" id=\"4QrPsC2-~_VL]6GoH_*O\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field></block></value></block></value><next><block type=\"controls_if\" id=\"le3Rmn/8;oI#ps$J,7la\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"pm_-a@W30t?pU$DT9!sX\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"IrfeoxR,w1!`9%NW+elg\"><field name=\"VAR\" id=\"L_e%=^0/~b[gZI1*^ZSd\">Analog_Input_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"R4b=e-`S!g*H6T7B1nel\"><field name=\"NUM\">100</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_atmega_set_output\" id=\"yvJ,i1lZv!^Q~}#Co+-i\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"Peb+]}4!:tv}p4J_B9]z\"><field name=\"BOOL\">TRUE</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_atmega_set_output\" id=\"z/@VGWnrW3D(x,d1SZ^y\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"$yU!z^ZFMBh!(m7s,9*:\"><field name=\"BOOL\">FALSE</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "Analog_Input_1 = None\n\n\nwhile True:\n get_prog_eng().check_end()\n Analog_Input_1 = get_atmega().get_input(0)\n get_cam().set_text('Analog Input 1: ' + str(Analog_Input_1))\n if Analog_Input_1 > 100:\n get_atmega().set_output(0, True)\n else:\n get_atmega().set_output(0, False)\n"} \ No newline at end of file diff --git a/defaults/programs/program_demo_line_follower.json b/defaults/programs/program_demo_line_follower.json index 2ad8fb82..2dc76af8 100644 --- a/defaults/programs/program_demo_line_follower.json +++ b/defaults/programs/program_demo_line_follower.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"44C`F*i%?EbRAm0f[}XQ\">line_x_1</variable><variable type=\"\" id=\"BShIh7Dye|p!AtQ`p8wj\">lista</variable><variable type=\"\" id=\"(`T?t~cnldIn9}cU!6P3\">line_x_list</variable><variable type=\"\" id=\"+9O~W5dFyMgb4R9?j?2j\">line_x_2</variable><variable type=\"\" id=\"G;b/=HFbfhuxT|0?~S[r\">ar_code</variable><variable type=\"\" id=\"kOrv]Wo^Y7{4+#7gA`K;\">ar_code_list</variable></variables><block type=\"controls_whileUntil\" id=\"`]WZt9m4:b-6v?sR0a{6\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"?g7Pi#[#{_)~?7~!MUL]\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"n/Jg4jt-?ANdJFh!U#R}\"><field name=\"VAR\" id=\"(`T?t~cnldIn9}cU!6P3\" variabletype=\"\">line_x_list</field><value name=\"VALUE\"><block type=\"coderbot_adv_findLine\" id=\"|O16NyeI_GMcWz}e#ht9\"></block></value><next><block type=\"variables_set\" id=\"d:T;q-q)7$dJ(@9w7DF=\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"oA1x#4CMYuz}p|KK8e~S\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"CIJd6?@63y$}V34}.bC-\"><field name=\"VAR\" id=\"(`T?t~cnldIn9}cU!6P3\" variabletype=\"\">line_x_list</field></block></value></block></value><next><block type=\"variables_set\" id=\"S2ieOivJB5(|7?}~us@M\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"tgJS~3PX=0SJTSMlsaVv\"><value name=\"key\"><block type=\"text\" id=\"Wz#h:CVLwyX,^(^kc{B`\"><field name=\"TEXT\">codes</field></block></value><value name=\"map\"><block type=\"coderbot_adv_findARCode\" id=\"9$MM{KjS8lUj}A;=Pr(z\"></block></value></block></value><next><block type=\"controls_if\" id=\"IL@9S#Xl-hRa#LwNvh.g\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_negate\" id=\"XQTF1;SNhjc#]4#_}9wU\"><value name=\"BOOL\"><block type=\"lists_isEmpty\" id=\"b^36mV09/]tRws|?BYoK\"><value name=\"VALUE\"><block type=\"variables_get\" id=\";qp!b+zbymPr{3WAvNrG\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field></block></value></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"uv4pqKisw(|c:|d/Do%J\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"a0JACY?SyTgO21=or@D6\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"ySld:`sc3M4=IjeN*RuO\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field></block></value></block></value></block></statement><statement name=\"ELSE\"><block type=\"variables_set\" id=\"/f{XE@50=WxbI;,=TeW]\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field><value name=\"VALUE\"><block type=\"math_number\" id=\"@XV^(en_.lQ0_#rZkz}#\"><field name=\"NUM\">0</field></block></value></block></statement><next><block type=\"text_print\" id=\"{f1ctd/iW#D,le1V(Cy-\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"5VI:=npMdg$L|=e0/Okn\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><next><block type=\"controls_if\" id=\"GvDQg$7WT=Qq6HBCexdf\"><mutation elseif=\"2\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\")M6ls=nOUTB^J;|3-Q@=\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"Y9PB[dJ*r*.*=2([@JT:\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"e`kkA/p8dDJT4Iu`PtP|\"><field name=\"NUM\">1</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_motor\" id=\"mM!-gOyoBb8xLuEK}:PY\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"MV9CvsB9cK7#oJv5M+Gy\"><field name=\"NUM\">80</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"@I!w63)Db*b!^mzk?7b-\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"xz=GX~R6!L1Lz?RO%xSE\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"nSLX(4#c?i({f6gx}h$b\"><field name=\"NUM\">1000</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"3C{Tr^vc`K1K7@whf0+#\"><field name=\"NUM\">1000</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"0[pEKb#+c1ukccsj-HGU\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"!.x!ti5!Jl_Qyi_98vP:\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\":Omnr1TfVKRT,{x+CErC\"><field name=\"NUM\">2</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_motor\" id=\"^@Y|H7}/,1f%m;D)rsqN\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"tpQfUU_t1N9uX9DDLpNK\"><field name=\"NUM\">60</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"X__|/-/MQqilOsxKk.Vn\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"sUK%h7;p?NFy6ej0G@ad\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"55Q_(wsMzLOOTn,AJ*=o\"><field name=\"NUM\">2000</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"Q(U)4jCVk5tml,K%_m3X\"><field name=\"NUM\">1550</field></block></value></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\"-.]jhYzu{)[`q?J|G*@i\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"TYK1ggBo;v^8(fzNK!PO\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"D2;EP}Ok0vx,}R7Te.[g\"><field name=\"NUM\">6</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_motor\" id=\"FWt]Cn.Gx+x%y|4TMq*/\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"PN3gP4:wymcc7g[G,=JC\"><field name=\"NUM\">60</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"$svZ(tsG{Q]%-=QakU@7\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"IxJ8gaf@V.5xrl3X3yu0\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"1hpVYp0#go4@HCi%[MZ`\"><field name=\"NUM\">1550</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"ZuV9iU47evPA,S7J?s+@\"><field name=\"NUM\">2000</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"controls_if\" id=\"]Xst$#BXb%U~.5?C5fN1\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"PD.BkyibEtTX2,VtMdsc\"><field name=\"OP\">GTE</field><value name=\"A\"><block type=\"variables_get\" id=\"UWRm7PH[oi_n9oQsRDGd\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"V1b;v7$b+m#/u;2dm6H$\"><field name=\"NUM\">0</field></block></value></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\",?`$EcLs;XYj{O%B$A~o\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"0WmrG/knZBBpiHSDmLBJ\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"%amYL^tWO^t8nX`JBAEF\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"hIduK@,Vwz{H?bp[WPjj\"><field name=\"NUM\">60</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_motor\" id=\";vD-YiW9)qU8sg-}vcm1\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"((}~wa#@9K8b}RS#DSq?\"><field name=\"NUM\">40</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\":,f0J=^9v|J$I;5Ahy|K\"><field name=\"NUM\">-40</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"L48OY[hxw|)quL7-vkb^\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_arithmetic\" id=\"Upl0F:r{a0y5cdS.crj)\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"variables_get\" id=\"oS=EnUt$f^C5Vj!8|9C8\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"7~z_5vl91w!1jP(k.(Qd\"><field name=\"NUM\">50</field></block></value></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_arithmetic\" id=\"A~(#(]O_(kSZBIc4,yw@\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"variables_get\" id=\"Vuwafvcd/K_ph5^FX:%!\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"x$bmhmC2RW9ZOLL7FWHF\"><field name=\"NUM\">50</field></block></value></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"I)Gu5YQYkX.:()}l^{xg\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\"zCKv1.|-Rios8@h5ilIg\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"vJw^%jvK#eR95btK#CeU\"><field name=\"NUM\">40</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_motor\" id=\"w(zj/fW0HsEnX1*u!4O?\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"y+F~@jqeyB9bS]M=9}J}\"><field name=\"NUM\">-40</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"1/(])B%ubDAdndUnXxg-\"><field name=\"NUM\">40</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"{?IB?(nV;5%Nm_F$1rMX\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_arithmetic\" id=\";dV0cDAx~my3rojA^G|4\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"math_number\" id=\"o/=rp-ECY@EVjB8FV/0~\"><field name=\"NUM\">50</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"W;jmAc*0%%;8cx.}*jQL\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_arithmetic\" id=\"hYIe9z|NuF;9Um0Fk)mu\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"math_number\" id=\"b-Ei9$@yv*bVNNAauA+o\"><field name=\"NUM\">50</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"c?]Gby*%LO[jc{jaa%-9\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_motor\" id=\"O.;G[S8aWfdf|`/h*59@\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"I6+d!/%ONX{B=e8{n0kx\"><field name=\"NUM\">50</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"C*9^tnhIr1`.e{Ts56$Z\"><field name=\"NUM\">50</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"(0,tpOtURC`/@~c2LSVs\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"Ka-C|%Y8;GO(qa1sH:XG\"><field name=\"NUM\">150</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"xLy*EHb!}4NrV0`Z-_yZ\"><field name=\"NUM\">150</field></block></value></block></statement></block></statement></block></statement></block></next></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "line_x_1 = None\nlista = None\nline_x_list = None\nline_x_2 = None\nar_code = None\nar_code_list = None\n\n\nwhile True:\n get_prog_eng().check_end()\n line_x_list = get_cam().find_line()\n line_x_1 = line_x_list[0]\n ar_code_list = get_cam().find_ar_code().get('codes')\n if not not len(ar_code_list):\n ar_code = ar_code_list[0]\n else:\n ar_code = 0\n get_cam().set_text(ar_code)\n if ar_code == 1:\n get_bot().motor_control(speed_left=80, speed_right=80, elapse=-1, steps_left=1000, steps_right=1000)\n elif ar_code == 2:\n get_bot().motor_control(speed_left=60, speed_right=60, elapse=-1, steps_left=2000, steps_right=1550)\n elif ar_code == 6:\n get_bot().motor_control(speed_left=60, speed_right=60, elapse=-1, steps_left=1550, steps_right=2000)\n else:\n if line_x_1 >= 0:\n if line_x_1 > 60:\n get_bot().motor_control(speed_left=40, speed_right=-40, elapse=-1, steps_left=line_x_1 - 50, steps_right=line_x_1 - 50)\n elif line_x_1 < 40:\n get_bot().motor_control(speed_left=-40, speed_right=40, elapse=-1, steps_left=50 - line_x_1, steps_right=50 - line_x_1)\n else:\n get_bot().motor_control(speed_left=50, speed_right=50, elapse=-1, steps_left=150, steps_right=150)\n", "name": "demo_line_follower"} \ No newline at end of file +{"id": "f893bc1c-9d22-4bbb-ac3c-05637c49d307", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"44C`F*i%?EbRAm0f[}XQ\">line_x_1</variable><variable type=\"\" id=\"BShIh7Dye|p!AtQ`p8wj\">lista</variable><variable type=\"\" id=\"(`T?t~cnldIn9}cU!6P3\">line_x_list</variable><variable type=\"\" id=\"+9O~W5dFyMgb4R9?j?2j\">line_x_2</variable><variable type=\"\" id=\"G;b/=HFbfhuxT|0?~S[r\">ar_code</variable><variable type=\"\" id=\"kOrv]Wo^Y7{4+#7gA`K;\">ar_code_list</variable></variables><block type=\"controls_whileUntil\" id=\"`]WZt9m4:b-6v?sR0a{6\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"?g7Pi#[#{_)~?7~!MUL]\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"n/Jg4jt-?ANdJFh!U#R}\"><field name=\"VAR\" id=\"(`T?t~cnldIn9}cU!6P3\" variabletype=\"\">line_x_list</field><value name=\"VALUE\"><block type=\"coderbot_adv_findLine\" id=\"|O16NyeI_GMcWz}e#ht9\"></block></value><next><block type=\"variables_set\" id=\"d:T;q-q)7$dJ(@9w7DF=\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"oA1x#4CMYuz}p|KK8e~S\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"CIJd6?@63y$}V34}.bC-\"><field name=\"VAR\" id=\"(`T?t~cnldIn9}cU!6P3\" variabletype=\"\">line_x_list</field></block></value></block></value><next><block type=\"variables_set\" id=\"S2ieOivJB5(|7?}~us@M\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field><value name=\"VALUE\"><block type=\"hashmap_get_value\" id=\"tgJS~3PX=0SJTSMlsaVv\"><value name=\"key\"><block type=\"text\" id=\"Wz#h:CVLwyX,^(^kc{B`\"><field name=\"TEXT\">codes</field></block></value><value name=\"map\"><block type=\"coderbot_adv_findARCode\" id=\"9$MM{KjS8lUj}A;=Pr(z\"></block></value></block></value><next><block type=\"controls_if\" id=\"IL@9S#Xl-hRa#LwNvh.g\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_negate\" id=\"XQTF1;SNhjc#]4#_}9wU\"><value name=\"BOOL\"><block type=\"lists_isEmpty\" id=\"b^36mV09/]tRws|?BYoK\"><value name=\"VALUE\"><block type=\"variables_get\" id=\";qp!b+zbymPr{3WAvNrG\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field></block></value></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"uv4pqKisw(|c:|d/Do%J\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"a0JACY?SyTgO21=or@D6\"><mutation statement=\"false\" at=\"false\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FIRST</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"ySld:`sc3M4=IjeN*RuO\"><field name=\"VAR\" id=\"kOrv]Wo^Y7{4+#7gA`K;\" variabletype=\"\">ar_code_list</field></block></value></block></value></block></statement><statement name=\"ELSE\"><block type=\"variables_set\" id=\"/f{XE@50=WxbI;,=TeW]\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field><value name=\"VALUE\"><block type=\"math_number\" id=\"@XV^(en_.lQ0_#rZkz}#\"><field name=\"NUM\">0</field></block></value></block></statement><next><block type=\"text_print\" id=\"{f1ctd/iW#D,le1V(Cy-\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"5VI:=npMdg$L|=e0/Okn\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><next><block type=\"controls_if\" id=\"GvDQg$7WT=Qq6HBCexdf\"><mutation elseif=\"2\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\")M6ls=nOUTB^J;|3-Q@=\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"Y9PB[dJ*r*.*=2([@JT:\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"e`kkA/p8dDJT4Iu`PtP|\"><field name=\"NUM\">1</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_motor\" id=\"mM!-gOyoBb8xLuEK}:PY\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"MV9CvsB9cK7#oJv5M+Gy\"><field name=\"NUM\">80</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"@I!w63)Db*b!^mzk?7b-\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"xz=GX~R6!L1Lz?RO%xSE\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"nSLX(4#c?i({f6gx}h$b\"><field name=\"NUM\">1000</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"3C{Tr^vc`K1K7@whf0+#\"><field name=\"NUM\">1000</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"0[pEKb#+c1ukccsj-HGU\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"!.x!ti5!Jl_Qyi_98vP:\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\":Omnr1TfVKRT,{x+CErC\"><field name=\"NUM\">2</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_motor\" id=\"^@Y|H7}/,1f%m;D)rsqN\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"tpQfUU_t1N9uX9DDLpNK\"><field name=\"NUM\">60</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"X__|/-/MQqilOsxKk.Vn\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"sUK%h7;p?NFy6ej0G@ad\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"55Q_(wsMzLOOTn,AJ*=o\"><field name=\"NUM\">2000</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"Q(U)4jCVk5tml,K%_m3X\"><field name=\"NUM\">1550</field></block></value></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\"-.]jhYzu{)[`q?J|G*@i\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"TYK1ggBo;v^8(fzNK!PO\"><field name=\"VAR\" id=\"G;b/=HFbfhuxT|0?~S[r\" variabletype=\"\">ar_code</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"D2;EP}Ok0vx,}R7Te.[g\"><field name=\"NUM\">6</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_motor\" id=\"FWt]Cn.Gx+x%y|4TMq*/\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"PN3gP4:wymcc7g[G,=JC\"><field name=\"NUM\">60</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"$svZ(tsG{Q]%-=QakU@7\"><field name=\"NUM\">60</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"IxJ8gaf@V.5xrl3X3yu0\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"1hpVYp0#go4@HCi%[MZ`\"><field name=\"NUM\">1550</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"ZuV9iU47evPA,S7J?s+@\"><field name=\"NUM\">2000</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"controls_if\" id=\"]Xst$#BXb%U~.5?C5fN1\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"PD.BkyibEtTX2,VtMdsc\"><field name=\"OP\">GTE</field><value name=\"A\"><block type=\"variables_get\" id=\"UWRm7PH[oi_n9oQsRDGd\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"V1b;v7$b+m#/u;2dm6H$\"><field name=\"NUM\">0</field></block></value></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\",?`$EcLs;XYj{O%B$A~o\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"0WmrG/knZBBpiHSDmLBJ\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"%amYL^tWO^t8nX`JBAEF\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"hIduK@,Vwz{H?bp[WPjj\"><field name=\"NUM\">60</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_motor\" id=\";vD-YiW9)qU8sg-}vcm1\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"((}~wa#@9K8b}RS#DSq?\"><field name=\"NUM\">40</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\":,f0J=^9v|J$I;5Ahy|K\"><field name=\"NUM\">-40</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"L48OY[hxw|)quL7-vkb^\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_arithmetic\" id=\"Upl0F:r{a0y5cdS.crj)\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"variables_get\" id=\"oS=EnUt$f^C5Vj!8|9C8\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"7~z_5vl91w!1jP(k.(Qd\"><field name=\"NUM\">50</field></block></value></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_arithmetic\" id=\"A~(#(]O_(kSZBIc4,yw@\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"variables_get\" id=\"Vuwafvcd/K_ph5^FX:%!\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"x$bmhmC2RW9ZOLL7FWHF\"><field name=\"NUM\">50</field></block></value></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"I)Gu5YQYkX.:()}l^{xg\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\"zCKv1.|-Rios8@h5ilIg\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"vJw^%jvK#eR95btK#CeU\"><field name=\"NUM\">40</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_motor\" id=\"w(zj/fW0HsEnX1*u!4O?\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"y+F~@jqeyB9bS]M=9}J}\"><field name=\"NUM\">-40</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"1/(])B%ubDAdndUnXxg-\"><field name=\"NUM\">40</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"{?IB?(nV;5%Nm_F$1rMX\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_arithmetic\" id=\";dV0cDAx~my3rojA^G|4\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"math_number\" id=\"o/=rp-ECY@EVjB8FV/0~\"><field name=\"NUM\">50</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"W;jmAc*0%%;8cx.}*jQL\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_arithmetic\" id=\"hYIe9z|NuF;9Um0Fk)mu\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"math_number\" id=\"b-Ei9$@yv*bVNNAauA+o\"><field name=\"NUM\">50</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"c?]Gby*%LO[jc{jaa%-9\"><field name=\"VAR\" id=\"44C`F*i%?EbRAm0f[}XQ\" variabletype=\"\">line_x_1</field></block></value></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_motor\" id=\"O.;G[S8aWfdf|`/h*59@\"><value name=\"SPEED_LEFT\"><block type=\"math_number\" id=\"I6+d!/%ONX{B=e8{n0kx\"><field name=\"NUM\">50</field></block></value><value name=\"SPEED_RIGHT\"><block type=\"math_number\" id=\"C*9^tnhIr1`.e{Ts56$Z\"><field name=\"NUM\">50</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"(0,tpOtURC`/@~c2LSVs\"><field name=\"NUM\">-1</field></block></value><value name=\"STEPS_LEFT\"><block type=\"math_number\" id=\"Ka-C|%Y8;GO(qa1sH:XG\"><field name=\"NUM\">150</field></block></value><value name=\"STEPS_RIGHT\"><block type=\"math_number\" id=\"xLy*EHb!}4NrV0`Z-_yZ\"><field name=\"NUM\">150</field></block></value></block></statement></block></statement></block></statement></block></next></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "line_x_1 = None\nlista = None\nline_x_list = None\nline_x_2 = None\nar_code = None\nar_code_list = None\n\n\nwhile True:\n get_prog_eng().check_end()\n line_x_list = get_cam().find_line()\n line_x_1 = line_x_list[0]\n ar_code_list = get_cam().find_ar_code().get('codes')\n if not not len(ar_code_list):\n ar_code = ar_code_list[0]\n else:\n ar_code = 0\n get_cam().set_text(ar_code)\n if ar_code == 1:\n get_bot().motor_control(speed_left=80, speed_right=80, elapse=-1, steps_left=1000, steps_right=1000)\n elif ar_code == 2:\n get_bot().motor_control(speed_left=60, speed_right=60, elapse=-1, steps_left=2000, steps_right=1550)\n elif ar_code == 6:\n get_bot().motor_control(speed_left=60, speed_right=60, elapse=-1, steps_left=1550, steps_right=2000)\n else:\n if line_x_1 >= 0:\n if line_x_1 > 60:\n get_bot().motor_control(speed_left=40, speed_right=-40, elapse=-1, steps_left=line_x_1 - 50, steps_right=line_x_1 - 50)\n elif line_x_1 < 40:\n get_bot().motor_control(speed_left=-40, speed_right=40, elapse=-1, steps_left=50 - line_x_1, steps_right=50 - line_x_1)\n else:\n get_bot().motor_control(speed_left=50, speed_right=50, elapse=-1, steps_left=150, steps_right=150)\n", "name": "demo_line_follower"} \ No newline at end of file diff --git a/defaults/programs/program_demo_obstacle_avoidance.json b/defaults/programs/program_demo_obstacle_avoidance.json index ab3e4a8e..899ffe38 100644 --- a/defaults/programs/program_demo_obstacle_avoidance.json +++ b/defaults/programs/program_demo_obstacle_avoidance.json @@ -1 +1 @@ -{"name": "demo_obstacle_avoidance", "code": "while True:\n get_prog_eng().check_end()\n if get_bot().get_sonar_distance(0) < 15:\n get_bot().right(speed=100, elapse=0.5)\n else:\n get_bot().forward(speed=100, elapse=1)\n", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables></variables><block type=\"controls_whileUntil\" id=\"-yfR%N=ZA:dr/vf[$_Y+\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"H@,=TqL*XM3|6M}Z:3+C\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"controls_if\" id=\"D~6eYo_:!JGW/LOSHdG-\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"Otlt5#y}Bm[e5ta5;YxY\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"ssLQq~!Drc._YB6B-d3S\"><field name=\"SONAR\">0</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"eH-VJ17iCGoZyj+UEq:}\"><field name=\"NUM\">15</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"trpdU@xT,u;^uH#kGc;f\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"LNg%=nl9p;4Ib`yn]hP8\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"iS!-;G+snS)ML@1l1*P%\"><field name=\"NUM\">0.5</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\"VxFs%Ie:uau;?%8H_;b{\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"~,ygpvFtKIs_R${W*q8e\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"Hs$baRlg*_rwO(m,0?yU\"><field name=\"NUM\">1</field></block></value></block></statement></block></statement></block></xml>"} \ No newline at end of file +{"id": "0cfd0dd1-7ec3-4f34-9720-41f42b0209e1", "name": "demo_obstacle_avoidance", "code": "while True:\n get_prog_eng().check_end()\n if get_bot().get_sonar_distance(0) < 15:\n get_bot().right(speed=100, elapse=0.5)\n else:\n get_bot().forward(speed=100, elapse=1)\n", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables></variables><block type=\"controls_whileUntil\" id=\"-yfR%N=ZA:dr/vf[$_Y+\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"H@,=TqL*XM3|6M}Z:3+C\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"controls_if\" id=\"D~6eYo_:!JGW/LOSHdG-\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"Otlt5#y}Bm[e5ta5;YxY\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"ssLQq~!Drc._YB6B-d3S\"><field name=\"SONAR\">0</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"eH-VJ17iCGoZyj+UEq:}\"><field name=\"NUM\">15</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"trpdU@xT,u;^uH#kGc;f\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"LNg%=nl9p;4Ib`yn]hP8\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"iS!-;G+snS)ML@1l1*P%\"><field name=\"NUM\">0.5</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\"VxFs%Ie:uau;?%8H_;b{\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"~,ygpvFtKIs_R${W*q8e\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"Hs$baRlg*_rwO(m,0?yU\"><field name=\"NUM\">1</field></block></value></block></statement></block></statement></block></xml>"} \ No newline at end of file diff --git a/defaults/programs/program_demo_roboetologist.json b/defaults/programs/program_demo_roboetologist.json index 71f717b8..1a50d542 100644 --- a/defaults/programs/program_demo_roboetologist.json +++ b/defaults/programs/program_demo_roboetologist.json @@ -1 +1 @@ -{"name":"demo_roboetologist","dom_code":"<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</variable><variable id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</variable><variable id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</variable><variable id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</variable><variable id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</variable><variable id=\"}Amjkrp!.(7[D41[a^{6\">velocita</variable><variable id=\";M|:6*RIcl{fLp+^(S~p\">stanco</variable></variables><block type=\"procedures_defnoreturn\" id=\"!]5:R,96H,d*lP5TdKtv\" x=\"32\" y=\"-248\"><field name=\"NAME\">Scodinzola</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"$@148i!0XDrE)=/74E,F\"><value name=\"TIMES\"><block type=\"math_number\" id=\"Z|tRJT3et)`/%nF;x|BX\"><field name=\"NUM\">3</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"ICVMx1}4##d{B2;1_0yw\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"YOER#;}9h-EjO#NWK$-r\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"c)2=ZX:s9Pu=6_!gAznZ\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"OkO@z~w=AGqzQZu357hr\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"`1Tkh_x5G03,$gK8[7`W\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"6k^]W@IDw;E{I)B2[vF[\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"r3grvcve;,ycs9O{$Z(`\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"KIT-F0Ks@@7mYljTMX}a\"><field name=\"NUM\">0.3</field></block></value><next><block type=\"coderbot_sleep\" id=\"8HSK*.y3si%z:5X:X}Cf\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"_JMB)UTj(N=+rh}WJ1gM\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"I!%c5zbo7`I8H8pPUGmi\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"=G4VJm2R._wOHz%QTKGH\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"sE)S[)9b8GYNM/}A?Q?a\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"th7m{buvj!fXr2[L}rdj\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"tD5onaW9m}8|$[!eMBlT\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"UI8*HDp}`l@z/mNCX#%h\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"?;j;(@*sHEBLK;FT9Snq\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"xm4O$9/uD/DtLEFUuc:H\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"C.gRCR/O:%1W,h%jxJQz\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"P@A2tlSC:EM}cZ{1qJOm\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"4^Vbi3$0bgFj([_q#a)!\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"gfVNt(aQi}BuKUSFJ.3:\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"s@*_u8JqM`F^;vK{O*_0\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"obZReNmla70EZtJwNI$8\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"IEU%gc|cb25NDN1pDPM*\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"{*bj!1W#x3tx!SeWj:kT\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"DaVdvC(WkUw{D:y*?4F6\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\".$SS=6=p56*%bV+0d!UP\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"~~F31]H,M#iZIBu-hpHt\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"S6tUIN@%q%t{Hz2ddE-{\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\".dOMH{.fxW#:}@%b#)JX\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"ZGo9-9/V=n8K.l-Ukk@h\"><field name=\"NUM\">0.3</field></block></value><next><block type=\"coderbot_sleep\" id=\"NK1usFSpUZ,JP33u=3#d\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"?f-Y1{[eyW,FRqS=Wjo$\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"]yMj3IsqdH!-7(8Cvk[U\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></next></block></next></block></statement></block></statement></block><block type=\"procedures_defnoreturn\" id=\"eAhV_z+X]idI9Y2#)$n(\" x=\"1037\" y=\"-296\"><field name=\"NAME\">Evita_Ostacoli</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"@c#NwB$D7537*F7m=!(7\"><value name=\"TIMES\"><shadow type=\"math_number\" id=\"YMSS!*wG*F@i;BhUmTE`\"><field name=\"NUM\">15</field></shadow></value><statement name=\"DO\"><block type=\"controls_if\" id=\"X*#hoa)#P0K0YxbKTgIs\"><mutation elseif=\"2\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"Otlt5#y}Bm[e5ta5;YxY\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"ssLQq~!Drc._YB6B-d3S\"><field name=\"SONAR\">0</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"eH-VJ17iCGoZyj+UEq:}\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"trpdU@xT,u;^uH#kGc;f\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"HcmX([S/=AKRH4R8$I0B\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"/rWP6rW9R]E3-naWqgJb\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\".t[s{j8IX2vxW-3BN:mY\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Fb`JpvO.k6Tc7[f,$O$v\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"$l?U4w3[2%qk..:nTePo\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"8Ifz1evG3eDtpQLtQGl9\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"iS!-;G+snS)ML@1l1*P%\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"/vCSdFhWoJq}Z~+GZv@B\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"x)rjS0}jg(awX7.?Vw6}\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"nkX`O8.7pQ/nRXu}}SJ=\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"lzJKDW53E#N;!A;c=C@_\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"PA|Q|jw0.1~mrO$9Q%P;\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"G|iI)YzX$qKo3I+17OnJ\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"I.S?k*]?]8:ux2At*LJ1\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"CXKnQkB)^Mp8+FB%/Kq}\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"Xe+Rt?_8u.vO?W@ZWs2-\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"j4=;9]Ka!u+7?MAJPGh?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"YTc?Tsq{XFq({Kc.X:l2\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"~D0glLe($lFOxGCVt({`\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"k=7sJ/UX#,{!dlpX;H`6\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"6%wD3wHrc$f(?}Bq)28s\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"i374]E^am-M6uyS?-gKC\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"Xp?Z4ev2ys-O`aN-$WNL\"><field name=\"SONAR\">1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\",2c5e_Y3:j:T[liXjo{l\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"Am`s@r3LgvQtrS1TL57q\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"~prj;Zl(AJ|,`oeCCf-,\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"DcI1#yBE~@moiU6YAv#x\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"j`G2K]gZRIV)]2.7dzG9\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"]wDU`;H3W8![o1a2fzk1\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"3/hwsno_gvMwqLT_mgV!\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"/5eh,CVTRpqcb/s5{R5H\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"8t@}mCD~^YNfqoRxQJl%\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"]/3=*vM9ken$o-O1f~fV\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"*SfrgoD6pBdYTZcV!|0b\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"WPe.SW;HHIq|eAB`,BJ`\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\"Oi)HJ7[XQLUo?9Ja,p{i\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"VX/j*WrI[j^f/|ei-f:(\"><field name=\"SONAR\">2</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"J=/3jvhaq=%R42539s$D\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_move\" id=\"Yw+`{06m}q=Xy[hpZc--\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"/^l1V(M*RdBL=xaqy1tq\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"m_d8qZ${$Q]1dgRC9kg1\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"P1aDE;avAT65i|PhY=-2\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"rv=.e$[u+4J|wpmE!WWc\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"=72b0Fu=xSqlre+0P==V\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\",=w/soAS//gtuY7.MR1L\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"HM%|wVB7+V~p-IL[*AR^\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"yJFCwyQPE5=?0r/~vamL\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"5W!KOp9GS.b=}L5otZuU\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"^omY,%{F`GV!pDo}yZrv\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\":l(I1S51$*1Y1BPm^@/w\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"SHq.(.XcZ}7M,l8RC_c@\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"w7#zA8o]]XpeNtS=VD-:\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"J9Igw@@/VH.K__Yl)@~p\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Uo@*[cy$0q1dgsf#Q^z-\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"tb~[WgJ9A+?zO!3y}p;U\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"`}JdE]gqQ@ZY1w]uW%5C\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"GHLs)siSUy|OQqqr3dIo\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"LcaW`EM+]Jb=X?I[;JSB\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"`tVVItwfg.HfaD1gzB=:\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"aBw0-LWH!FA$beTy(Zhv\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement></block></statement></block></statement></block><block type=\"variables_set\" id=\"i9a!EM@s`-6hUdv$sr@3\" x=\"-546\" y=\"-188\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field><value name=\"VALUE\"><block type=\"math_number\" id=\"^=8DhFn=]2Efwc(|OkiD\"><field name=\"NUM\">0.2</field></block></value><next><block type=\"variables_set\" id=\"zjzJg@NAQU,k/!!@n5,*\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field><value name=\"VALUE\"><block type=\"math_number\" id=\"nDs=tH{gKK+fBi0-bA/_\"><field name=\"NUM\">80</field></block></value><next><block type=\"variables_set\" id=\"uD3I^ll~9L#obOA^SI!0\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"VALUE\"><block type=\"math_number\" id=\"~G:^Vj.oE0(OO]ZP3Vcn\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"Obn8q0fElL9mB(i|1]5[\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"VALUE\"><block type=\"math_number\" id=\"H!=muFCqUw/I?)IGAUt|\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"I/mn7F@$p-}4[H4_SBqY\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"VALUE\"><block type=\"math_number\" id=\"*azH8=DJtBx-pQwu4|V6\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"tEC)Up7J)~4{(Dz1[lCj\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"VALUE\"><block type=\"math_number\" id=\"E%Tw$~W4?sv.fNIxv0Ma\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"x4jFKBKS^fdsk#T.U7Z!\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"6ZiB~3h3aO3z5)_kg[zG\"><field name=\"NUM\">1</field></block></value><next><block type=\"controls_whileUntil\" id=\"-yfR%N=ZA:dr/vf[$_Y+\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"H@,=TqL*XM3|6M}Z:3+C\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"math_change\" id=\"1%fq4KBED@gkjP~jlRMk\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"DELTA\"><block type=\"math_number\" id=\";S+Wfd9n5g26eOE9EngY\"><field name=\"NUM\">1</field></block></value><next><block type=\"math_change\" id=\"f-`F7YcK2uSF1[N^tPM{\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"{gD@*ayDq5d6tMw(2Kbc\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"math_change\" id=\"dS?rG_[64b{_2vBnB^QM\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"dkbf0gA|c8o0Cm=!@gQT\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"math_change\" id=\"`)S8h1qAw*?jy*ixY}u+\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"1L=-j:W;2d`s1`:q.su~\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"controls_if\" id=\"S!3#D%1@0YM^;{sm}Q.k\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"/dnfv--t9_A=(06arGX$\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"/}JP!cseKId$umH4~#!d\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"9WL24mxLME}qFQWRype$\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"~_/s2uIq9S6k56j~CVA#\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"VALUE\"><block type=\"math_number\" id=\"YjfWxc5Q+w#]Da0z;@@s\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"@Z/po(O(J`O{*FUL?#%K\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"jmeKZm8wIKG-As_[L%t4\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"E@jRA2fJ},Gr}awmmspH\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"|RNUw6)n!:kvhSz]2of^\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"Q@W~I[!UTRLrFCi:+4D4\"><field name=\"NUM\">3</field></block></value></block></value><statement name=\"DO1\"><block type=\"variables_set\" id=\"TX2klHO#QS96(-b;oxdw\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"}5,MJoA8{Gp/tD?@oBQq\"><field name=\"NUM\">0.5</field></block></value></block></statement><next><block type=\"procedures_callnoreturn\" id=\"k`=DiML{Ev{}a{|`u#r^\"><mutation name=\"Scodinzola\"></mutation><next><block type=\"procedures_callnoreturn\" id=\":ye0=GgRvJ|3|S7-:50(\"><mutation name=\"Evita_Ostacoli\"></mutation><next><block type=\"procedures_callnoreturn\" id=\"`QMv)mRAiqx$_MAPiJ#(\"><mutation name=\"Patugliamento\"></mutation><next><block type=\"controls_if\" id=\"BlK3e^r83~^p3h*QJQB(\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"N`FCfoA4|6B]gmd@$Dno\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"9ryL2^n0LI=Njn!yDEHO\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"-FitrZK{v?e%Bl96c?t[\"><field name=\"NUM\">4</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"oE:q?4%-V6J,QS}AjzFy\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"VALUE\"><block type=\"math_number\" id=\"b775EElpGb*z4nrauX3b\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"`hI(00uN;R!C0:4FyTci\"><mutation name=\"Ritirata_e_fuga\"></mutation></block></next></block></statement><next><block type=\"controls_if\" id=\"?p]@;Dl*R1%(/PQ!=dWJ\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"@MV6{HWJdTLo1usYNV2W\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"G56lN%n(%*qfMbha3fjO\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"@]`ZuP~Ps,dfw9u7_/]~\"><field name=\"NUM\">8</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\")Q=MM=wJix8:e}3t!6p8\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"VALUE\"><block type=\"math_number\" id=\"x7=CztX|VrM#X=PCQA2[\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"DTy{!1~CoWr@ee?Sa;-@\"><mutation name=\"Giravolte\"></mutation></block></next></block></statement><next><block type=\"coderbot_sleep\" id=\"88T*(,r#Vj@:5zDE9tEO\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"42a6{m0y}CCt=]AHjj`6\"><field name=\"NUM\">5</field></block></value><next><block type=\"controls_if\" id=\"?5V^l6nIq)IysusCwzDR\"><value name=\"IF0\"><block type=\"logic_compare\" id=\",Fqr6N)B(p0}6{`5cj@!\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"pOVIS4*1q_5EkuSnmj5O\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"V_L}xISG;/(yv+LDAq?C\"><field name=\"NUM\">6</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"!rUQPht{;fn5,B39fxcB\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"VALUE\"><block type=\"math_number\" id=\"3KIWSuuWoCFaux|K`2GK\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"=}BrOn/{1I*_k%*4~pC+\"><mutation name=\"MarciaIndietro_e_Scarto\"></mutation></block></next></block></statement></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></statement></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block><block type=\"procedures_defnoreturn\" id=\"Wph:,`b9y/Qr@m#qVKh8\" x=\"105\" y=\"236\"><field name=\"NAME\">Giravolte</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"){(:UQ%yk$)1o1Pguk9S\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"c5hzzlx2+eA%touCb]1`\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"lydvF$Ej,y;~N7Po7)o*\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"]9^qO6wW.}1C+h$MbiDE\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"|HP$c2sw0L^tzXq-fLy(\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"#wD6$fKI/W:^T0,9*{8.\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"i*Zleg*v;rpIcG.i7(J:\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"]EVJ2A)5rU){Yqlll0@p\"><field name=\"NUM\">2</field></block></value><next><block type=\"coderbot_sleep\" id=\"d.86;#zvChlP=wxiRYK{\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"wHB]k#o@Np$i#8^9apv!\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"Rde:F#~+L06azq2tVyD-\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement></block><block type=\"procedures_defnoreturn\" id=\"#Lt]PDTBgL/]Mr,,RwFk\" x=\"31\" y=\"400\"><field name=\"NAME\">Patugliamento</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"zU:(eaKOX8bwg|@q)l/x\"><value name=\"TIMES\"><block type=\"math_number\" id=\"yzK?W9/:u/?TIb)n`E{l\"><field name=\"NUM\">3</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"%k|)9QK~_+#YJ[i]f(^|\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"~_wpvFs,tj:4ZSU!6cmI\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"!qKX^lFR%49P+$0r%N;6\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"W0F$EFUx8!vMe|8,m`e)\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"8TVs2lFlm;#yzBe6_g9]\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"YHo$W[}K#~s[ir9kNv)_\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"u)Hj]9kY}4_a.DRL@rG?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"y4w)^60I$wv3fB6T@Gbj\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"5Bfgw2kcW($A8vSHtir.\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"*!VdE}A-vb2YZ-a^p06D\"><field name=\"NUM\">0.5</field></shadow></value></block></next></block></statement></block></statement></block><block type=\"procedures_defnoreturn\" id=\"k).IYZ!#sHk(8noL0i@l\" x=\"-93\" y=\"642\"><field name=\"NAME\">Ritirata_e_fuga</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"[~BG$Oi=L4ZH@MEvOEtV\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"?RuLhTzie::^EqgHxS)x\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"{o8]MWs*L7Xm(10NerE`\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"%F|VO,DV~}UHb:@|C2p-\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"c[;21(SABvfs)G)|4x^Z\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"Lb_3Nu2HTBW9gtaA8D+`\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"yst;fA`Z%rps/:1!a:v?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"a_?(=WI*yG|Qw@p0#tcq\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"Pp)@[psXrpWB%/nL5}Vc\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"rEx#9(2@Z%N`|DnWh+an\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"o7B~om;.tZrb6@p)?EKY\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"PR|@J[;x$lCEM(4:.S(~\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"f)~FYQvG=f/)C9n|kusd\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"^O.!+5/K#K!T#OZds3gz\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"v|f3Q5~D0I.k*to]}=vH\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"~egc|sz;b2=r#9h;O:F/\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"qRJL!80G9IL_?@PGQV$r\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"pfLThV)s=gML_k3{I5jV\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"]}Uj)tHeUYGo]lc^$yL+\"><field name=\"NUM\">3</field></block></value><next><block type=\"coderbot_sleep\" id=\"=%5988mlKNB(RjC0Ua^d\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"E~M696!a~}o-oXq1E]3x\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\":.J$pq2!m5|F4+^*qXiF\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\",5-k}T[BoGUuJt=#q8y/\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"Gw-[#MNK.kb(Pk+@oyR}\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"$:{Ytk.}NMv*^1k:*j+d\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"gMg4F/eD[6_*An+0N#1Y\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"IGeI6gf.7_tJ;uxoau+V\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"^yf:cE[2SnCjF6M7rKU~\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"mTnh,E_(RE`3L)j2;|s3\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"l+Ck2grV#HM3.7N!xIzk\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"D|Zu+_W_#Hecykew]HjB\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"Y(D;RDGx-_?vUoP@{E|S\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"_J~jub1fQ$0.7h}aRX9#\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></next></block></next></block></statement></block><block type=\"procedures_defnoreturn\" id=\"C2,|x88yVW6)$C|.Z[fn\" x=\"869\" y=\"650\"><field name=\"NAME\">MarciaIndietro_e_Scarto</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"io(!A$V*Tw58pI}^6_YY\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\":[u[8j)-^u#O^k`vIU9L\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"q2_I$}9a~5hZ4}@#`$^_\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"Y.`7b`52G9cmcxW?%3wl\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"hCC*}yGz5:h}h6dMwS!y\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"|m-nKgik@#(Y#zPfqU=,\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"`v-dkUixI3E=wr_G(!Ps\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"rRihLI!yF)H~N-qDFQz`\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"f)]lI*iZwr2k$/-,OJ09\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"S#Y;lv?GQsDc7Za1uD^+\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"%~G.hJ0_bq{H8p(^LE-1\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"n[LcL!+Xt9y6roV{2Z*[\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"QS=:BWqYG)%$)mU78~kQ\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"3||`T0aFosR5VFJaXS#I\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"LsMIWEV,WsfUY5KF]PVY\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Q@KPVYLIp2/|i/R/4?EZ\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"XdKC2u$Zz`AzvrUT/3]z\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"wu#EubUV3Ic$jo)%{UzR\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"53`z:pDpu+~Sv3~`N-G~\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"!rX}?uvL2bjbK+8xT_QY\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"/2aHV}CkHtI*dAV{sSM/\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"BOQ!ur6NR+#^~sk}YB)D\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></statement></block></xml>","code":"from numbers import Number\n\nattesa = None\nvelocita_max = None\nvar_marciaIndietro = None\nvar_giravolte = None\nvar_ritirata = None\nvelocita = None\nstanco = None\n\n# Descrivi questa funzione...\ndef Scodinzola():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count in range(3):\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.3)\n get_bot().sleep(attesa)\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.3)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Evita_Ostacoli():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count2 in range(15):\n get_prog_eng().check_end()\n if get_bot().get_sonar_distance(0) < 20:\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n elif get_bot().get_sonar_distance(1) < 20:\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n elif get_bot().get_sonar_distance(2) < 20:\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n else:\n get_bot().forward(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Giravolte():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=2)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Patugliamento():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count3 in range(3):\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(0.5)\n\n# Descrivi questa funzione...\ndef Ritirata_e_fuga():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=3)\n get_bot().sleep(attesa)\n get_bot().forward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef MarciaIndietro_e_Scarto():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n\n\nattesa = 0.2\nvelocita_max = 80\nvar_marciaIndietro = 0\nvar_giravolte = 0\nvar_ritirata = 0\nstanco = 0\nvelocita = 1\nwhile True:\n get_prog_eng().check_end()\n stanco = (stanco if isinstance(stanco, Number) else 0) + 1\n var_marciaIndietro = (var_marciaIndietro if isinstance(var_marciaIndietro, Number) else 0) + 1\n var_giravolte = (var_giravolte if isinstance(var_giravolte, Number) else 0) + 1\n var_ritirata = (var_ritirata if isinstance(var_ritirata, Number) else 0) + 1\n if stanco == 5:\n stanco = 0\n velocita = 1\n elif stanco > 3:\n velocita = 0.5\n Scodinzola()\n Evita_Ostacoli()\n Patugliamento()\n if var_ritirata == 4:\n var_ritirata = 0\n Ritirata_e_fuga()\n if var_giravolte == 8:\n var_giravolte = 0\n Giravolte()\n get_bot().sleep(5)\n if var_marciaIndietro == 6:\n var_marciaIndietro = 0\n MarciaIndietro_e_Scarto()\n","default":""} \ No newline at end of file +{"id": "a3a01609-abb9-471b-b1fb-9cbb126d67c8", "name":"demo_roboetologist","dom_code":"<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</variable><variable id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</variable><variable id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</variable><variable id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</variable><variable id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</variable><variable id=\"}Amjkrp!.(7[D41[a^{6\">velocita</variable><variable id=\";M|:6*RIcl{fLp+^(S~p\">stanco</variable></variables><block type=\"procedures_defnoreturn\" id=\"!]5:R,96H,d*lP5TdKtv\" x=\"32\" y=\"-248\"><field name=\"NAME\">Scodinzola</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"$@148i!0XDrE)=/74E,F\"><value name=\"TIMES\"><block type=\"math_number\" id=\"Z|tRJT3et)`/%nF;x|BX\"><field name=\"NUM\">3</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"ICVMx1}4##d{B2;1_0yw\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"YOER#;}9h-EjO#NWK$-r\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"c)2=ZX:s9Pu=6_!gAznZ\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"OkO@z~w=AGqzQZu357hr\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"`1Tkh_x5G03,$gK8[7`W\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"6k^]W@IDw;E{I)B2[vF[\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"r3grvcve;,ycs9O{$Z(`\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"KIT-F0Ks@@7mYljTMX}a\"><field name=\"NUM\">0.3</field></block></value><next><block type=\"coderbot_sleep\" id=\"8HSK*.y3si%z:5X:X}Cf\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"_JMB)UTj(N=+rh}WJ1gM\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"I!%c5zbo7`I8H8pPUGmi\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"=G4VJm2R._wOHz%QTKGH\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"sE)S[)9b8GYNM/}A?Q?a\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"th7m{buvj!fXr2[L}rdj\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"tD5onaW9m}8|$[!eMBlT\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"UI8*HDp}`l@z/mNCX#%h\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"?;j;(@*sHEBLK;FT9Snq\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"xm4O$9/uD/DtLEFUuc:H\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"C.gRCR/O:%1W,h%jxJQz\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"P@A2tlSC:EM}cZ{1qJOm\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"4^Vbi3$0bgFj([_q#a)!\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"gfVNt(aQi}BuKUSFJ.3:\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"s@*_u8JqM`F^;vK{O*_0\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"obZReNmla70EZtJwNI$8\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"IEU%gc|cb25NDN1pDPM*\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"{*bj!1W#x3tx!SeWj:kT\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"DaVdvC(WkUw{D:y*?4F6\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\".$SS=6=p56*%bV+0d!UP\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"~~F31]H,M#iZIBu-hpHt\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"S6tUIN@%q%t{Hz2ddE-{\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\".dOMH{.fxW#:}@%b#)JX\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"ZGo9-9/V=n8K.l-Ukk@h\"><field name=\"NUM\">0.3</field></block></value><next><block type=\"coderbot_sleep\" id=\"NK1usFSpUZ,JP33u=3#d\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"?f-Y1{[eyW,FRqS=Wjo$\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"]yMj3IsqdH!-7(8Cvk[U\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></next></block></next></block></statement></block></statement></block><block type=\"procedures_defnoreturn\" id=\"eAhV_z+X]idI9Y2#)$n(\" x=\"1037\" y=\"-296\"><field name=\"NAME\">Evita_Ostacoli</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"@c#NwB$D7537*F7m=!(7\"><value name=\"TIMES\"><shadow type=\"math_number\" id=\"YMSS!*wG*F@i;BhUmTE`\"><field name=\"NUM\">15</field></shadow></value><statement name=\"DO\"><block type=\"controls_if\" id=\"X*#hoa)#P0K0YxbKTgIs\"><mutation elseif=\"2\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"Otlt5#y}Bm[e5ta5;YxY\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"ssLQq~!Drc._YB6B-d3S\"><field name=\"SONAR\">0</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"eH-VJ17iCGoZyj+UEq:}\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"trpdU@xT,u;^uH#kGc;f\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"HcmX([S/=AKRH4R8$I0B\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"/rWP6rW9R]E3-naWqgJb\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\".t[s{j8IX2vxW-3BN:mY\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Fb`JpvO.k6Tc7[f,$O$v\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"$l?U4w3[2%qk..:nTePo\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"8Ifz1evG3eDtpQLtQGl9\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"iS!-;G+snS)ML@1l1*P%\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"/vCSdFhWoJq}Z~+GZv@B\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"x)rjS0}jg(awX7.?Vw6}\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"nkX`O8.7pQ/nRXu}}SJ=\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"lzJKDW53E#N;!A;c=C@_\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"PA|Q|jw0.1~mrO$9Q%P;\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"G|iI)YzX$qKo3I+17OnJ\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"I.S?k*]?]8:ux2At*LJ1\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"CXKnQkB)^Mp8+FB%/Kq}\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"Xe+Rt?_8u.vO?W@ZWs2-\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"j4=;9]Ka!u+7?MAJPGh?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"YTc?Tsq{XFq({Kc.X:l2\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"~D0glLe($lFOxGCVt({`\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"k=7sJ/UX#,{!dlpX;H`6\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"6%wD3wHrc$f(?}Bq)28s\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"i374]E^am-M6uyS?-gKC\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"Xp?Z4ev2ys-O`aN-$WNL\"><field name=\"SONAR\">1</field></block></value><value name=\"B\"><block type=\"math_number\" id=\",2c5e_Y3:j:T[liXjo{l\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"Am`s@r3LgvQtrS1TL57q\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"~prj;Zl(AJ|,`oeCCf-,\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"DcI1#yBE~@moiU6YAv#x\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"j`G2K]gZRIV)]2.7dzG9\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"]wDU`;H3W8![o1a2fzk1\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"3/hwsno_gvMwqLT_mgV!\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"/5eh,CVTRpqcb/s5{R5H\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"8t@}mCD~^YNfqoRxQJl%\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"]/3=*vM9ken$o-O1f~fV\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"*SfrgoD6pBdYTZcV!|0b\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"WPe.SW;HHIq|eAB`,BJ`\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement><value name=\"IF2\"><block type=\"logic_compare\" id=\"Oi)HJ7[XQLUo?9Ja,p{i\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"coderbot_sonar_get_distance\" id=\"VX/j*WrI[j^f/|ei-f:(\"><field name=\"SONAR\">2</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"J=/3jvhaq=%R42539s$D\"><field name=\"NUM\">20</field></block></value></block></value><statement name=\"DO2\"><block type=\"coderbot_adv_move\" id=\"Yw+`{06m}q=Xy[hpZc--\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"/^l1V(M*RdBL=xaqy1tq\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"m_d8qZ${$Q]1dgRC9kg1\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"P1aDE;avAT65i|PhY=-2\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"rv=.e$[u+4J|wpmE!WWc\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"=72b0Fu=xSqlre+0P==V\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\",=w/soAS//gtuY7.MR1L\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"HM%|wVB7+V~p-IL[*AR^\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"yJFCwyQPE5=?0r/~vamL\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"5W!KOp9GS.b=}L5otZuU\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"^omY,%{F`GV!pDo}yZrv\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\":l(I1S51$*1Y1BPm^@/w\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"SHq.(.XcZ}7M,l8RC_c@\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"w7#zA8o]]XpeNtS=VD-:\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"J9Igw@@/VH.K__Yl)@~p\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Uo@*[cy$0q1dgsf#Q^z-\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"tb~[WgJ9A+?zO!3y}p;U\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"`}JdE]gqQ@ZY1w]uW%5C\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"GHLs)siSUy|OQqqr3dIo\"><field name=\"NUM\">0.5</field></block></value><next><block type=\"coderbot_sleep\" id=\"LcaW`EM+]Jb=X?I[;JSB\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"`tVVItwfg.HfaD1gzB=:\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"aBw0-LWH!FA$beTy(Zhv\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement></block></statement></block></statement></block><block type=\"variables_set\" id=\"i9a!EM@s`-6hUdv$sr@3\" x=\"-546\" y=\"-188\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field><value name=\"VALUE\"><block type=\"math_number\" id=\"^=8DhFn=]2Efwc(|OkiD\"><field name=\"NUM\">0.2</field></block></value><next><block type=\"variables_set\" id=\"zjzJg@NAQU,k/!!@n5,*\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field><value name=\"VALUE\"><block type=\"math_number\" id=\"nDs=tH{gKK+fBi0-bA/_\"><field name=\"NUM\">80</field></block></value><next><block type=\"variables_set\" id=\"uD3I^ll~9L#obOA^SI!0\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"VALUE\"><block type=\"math_number\" id=\"~G:^Vj.oE0(OO]ZP3Vcn\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"Obn8q0fElL9mB(i|1]5[\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"VALUE\"><block type=\"math_number\" id=\"H!=muFCqUw/I?)IGAUt|\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"I/mn7F@$p-}4[H4_SBqY\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"VALUE\"><block type=\"math_number\" id=\"*azH8=DJtBx-pQwu4|V6\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"tEC)Up7J)~4{(Dz1[lCj\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"VALUE\"><block type=\"math_number\" id=\"E%Tw$~W4?sv.fNIxv0Ma\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"x4jFKBKS^fdsk#T.U7Z!\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"6ZiB~3h3aO3z5)_kg[zG\"><field name=\"NUM\">1</field></block></value><next><block type=\"controls_whileUntil\" id=\"-yfR%N=ZA:dr/vf[$_Y+\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"H@,=TqL*XM3|6M}Z:3+C\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"math_change\" id=\"1%fq4KBED@gkjP~jlRMk\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"DELTA\"><block type=\"math_number\" id=\";S+Wfd9n5g26eOE9EngY\"><field name=\"NUM\">1</field></block></value><next><block type=\"math_change\" id=\"f-`F7YcK2uSF1[N^tPM{\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"{gD@*ayDq5d6tMw(2Kbc\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"math_change\" id=\"dS?rG_[64b{_2vBnB^QM\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"dkbf0gA|c8o0Cm=!@gQT\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"math_change\" id=\"`)S8h1qAw*?jy*ixY}u+\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"DELTA\"><shadow type=\"math_number\" id=\"1L=-j:W;2d`s1`:q.su~\"><field name=\"NUM\">1</field></shadow></value><next><block type=\"controls_if\" id=\"S!3#D%1@0YM^;{sm}Q.k\"><mutation elseif=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"/dnfv--t9_A=(06arGX$\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"/}JP!cseKId$umH4~#!d\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"9WL24mxLME}qFQWRype$\"><field name=\"NUM\">5</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"~_/s2uIq9S6k56j~CVA#\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field><value name=\"VALUE\"><block type=\"math_number\" id=\"YjfWxc5Q+w#]Da0z;@@s\"><field name=\"NUM\">0</field></block></value><next><block type=\"variables_set\" id=\"@Z/po(O(J`O{*FUL?#%K\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"jmeKZm8wIKG-As_[L%t4\"><field name=\"NUM\">1</field></block></value></block></next></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"E@jRA2fJ},Gr}awmmspH\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"|RNUw6)n!:kvhSz]2of^\"><field name=\"VAR\" id=\";M|:6*RIcl{fLp+^(S~p\">stanco</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"Q@W~I[!UTRLrFCi:+4D4\"><field name=\"NUM\">3</field></block></value></block></value><statement name=\"DO1\"><block type=\"variables_set\" id=\"TX2klHO#QS96(-b;oxdw\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field><value name=\"VALUE\"><block type=\"math_number\" id=\"}5,MJoA8{Gp/tD?@oBQq\"><field name=\"NUM\">0.5</field></block></value></block></statement><next><block type=\"procedures_callnoreturn\" id=\"k`=DiML{Ev{}a{|`u#r^\"><mutation name=\"Scodinzola\"></mutation><next><block type=\"procedures_callnoreturn\" id=\":ye0=GgRvJ|3|S7-:50(\"><mutation name=\"Evita_Ostacoli\"></mutation><next><block type=\"procedures_callnoreturn\" id=\"`QMv)mRAiqx$_MAPiJ#(\"><mutation name=\"Patugliamento\"></mutation><next><block type=\"controls_if\" id=\"BlK3e^r83~^p3h*QJQB(\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"N`FCfoA4|6B]gmd@$Dno\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"9ryL2^n0LI=Njn!yDEHO\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"-FitrZK{v?e%Bl96c?t[\"><field name=\"NUM\">4</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"oE:q?4%-V6J,QS}AjzFy\"><field name=\"VAR\" id=\"]o~;Yi%sgc~I2zpMw@#p\">var_ritirata</field><value name=\"VALUE\"><block type=\"math_number\" id=\"b775EElpGb*z4nrauX3b\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"`hI(00uN;R!C0:4FyTci\"><mutation name=\"Ritirata_e_fuga\"></mutation></block></next></block></statement><next><block type=\"controls_if\" id=\"?p]@;Dl*R1%(/PQ!=dWJ\"><value name=\"IF0\"><block type=\"logic_compare\" id=\"@MV6{HWJdTLo1usYNV2W\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"G56lN%n(%*qfMbha3fjO\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"@]`ZuP~Ps,dfw9u7_/]~\"><field name=\"NUM\">8</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\")Q=MM=wJix8:e}3t!6p8\"><field name=\"VAR\" id=\"k0;Q7iBn,I9wGXMH?}Do\">var_giravolte</field><value name=\"VALUE\"><block type=\"math_number\" id=\"x7=CztX|VrM#X=PCQA2[\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"DTy{!1~CoWr@ee?Sa;-@\"><mutation name=\"Giravolte\"></mutation></block></next></block></statement><next><block type=\"coderbot_sleep\" id=\"88T*(,r#Vj@:5zDE9tEO\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"42a6{m0y}CCt=]AHjj`6\"><field name=\"NUM\">5</field></block></value><next><block type=\"controls_if\" id=\"?5V^l6nIq)IysusCwzDR\"><value name=\"IF0\"><block type=\"logic_compare\" id=\",Fqr6N)B(p0}6{`5cj@!\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\" id=\"pOVIS4*1q_5EkuSnmj5O\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"V_L}xISG;/(yv+LDAq?C\"><field name=\"NUM\">6</field></block></value></block></value><statement name=\"DO0\"><block type=\"variables_set\" id=\"!rUQPht{;fn5,B39fxcB\"><field name=\"VAR\" id=\"8|Zzym8yh{-PoN!=cEIq\">var_marciaIndietro</field><value name=\"VALUE\"><block type=\"math_number\" id=\"3KIWSuuWoCFaux|K`2GK\"><field name=\"NUM\">0</field></block></value><next><block type=\"procedures_callnoreturn\" id=\"=}BrOn/{1I*_k%*4~pC+\"><mutation name=\"MarciaIndietro_e_Scarto\"></mutation></block></next></block></statement></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></statement></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block><block type=\"procedures_defnoreturn\" id=\"Wph:,`b9y/Qr@m#qVKh8\" x=\"105\" y=\"236\"><field name=\"NAME\">Giravolte</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"){(:UQ%yk$)1o1Pguk9S\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"c5hzzlx2+eA%touCb]1`\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"lydvF$Ej,y;~N7Po7)o*\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"]9^qO6wW.}1C+h$MbiDE\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"|HP$c2sw0L^tzXq-fLy(\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"#wD6$fKI/W:^T0,9*{8.\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"i*Zleg*v;rpIcG.i7(J:\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"]EVJ2A)5rU){Yqlll0@p\"><field name=\"NUM\">2</field></block></value><next><block type=\"coderbot_sleep\" id=\"d.86;#zvChlP=wxiRYK{\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"wHB]k#o@Np$i#8^9apv!\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"Rde:F#~+L06azq2tVyD-\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></statement></block><block type=\"procedures_defnoreturn\" id=\"#Lt]PDTBgL/]Mr,,RwFk\" x=\"31\" y=\"400\"><field name=\"NAME\">Patugliamento</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"controls_repeat_ext\" id=\"zU:(eaKOX8bwg|@q)l/x\"><value name=\"TIMES\"><block type=\"math_number\" id=\"yzK?W9/:u/?TIb)n`E{l\"><field name=\"NUM\">3</field></block></value><statement name=\"DO\"><block type=\"coderbot_adv_move\" id=\"%k|)9QK~_+#YJ[i]f(^|\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"~_wpvFs,tj:4ZSU!6cmI\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"!qKX^lFR%49P+$0r%N;6\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"W0F$EFUx8!vMe|8,m`e)\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"8TVs2lFlm;#yzBe6_g9]\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"YHo$W[}K#~s[ir9kNv)_\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"u)Hj]9kY}4_a.DRL@rG?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"y4w)^60I$wv3fB6T@Gbj\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"5Bfgw2kcW($A8vSHtir.\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"*!VdE}A-vb2YZ-a^p06D\"><field name=\"NUM\">0.5</field></shadow></value></block></next></block></statement></block></statement></block><block type=\"procedures_defnoreturn\" id=\"k).IYZ!#sHk(8noL0i@l\" x=\"-93\" y=\"642\"><field name=\"NAME\">Ritirata_e_fuga</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"[~BG$Oi=L4ZH@MEvOEtV\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"?RuLhTzie::^EqgHxS)x\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"{o8]MWs*L7Xm(10NerE`\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"%F|VO,DV~}UHb:@|C2p-\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"c[;21(SABvfs)G)|4x^Z\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"Lb_3Nu2HTBW9gtaA8D+`\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"yst;fA`Z%rps/:1!a:v?\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"a_?(=WI*yG|Qw@p0#tcq\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"Pp)@[psXrpWB%/nL5}Vc\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"rEx#9(2@Z%N`|DnWh+an\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"o7B~om;.tZrb6@p)?EKY\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"PR|@J[;x$lCEM(4:.S(~\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"f)~FYQvG=f/)C9n|kusd\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"^O.!+5/K#K!T#OZds3gz\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"v|f3Q5~D0I.k*to]}=vH\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"~egc|sz;b2=r#9h;O:F/\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"qRJL!80G9IL_?@PGQV$r\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"pfLThV)s=gML_k3{I5jV\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"]}Uj)tHeUYGo]lc^$yL+\"><field name=\"NUM\">3</field></block></value><next><block type=\"coderbot_sleep\" id=\"=%5988mlKNB(RjC0Ua^d\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"E~M696!a~}o-oXq1E]3x\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\":.J$pq2!m5|F4+^*qXiF\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\",5-k}T[BoGUuJt=#q8y/\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"Gw-[#MNK.kb(Pk+@oyR}\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"$:{Ytk.}NMv*^1k:*j+d\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"gMg4F/eD[6_*An+0N#1Y\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"IGeI6gf.7_tJ;uxoau+V\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"^yf:cE[2SnCjF6M7rKU~\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"mTnh,E_(RE`3L)j2;|s3\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"l+Ck2grV#HM3.7N!xIzk\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"D|Zu+_W_#Hecykew]HjB\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"Y(D;RDGx-_?vUoP@{E|S\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"_J~jub1fQ$0.7h}aRX9#\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></next></block></next></block></statement></block><block type=\"procedures_defnoreturn\" id=\"C2,|x88yVW6)$C|.Z[fn\" x=\"869\" y=\"650\"><field name=\"NAME\">MarciaIndietro_e_Scarto</field><comment pinned=\"false\" h=\"80\" w=\"160\">Descrivi questa funzione...</comment><statement name=\"STACK\"><block type=\"coderbot_adv_move\" id=\"io(!A$V*Tw58pI}^6_YY\"><field name=\"ACTION\">BACKWARD</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\":[u[8j)-^u#O^k`vIU9L\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"q2_I$}9a~5hZ4}@#`$^_\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"Y.`7b`52G9cmcxW?%3wl\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"hCC*}yGz5:h}h6dMwS!y\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"|m-nKgik@#(Y#zPfqU=,\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"`v-dkUixI3E=wr_G(!Ps\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"rRihLI!yF)H~N-qDFQz`\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"f)]lI*iZwr2k$/-,OJ09\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"S#Y;lv?GQsDc7Za1uD^+\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"%~G.hJ0_bq{H8p(^LE-1\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value><next><block type=\"coderbot_adv_move\" id=\"n[LcL!+Xt9y6roV{2Z*[\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_constrain\" id=\"QS=:BWqYG)%$)mU78~kQ\"><value name=\"VALUE\"><shadow type=\"math_number\" id=\"!LaIzDe9hM33v4k~rW;R\"><field name=\"NUM\">50</field></shadow><block type=\"math_arithmetic\" id=\"3||`T0aFosR5VFJaXS#I\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"math_number\" id=\"LsMIWEV,WsfUY5KF]PVY\"><field name=\"NUM\">100</field></block></value><value name=\"B\"><block type=\"variables_get\" id=\"Q@KPVYLIp2/|i/R/4?EZ\"><field name=\"VAR\" id=\"}Amjkrp!.(7[D41[a^{6\">velocita</field></block></value></block></value><value name=\"LOW\"><shadow type=\"math_number\" id=\"XdKC2u$Zz`AzvrUT/3]z\"><field name=\"NUM\">1</field></shadow></value><value name=\"HIGH\"><shadow type=\"math_number\" id=\"khuxM7iyFn8#/XPdIM6(\"><field name=\"NUM\">100</field></shadow><block type=\"variables_get\" id=\"wu#EubUV3Ic$jo)%{UzR\"><field name=\"VAR\" id=\"pnH_=,ZT2cUsaU7OS+#X\">velocita_max</field></block></value></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"53`z:pDpu+~Sv3~`N-G~\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_sleep\" id=\"!rX}?uvL2bjbK+8xT_QY\"><value name=\"ELAPSE\"><shadow type=\"math_number\" id=\"/2aHV}CkHtI*dAV{sSM/\"><field name=\"NUM\">0.2</field></shadow><block type=\"variables_get\" id=\"BOQ!ur6NR+#^~sk}YB)D\"><field name=\"VAR\" id=\"%dU@,Fu?J~t%QJ,78`Md\">attesa</field></block></value></block></next></block></next></block></next></block></statement></block></xml>","code":"from numbers import Number\n\nattesa = None\nvelocita_max = None\nvar_marciaIndietro = None\nvar_giravolte = None\nvar_ritirata = None\nvelocita = None\nstanco = None\n\n# Descrivi questa funzione...\ndef Scodinzola():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count in range(3):\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.3)\n get_bot().sleep(attesa)\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.3)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Evita_Ostacoli():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count2 in range(15):\n get_prog_eng().check_end()\n if get_bot().get_sonar_distance(0) < 20:\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n elif get_bot().get_sonar_distance(1) < 20:\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n elif get_bot().get_sonar_distance(2) < 20:\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n else:\n get_bot().forward(speed=min(max(100 * velocita, 1), velocita_max), elapse=0.5)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Giravolte():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=2)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef Patugliamento():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n for count3 in range(3):\n get_prog_eng().check_end()\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(0.5)\n\n# Descrivi questa funzione...\ndef Ritirata_e_fuga():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n get_bot().left(speed=min(max(100 * velocita, 1), velocita_max), elapse=3)\n get_bot().sleep(attesa)\n get_bot().forward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n\n# Descrivi questa funzione...\ndef MarciaIndietro_e_Scarto():\n global attesa, velocita_max, var_marciaIndietro, var_giravolte, var_ritirata, velocita, stanco\n get_prog_eng().check_end()\n get_bot().backward(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n get_bot().right(speed=min(max(100 * velocita, 1), velocita_max), elapse=1)\n get_bot().sleep(attesa)\n\n\nattesa = 0.2\nvelocita_max = 80\nvar_marciaIndietro = 0\nvar_giravolte = 0\nvar_ritirata = 0\nstanco = 0\nvelocita = 1\nwhile True:\n get_prog_eng().check_end()\n stanco = (stanco if isinstance(stanco, Number) else 0) + 1\n var_marciaIndietro = (var_marciaIndietro if isinstance(var_marciaIndietro, Number) else 0) + 1\n var_giravolte = (var_giravolte if isinstance(var_giravolte, Number) else 0) + 1\n var_ritirata = (var_ritirata if isinstance(var_ritirata, Number) else 0) + 1\n if stanco == 5:\n stanco = 0\n velocita = 1\n elif stanco > 3:\n velocita = 0.5\n Scodinzola()\n Evita_Ostacoli()\n Patugliamento()\n if var_ritirata == 4:\n var_ritirata = 0\n Ritirata_e_fuga()\n if var_giravolte == 8:\n var_giravolte = 0\n Giravolte()\n get_bot().sleep(5)\n if var_marciaIndietro == 6:\n var_marciaIndietro = 0\n MarciaIndietro_e_Scarto()\n","default":""} \ No newline at end of file diff --git a/defaults/programs/program_demo_sound_clap_control.json b/defaults/programs/program_demo_sound_clap_control.json index a735de15..c42d2efd 100644 --- a/defaults/programs/program_demo_sound_clap_control.json +++ b/defaults/programs/program_demo_sound_clap_control.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"-43\" y=\"126\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">noise</field><value name=\"VALUE\"><block type=\"coderbot_audio_hear\"><value name=\"LEVEL\"><block type=\"math_number\"><field name=\"NUM\">1000</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.2</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"variables_get\"><field name=\"VAR\">noise</field></block></value><next><block type=\"controls_if\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">noise</field></block></value><value name=\"B\"><block type=\"logic_boolean\"><field name=\"BOOL\">FALSE</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">-1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.5</field></block></value></block></statement></block></next></block></next></block></statement><next><block type=\"coderbot_adv_stop\"></block></next></block></xml>", "code": "noise = None\n\n\nwhile True:\n get_prog_eng().check_end()\n noise = get_audio().hear(level=1000, elapse=0.2)\n get_cam().set_text(noise)\n if noise == False:\n get_bot().forward(speed=100, elapse=-1)\n else:\n get_bot().right(speed=100, elapse=0.5)\nget_bot().stop()\n", "name": "demo_sound_clap_control"} \ No newline at end of file +{"id": "e4dada78-915e-4916-931a-e96f754812c4", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"-43\" y=\"126\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">noise</field><value name=\"VALUE\"><block type=\"coderbot_audio_hear\"><value name=\"LEVEL\"><block type=\"math_number\"><field name=\"NUM\">1000</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.2</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"variables_get\"><field name=\"VAR\">noise</field></block></value><next><block type=\"controls_if\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\"><field name=\"OP\">EQ</field><value name=\"A\"><block type=\"variables_get\"><field name=\"VAR\">noise</field></block></value><value name=\"B\"><block type=\"logic_boolean\"><field name=\"BOOL\">FALSE</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">-1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">0.5</field></block></value></block></statement></block></next></block></next></block></statement><next><block type=\"coderbot_adv_stop\"></block></next></block></xml>", "code": "noise = None\n\n\nwhile True:\n get_prog_eng().check_end()\n noise = get_audio().hear(level=1000, elapse=0.2)\n get_cam().set_text(noise)\n if noise == False:\n get_bot().forward(speed=100, elapse=-1)\n else:\n get_bot().right(speed=100, elapse=0.5)\nget_bot().stop()\n", "name": "demo_sound_clap_control"} \ No newline at end of file diff --git a/defaults/programs/program_test_cnn_classifier.json b/defaults/programs/program_test_cnn_classifier.json index e79a8329..ac8cbdc2 100644 --- a/defaults/programs/program_test_cnn_classifier.json +++ b/defaults/programs/program_test_cnn_classifier.json @@ -1 +1 @@ -{"name": "test_cnn_classifier", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"controls_whileUntil\" id=\"[^a!+/Zsc!iXdJ*Z-Go#\" x=\"18\" y=\"118\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"2Qi5#s+x(vg-{l2glVGI\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"PAYJ[1S)`0Gl#=M`cX=g\"><value name=\"TEXT\"><block type=\"coderbot_adv_cnn_classify\" id=\"RIid_M~T~h6a}xySf%7I\"><field name=\"MODEL\">generic_fast_low</field></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().cnn_classify(\"generic_fast_low\"))\n"} \ No newline at end of file +{"id": "4b19dbc7-55a8-4888-9e2e-e05a0e65d29e", "name": "test_cnn_classifier", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"controls_whileUntil\" id=\"[^a!+/Zsc!iXdJ*Z-Go#\" x=\"18\" y=\"118\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"2Qi5#s+x(vg-{l2glVGI\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"PAYJ[1S)`0Gl#=M`cX=g\"><value name=\"TEXT\"><block type=\"coderbot_adv_cnn_classify\" id=\"RIid_M~T~h6a}xySf%7I\"><field name=\"MODEL\">generic_fast_low</field></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().cnn_classify(\"generic_fast_low\"))\n"} \ No newline at end of file diff --git a/defaults/programs/program_test_cnn_object_detect.json b/defaults/programs/program_test_cnn_object_detect.json index 9723235d..f7e994bd 100644 --- a/defaults/programs/program_test_cnn_object_detect.json +++ b/defaults/programs/program_test_cnn_object_detect.json @@ -1 +1 @@ -{"name": "test_cnn_object_detect", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"controls_whileUntil\" id=\"[^a!+/Zsc!iXdJ*Z-Go#\" x=\"18\" y=\"118\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"2Qi5#s+x(vg-{l2glVGI\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"PAYJ[1S)`0Gl#=M`cX=g\"><value name=\"TEXT\"><block type=\"coderbot_adv_cnn_detect_objects\" id=\"m(x+AUHK}k[f:xAb;!iH\"><field name=\"MODEL\">generic_object_detect</field></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().cnn_detect_objects(\"generic_object_detect\"))\n"} \ No newline at end of file +{"id": "9622b72c-c7d4-4643-9c76-3148f16572a7", "name": "test_cnn_object_detect", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"controls_whileUntil\" id=\"[^a!+/Zsc!iXdJ*Z-Go#\" x=\"18\" y=\"118\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"2Qi5#s+x(vg-{l2glVGI\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"PAYJ[1S)`0Gl#=M`cX=g\"><value name=\"TEXT\"><block type=\"coderbot_adv_cnn_detect_objects\" id=\"m(x+AUHK}k[f:xAb;!iH\"><field name=\"MODEL\">generic_object_detect</field></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().cnn_detect_objects(\"generic_object_detect\"))\n"} \ No newline at end of file diff --git a/defaults/programs/program_test_find_code.json b/defaults/programs/program_test_find_code.json index 37b1b610..346a4b04 100644 --- a/defaults/programs/program_test_find_code.json +++ b/defaults/programs/program_test_find_code.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables></variables><block type=\"controls_whileUntil\" id=\"0Mx[mSKoV~Gk1qbv5Wrn\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"q8(wB97}Y)d71cgy$yo#\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"0fGi]QOF@I*b$5x^?f#A\"><value name=\"TEXT\"><block type=\"coderbot_adv_findQRCode\" id=\"zG.;=ZyX~k=YR$T(6JF*\"></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().find_qr_code())\n", "name": "test_find_code"} \ No newline at end of file +{"id": "6cc16350-c47c-4e02-b442-be3fa7ce5942", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables></variables><block type=\"controls_whileUntil\" id=\"0Mx[mSKoV~Gk1qbv5Wrn\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"q8(wB97}Y)d71cgy$yo#\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"0fGi]QOF@I*b$5x^?f#A\"><value name=\"TEXT\"><block type=\"coderbot_adv_findQRCode\" id=\"zG.;=ZyX~k=YR$T(6JF*\"></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().find_qr_code())\n", "name": "test_find_code"} \ No newline at end of file diff --git a/defaults/programs/program_test_find_color.json b/defaults/programs/program_test_find_color.json index 293735b1..9cd9e0ee 100644 --- a/defaults/programs/program_test_find_color.json +++ b/defaults/programs/program_test_find_color.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"1\" y=\"90\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">dist</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">DIST</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"variables_set\"><field name=\"VAR\">angle</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">ANGLE</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"text_join\"><mutation items=\"4\"></mutation><value name=\"ADD0\"><block type=\"text\"><field name=\"TEXT\">Distance: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"ADD2\"><block type=\"text\"><field name=\"TEXT\"> angle: </field></block></value><value name=\"ADD3\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value></block></value></block></next></block></next></block></statement></block></xml>", "code": "dist = None\nangle = None\n\n\nwhile True:\n get_prog_eng().check_end()\n dist = get_cam().find_color('#96b73c')[0]\n angle = get_cam().find_color('#96b73c')[1]\n get_cam().set_text(''.join([str(temp_value) for temp_value in ['Distance: ', dist, ' angle: ', angle]]))\n", "name": "test_find_color"} \ No newline at end of file +{"id": "9fb15bbd-97a6-490f-89c9-67a1ae0f1598", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"1\" y=\"90\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\"><field name=\"VAR\">dist</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">DIST</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"variables_set\"><field name=\"VAR\">angle</field><value name=\"VALUE\"><block type=\"coderbot_adv_findColor\"><field name=\"RETVAL\">ANGLE</field><value name=\"COLOR\"><block type=\"text\"><field name=\"TEXT\">#96b73c</field></block></value></block></value><next><block type=\"text_print\"><value name=\"TEXT\"><block type=\"text_join\"><mutation items=\"4\"></mutation><value name=\"ADD0\"><block type=\"text\"><field name=\"TEXT\">Distance: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\"><field name=\"VAR\">dist</field></block></value><value name=\"ADD2\"><block type=\"text\"><field name=\"TEXT\"> angle: </field></block></value><value name=\"ADD3\"><block type=\"variables_get\"><field name=\"VAR\">angle</field></block></value></block></value></block></next></block></next></block></statement></block></xml>", "code": "dist = None\nangle = None\n\n\nwhile True:\n get_prog_eng().check_end()\n dist = get_cam().find_color('#96b73c')[0]\n angle = get_cam().find_color('#96b73c')[1]\n get_cam().set_text(''.join([str(temp_value) for temp_value in ['Distance: ', dist, ' angle: ', angle]]))\n", "name": "test_find_color"} \ No newline at end of file diff --git a/defaults/programs/program_test_find_face.json b/defaults/programs/program_test_find_face.json index 4320243b..44008f5f 100644 --- a/defaults/programs/program_test_find_face.json +++ b/defaults/programs/program_test_find_face.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"G`ooSD^IjFl@q`VRXz`M\">face</variable><variable type=\"\" id=\"JU]w:x,u6R_]KGB{:XP:\">face_x</variable><variable type=\"\" id=\"YdZ|nz8=@UwR53L{5(Te\">face_size</variable></variables><block type=\"controls_whileUntil\" id=\"CoP0+krwBNk-W]8d*90A\" x=\"32\" y=\"26\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"fi_0^7$bm]/5xQ|Zpg=(\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"f$?dr|af|Ac.xwmgSA%J\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field><value name=\"VALUE\"><block type=\"coderbot_adv_findFace\" id=\"H`#u_,_?;x,73RZ}}gR{\"><field name=\"RETVAL\">ALL</field></block></value><next><block type=\"variables_set\" id=\"{o9)u+=V]D]h(5aygd~M\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"dAqQ+k+Lsv!1N7zj4(4^\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"65Q5x52oC~jam{#uHnFe\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"^aod?Rq):AVnd02Or|!L\"><field name=\"NUM\">1</field></block></value></block></value><next><block type=\"variables_set\" id=\"I{^(8GT:UL9{7jdNlg[w\"><field name=\"VAR\" id=\"YdZ|nz8=@UwR53L{5(Te\" variabletype=\"\">face_size</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"2}fQ04Qws48,xb!?z1pW\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"hmZQMGjZ94)AhuZ6JUYa\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"=LbR3.00CDs*hnk()Y^-\"><field name=\"NUM\">2</field></block></value></block></value><next><block type=\"text_print\" id=\"O}.LG0(E@nzN,p;l%v2{\"><value name=\"TEXT\"><block type=\"text_join\" id=\"mRJtt8foB.;Gpq0fM,4D\"><mutation items=\"2\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\",=O:[=q5SBb`1$S,-R,:\"><field name=\"TEXT\">face: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\" id=\"UEwJl:.puwUq)R!zo@Z7\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value></block></value><next><block type=\"controls_if\" id=\"9tGk|M6u455Nu1(SI}{K\"><value name=\"IF0\"><block type=\"variables_get\" id=\"9}[hrA3rOFo0n+BAsX-f\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\"1-%~}MODhI#*$?^aB_tS\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"`rz$_58rWb#ufStSd](T\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\"O}zML^tGL7t3C*mWsEMo\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"gdx{O}:M_*b|FpvgG_~h\"><field name=\"NUM\">-10</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"@[^uw~TU^Vti#)6HZC?K\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"vt6%MV@vkT*tB]%2:7vQ\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"d3[F3QtIG#jb=1IPOem)\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"/zef{/F+:n[eI1@+MIKR\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"dh8opiswQU13wjT![yV[\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"2RVlzW2}AG#ywuHP6N=+\"><field name=\"NUM\">10</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"4`Z7%j+MV5(5,BM!RRBA\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"v`ab`#qs7J5]2XaOp]s[\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"A_y%A@DITmnWACnr0]zK\"><field name=\"NUM\">0.1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_stop\" id=\"B/$XZ_Giuo_h#Q?JM{w}\"></block></statement></block></statement></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "face = None\nface_x = None\nface_size = None\n\n\nwhile True:\n get_prog_eng().check_end()\n face = get_cam().find_face()\n face_x = face[0]\n face_size = face[1]\n get_cam().set_text(str('face: ') + str(face_x))\n if face_x:\n if face_x < -10:\n get_bot().left(speed=80, elapse=0.1)\n elif face_x > 10:\n get_bot().right(speed=80, elapse=0.1)\n else:\n get_bot().stop()\n", "name": "test_find_face"} \ No newline at end of file +{"id": "504eb5f8-650f-4385-8cb4-d30ea09c9ef7", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\"G`ooSD^IjFl@q`VRXz`M\">face</variable><variable type=\"\" id=\"JU]w:x,u6R_]KGB{:XP:\">face_x</variable><variable type=\"\" id=\"YdZ|nz8=@UwR53L{5(Te\">face_size</variable></variables><block type=\"controls_whileUntil\" id=\"CoP0+krwBNk-W]8d*90A\" x=\"32\" y=\"26\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"fi_0^7$bm]/5xQ|Zpg=(\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"f$?dr|af|Ac.xwmgSA%J\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field><value name=\"VALUE\"><block type=\"coderbot_adv_findFace\" id=\"H`#u_,_?;x,73RZ}}gR{\"><field name=\"RETVAL\">ALL</field></block></value><next><block type=\"variables_set\" id=\"{o9)u+=V]D]h(5aygd~M\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"dAqQ+k+Lsv!1N7zj4(4^\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"65Q5x52oC~jam{#uHnFe\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"^aod?Rq):AVnd02Or|!L\"><field name=\"NUM\">1</field></block></value></block></value><next><block type=\"variables_set\" id=\"I{^(8GT:UL9{7jdNlg[w\"><field name=\"VAR\" id=\"YdZ|nz8=@UwR53L{5(Te\" variabletype=\"\">face_size</field><value name=\"VALUE\"><block type=\"lists_getIndex\" id=\"2}fQ04Qws48,xb!?z1pW\"><mutation statement=\"false\" at=\"true\"></mutation><field name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block type=\"variables_get\" id=\"hmZQMGjZ94)AhuZ6JUYa\"><field name=\"VAR\" id=\"G`ooSD^IjFl@q`VRXz`M\" variabletype=\"\">face</field></block></value><value name=\"AT\"><block type=\"math_number\" id=\"=LbR3.00CDs*hnk()Y^-\"><field name=\"NUM\">2</field></block></value></block></value><next><block type=\"text_print\" id=\"O}.LG0(E@nzN,p;l%v2{\"><value name=\"TEXT\"><block type=\"text_join\" id=\"mRJtt8foB.;Gpq0fM,4D\"><mutation items=\"2\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\",=O:[=q5SBb`1$S,-R,:\"><field name=\"TEXT\">face: </field></block></value><value name=\"ADD1\"><block type=\"variables_get\" id=\"UEwJl:.puwUq)R!zo@Z7\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value></block></value><next><block type=\"controls_if\" id=\"9tGk|M6u455Nu1(SI}{K\"><value name=\"IF0\"><block type=\"variables_get\" id=\"9}[hrA3rOFo0n+BAsX-f\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><statement name=\"DO0\"><block type=\"controls_if\" id=\"1-%~}MODhI#*$?^aB_tS\"><mutation elseif=\"1\" else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_compare\" id=\"`rz$_58rWb#ufStSd](T\"><field name=\"OP\">LT</field><value name=\"A\"><block type=\"variables_get\" id=\"O}zML^tGL7t3C*mWsEMo\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"gdx{O}:M_*b|FpvgG_~h\"><field name=\"NUM\">-10</field></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"@[^uw~TU^Vti#)6HZC?K\"><field name=\"ACTION\">LEFT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"vt6%MV@vkT*tB]%2:7vQ\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"d3[F3QtIG#jb=1IPOem)\"><field name=\"NUM\">0.1</field></block></value></block></statement><value name=\"IF1\"><block type=\"logic_compare\" id=\"/zef{/F+:n[eI1@+MIKR\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"dh8opiswQU13wjT![yV[\"><field name=\"VAR\" id=\"JU]w:x,u6R_]KGB{:XP:\" variabletype=\"\">face_x</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"2RVlzW2}AG#ywuHP6N=+\"><field name=\"NUM\">10</field></block></value></block></value><statement name=\"DO1\"><block type=\"coderbot_adv_move\" id=\"4`Z7%j+MV5(5,BM!RRBA\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\"v`ab`#qs7J5]2XaOp]s[\"><field name=\"NUM\">80</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"A_y%A@DITmnWACnr0]zK\"><field name=\"NUM\">0.1</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_stop\" id=\"B/$XZ_Giuo_h#Q?JM{w}\"></block></statement></block></statement></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "face = None\nface_x = None\nface_size = None\n\n\nwhile True:\n get_prog_eng().check_end()\n face = get_cam().find_face()\n face_x = face[0]\n face_size = face[1]\n get_cam().set_text(str('face: ') + str(face_x))\n if face_x:\n if face_x < -10:\n get_bot().left(speed=80, elapse=0.1)\n elif face_x > 10:\n get_bot().right(speed=80, elapse=0.1)\n else:\n get_bot().stop()\n", "name": "test_find_face"} \ No newline at end of file diff --git a/defaults/programs/program_test_find_path_ahead.json b/defaults/programs/program_test_find_path_ahead.json index 703325e2..8875ed39 100644 --- a/defaults/programs/program_test_find_path_ahead.json +++ b/defaults/programs/program_test_find_path_ahead.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\",46fU~j08oojjbw,kof`\">spazio_libero</variable></variables><block type=\"controls_whileUntil\" id=\"18\" x=\"-6\" y=\"95\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"8\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"+.ndl3CthRQ~=B/JKR^u\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field><value name=\"VALUE\"><block type=\"coderbot_adv_pathAhead\" id=\"43\"></block></value><next><block type=\"text_print\" id=\"34\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"HvuukI#y0|2p~0G!J^1,\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><next><block type=\"controls_if\" id=\"j2kyA19rSa;+oDM_|TW1\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_operation\" id=\".h3ecm+6-QkNKadH^K^x\"><field name=\"OP\">AND</field><value name=\"A\"><block type=\"logic_compare\" id=\"?y*$N(f@|9rhe.mOI}Tw\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"j(v,2aQSE^A_2Um!%r%j\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"]@VPRw![OoT^Q6^@}+W]\"><field name=\"NUM\">30</field></block></value></block></value><value name=\"B\"><block type=\"logic_compare\" id=\"!E.x/E#B,Eqe=[6!!UpQ\"><field name=\"OP\">NEQ</field><value name=\"A\"><block type=\"variables_get\" id=\"1|EJ6P/9-k+=y!xD!n59\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"!3n*B?S(XK~u$1}#F:~N\"><field name=\"NUM\">60</field></block></value></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"#SW!Qq8M:4),17-S5HXx\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"ZIc[_OhSH1e.mz]:tL,?\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"-j(8o/#PiEQEY5L2zbT:\"><field name=\"NUM\">0.2</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\"e#qON.)K9J9!}_W`xlWx\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\")C53Vd7c_sC*PsSn0VCM\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"E3zjXN1SRNL5~IQJ|aRQ\"><field name=\"NUM\">0.2</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "spazio_libero = None\n\n\nwhile True:\n get_prog_eng().check_end()\n spazio_libero = get_cam().path_ahead()\n get_cam().set_text(spazio_libero)\n if spazio_libero > 30 and spazio_libero != 60:\n get_bot().forward(speed=100, elapse=0.2)\n else:\n get_bot().right(speed=100, elapse=0.2)\n", "name": "test_find_path_ahead"} \ No newline at end of file +{"id": "ced77927-df6b-475a-b41e-d36f3976a2a0", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables><variable type=\"\" id=\",46fU~j08oojjbw,kof`\">spazio_libero</variable></variables><block type=\"controls_whileUntil\" id=\"18\" x=\"-6\" y=\"95\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"8\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"variables_set\" id=\"+.ndl3CthRQ~=B/JKR^u\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field><value name=\"VALUE\"><block type=\"coderbot_adv_pathAhead\" id=\"43\"></block></value><next><block type=\"text_print\" id=\"34\"><value name=\"TEXT\"><block type=\"variables_get\" id=\"HvuukI#y0|2p~0G!J^1,\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><next><block type=\"controls_if\" id=\"j2kyA19rSa;+oDM_|TW1\"><mutation else=\"1\"></mutation><value name=\"IF0\"><block type=\"logic_operation\" id=\".h3ecm+6-QkNKadH^K^x\"><field name=\"OP\">AND</field><value name=\"A\"><block type=\"logic_compare\" id=\"?y*$N(f@|9rhe.mOI}Tw\"><field name=\"OP\">GT</field><value name=\"A\"><block type=\"variables_get\" id=\"j(v,2aQSE^A_2Um!%r%j\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"]@VPRw![OoT^Q6^@}+W]\"><field name=\"NUM\">30</field></block></value></block></value><value name=\"B\"><block type=\"logic_compare\" id=\"!E.x/E#B,Eqe=[6!!UpQ\"><field name=\"OP\">NEQ</field><value name=\"A\"><block type=\"variables_get\" id=\"1|EJ6P/9-k+=y!xD!n59\"><field name=\"VAR\" id=\",46fU~j08oojjbw,kof`\" variabletype=\"\">spazio_libero</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"!3n*B?S(XK~u$1}#F:~N\"><field name=\"NUM\">60</field></block></value></block></value></block></value><statement name=\"DO0\"><block type=\"coderbot_adv_move\" id=\"#SW!Qq8M:4),17-S5HXx\"><field name=\"ACTION\">FORWARD</field><value name=\"SPEED\"><block type=\"math_number\" id=\"ZIc[_OhSH1e.mz]:tL,?\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"-j(8o/#PiEQEY5L2zbT:\"><field name=\"NUM\">0.2</field></block></value></block></statement><statement name=\"ELSE\"><block type=\"coderbot_adv_move\" id=\"e#qON.)K9J9!}_W`xlWx\"><field name=\"ACTION\">RIGHT</field><value name=\"SPEED\"><block type=\"math_number\" id=\")C53Vd7c_sC*PsSn0VCM\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"E3zjXN1SRNL5~IQJ|aRQ\"><field name=\"NUM\">0.2</field></block></value></block></statement></block></next></block></next></block></statement></block></xml>", "code": "spazio_libero = None\n\n\nwhile True:\n get_prog_eng().check_end()\n spazio_libero = get_cam().path_ahead()\n get_cam().set_text(spazio_libero)\n if spazio_libero > 30 and spazio_libero != 60:\n get_bot().forward(speed=100, elapse=0.2)\n else:\n get_bot().right(speed=100, elapse=0.2)\n", "name": "test_find_path_ahead"} \ No newline at end of file diff --git a/defaults/programs/program_test_img_average.json b/defaults/programs/program_test_img_average.json index 0112e6cb..08e30d5b 100644 --- a/defaults/programs/program_test_img_average.json +++ b/defaults/programs/program_test_img_average.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\"><value name=\"TEXT\"><block type=\"coderbot_cam_average\"><field name=\"RETVAL\">V</field></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().get_average()[2])\n", "name": "test_img_average"} \ No newline at end of file +{"id": "4c448688-2d4f-424c-ac95-85417f30a447", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"9\" y=\"103\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\"><value name=\"TEXT\"><block type=\"coderbot_cam_average\"><field name=\"RETVAL\">V</field></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_cam().get_average()[2])\n", "name": "test_img_average"} \ No newline at end of file diff --git a/defaults/programs/program_test_input.json b/defaults/programs/program_test_input.json index 781dc25a..15fa7f9f 100644 --- a/defaults/programs/program_test_input.json +++ b/defaults/programs/program_test_input.json @@ -1 +1 @@ -{"name": "test_input", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"controls_whileUntil\" id=\"Eg+_}I*|KDj2r:7;lzVu\" x=\"16\" y=\"109\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"vjj7Y31uCw@dAO#:o!z=\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"|Oml,Wc+N7-.yv1S4tti\"><value name=\"TEXT\"><block type=\"text_join\" id=\"_:R_VIq+*$|i?`gYssJ/\"><mutation items=\"6\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\"]Ohyg]}FmQVhZ6z;]H59\"><field name=\"TEXT\">analog 1: </field></block></value><value name=\"ADD1\"><block type=\"coderbot_atmega_get_input\" id=\"c-@JnZzRduznZ!.oS2C4\"><field name=\"INPUT\">0</field></block></value><value name=\"ADD2\"><block type=\"text\" id=\"vJK8H/$_C*KFm)w=^mc!\"><field name=\"TEXT\"> analog 2: </field></block></value><value name=\"ADD3\"><block type=\"coderbot_atmega_get_input\" id=\"!y:zHIM%S^5yuAl@{d*x\"><field name=\"INPUT\">1</field></block></value><value name=\"ADD4\"><block type=\"text\" id=\"qB~`8GzOl^}ynUI1ycwT\"><field name=\"TEXT\"> digital 1: </field></block></value><value name=\"ADD5\"><block type=\"coderbot_atmega_get_input\" id=\"tVz][Ed:A#XFy]shvSRk\"><field name=\"INPUT\">2</field></block></value></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(''.join([str(x) for x in ['analog 1: ', get_atmega().get_input(0), ' analog 2: ', get_atmega().get_input(1), ' digital 1: ', get_atmega().get_input(2)]]))\n"} \ No newline at end of file +{"id": "c4cec8dc-f0e9-4aa0-ba2d-e8eb368a0f88", "name": "test_input", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"controls_whileUntil\" id=\"Eg+_}I*|KDj2r:7;lzVu\" x=\"16\" y=\"109\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"vjj7Y31uCw@dAO#:o!z=\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"|Oml,Wc+N7-.yv1S4tti\"><value name=\"TEXT\"><block type=\"text_join\" id=\"_:R_VIq+*$|i?`gYssJ/\"><mutation items=\"6\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\"]Ohyg]}FmQVhZ6z;]H59\"><field name=\"TEXT\">analog 1: </field></block></value><value name=\"ADD1\"><block type=\"coderbot_atmega_get_input\" id=\"c-@JnZzRduznZ!.oS2C4\"><field name=\"INPUT\">0</field></block></value><value name=\"ADD2\"><block type=\"text\" id=\"vJK8H/$_C*KFm)w=^mc!\"><field name=\"TEXT\"> analog 2: </field></block></value><value name=\"ADD3\"><block type=\"coderbot_atmega_get_input\" id=\"!y:zHIM%S^5yuAl@{d*x\"><field name=\"INPUT\">1</field></block></value><value name=\"ADD4\"><block type=\"text\" id=\"qB~`8GzOl^}ynUI1ycwT\"><field name=\"TEXT\"> digital 1: </field></block></value><value name=\"ADD5\"><block type=\"coderbot_atmega_get_input\" id=\"tVz][Ed:A#XFy]shvSRk\"><field name=\"INPUT\">2</field></block></value></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(''.join([str(x) for x in ['analog 1: ', get_atmega().get_input(0), ' analog 2: ', get_atmega().get_input(1), ' digital 1: ', get_atmega().get_input(2)]]))\n"} \ No newline at end of file diff --git a/defaults/programs/program_test_led.json b/defaults/programs/program_test_led.json index 7246e80d..58f1534c 100644 --- a/defaults/programs/program_test_led.json +++ b/defaults/programs/program_test_led.json @@ -1 +1 @@ -{"name": "test_led", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\"/xw.j?2UDr3u^6ElAbfw\">leds</variable><variable id=\"mV|1?_`t].w9ldDjB#Pd\">i</variable><variable id=\".^%KgNcWO{?uvr(igb/M\">c</variable></variables><block type=\"variables_set\" id=\"`7Sm1AK0q1yrCf3yj1jY\" x=\"83\" y=\"6\"><field name=\"VAR\" id=\"/xw.j?2UDr3u^6ElAbfw\">leds</field><value name=\"VALUE\"><block type=\"math_number\" id=\"~XqK1jXL`MkyR[:R*A^Z\"><field name=\"NUM\">60</field></block></value><next><block type=\"controls_repeat_ext\" id=\";niBg8v_6u=JPSvZ{Rq~\"><value name=\"TIMES\"><block type=\"math_number\" id=\"LbXC!xr+QmP1{y?aQKgh\"><field name=\"NUM\">3</field></block></value><statement name=\"DO\"><block type=\"coderbot_atmega_set_led\" id=\"U4M/5!Z8)ydVSl6!KGfl\"><value name=\"BEGIN\"><block type=\"math_number\" id=\"}+N@zF-K}std2rBA.rcB\"><field name=\"NUM\">1</field></block></value><value name=\"END\"><block type=\"variables_get\" id=\"ug]D+ea8)#!5hvSs*L$U\"><field name=\"VAR\" id=\"/xw.j?2UDr3u^6ElAbfw\">leds</field></block></value><value name=\"RED\"><block type=\"math_number\" id=\"n`wi],+ar)H__{76(8aO\"><field name=\"NUM\">0</field></block></value><value name=\"GREEN\"><block type=\"math_number\" id=\"aXK={ZR{EA-S~kZ4r2x)\"><field name=\"NUM\">0</field></block></value><value name=\"BLUE\"><block type=\"math_number\" id=\"H5Av._zz|gP;e)uQnw7D\"><field name=\"NUM\">0</field></block></value><next><block type=\"controls_for\" id=\"(HLoJr|poNT!f(*wl5Gt\"><field name=\"VAR\" id=\"mV|1?_`t].w9ldDjB#Pd\">i</field><value name=\"FROM\"><block type=\"math_number\" id=\"q%I+x1$v$Hb9qjS^gv|X\"><field name=\"NUM\">1</field></block></value><value name=\"TO\"><block type=\"variables_get\" id=\"mSG+|MQ6P8$;Des`tSSz\"><field name=\"VAR\" id=\"/xw.j?2UDr3u^6ElAbfw\">leds</field></block></value><value name=\"BY\"><block type=\"math_number\" id=\"L,d:{%h6_[vN@,jN/wi2\"><field name=\"NUM\">1</field></block></value><statement name=\"DO\"><block type=\"coderbot_atmega_set_led\" id=\",(rL?k}`#UYM@CY`5ZOF\"><value name=\"BEGIN\"><block type=\"math_number\" id=\"Ql5,)ZkO{_chavvTnCn6\"><field name=\"NUM\">1</field></block></value><value name=\"END\"><block type=\"math_arithmetic\" id=\"TSN}K9t%.206Lp03*^#u\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"variables_get\" id=\"%|yMnq+m;GQhyw2I3(7Q\"><field name=\"VAR\" id=\"mV|1?_`t].w9ldDjB#Pd\">i</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"E=ifR{(UUuG+j*hsDx8S\"><field name=\"NUM\">1</field></block></value></block></value><value name=\"RED\"><block type=\"math_number\" id=\"@yqVmOuAeq~eAL*N|q+#\"><field name=\"NUM\">0</field></block></value><value name=\"GREEN\"><block type=\"math_number\" id=\"@YVgd/x:B#YxVjxS:,T@\"><field name=\"NUM\">0</field></block></value><value name=\"BLUE\"><block type=\"math_number\" id=\"k5+jbhcY0MWc_z2@03{n\"><field name=\"NUM\">0</field></block></value><next><block type=\"coderbot_atmega_set_led\" id=\"xu/0IEI)Ts8=FqPFqVn)\"><value name=\"BEGIN\"><block type=\"math_arithmetic\" id=\")Rx_thG1*MJwhu5a`GCX\"><field name=\"OP\">ADD</field><value name=\"A\"><block type=\"variables_get\" id=\"i|S#;A}wazp[.tZonQ;g\"><field name=\"VAR\" id=\"mV|1?_`t].w9ldDjB#Pd\">i</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"7t{7y%u?Mz?k]GO$1SA9\"><field name=\"NUM\">5</field></block></value></block></value><value name=\"END\"><block type=\"variables_get\" id=\"X*ZrOoMNe%xtt*yp3#|a\"><field name=\"VAR\" id=\"/xw.j?2UDr3u^6ElAbfw\">leds</field></block></value><value name=\"RED\"><block type=\"math_number\" id=\"3]+P|Rq;Si5wHGK6/@^3\"><field name=\"NUM\">0</field></block></value><value name=\"GREEN\"><block type=\"math_number\" id=\"q#!lPC%rrlw~8O*O:sz^\"><field name=\"NUM\">0</field></block></value><value name=\"BLUE\"><block type=\"math_number\" id=\"l!Tzd:G5fPm=3Kax^5M0\"><field name=\"NUM\">0</field></block></value><next><block type=\"controls_for\" id=\"E`+DR_wKgE9^3DO}G8ew\"><field name=\"VAR\" id=\".^%KgNcWO{?uvr(igb/M\">c</field><value name=\"FROM\"><block type=\"math_number\" id=\"_q2GlJkegi#GR|dez;A!\"><field name=\"NUM\">1</field></block></value><value name=\"TO\"><block type=\"math_number\" id=\"x/aQ`cU1Ks(6=yJu{2^k\"><field name=\"NUM\">100</field></block></value><value name=\"BY\"><block type=\"math_number\" id=\")/gFUFR1opq/8HgCVNws\"><field name=\"NUM\">5</field></block></value><statement name=\"DO\"><block type=\"coderbot_atmega_set_led\" id=\"chy~IyYrzHH*[t+@jnZ#\"><value name=\"BEGIN\"><block type=\"variables_get\" id=\"HtnTmdSQ[/||-yHV!Li.\"><field name=\"VAR\" id=\"mV|1?_`t].w9ldDjB#Pd\">i</field></block></value><value name=\"END\"><block type=\"math_arithmetic\" id=\"Y#AHd_Be05gTr_XeqTO:\"><field name=\"OP\">ADD</field><value name=\"A\"><block type=\"variables_get\" id=\"$y/*rz!oS[8Z8-H2#Iuk\"><field name=\"VAR\" id=\"mV|1?_`t].w9ldDjB#Pd\">i</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"j*iHZ-T$?yn%m-FJCY{c\"><field name=\"NUM\">5</field></block></value></block></value><value name=\"RED\"><block type=\"math_arithmetic\" id=\";kBE!f4tZqXL^tuWv7zr\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"variables_get\" id=\"deHK(hlFV.KR=uZg9z;w\"><field name=\"VAR\" id=\".^%KgNcWO{?uvr(igb/M\">c</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"46z)lg$93j{/jj.Co{^(\"><field name=\"NUM\">0</field></block></value></block></value><value name=\"GREEN\"><block type=\"math_arithmetic\" id=\";Esa/)mXftItk:dsgx2H\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"variables_get\" id=\"@:64T_Ryd_XG~BF|-3l}\"><field name=\"VAR\" id=\".^%KgNcWO{?uvr(igb/M\">c</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"`0hSm^wEqrW:-mM%CjiZ\"><field name=\"NUM\">0</field></block></value></block></value><value name=\"BLUE\"><block type=\"math_arithmetic\" id=\"iUrI|HZnVrxre*:bpwtp\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"variables_get\" id=\"aKlo?CPZPeg]$~[L)y^h\"><field name=\"VAR\" id=\".^%KgNcWO{?uvr(igb/M\">c</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"f:`}o(Dz)Fp`fXC^GIN@\"><field name=\"NUM\">3</field></block></value></block></value></block></statement></block></next></block></next></block></statement><next><block type=\"coderbot_atmega_set_led\" id=\"|6n;D0.SJPHwfd2TTH1o\"><value name=\"BEGIN\"><block type=\"math_number\" id=\"`?=rb;gGH5)zvs{.0W[c\"><field name=\"NUM\">1</field></block></value><value name=\"END\"><block type=\"variables_get\" id=\"ri2K1wws76aIcZg@hC/I\"><field name=\"VAR\" id=\"/xw.j?2UDr3u^6ElAbfw\">leds</field></block></value><value name=\"RED\"><block type=\"math_number\" id=\"`T5m0oiNlt3kn34rWK#g\"><field name=\"NUM\">0</field></block></value><value name=\"GREEN\"><block type=\"math_number\" id=\"dEo{NKNG6@2_2neC|bXa\"><field name=\"NUM\">0</field></block></value><value name=\"BLUE\"><block type=\"math_number\" id=\"AvIT+M?iR;e05eB{r40_\"><field name=\"NUM\">0</field></block></value></block></next></block></next></block></statement></block></next></block></xml>", "code": "leds = None\ni = None\nc = None\n\ndef upRange(start, stop, step):\n while start <= stop:\n yield start\n start += abs(step)\n\ndef downRange(start, stop, step):\n while start >= stop:\n yield start\n start -= abs(step)\n\n\nleds = 60\nfor count in range(3):\n get_prog_eng().check_end()\n get_atmega().set_led(1, leds, 0, 0, 0)\n for i in (1 <= float(leds)) and upRange(1, float(leds), 1) or downRange(1, float(leds), 1):\n get_prog_eng().check_end()\n get_atmega().set_led(1, i - 1, 0, 0, 0)\n get_atmega().set_led(i + 5, leds, 0, 0, 0)\n for c in range(1, 101, 5):\n get_prog_eng().check_end()\n get_atmega().set_led(i, i + 5, c * 0, c * 0, c * 3)\n get_atmega().set_led(1, leds, 0, 0, 0)\n"} \ No newline at end of file +{"id": "4bf5a8a8-eb06-44aa-8450-e73b62e11f8c", "name": "test_led", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\"/xw.j?2UDr3u^6ElAbfw\">leds</variable><variable id=\"mV|1?_`t].w9ldDjB#Pd\">i</variable><variable id=\".^%KgNcWO{?uvr(igb/M\">c</variable></variables><block type=\"variables_set\" id=\"`7Sm1AK0q1yrCf3yj1jY\" x=\"83\" y=\"6\"><field name=\"VAR\" id=\"/xw.j?2UDr3u^6ElAbfw\">leds</field><value name=\"VALUE\"><block type=\"math_number\" id=\"~XqK1jXL`MkyR[:R*A^Z\"><field name=\"NUM\">60</field></block></value><next><block type=\"controls_repeat_ext\" id=\";niBg8v_6u=JPSvZ{Rq~\"><value name=\"TIMES\"><block type=\"math_number\" id=\"LbXC!xr+QmP1{y?aQKgh\"><field name=\"NUM\">3</field></block></value><statement name=\"DO\"><block type=\"coderbot_atmega_set_led\" id=\"U4M/5!Z8)ydVSl6!KGfl\"><value name=\"BEGIN\"><block type=\"math_number\" id=\"}+N@zF-K}std2rBA.rcB\"><field name=\"NUM\">1</field></block></value><value name=\"END\"><block type=\"variables_get\" id=\"ug]D+ea8)#!5hvSs*L$U\"><field name=\"VAR\" id=\"/xw.j?2UDr3u^6ElAbfw\">leds</field></block></value><value name=\"RED\"><block type=\"math_number\" id=\"n`wi],+ar)H__{76(8aO\"><field name=\"NUM\">0</field></block></value><value name=\"GREEN\"><block type=\"math_number\" id=\"aXK={ZR{EA-S~kZ4r2x)\"><field name=\"NUM\">0</field></block></value><value name=\"BLUE\"><block type=\"math_number\" id=\"H5Av._zz|gP;e)uQnw7D\"><field name=\"NUM\">0</field></block></value><next><block type=\"controls_for\" id=\"(HLoJr|poNT!f(*wl5Gt\"><field name=\"VAR\" id=\"mV|1?_`t].w9ldDjB#Pd\">i</field><value name=\"FROM\"><block type=\"math_number\" id=\"q%I+x1$v$Hb9qjS^gv|X\"><field name=\"NUM\">1</field></block></value><value name=\"TO\"><block type=\"variables_get\" id=\"mSG+|MQ6P8$;Des`tSSz\"><field name=\"VAR\" id=\"/xw.j?2UDr3u^6ElAbfw\">leds</field></block></value><value name=\"BY\"><block type=\"math_number\" id=\"L,d:{%h6_[vN@,jN/wi2\"><field name=\"NUM\">1</field></block></value><statement name=\"DO\"><block type=\"coderbot_atmega_set_led\" id=\",(rL?k}`#UYM@CY`5ZOF\"><value name=\"BEGIN\"><block type=\"math_number\" id=\"Ql5,)ZkO{_chavvTnCn6\"><field name=\"NUM\">1</field></block></value><value name=\"END\"><block type=\"math_arithmetic\" id=\"TSN}K9t%.206Lp03*^#u\"><field name=\"OP\">MINUS</field><value name=\"A\"><block type=\"variables_get\" id=\"%|yMnq+m;GQhyw2I3(7Q\"><field name=\"VAR\" id=\"mV|1?_`t].w9ldDjB#Pd\">i</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"E=ifR{(UUuG+j*hsDx8S\"><field name=\"NUM\">1</field></block></value></block></value><value name=\"RED\"><block type=\"math_number\" id=\"@yqVmOuAeq~eAL*N|q+#\"><field name=\"NUM\">0</field></block></value><value name=\"GREEN\"><block type=\"math_number\" id=\"@YVgd/x:B#YxVjxS:,T@\"><field name=\"NUM\">0</field></block></value><value name=\"BLUE\"><block type=\"math_number\" id=\"k5+jbhcY0MWc_z2@03{n\"><field name=\"NUM\">0</field></block></value><next><block type=\"coderbot_atmega_set_led\" id=\"xu/0IEI)Ts8=FqPFqVn)\"><value name=\"BEGIN\"><block type=\"math_arithmetic\" id=\")Rx_thG1*MJwhu5a`GCX\"><field name=\"OP\">ADD</field><value name=\"A\"><block type=\"variables_get\" id=\"i|S#;A}wazp[.tZonQ;g\"><field name=\"VAR\" id=\"mV|1?_`t].w9ldDjB#Pd\">i</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"7t{7y%u?Mz?k]GO$1SA9\"><field name=\"NUM\">5</field></block></value></block></value><value name=\"END\"><block type=\"variables_get\" id=\"X*ZrOoMNe%xtt*yp3#|a\"><field name=\"VAR\" id=\"/xw.j?2UDr3u^6ElAbfw\">leds</field></block></value><value name=\"RED\"><block type=\"math_number\" id=\"3]+P|Rq;Si5wHGK6/@^3\"><field name=\"NUM\">0</field></block></value><value name=\"GREEN\"><block type=\"math_number\" id=\"q#!lPC%rrlw~8O*O:sz^\"><field name=\"NUM\">0</field></block></value><value name=\"BLUE\"><block type=\"math_number\" id=\"l!Tzd:G5fPm=3Kax^5M0\"><field name=\"NUM\">0</field></block></value><next><block type=\"controls_for\" id=\"E`+DR_wKgE9^3DO}G8ew\"><field name=\"VAR\" id=\".^%KgNcWO{?uvr(igb/M\">c</field><value name=\"FROM\"><block type=\"math_number\" id=\"_q2GlJkegi#GR|dez;A!\"><field name=\"NUM\">1</field></block></value><value name=\"TO\"><block type=\"math_number\" id=\"x/aQ`cU1Ks(6=yJu{2^k\"><field name=\"NUM\">100</field></block></value><value name=\"BY\"><block type=\"math_number\" id=\")/gFUFR1opq/8HgCVNws\"><field name=\"NUM\">5</field></block></value><statement name=\"DO\"><block type=\"coderbot_atmega_set_led\" id=\"chy~IyYrzHH*[t+@jnZ#\"><value name=\"BEGIN\"><block type=\"variables_get\" id=\"HtnTmdSQ[/||-yHV!Li.\"><field name=\"VAR\" id=\"mV|1?_`t].w9ldDjB#Pd\">i</field></block></value><value name=\"END\"><block type=\"math_arithmetic\" id=\"Y#AHd_Be05gTr_XeqTO:\"><field name=\"OP\">ADD</field><value name=\"A\"><block type=\"variables_get\" id=\"$y/*rz!oS[8Z8-H2#Iuk\"><field name=\"VAR\" id=\"mV|1?_`t].w9ldDjB#Pd\">i</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"j*iHZ-T$?yn%m-FJCY{c\"><field name=\"NUM\">5</field></block></value></block></value><value name=\"RED\"><block type=\"math_arithmetic\" id=\";kBE!f4tZqXL^tuWv7zr\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"variables_get\" id=\"deHK(hlFV.KR=uZg9z;w\"><field name=\"VAR\" id=\".^%KgNcWO{?uvr(igb/M\">c</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"46z)lg$93j{/jj.Co{^(\"><field name=\"NUM\">0</field></block></value></block></value><value name=\"GREEN\"><block type=\"math_arithmetic\" id=\";Esa/)mXftItk:dsgx2H\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"variables_get\" id=\"@:64T_Ryd_XG~BF|-3l}\"><field name=\"VAR\" id=\".^%KgNcWO{?uvr(igb/M\">c</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"`0hSm^wEqrW:-mM%CjiZ\"><field name=\"NUM\">0</field></block></value></block></value><value name=\"BLUE\"><block type=\"math_arithmetic\" id=\"iUrI|HZnVrxre*:bpwtp\"><field name=\"OP\">MULTIPLY</field><value name=\"A\"><block type=\"variables_get\" id=\"aKlo?CPZPeg]$~[L)y^h\"><field name=\"VAR\" id=\".^%KgNcWO{?uvr(igb/M\">c</field></block></value><value name=\"B\"><block type=\"math_number\" id=\"f:`}o(Dz)Fp`fXC^GIN@\"><field name=\"NUM\">3</field></block></value></block></value></block></statement></block></next></block></next></block></statement><next><block type=\"coderbot_atmega_set_led\" id=\"|6n;D0.SJPHwfd2TTH1o\"><value name=\"BEGIN\"><block type=\"math_number\" id=\"`?=rb;gGH5)zvs{.0W[c\"><field name=\"NUM\">1</field></block></value><value name=\"END\"><block type=\"variables_get\" id=\"ri2K1wws76aIcZg@hC/I\"><field name=\"VAR\" id=\"/xw.j?2UDr3u^6ElAbfw\">leds</field></block></value><value name=\"RED\"><block type=\"math_number\" id=\"`T5m0oiNlt3kn34rWK#g\"><field name=\"NUM\">0</field></block></value><value name=\"GREEN\"><block type=\"math_number\" id=\"dEo{NKNG6@2_2neC|bXa\"><field name=\"NUM\">0</field></block></value><value name=\"BLUE\"><block type=\"math_number\" id=\"AvIT+M?iR;e05eB{r40_\"><field name=\"NUM\">0</field></block></value></block></next></block></next></block></statement></block></next></block></xml>", "code": "leds = None\ni = None\nc = None\n\ndef upRange(start, stop, step):\n while start <= stop:\n yield start\n start += abs(step)\n\ndef downRange(start, stop, step):\n while start >= stop:\n yield start\n start -= abs(step)\n\n\nleds = 60\nfor count in range(3):\n get_prog_eng().check_end()\n get_atmega().set_led(1, leds, 0, 0, 0)\n for i in (1 <= float(leds)) and upRange(1, float(leds), 1) or downRange(1, float(leds), 1):\n get_prog_eng().check_end()\n get_atmega().set_led(1, i - 1, 0, 0, 0)\n get_atmega().set_led(i + 5, leds, 0, 0, 0)\n for c in range(1, 101, 5):\n get_prog_eng().check_end()\n get_atmega().set_led(i, i + 5, c * 0, c * 0, c * 3)\n get_atmega().set_led(1, leds, 0, 0, 0)\n"} \ No newline at end of file diff --git a/defaults/programs/program_test_music.json b/defaults/programs/program_test_music.json index a3d0f3fd..053a21a2 100644 --- a/defaults/programs/program_test_music.json +++ b/defaults/programs/program_test_music.json @@ -1 +1 @@ -{"name": "test_music", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"coderbot_music_note_adv\" id=\"wU*%v+7?j^b/P`/r7T2F\" x=\"16\" y=\"10\"><field name=\"note\">C2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"Wg_BML4JCSE`=xj{e*x*\"><field name=\"instrument\">dog</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"akIx85+Xsw2PO;LGAw}a\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"B;mmI4j-l0JYE%)uO$=D\"><field name=\"note\">D2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"krvcf`|9E[Z9q_WI)W+e\"><field name=\"instrument\">cat</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"%Q}lUA{+eR%+aBeRKC#l\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"{I@8C@;.TlDXD?D4te,+\"><field name=\"note\">E2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"m2|[h#nxCrS-VO^tM,x+\"><field name=\"instrument\">pig</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"~[?w~tla)S;mtb``/9M/\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"t3b)hP-vLRs0_~y(u1:V\"><field name=\"note\">F2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"(Unfm?Z/=b+QnZ|qjf6$\"><field name=\"instrument\">elephant</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\":OBb];9A5U+-9;NgBGjv\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"#=]%R]ZeZ1?qp[DsaT+j\"><field name=\"note\">G2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"nZsm62Wm-t._?KcA[D2R\"><field name=\"instrument\">snake</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"X8zc{-8sT,J~c@g_OVX/\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"jV|.0Sl;j=Tkv;;jDIkZ\"><field name=\"note\">A2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"RglHt%71{DY:qvN#2aAx\"><field name=\"instrument\">duck</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"Sz:E94T7m^9{g$^gMm6)\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"RNZ@6__`#uf6M{(L3PLW\"><field name=\"note\">B2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"?!)J-A*mj_=;]QE_J]YY\"><field name=\"instrument\">cat</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"013?KE6*?/JWE94MRkp,\"><field name=\"NUM\">1</field></block></value></block></next></block></next></block></next></block></next></block></next></block></next></block></xml>", "code": "get_music().play_note(note=\"C2\", alteration=\"none\" ,instrument=\"dog\" ,duration=1)\nget_music().play_note(note=\"D2\", alteration=\"none\" ,instrument=\"cat\" ,duration=1)\nget_music().play_note(note=\"E2\", alteration=\"none\" ,instrument=\"pig\" ,duration=1)\nget_music().play_note(note=\"F2\", alteration=\"none\" ,instrument=\"elephant\" ,duration=1)\nget_music().play_note(note=\"G2\", alteration=\"none\" ,instrument=\"snake\" ,duration=1)\nget_music().play_note(note=\"A2\", alteration=\"none\" ,instrument=\"duck\" ,duration=1)\nget_music().play_note(note=\"B2\", alteration=\"none\" ,instrument=\"cat\" ,duration=1)\n"} \ No newline at end of file +{"id": "8281a5f5-f9a4-4128-bd3d-bef41fb2c30b", "name": "test_music", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"coderbot_music_note_adv\" id=\"wU*%v+7?j^b/P`/r7T2F\" x=\"16\" y=\"10\"><field name=\"note\">C2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"Wg_BML4JCSE`=xj{e*x*\"><field name=\"instrument\">dog</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"akIx85+Xsw2PO;LGAw}a\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"B;mmI4j-l0JYE%)uO$=D\"><field name=\"note\">D2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"krvcf`|9E[Z9q_WI)W+e\"><field name=\"instrument\">cat</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"%Q}lUA{+eR%+aBeRKC#l\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"{I@8C@;.TlDXD?D4te,+\"><field name=\"note\">E2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"m2|[h#nxCrS-VO^tM,x+\"><field name=\"instrument\">pig</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"~[?w~tla)S;mtb``/9M/\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"t3b)hP-vLRs0_~y(u1:V\"><field name=\"note\">F2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"(Unfm?Z/=b+QnZ|qjf6$\"><field name=\"instrument\">elephant</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\":OBb];9A5U+-9;NgBGjv\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"#=]%R]ZeZ1?qp[DsaT+j\"><field name=\"note\">G2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"nZsm62Wm-t._?KcA[D2R\"><field name=\"instrument\">snake</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"X8zc{-8sT,J~c@g_OVX/\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"jV|.0Sl;j=Tkv;;jDIkZ\"><field name=\"note\">A2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"RglHt%71{DY:qvN#2aAx\"><field name=\"instrument\">duck</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"Sz:E94T7m^9{g$^gMm6)\"><field name=\"NUM\">1</field></block></value><next><block type=\"coderbot_music_note_adv\" id=\"RNZ@6__`#uf6M{(L3PLW\"><field name=\"note\">B2</field><field name=\"alteration\">none</field><value name=\"instrument\"><block type=\"coderbot_music_animal_adv\" id=\"?!)J-A*mj_=;]QE_J]YY\"><field name=\"instrument\">cat</field></block></value><value name=\"duration\"><block type=\"math_number\" id=\"013?KE6*?/JWE94MRkp,\"><field name=\"NUM\">1</field></block></value></block></next></block></next></block></next></block></next></block></next></block></next></block></xml>", "code": "get_music().play_note(note=\"C2\", alteration=\"none\" ,instrument=\"dog\" ,duration=1)\nget_music().play_note(note=\"D2\", alteration=\"none\" ,instrument=\"cat\" ,duration=1)\nget_music().play_note(note=\"E2\", alteration=\"none\" ,instrument=\"pig\" ,duration=1)\nget_music().play_note(note=\"F2\", alteration=\"none\" ,instrument=\"elephant\" ,duration=1)\nget_music().play_note(note=\"G2\", alteration=\"none\" ,instrument=\"snake\" ,duration=1)\nget_music().play_note(note=\"A2\", alteration=\"none\" ,instrument=\"duck\" ,duration=1)\nget_music().play_note(note=\"B2\", alteration=\"none\" ,instrument=\"cat\" ,duration=1)\n"} \ No newline at end of file diff --git a/defaults/programs/program_test_output.json b/defaults/programs/program_test_output.json index dbd31e04..1fcb8a4a 100644 --- a/defaults/programs/program_test_output.json +++ b/defaults/programs/program_test_output.json @@ -1 +1 @@ -{"name": "test_output", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"controls_whileUntil\" id=\"Eg+_}I*|KDj2r:7;lzVu\" x=\"16\" y=\"109\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"vjj7Y31uCw@dAO#:o!z=\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"coderbot_atmega_set_output\" id=\"FWQt#G1gxXgvCXg_pJSD\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"OX}R-$-yxOonk~1)~V@8\"><field name=\"BOOL\">TRUE</field></block></value><next><block type=\"coderbot_sleep\" id=\"hn*rWB|=?5VdK=9d#~Q,\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"X4z;@`hR!z6Wr,]?mr!8\"><field name=\"NUM\">0.1</field></block></value><next><block type=\"coderbot_atmega_set_output\" id=\"%gGkLCH-,tpv8-Cvh@m9\"><field name=\"OUTPUT\">1</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"$WPv~h)tka4-4ac)B;d-\"><field name=\"BOOL\">TRUE</field></block></value><next><block type=\"coderbot_sleep\" id=\";V5!M5]]T8qq|j`Bdl|h\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"Z-fZi_u%ISNl3D/?Cy_Q\"><field name=\"NUM\">0.1</field></block></value><next><block type=\"coderbot_atmega_set_output\" id=\"]S_7t8;yoT6_vto%_^]#\"><field name=\"OUTPUT\">2</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"6a*oNkOM`1fbClSoMAu)\"><field name=\"BOOL\">TRUE</field></block></value><next><block type=\"coderbot_sleep\" id=\"!ki0*0*T,b5Gr9ZweOAH\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"jcQPERvz]3Ax}+(PFIJ~\"><field name=\"NUM\">0.1</field></block></value><next><block type=\"coderbot_atmega_set_output\" id=\"9Tmmbu4g;%4U%NN}6^*~\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"l8J8y%;Lq(j-2c7|]-Dx\"><field name=\"BOOL\">FALSE</field></block></value><next><block type=\"coderbot_sleep\" id=\"]sK==U]48RmtmtEQeYo.\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"QLzo=Bik,6*oygOtmi(;\"><field name=\"NUM\">0.1</field></block></value><next><block type=\"coderbot_atmega_set_output\" id=\"XF@xS7zgaWl(,^hup`qP\"><field name=\"OUTPUT\">1</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"x5axsrx_%hM(@MP1O??0\"><field name=\"BOOL\">FALSE</field></block></value><next><block type=\"coderbot_sleep\" id=\"3_fx6eK)|8mP1ubjFfZq\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"HQ4:!?6-V41HAQaJCxtr\"><field name=\"NUM\">0.1</field></block></value><next><block type=\"coderbot_atmega_set_output\" id=\"CURTVoSTK_`uN%{,/cVc\"><field name=\"OUTPUT\">2</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"`qobZ6#VrlWZlrz:I_yn\"><field name=\"BOOL\">FALSE</field></block></value><next><block type=\"coderbot_sleep\" id=\"V[cnM=e?S(c{9U1;d$hB\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"BU7nnRfsY/UXGOT4%Cdy\"><field name=\"NUM\">0.1</field></block></value></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_atmega().set_output(0, True)\n get_bot().sleep(0.1)\n get_atmega().set_output(1, True)\n get_bot().sleep(0.1)\n get_atmega().set_output(2, True)\n get_bot().sleep(0.1)\n get_atmega().set_output(0, False)\n get_bot().sleep(0.1)\n get_atmega().set_output(1, False)\n get_bot().sleep(0.1)\n get_atmega().set_output(2, False)\n get_bot().sleep(0.1)\n"} \ No newline at end of file +{"id": "604ca7a1-f2e2-45f0-92b2-afd3c621921f", "name": "test_output", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"controls_whileUntil\" id=\"Eg+_}I*|KDj2r:7;lzVu\" x=\"16\" y=\"109\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"vjj7Y31uCw@dAO#:o!z=\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"coderbot_atmega_set_output\" id=\"FWQt#G1gxXgvCXg_pJSD\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"OX}R-$-yxOonk~1)~V@8\"><field name=\"BOOL\">TRUE</field></block></value><next><block type=\"coderbot_sleep\" id=\"hn*rWB|=?5VdK=9d#~Q,\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"X4z;@`hR!z6Wr,]?mr!8\"><field name=\"NUM\">0.1</field></block></value><next><block type=\"coderbot_atmega_set_output\" id=\"%gGkLCH-,tpv8-Cvh@m9\"><field name=\"OUTPUT\">1</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"$WPv~h)tka4-4ac)B;d-\"><field name=\"BOOL\">TRUE</field></block></value><next><block type=\"coderbot_sleep\" id=\";V5!M5]]T8qq|j`Bdl|h\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"Z-fZi_u%ISNl3D/?Cy_Q\"><field name=\"NUM\">0.1</field></block></value><next><block type=\"coderbot_atmega_set_output\" id=\"]S_7t8;yoT6_vto%_^]#\"><field name=\"OUTPUT\">2</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"6a*oNkOM`1fbClSoMAu)\"><field name=\"BOOL\">TRUE</field></block></value><next><block type=\"coderbot_sleep\" id=\"!ki0*0*T,b5Gr9ZweOAH\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"jcQPERvz]3Ax}+(PFIJ~\"><field name=\"NUM\">0.1</field></block></value><next><block type=\"coderbot_atmega_set_output\" id=\"9Tmmbu4g;%4U%NN}6^*~\"><field name=\"OUTPUT\">0</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"l8J8y%;Lq(j-2c7|]-Dx\"><field name=\"BOOL\">FALSE</field></block></value><next><block type=\"coderbot_sleep\" id=\"]sK==U]48RmtmtEQeYo.\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"QLzo=Bik,6*oygOtmi(;\"><field name=\"NUM\">0.1</field></block></value><next><block type=\"coderbot_atmega_set_output\" id=\"XF@xS7zgaWl(,^hup`qP\"><field name=\"OUTPUT\">1</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"x5axsrx_%hM(@MP1O??0\"><field name=\"BOOL\">FALSE</field></block></value><next><block type=\"coderbot_sleep\" id=\"3_fx6eK)|8mP1ubjFfZq\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"HQ4:!?6-V41HAQaJCxtr\"><field name=\"NUM\">0.1</field></block></value><next><block type=\"coderbot_atmega_set_output\" id=\"CURTVoSTK_`uN%{,/cVc\"><field name=\"OUTPUT\">2</field><value name=\"VALUE\"><block type=\"logic_boolean\" id=\"`qobZ6#VrlWZlrz:I_yn\"><field name=\"BOOL\">FALSE</field></block></value><next><block type=\"coderbot_sleep\" id=\"V[cnM=e?S(c{9U1;d$hB\"><value name=\"ELAPSE\"><block type=\"math_number\" id=\"BU7nnRfsY/UXGOT4%Cdy\"><field name=\"NUM\">0.1</field></block></value></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_atmega().set_output(0, True)\n get_bot().sleep(0.1)\n get_atmega().set_output(1, True)\n get_bot().sleep(0.1)\n get_atmega().set_output(2, True)\n get_bot().sleep(0.1)\n get_atmega().set_output(0, False)\n get_bot().sleep(0.1)\n get_atmega().set_output(1, False)\n get_bot().sleep(0.1)\n get_atmega().set_output(2, False)\n get_bot().sleep(0.1)\n"} \ No newline at end of file diff --git a/defaults/programs/program_test_sonars.json b/defaults/programs/program_test_sonars.json index 6664424a..7c58bec3 100644 --- a/defaults/programs/program_test_sonars.json +++ b/defaults/programs/program_test_sonars.json @@ -1 +1 @@ -{"name": "test_sonars", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"controls_whileUntil\" id=\"0Mx[mSKoV~Gk1qbv5Wrn\" x=\"68\" y=\"148\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"q8(wB97}Y)d71cgy$yo#\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"0fGi]QOF@I*b$5x^?f#A\"><value name=\"TEXT\"><block type=\"text_join\" id=\"HA#?-0mP[+$WL+So^l5J\"><mutation items=\"6\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\"E%5LX*8^Gl-$lv$UIWBv\"><field name=\"TEXT\">Front: </field></block></value><value name=\"ADD1\"><block type=\"coderbot_sonar_get_distance\" id=\"9Mw8Ob~`;a.l/tw}fui`\"><field name=\"SONAR\">0</field></block></value><value name=\"ADD2\"><block type=\"text\" id=\"{xub0XYN;{o:+?BqYjz:\"><field name=\"TEXT\"> Right: </field></block></value><value name=\"ADD3\"><block type=\"coderbot_sonar_get_distance\" id=\"c~T`mQ}cq/AzVk|=_;k#\"><field name=\"SONAR\">1</field></block></value><value name=\"ADD4\"><block type=\"text\" id=\"{oo.?}O~rUC7|]Q9Wu0[\"><field name=\"TEXT\"> Left: </field></block></value><value name=\"ADD5\"><block type=\"coderbot_sonar_get_distance\" id=\"}`5RPkPB/|v%D;^Gc1WM\"><field name=\"SONAR\">2</field></block></value></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(''.join([str(x) for x in ['Front: ', get_bot().get_sonar_distance(0), ' Right: ', get_bot().get_sonar_distance(1), ' Left: ', get_bot().get_sonar_distance(2)]]))\n"} \ No newline at end of file +{"id": "ddab8e33-eba7-4f02-93af-823c523d63de", "name": "test_sonars", "dom_code": "<xml xmlns=\"https://developers.google.com/blockly/xml\"><block type=\"controls_whileUntil\" id=\"0Mx[mSKoV~Gk1qbv5Wrn\" x=\"68\" y=\"148\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"q8(wB97}Y)d71cgy$yo#\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\" id=\"0fGi]QOF@I*b$5x^?f#A\"><value name=\"TEXT\"><block type=\"text_join\" id=\"HA#?-0mP[+$WL+So^l5J\"><mutation items=\"6\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\"E%5LX*8^Gl-$lv$UIWBv\"><field name=\"TEXT\">Front: </field></block></value><value name=\"ADD1\"><block type=\"coderbot_sonar_get_distance\" id=\"9Mw8Ob~`;a.l/tw}fui`\"><field name=\"SONAR\">0</field></block></value><value name=\"ADD2\"><block type=\"text\" id=\"{xub0XYN;{o:+?BqYjz:\"><field name=\"TEXT\"> Right: </field></block></value><value name=\"ADD3\"><block type=\"coderbot_sonar_get_distance\" id=\"c~T`mQ}cq/AzVk|=_;k#\"><field name=\"SONAR\">1</field></block></value><value name=\"ADD4\"><block type=\"text\" id=\"{oo.?}O~rUC7|]Q9Wu0[\"><field name=\"TEXT\"> Left: </field></block></value><value name=\"ADD5\"><block type=\"coderbot_sonar_get_distance\" id=\"}`5RPkPB/|v%D;^Gc1WM\"><field name=\"SONAR\">2</field></block></value></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(''.join([str(x) for x in ['Front: ', get_bot().get_sonar_distance(0), ' Right: ', get_bot().get_sonar_distance(1), ' Left: ', get_bot().get_sonar_distance(2)]]))\n"} \ No newline at end of file diff --git a/defaults/programs/program_test_sound_hear.json b/defaults/programs/program_test_sound_hear.json index 6d9026d6..e08fe560 100644 --- a/defaults/programs/program_test_sound_hear.json +++ b/defaults/programs/program_test_sound_hear.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"-68\" y=\"108\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\"><value name=\"TEXT\"><block type=\"coderbot_audio_hear\"><value name=\"LEVEL\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">1.0</field></block></value></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_audio().hear(level=100, elapse=1))\n", "name": "test_sound_hear"} \ No newline at end of file +{"id": "458186a6-1285-4da2-b447-5db266b89c45", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"controls_whileUntil\" x=\"-68\" y=\"108\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"text_print\"><value name=\"TEXT\"><block type=\"coderbot_audio_hear\"><value name=\"LEVEL\"><block type=\"math_number\"><field name=\"NUM\">100</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\"><field name=\"NUM\">1.0</field></block></value></block></value></block></statement></block></xml>", "code": "while True:\n get_prog_eng().check_end()\n get_cam().set_text(get_audio().hear(level=100, elapse=1))\n", "name": "test_sound_hear"} \ No newline at end of file diff --git a/defaults/programs/program_test_sound_rec.json b/defaults/programs/program_test_sound_rec.json index d6740905..9efd1c1f 100644 --- a/defaults/programs/program_test_sound_rec.json +++ b/defaults/programs/program_test_sound_rec.json @@ -1 +1 @@ -{"dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables></variables><block type=\"coderbot_audio_record\" id=\"LAC_$g%]@y$*]*==lpr=\" x=\"9\" y=\"56\"><value name=\"FILENAME\"><block type=\"text\" id=\"E2o@Zpp|6ZDTxst,*K%+\"><field name=\"TEXT\">test01.wav</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"_Ru290cPp#|Il6+AK[34\"><field name=\"NUM\">5</field></block></value></block></xml>", "code": "get_audio().record_to_file(filename='test01.wav', elapse=5)\n", "name": "test_sound_rec"} \ No newline at end of file +{"id": "522b2754-65ba-4fa7-8264-e15e819c587b", "dom_code": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><variables></variables><block type=\"coderbot_audio_record\" id=\"LAC_$g%]@y$*]*==lpr=\" x=\"9\" y=\"56\"><value name=\"FILENAME\"><block type=\"text\" id=\"E2o@Zpp|6ZDTxst,*K%+\"><field name=\"TEXT\">test01.wav</field></block></value><value name=\"ELAPSE\"><block type=\"math_number\" id=\"_Ru290cPp#|Il6+AK[34\"><field name=\"NUM\">5</field></block></value></block></xml>", "code": "get_audio().record_to_file(filename='test01.wav', elapse=5)\n", "name": "test_sound_rec"} \ No newline at end of file From f561d460154776956df5f8b386ef5b434a24b8f8 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Thu, 28 Dec 2023 22:34:56 +0000 Subject: [PATCH 53/60] add uuid --- coderbot/activity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index b7e8ab73..c275154b 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -50,7 +50,7 @@ def save(self, activity): if activity.get("default", False) is True: self.activities.update({'default': False}) if self.activities.search(self.query.id == activity.get("id")) == []: - activity = self.activities.insert(activity) + self.activities.insert(activity) else: self.activities.update(activity, self.query.id == activity.get("id")) activity = self.activities.search(self.query.id == activity.get("id"))[0] From 5880e8794e2bf0ed9a83ddf023c2b4f157094fca Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Thu, 28 Dec 2023 22:39:05 +0000 Subject: [PATCH 54/60] add uuid --- coderbot/api.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coderbot/api.py b/coderbot/api.py index 9b381f6c..8569f869 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -326,7 +326,10 @@ def runProgram(id): """ logging.debug("program_exec") prog = prog_engine.load(id) - return prog.execute() + if prog is not None: + return prog.execute() + else: + return {}, 404 def stopProgram(id): """ From 2b1be1954497dbb2f0816936ce7e2327d0d24a8e Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Thu, 28 Dec 2023 23:53:27 +0000 Subject: [PATCH 55/60] add uuid --- coderbot/api.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/coderbot/api.py b/coderbot/api.py index 8569f869..a0b900d8 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -294,6 +294,8 @@ def saveProgram(id, body): overwrite = body.get("overwrite") name = body["name"] existing_program = prog_engine.load(id) + if existing_program is None: + return {}, 404 logging.info("saving - id: %s - name: %s - existing: %s", id, name, str(existing_program is not None)) if existing_program is not None and existing_program.is_stock() == True: return "defaultCannotOverwrite", 400 From ca68f8f3a9b5c1585915c408be6a03ff4c097aaf Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sat, 30 Dec 2023 23:05:51 +0000 Subject: [PATCH 56/60] fix sync activity, program --- coderbot/activity.py | 2 +- coderbot/cloud/__init__.py | 55 +++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/coderbot/activity.py b/coderbot/activity.py index c275154b..79c87a81 100644 --- a/coderbot/activity.py +++ b/coderbot/activity.py @@ -54,7 +54,7 @@ def save(self, activity): else: self.activities.update(activity, self.query.id == activity.get("id")) activity = self.activities.search(self.query.id == activity.get("id"))[0] - logging.info("updating/creating activity: %s", str(activity)) + logging.info("updating/creating activity - id: %s, name: %s", str(activity.get("id")), str(activity.get("name"))) return activity def delete(self, id, logical = True): diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/__init__.py index 7d767859..db507018 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/__init__.py @@ -152,7 +152,7 @@ def sync(self): # Create an instance of the API class api_instance = robot_sync_api.RobotSyncApi(api_client) - self.sync_settings(api_instance, sync_modes["settings"]) + #self.sync_settings(api_instance, sync_modes["settings"]) self.sync_activities(api_instance, sync_modes["activities"]) self.sync_programs(api_instance, sync_modes["programs"]) except Exception as e: @@ -223,7 +223,7 @@ def sync_settings(self, api_instance, sync_mode): logging.info("settings.downstream") self._sync_status["settings"] = "synced" except cloud_api_robot_client.ApiException as e: - logging.warn("Exception when calling settings RobotSyncApi: %s\n" % e) + logging.warn("Exception when calling settings RobotSyncApi: %s\n", e) self._sync_status["registration"] = "failed" def sync_activities(self, api_instance, sync_mode): @@ -251,14 +251,16 @@ def sync_activities(self, api_instance, sync_mode): # cloud activities activities_cloud_map = {} for a in cloud_activities: - if a.get("status") == ACTIVITY_STATUS_ACTIVE: + logging.info("cloud_activities %s, %s", str(a.get("status")), a.get("id")) + if a.get("status") == ACTIVITY_STATUS_ACTIVE: activities_cloud_map[a.get("id")] = a # loop through local for al in activities_local_user: logging.info("activities.syncing: " + str(al.get("id")) + " name: " + str(al.get("name"))) ac = activities_cloud_map.get(al.get("id")) - ac_al_equals = (ac is not None and ac.get("data") == al.get("data")) + ac_al_equals = (ac is not None and ac.get("id") == al.get("id")) + if ac is not None and not ac_al_equals: al["modified"] = al.get("modified", datetime.now(tz=timezone.utc).isoformat()) local_activity_more_recent = datetime.fromisoformat(ac.get("modified")).timestamp() < datetime.fromisoformat(al.get("modified")).timestamp() @@ -285,7 +287,7 @@ def sync_activities(self, api_instance, sync_mode): logging.info("activities.update.downstream: " + al.get("id")) elif ac is None and sync_mode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: body = Activity( - id="", + id=al.get("id"), org_id="", name=al.get("name"), description=al.get("description"), @@ -294,13 +296,14 @@ def sync_activities(self, api_instance, sync_mode): modified=al.get("modified", datetime.now(tz=timezone.utc).isoformat()), status="active", ) + logging.info("activities.create.upstream - id %s, name: %s", al.get("id"), al.get("name")) api_response = api_instance.create_robot_activity(body=body) al["id"] = api_response.body["id"] al["org_id"] = api_response.body["org_id"] Activities.get_instance().save(al) - logging.info("activities.create.upstream: " + al.get("name")) + #logging.info("activities.create.upstream: " + al.get("name")) elif ac is None and sync_mode in [SYNC_DOWNSTREAM]: - Activities.get_instance().delete(al.get("name")) + Activities.get_instance().delete(al.get("id")) logging.info("activities.delete.downstream: " + al.get("name")) for k, ac in activities_cloud_map.items(): @@ -319,17 +322,17 @@ def sync_activities(self, api_instance, sync_mode): for al in activities_local_to_be_deleted: if al.get("id") is not None: logging.info("activities.delete.upstream: " + al.get("name")) - api_response = api_instance.delete_robot_program(path_params={"activity_id":al.get("id")}) + api_response = api_instance.delete_robot_activity(path_params={"activity_id":al.get("id")}) # delete locally permanently Activities.get_instance().delete(al.get("id"), logical=False) # manage local stock activities to be deleted locally - for al in activities_local_stock: - # logging.info("activities.check.stock.locally: " + al.get("name") + " id: " + str(al.get("id"))) - if al.get("id") is not None and activities_cloud_map.get(al.get("id")) is None: - logging.info("activities.delete.stock.locally: " + al.get("name")) - # delete locally permanently - Activities.get_instance().delete(al.get("id"), logical=False) + # for al in activities_local_stock: + # # logging.info("activities.check.stock.locally: " + al.get("name") + " id: " + str(al.get("id"))) + # if al.get("id") is not None and activities_cloud_map.get(al.get("id")) is None: + # logging.info("activities.delete.stock.locally: " + al.get("name")) + # # delete locally permanently + # Activities.get_instance().delete(al.get("id"), logical=False) self._sync_status["activities"] = "synced" except cloud_api_robot_client.ApiException as e: @@ -370,11 +373,7 @@ def sync_programs(self, api_instance, sync_mode): for pl in programs_local_user: pc = programs_cloud_map.get(pl.get("id")) pc_pl_equals = (pc is not None and - pc.get("id") == pl.get("id") and - pc.get("name") == pl.get("name") and - pc.get("code") == pl.get("code") and - pc.get("dom_code") == pl.get("dom_code") and - pc.get("status") == pl.get("status")) + pc.get("id") == pl.get("id")) logging.info("programs.syncing: " + str(pl.get("id")) + " name: " + pl.get("name")) if pc is not None and not pc_pl_equals: @@ -408,7 +407,7 @@ def sync_programs(self, api_instance, sync_mode): elif pc is None and sync_mode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: # cloud program does not exist body = Program( - id="", + id=pl.get("id"), org_id="", name=pl.get("name"), description=pl.get("description", ""), @@ -425,7 +424,7 @@ def sync_programs(self, api_instance, sync_mode): logging.info("programs.create.upstream: " + pl.get("name")) elif pc is None and sync_mode in [SYNC_DOWNSTREAM]: # cloud program does not exist, delete locally since sync_mode is downstream - ProgramEngine.get_instance().delete(pl.get("name")) + ProgramEngine.get_instance().delete(pl.get("id")) logging.info("programs.delete.downstream: " + pl.get("name")) # manage cloud programs not present locally in "active" status @@ -447,15 +446,15 @@ def sync_programs(self, api_instance, sync_mode): logging.info("programs.delete.upstream: " + pl.get("name")) api_response = api_instance.delete_robot_program(path_params={"program_id":pl.get("id")}) # delete locally permanently - ProgramEngine.get_instance().delete(pl.get("name"), logical=False) + ProgramEngine.get_instance().delete(pl.get("id"), logical=False) # manage local stock programs to be deleted locally - for pl in programs_local_stock: - # logging.info("programs.check.stock.locally: " + pl.get("name") + " id: " + str(pl.get("id"))) - if pl.get("id") is not None and programs_cloud_map.get(pl.get("id")) is None: - logging.info("programs.delete.stock.locally: " + pl.get("name")) - # delete locally permanently - ProgramEngine.get_instance().delete(pl.get("name"), logical=False) + # for pl in programs_local_stock: + # # logging.info("programs.check.stock.locally: " + pl.get("name") + " id: " + str(pl.get("id"))) + # if pl.get("id") is not None and programs_cloud_map.get(pl.get("id")) is None: + # logging.info("programs.delete.stock.locally: " + pl.get("name")) + # # delete locally permanently + # ProgramEngine.get_instance().delete(pl.get("name"), logical=False) self._sync_status["programs"] = "synced" except cloud_api_robot_client.ApiException as e: logging.warn("Exception when calling programs RobotSyncApi: %s\n" % e) From e0582ace78aecf6f978ef754ac41f05682be00ab Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 31 Dec 2023 15:00:47 +0000 Subject: [PATCH 57/60] fix daveProgram case of null body --- coderbot/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderbot/api.py b/coderbot/api.py index a0b900d8..176265cc 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -292,7 +292,7 @@ def saveNewProgram(body): def saveProgram(id, body): overwrite = body.get("overwrite") - name = body["name"] + name = body.get("name", None) existing_program = prog_engine.load(id) if existing_program is None: return {}, 404 From e214e5993401a9ef10404e5682f16f78e673b433 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Sun, 31 Dec 2023 22:26:37 +0000 Subject: [PATCH 58/60] sync settings --- coderbot/api.py | 2 +- coderbot/cloud/{__init__.py => sync.py} | 17 ++++++++--------- coderbot/main.py | 6 +++++- coderbot/program.py | 4 ++-- requirements.txt | 2 +- 5 files changed, 17 insertions(+), 14 deletions(-) rename coderbot/cloud/{__init__.py => sync.py} (96%) diff --git a/coderbot/api.py b/coderbot/api.py index 176265cc..c150f44e 100644 --- a/coderbot/api.py +++ b/coderbot/api.py @@ -23,7 +23,7 @@ from musicPackages import MusicPackageManager from program import Program, ProgramEngine from motion import Motion -from cloud import CloudManager +from cloud.sync import CloudManager from balena import Balena from coderbot import CoderBot diff --git a/coderbot/cloud/__init__.py b/coderbot/cloud/sync.py similarity index 96% rename from coderbot/cloud/__init__.py rename to coderbot/cloud/sync.py index db507018..93ed8779 100644 --- a/coderbot/cloud/__init__.py +++ b/coderbot/cloud/sync.py @@ -122,7 +122,7 @@ def registration_status(self): def run(self): while(True): - sync_period = int(Config.read().get("sync_period", "60")) + sync_period = int(Config.read().get("cloud").get("sync_period", "60")) self.sync() sleep(sync_period) @@ -152,11 +152,12 @@ def sync(self): # Create an instance of the API class api_instance = robot_sync_api.RobotSyncApi(api_client) - #self.sync_settings(api_instance, sync_modes["settings"]) + self.sync_settings(api_instance, sync_modes["settings"]) self.sync_activities(api_instance, sync_modes["activities"]) self.sync_programs(api_instance, sync_modes["programs"]) except Exception as e: logging.warn("run.sync.api_not_available: " + str(e)) + raise e logging.info("run.sync.end") self._syncing = False @@ -193,32 +194,30 @@ def sync_settings(self, api_instance, sync_mode): api_response = api_instance.get_robot_setting() cloud_setting_object = api_response.body cloud_setting = json.loads(cloud_setting_object.get('data')) - # sync only the "settings" and "cloud" sections, do not sync "network" config = Config.read() local_setting = { - "settings": config.get("settings"), - #"cloud": config.get("cloud") + "settings": config.get("settings") } local_most_recent = datetime.fromisoformat(cloud_setting_object.get("modified")).timestamp() < Config.modified() cloud_kind_user = cloud_setting_object.get("kind") == ENTITY_KIND_USER + # logging.info(f"cloud_kind_user: {cloud_kind_user}, cloud_setting != local_setting: {cloud_setting != local_setting}, local_most_recent: {local_most_recent}, sync_mode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: {sync_mode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]}") # logging.info("settings.syncing: " + cloud_setting_object.get("id", "") + " name: " + cloud_setting_object.get("name", "")) - if cloud_kind_user and cloud_setting != local_setting and local_most_recent: + if cloud_kind_user and cloud_setting != local_setting and local_most_recent and sync_mode in [SYNC_UPSTREAM, SYNC_BIDIRECTIONAL]: body = Setting( id = cloud_setting_object.get('id'), org_id = cloud_setting_object.get('org_id'), name = cloud_setting_object.get('name'), description = cloud_setting_object.get('description'), data = json.dumps(local_setting), - kind = local_setting.get("kind", ENTITY_KIND_STOCK), + kind = cloud_setting_object.get("kind"), modified = datetime.now().isoformat(), status = cloud_setting_object.get('status'), ) api_response = api_instance.set_robot_setting(body) logging.info("settings.upstream") - elif cloud_setting != local_setting: # setting, down + elif cloud_setting != local_setting and sync_mode in [SYNC_DOWNSTREAM, SYNC_BIDIRECTIONAL]: # setting, down config["settings"] = cloud_setting["settings"] - #config["cloud"] = cloud_setting["cloud"] Config.write(config) logging.info("settings.downstream") self._sync_status["settings"] = "synced" diff --git a/coderbot/main.py b/coderbot/main.py index 9a715aa6..fb001fb4 100644 --- a/coderbot/main.py +++ b/coderbot/main.py @@ -19,7 +19,7 @@ from cnn.cnn_manager import CNNManager from event import EventManager from coderbot import CoderBot -from cloud import CloudManager +from cloud.sync import CloudManager # Logging configuration logger = logging.getLogger() @@ -66,6 +66,10 @@ def run_server(): try: try: settings = Config.read().get("settings") + # if settings.get("id") is None: + # settings["id"] = str(uuid.uuid4()) # init uuid for local settings + # Config.write() + app.settings = settings network_settings = Config.read().get("network") diff --git a/coderbot/program.py b/coderbot/program.py index d78e9d4d..0cf275ff 100644 --- a/coderbot/program.py +++ b/coderbot/program.py @@ -192,9 +192,9 @@ class Program: def dom_code(self): return self._dom_code - def __init__(self, name, id=str(uuid.uuid4()), description=None, code=None, dom_code=None, kind=PROGRAM_KIND_USER, modified=None, status=None): + def __init__(self, name, id=None, description=None, code=None, dom_code=None, kind=PROGRAM_KIND_USER, modified=None, status=None): self._thread = None - self._id = id + self._id = id if id is not None else str(uuid.uuid4()) self._name = name self._description = description self._dom_code = dom_code diff --git a/requirements.txt b/requirements.txt index dc2210a3..fe28f3bf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,7 +23,7 @@ numpy==1.24.3 Pillow==10.1.0 protobuf==4.25.1 opencv-contrib-python==4.5.5.62 -tflite-runtime==2.12.0 +tflite-runtime==2.13.0 pytesseract==0.3.10 picamera==1.13 pyzbar==0.1.9 From 93735f79af9fead604dcf3b3f59331d1a15b9182 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Wed, 28 Feb 2024 23:13:31 +0100 Subject: [PATCH 59/60] fix detectMultiScale --- coderbot/cv/image.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coderbot/cv/image.py b/coderbot/cv/image.py index 24dd9efb..e9c6f12e 100644 --- a/coderbot/cv/image.py +++ b/coderbot/cv/image.py @@ -39,8 +39,7 @@ class Image(): _aruco_dict = cv2.aruco.Dictionary_get(cv2.aruco.DICT_ARUCO_ORIGINAL) _aruco_parameters = cv2.aruco.DetectorParameters_create() - #_face_cascade = cv2.CascadeClassifier('/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml') - _face_cascade = cv2.CascadeClassifier('/usr/share/opencv/lbpcascades/lbpcascade_frontalface.xml') + _face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') def __init__(self, array): self._data = array @@ -85,7 +84,8 @@ def get_transform(cls, image_size_x): return tx def find_faces(self): - faces = self._face_cascade.detectMultiScale(self._data) + gray = cv2.cvtColor(self._data, cv2.COLOR_BGR2GRAY) + faces = self._face_cascade.detectMultiScale(gray) return faces def filter_color(self, color): From 13e081aab3878921fd0074328e0b181ee2f4e4a1 Mon Sep 17 00:00:00 2001 From: previ <roberto.previtera@gmail.com> Date: Thu, 28 Mar 2024 23:02:03 +0100 Subject: [PATCH 60/60] schemathesis==3.24.3 --- .github/workflows/build_backend.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml index 41ea5341..e78c948a 100644 --- a/.github/workflows/build_backend.yml +++ b/.github/workflows/build_backend.yml @@ -34,7 +34,7 @@ jobs: mkdir -p schemathesis python3 -m venv schemathesis . schemathesis/bin/activate - pip install schemathesis + pip install schemathesis==3.24.3 st run --endpoint 'activities' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json #st run --endpoint 'media' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json st run --endpoint 'control/speak' --hypothesis-max-examples=10 --request-timeout=20 http://localhost:5000/api/v1/openapi.json