Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitaminiaev committed Jan 1, 2023
1 parent 340edc9 commit 3cb1879
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

from controller.core_logic.entity.feature import Feature
from controller.core_logic.lapshin_algorithm.binding_probe_to_feature_interface import BindingProbeToFeatureInterface
from controller.core_logic.lapshin_algorithm.recognition.feature_recognizer_interface import FeatureRecognizerInterface
from controller.core_logic.scan_algorithms import ScanAlgorithms
from controller.core_logic.lapshin_algorithm.service.recognition.feature_recognizer_interface import FeatureRecognizerInterface
from controller.core_logic.service.feature_scanner import ScannerInterface


Expand Down Expand Up @@ -45,7 +44,6 @@ def __init__(self, feature_recognizer: FeatureRecognizerInterface, feature_scann
self.delay_between_iterations = 0.1
self.stop = True
self.optimal_height = None
self.scan_algorithm = ScanAlgorithms(0)
self.feature_recognizer = feature_recognizer

def bind_to_feature(self, feature: Feature) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from controller.core_logic.entity.atom import Atom
from controller.core_logic.entity.feature import Feature
from controller.core_logic.lapshin_algorithm.recognition.feature_recognizer_interface import FeatureRecognizerInterface
from controller.core_logic.lapshin_algorithm.service.recognition.feature_recognizer_interface import FeatureRecognizerInterface


class LapshinFeatureRecognizer(FeatureRecognizerInterface):
Expand Down
30 changes: 22 additions & 8 deletions controller/core_logic/service/feature_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,37 @@
import numpy as np
from controller.constants import DTO_Y, DTO_Z, DTO_X
from controller.core_logic.entity.feature import Feature
from controller.core_logic.scan_algorithms import ScanAlgorithms
from controller.core_logic.scan_algorithms import ScanAlgorithms, FIELD_SIZE
from controller.core_logic.service.scanner_interface import ScannerInterface


class FeatureScanner(ScannerInterface):

def __init__(self, get_val_func, set_x_func, set_y_func, touching_surface_event: Event, external_surface):
def __init__(self, get_val_func, set_x_func, set_y_func, touching_surface_event: Event, external_surface, push_coord_to_mk, delay: float):
self.external_surface = external_surface
self.touching_surface_event = touching_surface_event
self.set_y_func = set_y_func
self.set_x_func = set_x_func
self.get_val_func = get_val_func
self.scan_algorithm = ScanAlgorithms(0)
self.push_coord_to_mk = push_coord_to_mk
self.scan_algorithm = ScanAlgorithms(delay)

def scan_aria_around_feature(self, feature: Feature) -> np.ndarray:
x_max, x_min, y_max, y_min = self.__calc_aria_borders(feature)
x_min, x_max, y_min, y_max = self.__calc_aria_borders(feature)

return self.scan_aria(x_min, y_min, x_max, y_max)

def scan_aria(self, x_min: int = 0, y_min: int = 0, x_max: int = FIELD_SIZE, y_max: int = FIELD_SIZE) -> np.ndarray:
self.set_x_func(
x_max,
self.get_val_func(DTO_Y),
self.get_val_func(DTO_Z),
(
x_max,
self.get_val_func(DTO_Y),
self.get_val_func(DTO_Z)
)
)

self.push_coord_to_mk(DTO_Z, True)

self.scan_algorithm.scan_line_by_line(
self.get_val_func,
self.set_x_func,
Expand All @@ -48,10 +56,16 @@ def go_in_direction(self, vector: np.ndarray) -> None:
self.set_x_func((self.get_val_func(DTO_X) + vector[0], self.get_val_func(DTO_Y), z_current))
self.set_y_func((self.get_val_func(DTO_X), self.get_val_func(DTO_Y) + vector[1], z_current))

def switch_scan(self) -> None:
if self.scan_algorithm.stop:
self.scan_algorithm.stop = False
else:
self.scan_algorithm.stop = True

def __calc_aria_borders(self, feature):
# todo вычислить максимальный радиус фичи и прибавлять к нему const
x_min = feature.coordinates[0] - 6 # todo вычислять из радиуса фичи
y_min = feature.coordinates[1] - 6
x_max = feature.coordinates[0] + 7
y_max = feature.coordinates[1] + 7
return x_max, x_min, y_max, y_min
return x_min, x_max, y_min, y_max
9 changes: 9 additions & 0 deletions controller/core_logic/service/scanner_interface.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from abc import ABC, abstractmethod
import numpy as np
from controller.core_logic.entity.feature import Feature
from controller.core_logic.scan_algorithms import FIELD_SIZE


class ScannerInterface(ABC):
Expand All @@ -9,10 +10,18 @@ class ScannerInterface(ABC):
def scan_aria_around_feature(self, feature: Feature) -> np.ndarray:
pass

@abstractmethod
def scan_aria(self, x_min: int = 0, y_min: int = 0, x_max: int = FIELD_SIZE, y_max: int = FIELD_SIZE) -> np.ndarray:
pass

@abstractmethod
def go_to_feature(self, feature: Feature) -> None:
pass

@abstractmethod
def go_in_direction(self, vector: np.ndarray) -> None:
pass

@abstractmethod
def switch_scan(self) -> None:
pass
42 changes: 17 additions & 25 deletions controller/frontend/manipulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import matplotlib as plt
from controller.core_logic.scan_algorithms import ScanAlgorithms, FIELD_SIZE
from controller.core_logic.exceptions.touching_surface import TouchingSurface
from controller.core_logic.service.feature_scanner import FeatureScanner
from controller.core_logic.service.scanner_interface import ScannerInterface
from controller.frontend.graph import Graph, GraphFrame
from tkinter import Frame, Button, Scale, Canvas, StringVar, Entry, Label, constants as c
import tkinter as tk
Expand Down Expand Up @@ -147,7 +149,7 @@ def __init__(self, tk: Manipulator):
self.__load_data_entry.place(width=20, height=5)
self.__load_data_btn = Button(self.__frame_debug, text='load data', command=self.__load_file)
self.default_bg = self.__stop_render_btn.cget("background")
self.scanAlgorithm = ScanAlgorithms(SLEEP_BETWEEN_SCAN_ITERATION)
self.feature_scanner = self.create_scanner(self.tk.graph.frame.atoms_logic.touching_surface_event)
self.__bind_scale_to_tip()

def __transmitting_value_x(self, x: int):
Expand Down Expand Up @@ -258,54 +260,44 @@ def __go_scan_count(self):

def __go_n_scan(self, count, vars):
for _ in range(count):
self.scanAlgorithm.stop = False
self.feature_scanner.scan_algorithm.stop = False
self._go_auto(*vars)
self.tk.graph.frame.atoms_logic.remember_surface()
self.tk.graph.frame.atoms_logic.gen_new_noise()
self.tk.graph.frame.atoms_logic.remove_noise()

def auto(self):
if self.scanAlgorithm.stop:
self.scanAlgorithm.stop = False
else:
self.scanAlgorithm.stop = True
self.feature_scanner.switch_scan()
vars = self.__get_params()
threading.Thread(target=self._go_auto, args=vars).start()

def __get_params(self) -> tuple:
params = (self.tk.graph.frame.atoms_logic.touching_surface_event,)
params = ()
if self.__scan_vars_x_min.get().strip() != '': params += (int(self.__scan_vars_x_min.get().strip()),)
if self.__scan_vars_y_min.get().strip() != '': params += (int(self.__scan_vars_y_min.get().strip()),)
if self.__scan_vars_x_max.get().strip() != '': params += (int(self.__scan_vars_x_max.get().strip()),)
if self.__scan_vars_y_max.get().strip() != '': params += (int(self.__scan_vars_y_max.get().strip()),)

return params

def _go_auto(self, touching_surface_event, x_min: int = 0, y_min: int = 0, x_max: int = FIELD_SIZE, y_max: int = FIELD_SIZE) -> None:
def _go_auto(self, x_min: int = 0, y_min: int = 0, x_max: int = FIELD_SIZE, y_max: int = FIELD_SIZE) -> None:
self.feature_scanner.scan_aria(x_min, y_min, x_max, y_max)

def create_scanner(self, touching_surface_event) -> FeatureScanner:
get_val_func = self.tk.graph.frame.atoms_logic.get_dto_val
self.tk.graph.frame.atoms_logic.set_val_to_dto(
DTO_X,
(
x_max,
get_val_func(DTO_Y),
get_val_func(DTO_Z)
),
True
)
set_x_func = self.tk.graph.frame.atoms_logic.set_val_dto_curried(DTO_X)
set_y_func = self.tk.graph.frame.atoms_logic.set_val_dto_curried(DTO_Y)
self.tk.graph.frame.atoms_logic.push_z_coord_to_mk(True)

self.scanAlgorithm.scan_line_by_line(
push_coord_to_mk = self.tk.graph.frame.atoms_logic.push_coord_to_mk
feature_scanner = FeatureScanner(
get_val_func,
set_x_func,
set_y_func,
touching_surface_event,
x_min=x_min,
y_min=y_min,
x_max=x_max,
y_max=y_max,
self.tk.graph.frame.atoms_logic.surface_data,
push_coord_to_mk,
SLEEP_BETWEEN_SCAN_ITERATION
)
return feature_scanner

def __stop_go_render(self):
if self.tk.graph.frame.quit:
Expand Down Expand Up @@ -373,7 +365,7 @@ def scale_set(self, x, y, z):

def change_button(self, event, cause):
cause = {
'scanAlgorithm.stop': {'condition': not self.scanAlgorithm.stop, 'button': self.__auto_on_off_btn},
'scanAlgorithm.stop': {'condition': not self.feature_scanner.scan_algorithm.stop, 'button': self.__auto_on_off_btn},
'tk.graph.frame.quit': {'condition': not self.tk.graph.frame.quit, 'button': self.__stop_render_btn},
'tk.graph.frame.condition_build_surface': {'condition': self.tk.graph.frame.condition_build_surface, 'button': self.__build_surface_btn},
'tk.graph.frame.condition_scan_mode': {'condition': self.tk.graph.frame.atoms_logic.is_scan_mode(), 'button': self.__scan_mode},
Expand Down
3 changes: 1 addition & 2 deletions stub_microcontroller/servo_controller.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from surface_generator import *
import numpy as np
from noise_generator import NoiseGenerator

DEPARTURE_BY_Z = 10
OFFSET = 400
OFFSET = 425

class ServoController:

Expand Down
2 changes: 1 addition & 1 deletion stub_microcontroller/surface_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

MAX_FIELD_SIZE = 1000
GENERAL_HEIGHT = 20
OFFSET = 400
OFFSET = 425
ATOMS = [
(10 + OFFSET, 5 + OFFSET),
(10 + OFFSET, 25 + OFFSET),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import sys, os
path = os.path.abspath("../../../stub_microcontroller")
root = sys.path[1]
path = os.path.join(root, "stub_microcontroller")
if path not in sys.path:
sys.path.insert(0, path)
sys.path.insert(0, os.path.abspath("../../../stub_microcontroller"))

from controller.core_logic.service.feature_scanner import FeatureScanner
from unittest import TestCase
from controller.core_logic.entity.atom import Atom
from controller.core_logic.lapshin_algorithm.recognition.lapshin_feature_recognizer import LapshinFeatureRecognizer
from controller.core_logic.lapshin_algorithm.service.recognition.lapshin_feature_recognizer import LapshinFeatureRecognizer
from unittest.mock import MagicMock
from controller.core_logic.lapshin_algorithm.binding_probe_to_feature import BindingProbeToFeature
from stub_microcontroller.surface_generator import SurfaceGenerator
Expand All @@ -20,7 +22,8 @@ def setUp(self) -> None:
set_y_func = MagicMock()
touching_surface_event = MagicMock()
external_surface = MagicMock()
scanner = FeatureScanner(get_val_func, set_x_func, set_y_func, touching_surface_event, external_surface)
push_coord_to_mk = MagicMock()
scanner = FeatureScanner(get_val_func, set_x_func, set_y_func, touching_surface_event, external_surface, push_coord_to_mk, 0)

self.binding_probe_to_feature = BindingProbeToFeature(
LapshinFeatureRecognizer(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import sys, os

path = os.path.abspath("../../../stub_microcontroller")
root = sys.path[1]
path = os.path.join(root, "stub_microcontroller")
if path not in sys.path:
sys.path.insert(0, path)
sys.path.insert(0, os.path.abspath("../../../stub_microcontroller"))

from controller.core_logic.lapshin_algorithm.recognition.lapshin_feature_recognizer import LapshinFeatureRecognizer
from controller.core_logic.lapshin_algorithm.service.recognition.lapshin_feature_recognizer import LapshinFeatureRecognizer
from stub_microcontroller.surface_generator import SurfaceGenerator
from unittest import TestCase
import numpy as np
Expand Down
31 changes: 28 additions & 3 deletions tests/scan_algorithm/fixture_scan_algo.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,37 @@
y_max = 5
INITIAL_DATA = (x_min, y_min, x_max, y_max)

X_DATA_WITHOUT_SURFACE = [call((5, 0, 75))]
X_DATA_WITHOUT_SURFACE = [
call((5, 0, 75)),
call((5, 1, 75)),
call((4, 1, 75)),
call((3, 1, 75)),
call((2, 1, 75)),
call((1, 1, 75)),
call((1, 2, 75)),
call((2, 2, 75)),
call((3, 2, 75)),
call((4, 2, 75)),
call((5, 2, 75)),
call((5, 3, 75)),
call((4, 3, 75)),
call((3, 3, 75)),
call((2, 3, 75)),
call((1, 3, 75)),
call((1, 4, 75)),
call((2, 4, 75)),
call((3, 4, 75)),
call((4, 4, 75)),
call((5, 4, 75)),
call((5, 5, 75)),
call((4, 5, 75)),
call((3, 5, 75)),
call((2, 5, 75)),
call((1, 5, 75))
]

Y_DATA_WITHOUT_SURFACE = []

Z_DATA_WITHOUT_SURFACE = [call((0, 0, 75))]

X_DATA_WITH_SURFACE = [call((5, 0, 75))]

Y_DATA_WITH_SURFACE = []
Expand Down
21 changes: 13 additions & 8 deletions tests/scan_algorithm/test_scan_algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@
from controller.core_logic.atom_logic import AtomsLogic
from controller.core_logic.dto import Dto
from controller.core_logic.exceptions.touching_surface import TouchingSurface
from controller.core_logic.scan_algorithms import ScanAlgorithms
from controller.core_logic.service.feature_scanner import FeatureScanner
from controller.frontend.manipulator import ConstructorFrames
from tests.scan_algorithm.fixture_scan_algo import INITIAL_DATA, X_DATA_WITHOUT_SURFACE, \
Y_DATA_WITHOUT_SURFACE, Z_DATA_WITHOUT_SURFACE, X_DATA_WITH_SURFACE, Y_DATA_WITH_SURFACE, Z_DATA_WITH_SURFACE
Y_DATA_WITHOUT_SURFACE, X_DATA_WITH_SURFACE, Y_DATA_WITH_SURFACE


class FakeConstructorFrames(ConstructorFrames):

def __init__(self, atoms_logic):
self.scanAlgorithm = ScanAlgorithms(0)
def __init__(self, atoms_logic: AtomsLogic):
get_val_func = atoms_logic.get_dto_val
set_x_func = atoms_logic.set_val_dto_curried(DTO_X)
set_y_func = atoms_logic.set_val_dto_curried(DTO_Y)
touching_surface_event = MagicMock()
external_surface = atoms_logic.surface_data
push_coord_to_mk = MagicMock()
self.feature_scanner = FeatureScanner(get_val_func, set_x_func, set_y_func, touching_surface_event, external_surface, push_coord_to_mk, 0)
self.scanAlgorithm = self.feature_scanner.scan_algorithm
self.tk = Mock()
self.tk.graph.frame.atoms_logic = atoms_logic

Expand Down Expand Up @@ -62,23 +69,21 @@ def test_auto_scan_without_surface(self):
atoms_logic = self.__get_atoms_logic(AtomsLogic, 10, 10, MAX)

fake_constructor_frames = FakeConstructorFrames(atoms_logic)
fake_constructor_frames.scanAlgorithm.stop = False
fake_constructor_frames.feature_scanner.scan_algorithm.stop = False
fake_constructor_frames._go_auto(*INITIAL_DATA)

atoms_logic.dto_x.mock_value.assert_has_calls(X_DATA_WITHOUT_SURFACE, any_order=False)
atoms_logic.dto_y.mock_value.assert_has_calls(Y_DATA_WITHOUT_SURFACE, any_order=False)
atoms_logic.dto_z.mock_value.assert_has_calls(Z_DATA_WITHOUT_SURFACE, any_order=False)

def test_auto_scan_with_surface(self):
atoms_logic = self.__get_atoms_logic(FakeAtomsLogic, 10, 10, MAX)

fake_constructor_frames = FakeConstructorFrames(atoms_logic)
fake_constructor_frames.scanAlgorithm.stop = False
fake_constructor_frames.feature_scanner.scan_algorithm.stop = False
fake_constructor_frames._go_auto(*INITIAL_DATA)

atoms_logic.dto_x.mock_value.assert_has_calls(X_DATA_WITH_SURFACE, any_order=False)
atoms_logic.dto_y.mock_value.assert_has_calls(Y_DATA_WITH_SURFACE, any_order=False)
atoms_logic.dto_z.mock_value.assert_has_calls(Z_DATA_WITH_SURFACE, any_order=False)

def __get_atoms_logic(self, atoms_logic_class, x_max, y_max, z_max):
atoms_logic = atoms_logic_class(x_max, y_max, self.server_mock)
Expand Down

0 comments on commit 3cb1879

Please sign in to comment.