def __init__(self): self.logger = get_component_logger("UART.Communicator") self.target_movement = (0, 0) self.latest_status = (0, 0, 0, 0, 0) self.uart = None self.read_queue = collections.deque() self.movement_command_updated_handler = None self.status_updated_handler = None
""" import time try: from picamera.array import PiRGBArray from picamera import PiCamera except ImportError: # We are not on a raspberry pi from unittest import mock PiRGBArray = mock.MagicMock() PiCamera = mock.MagicMock() from hns.logger import get_component_logger logger = get_component_logger("Camera") class Camera: @classmethod def from_config(cls, config): logger.info( "Using Camera settings: resolution=%s, rotation=%s, shutter_speed=%s, iso=%s", config["resolution"], config["rotation"], config["shutter_speed"], config["iso"]) resolution = config.get("resolution").split("x") rotation = config.getint("rotation") shutter_speed = config.getint("shutter_speed") iso = config.getint("iso") return cls((int(resolution[0]), int(resolution[1])), rotation, shutter_speed, iso)
""" Implements functionality to estimate the distances on an image. """ from hns.logger import get_component_logger logger = get_component_logger("DistanceEstimator") class DistanceEstimator: """Estimate distances to a cropped image. The distance is currently estimated by using the dimensions of a cropped image. This estimater needs calibration. """ def estimate(self, cropped_image): """Estimate the distance to the cropped image :return distance to stopsign in Millimeter mm. """ height, *_ = cropped_image.shape return ((-4.1225) * height) + 372.02 - 32
""" Entry point for 2/4 HNS """ import sys import pathlib import logging import argparse import threading from hns.core import HNS from hns.logger import get_component_logger logger = get_component_logger("main") logging.basicConfig(level=logging.INFO) #: Holds a global thread-specific context variable for the HNS app context = threading.local() def main(args=sys.argv[1:]): """ Main entry point for the 2/4 HNS control software. """ parser = argparse.ArgumentParser(description="2/4 HNS Control Software") parser.add_argument("configfile", metavar="CONFIG", nargs="?", default=pathlib.Path(__file__).parent / "../configs/stable.ini",
""" HNS Digit Detector """ from pathlib import Path import cv2 import numpy as np from keras.models import load_model from hns.logger import get_component_logger from hns.utils import timeit logger = get_component_logger("DigitDetector") class DigitDetector: """ Functionality to detect a digit from an image. Args: config: the Digit Detector configuration """ @classmethod def from_config(cls, config): model_path = Path(__file__).parent / config["model"] logger.info("Using model=%s", model_path) return cls(model_path) def __init__(self, model_path): self.model_path = model_path
def __init__(self): self.logger = get_component_logger("UART.Communication") self.communicator = UartCommunicator() self.runner = UartRunner(self.communicator)
""" Implement the interface to the crane for the cube pick up. """ from threading import Event from hns.logger import get_component_logger logger = get_component_logger("Crane") class Crane: """ Interface to the Crane responsible to pick up and hold the cube. """ def __init__(self): #: Holds an Event which indicates if the cube was picked up self.__cube_picked_up = Event() def picked_up(self): """Notify the Crane that the cube is successfully picked up""" logger.info("Cube has been picked up") self.__cube_picked_up.set() def wait_for_cube(self): """Wait until the cube is picked up""" logger.debug("Waiting for the cube to be picked up") picked = self.__cube_picked_up.wait() logger.debug("Finished waiting for the cube to be picked up: %d", picked)
import operator import multiprocessing from collections import defaultdict from hns.logger import get_component_logger from hns.signal_detector import SignalDetector, SignalType from hns.digit_detector import DigitDetector from hns.config import parse_config logger = get_component_logger("AsyncInfosignalDetector") class AsyncInfosignalDetector: """ Async infosignal detector using multiprocessing Args: config: the config async_camera: the async camera interface """ @classmethod def from_config(cls, configfile, config, async_camera): number_of_workers = config["workers"].getint("number_of_workers") logger.info( "Using AsyncInfosignalDetector settings: number_of_workers=%d", number_of_workers) return cls(configfile, config, number_of_workers, async_camera) def __init__(self, configfile, config, number_of_workers, async_camera): #: Holds the config self.configfile = configfile
from threading import Thread from hns.config import parse_config from hns.logger import get_component_logger from hns.uart_communication import UartCommunication from hns.crane import Crane from hns.camera import Camera from hns.signal_detector import SignalDetector, SignalType from hns.digit_detector import DigitDetector from hns.distance_estimator import DistanceEstimator from hns.sound_output import SoundOutput from hns.async_camera import AsyncCamera from hns.async_infosignal_detector import AsyncInfosignalDetector logger = get_component_logger("HNS") telemetry_logger = get_component_logger("telemetry") class HNS: """ Core Application for the 2/4 HNS control software. Args: configfile (str, pathlib.Path): path to the config file """ def __init__(self, configfile, debug=False): self.debug = debug self.config = parse_config(configfile) self.wheel_revolutions = 0 logger.info("Created HNS from config %s", configfile)
""" HNS Signal Detector """ from pathlib import Path from collections import namedtuple import cv2 import numpy as np from hns.logger import get_component_logger from hns.utils import timeit from hns.models import SignalType logger = get_component_logger("SignalDetector") # Type to represent a detected signal DetectedSignal = namedtuple("DetectedSignal", ["type", "image", "data"]) def sliding_window(image, window_size, step_size=1): for y in range(0, image.shape[0], step_size): for x in range(0, image.shape[1], step_size): yield (x, y, image[y:y + window_size[1], x:x + window_size[0]]) class SignalDetector: """ Functionality to detect a signal. Supported Signals are:
import time try: import RPi.GPIO as GPIO except (ImportError, RuntimeError): # NOTE(TF): RPi.GPIO refuses to be imported on systems # other than the RPI. # So we just provide a mock for testing. from unittest import mock GPIO = mock.MagicMock() from hns.logger import get_component_logger logger = get_component_logger("Sound") class SoundOutput: @classmethod def from_config(cls, config): logger.info( "Using SoundOutput settings: buzzer_pin=%s, pitch=%s, pitch_duration=%s, interval=%s", config["buzzer_pin"], config["pitch"], config["pitch_duration"], config["interval"], ) buzzer_pin = config.getint("buzzer_pin") pitch = config.getint("pitch") pitch_duration = config.getfloat("pitch_duration") interval = config.getfloat("interval")