Пример #1
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)
        _ifs.enable() 
        _motors = Motors(_config, None, None, Level.INFO)

        print(Fore.RED   + 'avoiding PORT...' + Style.RESET_ALL)
        _avoid = Behaviours(_motors,_ifs, Level.INFO)
        _avoid.avoid(Orientation.PORT)
        time.sleep(1.0)

#       print(Fore.BLUE  + 'avoiding CNTR...' + Style.RESET_ALL)
#       _avoid = AvoidBehaviour(_motors,_ifs, Level.INFO)
#       _avoid.avoid(Orientation.CNTR)
#       time.sleep(1.0)

#       print(Fore.GREEN + 'avoiding STBD...' + Style.RESET_ALL)
#       _avoid = AvoidBehaviour(_motors,_ifs, Level.INFO)
#       _avoid.avoid(Orientation.STBD)

        print(Fore.YELLOW + 'complete: closing...' + Style.RESET_ALL)
        _ifs.disable() 
        _ifs.close() 
        _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)
Пример #2
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)
Пример #3
0
def main():
    try:

        #       signal.signal(signal.SIGINT, signal_handler)

        _wheel_circumference_mm = 218
        _forward_steps_per_rotation = 494
        _forward_steps = get_forward_steps()

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

        _queue = MessageQueue(Level.INFO)
        _indicator = Indicator(Level.INFO)
        _compass = Compass(_config, _queue, _indicator, Level.INFO)
        _compass.enable()

        print(Fore.CYAN + Style.BRIGHT +
              'wave robot in the air until calibrated.' + Style.RESET_ALL)
        while not _compass.is_calibrated():
            time.sleep(0.33)

        print(
            Fore.CYAN + Style.BRIGHT +
            'CALIBRATED.      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx '
            + Style.RESET_ALL)
        time.sleep(5.0)

        _motors = Motors(_config, None, None, Level.INFO)
        #       _port_motor = _motors.get_motor(Orientation.PORT)
        #       _stbd_motor = _motors.get_motor(Orientation.STBD)

        _heading = 0.0  # due south
        _spin(_motors, Rotation.CLOCKWISE,
              lambda: not has_heading(_compass, _heading))

        print(Fore.CYAN + Style.BRIGHT + 'test complete.' + Style.RESET_ALL)

    except KeyboardInterrupt:
        _stbd_motor.halt()
        quit()
    except Exception as e:
        print(Fore.RED + Style.BRIGHT +
              'error in PID controller: {}'.format(e) + Style.RESET_ALL)
        traceback.print_exc(file=sys.stdout)
    finally:
        print(Fore.YELLOW + Style.BRIGHT + 'C. finally.' + Style.RESET_ALL)
Пример #4
0
def main():

    _log = Logger('main', Level.INFO)
    _rate = Rate(20) # Hz

    _loader = ConfigLoader(Level.INFO)
    filename = 'config.yaml'
    _config = _loader.configure(filename)
    _pot = Potentiometer(_config, Level.INFO)
#   _pot.set_out_max(3.0)

    try:

        # motors ...............................................................
        _motors = Motors(_config, None, Level.INFO)
        _port_motor = _motors.get_motor(Orientation.PORT)
        _stbd_motor = _motors.get_motor(Orientation.STBD)
#       _motor = _stbd_motor

        # pid ..................................................................
        _pid_config = _config['ros'].get('motors').get('pid')

        _target_velocity = 0.0

        _port_pid = PID(_config, setpoint=_target_velocity, sample_time=_rate.get_period_sec(), level=Level.INFO)
        _stbd_pid = PID(_config, setpoint=_target_velocity, sample_time=_rate.get_period_sec(), level=Level.INFO)

#       _stbd_pid.auto_mode = True
#       _stbd_pid.proportional_on_measurement = True
#       _stbd_pid.set_auto_mode(False)
#       _stbd_pid.tunings = ( _kp, _ki, _kd )
#       _stbd_pid.output_limits = ( -10.0, 10.0 )
#       _stbd_pid.sample_time = _rate.get_period_sec()
#       _log.info(Fore.GREEN + 'sample time: {:>6.3f} sec.'.format(_stbd_pid.sample_time))

#       _clip_max = 1.0
#       _clip_min = -1.0 * _clip_max
#       _clip = lambda n: _clip_min if n <= _clip_min else _clip_max if n >= _clip_max else n
#       _limiter = SlewLimiter(_config, None, Level.WARN)
#       _limiter.enable()
#       _stbd_pid.setpoint = _target_velocity

        _kp = 0.0
        _ki = 0.0
        _kd = 0.0
        _power = 0.0
        _limit = -1
        _count = -1

        try:
            while True: 
                _count = 0
                _counter = itertools.count()
                while _limit < 0 or _count < _limit:

                    _count = next(_counter)
                    _pot_value = _pot.get_scaled_value()
                    _target_velocity = _pot_value

                    _port_pid.setpoint = _target_velocity
#                   _port_pid.tunings = ( _kp, _ki, _kd )
                    _last_power = _port_motor.get_current_power_level()
                    _current_velocity = _port_motor.get_velocity()
                    _power += _port_pid(_current_velocity) / 100.0
                    _set_power = _power / 100.0
                    _port_motor.set_motor_power(_power)
                    # .........................
                    kp, ki, kd = _port_pid.constants
                    print(Fore.RED + '{:d}\tPID:{:6.3f}|{:6.3f}|{:6.3f};\tLAST={:>7.4f}\tSET={:>7.4f};  \tvel: {:>6.3f}/{:>6.3f}'.format(\
                            _count, kp, ki, kd, _last_power, _power, _current_velocity, _target_velocity) + Style.RESET_ALL)

                    _stbd_pid.setpoint = _target_velocity
#                   _stbd_pid.tunings = ( _kp, _ki, _kd )
                    _last_power = _stbd_motor.get_current_power_level()
                    _current_velocity = _stbd_motor.get_velocity()
                    _power += _stbd_pid(_current_velocity) / 100.0
#                   _set_power = _power / 100.0
                    _stbd_motor.set_motor_power(_power)
                    # .........................
                    kp, ki, kd = _stbd_pid.constants
                    print(Fore.GREEN + '{:d}\tPID:{:6.3f}|{:6.3f}|{:6.3f};\tLAST={:>7.4f}\tSET={:>7.4f};  \tvel: {:>6.3f}/{:>6.3f}'.format(\
                            _count, kp, ki, kd, _last_power, _power, _current_velocity, _target_velocity) + Style.RESET_ALL)

                    _rate.wait()

                _motors.brake()
                time.sleep(1.0)

        except KeyboardInterrupt:
            _log.info(Fore.CYAN + Style.BRIGHT + 'B. motor test complete.')
        finally:
            _motors.brake()

        '''
        Kpro = 0.380
        Kdrv = 0.0
        last_proportional_error = 0.0
        power = 0.0
        while True:
            Kdrv = _pot.get_scaled_value()
            _current_velocity = _motor.get_velocity()
            proportional_error = _target_velocity - _current_velocity
            derivative_error = proportional_error - last_proportional_error
            last_proportional_error = proportional_error
            power += (proportional_error * Kpro) + (derivative_error * Kdrv)
            _motor.set_motor_power( power / 100.0 )
            _log.info(Fore.GREEN + ' P:{:6.3f}; D:{:6.3f};'.format(Kpro, Kdrv) \
                    + Fore.YELLOW + ' power: {:>8.5f};'.format(power) \
                    + Fore.MAGENTA + ' velocity: {:>6.3f}/{:>6.3f}'.format(_current_velocity, _target_velocity))
            _rate.wait()
        '''




    except Exception as e:
        _log.info(Fore.RED + Style.BRIGHT + 'error in PID controller: {}'.format(e))
        traceback.print_exc(file=sys.stdout)
    finally:
        _log.info(Fore.YELLOW + Style.BRIGHT + 'C. finally.')
Пример #5
0
def main():

    _level = Level.INFO
    _log = Logger('main', _level)
    _loader = ConfigLoader(_level)
    _config = _loader.configure('config.yaml')

    try:
        _motors = Motors(_config, None, Level.WARN)
        _pot = Potentiometer(_config, Level.WARN)
        _pot.set_output_limits(0.0, 127.0) 

        # motor configuration: starboard, port or both?
        _orientation = Orientation.BOTH

        if _orientation == Orientation.BOTH or _orientation == Orientation.PORT:
            _port_motor = _motors.get_motor(Orientation.PORT)
            _port_pid = PIDController(_config, _port_motor, level=Level.WARN)
            _port_pid.enable()

        if _orientation == Orientation.BOTH or _orientation == Orientation.STBD:
            _stbd_motor = _motors.get_motor(Orientation.STBD)
            _stbd_pid = PIDController(_config, _stbd_motor, level=Level.WARN)
            _stbd_pid.enable()

        ROTATE = True
        _rotate = -1.0 if ROTATE else 1.0
     
#       sys.exit(0)
        _stbd_velocity = 0.0
        _port_velocity = 0.0

        _step =  0.5
        _min  =  0.0
        _max  = 70.0
        _rate = Rate(10)

        try:

#           for _value in numpy.arange(_min, _max, _step):
            while True:
                # update RGB LED
#               _pot.set_rgb(_pot.get_value())
                _value = 127.0 - _pot.get_scaled_value(True)
                if _value > 125.0:
                    _value = 127.0
                _velocity = Gamepad.convert_range(_value)
                if _orientation == Orientation.BOTH or _orientation == Orientation.PORT:
                    _port_pid.setpoint = _velocity * 100.0
                    _port_velocity = _port_pid.setpoint
                if _orientation == Orientation.BOTH or _orientation == Orientation.STBD:
                    _stbd_pid.setpoint = _rotate * _velocity * 100.0
                    _stbd_velocity = _stbd_pid.setpoint
                _log.info(Fore.WHITE + 'value: {:<5.2f}; set-point: {:5.2f}; velocity: '.format(_value, _velocity) \
                        + Fore.RED   + ' port: {:5.2f}\t'.format(_port_velocity) + Fore.GREEN + ' stbd: {:5.2f}'.format(_stbd_velocity))
                _rate.wait()

            _log.info(Fore.YELLOW + 'resting...')
            time.sleep(10.0)

#           for _value in numpy.arange(_min, _max, _step):
            while True:
                # update RGB LED
#               _pot.set_rgb(_pot.get_value())
                _value = 127.0 - _pot.get_scaled_value(True)
                if _value > 125.0:
                    _value = 127.0
                _velocity = Gamepad.convert_range(_value)
                if _orientation == Orientation.BOTH or _orientation == Orientation.PORT:
                    _port_pid.setpoint = _rotate * _velocity * 100.0
                    _port_velocity = _port_pid.setpoint
                if _orientation == Orientation.BOTH or _orientation == Orientation.STBD:
                    _stbd_pid.setpoint = _velocity * 100.0
                    _stbd_velocity = _stbd_pid.setpoint
                _log.info(Fore.MAGENTA + 'value: {:<5.2f}; set-point: {:5.2f}; velocity: '.format(_value, _velocity) \
                        + Fore.RED   + ' port: {:5.2f}\t'.format(_port_velocity) + Fore.GREEN + ' stbd: {:5.2f}'.format(_stbd_velocity))
                _rate.wait()

            _log.info(Fore.YELLOW + 'end of cruising.')

        except KeyboardInterrupt:
            _log.info(Fore.CYAN + Style.BRIGHT + 'PID test complete.')
        finally:
            if _orientation == Orientation.BOTH or _orientation == Orientation.PORT:
                _port_pid.disable()
            if _orientation == Orientation.BOTH or _orientation == Orientation.STBD:
                _stbd_pid.disable()
            _motors.brake()

    except Exception as e:
        _log.info(Fore.RED + Style.BRIGHT + 'error in PID controller: {}\n{}'.format(e, traceback.format_exc()))

    finally:
        _log.info(Fore.YELLOW + Style.BRIGHT + 'C. finally.')
Пример #6
0
def main():
    '''
         494 encoder steps per rotation (maybe 493)
         218mm wheel circumference
         1 wheel rotation = 218mm
         2262 steps per meter
         2262 steps per second = 1 m/sec
         2262 steps per second = 100 cm/sec

    '''
    STEPS_PER_METER = 2262
    _wheel_circumference_mm = 218
    _forward_steps_per_rotation = 494
    _reverse_steps_per_rotation = 494

    signal.signal(signal.SIGINT, signal_handler)

    try:
        _loader = ConfigLoader(Level.INFO)
        filename = 'config.yaml'
        _config = _loader.configure(filename)

        _speed = 70.0

        _motors = Motors(_config, None, None, Level.DEBUG)
        _port_motor = _motors.get_motor(Orientation.PORT)
        _stbd_motor = _motors.get_motor(Orientation.STBD)
        _motors.enable()

        _rotations = 3
        forward_test = True
        if forward_test:
            #_forward_steps_per_rotation * _rotations
            _forward_steps = int(1.0 * STEPS_PER_METER)

            print(Fore.YELLOW + Style.BRIGHT + 'starting forward motor test for steps: {:d}.'.format(_forward_steps) + Style.RESET_ALL)
            while not _motors.ahead_for_steps(_speed, _speed, _forward_steps, _forward_steps):
                time.sleep(0.1)

            time.sleep(2.0)

#           _speed = -1 * _speed
#           while not _motors.ahead_for_steps(_speed, _speed, _forward_steps, _forward_steps):
#               time.sleep(0.1)

            print(Fore.YELLOW + Style.BRIGHT + 'motor test complete; intended: {:d}; actual steps: {:d}/{:d}.'.format(\
                    _forward_steps, _port_motor.get_steps(), _stbd_motor.get_steps()) + Style.RESET_ALL)

        else:
            _reverse_steps = _reverse_steps_per_rotation * _rotations
            print(Fore.YELLOW + Style.BRIGHT + 'starting reverse motor test for steps: {:d}.'.format(_reverse_steps) + Style.RESET_ALL)
#           _stbd_motor.ahead_for_steps(-30.0, _reverse_steps)
#           _stbd_motor.stop()
#           print(Fore.YELLOW + Style.BRIGHT + 'motor test complete; intended: {:d}; actual steps: {:d}.'.format(\
#                   _reverse_steps, _stbd_motor.get_steps()) + Style.RESET_ALL)

    except KeyboardInterrupt:
        print('Ctrl-C caught, exiting...')
    finally:
        if _motors:
            _motors.brake()
Пример #7
0
def main():

    _level = Level.INFO
    _log = Logger('main', _level)
    _loader = ConfigLoader(_level)
    _config = _loader.configure('config.yaml')
    _rot_min = 0
    _rot_max = 100
    _rot_step = 5
    _rot_ctrl = RotaryControl(_config, _rot_min, _rot_max, _rot_step,
                              Level.WARN)

    _pot_min = 0.0
    _pot_max = 0.00030
    _pot = Potentiometer(_config, Level.INFO)
    _pot.set_output_limits(_pot_min, _pot_max)

    try:
        _motors = Motors(_config, None, _level)
        #       _port_motor = _motors.get_motor(Orientation.PORT)
        #       _port_pid = PIDController(_config, _port_motor, level=Level.DEBUG)

        _stbd_motor = _motors.get_motor(Orientation.STBD)
        _stbd_pid = PIDController(_config, _stbd_motor, level=Level.DEBUG)

        #       sys.exit(0)

        _max_velocity = 30.0
        #       _port_pid.enable()
        _stbd_pid.enable()

        try:

            _log.info(Fore.YELLOW + 'accelerating...')

            _read_value = _rot_ctrl.read()
            _velocity = _read_value / 100.0
            _log.info(Fore.YELLOW + 'value: {}'.format(_read_value))
            _stbd_pid.setpoint = 10.0

            #           for _velocity in numpy.arange(0.0, _max_velocity, 0.3):
            #               _log.info(Fore.YELLOW + '_velocity={:>5.2f}.'.format(_velocity))
            #               _stbd_pid.setpoint = _velocity
            #               _log.info(Fore.GREEN + 'STBD setpoint={:>5.2f}.'.format(_stbd_pid.setpoint))
            #               _port_pid.setpoint = _velocity
            #               _log.info(Fore.RED   + 'PORT setpoint={:>5.2f}.'.format(_port_pid.setpoint))

            #               time.sleep(1.0)
            # ..........................................

            _log.info(Fore.YELLOW + 'cruising...')
            time.sleep(10.0)
            _log.info(Fore.YELLOW + 'end of cruising.')

            #           _log.info(Fore.YELLOW + 'decelerating...')
            #           for _velocity in numpy.arange(_max_velocity, 0.0, -0.25):
            #               _log.info(Fore.YELLOW + '_velocity={:>5.2f}.'.format(_velocity))
            #               _port_pid.setpoint = _velocity
            #               _stbd_pid.setpoint = _velocity
            #               _log.info(Fore.GREEN + 'STBD setpoint={:>5.2f}.'.format(_stbd_pid.setpoint))
            #               _log.info(Fore.RED   + 'PORT setpoint={:>5.2f}.'.format(_port_pid.setpoint))
            #               time.sleep(1.0)

            #           _log.info(Fore.YELLOW + 'stopped...')
            _stbd_pid.setpoint = 0.0
            time.sleep(3.0)
            _log.info(Fore.YELLOW + 'end of test.')

        except KeyboardInterrupt:
            _log.info(Fore.CYAN + Style.BRIGHT + 'PID test complete.')
        finally:
            #           _port_pid.disable()
            _stbd_pid.disable()
            _motors.brake()

    except Exception as e:
        _log.info(Fore.RED + Style.BRIGHT +
                  'error in PID controller: {}'.format(e))
        traceback.print_exc(file=sys.stdout)
    finally:
        _log.info(Fore.YELLOW + Style.BRIGHT + 'C. finally.')
Пример #8
0
def main():
    global test_triggered, test_enabled
    # initial states
    test_triggered = False
    test_enabled = True

    _loader = ConfigLoader(_level)
    _config = _loader.configure('config.yaml')

    _pin_A = 12
    _button_24 = Button(_pin_A, callback_method_A, Level.INFO)
    _log.info(
        Style.BRIGHT +
        'press button A (connected to pin {:d}) to toggle or initiate action.'.
        format(_pin_A))

    _pin_B = 24
    _button_24 = Button(_pin_B, callback_method_B, Level.INFO)
    _log.info(Style.BRIGHT +
              'press button B connected to pin {:d}) to exit.'.format(_pin_B))

    try:

        # .........................................
        _motors = Motors(_config, None, Level.INFO)
        _pot = Potentiometer(_config, Level.WARN)

        _pot_min = 0.0000
        _pot_max = 0.1500
        _pot.set_output_limits(_pot_min, _pot_max)

        _limit = 90.0
        #       _min    = -127
        _stbd_setpoint = 0.0
        _port_setpoint = 0.0
        _scaled_value = 0.0
        _value = 0.0
        _port_pid = None
        _stbd_pid = None

        # rotary controller
        _min = 90
        _max = 0
        _step = 5
        _rotary_ctrl = RotaryControl(_config, _min, _max, _step, Level.INFO)

        # configure motors/PID controllers
        _port_motor = _motors.get_motor(Orientation.PORT)
        _port_pid = PIDController(_config, _port_motor, level=Level.INFO)
        _port_pid.set_limit(_limit)
        if ORIENTATION == Orientation.BOTH or ORIENTATION == Orientation.PORT:
            _port_pid.enable()
        if ORIENTATION == Orientation.BOTH or ORIENTATION == Orientation.STBD:
            _stbd_motor = _motors.get_motor(Orientation.STBD)
            _stbd_pid = PIDController(_config, _stbd_motor, level=Level.INFO)
            _stbd_pid.set_limit(_limit)
            _stbd_pid.enable()


#       sys.exit(0)

        _fixed_value = 15.0  # fixed setpoint value
        DRY_RUN = False
        USE_POTENTIOMETER = False
        USE_ROTARY_ENCODER = False
        ANYTHING_ELSE = False

        try:
            while test_enabled:
                if test_triggered:
                    _log.info(Fore.BLUE + Style.BRIGHT + 'action A.')
                    test_triggered = False  # trigger once
                    rotate_in_place(_rotary_ctrl, _port_pid, _stbd_pid)
                    test_enabled = False  # quit after action
                    time.sleep(1.0)
                    # and we now return to our regularly scheduled broadcast...
                _kp = _pot.get_scaled_value(True)
                _stbd_pid._pid.kp = _kp
                _log.info(Fore.YELLOW + 'waiting for button A...;' +
                          Style.BRIGHT +
                          ' kp: {:8.5f}'.format(_stbd_pid._pid.kp))
                time.sleep(1.0)

            _log.info(Fore.YELLOW + 'end of test.')

        except KeyboardInterrupt:
            _log.info(Fore.CYAN + Style.BRIGHT + 'Ctrl-C caught: closing...')
        finally:
            if ORIENTATION == Orientation.BOTH or ORIENTATION == Orientation.PORT:
                _port_pid.disable()
            if ORIENTATION == Orientation.BOTH or ORIENTATION == Orientation.STBD:
                _stbd_pid.disable()
            _motors.brake()
            if _rotary_ctrl:
                _log.info('resetting rotary encoder...')
                _rotary_ctrl.reset()
            time.sleep(1.0)
            _log.info('complete.')

    except Exception as e:
        _log.info(Fore.RED + Style.BRIGHT +
                  'error in test: {}'.format(e, traceback.format_exc()))
    finally:
        _log.info(Fore.YELLOW + Style.BRIGHT + 'finally.')
Пример #9
0
    def __init__(self, level):
        super().__init__()
        _loader = ConfigLoader(Level.INFO)
        filename = 'config.yaml'
        _config = _loader.configure(filename)
        self._log = Logger("gamepad-demo", level)
        self._log.heading('gamepad-demo', 'Configuring Gamepad...', None)
        self._config = _config['ros'].get('gamepad_demo')
        self._enable_ifs = self._config.get('enable_ifs')
        self._enable_compass = self._config.get('enable_compass')
        self._enable_indicator = self._config.get('enable_indicator')
        self._message_factory = MessageFactory(level)
        self._motors = Motors(_config, None, Level.INFO)
        #       self._motor_controller = SimpleMotorController(self._motors, Level.INFO)
        self._pid_motor_ctrl = PIDMotorController(_config, self._motors,
                                                  Level.INFO)
        # i2c scanner, let's us know if certain devices are available
        _i2c_scanner = I2CScanner(Level.WARN)
        _addresses = _i2c_scanner.get_int_addresses()
        ltr559_available = (0x23 in _addresses)
        '''
        Availability of displays:
        The 5x5 RGB Matrix is at 0x74 for port, 0x77 for starboard.
        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.
        We check for either the 0x74 address to see if RGB Matrix displays are 
        used, OR for 0x75 to assume a pair of 11x7 Matrix displays are being used.
        '''
        #       rgbmatrix5x5_stbd_available = ( 0x74 in _addresses ) # not used yet
        #       matrix11x7_stbd_available   = ( 0x75 in _addresses ) # used as camera lighting
        matrix11x7_stbd_available = False

        #       self._blob       = BlobSensor(_config, self._motors, Level.INFO)
        self._blob = None
        self._lux = Lux(Level.INFO) if ltr559_available else None
        self._video = None
        #       self._video      = Video(_config, self._lux, matrix11x7_stbd_available, Level.INFO)

        self._message_bus = MessageBus(Level.INFO)

        # in this application the gamepad controller is the message queue
        #       self._queue = MessageQueue(self._message_factory, Level.INFO)

        self._clock = Clock(_config, self._message_bus, self._message_factory,
                            Level.INFO)

        # attempt to find the gamepad
        self._gamepad = Gamepad(_config, self._message_bus,
                                self._message_factory, Level.INFO)

        #       if self._enable_indicator:
        #           self._indicator = Indicator(Level.INFO)
        #       if self._enable_compass:
        #           self._compass = Compass(_config, self._queue, self._indicator, Level.INFO)
        #           self._video.set_compass(self._compass)

        _enable_battery_check = False
        if _enable_battery_check:
            self._log.info('starting battery check thread...')
            self._battery_check = BatteryCheck(_config, self._queue,
                                               self._message_factory,
                                               Level.INFO)
        else:
            self._battery_check = None

        if self._enable_ifs:
            self._log.info('integrated front sensor enabled.')
            self._ifs = IntegratedFrontSensor(_config, self._clock,
                                              self._message_bus,
                                              self._message_factory,
                                              Level.INFO)
            # add indicator as message consumer
            if self._enable_indicator:
                self._queue.add_consumer(self._indicator)
        else:
            self._ifs = None
            self._log.info('integrated front sensor disabled.')

#       self._ctrl = GamepadController(_config, self._queue, self._pid_motor_ctrl, self._ifs, self._video, self._blob, matrix11x7_stbd_available, Level.INFO, self._close_demo_callback)
        self._ctrl = GamepadController(_config, self._message_bus,
                                       self._pid_motor_ctrl, self._ifs,
                                       self._video, self._blob,
                                       matrix11x7_stbd_available, Level.INFO,
                                       self._close_demo_callback)
        self._message_bus.add_handler(Message, self._ctrl.handle_message)

        self._enabled = False
        self._log.info('connecting gamepad...')
        self._gamepad.connect()
        self._log.info('ready.')
Пример #10
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2020 by Murray Altheim. All rights reserved. This file is part of
# the Robot OS project and is released under the "Apache Licence, Version 2.0".
# Please see the LICENSE file included as part of this package.
#
# author:   Murray Altheim
# created:  2020-03-30
# modified: 2020-08-21
#
#  Quickly halts the motors if they're running.
#

import time
from lib.logger import Level
from lib.config_loader import ConfigLoader
from lib.motors import Motors

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

_motors = Motors(_config, None, Level.INFO)
_motors.halt()

_motors.close()

#EOF
Пример #11
0
    def configure(self):
        '''
            Import the ThunderBorg library, then configure and return the Motors.
        '''
        self._log.info('configure thunderborg & motors...')
        try:
            self._log.info('importing ThunderBorg...')
            import lib.ThunderBorg3 as ThunderBorg
            self._log.info('successfully imported ThunderBorg.')
            TB = ThunderBorg.ThunderBorg(Level.INFO)  # create a new ThunderBorg object
            TB.Init()                       # set the board up (checks the board is connected)
            self._log.info('successfully instantiated ThunderBorg.')

            if not TB.foundChip:
                boards = ThunderBorg.ScanForThunderBorg()
                if len(boards) == 0:
                    self._log.error('No ThunderBorg found, check you are attached :)')
                else:
                    self._log.error('No ThunderBorg at address %02X, but we did find boards:' % (TB.i2cAddress))
                    for board in boards:
                        self._log.info('    %02X (%d)' % (board, board))
                    self._log.error('If you need to change the I²C address change the setup line so it is correct, e.g. TB.i2cAddress = 0x{}'.format(boards[0]))
                sys.exit(1)
            TB.SetLedShowBattery(True)
    
            # initialise ThunderBorg ...........................
            self._log.debug('getting battery reading...')
            # get battery voltage to determine max motor power
            # could be: Makita 12V or 18V power tool battery, or 12V line supply
            voltage_in = TB.GetBatteryReading()
            if voltage_in is None:
                raise OSError('cannot continue: cannot read battery voltage.')
            self._log.info('voltage in: {:>5.2f}V'.format(voltage_in))
    #       voltage_in = 20.5
            # maximum motor voltage
            voltage_out = 9.0
            self._log.info('voltage out: {:>5.2f}V'.format(voltage_out))
            if voltage_in < voltage_out:
                raise OSError('cannot continue: battery voltage too low ({:>5.2f}V).'.format(voltage_in))
            # Setup the power limits
            if voltage_out > voltage_in:
                _max_power_ratio = 1.0
            else:
                _max_power_ratio = voltage_out / float(voltage_in)
            # convert float to ratio format
            self._log.info('battery level: {:>5.2f}V; motor voltage: {:>5.2f}V; maximum power ratio: {}'.format(voltage_in, voltage_out, \
                    str(Fraction(_max_power_ratio).limit_denominator(max_denominator=20)).replace('/',':')))

        except Exception as e:
            self._log.error('unable to import ThunderBorg: {}'.format(e))
            traceback.print_exc(file=sys.stdout)
            sys.exit(1)

        # now import motors
        from lib.motors import Motors
        try:
            self._log.info('getting raspberry pi...')
            self._log.info('configuring motors...')
            self._motors = Motors(self._config, TB, Level.INFO)
            self._motors.get_motor(Orientation.PORT).set_max_power_ratio(_max_power_ratio)
            self._motors.get_motor(Orientation.STBD).set_max_power_ratio(_max_power_ratio)
            return self._motors
        except OSError as oe:
            self._log.error('failed to configure motors: {}'.format(oe))
#           sys.stderr = DevNull()
            sys.exit(1)
Пример #12
0
def main():
    '''
         494 encoder steps per rotation (maybe 493)
         218mm wheel circumference
         1 wheel rotation = 218mm
         2262 steps per meter
         2262 steps per second = 1 m/sec
         2262 steps per second = 100 cm/sec

    '''
    _wheel_circumference_mm = 218
    _forward_steps_per_rotation = 494
    _reverse_steps_per_rotation = 494

    signal.signal(signal.SIGINT, signal_handler)

    try:
        _loader = ConfigLoader(Level.INFO)
        filename = 'config.yaml'
        _config = _loader.configure(filename)

        _port_speed = 0.0
        _stbdt_speed = 50.0
        _port_steps = 0
        _stbd_steps = 0

        _motors = Motors(_config, None, None, Level.INFO)
        #       _motors.step(_port_speed, _stbd_speed, _port_steps, _stbd_steps):

        _speed = 70.0
        _port_motor = _motors.get_motor(Orientation.PORT)
        _stbd_motor = _motors.get_motor(Orientation.STBD)

        _rotations = 4
        forward_test = True
        if forward_test:
            _forward_steps = _forward_steps_per_rotation * _rotations
            print(Fore.YELLOW + Style.BRIGHT +
                  'starting forward motor test for steps: {:d}.'.format(
                      _forward_steps) + Style.RESET_ALL)

            #           _port_motor.ahead_for_steps(_speed, _forward_steps)
            #           _stbd_motor.ahead_for_steps(_speed, _forward_steps)
            #           _port_motor.stop()
            #           _stbd_motor.stop()

            _motors.ahead_for_steps(_speed, _speed, _forward_steps,
                                    _forward_steps)
            _motors.stop()

            print(Fore.YELLOW + Style.BRIGHT + 'motor test complete; intended: {:d}; actual port steps: {:d}, stbd steps: {:d}'.format(\
                    _forward_steps, _port_motor.get_steps(), _stbd_motor.get_steps()) + Style.RESET_ALL)

        else:
            _reverse_steps = _reverse_steps_per_rotation * _rotations
            print(Fore.YELLOW + Style.BRIGHT +
                  'starting reverse motor test for steps: {:d}.'.format(
                      _reverse_steps) + Style.RESET_ALL)
            _stbd_motor.ahead_for_steps(-30.0, _reverse_steps)
            _stbd_motor.stop()
            print(Fore.YELLOW + Style.BRIGHT +
                  'motor test complete; intended: {:d}; actual steps: {:d}.'.
                  format(_reverse_steps, _stbd_motor.get_steps()) +
                  Style.RESET_ALL)

    except KeyboardInterrupt:
        print('Ctrl-C caught, exiting...')
    finally:
        _motors.brake()
Пример #13
0
class MotorConfigurer():
    '''
    Configures the ThunderBorg motor controller for a pair of motors.

    :param config:       the application configuration
    :param clock:        the 'system' clock providing timing for velocity calculation
    :param enable_mock:  if set True a failure to instantiate the ThunderBorg will instead use a mock
    :param level:        the logging level
    '''
    def __init__(self, config, clock, enable_mock=False, level=Level.INFO):
        self._log = Logger("motor-conf", level)
        if config is None:
            raise ValueError('null configuration argument.')
        if clock is None:
            raise ValueError('null clock argument.')
        self._config = config
        # Import the ThunderBorg library, then configure and return the Motors.
        self._log.info('configure thunderborg & motors...')
        try:

            _i2c_scanner = I2CScanner(Level.WARN)
            _has_thunderborg = _i2c_scanner.has_address([THUNDERBORG_ADDRESS])
            if _has_thunderborg:
                self._log.info('importing ThunderBorg...')
                import lib.ThunderBorg3 as ThunderBorg
                self._log.info('successfully imported ThunderBorg.')
            else:
                self._log.info('importing mock ThunderBorg...')
                import mock.thunderborg as ThunderBorg
                self._log.info('successfully imported mock ThunderBorg.')

            TB = ThunderBorg.ThunderBorg(Level.INFO)  # create a new ThunderBorg object
            TB.Init()                       # set the board up (checks the board is connected)
            self._log.info('successfully instantiated ThunderBorg.')

            if not TB.foundChip:
                boards = ThunderBorg.ScanForThunderBorg()
                if len(boards) == 0:
                    self._log.error('No ThunderBorg found, check you are attached :)')
                else:
                    self._log.error('No ThunderBorg at address %02X, but we did find boards:' % (TB.i2cAddress))
                    for board in boards:
                        self._log.info('    %02X (%d)' % (board, board))
                    self._log.error('If you need to change the I²C address change the setup line so it is correct, e.g. TB.i2cAddress = 0x{}'.format(boards[0]))
                raise Exception('unable to instantiate ThunderBorg [1].')
#               sys.exit(1)
            TB.SetLedShowBattery(True)

            # initialise ThunderBorg ...........................
            self._log.debug('getting battery reading...')
            # get battery voltage to determine max motor power
            # could be: Makita 12V or 18V power tool battery, or 12V line supply
            voltage_in = TB.GetBatteryReading()
            if voltage_in is None:
                raise OSError('cannot continue: cannot read battery voltage.')
            self._log.info('voltage in: {:>5.2f}V'.format(voltage_in))
    #       voltage_in = 20.5
            # maximum motor voltage
            voltage_out = 9.0
            self._log.info('voltage out: {:>5.2f}V'.format(voltage_out))
            if voltage_in < voltage_out:
                raise OSError('cannot continue: battery voltage too low ({:>5.2f}V).'.format(voltage_in))
            # Setup the power limits
            if voltage_out > voltage_in:
                _max_power_ratio = 1.0
            else:
                _max_power_ratio = voltage_out / float(voltage_in)
            # convert float to ratio format
            self._log.info('battery level: {:>5.2f}V; motor voltage: {:>5.2f}V; maximum power ratio: {}'.format(voltage_in, voltage_out, \
                    str(Fraction(_max_power_ratio).limit_denominator(max_denominator=20)).replace('/',':')))

        except OSError as e:
            if enable_mock:
                self._log.info('using mock ThunderBorg.')
                import mock.thunderborg as ThunderBorg
            else:
                self._log.error('unable to import ThunderBorg: {}'.format(e))
                traceback.print_exc(file=sys.stdout)
                raise Exception('unable to instantiate ThunderBorg [2].')
        except Exception as e:
            if enable_mock:
                self._log.info('using mock ThunderBorg.')
                import mock.thunderborg as ThunderBorg
            else:
                self._log.error('unable to import ThunderBorg: {}'.format(e))
                traceback.print_exc(file=sys.stdout)
                raise Exception('unable to instantiate ThunderBorg [2].')
#               sys.exit(1)

        # now import motors
        from lib.motors import Motors
        try:
            self._log.info('getting raspberry pi...')
            self._log.info('configuring motors...')
            self._motors = Motors(self._config, clock, TB, Level.INFO)
            self._motors.get_motor(Orientation.PORT).set_max_power_ratio(_max_power_ratio)
            self._motors.get_motor(Orientation.STBD).set_max_power_ratio(_max_power_ratio)
        except OSError as oe:
            self._log.error('failed to configure motors: {}'.format(oe))
            self._motors = None
#           sys.stderr = DevNull()
            raise Exception('unable to instantiate ThunderBorg [3].')
#           sys.exit(1)
        self._log.info('ready.')

    # ..........................................................................
    def get_motors(self):
        '''
        Return the configured motors.
        '''
        return self._motors
Пример #14
0
from colorama import init, Fore, Style
init()

from lib.logger import Level
from lib.motors import Motors
from lib.config_loader import ConfigLoader

# ..............................................................................
try:

    print('brake             :' + Fore.CYAN + Style.BRIGHT +
          ' INFO  : braking...' + Style.RESET_ALL)

    # read YAML configuration
    _loader = ConfigLoader(Level.INFO)
    filename = 'config.yaml'
    _config = _loader.configure(filename)

    _motors = Motors(_config, None, None, Level.INFO)
    _motors.brake()

except KeyboardInterrupt:
    print(Fore.RED + 'Ctrl-C caught in main: exiting...' + Style.RESET_ALL)
finally:
    _motors.stop()
    _motors.close()
    print('brake             :' + Fore.CYAN + Style.BRIGHT +
          ' INFO  : complete.' + Style.RESET_ALL)

#EOF