Exemplo n.º 1
0
class Dosificadora:
    def __init__(self):
        #Crear el objeto de la clase dosificadora

        ##Convenciones: axxxx: a significa atributo
        #Con-> Concentrado
        #Min-> Mineral
        #Lev-> Levadura

        #Puertos de control para las valvulas
        self.avTolva = 2
        self.avMineral = 16
        self.avLevadura = 27

        #Puertos de asignacion de las celdas de carga
        self.alsensorC1 = (11, 9)  #Formato tupla: (dt,sck)
        self.alsensorC2 = (22, 10)
        self.alsensorC3 = (24, 23)
        self.alsensorC4 = (12, 6)
        self.alsensorML = (19, 13)

        #Puertos control de motores
        self.amCon = (7, 8)  #Formato tupla: (Encendido, velocidad)
        self.amMin = (20, 21)  #Formato tupla: (velocidad, sentido)
        self.amLev = (25, 26)

        #Sensibilidades celdas de carga
        self.asMin = 1030.3320
        self.asLev = 2563.3821
        self.asC1 = 1
        self.asC2 = 1
        self.asC3 = 1
        self.asC4 = 1
        self.asConc = 50.380

        #Valores de Tara para cada celda de carga
        self.asZeroMin = 0
        self.asZeroLev = 0
        self.asZeroA1 = 0
        self.asZeroA2 = 0
        self.asZeroB1 = 0
        self.asZeroB2 = 0

        #Masas objetivo
        self.aConObj = 1
        self.aMinObj = 1
        self.aLevObj = 1

        #Parametros del filtro de media movil
        self.peso_k_1 = [0, 0, 0]  #Formato de lista [Con,Min,Lev]
        self.peso_k_2 = [0, 0, 0]  #Formato lista [Con,Min,Lev]

        #Otros atributos
        self.asText = "________________"  #Separador de Textos
        self.minCon = 39  #Menor ciclo de PWM permitido para el concentrado
        self.maxCon = 99  #Mayor ciclo de PWM permitido para el concentrado
        self.razon = [
            800, 50, 10
        ]  #Mayor tasa de cambio permitida por el filtro tamizador
        #Formato lista [Con,Min,Lev]
        self.aConCrucero = 70  #Velocidad crucero motor Con
        self.aConMin = 60  #Minima velocidad para mover el motor

    def __del__(self):
        #Metodo destructor de objeto
        nombre = self.__class__.__name__
        print nombre, "Destruido"

    def inicializarPuertos(self):
        #Encargado de iniciar el estado de los puertos de RPi.

        print("\n________________\nIniciando puertos\n________________\n")
        #Configurar puertos
        #Valvulas
        GPIO.setup(self.avTolva, GPIO.OUT)
        GPIO.setup(self.avMineral, GPIO.OUT)
        GPIO.setup(self.avLevadura, GPIO.OUT)

        #Motores
        #Concentrado
        GPIO.setup(self.amCon[0], GPIO.OUT)
        GPIO.setup(self.amCon[1], GPIO.OUT)

        #Mineral
        GPIO.setup(self.amMin[0], GPIO.OUT)
        GPIO.setup(self.amLev[0], GPIO.OUT)

        #Levadura
        GPIO.setup(self.amMin[1], GPIO.OUT)
        GPIO.setup(self.amLev[1], GPIO.OUT)

        #Colocar todos los puertos en BAJO "LOW".
        GPIO.output(self.avTolva, 0)
        GPIO.output(self.avMineral, 0)
        GPIO.output(self.avLevadura, 0)

        GPIO.output(self.amCon[0], 0)
        GPIO.output(self.amCon[1], 0)

        GPIO.output(self.amMin[0], 0)
        GPIO.output(self.amMin[1], 0)

        GPIO.output(self.amLev[0], 0)
        GPIO.output(self.amLev[1], 0)

    def inicializarMotores(self):
        #Iniciar el estado de los motores
        #Frecuencia de PWM
        self.amMinPWM = GPIO.PWM(self.amMin[0],
                                 300)  #Formato tupla: (velocidad, sentido)
        self.amLevPWM = GPIO.PWM(self.amLev[0],
                                 300)  #Formato tupla: (velocidad, sentido)
        self.amConPWM = GPIO.PWM(self.amCon[1], 250)

        ##Iniciar PWM en valor 0
        self.amMinPWM.start(0)
        self.amLevPWM.start(0)
        self.amConPWM.start(0)

    def inicializarCeldas(self):
        #Inciar celdas de carga
        print(
            "\n________________\nIniciando celdas de carga\n________________\n"
        )
        #Formato tupla: self.alsensorA	=	(dt,sck)

        #Celda de carga Concentrado C1
        self.ahxC1 = Scale(self.alsensorC1[0], self.alsensorC1[1], 1, 80)
        #Celda de carga Concentrado C2
        self.ahxC2 = Scale(self.alsensorC2[0], self.alsensorC2[1], 1, 80)
        #Celda de carga Concentrado C3
        self.ahxC3 = Scale(self.alsensorC3[0], self.alsensorC3[1], 1, 80)
        #Celda de carga Concentrado C4
        self.ahxC4 = Scale(self.alsensorC4[0], self.alsensorC4[1], 1, 80)
        #Celda de carga Levadura Mineral
        self.ahxML = Scale(self.alsensorML[0], selfalsensorML[1], 1, 80)

        #Inicializa, resetea y tara A

        print(
            "\n________________\nConfigurando Amplificador C1\n________________\n"
        )
        #Resetear amplificador C1
        self.ahxA.reset()
        self.ahxA.set_gain(gain=64)  #Configurar ganancia para el canal A
        self.ahxA.select_channel(channel='A')
        self.ahxA.set_reference_unit(1)  #Resetear calibracion amplificador C1

        self.ahxA.select_channel(channel='B')

        self.ahxA.set_offset(0)

        self.ahxA.select_channel(channel='A')
        print('\tConfigurado\n')

        # -------------------------------------------------------------#
        ##Configurar amplificador C2
        #Inicializa, resetea y tara amplificador C2
        print(
            "\n________________\nConfigurando Amplificador C2\n________________\n"
        )
        print("\tReseteando...")
        self.ahxA.reset()  #Resetear amplificador C2
        self.ahxB.set_gain(gain=64)  #Configurar ganancia para el canal A
        self.ahxB.select_channel(channel='A')
        self.ahxB.set_reference_unit(1)  #Resetear calibracion amplificador C2
        self.asZeroB1 = self.ahxA.tare(1)  #Tarar celda de carga

        self.ahxB.select_channel(channel='B')
        self.asZeroB2 = self.ahxA.tare(1)
        self.ahxB.set_offset(0)

        self.ahxB.select_channel(channel='A')
        print('\tConfigurado\n')

        ##Configurar amplificador Min Lev
        #Inicializa, resetea y tara Min Lev
        print(
            "\n________________\nConfigurando Amplificador Min Lev\n________________\n"
        )
        print("\tReseteando...")
        self.ahxML.reset()  #Resetear amplificador
        print('\tConfigurado')

        self.ahxML.set_gain(gain=64)  #Configurar ganancia para el canal A
        self.ahxML.select_channel(channel='A')
        self.ahxML.set_reference_unit(1)  #Calibrar celda A
        self.asZeroMin = self.ahxML.tare(1)  #Tarar celda de carga

        self.ahxML.select_channel(channel='B')
        self.asZeroLev = self.ahxML.tare(1)
        self.ahxML.set_offset(0)

        self.ahxML.select_channel(channel='A')

    def encenderMotores(self, motor):
        #Metodo que activa los motores
        #Entrada: 	self-> 	Objeto propio de python
        #			motor->	Selector del motor:
        #					Con: Concentrado, Min: mineral Lev: levadura

        if (motor == 'Con'):
            if self.aConObj != 0:
                #Encendido motor Con
                velocidad = self.aConCrucero
                self.amConPWM.ChangeDutyCycle(velocidad)
                GPIO.output(self.amCon[0], 1)
            else:
                print "Masa es 0, concentrado no encendido"
            return

        if (motor == 'Min'):
            if self.aMinObj != 0:
                self.amMinPWM.ChangeFrequency(750)
                self.amMinPWM.ChangeDutyCycle(50)
            else:
                print "Masa igual a 0, mineral no encendido"
            return

        if (motor == 'Lev'):
            if self.aLevObj != 0:
                self.amLevPWM.ChangeFrequency(750)
                self.amLevPWM.ChangeDutyCycle(50)
            else:
                print "Masa igual a 0, levadura no encendido"
            return

        else:
            print("Motor no encontrado")

    def desacelerarMotores(self, motor):
        #Metodo que desacelera los motores
        if (motor == 'Con'):
            velocidad = self.aConMin
            self.amConPWM.ChangeDutyCycle(velocidad)
            return

        if (motor == 'Min'):
            self.amMinPWM.ChangeFrequency(200)
            self.amMinPWM.ChangeDutyCycle(50)
            return

        if (motor == 'Lev'):
            self.amLevPWM.ChangeFrequency(200)
            self.amLevPWM.ChangeDutyCycle(50)
            return

        else:
            print "Motor no encontrado"
            return

    def apagarMotores(self, motor, condicion):
        #Detener motores
        #Entradas: motor: 	Seleccion del motor deseado
        #					Con -> Concentrado
        #					Min -> Mineral
        #					Lev -> Levadura
        #		Condicion:	Indica si el motor no fue apagado en la iteracion anterior
        if (motor == 'Con'):
            GPIO.output(self.amCon[0], 0)
            self.amConPWM.stop()
            if condicion:
                print("Concentrado apagado")
            return

        if (motor == 'Min'):
            self.amMinPWM.ChangeFrequency(50)
            self.amMinPWM.ChangeDutyCycle(0)
            if condicion:
                print("Mineral apagado")
            return

        if (motor == 'Lev'):
            self.amLevPWM.ChangeFrequency(50)
            self.amLevPWM.ChangeDutyCycle(0)
            if condicion:
                print("Levadura apagado")
            return

        else:
            print("Motor no encontrado")
            return

    def abrirCerrarValvulas(self, valvula, condicion):
        #Metodo de abrir y cerrar valvulas
        #Entradas:	valvula:
        #				Tolv -> Puerta de la tolva Romana
        #				Min	->	Compuerta del mineral
        #				Lev ->	Compuerta levadura
        #			condicion:
        #				0 	->	Valvula cerrada
        #				1	->	Valvula abierta

        if (valvula == 'Tolv'):
            GPIO.output(self.avTolva, condicion)
            return

        if (valvula == 'Min'):
            GPIO.output(self.avMineral, condicion)
            return

        if (valvula == 'Lev'):
            GPIO.output(self.avLevadura, condicion)
            return

        else:
            print("Valvula incorrecta")

    def cambiarSensibilidad(self, celda, sensibilidad):
        #Metodo para cambiar la sensibilidad de la celda de carga: (depuracion)
        #Formato de celda: 'Min','Lev','A','B'
        #Entradas: celda: A1, A2, B1, B2, Min, Lev
        print("Cambiando sensibilidad")
        if (celda == 'A1'):
            self.asA1 = sensibilidad
            self.axA.select_channel(channel='A')
            self.axA.set_scale_ratio(sensibilidad)
            return

        if (celda == 'A2'):
            self.asA2 = sensibilidad
            self.axA.select_channel(channel='B')
            self.axA.set_scale_ratio(sensibilidad)
            return

        if (celda == 'B1'):
            self.asB1 = sensibilidad
            self.axB.select_channel(channel='A')
            self.axB.set_scale_ratio(sensibilidad)
            return

        if (celda == 'B2'):
            self.asB2 = sensibilidad
            self.axB.select_channel(channel='B')
            self.axB.set_scale_ratio(sensibilidad)
            return

        if (celda == 'Min'):
            self.asMin = sensibilidad
            self.axML.select_channel(channel='A')
            self.axML.set_scale_ratio(sensibilidad)
            return

        if (celda == 'Lev'):
            self.asLev = sensibilidad
            self.axML.select_channel(channel='A')
            self.axML.set_scale_ratio(sensibilidad)
            return

        else:
            print("Celda no encontrada")

    def leerMineral(self, lecturas):
        #Leer el peso del mineral en gramos.
        #Entrada: lecturas -> Cantidad de veces que el sensor se lee antes de retornar

        #Mineral puerto A del sensor
        self.ahxML.select_channel(channel='A')
        masaMin = -(
            (self.ahxML.get_value(lecturas)) - self.asZeroMin) / self.asMin
        return masaMin

    def leerLevadura(self, lecturas):
        #Leer el peso del mineral en gramos.
        #Entrada: lecturas -> Cantidad de veces que el sensor se lee antes de retornar
        self.ahxML.select_channel(channel='B')
        masaLev = (self.ahxML.get_value(lecturas) -
                   self.asZeroLev) / self.asLev
        return masaLev

    def leerConcentrado(self, lecturas):
        #Leer el peso del concentrado en gramos.
        #Entrada: lecturas -> Cantidad de veces que el sensor se lee antes de retornar
        self.ahxA.select_channel(channel='A')
        Conc1 = (self.ahxA.get_value(lecturas) - self.asZeroA1)

        self.ahxA.select_channel(channel='B')
        Conc2 = (self.ahxA.get_value(lecturas) - self.asZeroA2)

        self.ahxB.select_channel(channel='A')
        Conc3 = (self.ahxB.get_value(lecturas) - self.asZeroB1)

        self.ahxB.select_channel(channel='B')
        Conc4 = (self.ahxB.get_value(lecturas) - self.asZeroB1)

        Conc = (Conc1 + Conc2 + Conc3 + Conc4) / 2 * self.asConc
        #Nota: De momento se estan leyendo solo las celdas de los puertos A del concentrado
        #		las celdas B presetan problemas de retardos en las lecturas
        return Conc

    def cerrarSteppers(self):
        #Metodo para apagar puertos de velocidad de los motores
        self.amMinPWM.stop()
        self.amLevPWM.stop()
        self.amConPWM.stop()

    def leer4Concentrado(self):
        #Metodo para leer por separado cada celda de carga del concentrado 	(depuracion)
        self.ahxA.select_channel(channel='A')
        Conc1 = (self.ahxA.get_value(1) - self.asZeroA1)

        self.ahxA.select_channel(channel='B')
        Conc2 = (self.ahxA.get_value(1) - self.asZeroA2)

        self.ahxB.select_channel(channel='A')
        Conc3 = (self.ahxB.get_value(1) - self.asZeroB1)

        self.ahxB.select_channel(channel='B')
        Conc4 = (self.ahxB.get_value(1) - self.asZeroB1)

        print("%d\t%d\t%d\t%d" % (Conc1, Conc2, Conc3, Conc4))

    def leer4ConcentradoRaw(self, lecturas):
        #Metodo para leer cada celda del concentrado sin restar tara 		(depuracion)
        self.ahxA.select_channel(channel='A')
        Conc1 = (self.ahxA.get_value(lecturas))

        self.ahxA.select_channel(channel='B')
        Conc2 = (self.ahxA.get_value(lecturas))

        self.ahxB.select_channel(channel='A')
        Conc3 = (self.ahxB.get_value(lecturas))

        self.ahxB.select_channel(channel='B')
        Conc4 = (self.ahxB.get_value(lecturas))

        print("%d\t%d\t%d\t%d" % (Conc1, Conc2, Conc3, Conc4))
        return

    def tararConcentrado(self, lecturas=30):
        #Metodo para tarar los amplificadores del concentrado
        self.ahxA.select_channel(channel='A')
        self.asZeroA1 = self.ahxA.get_value(lecturas)

        self.ahxA.select_channel(channel='B')
        self.asZeroA2 = self.ahxA.get_value(lecturas)

        self.ahxB.select_channel(channel='A')
        self.asZeroB1 = self.ahxB.get_value(lecturas)

        self.ahxB.select_channel(channel='B')
        self.asZeroB2 = self.ahxB.get_value(lecturas)

    def tararMineral(self, lecturas=30):
        #print self.ahxML.GAIN
        #Metodo para tarar mineral
        self.ahxML.select_channel(channel='A')
        self.asZeroMin = self.ahxML.get_value(lecturas)
        print("\tTara del mineral %d" % (self.asZeroMin))

    def tararLevadura(self, lecturas=30):
        #Metodo para tarar levdura
        self.ahxML.select_channel(channel='B')
        self.asZeroMin = self.ahxML.get_value(lecturas)
        print("\tTara de la levadura %d" % (self.asZeroMin))

    def filtradorTamizador(self, dato, alimento):
        #Metodo para filtrar y tamizar los valores de las celdas de carga
        #Se aplica un filtro de media movil con tres periodos,
        #luego se eliminan las lecturas que presenten cambios abruptos respecto de los valores predecesores.

        if alimento == 'Con':
            #Tamizar
            if ((abs(dato - self.peso_k_1[0])) > self.razon[0]):
                dato = self.peso_k_1[0]
                print "Tamizado"
            #Filtrar
            concentrado = (dato + self.peso_k_1[0] + self.peso_k_2[0]) / 3
            self.peso_k_2[0] = self.peso_k_1[0]
            self.peso_k_1[0] = concentrado
            return concentrado

        if alimento == 'Min':
            #Tamizar
            if ((abs(dato - self.peso_k_1[1])) > self.razon[1]):
                dato = self.peso_k_1[1]
                print "Tamizado"
            #Filtrar
            mineral = (dato + self.peso_k_1[1] + self.peso_k_2[1]) / 3
            self.peso_k_2[1] = self.peso_k_1[1]
            self.peso_k_1[1] = mineral
            return mineral

        if alimento == 'Lev':
            #Tamizar
            if ((abs(dato - self.peso_k_1[2])) > self.razon[2]):
                dato = self.peso_k_1[2]
                print "Tamizado"
            #Filtrar
            levadura = (dato + self.peso_k_1[2] + self.peso_k_2[2]) / 3
            self.peso_k_2[2] = self.peso_k_1[2]
            self.peso_k_1[2] = levadura
            return levadura

        else:
            print("Alimento no encontrado")

    def inRangeCoerce(self, dato, minimo=0.0, maximo=100.0):
        #Metodo que limita los valores de una variable
        if dato > maximo:
            return maximo

        if dato < minimo:
            return minimo

        else:
            return dato

    def normalizarVelocidadConcentrado(self, dato):
        #Metodo para normalizar los valores del concentrado
        #Debido a la electronica, el valor de PWM permitido es entre 39 y 99.
        #Fuera de esos valores comienza a presentarse comportamiento erratico.
        dato = self.inRangeCoerce(dato, 0, 100)
        dato = (self.maxCon - self.minCon) / 100 * dato + self.minCon
        return dato

    #Metodos para resumir bloques de la secuencia
    def tararCeldas(self):
        #Metodo para tarar todas las cedas de carga. Permite no hacerlo desde el main
        self.leerMineral(30)
        print("________________\nTarando Concentrado\n________________\n")
        self.tararConcentrado(30)
        print("Zero A1 ", self.asZeroA1)
        print("Zero A2 ", self.asZeroA2)
        print("Zero B1 ", self.asZeroB1)
        print("Zero B2 ", self.asZeroB2)

        print("________________\nTarando Mineral\n________________\n")
        self.tararMineral(30)
        print("________________\nTarando Levadura\n________________\n")
        self.tararLevadura(30)
        self.tararMineral(30)

    def resetearCeldas(self):
        print("Reseteando celdas de carga concentrado")
        #Celdas del concentrado
        self.hxC1.turnOff()
        time.sleep(0.5)
        self.hxC1.turnOn()
        time.sleep(0.5)

        self.hxC1.turnOff()
        time.sleep(0.5)
        self.hxC1.turnOn()
        time.sleep(0.5)

        self.hxC2.turnOff()
        time.sleep(0.5)
        self.hxC2.turnOn()
        time.sleep(0.5)

        self.hxC3.turnOff()
        time.sleep(0.5)
        self.hxC3.turnOn()
        time.sleep(0.5)

        self.hxC4.turnOff()
        time.sleep(0.5)
        self.hxC4.turnOn()
        time.sleep(0.5)

        print("Reseteando celdas de carga Mineral y Levadura")
        self.hxML.turnOff()
        time.sleep(0.5)
        self.hxML.turnOn()
        time.sleep(0.5)
Exemplo n.º 2
0
class Trial():
    """
    A class specifying a Trial and methods related to a trial. when a trial is created, it only needs to be drawn and checked for input.
    """
    def __init__(self,
                 win,
                 colours,
                 sequence,
                 mouse,
                 output_stream,
                 clock,
                 location_sequence,
                 manager,
                 override_text=None):
        """
        Initializes a Trial object.
        Params:
            win: A window object the form should be drawn onto
            colours: A tuple of colour strings. (names, hex, or rgb)
            sequence: A sequence string containing only 0's and 1's
            mouse: A mouse object for checking against mouse input
            output_stream: A dictionary object containing lists for writing data into
            clock: A clock object to get the current time
        """
        self.manager = manager
        self.clock = clock
        self.win = win
        self.mouse = mouse
        self.output = output_stream
        self.colours = colours
        self.sequence = sequence
        self.location_sequence = location_sequence
        self.place_boxes()
        info_text = Constants.TRIAL_BASE_INFO
        if override_text is not None:
            info_text = override_text
        else:
            if self.manager.failed_last == True:
                info_text += Constants.FAILED_TRIAL
            else:
                info_text += Constants.COMPLETED_TRIAL
        if len(sequence) != Constants.MATRIX[0] * Constants.MATRIX[1]:
            info_text += Constants.TIMED_TRIAL_INFO
            banner = Constants.BANNER_TIMED
        else:
            info_text += Constants.NOT_TIMED_INFO
            banner = Constants.BANNER_NOT_TIMED
        self.manager.scene = InfoScene(self.win, self, self.mouse, info_text)
        self.create_stimuli(banner)

    def to_trial(self):
        self.manager.scene = self

    def place_boxes(self):
        """
        Places a centered grid of box stimuli and returns a list of the created grid.
        Params:
            None
        Returns:
            A python list containing all the boxes that was created for the grid

        """
        boxes = []
        y_offset = (
            Constants.WINDOW_SIZE[1] / 2
        ) - 2 * Constants.SQUARE_SIZE  # The starting offset of the first square. (Upper-left)
        y_spacing = abs(
            y_offset * 2 / (Constants.MATRIX[1] - 1)
        )  #Has the value for the spacing between the squares. The formula calculates even distribution on all monitors

        #Places the squares in two-dimensional array structure
        for _ in range(Constants.MATRIX[1]):
            x_offset = (-Constants.WINDOW_SIZE[0] /
                        2) + 2 * Constants.SQUARE_SIZE
            x_spacing = abs(x_offset * 2 / (Constants.MATRIX[0] - 1))
            for _ in range(Constants.MATRIX[0]):
                box = visual.Rect(
                    self.win,
                    width=Constants.SQUARE_SIZE,
                    height=Constants.SQUARE_SIZE,
                    pos=[
                        x_offset + Constants.CENTER_OFFSET[0],
                        y_offset + Constants.CENTER_OFFSET[1]
                    ],  # Sets the position to the offset values in addition to adding a global offset to each box to control grid location
                    fillColor="#BEBEBE")
                boxes.append(box)
                x_offset += x_spacing
            y_offset -= y_spacing
        self.grid = boxes

    """
    Creates the confidence scales
    """

    def create_stimuli(self, banner):
        """
        Creates all stimuli that is to be drawn by the Trial class and stores them as attributes and into lists for easy drawing.
        Params:
            None
        Returns:
            None
        """
        banner_text = visual.TextStim(self.win,
                                      text=banner,
                                      pos=[0, 500],
                                      height=40,
                                      wrapWidth=Constants.WINDOW_SIZE[0])
        next_box_text = visual.TextStim(self.win,
                                        text="Show next box",
                                        pos=[0, -300])
        choice_text0 = visual.TextStim(
            self.win,
            text='Press the circle if you believe it is the dominant colour:',
            pos=[-600, -300])
        choice_text1 = visual.TextStim(
            self.win,
            text='Press the circle if you believe it is the dominant colour:',
            pos=[600, -300])
        self.button0 = visual.Circle(self.win,
                                     radius=50,
                                     pos=[-600, -400],
                                     fillColor=self.colours[0])
        self.button1 = visual.Circle(self.win,
                                     radius=50,
                                     pos=[600, -400],
                                     fillColor=self.colours[1])
        self.continue_box = visual.Rect(self.win,
                                        pos=[0, -300],
                                        width=Constants.SQUARE_SIZE,
                                        height=Constants.SQUARE_SIZE / 2,
                                        fillColor="black")
        rating_text0 = visual.TextStim(self.win,
                                       text=f"More \n{self.colours[2]}",
                                       pos=[-800, -400],
                                       color=self.colours[0])
        rating_text1 = visual.TextStim(self.win,
                                       text=f"More \n{self.colours[3]}",
                                       pos=[800, -400],
                                       color=self.colours[1])
        self.rating_scale = Scale(self.win, self.colours)
        self.rating_stims = [rating_text0, rating_text1, banner_text
                             ] + self.grid
        self.drawables = [self.continue_box, next_box_text, banner_text
                          ] + self.grid
        self.choice_stims = [
            self.button0, self.button1, choice_text0, choice_text1
        ]
        self.boxes_revealed = 0

    def check_input(self):
        """
        Checks input for all components of the trial on screen except for the rating scale. It also writes to the output if a trial is failed.
        Params:
            None    
        Returns:
            bool: indicating wether the Trial has ended. A true value indicates the trial has ended
        """
        if (self.mouse.isPressedIn(self.button0, buttons=[0])
                and self.button0 in self.drawables):
            [
                self.output["Decision"].append(-1)
                for _ in range(len(self.output["Box_Num"]) - 1)
            ]
            self.output["Decision"].append(self.colours[2])
            self.manager.completed_trial(False)
            return
        elif (self.mouse.isPressedIn(self.button1, buttons=[0])
              and self.button0 in self.drawables):
            [
                self.output["Decision"].append(-1)
                for _ in range(len(self.output["Box_Num"]) - 1)
            ]
            self.output["Decision"].append(self.colours[3])
            self.manager.completed_trial(False)
            return
        elif (len(self.sequence) == 0
              and self.mouse.isPressedIn(self.continue_box, buttons=[0])):
            self.output["Box_Num"].append(self.boxes_revealed + 1)
            self.output["Reaction_time"].append(-1)
            self.output["Probability_Estimates"].append(-1)
            [
                self.output["Decision"].append(-1)
                for _ in self.output["Box_Num"]
            ]
            self.manager.completed_trial(True)
            return
        if 'escape' in event.getKeys():
            core.quit()
        if self.mouse.isPressedIn(self.continue_box, buttons=[0]):
            self.next_box()
            box_seen = self.clock.getTime()
            self.get_rating()
            rating_given = self.clock.getTime()
            self.output["Reaction_time"].append(rating_given - box_seen)

    def next_box(self):
        """
        Opens the next box. Reads the sequence data and gives the appropriate box its colour and writes data to the output.
        Params:
            None
        Returns:
            None
        """
        if (self.boxes_revealed == 0):
            self.drawables += self.choice_stims
        location = self.location_sequence[0]
        box = self.grid[location - 1]
        if (self.sequence[0] == '0'):
            box.fillColor = self.colours[0]
        elif (self.sequence[0] == '1'):
            box.fillColor = self.colours[1]
        else:
            raise SyntaxError(
                "The given input does not match program specification for a sequence. Allowed values: 0 and 1"
            )
        self.boxes_revealed += 1
        self.output["Box_Num"].append(self.boxes_revealed)
        self.sequence = self.sequence[1:]
        self.location_sequence = self.location_sequence[1:]

    def get_rating(self):
        """
        Draws the rating scale and waits for input. Once the input is given, it is written to the output and the method returns.
        Params:
            None
        Returns:
            None
        """
        event.clearEvents()
        while (self.rating_scale.noResponse() == True):
            if 'escape' in event.getKeys():
                core.quit()
            self.rating_scale.draw()
            [x.draw() for x in self.rating_stims]
            self.win.flip()
        self.output["Probability_Estimates"].append(
            self.rating_scale.getRating())
        self.rating_scale.reset()
        event.clearEvents(
        )  #Event queue is cleared to prevent keypresses from rating period to be carried forward

    def save(self):
        return self.output

    def draw(self):
        """
        Draws the Trial to a window.
        Params:
            None
        Returns:
            None
        """
        for drawable in self.drawables:
            drawable.draw()