Beispiel #1
0
    def __init__(self):
        print("Initializing QBot2e...")

        # Define DAQ type
        self._card = HIL()
        self._card.open("qbot2e", "0")

        # Configure analog channels
        self._ai_channels = array('I', [0, 4, 5])
        self._ai_buffer = array('d', [0.0] * len(self._ai_channels))

        # Configure digital channels
        self._do_channels = array('I', [i for i in range(28, 36)])
        self._do_buffer = array('b', [0, 0, 0, 0, 1, 1, 1, 1])
        self._di_channels = array('I', [i for i in range(28, 59)])
        self._di_buffer = array('b', [0] * len(self._di_channels))
        #self._card.set_digital_directions(self._di_channels, self._di_num_channels, self._do_channels, self._do_num_channels)

        # Configure other channels
        self._oo_channels = array('I', [2000, 2001])
        self._oo_buffer = array('d', [0.0] * len(self._oo_channels))
        self._oi_channels = array(
            'I', [1002, 3000, 3001, 3002, 11000, 11001, 12000, 16000])
        self._oi_buffer = array('d', [0.0] * len(self._oi_channels))

        # Configure encoder channels
        self._enc_channels = array('I', [0, 1])
        self._enc_buffer = array('i', [0] * len(self._enc_channels))

        # Reset QBot2e
        self.reset()

        print("QBot2e Initialized")
Beispiel #2
0
    def __init__(self):
        # Define DAQ type as Q2-USB
        self._card = HIL()
        self._card.open("q2_usb", "0")

        # Set Q2-USB speed to noraml
        self._card.set_card_specific_options("update_rate=normal;", 50)

        # Configure analog input channels
        self._ai_channels = array('I', [0, 1])
        self._ai_buffer = array('d', [0.0] * len(self._ai_channels))

        # Configure analog output channels
        self._ao_channels = array('I', [0, 1])
        self._ao_buffer = array('d', [0.0] * len(self._ao_channels))

        # Configure encoder input channels
        self._enc_channels = array('I', [0, 1])
        self._enc_buffer = array('i', [0] * len(self._enc_channels))

        # Write 0 V to all AO channels
        self._card.write_analog(self._ao_channels, len(self._ao_channels),
                                self._ao_buffer)

        # Set encoder counts to 0
        _init_enc_counts = array('i', [0, 0])
        self._card.set_encoder_counts(self._enc_channels,
                                      len(self._enc_channels),
                                      _init_enc_counts)

        print("Q2-USB DAQ Initialized")
Beispiel #3
0
    def __init__(self):
        ''' This function configures the QCar and returns a handle to the QCar card. Use the handle for other methods such as qcar_io or terminate_qcar.'''

        self.card = HIL()
        try:
            # Open the Card
            self.card.open("qcar", "0")
            if self.card.is_valid():
                # Set PWM mode (duty cycle) and frequency
                self.card.set_pwm_mode(
                    np.array([0], dtype=np.uint32),
                    len(np.array([0], dtype=np.uint32)),
                    np.array([PWMMode.DUTY_CYCLE], dtype=np.int32))
                self.card.set_pwm_frequency(
                    np.array([0], dtype=np.uint32),
                    len(np.array([0], dtype=np.uint32)),
                    np.array([60e6 / 4096], dtype=np.float64))

                # Set Motor coast to 0
                self.card.write_digital(
                    np.array([40], dtype=np.uint32),
                    len(np.array([40], dtype=np.uint32)),
                    np.zeros(len(np.array([0], dtype=np.uint32)),
                             dtype=np.float64))

                # Set Encoder Quadrature
                encoder_channels = np.array([0], dtype=np.uint32)
                num_encoder_channels = len(encoder_channels)
                self.card.set_encoder_quadrature_mode(
                    encoder_channels, num_encoder_channels,
                    np.array([4], dtype=np.uint32))
                self.card.set_encoder_filter_frequency(
                    encoder_channels, num_encoder_channels,
                    np.array([60e6 / 1], dtype=np.uint32))
                self.card.set_encoder_counts(encoder_channels,
                                             num_encoder_channels,
                                             np.zeros(1, dtype=np.int32))

                print('QCar configured successfully.')

        except HILError as h:
            print(h.get_error_message())
Beispiel #4
0
class QCar():
    #region: Buffers
    # Throttle Write Only - PWM channel 0 is mtr cmd
    write_pwm_channel_throttle = np.array([0], dtype=np.int32)
    write_pwm_buffer_throttle = np.array([0], dtype=np.float64)

    # Steering Write Only - Other channel 1000 is steering cmd
    write_other_channel_steering = np.array([1000], dtype=np.int32)
    write_other_buffer_steering = np.array([0], dtype=np.float64)

    # LEDs Write Only - Other channel 11000:11003 + 11008:11011 are LEDs
    write_other_channels_LEDs = np.array(
        [11008, 11009, 11010, 11011, 11000, 11001, 11002, 11003],
        dtype=np.int32)
    write_other_buffer_LEDs = np.zeros(8, dtype=np.float64)

    # User LEDs Write Only - Other channel 11004:11007 are User LEDs
    write_other_channels_usr_LEDs = np.array([11004, 11005, 11006, 11007],
                                             dtype=np.int32)
    write_other_buffer_usr_LEDs = np.zeros(4, dtype=np.float64)

    # Steering and LEDs Write - Other channel 1000 is steering cmd and 11000:11003 + 11008:11011 are LEDs
    write_other_channels_str_LEDs = np.array(
        [1000, 11008, 11009, 11010, 11011, 11000, 11001, 11002, 11003],
        dtype=np.int32)
    write_other_buffer_str_LEDs = np.append(np.array([0], dtype=np.float64),
                                            np.zeros(8, dtype=np.float64))

    # Initialize return arrays
    mtr_current, bat_voltage = np.zeros(2, dtype=np.float64)
    mtr_encoder = np.zeros(1, dtype=np.int32)
    accelerometer = np.zeros(3, dtype=np.float64)
    gyroscope = np.zeros(3, dtype=np.float64)

    # Battery Read Only - Analog channel 6 is battery voltage
    read_analog_channels_battery = np.array([6], dtype=np.int32)
    read_analog_buffer_battery = np.zeros(1, dtype=np.float64)

    # Encoder Read Only - Encoder channel 0 is throttle motor encoder
    read_encoder_channels_throttle = np.array([0], dtype=np.int32)
    read_encoder_buffer_throttle = np.zeros(1, dtype=np.int32)

    # Gyroscope Read Only - Other channels 3000:3002 are for gyroscope
    read_other_channels_gyroscope = np.array([3000, 3001, 3002],
                                             dtype=np.int32)
    read_other_buffer_gyroscope = np.zeros(3, dtype=np.float64)

    # Accelerometer Read Only - Other channels 4000:4002 are for accelerometer
    read_other_channels_accelerometer = np.array([4000, 4001, 4002],
                                                 dtype=np.int32)
    read_other_buffer_accelerometer = np.zeros(3, dtype=np.float64)

    # IMU Read - Other channels 3000:3002 + 4000:4002 are for IMU
    read_other_channels_IMU = np.array([3000, 3001, 3002, 4000, 4001, 4002],
                                       dtype=np.int32)
    read_other_buffer_IMU = np.zeros(6, dtype=np.float64)

    # Power Read - Analog channels 5, 6 are motor current and battery voltage
    read_analog_channels_power = np.array([5, 6], dtype=np.int32)
    read_analog_buffer_power = np.zeros(2, dtype=np.float64)

    #endregion

    def __init__(self):
        ''' This function configures the QCar and returns a handle to the QCar card. Use the handle for other methods such as qcar_io or terminate_qcar.'''

        self.card = HIL()
        try:
            # Open the Card
            self.card.open("qcar", "0")
            if self.card.is_valid():
                # Set PWM mode (duty cycle) and frequency
                self.card.set_pwm_mode(
                    np.array([0], dtype=np.uint32),
                    len(np.array([0], dtype=np.uint32)),
                    np.array([PWMMode.DUTY_CYCLE], dtype=np.int32))
                self.card.set_pwm_frequency(
                    np.array([0], dtype=np.uint32),
                    len(np.array([0], dtype=np.uint32)),
                    np.array([60e6 / 4096], dtype=np.float64))

                # Set Motor coast to 0
                self.card.write_digital(
                    np.array([40], dtype=np.uint32),
                    len(np.array([40], dtype=np.uint32)),
                    np.zeros(len(np.array([0], dtype=np.uint32)),
                             dtype=np.float64))

                # Set Encoder Quadrature
                encoder_channels = np.array([0], dtype=np.uint32)
                num_encoder_channels = len(encoder_channels)
                self.card.set_encoder_quadrature_mode(
                    encoder_channels, num_encoder_channels,
                    np.array([4], dtype=np.uint32))
                self.card.set_encoder_filter_frequency(
                    encoder_channels, num_encoder_channels,
                    np.array([60e6 / 1], dtype=np.uint32))
                self.card.set_encoder_counts(encoder_channels,
                                             num_encoder_channels,
                                             np.zeros(1, dtype=np.int32))

                print('QCar configured successfully.')

        except HILError as h:
            print(h.get_error_message())

    def terminate(self):
        ''' This function terminates the QCar card after setting final values for throttle, steering and LEDs.'''

        # PWM channel 0 is mtr cmd
        pwm_channels = np.array([0], dtype=np.int32)
        pwm_buffer = np.zeros(1, dtype=np.float64)

        # Other channel 1000 is steering, 11008:11011 are 4x indicators, and 11000:11003 are 4x lamps
        other_channels = np.array(
            [1000, 11000, 11001, 11002, 11003, 11008, 11009, 11010, 11011],
            dtype=np.int32)
        other_buffer = np.zeros(9, dtype=np.float64)

        try:
            self.card.write(None, 0, pwm_channels,
                            len(pwm_channels), None, 0, other_channels,
                            len(other_channels), None, pwm_buffer, None,
                            other_buffer)
            self.card.close()

        except HILError as h:
            print(h.get_error_message())

    def read_encoder(self):
        '''Use this to read encoder counts \n

        OUTPUTS:
        mtr_encoder - throttle motor encoder measurement'''

        try:
            if True:
                #Reads: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.read(None, 0, self.read_encoder_channels_throttle, 1,
                               None, 0, None, 0, None,
                               self.read_encoder_buffer_throttle, None, None)

        except HILError as h:
            print(h.get_error_message())

        finally:
            return self.read_encoder_buffer_throttle[0]

    def read_gyroscope(self):
        '''Use this to read the gyroscope \n
        
        OUTPUTS:
        gyroscope - gyroscopic measurement'''

        try:
            if True:
                #Reads: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.read(None, 0, None, 0, None, 0,
                               self.read_other_channels_gyroscope, 3, None,
                               None, None, self.read_other_buffer_gyroscope)

        except HILError as h:
            print(h.get_error_message())

        finally:
            self.read_other_buffer_IMU[0:3] = self.read_other_buffer_gyroscope
            return self.read_other_buffer_gyroscope

    def read_accelerometer(self):
        '''Use this to read the accelerometer \n

        OUTPUTS:
        accelerometer - accelerometer measurement'''

        try:
            if True:
                #Reads: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.read(None, 0, None, 0, None, 0,
                               self.read_other_channels_accelerometer, 3, None,
                               None, None,
                               self.read_other_buffer_accelerometer)

        except HILError as h:
            print(h.get_error_message())

        finally:
            self.read_other_buffer_IMU[
                3:6] = self.read_other_buffer_accelerometer
            return self.read_other_buffer_accelerometer

    def read_IMU(self):
        '''Use this to read the IMU (gyroscope and accelerometer) \n

        OUTPUTS:
        gyroscope - gyroscopic measurement
        accelerometer - accelerometer measurement'''

        try:
            if True:
                #Reads: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.read(None, 0, None, 0, None, 0,
                               self.read_other_channels_IMU, 6, None, None,
                               None, self.read_other_buffer_IMU)

        except HILError as h:
            print(h.get_error_message())

        finally:
            self.read_other_buffer_gyroscope = self.read_other_buffer_IMU[0:3]
            self.read_other_buffer_accelerometer = self.read_other_buffer_IMU[
                3:6]
            return self.read_other_buffer_gyroscope, self.read_other_buffer_gyroscope

    def read_power(self):
        '''Use this to read the motor current and battery voltage \n

        OUTPUTS:
        mtr_current - throttle motor current measurement
        bat_voltage - battery voltage measurement'''

        try:
            if True:
                #Reads: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.read(self.read_analog_channels_power, 2, None, 0,
                               None, 0, None, 0, self.read_analog_buffer_power,
                               None, None, None)

        except HILError as h:
            print(h.get_error_message())

        finally:
            self.read_analog_buffer_battery = self.read_analog_buffer_power[1]
            return self.read_analog_buffer_power[
                0], self.read_analog_buffer_battery

    def read_std(self):
        '''Use this to read the motor current, battery voltage and encoder counts \n
        
        OUTPUTS:
        mtr_current - throttle motor current measurement
        bat_voltage - battery voltage measurement
        mtr_encoder - throttle motor encoder measurement'''

        # IO
        try:
            if True:
                #Reads: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.read(self.read_analog_channels_power, 2,
                               self.read_encoder_channels_throttle, 1, None, 0,
                               None, 0, self.read_analog_buffer_power,
                               self.read_encoder_buffer_throttle, None, None)

        except HILError as h:
            print(h.get_error_message())

        finally:
            self.read_analog_buffer_battery = self.read_analog_buffer_power[1]
            return self.read_analog_buffer_power[
                0], self.read_analog_buffer_power[
                    1], self.read_encoder_buffer_throttle[0]

    def write_mtrs(self, mtr_cmd):
        '''Use this to write motor commands\n
        INPUTS:
        mtr_cmd - numpy 1x2 array of throttle (%) and steering (rad) motor commands. '''

        self.write_pwm_buffer_throttle[0] = -saturate(mtr_cmd[0], 0.2, -0.2)
        self.write_other_buffer_steering[0] = -saturate(mtr_cmd[1], 0.5, -0.5)

        try:
            if True:
                #Writes: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.write(None, 0, self.write_pwm_channel_throttle, 1,
                                None, 0, self.write_other_channel_steering, 1,
                                None, self.write_pwm_buffer_throttle, None,
                                self.write_other_buffer_steering)

        except HILError as h:
            print(h.get_error_message())

    def write_LEDs(self, LEDs):
        '''Use this to write LED commands\n
        INPUTS:
        LEDs - numpy 1x8 array of 4x indicators (0, 1) and 4x lamps (0, 1)'''

        self.write_other_buffer_LEDs = LEDs

        try:
            if True:
                #Writes: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.write(None, 0, None, 0, None, 0,
                                self.write_other_channels_LEDs, 8, None, None,
                                None, self.write_other_buffer_LEDs)

        except HILError as h:
            print(h.get_error_message())

    def write_usr_LEDs(self, LEDs):
        '''Use this to write user LED commands\n
        INPUTS:
        LEDs - numpy 1x4 array of 4x LEDs'''

        self.write_other_buffer_usr_LEDs = LEDs

        try:
            if True:
                #Writes: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.write(None, 0, None, 0, None, 0,
                                self.write_other_channels_usr_LEDs, 4, None,
                                None, None, self.write_other_buffer_usr_LEDs)

        except HILError as h:
            print(h.get_error_message())

    def write_std(self, mtr_cmd, LEDs):
        '''Use this to write motor and LED commands\n
        INPUTS:
        mtr_cmd - numpy 1x2 array of throttle (%) and steering (rad) motor commands. 
        LEDs - numpy 1x8 array of 4x indicators (0, 1) and 4x lamps (0, 1)'''

        self.write_pwm_buffer_throttle[0] = -saturate(mtr_cmd[0], 0.2, -0.2)
        self.write_other_buffer_str_LEDs[0] = -saturate(mtr_cmd[1], 0.5, -0.5)
        self.write_other_buffer_str_LEDs[1:9] = LEDs

        try:
            if True:
                #Writes: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.write(None, 0, self.write_pwm_channel_throttle, 1,
                                None, 0, self.write_other_channels_str_LEDs, 9,
                                None, self.write_pwm_buffer_throttle, None,
                                self.write_other_buffer_str_LEDs)

        except HILError as h:
            print(h.get_error_message())

    def read_write_std(self, mtr_cmd, LEDs):
        '''Use this to write motor and LED commands, and read the battery voltage, motor current and encoder counts \n

        INPUTS:
        mtr_cmd - numpy 1x2 array of throttle (%) and steering (rad) motor commands. 
        LEDs - numpy 1x8 array of 4x indicators (0, 1) and 4x lamps (0, 1)

        OUTPUTS:
        mtr_current - throttle motor current measurement
        bat_voltage - battery voltage measurement
        mtr_encoder - throttle motor encoder measurement'''

        self.write_pwm_buffer_throttle[0] = -saturate(mtr_cmd[0], 0.2, -0.2)
        self.write_other_buffer_str_LEDs[0] = -saturate(mtr_cmd[1], 0.5, -0.5)
        self.write_other_buffer_str_LEDs[1:9] = LEDs

        # IO
        try:
            if True:
                #Writes: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.write(None, 0, self.write_pwm_channel_throttle, 1,
                                None, 0, self.write_other_channels_str_LEDs, 9,
                                None, self.write_pwm_buffer_throttle, None,
                                self.write_other_buffer_str_LEDs)

                #Reads: Analog Channel, Num Analog Channel, PWM Channel, Num PWM Channel, Digital Channel, Num Digital Channel, Other Channel, Num Other Channel, Analog Buffer, PWM Buffer, Digital Buffer, Other Buffer
                self.card.read(self.read_analog_channels_power, 2,
                               self.read_encoder_channels_throttle, 1, None, 0,
                               None, 0, self.read_analog_buffer_power,
                               self.read_encoder_buffer_throttle, None, None)

        except HILError as h:
            print(h.get_error_message())

        finally:
            self.read_analog_buffer_battery = self.read_analog_buffer_power[1]
            return self.read_analog_buffer_power[
                0], self.read_analog_buffer_battery, self.read_encoder_buffer_throttle[
                    0]
Beispiel #5
0
class QBot2e:

    # Define class-level variables
    _card = None
    _capture = None
    _RGB_stream = None
    _ai_channels = None
    _ai_buffer = None
    _di_channels = None
    _di_buffer = None
    _do_channels = None
    _do_buffer = None
    _oi_channels = None
    _oi_buffer = None
    _gyro_z_bias = None
    _oo_channels = None
    _oo_buffer = None
    _enc_channels = None
    _enc_buffer = None
    _image_data = None

    _qbot_diameter = 0.235

    # Initilize QBot2e
    def __init__(self):
        print("Initializing QBot2e...")

        # Define DAQ type
        self._card = HIL()
        self._card.open("qbot2e", "0")

        # Configure analog channels
        self._ai_channels = array('I', [0, 4, 5])
        self._ai_buffer = array('d', [0.0] * len(self._ai_channels))

        # Configure digital channels
        self._do_channels = array('I', [i for i in range(28, 36)])
        self._do_buffer = array('b', [0, 0, 0, 0, 1, 1, 1, 1])
        self._di_channels = array('I', [i for i in range(28, 59)])
        self._di_buffer = array('b', [0] * len(self._di_channels))
        #self._card.set_digital_directions(self._di_channels, self._di_num_channels, self._do_channels, self._do_num_channels)

        # Configure other channels
        self._oo_channels = array('I', [2000, 2001])
        self._oo_buffer = array('d', [0.0] * len(self._oo_channels))
        self._oi_channels = array(
            'I', [1002, 3000, 3001, 3002, 11000, 11001, 12000, 16000])
        self._oi_buffer = array('d', [0.0] * len(self._oi_channels))

        # Configure encoder channels
        self._enc_channels = array('I', [0, 1])
        self._enc_buffer = array('i', [0] * len(self._enc_channels))

        # Reset QBot2e
        self.reset()

        print("QBot2e Initialized")

    ################## ANALOG IN METHODS ##################

    # Get analog input buffers
    def update_ai_buffer(self):
        self._card.read_analog(self._ai_channels, len(self._ai_channels),
                               self._ai_buffer)

    # Read battery voltage
    def get_batt_volts(self):
        self.update_ai_buffer()
        return self._ai_buffer[0]

    ################## ENCODER METHODS ####################

    # Get/set encoder values
    def update_enc_buffer(self):
        self._card.read_encoder(self._enc_channels, len(self._enc_channels),
                                self._enc_buffer)

    def push_enc_buffer(self):
        self._card.set_encoder_counts(self._enc_channels,
                                      len(self._enc_channels),
                                      self._enc_buffer)

    # Read raw encoder counts
    def read_encoder_count(self, _channel):
        self.update_enc_buffer()
        return self._enc_buffer[_channel]

    ################## DIGITAL I/O METHODS ################

    # Get/set digital I/O buffers
    def update_di_buffer(self):
        self._card.read_digital(self._di_channels, len(self._di_channels),
                                self._di_buffer)

    def push_do_buffer(self):
        self._card.write_digital(self._do_channels, len(self._do_channels),
                                 self._do_buffer)

    # Set LED outputs
    def set_leds(self, bLED=[0, 0, 0, 0]):
        self._do_buffer[0:4] = array('b', bLED)
        self.push_do_buffer()

    # Read all digital in
    def read_din(self):
        self.update_di_buffer()
        return self._di_buffer

    # Return bump sensor inputs
    def read_bump_sensors(self):
        self.update_di_buffer()
        return self._di_buffer[0:3]

    # Return button inputs
    def read_buttons(self):
        self.update_di_buffer()
        return self._di_buffer[8:11]

    # Read right dock IR; [NR, NC, NL, FR, FC, FL]
    def read_right_dock_ir(self):
        self.update_di_buffer()
        return self._di_buffer[13:19]

    # Read center dock IR; [NR, NC, NL, FR, FC, FL]
    def read_center_dock_ir(self):
        self.update_di_buffer()
        return self._di_buffer[19:25]

    # Read left dock IR; [NR, NC, NL, FR, FC, FL]
    def read_left_dock_ir(self):
        self.update_di_buffer()
        return self._di_buffer[25:31]

    ################## OTHER I/O METHODS ##################

    # Get/set other I/O buffers
    def update_oi_buffer(self):
        self._card.read_other(self._oi_channels, len(self._oi_channels),
                              self._oi_buffer)

    def push_oo_buffer(self):
        self._card.write_other(self._oo_channels, len(self._oo_channels),
                               self._oo_buffer)

    # Read z gyro
    def read_z_gyro(self):
        self.update_oi_buffer()
        z_gyro = self._oi_buffer[3] - self._z_bias
        return z_gyro

    # Measure gyro z-axis bias
    def update_gyro_z_bias(self):
        gyro = 0.0
        for i in range(10000):
            self.update_oi_buffer()
            gyro += self._oi_buffer[3]
        self._gyro_z_bias = gyro / 10000.0
        print("Z-axis gyro bias: {}".format(self._gyro_z_bias))

    # Set motor speed command
    def set_velocity(self, velocity=[0, 0]):
        self._oo_buffer = array('d', velocity)
        self.push_oo_buffer()

    ################## CONTROL METHODS ####################

    # Move a set distance and angle open loop
    def move_time(self, distance=0, angle=0, move_time=1):
        # Ignore command if time <= 0 seconds
        if (move_time > 0):
            avg_linear_velocity = distance / move_time
            avg_angular_velocity = angle / move_time
            linear_velocity_delta = avg_angular_velocity * (
                self._qbot_diameter / 2)
            velocity_command = [
                avg_linear_velocity + linear_velocity_delta,
                avg_linear_velocity - linear_velocity_delta
            ]
            self.set_velocity(velocity_command)
            time.sleep(move_time)
            self.halt()

    # Move a set distance and angle using odometry
    def move_odo(self, distance=0, angle=0, move_time=1):
        # TODO
        time.sleep(move_time)

    # Move a set distance and angle using gyro
    def move_gyro(self, distance=0, angle=0, move_time=1):
        # TODO
        time.sleep(move_time)

    # Stop both motors
    def halt(self):
        self.set_velocity([0, 0])

    ################## DEVICE MANAGEMENT ##################

    # Reset QBot2e
    def reset(self):
        print("Resetting QBot2e...")

        #Clear LEDs
        self.set_leds([0, 0, 0, 0])

        # Stop motors
        self.set_velocity([0, 0])

        # Reset encoders to 0
        self._enc_buffer = array('I', [0, 0])
        self.push_enc_buffer()

        # Sample gyroscope z-axis bias
        if self._gyro_z_bias == None:
            self.update_gyro_z_bias()

    # Close DAQ
    def close(self):
        self.__exit__()

    # Exit routine
    def __exit__(self):
        print("Closing DAQ...")
        self.reset()
        self._card.close()
        print("QBot2e closed")
Beispiel #6
0
class q2usb:

    # Define class-level variables

    # Q2-USB variables
    _card = None
    _ai_channels = None
    _ai_buffer = None
    _ao_channels = None
    _ao_buffer = None
    _enc_channels = None
    _enc_buffer = None

    # Initilize Q2-USB
    def __init__(self):
        # Define DAQ type as Q2-USB
        self._card = HIL()
        self._card.open("q2_usb", "0")

        # Set Q2-USB speed to noraml
        self._card.set_card_specific_options("update_rate=normal;", 50)

        # Configure analog input channels
        self._ai_channels = array('I', [0, 1])
        self._ai_buffer = array('d', [0.0] * len(self._ai_channels))

        # Configure analog output channels
        self._ao_channels = array('I', [0, 1])
        self._ao_buffer = array('d', [0.0] * len(self._ao_channels))

        # Configure encoder input channels
        self._enc_channels = array('I', [0, 1])
        self._enc_buffer = array('i', [0] * len(self._enc_channels))

        # Write 0 V to all AO channels
        self._card.write_analog(self._ao_channels, len(self._ao_channels),
                                self._ao_buffer)

        # Set encoder counts to 0
        _init_enc_counts = array('i', [0, 0])
        self._card.set_encoder_counts(self._enc_channels,
                                      len(self._enc_channels),
                                      _init_enc_counts)

        print("Q2-USB DAQ Initialized")

    ######################### Q2-USB ANALOG IN METHODS #########################

    # Read single analog input channel
    def read_analog_input(self, channel):
        self._card.read_analog(self._ai_channels, len(self._ai_channels),
                               self._ai_buffer)
        return self._ai_buffer[channel]

    ######################### Q2-USB ANALOG OUT METHODS #########################

    # Write value to single analog output channel
    def write_analog_output(self, channel, value):
        self._card.write_analog(array('I', [channel]), 1, array('d', [value]))

    ######################### Q2-USB ENCODER METHODS #########################

    # Read raw encoder counts for single channel
    def read_encoder_count(self, channel):
        self._card.read_encoder(self._enc_channels, len(self._enc_channels),
                                self._enc_buffer)
        return self._enc_buffer[channel]

    ################## DEVICE MANAGEMENT ##################

    # Close Q2-USB
    def close(self):
        self.__exit__()

    # Exit routine
    def __exit__(self):
        print("Closing Q2-USB ...")
        # Write 0 V AO channels 0 and 1
        self.write_analog_output(0, 0)
        self.write_analog_output(1, 0)

        # Close DAQ
        self._card.close()

        print("Q2-USB closed")