Пример #1
0
 def test_get_rover_commands(self):
     controller = Controller(ControllerTestCase.path)
     rover_commands = controller.get_rover_commands()
     expected_commands = [['1', '2', 'N'], ['LMLMLMLMM'], ['3', '3', 'E'], ['MMRMMRMRRM']]
     for i, j in enumerate(rover_commands):
         self.assertEqual(rover_commands[i], expected_commands[i],
                          msg='{0}'.format(ControllerTestCase.error_list['10']))
Пример #2
0
async def start(websocket, path):
    ctrl = Controller()
    setup = Setup()

    p_rate = CONF.GUI['web_socket_pulse_rate']
    w_rate = CONF.GUI['web_socket_wait_rate']

    SCRfield = setup.field()
    SCRenv = setup.env(SCRfield=SCRfield, roll='WS')

    GUIraw = copy(CONF.GUI['GUIraw'])
    SCRenv['log'].output(lv='INFO', log='new conection.')

    try:
        while True:
            time.sleep(p_rate)
            send_json, GUIraw = ctrl.websocket_chaser(SCRfield=SCRfield,
                                                      GUIenv=SCRenv,
                                                      GUIraw=GUIraw)
            if (len(send_json.keys()) == 0):
                time.sleep(w_rate)
                await websocket.send('check')
            else:
                await websocket.send(json.dumps(send_json))
    except websockets.exceptions.ConnectionClosedError:
        SCRenv['log'].output(lv='INFO', log='close conection.')
        GUIraw = {}
Пример #3
0
def main():
    profile_path = os.path.join(os.environ['HOME'], '.pmaya')

    app = QtGui.QApplication(sys.argv)
    controller = Controller(app)
    controller.loadProfile(profile_path)
    app.exec_()
    controller.saveProfile(profile_path)
Пример #4
0
def run() -> None:
    rospy.init_node("follow_wall")

    Controller.run(
        model=init_model,
        update=update,
        subscriptions=subscriptions,
    )

    rospy.spin()
Пример #5
0
def run() -> None:
    rospy.init_node("drive_square")

    Controller.run(
        model=init_model,
        update=update,
        subscriptions=subscriptions,
    )

    rospy.spin()
Пример #6
0
def main():
    '''
    需要安装'crawlergo','dirsearch','oneforall','xray_linux_amd64'到tools目录
    定义是自动下载,但是由于github问题可能经常会出错;出错的话手动下载解压最好;
    具体链接在download_tools.py里有
    '''
    if not os.path.exists(os.path.join(TOOLS_DIR, 'install.lock')):
        print('tools not exists; downloading ...')
        time.sleep(3)
        from lib.download_tools import download
        download()

    arguments = ArgumentParser()
    controller = Controller(arguments)
    controller.assign_task()
Пример #7
0
def main():
    controller = Controller()

    kwargs = {"num_workers": 1, "pin_memory": True} if FLAGS.CUDA else {}
    train_loader = DataLoader(
        datasets.Omniglot(
            "data",
            train=True,
            download=True,
            transform=transforms.Compose([
                transforms.ToTensor(),
                # transforms.Normalize(mean, std) should add for better performance, + other transforms
            ])),
        batch_sizer=FLAGS.BATCH_SIZE,
        shuffle=True,
        **kwargs)

    test_loader = DataLoader(
        datasets.Omniglot(
            "data",
            train=False,
            transform=transforms.Compose([
                transforms.ToTensor(),
                # transforms.Normalize(mean, std) should add for better performance, + other transforms
            ])),
        batch_sizer=FLAGS.BATCH_SIZE,
        shuffle=True,
        **kwargs)

    if FLAGS.TRAIN:
        train(controller, train_loader)
    else:
        test(controller, test_loader)
Пример #8
0
    def __init__(self):
        self.script_path = os.path.dirname(os.path.realpath(__file__))

        self.arguments = ArgumentParser(self.script_path)

        if self.arguments.quiet:
            self.output = PrintOutput(self.arguments.color)
        else:
            self.output = CLIOutput(self.arguments.color)

        self.controller = Controller(self.script_path, self.arguments,
                                     self.output)
Пример #9
0
def main():
    try:

        _loader = ConfigLoader(Level.INFO)
        filename = 'config.yaml'
        _config = _loader.configure(filename)
        _queue = MessageQueue(Level.INFO)

        _ifs = IntegratedFrontSensor(_config, _queue, Level.INFO)
        _motors = Motors(_config, None, None, Level.INFO)

        # configure Controller and Arbitrator
        _controller = Controller(_config, _ifs, _motors, _callback_shutdown,
                                 Level.INFO)
        _arbitrator = Arbitrator(_config, _queue, _controller, Level.WARN)

        print(Fore.RED + 'roam...' + Style.RESET_ALL)
        _ifs.enable()
        _arbitrator.start()
        #       _controller.enable()
        _roam = RoamBehaviour(_motors, Level.INFO)
        _roam.roam()
        while _roam.is_roaming():
            print(Fore.BLACK + Style.DIM + '(roaming)' + Style.RESET_ALL)
            time.sleep(1.0)

        print(Fore.YELLOW + 'complete: closing...' + Style.RESET_ALL)
        _motors.close()
        print(Fore.YELLOW + 'closed.' + Style.RESET_ALL)
        sys.exit(0)

    except KeyboardInterrupt:
        print('test complete')
        sys.exit(0)
    except Exception as e:
        print(Fore.RED + Style.BRIGHT +
              'error in PID controller: {}'.format(e))
        traceback.print_exc(file=sys.stdout)
        sys.exit(1)
Пример #10
0
#!/usr/bin/env python3.8
from lib.views.Frames import topView
from lib.controller import Controller
import wx

if __name__ == "__main__":
    app = wx.App(False)
    controller = Controller(app)
    app.MainLoop()
Пример #11
0
def main():
    """
    Prepara las ventanas, define modelos, controlador y vista y corre el programa
    :return: void
    """

    # Se obtiene el checksum del juego
    checksum = [path_checksum('lib', VERBOSE),
                md5file('main.py', VERBOSE).upper(),
                path_checksum('bin', VERBOSE)]

    # Se cargan las configuraciones
    control_config = configLoader(DIR_CONFIG + "control.ini", verbose=VERBOSE)
    game_config = configLoader(DIR_CONFIG + "game.ini", verbose=VERBOSE)
    map_config = configLoader(DIR_CONFIG + "map.ini", verbose=VERBOSE)
    score_config = configLoader(DIR_CONFIG + "scoreboard.ini", verbose=VERBOSE)
    user_config = configLoader(DIR_CONFIG + "user.ini", verbose=VERBOSE)
    view_config = configLoader(DIR_CONFIG + "view.ini", verbose=VERBOSE)
    window_config = configLoader(DIR_CONFIG + "window.ini", verbose=VERBOSE)
    world_config = configLoader(DIR_CONFIG + "world.ini", verbose=VERBOSE)

    # Se carga el idioma
    lang = langs.langLoader(game_config.getValue("LANG"))  # @UndefinedVariable

    # Se carga la información de la pantalla del cliente
    display_info = pygame.display.Info()  # @UndefinedVariable

    # Se comprueba que el nombre de jugador no sea Player, si no es valido se pide uno nuevo
    if not username.validate(
            user_config.getValue("NAME")):  # @UndefinedVariable
        new_name = username.request(lang.get(111),
                                    lang.get(112))  # @UndefinedVariable
        if new_name is not username.NO_VALID_NAME:  # @UndefinedVariable
            user_config.setParameter("NAME", new_name)
            user_config.export()
        else:
            utils.destroyProcess()  # @UndefinedVariable

    # Creación de ventana
    window = Window(window_config, lang.get(10),
                    pygame.image.load(getIcons("icon")),
                    display_info)  # @UndefinedVariable
    clock = pygame.time.Clock()  # reloj @UndefinedVariable
    fps = int(game_config.getValue("FPS"))  # fps a dibujar

    # Se crea el mundo
    world = World(world_config, map_config, window, checksum, score_config,
                  user_config, lang, game_config, verbose=VERBOSE)
    # TEST: world.loadMap(1)

    # Se crean los menús de inicio y pause
    menus = Createuimenu(lang, window, world, game_config, user_config,
                         view_config, window_config, world_config, map_config)

    # Se crea la vista
    vista = View(window, clock, world, lang, view_config, menus)
    menus.addView(vista)

    # Se crea el controlador
    control = Controller(world, clock, lang, control_config, window, menus,
                         verbose=VERBOSE)
    menus.addController(control)
    vista.add_controller(control)

    # Se lanza el mainloop
    while True:
        clock.tick(fps)
        vista.draw(control.event_loop())
Пример #12
0
from lib.controller import Controller, PlayerDeath
import json
import random

game = Controller()
game.start_game()

# beginning scene
begin_file = open('txt/begin.txt', 'r')
begin_dialogue = list(begin_file)
print(begin_dialogue[0])

envs = open('lib/environment.json')
data = json.loads(envs.read())
episodes = data['episodes']

def view(episode):
    print(episode['desc'])
    actions = list(episode['actions'].keys())
    possible_choices = range(len(actions))
    action_map = dict(zip(possible_choices, actions))
    for i in possible_choices:
        key = action_map[i]
        print("{0}: {1}".format(i, key))
    return action_map

def play_episode(episode, choice, action_map):
    action = action_map[choice]
    scenario = episode['actions'][action]
    result = scenario[1]
    if result == 'walk':
Пример #13
0
class ROS(AbstractTask):
    '''
        Extends AbstractTask as a Finite State Machine (FSM) basis of a Robot 
        Operating System (ROS) or behaviour-based system (BBS), including 
        spawning the various tasks and an Arbitrator as separate threads, 
        inter-communicating over a common message queue.
    
        This establishes a message queue, an Arbitrator and a Controller, as
        well as an optional RESTful flask-based web service.
    
        The message queue receives Event-containing messages, which are passed 
        on to the Arbitrator, whose job it is to determine the highest priority 
        action to execute for that task cycle.

        Example usage:

            try:
                _ros = ROS()
                _ros.start()
            except Exception:
                _ros.close()

      
        There is also a rosd linux daemon, which can be used to start, enable
        and disable ros (actually via its Arbitrator).
    '''

    # ..........................................................................
    def __init__(self):
        '''
            This initialises the ROS and calls the YAML configurer.
        '''
        self._queue = MessageQueue(Level.INFO)
        self._mutex = threading.Lock()
        super().__init__("ros", self._queue, None, None, self._mutex)
        self._log.info('initialising...')
        self._active = False
        self._closing = False
        self._disable_leds = False
        #       self._switch        = None
        self._motors = None
        self._arbitrator = None
        self._controller = None
        self._gamepad = None
        self._features = []
        #       self._flask_wrapper = None
        # read YAML configuration
        _loader = ConfigLoader(Level.INFO)
        filename = 'config.yaml'
        self._config = _loader.configure(filename)
        self._gamepad_enabled = self._config['ros'].get('gamepad').get(
            'enabled')
        self._log.info('initialised.')
        self._configure()

    # ..........................................................................
    def _configure(self):
        '''
            Configures ROS based on both KR01 standard hardware as well as
            optional features, the latter based on devices showing up (by 
            address) on the I²C bus. Optional devices are only enabled at
            startup time via registration of their feature availability.
        '''
        scanner = I2CScanner(Level.WARN)
        self._addresses = scanner.getAddresses()
        hexAddresses = scanner.getHexAddresses()
        self._addrDict = dict(
            list(map(lambda x, y: (x, y), self._addresses, hexAddresses)))
        for i in range(len(self._addresses)):
            self._log.debug(
                Fore.BLACK + Style.DIM +
                'found device at address: {}'.format(hexAddresses[i]) +
                Style.RESET_ALL)

        self._log.info('configure default features...')
        # standard devices ...........................................
        self._log.info('configuring integrated front sensors...')
        self._ifs = IntegratedFrontSensor(self._config, self._queue,
                                          Level.INFO)
        self._log.info('configure ht0740 switch...')
        self._switch = Switch(Level.INFO)
        # since we're using the HT0740 Switch, turn it on to enable sensors that rely upon its power
        #       self._switch.enable()
        self._switch.on()
        self._log.info('configuring button...')
        self._button = Button(self._config, self.get_message_queue(),
                              self._mutex)

        self._log.info('configure battery check...')
        _battery_check = BatteryCheck(self._config, self.get_message_queue(),
                                      Level.INFO)
        self.add_feature(_battery_check)

        self._log.info('configure CPU temperature check...')
        _temperature_check = Temperature(self._config, self._queue, Level.INFO)
        self.add_feature(_temperature_check)

        ultraborg_available = (0x36 in self._addresses)
        if ultraborg_available:
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            '-- UltraBorg available at 0x36.' +
                            Style.RESET_ALL)
        else:
            self._log.debug(Fore.RED + Style.BRIGHT +
                            '-- no UltraBorg available at 0x36.' +
                            Style.RESET_ALL)
        self._set_feature_available('ultraborg', ultraborg_available)

        thunderborg_available = (0x15 in self._addresses)
        if thunderborg_available:  # then configure motors
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            '-- ThunderBorg available at 0x15' +
                            Style.RESET_ALL)
            _motor_configurer = MotorConfigurer(self, self._config, Level.INFO)
            self._motors = _motor_configurer.configure()
        else:
            self._log.debug(Fore.RED + Style.BRIGHT +
                            '-- no ThunderBorg available at 0x15.' +
                            Style.RESET_ALL)
        self._set_feature_available('thunderborg', thunderborg_available)

        # optional devices ...........................................
        # the 5x5 RGB Matrix is at 0x74 for port, 0x77 for starboard
        rgbmatrix5x5_stbd_available = (0x74 in self._addresses)
        if rgbmatrix5x5_stbd_available:
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            '-- RGB Matrix available at 0x74.' +
                            Style.RESET_ALL)
        else:
            self._log.debug(Fore.RED + Style.BRIGHT +
                            '-- no RGB Matrix available at 0x74.' +
                            Style.RESET_ALL)
        self._set_feature_available('rgbmatrix5x5_stbd',
                                    rgbmatrix5x5_stbd_available)
        rgbmatrix5x5_port_available = (0x77 in self._addresses)
        if rgbmatrix5x5_port_available:
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            '-- RGB Matrix available at 0x77.' +
                            Style.RESET_ALL)
        else:
            self._log.debug(Fore.RED + Style.BRIGHT +
                            '-- no RGB Matrix available at 0x77.' +
                            Style.RESET_ALL)
        self._set_feature_available('rgbmatrix5x5_port',
                                    rgbmatrix5x5_port_available)

        if rgbmatrix5x5_stbd_available or rgbmatrix5x5_port_available:
            self._log.info('configure rgbmatrix...')
            self._rgbmatrix = RgbMatrix(Level.INFO)
            self.add_feature(self._rgbmatrix)  # FIXME this is added twice

        # ............................................
        # the 11x7 LED matrix is at 0x75 for starboard, 0x77 for port. The latter
        # conflicts with the RGB LED matrix, so both cannot be used simultaneously.
        matrix11x7_stbd_available = (0x75 in self._addresses)
        if matrix11x7_stbd_available:
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            '-- 11x7 Matrix LEDs available at 0x75.' +
                            Style.RESET_ALL)
        else:
            self._log.debug(Fore.RED + Style.BRIGHT +
                            '-- no 11x7 Matrix LEDs available at 0x75.' +
                            Style.RESET_ALL)
        self._set_feature_available('matrix11x7_stbd',
                                    matrix11x7_stbd_available)

        # device availability ........................................

        bno055_available = (0x28 in self._addresses)
        if bno055_available:
            self._log.info('configuring BNO055 9DoF sensor...')
            self._bno055 = BNO055(self._config, self.get_message_queue(),
                                  Level.INFO)
        else:
            self._log.debug(Fore.RED + Style.BRIGHT +
                            'no BNO055 orientation sensor available at 0x28.' +
                            Style.RESET_ALL)
        self._set_feature_available('bno055', bno055_available)

        # NOTE: the default address for the ICM20948 is 0x68, but this conflicts with the PiJuice
        icm20948_available = (0x69 in self._addresses)
        if icm20948_available:
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            'ICM20948 available at 0x69.' + Style.RESET_ALL)
        else:
            self._log.debug(Fore.RED + Style.BRIGHT +
                            'no ICM20948 available at 0x69.' + Style.RESET_ALL)
        self._set_feature_available('icm20948', icm20948_available)

        lsm303d_available = (0x1D in self._addresses)
        if lsm303d_available:
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            'LSM303D available at 0x1D.' + Style.RESET_ALL)
        else:
            self._log.debug(Fore.RED + Style.BRIGHT +
                            'no LSM303D available at 0x1D.' + Style.RESET_ALL)
        self._set_feature_available('lsm303d', lsm303d_available)

        vl53l1x_available = (0x29 in self._addresses)
        if vl53l1x_available:
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            'VL53L1X available at 0x29.' + Style.RESET_ALL)
        else:
            self._log.debug(Fore.RED + Style.BRIGHT +
                            'no VL53L1X available at 0x29.' + Style.RESET_ALL)
        self._set_feature_available('vl53l1x', vl53l1x_available)

        as7262_available = (0x49 in self._addresses)
        if as7262_available:
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            '-- AS7262 Spectrometer available at 0x49.' +
                            Style.RESET_ALL)
        else:
            self._log.debug(Fore.RED + Style.BRIGHT +
                            '-- no AS7262 Spectrometer available at 0x49.' +
                            Style.RESET_ALL)
        self._set_feature_available('as7262', as7262_available)

        pijuice_available = (0x68 in self._addresses)
        if pijuice_available:
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            'PiJuice hat available at 0x68.' + Style.RESET_ALL)
        else:
            self._log.debug(Fore.RED + Style.BRIGHT +
                            'no PiJuice hat available at 0x68.' +
                            Style.RESET_ALL)
        self._set_feature_available('pijuice', pijuice_available)

        self._log.info('configured.')

    # ..........................................................................
    def summation():
        '''
            Displays unaccounted I2C addresses. This is currently non-functional,
            as we don't remove a device from the list when its address is found.
        '''
        self._log.info(Fore.YELLOW + '-- unaccounted for self._addresses:')
        for i in range(len(self._addresses)):
            hexAddr = self._addrDict.get(self._addresses[i])
            self._log.info(Fore.YELLOW + Style.BRIGHT +
                           '-- address: {}'.format(hexAddr) + Style.RESET_ALL)

    # ..........................................................................
    def _set_feature_available(self, name, value):
        '''
            Sets a feature's availability to the boolean value.
        '''
        self._log.debug(Fore.BLUE + Style.BRIGHT +
                        '-- set feature available. name: \'{}\' value: \'{}\'.'
                        .format(name, value))
        self.set_property('features', name, value)

    # ..........................................................................
    def get_message_queue(self):
        return self._queue

    # ..........................................................................
    def get_controller(self):
        return self._controller

    # ..........................................................................
    def get_configuration(self):
        return self._config

    # ..........................................................................
    def get_property(self, section, property_name):
        '''
            Return the value of the named property of the application
            configuration, provided its section and property name.
        '''
        return self._config[section].get(property_name)

    # ..........................................................................
    def set_property(self, section, property_name, property_value):
        '''
            Set the value of the named property of the application
            configuration, provided its section, property name and value.
        '''
        self._log.debug(
            Fore.GREEN +
            'set config on section \'{}\' for property key: \'{}\' to value: {}.'
            .format(section, property_name, property_value))
        if section == 'ros':
            self._config[section].update(property_name=property_value)
        else:
            _ros = self._config['ros']
            _ros[section].update(property_name=property_value)

    # ..........................................................................
    def _set_pi_leds(self, enable):
        '''
            Enables or disables the Raspberry Pi's board LEDs.
        '''
        sudo_name = self.get_property('pi', 'sudo_name')
        led_0_path = self._config['pi'].get('led_0_path')
        led_1_path = self._config['pi'].get('led_1_path')
        if enable:
            self._log.info('re-enabling LEDs...')
            os.system('echo 1 | {} tee {}'.format(sudo_name, led_0_path))
            os.system('echo 1 | {} tee {}'.format(sudo_name, led_1_path))
        else:
            self._log.debug('disabling LEDs...')
            os.system('echo 0 | {} tee {}'.format(sudo_name, led_0_path))
            os.system('echo 0 | {} tee {}'.format(sudo_name, led_1_path))

    # ..........................................................................
    def _connect_gamepad(self):
        if not self._gamepad_enabled:
            self._log.info('gamepad disabled.')
            return
        if self._gamepad is None:
            self._log.info('creating gamepad...')
            try:
                self._gamepad = Gamepad(self._config, self._queue, Level.INFO)
            except GamepadConnectException as e:
                self._log.error('unable to connect to gamepad: {}'.format(e))
                self._gamepad = None
                self._gamepad_enabled = False
                self._log.info('gamepad unavailable.')
                return
        if self._gamepad is not None:
            self._log.info('enabling gamepad...')
            self._gamepad.enable()
            _count = 0
            while not self._gamepad.has_connection():
                _count += 1
                if _count == 1:
                    self._log.info('connecting to gamepad...')
                else:
                    self._log.info(
                        'gamepad not connected; re-trying... [{:d}]'.format(
                            _count))
                self._gamepad.connect()
                time.sleep(0.5)
                if self._gamepad.has_connection() or _count > 5:
                    break

    # ..........................................................................
    def has_connected_gamepad(self):
        return self._gamepad is not None and self._gamepad.has_connection()

    # ..........................................................................
    def get_arbitrator(self):
        return self._arbitrator

    # ..........................................................................
    def add_feature(self, feature):
        '''
            Add the feature to the list of features. Features must have 
            an enable() method.
        '''
        self._features.append(feature)
        self._log.info('added feature {}.'.format(feature.name()))

    # ..........................................................................
    def _callback_shutdown(self):
        _enable_self_shutdown = self._config['ros'].get('enable_self_shutdown')
        if _enable_self_shutdown:
            self._log.critical('callback: shutting down os...')
            self.close()
            sys.exit(0)
        else:
            self._log.critical('self-shutdown disabled.')

    # ..........................................................................
    def run(self):
        '''
            This first disables the Pi's status LEDs, establishes the
            message queue arbitrator, the controller, enables the set
            of features, then starts the main OS loop.
        '''
        super(AbstractTask, self).run()
        loop_count = 0
        # display banner!
        _banner = '\n' \
                  'ros\n' \
                  'ros                         █▒▒▒▒▒▒▒     █▒▒▒▒▒▒     █▒▒▒▒▒▒    █▒▒  \n' \
                + 'ros                         █▒▒   █▒▒   █▒▒   █▒▒   █▒▒         █▒▒  \n' \
                + 'ros                         █▒▒▒▒▒▒     █▒▒   █▒▒    █▒▒▒▒▒▒    █▒▒  \n' \
                + 'ros                         █▒▒  █▒▒    █▒▒   █▒▒         █▒▒        \n' \
                + 'ros                         █▒▒   █▒▒    █▒▒▒▒▒▒     █▒▒▒▒▒▒    █▒▒  \n' \
                + 'ros\n'
        self._log.info(_banner)

        self._disable_leds = self._config['pi'].get('disable_leds')
        if self._disable_leds:
            # disable Pi LEDs since they may be distracting
            self._set_pi_leds(False)

        self._log.info('enabling features...')
        for feature in self._features:
            self._log.info('enabling feature {}...'.format(feature.name()))
            feature.enable()

#       __enable_player = self._config['ros'].get('enable_player')
#       if __enable_player:
#           self._log.info('configuring sound player...')
#           self._player = Player(Level.INFO)
#       else:
#           self._player = None

#       i2c_slave_address = config['ros'].get('i2c_master').get('device_id') # i2c hex address of I2C slave device

        vl53l1x_available = True  # self.get_property('features', 'vl53l1x')
        ultraborg_available = True  # self.get_property('features', 'ultraborg')
        if vl53l1x_available and ultraborg_available:
            self._log.critical('starting scanner tool...')
            self._lidar = Lidar(self._config, Level.INFO)
            self._lidar.enable()
        else:
            self._log.critical(
                'lidar scanner tool does not have necessary dependencies.')

        # wait to stabilise features?

        # configure the Controller and Arbitrator
        self._log.info('configuring controller...')
        self._controller = Controller(self._config, self._ifs, self._motors,
                                      self._callback_shutdown, Level.INFO)

        self._log.info('configuring arbitrator...')
        self._arbitrator = Arbitrator(self._config, self._queue,
                                      self._controller, Level.WARN)

        _flask_enabled = self._config['flask'].get('enabled')
        if _flask_enabled:
            self._log.info('starting flask web server...')
            self.configure_web_server()
        else:
            self._log.info(
                'not starting flask web server (suppressed from command line).'
            )

        # bluetooth gamepad controller
        if self._gamepad_enabled:
            self._connect_gamepad()

        self._log.warning('Press Ctrl-C to exit.')

        _wait_for_button_press = self._config['ros'].get(
            'wait_for_button_press')
        self._controller.set_standby(_wait_for_button_press)

        # begin main loop ..............................

        self._log.info('starting button thread...')
        self._button.start()

        #       self._log.info('enabling bno055 sensor...')
        #       self._bno055.enable()

        #       self._bumpers.enable()

        self._indicator = Indicator(Level.INFO)
        # add indicator as message consumer
        self._queue.add_consumer(self._indicator)

        self._log.info(Fore.MAGENTA + 'enabling integrated front sensor...')
        self._ifs.enable()
        #       self._log.info('starting info thread...')
        #       self._info.start()

        #       self._log.info('starting blinky thread...')
        #       self._rgbmatrix.enable(DisplayType.RANDOM)

        # enable arbitrator tasks (normal functioning of robot)

        main_loop_delay_ms = self._config['ros'].get('main_loop_delay_ms')
        self._log.info(
            'begin main os loop with {:d}ms delay.'.format(main_loop_delay_ms))
        _loop_delay_sec = main_loop_delay_ms / 1000
        _main_loop_count = 0
        self._arbitrator.start()
        self._active = True
        while self._active:
            #           The sensors and the flask service sends messages to the message queue,
            #           which forwards those messages on to the arbitrator, which chooses the
            #           highest priority message to send on to the controller. So the timing
            #           of this loop is inconsequential; it exists solely as a keep-alive.
            _main_loop_count += 1
            self._log.debug(Fore.BLACK + Style.DIM +
                            '[{:d}] main loop...'.format(_main_loop_count))
            time.sleep(_loop_delay_sec)
            # end application loop .........................

        if not self._closing:
            self._log.warning('closing following loop...')
            self.close()
        # end main ...................................

    # ..........................................................................
    def configure_web_server(self):
        '''
            Start flask web server.
        '''
        try:
            self._mutex.acquire()
            self._log.info('starting web service...')
            self._flask_wrapper = FlaskWrapperService(self._queue,
                                                      self._controller)
            self._flask_wrapper.start()
        except KeyboardInterrupt:
            self._log.error('caught Ctrl-C interrupt.')
        finally:
            self._mutex.release()
            time.sleep(1)
            self._log.info(Fore.BLUE + 'web service started.' +
                           Style.RESET_ALL)

    # ..........................................................................
    def emergency_stop(self):
        '''
            Stop immediately, something has hit the top feelers.
        '''
        self._motors.stop()
        self._log.info(Fore.RED + Style.BRIGHT +
                       'emergency stop: contact on upper feelers.')

    # ..........................................................................
    def send_message(self, message):
        '''
            Send the Message into the MessageQueue.
        '''
        self._queue.add(message)

    # ..........................................................................
    def enable(self):
        super(AbstractTask, self).enable()

    # ..........................................................................
    def disable(self):
        super(AbstractTask, self).disable()

    # ..........................................................................
    def close(self):
        '''
            This sets the ROS back to normal following a session.
        '''
        if self._closing:
            # this also gets called by the arbitrator so we ignore that
            self._log.info('already closing.')
            return
        else:
            self._active = False
            self._closing = True
            self._log.info(Style.BRIGHT + 'closing...')

            if self._gamepad:
                self._gamepad.close()
            if self._motors:
                self._motors.close()
            if self._ifs:
                self._ifs.close()

            # close features
            for feature in self._features:
                self._log.info('closing feature {}...'.format(feature.name()))
                feature.close()
            self._log.info('finished closing features.')

            if self._arbitrator:
                self._arbitrator.disable()
                self._arbitrator.close()
#               self._arbitrator.join(timeout=1.0)
            if self._controller:
                self._controller.disable()

#           if self._flask_wrapper is not None:
#               self._flask_wrapper.close()

            super().close()

            #           self._info.close()
            #           self._rgbmatrix.close()
            #           if self._switch:
            #               self._switch.close()
            #           super(AbstractTask, self).close()

            if self._disable_leds:
                # restore LEDs
                self._set_pi_leds(True)

#           GPIO.cleanup()
#           self._log.info('joining main thread...')
#           self.join(timeout=0.5)
            self._log.info('os closed.')
            sys.stderr = DevNull()
            sys.exit(0)
Пример #14
0
def api_rest(env):
    g_c = Controller()
    json = g_c.get_json(path=env['PATH_INFO'])
    headers = [('Content-Type', 'text/json; charset=utf-8')]
    return '200 OK', headers, [bytes(json, encoding='utf-8')]
Пример #15
0
 def test_controller_file_input(self,mock___init__):
     Controller.__init__("path")
     mock___init__.assert_called_with("path")
Пример #16
0
def api_index(env):
    g_c = Controller()
    html = g_c.get_index()
    headers = [('Content-Type', 'text/html; charset=utf-8')]
    return '200 OK', headers, html
Пример #17
0
class ROS(AbstractTask):
    '''
        Extends AbstractTask as a Finite State Machine (FSM) basis of a Robot 
        Operating System (ROS) or behaviour-based system (BBS), including 
        spawning the various tasks and an Arbitrator as separate threads, 
        inter-communicating over a common message queue.
    
        This establishes a RESTful flask service, a message queue, an Arbitrator 
        and a Controller. 
    
        The message queue receives Event-containing messages, which are passed 
        on to the Arbitrator, whose job it is to determine the highest priority 
        action to execute for that task cycle.

        Example usage:

            try:
                _ros = ROS()
                _ros.start()
            except Exception:
                _ros.close()
    '''

    # ..........................................................................
    def __init__(self):
        '''
            This initialises the ROS and calls the YAML configurer.
        '''
        self._queue = MessageQueue(Level.INFO)
        self._mutex = threading.Lock()
        super().__init__("os", self._queue, None, None, self._mutex)
        self._log.info('initialising...')
        self._active = False
        self._closing = False
        self._disable_leds = False
        self._switch = None
        self._motors = None
        self._arbitrator = None
        self._controller = None
        # read YAML configuration
        _loader = ConfigLoader(Level.INFO)
        filename = 'config.yaml'
        self._config = _loader.configure(filename)
        # import available features
        self._features = []
        _configurer = Configurer(self, Level.INFO)
        _configurer.scan()
        self._log.info('initialised.')

#   def configure(self):
#       '''
#           Read and return configuration from the YAML file.
#       '''
#       filename = 'config.yaml'
#       self._log.info('reading from yaml configuration file {}...'.format(filename))
#       _config = yaml.safe_load(open(filename, 'r'))
#       for key, value in _config.items():
#           self._log.debug('config key: {}; value: {}'.format(key, str(value)))
#       self._log.info('configuration read.')
#       return _config

# ..........................................................................

    def get_message_queue(self):
        return self._queue

    # ..........................................................................
    def get_controller(self):
        return self._controller

    # ..........................................................................
    def get_configuration(self):
        return self._config

    # ..........................................................................
    def get_property(self, section, property_name):
        '''
            Return the value of the named property of the application
            configuration, provided its section and property name.
        '''
        return self._config[section].get(property_name)

    # ..........................................................................
    def set_property(self, section, property_name, property_value):
        '''
            Set the value of the named property of the application
            configuration, provided its section, property name and value.
        '''
        self._log.info(
            Fore.GREEN +
            'set config on section \'{}\' for property key: \'{}\' to value: {}.'
            .format(section, property_name, property_value))
        if section == 'ros':
            self._config[section].update(property_name=property_value)
        else:
            _ros = self._config['ros']
            _ros[section].update(property_name=property_value)

    # ..........................................................................
    def _set_pi_leds(self, enable):
        '''
            Enables or disables the Raspberry Pi's board LEDs.
        '''
        sudo_name = self.get_property('pi', 'sudo_name')
        led_0_path = self._config['pi'].get('led_0_path')
        led_1_path = self._config['pi'].get('led_1_path')
        if enable:
            self._log.info('re-enabling LEDs...')
            os.system('echo 1 | {} tee {}'.format(sudo_name, led_0_path))
            os.system('echo 1 | {} tee {}'.format(sudo_name, led_1_path))
        else:
            self._log.debug('disabling LEDs...')
            os.system('echo 0 | {} tee {}'.format(sudo_name, led_0_path))
            os.system('echo 0 | {} tee {}'.format(sudo_name, led_1_path))

    # ..........................................................................
    def add_feature(self, feature):
        '''
            Add the feature to the list of features. Features must have 
            an enable() method.
        '''
        self._features.append(feature)
        self._log.info('added feature {}.'.format(feature.name()))

    # ..........................................................................
    def _callback_shutdown(self):
        __enable_self_shutdown = self._config['ros'].get(
            'enable_self_shutdown')
        if _enable_self_shutdown:
            self._log.critical('callback: shutting down os...')
            if self._arbitrator:
                self._arbitrator.disable()
            self.close()
        else:
            self._log.critical('self-shutdown disabled.')

    # ..........................................................................
    def run(self):
        '''
            This first disables the Pi's status LEDs, establishes the
            message queue arbitrator, the controller, enables the set
            of features, then starts the main OS loop.
        '''
        super(AbstractTask, self).run()
        loop_count = 0

        self._disable_leds = self._config['pi'].get('disable_leds')
        if self._disable_leds:
            # disable Pi LEDs since they may be distracting
            self._set_pi_leds(False)

        self._log.info('enabling features...')
        for feature in self._features:
            self._log.info('enabling feature {}...'.format(feature.name()))
            feature.enable()

        __enable_player = self._config['ros'].get('enable_player')
        if __enable_player:
            self._log.info('configuring sound player...')
            self._player = Player(Level.INFO)
        else:
            self._player = None

        vl53l1x_available = True  # self.get_property('features', 'vl53l1x')
        self._log.critical('vl53l1x_available? {}'.format(vl53l1x_available))
        ultraborg_available = True  # self.get_property('features', 'ultraborg')
        self._log.critical(
            'ultraborg available? {}'.format(ultraborg_available))
        if vl53l1x_available and ultraborg_available:
            self._log.critical('starting scanner tool...')
            self._lidar = Lidar(self._config, self._player, Level.INFO)
            self._lidar.enable()
        else:
            self._log.critical(
                'scanner tool does not have necessary dependencies.')

        # wait to stabilise features?

        # configure the Controller and Arbitrator
        self._log.info('configuring controller...')
        self._controller = Controller(Level.INFO, self._config, self._switch,
                                      self._infrareds, self._motors,
                                      self._rgbmatrix, self._lidar,
                                      self._callback_shutdown)

        self._log.info('configuring arbitrator...')
        self._arbitrator = Arbitrator(_level, self._queue, self._controller,
                                      self._mutex)

        flask_enabled = self._config['flask'].get('enabled')
        if flask_enabled:
            self._log.info('starting flask web server...')
            self.configure_web_server()
        else:
            self._log.info(
                'not starting flask web server (suppressed from command line).'
            )

        self._log.warning('Press Ctrl-C to exit.')

        wait_for_button_press = self._config['ros'].get(
            'wait_for_button_press')
        self._controller.set_standby(wait_for_button_press)

        # begin main loop ..............................

        #       self._log.info('starting battery check thread...')
        #       self._battery_check.enable()

        self._log.info('starting button thread...')
        self._button.start()

        #       self._log.info('enabling bno055 sensor...')
        #       self._bno055.enable()

        self._log.info('enabling bumpers...')
        self._bumpers.enable()

        #       self._log.info('starting info thread...')
        #       self._info.start()

        #       self._log.info('starting blinky thread...')
        #       self._rgbmatrix.enable(DisplayType.RANDOM)

        # enable arbitrator tasks (normal functioning of robot)

        main_loop_delay_ms = self._config['ros'].get('main_loop_delay_ms')
        self._log.info(
            'begin main os loop with {:d}ms delay.'.format(main_loop_delay_ms))
        _loop_delay_sec = main_loop_delay_ms / 1000
        self._arbitrator.start()
        while self._arbitrator.is_alive():
            #           The sensors and the flask service sends messages to the message queue,
            #           which forwards those messages on to the arbitrator, which chooses the
            #           highest priority message to send on to the controller. So the timing
            #           of this loop is inconsequential; it exists solely as a keep-alive.
            time.sleep(_loop_delay_sec)
            # end application loop .........................

        if not self._closing:
            self._log.warning('closing following loop...')
            self.close()
        # end main ...................................

    # ..........................................................................
    def configure_web_server(self):
        '''
            Start flask web server.
        '''
        try:
            self._mutex.acquire()
            self._log.info('starting web service...')
            self._flask_wrapper = FlaskWrapperService(self._queue,
                                                      self._controller)
            self._flask_wrapper.start()
        except KeyboardInterrupt:
            self._log.error('caught Ctrl-C interrupt.')
        finally:
            self._mutex.release()
            time.sleep(1)
            self._log.info(Fore.BLUE + 'web service started.' +
                           Style.RESET_ALL)

    # ..........................................................................
    def emergency_stop(self):
        '''
            Stop immediately, something has hit the top feelers.
        '''
        self._motors.stop()
        self._log.info(Fore.RED + Style.BRIGHT +
                       'emergency stop: contact on upper feelers.')

    # ..........................................................................
    def send_message(self, message):
        '''
            Send the Message into the MessageQueue.
        '''
        self._queue.add(message)

    # ..........................................................................
    def enable(self):
        super(AbstractTask, self).enable()

    # ..........................................................................
    def disable(self):
        super(AbstractTask, self).disable()

    # ..........................................................................
    def close(self):
        '''
            This sets the ROS back to normal following a session.
        '''
        if self._closing:
            # this also gets called by the arbitrator so we ignore that
            self._log.info('already closing.')
            return
        else:
            self._active = False
            self._closing = True
            self._log.info(Style.BRIGHT + 'closing...')
            self._flask_wrapper.close()
            if self._arbitrator:
                self._arbitrator.disable()
            super().close()
            #           self._arbitrator.join(timeout=1.0)

            # close features
            for feature in self._features:
                self._log.info('closing feature {}...'.format(feature.name()))
                feature.close()
            self._log.info('finished closing features.')

            if self._motors:
                self._motors.close()

#           self._info.close()
#           self._rgbmatrix.close()
            if self._switch:
                self._switch.close()
#           super(AbstractTask, self).close()
            if self._arbitrator:
                self._arbitrator.close()

            if self._disable_leds:
                # restore LEDs
                self._set_pi_leds(True)

#           GPIO.cleanup()
#           self._log.info('joining main thread...')
#           self.join(timeout=0.5)
            self._log.info('os closed.')
            sys.stderr = DevNull()
            sys.exit(0)
Пример #18
0
    def run(self):
        '''
            This first disables the Pi's status LEDs, establishes the
            message queue arbitrator, the controller, enables the set
            of features, then starts the main OS loop.
        '''
        super(AbstractTask, self).run()
        loop_count = 0

        self._disable_leds = self._config['pi'].get('disable_leds')
        if self._disable_leds:
            # disable Pi LEDs since they may be distracting
            self._set_pi_leds(False)

        self._log.info('enabling features...')
        for feature in self._features:
            self._log.info('enabling feature {}...'.format(feature.name()))
            feature.enable()

        __enable_player = self._config['ros'].get('enable_player')
        if __enable_player:
            self._log.info('configuring sound player...')
            self._player = Player(Level.INFO)
        else:
            self._player = None

        vl53l1x_available = True  # self.get_property('features', 'vl53l1x')
        self._log.critical('vl53l1x_available? {}'.format(vl53l1x_available))
        ultraborg_available = True  # self.get_property('features', 'ultraborg')
        self._log.critical(
            'ultraborg available? {}'.format(ultraborg_available))
        if vl53l1x_available and ultraborg_available:
            self._log.critical('starting scanner tool...')
            self._lidar = Lidar(self._config, self._player, Level.INFO)
            self._lidar.enable()
        else:
            self._log.critical(
                'scanner tool does not have necessary dependencies.')

        # wait to stabilise features?

        # configure the Controller and Arbitrator
        self._log.info('configuring controller...')
        self._controller = Controller(Level.INFO, self._config, self._switch,
                                      self._infrareds, self._motors,
                                      self._rgbmatrix, self._lidar,
                                      self._callback_shutdown)

        self._log.info('configuring arbitrator...')
        self._arbitrator = Arbitrator(_level, self._queue, self._controller,
                                      self._mutex)

        flask_enabled = self._config['flask'].get('enabled')
        if flask_enabled:
            self._log.info('starting flask web server...')
            self.configure_web_server()
        else:
            self._log.info(
                'not starting flask web server (suppressed from command line).'
            )

        self._log.warning('Press Ctrl-C to exit.')

        wait_for_button_press = self._config['ros'].get(
            'wait_for_button_press')
        self._controller.set_standby(wait_for_button_press)

        # begin main loop ..............................

        #       self._log.info('starting battery check thread...')
        #       self._battery_check.enable()

        self._log.info('starting button thread...')
        self._button.start()

        #       self._log.info('enabling bno055 sensor...')
        #       self._bno055.enable()

        self._log.info('enabling bumpers...')
        self._bumpers.enable()

        #       self._log.info('starting info thread...')
        #       self._info.start()

        #       self._log.info('starting blinky thread...')
        #       self._rgbmatrix.enable(DisplayType.RANDOM)

        # enable arbitrator tasks (normal functioning of robot)

        main_loop_delay_ms = self._config['ros'].get('main_loop_delay_ms')
        self._log.info(
            'begin main os loop with {:d}ms delay.'.format(main_loop_delay_ms))
        _loop_delay_sec = main_loop_delay_ms / 1000
        self._arbitrator.start()
        while self._arbitrator.is_alive():
            #           The sensors and the flask service sends messages to the message queue,
            #           which forwards those messages on to the arbitrator, which chooses the
            #           highest priority message to send on to the controller. So the timing
            #           of this loop is inconsequential; it exists solely as a keep-alive.
            time.sleep(_loop_delay_sec)
            # end application loop .........................

        if not self._closing:
            self._log.warning('closing following loop...')
            self.close()
Пример #19
0
 def __init__(self, input_file_path):
     controller = Controller(input_file_path)
     self.plateau = RectangularPlateau(controller.get_plateau_bounds())
     self.rover_commands = controller.get_rover_commands()
     self.rovers = []
Пример #20
0
#!/usr/bin/python

try:
        import sys
        from lib.controller import Controller
        from lib.core.common import *
        from lib.core.version import *
except ImportError,e:
        import sys
        sys.stdout.write("%s\n" %e)
        print exit_message
        sys.exit(1)


##
### Main ...
##

if __name__ == "__main__":

	try:
       		controller = Controller()
       		controller.run()
	except Exception, err_mess:
		print err_mess
		print exit_message	
		sys.exit(2)
 
Пример #21
0
 def test_get_plateau_bounds(self):
     controller = Controller(ControllerTestCase.path)
     self.assertEqual(ControllerTestCase.plateau_bounds, controller.get_plateau_bounds(),
                      msg= '{0}'.format(ControllerTestCase.error_list['9']))
Пример #22
0
    def configure(self, arguments):
        '''
        Provided with a set of configuration arguments, configures ROS based on
        both KD01/KR01 standard hardware as well as optional features, the 
        latter based on devices showing up (by address) on the I²C bus. Optional
        devices are only enabled at startup time via registration of their feature
        availability.
        '''
        self._log.heading('configuration', 'configuring ros...',
                          '[1/2]' if arguments.start else '[1/1]')
        self._log.info('application log level: {}'.format(
            self._log.level.name))
        # configuration from command line arguments
        self._using_mocks = False
        self._permit_mocks = arguments.mock
        self._enable_camera = arguments.camera  # TODO
        # read YAML configuration
        _loader = ConfigLoader(self._log.level)
        _config_file = arguments.config_file if arguments.config_file is not None else 'config.yaml'
        self._config = _loader.configure(_config_file)
        # scan I2C bus
        self._log.info('scanning I²C address bus...')
        scanner = I2CScanner(self._log.level)
        self._addresses = scanner.get_int_addresses()
        _hex_addresses = scanner.get_hex_addresses()
        self._addrDict = dict(
            list(map(lambda x, y: (x, y), self._addresses, _hex_addresses)))
        #       for i in range(len(self._addresses)):
        for _address in self._addresses:
            _device_name = self.get_device_for_address(_address)
            self._log.info('found device at I²C address 0x{:02X}: {}'.format(
                _address, _device_name) + Style.RESET_ALL)
            # TODO look up address and make assumption about what the device is
        # establish basic subsumption components
        self._log.info('configure application messaging...')
        self._message_factory = MessageFactory(self._log.level)
        self._message_bus = MessageBus(self._log.level)
        self._log.info('configuring system clock...')
        self._clock = Clock(self._config, self._message_bus,
                            self._message_factory, Level.WARN)
        self.add_feature(self._clock)

        # standard devices ...........................................
        self._log.info('configure default features...')

        self._log.info('configure CPU temperature check...')
        _temperature_check = Temperature(self._config, self._clock,
                                         self._log.level)
        if _temperature_check.get_cpu_temperature() > 0:
            self.add_feature(_temperature_check)
        else:
            self._log.warning('no support for CPU temperature.')

        motors_enabled = not arguments.no_motors and (0x15 in self._addresses)
        if motors_enabled:  # then configure motors
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            '-- ThunderBorg available at 0x15' +
                            Style.RESET_ALL)
            _motor_configurer = MotorConfigurer(self._config, self._clock,
                                                self._log.level)
            self._motors = _motor_configurer.get_motors()
            self.add_feature(self._motors)
            self._set_feature_available('motors', motors_enabled)
        elif self._permit_mocks:
            self._using_mocks = True
            self._log.debug(Fore.RED + Style.BRIGHT +
                            '-- no ThunderBorg available, using mocks.' +
                            Style.RESET_ALL)
            from mock.motor_configurer import MockMotorConfigurer
            _motor_configurer = MockMotorConfigurer(self._config, self._clock,
                                                    self._log.level)
            self._motors = _motor_configurer.get_motors()
            self.add_feature(self._motors)
            self._set_feature_available('motors', motors_enabled)

        ifs_available = (0x0E in self._addresses)
        if ifs_available:
            self._log.info('configuring integrated front sensor...')
            self._ifs = IntegratedFrontSensor(self._config, self._clock,
                                              self._log.level)
            self.add_feature(self._ifs)
        elif self._permit_mocks:
            self._using_mocks = True
            self._log.info(
                'integrated front sensor not available; loading mock sensor.')
            from mock.ifs import MockIntegratedFrontSensor
            self._ifs = MockIntegratedFrontSensor(self._message_bus,
                                                  exit_on_complete=False,
                                                  level=self._log.level)
            self._message_bus.set_ifs(self._ifs)
            self.add_feature(self._ifs)
        else:
            self._ifs = None
            self._log.warning('no integrated front sensor available.')

#       ultraborg_available = ( 0x36 in self._addresses )
#       if ultraborg_available:
#           self._log.debug(Fore.CYAN + Style.BRIGHT + '-- UltraBorg available at 0x36.' + Style.RESET_ALL)
#       else:
#           self._log.debug(Fore.RED + Style.BRIGHT + '-- no UltraBorg available at 0x36.' + Style.RESET_ALL)
#       self._set_feature_available('ultraborg', ultraborg_available)

#       # optional devices ...........................................
        self._log.info('configure optional features...')
        self._gamepad_enabled = arguments.gamepad and self._config['ros'].get(
            'gamepad').get('enabled')

        #       # the 5x5 RGB Matrix is at 0x74 for port, 0x77 for starboard
        #       rgbmatrix5x5_stbd_available = ( 0x74 in self._addresses )
        #       if rgbmatrix5x5_stbd_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + '-- RGB Matrix available at 0x74.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + '-- no RGB Matrix available at 0x74.' + Style.RESET_ALL)
        #       self._set_feature_available('rgbmatrix5x5_stbd', rgbmatrix5x5_stbd_available)
        #       rgbmatrix5x5_port_available = ( 0x77 in self._addresses )
        #       if rgbmatrix5x5_port_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + '-- RGB Matrix available at 0x77.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + '-- no RGB Matrix available at 0x77.' + Style.RESET_ALL)
        #       self._set_feature_available('rgbmatrix5x5_port', rgbmatrix5x5_port_available)

        #       if rgbmatrix5x5_stbd_available or rgbmatrix5x5_port_available:
        #           self._log.info('configure rgbmatrix...')
        #           self._rgbmatrix = RgbMatrix(Level.INFO)
        #           self.add_feature(self._rgbmatrix) # FIXME this is added twice

        #       # ............................................
        #       # the 11x7 LED matrix is at 0x75 for starboard, 0x77 for port. The latter
        #       # conflicts with the RGB LED matrix, so both cannot be used simultaneously.
        #       matrix11x7_stbd_available = ( 0x75 in self._addresses )
        #       if matrix11x7_stbd_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + '-- 11x7 Matrix LEDs available at 0x75.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + '-- no 11x7 Matrix LEDs available at 0x75.' + Style.RESET_ALL)
        #       self._set_feature_available('matrix11x7_stbd', matrix11x7_stbd_available)

        #       # device availability ........................................

        #       bno055_available = ( 0x28 in self._addresses )
        #       if bno055_available:
        #           self._log.info('configuring BNO055 9DoF sensor...')
        #           self._bno055 = BNO055(self._config, self.get_message_queue(), Level.INFO)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + 'no BNO055 orientation sensor available at 0x28.' + Style.RESET_ALL)
        #       self._set_feature_available('bno055', bno055_available)

        #       # NOTE: the default address for the ICM20948 is 0x68, but this conflicts with the PiJuice
        #       icm20948_available = ( 0x69 in self._addresses )
        #       if icm20948_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + 'ICM20948 available at 0x69.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + 'no ICM20948 available at 0x69.' + Style.RESET_ALL)
        #       self._set_feature_available('icm20948', icm20948_available)

        #       lsm303d_available = ( 0x1D in self._addresses )
        #       if lsm303d_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + 'LSM303D available at 0x1D.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + 'no LSM303D available at 0x1D.' + Style.RESET_ALL)
        #       self._set_feature_available('lsm303d', lsm303d_available)
        #
        #       vl53l1x_available = ( 0x29 in self._addresses )
        #       if vl53l1x_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + 'VL53L1X available at 0x29.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + 'no VL53L1X available at 0x29.' + Style.RESET_ALL)
        #       self._set_feature_available('vl53l1x', vl53l1x_available)

        #       as7262_available = ( 0x49 in self._addresses )
        #       if as7262_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + '-- AS7262 Spectrometer available at 0x49.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + '-- no AS7262 Spectrometer available at 0x49.' + Style.RESET_ALL)
        #       self._set_feature_available('as7262', as7262_available)

        #       pijuice_available = ( 0x68 in self._addresses )
        #       if pijuice_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + 'PiJuice hat available at 0x68.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + 'no PiJuice hat available at 0x68.' + Style.RESET_ALL)
        #       self._set_feature_available('pijuice', pijuice_available)

        self._log.info(Fore.YELLOW + 'configure subsumption support...')

        # configure the MessageQueue, Controller and Arbitrator
        self._log.info('configuring message queue...')
        self._queue = MessageQueue(self._message_bus, self._log.level)
        self._message_bus.add_handler(Message, self._queue.handle)
        self._log.info('configuring controller...')
        self._controller = Controller(self._config, self._ifs, self._motors,
                                      self._callback_shutdown, self._log.level)
        self._log.info('configuring arbitrator...')
        self._arbitrator = Arbitrator(self._config, self._queue,
                                      self._controller, self._log.level)
        self._log.info('configured.')
Пример #23
0
 def test_controller_init(self):
     controller = Controller(ControllerTestCase.path)
     self.assertEqual(ControllerTestCase.plateaubounds, (controller.x_plateau_lower,
                                                         controller.y_plateau_lower,
                                                         controller.x_plateau_upper,
                                                         controller.y_plateau_upper))
Пример #24
0
class ROS(AbstractTask):
    '''
    Extends AbstractTask as a Finite State Machine (FSM) basis of a Robot 
    Operating System (ROS) or behaviour-based system (BBS), including 
    spawning the various tasks and an Arbitrator as separate threads, 
    inter-communicating over a common message queue.

    This establishes the basic subsumption foundation of a MessageBus, a
    MessageFactory, a system Clock, an Arbitrator and a Controller.

    The MessageBus receives Event-containing messages from sensors and other
    message sources, which are passed on to the Arbitrator, whose job it is
    to determine the highest priority action to execute for that task cycle,
    by passing it on to the Controller.

    There is also a rosd linux daemon, which can be used to start, enable
    and disable ros. 

    :param mutex:   the optional logging mutex, passed on from rosd
    '''

    # ..........................................................................
    def __init__(self, mutex=None, level=Level.INFO):
        '''
        This initialises the ROS and calls the YAML configurer.
        '''
        self._mutex = mutex if mutex is not None else threading.Lock()
        super().__init__("ros", None, self._mutex)
        self._log.info('setting process as high priority...')
        # set ROS as high priority
        proc = psutil.Process(os.getpid())
        proc.nice(10)
        self._config = None
        self._active = False
        self._closing = False
        self._disable_leds = False
        self._arbitrator = None
        self._controller = None
        self._gamepad = None
        self._motors = None
        self._ifs = None
        self._features = []
        self._log.info('initialised.')

    # ..........................................................................
    def configure(self, arguments):
        '''
        Provided with a set of configuration arguments, configures ROS based on
        both KD01/KR01 standard hardware as well as optional features, the 
        latter based on devices showing up (by address) on the I²C bus. Optional
        devices are only enabled at startup time via registration of their feature
        availability.
        '''
        self._log.heading('configuration', 'configuring ros...',
                          '[1/2]' if arguments.start else '[1/1]')
        self._log.info('application log level: {}'.format(
            self._log.level.name))
        # configuration from command line arguments
        self._using_mocks = False
        self._permit_mocks = arguments.mock
        self._enable_camera = arguments.camera  # TODO
        # read YAML configuration
        _loader = ConfigLoader(self._log.level)
        _config_file = arguments.config_file if arguments.config_file is not None else 'config.yaml'
        self._config = _loader.configure(_config_file)
        # scan I2C bus
        self._log.info('scanning I²C address bus...')
        scanner = I2CScanner(self._log.level)
        self._addresses = scanner.get_int_addresses()
        _hex_addresses = scanner.get_hex_addresses()
        self._addrDict = dict(
            list(map(lambda x, y: (x, y), self._addresses, _hex_addresses)))
        #       for i in range(len(self._addresses)):
        for _address in self._addresses:
            _device_name = self.get_device_for_address(_address)
            self._log.info('found device at I²C address 0x{:02X}: {}'.format(
                _address, _device_name) + Style.RESET_ALL)
            # TODO look up address and make assumption about what the device is
        # establish basic subsumption components
        self._log.info('configure application messaging...')
        self._message_factory = MessageFactory(self._log.level)
        self._message_bus = MessageBus(self._log.level)
        self._log.info('configuring system clock...')
        self._clock = Clock(self._config, self._message_bus,
                            self._message_factory, Level.WARN)
        self.add_feature(self._clock)

        # standard devices ...........................................
        self._log.info('configure default features...')

        self._log.info('configure CPU temperature check...')
        _temperature_check = Temperature(self._config, self._clock,
                                         self._log.level)
        if _temperature_check.get_cpu_temperature() > 0:
            self.add_feature(_temperature_check)
        else:
            self._log.warning('no support for CPU temperature.')

        motors_enabled = not arguments.no_motors and (0x15 in self._addresses)
        if motors_enabled:  # then configure motors
            self._log.debug(Fore.CYAN + Style.BRIGHT +
                            '-- ThunderBorg available at 0x15' +
                            Style.RESET_ALL)
            _motor_configurer = MotorConfigurer(self._config, self._clock,
                                                self._log.level)
            self._motors = _motor_configurer.get_motors()
            self.add_feature(self._motors)
            self._set_feature_available('motors', motors_enabled)
        elif self._permit_mocks:
            self._using_mocks = True
            self._log.debug(Fore.RED + Style.BRIGHT +
                            '-- no ThunderBorg available, using mocks.' +
                            Style.RESET_ALL)
            from mock.motor_configurer import MockMotorConfigurer
            _motor_configurer = MockMotorConfigurer(self._config, self._clock,
                                                    self._log.level)
            self._motors = _motor_configurer.get_motors()
            self.add_feature(self._motors)
            self._set_feature_available('motors', motors_enabled)

        ifs_available = (0x0E in self._addresses)
        if ifs_available:
            self._log.info('configuring integrated front sensor...')
            self._ifs = IntegratedFrontSensor(self._config, self._clock,
                                              self._log.level)
            self.add_feature(self._ifs)
        elif self._permit_mocks:
            self._using_mocks = True
            self._log.info(
                'integrated front sensor not available; loading mock sensor.')
            from mock.ifs import MockIntegratedFrontSensor
            self._ifs = MockIntegratedFrontSensor(self._message_bus,
                                                  exit_on_complete=False,
                                                  level=self._log.level)
            self._message_bus.set_ifs(self._ifs)
            self.add_feature(self._ifs)
        else:
            self._ifs = None
            self._log.warning('no integrated front sensor available.')

#       ultraborg_available = ( 0x36 in self._addresses )
#       if ultraborg_available:
#           self._log.debug(Fore.CYAN + Style.BRIGHT + '-- UltraBorg available at 0x36.' + Style.RESET_ALL)
#       else:
#           self._log.debug(Fore.RED + Style.BRIGHT + '-- no UltraBorg available at 0x36.' + Style.RESET_ALL)
#       self._set_feature_available('ultraborg', ultraborg_available)

#       # optional devices ...........................................
        self._log.info('configure optional features...')
        self._gamepad_enabled = arguments.gamepad and self._config['ros'].get(
            'gamepad').get('enabled')

        #       # the 5x5 RGB Matrix is at 0x74 for port, 0x77 for starboard
        #       rgbmatrix5x5_stbd_available = ( 0x74 in self._addresses )
        #       if rgbmatrix5x5_stbd_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + '-- RGB Matrix available at 0x74.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + '-- no RGB Matrix available at 0x74.' + Style.RESET_ALL)
        #       self._set_feature_available('rgbmatrix5x5_stbd', rgbmatrix5x5_stbd_available)
        #       rgbmatrix5x5_port_available = ( 0x77 in self._addresses )
        #       if rgbmatrix5x5_port_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + '-- RGB Matrix available at 0x77.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + '-- no RGB Matrix available at 0x77.' + Style.RESET_ALL)
        #       self._set_feature_available('rgbmatrix5x5_port', rgbmatrix5x5_port_available)

        #       if rgbmatrix5x5_stbd_available or rgbmatrix5x5_port_available:
        #           self._log.info('configure rgbmatrix...')
        #           self._rgbmatrix = RgbMatrix(Level.INFO)
        #           self.add_feature(self._rgbmatrix) # FIXME this is added twice

        #       # ............................................
        #       # the 11x7 LED matrix is at 0x75 for starboard, 0x77 for port. The latter
        #       # conflicts with the RGB LED matrix, so both cannot be used simultaneously.
        #       matrix11x7_stbd_available = ( 0x75 in self._addresses )
        #       if matrix11x7_stbd_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + '-- 11x7 Matrix LEDs available at 0x75.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + '-- no 11x7 Matrix LEDs available at 0x75.' + Style.RESET_ALL)
        #       self._set_feature_available('matrix11x7_stbd', matrix11x7_stbd_available)

        #       # device availability ........................................

        #       bno055_available = ( 0x28 in self._addresses )
        #       if bno055_available:
        #           self._log.info('configuring BNO055 9DoF sensor...')
        #           self._bno055 = BNO055(self._config, self.get_message_queue(), Level.INFO)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + 'no BNO055 orientation sensor available at 0x28.' + Style.RESET_ALL)
        #       self._set_feature_available('bno055', bno055_available)

        #       # NOTE: the default address for the ICM20948 is 0x68, but this conflicts with the PiJuice
        #       icm20948_available = ( 0x69 in self._addresses )
        #       if icm20948_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + 'ICM20948 available at 0x69.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + 'no ICM20948 available at 0x69.' + Style.RESET_ALL)
        #       self._set_feature_available('icm20948', icm20948_available)

        #       lsm303d_available = ( 0x1D in self._addresses )
        #       if lsm303d_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + 'LSM303D available at 0x1D.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + 'no LSM303D available at 0x1D.' + Style.RESET_ALL)
        #       self._set_feature_available('lsm303d', lsm303d_available)
        #
        #       vl53l1x_available = ( 0x29 in self._addresses )
        #       if vl53l1x_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + 'VL53L1X available at 0x29.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + 'no VL53L1X available at 0x29.' + Style.RESET_ALL)
        #       self._set_feature_available('vl53l1x', vl53l1x_available)

        #       as7262_available = ( 0x49 in self._addresses )
        #       if as7262_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + '-- AS7262 Spectrometer available at 0x49.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + '-- no AS7262 Spectrometer available at 0x49.' + Style.RESET_ALL)
        #       self._set_feature_available('as7262', as7262_available)

        #       pijuice_available = ( 0x68 in self._addresses )
        #       if pijuice_available:
        #           self._log.debug(Fore.CYAN + Style.BRIGHT + 'PiJuice hat available at 0x68.' + Style.RESET_ALL)
        #       else:
        #           self._log.debug(Fore.RED + Style.BRIGHT + 'no PiJuice hat available at 0x68.' + Style.RESET_ALL)
        #       self._set_feature_available('pijuice', pijuice_available)

        self._log.info(Fore.YELLOW + 'configure subsumption support...')

        # configure the MessageQueue, Controller and Arbitrator
        self._log.info('configuring message queue...')
        self._queue = MessageQueue(self._message_bus, self._log.level)
        self._message_bus.add_handler(Message, self._queue.handle)
        self._log.info('configuring controller...')
        self._controller = Controller(self._config, self._ifs, self._motors,
                                      self._callback_shutdown, self._log.level)
        self._log.info('configuring arbitrator...')
        self._arbitrator = Arbitrator(self._config, self._queue,
                                      self._controller, self._log.level)
        self._log.info('configured.')

    # ..........................................................................
    def _set_feature_available(self, name, value):
        '''
            Sets a feature's availability to the boolean value.
        '''
        self._log.debug(Fore.BLUE + Style.BRIGHT +
                        '-- set feature available. name: \'{}\' value: \'{}\'.'
                        .format(name, value))
        self.set_property('features', name, value)

    # ..........................................................................
    def get_device_for_address(self, address):
        if address == 0x0E:
            return 'RGB Potentiometer'
        elif address == 0x0F:
            return 'RGB Encoder'  # default, moved to 0x16
        elif address == 0x15:
            return 'ThunderBorg'
        elif address == 0x16:
            return 'RGB Encoder'
        elif address == 0x18:
            return 'IO Expander'
        elif address == 0x48:
            return 'ADS1015'
        elif address == 0x4A:
            return 'Unknown'
        elif address == 0x74:
            return '5x5 RGB Matrix'
        elif address == 0x77:
            return '5x5 RGB Matrix (or 11x7 LED Matrix)'
        else:
            return 'Unknown'

    # ..........................................................................
    @property
    def controller(self):
        return self._controller

    # ..........................................................................
    @property
    def configuration(self):
        return self._config

    # ..........................................................................
    def get_property(self, section, property_name):
        '''
        Return the value of the named property of the application
        configuration, provided its section and property name.
        '''
        return self._config[section].get(property_name)

    # ..........................................................................
    def set_property(self, section, property_name, property_value):
        '''
        Set the value of the named property of the application
        configuration, provided its section, property name and value.
        '''
        self._log.debug(Fore.GREEN + 'set config on section \'{}\' for property key: \'{}\' to value: {}.'.format(\
                section, property_name, property_value))
        if section == 'ros':
            self._config[section].update(property_name=property_value)
        else:
            _ros = self._config['ros']
            _ros[section].update(property_name=property_value)

    # ..........................................................................
    def _set_pi_leds(self, enable):
        '''
        Enables or disables the Raspberry Pi's board LEDs.
        '''
        sudo_name = self.get_property('pi', 'sudo_name')
        # led_0_path:   '/sys/class/leds/led0/brightness'
        _led_0_path = self._config['pi'].get('led_0_path')
        _led_0 = Path(_led_0_path)
        # led_1_path:   '/sys/class/leds/led1/brightness'
        _led_1_path = self._config['pi'].get('led_1_path')
        _led_1 = Path(_led_1_path)
        if _led_0.is_file() and _led_0.is_file():
            if enable:
                self._log.info('re-enabling LEDs...')
                os.system('echo 1 | {} tee {}'.format(sudo_name, _led_0_path))
                os.system('echo 1 | {} tee {}'.format(sudo_name, _led_1_path))
            else:
                self._log.debug('disabling LEDs...')
                os.system('echo 0 | {} tee {}'.format(sudo_name, _led_0_path))
                os.system('echo 0 | {} tee {}'.format(sudo_name, _led_1_path))
        else:
            self._log.warning(
                'could not change state of LEDs: does not appear to be a Raspberry Pi.'
            )

    # ..........................................................................
    def _connect_gamepad(self):
        if not self._gamepad_enabled:
            self._log.info('gamepad disabled.')
            return
        if self._gamepad is None:
            self._log.info('creating gamepad...')
            try:
                self._gamepad = Gamepad(self._config, self._queue, Level.INFO)
            except GamepadConnectException as e:
                self._log.error('unable to connect to gamepad: {}'.format(e))
                self._gamepad = None
                self._gamepad_enabled = False
                self._log.info('gamepad unavailable.')
                return
        if self._gamepad is not None:
            self._log.info('enabling gamepad...')
            self._gamepad.enable()
            _count = 0
            while not self._gamepad.has_connection():
                _count += 1
                if _count == 1:
                    self._log.info('connecting to gamepad...')
                else:
                    self._log.info(
                        'gamepad not connected; re-trying... [{:d}]'.format(
                            _count))
                self._gamepad.connect()
                time.sleep(0.5)
                if self._gamepad.has_connection() or _count > 5:
                    break

    # ..........................................................................
    def has_connected_gamepad(self):
        return self._gamepad is not None and self._gamepad.has_connection()

    # ..........................................................................
    def get_arbitrator(self):
        return self._arbitrator

    # ..........................................................................
    def add_feature(self, feature):
        '''
        Add the feature to the list of features. Features must have 
        an enable() method.
        '''
        self._features.append(feature)
        self._log.info('added feature {}.'.format(feature.name()))

    # ..........................................................................
    def _callback_shutdown(self):
        _enable_self_shutdown = self._config['ros'].get('enable_self_shutdown')
        if _enable_self_shutdown:
            self._log.critical('callback: shutting down os...')
            self.close()
            sys.exit(0)
        else:
            self._log.critical('self-shutdown disabled.')

    # ..........................................................................
    def _print_banner(self):
        '''
        Display banner on console.
        '''
        self._log.info('…')
        self._log.info('…     █▒▒▒▒▒▒▒     █▒▒▒▒▒▒     █▒▒▒▒▒▒    █▒▒ ')
        self._log.info('…     █▒▒   █▒▒   █▒▒   █▒▒   █▒▒         █▒▒ ')
        self._log.info('…     █▒▒▒▒▒▒     █▒▒   █▒▒    █▒▒▒▒▒▒    █▒▒ ')
        self._log.info('…     █▒▒  █▒▒    █▒▒   █▒▒         █▒▒       ')
        self._log.info('…     █▒▒   █▒▒    █▒▒▒▒▒▒     █▒▒▒▒▒▒    █▒▒ ')
        self._log.info('…')

    # ..........................................................................
    def run(self):
        '''
        This first disables the Pi's status LEDs, establishes the
        message queue arbitrator, the controller, enables the set
        of features, then starts the main OS loop.
        '''
        super(AbstractTask, self).run()
        loop_count = 0
        self._print_banner()

        self._disable_leds = self._config['pi'].get('disable_leds')
        if self._disable_leds:
            # disable Pi LEDs since they may be distracting
            self._set_pi_leds(False)

        _main_loop_freq_hz = self._config['ros'].get('main_loop_freq_hz')
        self._main_loop_rate = Rate(_main_loop_freq_hz)

        #       __enable_player = self._config['ros'].get('enable_player')
        #       if __enable_player:
        #           self._log.info('configuring sound player...')
        #           self._player = Player(Level.INFO)
        #       else:
        #           self._player = None

        #       i2c_slave_address = config['ros'].get('i2c_master').get('device_id') # i2c hex address of I2C slave device

        #       vl53l1x_available = True # self.get_property('features', 'vl53l1x')
        #       ultraborg_available = True # self.get_property('features', 'ultraborg')
        #       if vl53l1x_available and ultraborg_available:
        #           self._log.critical('starting scanner tool...')
        #           self._lidar = Lidar(self._config, Level.INFO)
        #           self._lidar.enable()
        #       else:
        #           self._log.critical('lidar scanner tool does not have necessary dependencies.')

        # wait to stabilise features?

        #       _flask_enabled = self._config['flask'].get('enabled')
        #       if _flask_enabled:
        #           self._log.info('starting flask web server...')
        #           self.configure_web_server()
        #       else:
        #           self._log.info('not starting flask web server (suppressed from command line).')

        # bluetooth gamepad controller
        #       if self._gamepad_enabled:
        #           self._connect_gamepad()

        #       _wait_for_button_press = self._config['ros'].get('wait_for_button_press')
        #       self._controller.set_standby(_wait_for_button_press)

        # begin main loop ..............................

        #       self._log.info('enabling bno055 sensor...')
        #       self._bno055.enable()

        #       self._bumpers.enable()

        #       self._indicator = Indicator(Level.INFO)
        # add indicator as message listener
        #       self._queue.add_listener(self._indicator)

        #       self._log.info(Fore.MAGENTA + 'enabling integrated front sensor...')
        #       self._ifs.enable()
        #       self._log.info('starting info thread...')
        #       self._info.start()

        #       self._log.info('starting blinky thread...')
        #       self._rgbmatrix.enable(DisplayType.RANDOM)

        self._log.info('enabling features...')
        for feature in self._features:
            self._log.info('enabling feature {}...'.format(feature.name()))
            feature.enable()

        self._log.notice('Press Ctrl-C to exit.')
        self._log.info('begin main os loop.\r')

        # enable arbitrator tasks (normal functioning of robot)
        #       self._arbitrator.start()

        _main_loop_counter = itertools.count()
        self._active = True
        while self._active:
            # the timing of this loop is inconsequential; it exists solely as a keep-alive.
            self._log.debug('[{:d}] main loop...'.format(
                next(_main_loop_counter)))
            self._main_loop_rate.wait()

        if not self._closing:
            self._log.warning('closing following loop...')
            self.close()
        # end main ...................................

    # ..........................................................................
    def emergency_stop(self):
        '''
        Stop immediately, something has hit the top feelers.
        '''
        self._motors.stop()
        self._log.info(Fore.RED + Style.BRIGHT +
                       'emergency stop: contact on upper feelers.')

    # ..........................................................................
    def send_message(self, message):
        '''
        Send the Message into the MessageQueue.
        '''
        #       self._queue.add(message)
        raise Exception('unsupported')

    # ..........................................................................
    def enable(self):
        super(AbstractTask, self).enable()

    # ..........................................................................
    def disable(self):
        super(AbstractTask, self).disable()

    # ..........................................................................
    def close(self):
        '''
        This sets the ROS back to normal following a session.
        '''
        if self._closing:
            # this also gets called by the arbitrator so we ignore that
            self._log.info('already closing.')
            return
        else:
            self._active = False
            self._closing = True
            self._log.info(Style.BRIGHT + 'closing...')
            if self._gamepad:
                self._gamepad.close()
            if self._motors:
                self._motors.close()
            if self._ifs:
                self._ifs.close()

            # close features
            for feature in self._features:
                self._log.info('closing feature {}...'.format(feature.name()))
                feature.close()
            self._log.info('finished closing features.')
            if self._arbitrator:
                self._arbitrator.disable()
                self._arbitrator.close()
#               self._arbitrator.join(timeout=1.0)
            if self._controller:
                self._controller.disable()
            super().close()

            if self._disable_leds:
                # restore LEDs
                self._set_pi_leds(True)

#           GPIO.cleanup()
#           self._log.info('joining main thread...')
#           self.join(timeout=0.5)
            self._log.info('os closed.')
            sys.stderr = DevNull()
            sys.exit(0)
Пример #25
0
def main():
    """
    Prepara las ventanas, define modelos, controlador y vista y corre el programa.
    :return: void
    """

    # Se obtiene el checksum del juego
    checksum = [
        path_checksum('lib', VERBOSE),
        '8e1fd1c03d2bfe89d7dbdab8b0c4c69a'.upper(),
        path_checksum('bin', VERBOSE)
    ]

    # Se cargan las configuraciones
    control_config = Configloader(DIR_CONFIG + 'control.ini', verbose=VERBOSE)
    game_config = Configloader(DIR_CONFIG + 'game.ini', verbose=VERBOSE)
    map_config = Configloader(DIR_CONFIG + 'map.ini', verbose=VERBOSE)
    score_config = Configloader(DIR_CONFIG + 'scoreboard.ini', verbose=VERBOSE)
    user_config = Configloader(DIR_CONFIG + 'user.ini', verbose=VERBOSE)
    view_config = Configloader(DIR_CONFIG + 'view.ini', verbose=VERBOSE)
    window_config = Configloader(DIR_CONFIG + 'window.ini', verbose=VERBOSE)
    world_config = Configloader(DIR_CONFIG + 'world.ini', verbose=VERBOSE)

    # Se carga el idioma
    lang = langs.Langloader(game_config.getValue('LANG'))

    # Se carga la información de la pantalla del cliente
    display_info = pygame.display.Info()

    # Se comprueba que el nombre de jugador no sea Player, si no es valido se pide uno nuevo
    if not username.validate(user_config.getValue('NAME')):
        new_name = username.request(lang.get(111), lang.get(112))
        if new_name is not username.NO_VALID_NAME:
            user_config.setParameter('NAME', new_name)
            user_config.export()
        else:
            utils.destroy_process()

    # Creación de ventana
    window = Window(window_config, lang.get(10),
                    pygame.image.load(getIcons('icon')), display_info)
    clock = pygame.time.Clock()  # Reloj
    fps = int(game_config.getValue('FPS'))  # FPS a dibujar

    # Se crea el mundo
    world = World(world_config,
                  map_config,
                  window,
                  checksum,
                  score_config,
                  user_config,
                  lang,
                  game_config,
                  verbose=VERBOSE)
    # world.load_map(1)

    # Se crean los menús de inicio y pause
    menus = Createuimenu(lang, window, world, game_config, user_config,
                         view_config, window_config, world_config, map_config)

    # Se crea la vista
    vista = View(window, clock, world, lang, view_config, menus)
    menus.addView(vista)

    # Se crea el controlador
    control = Controller(world,
                         clock,
                         lang,
                         control_config,
                         window,
                         menus,
                         verbose=VERBOSE)
    menus.addController(control)
    vista.add_controller(control)

    # Se lanza el mainloop
    while True:
        clock.tick(fps)
        vista.draw(control.event_loop())
Пример #26
0
def main():
    app = Controller()
    app.run_app()
Пример #27
0
def main():
    app = Flask(__name__)
    controller = Controller(config.controller['leds'],
                            config.controller['neopixel_gpio_pin'],
                            config.controller['neopixel_frequency'],
                            config.controller['neopixel_dma'],
                            config.controller['neopixel_invert'],
                            config.controller['neopixel_brightness'],
                            config.controller['neopixel_channel'],
                            config.controller['neopixel_strip'])
    db = TinyDB('data/database.json')
    query = Query()

    app.config['SECRET_KEY'] = os.urandom(24)

    CSRFProtect(app)

    main.color = Color(0, 0, 0)
    main.brightness = 255
    main.state = False
    main.effects = []

    @app.before_first_request
    def init():
        if db.search(query.color != ''):
            result = db.get(query.color != '')['color'].split(',')
            main.color = Color(int(result[0]), int(result[1]), int(result[2]))

        if db.search(query.brightness != ''):
            result = db.get(query.brightness != '')
            main.brightness = result['brightness']

        if db.search(query.state != ''):
            result = db.get(query.state != '')
            main.state = bool(result['state'])

        if main.state:
            controller.color(main.color)
            controller.brightness(main.brightness)

        main.effects = controller.effects()

    @app.route('/', methods=['GET', 'POST'])
    def index():
        if request.method == 'POST':
            data = request.form

            main.color = Color(int(data['red']), int(data['green']),
                               int(data['blue']))
            main.brightness = int(data['brightness'])

            controller.brightness(main.brightness)

            if data['submit'] == 'apply':
                main.state = True
                controller.clear()
                controller.color(main.color)
                controller.brightness(main.brightness)

            elif data['submit'] == 'effect':
                main.state = True
                controller.clear()
                controller.brightness(main.brightness)

                if data['effect'] in main.effects:
                    controller.start_effect(
                        data['effect'],
                        Color(int(data['red']), int(data['green']),
                              int(data['blue'])))
            elif data['submit'] == 'off':
                main.state = False
                controller.clear()

            if main.state:
                db.update({'color': main.color.__str__()}, query.color != '')
                db.update({'brightness': main.brightness},
                          query.brightness != '')

            db.update({'state': main.state}, query.state != '')

            return redirect(url_for('index'))

        return render_template('index.html',
                               effects=main.effects,
                               color=main.color,
                               brightness=main.brightness)

    @app.route('/api/v1.0/state/<string:state>', methods=['GET'])
    def state(state):
        if not state:
            abort(400)

        main.state = True if state == 'true' else False
        db.update({'state': main.state}, query.state != '')
        controller.clear()

        if main.state:
            controller.color(main.color)
            controller.brightness(main.brightness)

        return jsonify({'state': main.state}), 201

    @app.route('/api/v1.0/color/<int:red>/<int:green>/<int:blue>',
               methods=['GET'])
    def color(red, green, blue):
        if not red or not green or not blue:
            abort(400)

        main.state = True
        main.color = Color(int(red), int(green), int(blue))
        controller.color(main.color)
        db.update({'color': main.color.__str__()}, query.color != '')

        return jsonify({'color': main.color.__str__()}), 201

    @app.route('/api/v1.0/brightness/<int:brightness>', methods=['GET'])
    def brightness(brightness):
        if not brightness:
            abort(400)

        main.state = True
        main.brightness = int(brightness)
        controller.brightness(main.brightness)
        db.update({'brightness': main.brightness}, query.brightness != '')

        return jsonify({'brightness': main.brightness}), 201

    app.run(host='0.0.0.0', port=5000)
    db.close()
    atexit.register(controller.__exit__)
Пример #28
0
    def run(self):
        '''
            This first disables the Pi's status LEDs, establishes the
            message queue arbitrator, the controller, enables the set
            of features, then starts the main OS loop.
        '''
        super(AbstractTask, self).run()
        loop_count = 0
        # display banner!
        _banner = '\n' \
                  'ros\n' \
                  'ros                         █▒▒▒▒▒▒▒     █▒▒▒▒▒▒     █▒▒▒▒▒▒    █▒▒  \n' \
                + 'ros                         █▒▒   █▒▒   █▒▒   █▒▒   █▒▒         █▒▒  \n' \
                + 'ros                         █▒▒▒▒▒▒     █▒▒   █▒▒    █▒▒▒▒▒▒    █▒▒  \n' \
                + 'ros                         █▒▒  █▒▒    █▒▒   █▒▒         █▒▒        \n' \
                + 'ros                         █▒▒   █▒▒    █▒▒▒▒▒▒     █▒▒▒▒▒▒    █▒▒  \n' \
                + 'ros\n'
        self._log.info(_banner)

        self._disable_leds = self._config['pi'].get('disable_leds')
        if self._disable_leds:
            # disable Pi LEDs since they may be distracting
            self._set_pi_leds(False)

        self._log.info('enabling features...')
        for feature in self._features:
            self._log.info('enabling feature {}...'.format(feature.name()))
            feature.enable()

#       __enable_player = self._config['ros'].get('enable_player')
#       if __enable_player:
#           self._log.info('configuring sound player...')
#           self._player = Player(Level.INFO)
#       else:
#           self._player = None

#       i2c_slave_address = config['ros'].get('i2c_master').get('device_id') # i2c hex address of I2C slave device

        vl53l1x_available = True  # self.get_property('features', 'vl53l1x')
        ultraborg_available = True  # self.get_property('features', 'ultraborg')
        if vl53l1x_available and ultraborg_available:
            self._log.critical('starting scanner tool...')
            self._lidar = Lidar(self._config, Level.INFO)
            self._lidar.enable()
        else:
            self._log.critical(
                'lidar scanner tool does not have necessary dependencies.')

        # wait to stabilise features?

        # configure the Controller and Arbitrator
        self._log.info('configuring controller...')
        self._controller = Controller(self._config, self._ifs, self._motors,
                                      self._callback_shutdown, Level.INFO)

        self._log.info('configuring arbitrator...')
        self._arbitrator = Arbitrator(self._config, self._queue,
                                      self._controller, Level.WARN)

        _flask_enabled = self._config['flask'].get('enabled')
        if _flask_enabled:
            self._log.info('starting flask web server...')
            self.configure_web_server()
        else:
            self._log.info(
                'not starting flask web server (suppressed from command line).'
            )

        # bluetooth gamepad controller
        if self._gamepad_enabled:
            self._connect_gamepad()

        self._log.warning('Press Ctrl-C to exit.')

        _wait_for_button_press = self._config['ros'].get(
            'wait_for_button_press')
        self._controller.set_standby(_wait_for_button_press)

        # begin main loop ..............................

        self._log.info('starting button thread...')
        self._button.start()

        #       self._log.info('enabling bno055 sensor...')
        #       self._bno055.enable()

        #       self._bumpers.enable()

        self._indicator = Indicator(Level.INFO)
        # add indicator as message consumer
        self._queue.add_consumer(self._indicator)

        self._log.info(Fore.MAGENTA + 'enabling integrated front sensor...')
        self._ifs.enable()
        #       self._log.info('starting info thread...')
        #       self._info.start()

        #       self._log.info('starting blinky thread...')
        #       self._rgbmatrix.enable(DisplayType.RANDOM)

        # enable arbitrator tasks (normal functioning of robot)

        main_loop_delay_ms = self._config['ros'].get('main_loop_delay_ms')
        self._log.info(
            'begin main os loop with {:d}ms delay.'.format(main_loop_delay_ms))
        _loop_delay_sec = main_loop_delay_ms / 1000
        _main_loop_count = 0
        self._arbitrator.start()
        self._active = True
        while self._active:
            #           The sensors and the flask service sends messages to the message queue,
            #           which forwards those messages on to the arbitrator, which chooses the
            #           highest priority message to send on to the controller. So the timing
            #           of this loop is inconsequential; it exists solely as a keep-alive.
            _main_loop_count += 1
            self._log.debug(Fore.BLACK + Style.DIM +
                            '[{:d}] main loop...'.format(_main_loop_count))
            time.sleep(_loop_delay_sec)
            # end application loop .........................

        if not self._closing:
            self._log.warning('closing following loop...')
            self.close()