def _configure_thunderborg_motors(self, level): ''' Import the ThunderBorg library, then configure the Motors. ''' self._log.info('configure thunderborg & motors...') global pi try: self._log.info('importing thunderborg...') import lib.ThunderBorg3 as ThunderBorg self._log.info('successfully imported thunderborg.') TB = ThunderBorg.ThunderBorg(level) # 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:'.format(TB.i2cAddress)) for board in boards: self._log.info('board {:02x} {:d}'.format(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) return TB except Exception as e: self._log.error('unable to import thunderborg: {}'.format(e)) traceback.print_exc(file=sys.stdout) sys.exit(1)
def __init__(self, config, clock, queue, message_factory, level): self._log = Logger("battery", level) if config is None: raise ValueError('no configuration provided.') _battery_config = config['ros'].get('battery') # configuration .................... self._enable_battery_messaging = _battery_config.get('enable_battery_messaging') self._enable_channel_a_messaging = _battery_config.get('enable_channel_a_messaging') self._enable_channel_b_messaging = _battery_config.get('enable_channel_b_messaging') _CHANNELS = ['in0/ref', 'in1/ref', 'in2/ref'] self._battery_channel = _CHANNELS[_battery_config.get('battery_channel')] self._five_volt_a_channel = _CHANNELS[_battery_config.get('five_volt_a_channel')] self._five_volt_b_channel = _CHANNELS[_battery_config.get('five_volt_b_channel')] self._raw_battery_threshold = _battery_config.get('raw_battery_threshold') self._five_volt_threshold = _battery_config.get('low_5v_threshold') _loop_delay_sec = _battery_config.get('loop_delay_sec') self._loop_delay_sec_div_10 = _loop_delay_sec / 10 self._log.info('battery check loop delay: {:>5.2f} sec'.format(_loop_delay_sec)) self._log.info('setting 5v regulator threshold to {:>5.2f}v'.format(self._five_volt_threshold)) self._log.info("channel A from '{}'; channel B from '{}'; raw battery threshold to {:>5.2f}v from '{}'".format(\ self._five_volt_a_channel, self._five_volt_b_channel, self._raw_battery_threshold, self._battery_channel)) self._clock = clock # configure ThunderBorg try: TB = ThunderBorg.ThunderBorg(Level.INFO) TB.Init() if not TB.foundChip: boards = ThunderBorg.ScanForThunderBorg() if len(boards) == 0: raise Exception('no thunderborg found, check you are attached.') else: raise Exception('no ThunderBorg at address {:02x}, but we did find boards:'.format(TB.i2cAddress)) self._tb = TB except Exception as e: self._tb = None self._log.error('unable to configure ThunderBorg: {}\n{}'.format(e, traceback.format_exc())) self._queue = queue self._queue.add_consumer(self) self._message_factory = message_factory self._battery_voltage = 0.0 self._regulator_a_voltage = 0.0 self._regulator_b_voltage = 0.0 try: self._ads1015 = ADS1015() self._ads1015.set_mode('single') self._ads1015.set_programmable_gain(2.048) self._ads1015.set_sample_rate(1600) self._reference = self._ads1015.get_reference_voltage() self._log.info('reference voltage: {:6.3f}v'.format(self._reference)) except Exception as e: raise RuntimeError('error configuring AD converter: {}'.format(traceback.format_exc())) self._count = 0 self._enabled = False self._closed = False self._log.info('ready.')
def _configure_thunderborg_motors(): ''' Import the ThunderBorg library, then configure the Motors. ''' print('tbconfig :' + Fore.CYAN + ' INFO : configure thunderborg & motors...' + Style.RESET_ALL) global pi try: print('tbconfig :' + Fore.CYAN + ' INFO : importing thunderborg...' + Style.RESET_ALL) # sys.path.append('/home/pi/thunderborg') import lib.ThunderBorg3 as ThunderBorg print('tbconfig :' + Fore.CYAN + ' INFO : successfully imported thunderborg.' + Style.RESET_ALL) TB = ThunderBorg.ThunderBorg() # create a new ThunderBorg object TB.Init() # set the board up (checks the board is connected) print('tbconfig :' + Fore.CYAN + ' INFO : successfully instantiated thunderborg.' + Style.RESET_ALL) if not TB.foundChip: boards = ThunderBorg.ScanForThunderBorg() if len(boards) == 0: print( 'tbconfig :' + Fore.RED + Style.BRIGHT + ' ERROR : no thunderborg found, check you are attached.' + Style.RESET_ALL) else: print( 'tbconfig :' + Fore.RED + Style.BRIGHT + ' ERROR : no ThunderBorg at address {:02x}, but we did find boards:' .format(TB.i2cAddress) + Style.RESET_ALL) for board in boards: print('tbconfig :' + Fore.RED + Style.BRIGHT + ' ERROR : {:02x} {:d}'.format(board, board)) print( 'tbconfig :' + Fore.RED + Style.BRIGHT + ' 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]) + Style.RESET_ALL) sys.exit(1) TB.SetLedShowBattery(True) return TB except Exception as e: print('tbconfig :' + Fore.RED + Style.BRIGHT + ' ERROR : unable to import thunderborg: {}'.format(e) + Style.RESET_ALL) traceback.print_exc(file=sys.stdout) sys.exit(1)
def __init__(self, level): super().__init__() self._log = Logger("batlev", Level.INFO) TB = ThunderBorg.ThunderBorg(Level.INFO) TB.Init() if not TB.foundChip: boards = ThunderBorg.ScanForThunderBorg() if len(boards) == 0: raise Exception( 'no thunderborg found, check you are attached.') else: raise Exception( 'no ThunderBorg at address {:02x}, but we did find boards:' .format(TB.i2cAddress)) self._tb = TB self._enabled = False self._thread = None self._loop_delay_sec = 15.0 self._log.info('ready.')
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)