def test_i2c_alltargets(self): """ Queries each cartridge and cartridge holder for each EEPROM spot, expecting a response Conditions: Pass: Each target gives an accurate EEPROM response Fail: Any timeouts or dropped packets from any target """ t = ResponseData() logging.info( "Querying first 30 EEPROM locations for each cartridge and the cartridge holder") for i in range(0, 30): string = 'E'+str(i) response = self.commandparser('M244', 'C0', string) if response.failed: return response response = self.commandparser('M244', 'C1', string) if response.failed: return response response = self.commandparser('M244', 'C2', string) if response.failed: return response t.success("All EEPROM locations successfully queried\n") return t
def test_Diagnostics_trial_house(self): t = ResponseData() # Test Failure Criteria pressure_house_start = 30 # Beginning of house air pressure test pressure_house_end = 80 # Highest pressure reached while testing house air pressure_interval = 5 # Interval in which the pressure increases between bounds global current_ramp_cycle with cd(path): g = self.g task = AnalogInputTask() self.close_house_air() for i in range(0, self.pressure_ramp_cycles): # Ensure solenoid is closed at start # Ensure Solenoid is closed self.close_solenoid() # Set tank pressure to 40psi self.pneumatics.setPumpPressure(40) logging.info("Testing Output Pressure (Source: House Air)") self.open_house_air() for i in range(0, self.pressure_ramp_cycles): # Ensure solenoid is closed at start # Ensure Solenoid is closed self.close_solenoid() # Set tank pressure to 40psi self.pneumatics.setPumpPressure(40) current_ramp_cycle = i # Interval added / subtracted to help make range function more # intuitive for p in range(pressure_house_start, pressure_house_end + pressure_interval, pressure_interval): logging.debug(p) self.record_solenoid_pressure(p) if self.daq.u.failed: self.close_house_air() self.pneumatics.setRegulatorPressure(0) self.pneumatics.setPumpPressure(0) for p in range(pressure_house_end, pressure_house_start - pressure_interval, -pressure_interval): logging.debug(p) self.record_solenoid_pressure(p) if self.daq.u.failed: self.close_house_air() self.pneumatics.setRegulatorPressure(0) self.pneumatics.setPumpPressure(0) self.close_house_air() self.daq.display_test_results() t.success("Pressure test run successfully") return t
def __init__(self, test): """Initializes the DAQ with a task, and a logger""" self.task1 = test.task self.data = {} self.log = Logger(test) self.g = test.g self.wait_time_s = test.wait_time_s self.sample_rate = test.sample_rate self.checkpoint = test.checkpoint self.u = ResponseData() self.test = test
def commandparser(self, command, p1='', p2='', p3=''): """ Checks for errors on sent commands, returns response. Args: command (string): The M or G code being sent p1 (string): first argument for the M Code p2 (string): second argument for the M Code p3 (string): third argument for the M Code Returns: int: The response sent from the printer. Returns 0 if the packet was dropped or if the request timed out. """ u = ResponseData() resp = self.g.write(command + ' ' + p1 + ' ' + p2 + ' ' + p3, resp_needed=True) logging.debug( str(command + ' ' + p1 + ' ' + p2 + ' ' + p3 + ' Response: ' + resp)) PacketSplit = re.findall('Packet', resp) TimeoutSplit = re.findall('Timeout', resp) if len(PacketSplit): u.fail("Dropped " + str(len(PacketSplit)) + " Packets from address " + str(p1) + ". " + str(p1) + " is either not present or not communicating.") if len(TimeoutSplit): u.fail(str(len(TimeoutSplit)) + " Timeouts from " + str(p1)) u.success(resp) return u
def commandparser(self, command, p1='', p2='', p3=''): """ Checks for errors on sent commands, returns response. Args: command (string): The M or G code being sent p1 (string): first argument for the M Code p2 (string): second argument for the M Code p3 (string): third argument for the M Code Returns: int: The response sent from the printer. Returns 0 if the packet was dropped or if the request timed out. """ u = ResponseData() resp = self.g.write( command + ' ' + p1 + ' ' + p2 + ' ' + p3, resp_needed=True) logging.debug( str(command + ' ' + p1 + ' ' + p2 + ' ' + p3 + ' Response: ' + resp)) PacketSplit = re.findall('Packet', resp) TimeoutSplit = re.findall('Timeout', resp) if len(PacketSplit): u.fail("Dropped " + str(len(PacketSplit)) + " Packets from address " + str( p1) + ". " + str(p1) + " is either not present or not communicating.") if len(TimeoutSplit): u.fail(str(len(TimeoutSplit)) + " Timeouts from " + str(p1)) u.success(resp) return u
def test_cart1_info(self): """ Retrieves cartridge information from Cartridge 1 Conditions: Pass: Gives a response to M245 Fail: Any timeouts or dropped packets """ t = ResponseData() logging.info("Retrieving Cartridge 1 information\n") cart1status = self.commandparser('M245', 'C1') if cart1status.failed: return cart1status parsedStatus = self.parseCartridgeStatus(cart1status.data, "Cartridge 1") if parsedStatus.failed: return parsedStatus t.success("Cartridge 1 info retrieved successfully\n") return t
def test_set_pressure(self): """ Sets tank pressure, then tests the E-Reg at various pressures and reads it back. Conditions: Pass: Reachs the enumerated pressures in a reasonable amount of time and accuracy, after achieving the correct tank pressure Fail: After the set period of time, is not at the correct pressure for any of the above. """ PASSING_CRITERIA = .5 t = ResponseData() logging.info("Setting Pressure, checking accuracy\n") self.setPumpPressure(40) for i in range(10): pumpPressure = self.readPumpPressure() logging.debug("Pump Pressure: {} PSI".format(pumpPressure)) if pumpPressure > 35: break sleep(1) if i is 9: t.fail("Tank Pressure too low") return t for i in range(0, 30, 5): if pumpPressure > i: self.setRegulatorPressure(i) sleep(1) regulatorPressure = self.readRegulatorPressure() logging.debug("Reg pressure: {} PSI".format(regulatorPressure)) if i - regulatorPressure > PASSING_CRITERIA: t.fail("Pressure too low at {} PSI ({})".format( i, regulatorPressure)) return t elif i - regulatorPressure < -PASSING_CRITERIA: t.fail("Pressure too high at {} PSI ({})".format( i, regulatorPressure)) return t self.setRegulatorPressure(0) else: t.success("Pressure is appropriate") return t
def __init__(self, test): """Initializes the DAQ with a task, and a logger""" self.task1 = test.task self.data = {} self.log = Logger(test) self.g = test.g self.wait_time_s = test.wait_time_s self.sample_rate = test.sample_rate self.checkpoint = test.checkpoint self.u = ResponseData() self.test = test
def test_set_pressure(self): """ Sets tank pressure, then tests the E-Reg at various pressures and reads it back. Conditions: Pass: Reachs the enumerated pressures in a reasonable amount of time and accuracy, after achieving the correct tank pressure Fail: After the set period of time, is not at the correct pressure for any of the above. """ PASSING_CRITERIA = .5 t = ResponseData() logging.info( "Setting Pressure, checking accuracy\n") self.setPumpPressure(40) for i in range(10): pumpPressure = self.readPumpPressure() logging.debug("Pump Pressure: {} PSI".format(pumpPressure)) if pumpPressure > 35: break sleep(1) if i is 9: t.fail("Tank Pressure too low") return t for i in range(0, 30, 5): if pumpPressure > i: self.setRegulatorPressure(i) sleep(1) regulatorPressure = self.readRegulatorPressure() logging.debug("Reg pressure: {} PSI".format(regulatorPressure)) if i - regulatorPressure > PASSING_CRITERIA: t.fail( "Pressure too low at {} PSI ({})".format(i, regulatorPressure)) return t elif i - regulatorPressure < -PASSING_CRITERIA: t.fail( "Pressure too high at {} PSI ({})".format(i, regulatorPressure)) return t self.setRegulatorPressure(0) else: t.success("Pressure is appropriate") return t
def disableAndReadSolenoid(self, solenoid): """ Activates the solenoid and reads the status Deactivates the given solenoid using M381, and reads back the status. Args: solenoid (int): Desired Solenoid Returns: int: Solenoid Status """ u = ResponseData() solenoidStatus = self.g.write('M381', resp_needed=True).split() solenoidI2CStatus = self.commandparser('M253', 'C1').split() if solenoidI2CStatus.failed: u.fail(solenoidI2CStatus) return u else: logging.debug(repr(solenoidI2CStatus[3])) u.success(int(solenoidI2CStatus[3])) return u
def readLaser(self): """ Return the laser reading Queries the laser value, which is sent to Marlin by I2C. Args: None Returns: The value of the laser """ u = ResponseData() logging.info("Reading Laser") M234Response = self.g.write("M234", resp_needed=True).split() logging.debug(M234Response) if int(M234Response[1]) > self.laserMax: u.fail("Too far") return u else: u.data = int(M234Response[1]) return u
def parseCartridgeStatus(self, cartridgeStatus, cartridgeNumber): """ Checks the cartridge status Parses and dispalys the cartridge status, and then checks to see if the flash and eeprom have been loaded correctly, based on the firmware version and the cartridge type. Args: cartridgeStatus (string): The string to be parsed cartridgeNumber (string): Which cartridge it is ("Cartridge 0", "Cartridge 1", or "Cartridge Holder") Returns: None """ u = ResponseData() infoList = re.split('\W+', cartridgeStatus) try: if (len(infoList) >= 18): logging.info("%s Info", cartridgeNumber) logging.debug(infoList) logging.debug("-------------------------------------") logging.debug("Cartridge Serial Number: %s", infoList[2]) logging.debug("Cartridge Firmware Version: %s", infoList[18]) logging.debug("Cartridge Programmer Station: %s", infoList[5]) logging.debug("Cartridge Type: %s", infoList[8]) logging.debug("Cartridge Size: %s", infoList[11]) logging.debug("Cartridge Material: %s", infoList[14]) if (int(infoList[18]) == 255): u.fail( "{} FLASH not loaded properly, or cartridge is out of date\n".format(cartridgeNumber)) return u if (int(infoList[8]) == 15) and (cartridgeNumber != "Cartridge Holder"): u.fail( "{} EEPROM not loaded properly\n".format(cartridgeNumber)) u.data = "Success" return u except: u.fail("{} Status Parse Failed. Received Message: {}".format(cartridgeNumber, cartridgeStatus)) return u
def disableAndReadSyringe(self): """ Activates the syringe and reads the status Deactivates the given syringe using M381, and reads back the status. Args: syringe (int): Desired Syringe Returns: int: Syringe Status """ u = ResponseData() self.g.write('M42 P75 S0') sleep(2) syringeStatus = self.commandparser("M251").split() if syringeStatus.failed: u.fail(syringeStatus) return u else: logging.debug(syringeStatus) u.success(int(syringeStatus[3])) return u
def test_solenoid(self): """ Opens and closes the solenoid, checking the status over I2C for both states. Conditions: Pass: I2C command reads correct solenoid condition Fail: I2C command incorrectly reads solenoid condition """ t = ResponseData() logging.debug("Activating Solenoid") if self.activateAndReadSolenoid(1) is not 1: t.fail("Solenoid not activated") return t sleep(.25) logging.debug("Deactivating Solenoid") if self.disableAndReadSolenoid(1) is not 0: t.fail("Solenoid not activated") return t t.success("Solenoid operating correctly") return t
def test_solenoid(self): """ Opens and closes the solenoid, checking the status over I2C for both states. Conditions: Pass: I2C command reads correct solenoid condition Fail: I2C command incorrectly reads solenoid condition """ t = ResponseData() logging.debug("Activating Solenoid") if self.activateAndReadSolenoid(1) is not 1: t.fail("Solenoid not activated") return t sleep(.25) logging.debug("Deactivating Solenoid") if self.disableAndReadSolenoid(1) is not 0: t.fail("Solenoid not activated") return t t.success("Solenoid operating correctly") return t
def disableAndReadSolenoid(self, solenoid): """ Activates the solenoid and reads the status Deactivates the given solenoid using M381, and reads back the status. Args: solenoid (int): Desired Solenoid Returns: int: Solenoid Status """ u = ResponseData() solenoidStatus = self.g.write('M381', resp_needed=True).split() solenoidI2CStatus = self.commandparser('M253', 'C1').split() if solenoidI2CStatus.failed: u.fail(solenoidI2CStatus) return u else: logging.debug(repr(solenoidI2CStatus[3])) u.success(int(solenoidI2CStatus[3])) return u
def disableAndReadSyringe(self): """ Activates the syringe and reads the status Deactivates the given syringe using M381, and reads back the status. Args: syringe (int): Desired Syringe Returns: int: Syringe Status """ u = ResponseData() self.g.write('M42 P75 S0') sleep(2) syringeStatus = self.commandparser("M251").split() if syringeStatus.failed: u.fail(syringeStatus) return u else: logging.debug(syringeStatus) u.success(int(syringeStatus[3])) return u
def test_for_leaks(self, speed='slow'): """ Tests tank pressure for stability Sets the tank pressure, and makes sure it reaches an acceptably close level within a set period of time. Then checks for a set period of time to make sure it mantains a close level to this value. Conditions: Pass: Reachs the set tank pressure in a reasonable amount of time with a set accuracy, then makes sure it mantains that pressure. Fail: After the set period of time, the tank never reaches the appropriate pressure. Fail: After the tank reaches pressure, is unable to hold it for a set length of time. """ setPressure = 40 getToPressureTime_s = 60 pressureMeasurementTime_slow_s = 540 pressureMeasurementTime_fast_s = 20 measurement_delay_time_slow_s = 60 measurement_delay_time_fast_s = 10 t = ResponseData() passingPressureRange_psi = 1 allowed_leak_amount_psi = .1 logging.info("Testing for leaking Pressure Tank\n") self.setPumpPressure(setPressure) for i in range(getToPressureTime_s): pumpPressure = self.readPumpPressure() logging.debug("Pump Pressure: {} PSI".format(pumpPressure)) if pumpPressure > setPressure - passingPressureRange_psi: break sleep(1) if i is getToPressureTime_s - 1: t.fail("Tank Pressure did not reach acceptable pressure range") return t self.setPumpPressure(0) if speed is not 'fast': logging.info( "Waiting for {} seconds to allow time to stabilize".format( measurement_delay_time_slow_s)) sleep(measurement_delay_time_slow_s) logging.info( "Starting to analyse pressure. This will take {} Seconds ({} Minutes)" .format(pressureMeasurementTime_slow_s, pressureMeasurementTime_slow_s / 60.0)) else: logging.info( "Waiting for {} seconds to allow time to stabilize".format( measurement_delay_time_fast_s)) sleep(measurement_delay_time_fast_s) logging.info( "Starting to analyse pressure. This will take {} Seconds ({} Minutes)" .format(pressureMeasurementTime_fast_s, pressureMeasurementTime_fast_s / 60.0)) startingPumpPressure = self.readPumpPressure() if speed is not 'fast': for i in range(pressureMeasurementTime_slow_s): pumpPressure = self.readPumpPressure() logging.debug("Pump Pressure: {} PSI".format(pumpPressure)) if pumpPressure < startingPumpPressure - allowed_leak_amount_psi: t.fail( "Tank Pressure too low, likely a leak. Pressure: {}. Time: {} Seconds" .format(pumpPressure, i)) return t sleep(1) if i is pressureMeasurementTime_slow_s - 1: t.success("Tank is mantaining pressure correctly") return t t.success("Tank is mantaining pressure correctly") return t else: for i in range(pressureMeasurementTime_fast_s): pumpPressure = self.readPumpPressure() logging.debug("Pump Pressure: {} PSI".format(pumpPressure)) if pumpPressure < startingPumpPressure - allowed_leak_amount_psi: t.fail( "Tank Pressure too low, likely a leak. Pressure: {}. Time: {} Seconds" .format(pumpPressure, i)) return t sleep(1) if i is pressureMeasurementTime_fast_s - 1: t.success("Tank is mantaining pressure correctly") return t t.success("Tank is mantaining pressure correctly") return t
def test_Diagnostics_trial_pump(self): t = ResponseData() # Test Failure Criteria pump_to_pressure_time = 60 pump_pressure = 40 pump_pressure_acceptable_bound = 2 pressure_tank_start = 0 # Beginning pressure while testing for tank pressure pressure_tank_end = 30 # Highest pressure reached while testing on tank pressure pressure_interval = 5 # Interval in which the pressure increases between bounds global current_ramp_cycle with cd(path): g = self.g task = AnalogInputTask() self.close_house_air() for i in range(0, self.pressure_ramp_cycles): # Ensure solenoid is closed at start self.close_solenoid() # Set tank pressure to pump pressure self.pneumatics.setPumpPressure(pump_pressure) # Wait for pump to reach pressure for i in range(pump_to_pressure_time): p = self.pneumatics.readPumpPressure() if p > pump_pressure - pump_pressure_acceptable_bound: break if i is pump_to_pressure_time - 1: t.fail("Didn't reach pump pressure") return t sleep(1) logging.debug("Pump Pressure: {}".format(p)) logging.info("Testing Output Pressure (Source: Tank)") current_ramp_cycle = i # Interval added / subtracted to help make range function more # intuitive for p in range(pressure_tank_start, pressure_tank_end + pressure_interval, pressure_interval): logging.debug(p) self.record_solenoid_pressure(p) if self.daq.u.failed: self.close_house_air() self.pneumatics.setRegulatorPressure(0) self.pneumatics.setPumpPressure(0) if (p >= 10 or p <= 25): t = self.daq.u return t for p in range(pressure_tank_end, pressure_tank_start - pressure_interval, -pressure_interval): logging.debug(p) self.record_solenoid_pressure(p) if self.daq.u.failed: self.close_house_air() self.pneumatics.setRegulatorPressure(0) self.pneumatics.setPumpPressure(0) print(self.daq.u.data.split()) t = self.daq.u return t self.close_house_air() self.daq.display_test_results() t.success("Pressure test run successfully") return t
def test_for_leaks(self, speed = 'slow'): """ Tests tank pressure for stability Sets the tank pressure, and makes sure it reaches an acceptably close level within a set period of time. Then checks for a set period of time to make sure it mantains a close level to this value. Conditions: Pass: Reachs the set tank pressure in a reasonable amount of time with a set accuracy, then makes sure it mantains that pressure. Fail: After the set period of time, the tank never reaches the appropriate pressure. Fail: After the tank reaches pressure, is unable to hold it for a set length of time. """ setPressure = 40 getToPressureTime_s = 60 pressureMeasurementTime_slow_s = 540 pressureMeasurementTime_fast_s = 20 measurement_delay_time_slow_s = 60 measurement_delay_time_fast_s = 10 t = ResponseData() passingPressureRange_psi = 1 allowed_leak_amount_psi = .1 logging.info( "Testing for leaking Pressure Tank\n") self.setPumpPressure(setPressure) for i in range(getToPressureTime_s): pumpPressure = self.readPumpPressure() logging.debug("Pump Pressure: {} PSI".format(pumpPressure)) if pumpPressure > setPressure - passingPressureRange_psi: break sleep(1) if i is getToPressureTime_s - 1: t.fail( "Tank Pressure did not reach acceptable pressure range") return t self.setPumpPressure(0) if speed is not 'fast': logging.info("Waiting for {} seconds to allow time to stabilize".format(measurement_delay_time_slow_s)) sleep(measurement_delay_time_slow_s) logging.info("Starting to analyse pressure. This will take {} Seconds ({} Minutes)".format(pressureMeasurementTime_slow_s, pressureMeasurementTime_slow_s / 60.0)) else: logging.info("Waiting for {} seconds to allow time to stabilize".format(measurement_delay_time_fast_s)) sleep(measurement_delay_time_fast_s) logging.info("Starting to analyse pressure. This will take {} Seconds ({} Minutes)".format(pressureMeasurementTime_fast_s, pressureMeasurementTime_fast_s / 60.0)) startingPumpPressure = self.readPumpPressure() if speed is not 'fast': for i in range(pressureMeasurementTime_slow_s): pumpPressure = self.readPumpPressure() logging.debug("Pump Pressure: {} PSI".format(pumpPressure)) if pumpPressure < startingPumpPressure - allowed_leak_amount_psi: t.fail("Tank Pressure too low, likely a leak. Pressure: {}. Time: {} Seconds".format(pumpPressure, i)) return t sleep(1) if i is pressureMeasurementTime_slow_s-1: t.success("Tank is mantaining pressure correctly") return t t.success("Tank is mantaining pressure correctly") return t else: for i in range(pressureMeasurementTime_fast_s): pumpPressure = self.readPumpPressure() logging.debug("Pump Pressure: {} PSI".format(pumpPressure)) if pumpPressure < startingPumpPressure - allowed_leak_amount_psi: t.fail("Tank Pressure too low, likely a leak. Pressure: {}. Time: {} Seconds".format(pumpPressure, i)) return t sleep(1) if i is pressureMeasurementTime_fast_s-1: t.success("Tank is mantaining pressure correctly") return t t.success("Tank is mantaining pressure correctly") return t
class DAQ(object): """Interface for the NI DAQ""" def __init__(self, test): """Initializes the DAQ with a task, and a logger""" self.task1 = test.task self.data = {} self.log = Logger(test) self.g = test.g self.wait_time_s = test.wait_time_s self.sample_rate = test.sample_rate self.checkpoint = test.checkpoint self.u = ResponseData() self.test = test def record(self, samples, cycle, pressure): """Starts a thread that launches a record_worker""" self._rec_thread = Thread(target=self.record_worker, args=(samples, cycle, pressure)) self._rec_thread.start() def record_worker(self, samples, cycle, pressure): # Test Warning Criteria error_actual_warning_bound = .5 error_reported_warning_bound = 1 response_time_warning_bound = .25 # Test Failing Criteria error_actual_bound = 1 error_reported_bound = 2 response_time_bound = .35 pressure_failing_low = 5 pressure_failing_high = 25 response_time_tolerance = 0.95 # The percentage of the set value that, when reached, will be marked as reaching the value. global current_ramp_cycle """Records the number of samples losted, logs the data""" # Record data self.task1.start() self.data[cycle] = self.task1.read(samples) self.task1.stop() resp = (self.g.write('M236', resp_needed=True)) pressure_reported = (resp.split()[0]) logging.debug("pressure reported {} ".format(pressure_reported)) # Save times required to reach tolerance point timestamp = self.wait_time_s last_timestamp = self.wait_time_s final_value = float(np.average(self.data[cycle][-10:-5])) target = response_time_tolerance * final_value error_actual = float(final_value * 20) - float(pressure) error_reported = float(pressure_reported) - float(final_value * 20) for value in reversed(self.data[cycle]): if value < target: self.log.log_and_print(cycle, pressure, float(final_value) * 20.0, error_actual, pressure_reported, error_reported, last_timestamp) if abs(error_actual) > error_actual_bound or abs( error_reported) > error_reported_bound: if pressure >= pressure_failing_low and pressure <= pressure_failing_high: self.u.fail( "Error too high, test failed: Actual: {:2f}, Reported {:2f}, Pressure {}" .format(error_actual, error_reported, pressure)) elif abs(error_actual) > error_actual_warning_bound or abs( error_reported) > error_reported_warning_bound: self.test.test.logWarning( "Error may be outside of acceptable range: Actual: {:2f} PSI Reported: {:2f} PSI, Pressure {}" .format(error_actual, error_reported, pressure)) elif last_timestamp > response_time_bound and pressure > 0: self.u.fail( "Response time too high, test failed: Time: {}, Pressure: {}" .format(last_timestamp, pressure)) elif last_timestamp > response_time_warning_bound and pressure > 0: self.test.test.logWarning( "Response time might be outside of acceptable range: Time {:2f}, Pressure: {}" .format(last_timestamp, pressure)) break last_timestamp = timestamp timestamp -= (1.0 / self.sample_rate) if timestamp is (1.0 / self.sample_rate): self.log.log_and_print(cycle, pressure, float(final_value) * 20.0, error_actual, pressure_reported, error_reported, self.wait_time_s) if pressure is not 0: u.fail("Response time too long, test failed") # Periodically save full data for a cycle if cycle % self.checkpoint == 0: self.log.log_checkpoint(self.data, cycle, current_ramp_cycle, pressure) def display_test_results(self): """Shows the final display from the stat tracker in the logger""" self.log.display_test_results()
class DAQ(object): """Interface for the NI DAQ""" def __init__(self, test): """Initializes the DAQ with a task, and a logger""" self.task1 = test.task self.data = {} self.log = Logger(test) self.g = test.g self.wait_time_s = test.wait_time_s self.sample_rate = test.sample_rate self.checkpoint = test.checkpoint self.u = ResponseData() self.test = test def record(self, samples, cycle, pressure): """Starts a thread that launches a record_worker""" self._rec_thread = Thread(target=self.record_worker, args=(samples, cycle, pressure)) self._rec_thread.start() def record_worker(self, samples, cycle, pressure): # Test Warning Criteria error_actual_warning_bound = .5 error_reported_warning_bound = 1 response_time_warning_bound = .25 # Test Failing Criteria error_actual_bound = 1 error_reported_bound = 2 response_time_bound = .35 pressure_failing_low = 5 pressure_failing_high = 25 response_time_tolerance = 0.95 # The percentage of the set value that, when reached, will be marked as reaching the value. global current_ramp_cycle """Records the number of samples losted, logs the data""" # Record data self.task1.start() self.data[cycle] = self.task1.read(samples) self.task1.stop() resp = (self.g.write('M236', resp_needed=True)) pressure_reported = (resp.split()[0]) logging.debug("pressure reported {} ".format(pressure_reported)) # Save times required to reach tolerance point timestamp = self.wait_time_s last_timestamp = self.wait_time_s final_value = float(np.average(self.data[cycle][-10:-5])) target = response_time_tolerance * final_value error_actual = float(final_value*20) - float(pressure) error_reported = float(pressure_reported) - float(final_value*20) for value in reversed(self.data[cycle]): if value < target: self.log.log_and_print(cycle, pressure, float( final_value)*20.0, error_actual, pressure_reported, error_reported, last_timestamp) if abs(error_actual) > error_actual_bound or abs(error_reported) > error_reported_bound: if pressure >= pressure_failing_low and pressure <= pressure_failing_high: self.u.fail("Error too high, test failed: Actual: {:2f}, Reported {:2f}, Pressure {}".format(error_actual, error_reported, pressure)) elif abs(error_actual) > error_actual_warning_bound or abs(error_reported) > error_reported_warning_bound: self.test.test.logWarning("Error may be outside of acceptable range: Actual: {:2f} PSI Reported: {:2f} PSI, Pressure {}".format(error_actual, error_reported, pressure)) elif last_timestamp > response_time_bound and pressure > 0: self.u.fail("Response time too high, test failed: Time: {}, Pressure: {}".format(last_timestamp, pressure)) elif last_timestamp > response_time_warning_bound and pressure > 0: self.test.test.logWarning("Response time might be outside of acceptable range: Time {:2f}, Pressure: {}".format(last_timestamp, pressure)) break last_timestamp = timestamp timestamp -= (1.0 / self.sample_rate) if timestamp is (1.0 / self.sample_rate): self.log.log_and_print(cycle, pressure, float( final_value)*20.0, error_actual, pressure_reported, error_reported, self.wait_time_s) if pressure is not 0: u.fail("Response time too long, test failed") # Periodically save full data for a cycle if cycle % self.checkpoint == 0: self.log.log_checkpoint( self.data, cycle, current_ramp_cycle, pressure) def display_test_results(self): """Shows the final display from the stat tracker in the logger""" self.log.display_test_results()
def test_laser(self): """ Tests the laser responses to see that the ADC and laser are responding correctly. Conditions: Pass: After each movement, laser gives a valid response and stays within bounds of the test. Fail: Any of the responses given are outside the set limits of the test. """ t = ResponseData() logging.info("Testing Laser Response") logging.info("Setting Printer to Relative Mode:") relativeResponse = self.g.write("G91", resp_needed=True) logging.debug(relativeResponse) logging.info("Homing to put bed in range for laser") homingresponse = self.g.write("G28", resp_needed=True) logging.debug(homingresponse) logging.info("Homing Complete") M234ResponseHigh1 = self.readLaser() if M234ResponseHigh1.failed: return M234ResponseHigh1 logging.info("Reading ADC") M235Response = self.g.write("M235", resp_needed=True).split() if int(M235Response[1]) > self.adcMax: t.fail("Too far, out of adc max range") return t logging.debug(M235Response) logging.info("Moving Z") G0Response = self.g.write( "G0 Z4 F10000.0", resp_needed=True).split() logging.debug(G0Response) sleep(1) M234ResponseLow = self.readLaser() if M234ResponseLow.failed: return M234ResponseLow observed_diff = self.laserObservedDifference diff = M234ResponseHigh1.data - M234ResponseLow.data logging.debug("Distance Difference Pre and Post: {0}".format(diff)) if diff > observed_diff + self.laserHeightDifferenceAcceptedRange or diff < observed_diff - self.laserHeightDifferenceAcceptedRange: t.fail("Distance between original reading and new reading is too large") return t logging.info("Moving Z") G0Response = self.g.write( "G0 Z-4 F10000.0", resp_needed=True).split() logging.debug(G0Response) sleep(1) M234ResponseHigh2 = self.readLaser() if M234ResponseHigh2.failed: return M234ResponseHigh2 diff = M234ResponseHigh1.data - M234ResponseHigh2.data logging.debug("Distance Difference High 1 and 2: {0}".format(diff)) if diff > self.laserHysteresis or diff < -self.laserHysteresis: t.fail("Too far") return t t.success("Laser Test Passed\n") return t
def test_Diagnostics_trial_pump(self): t = ResponseData() # Test Failure Criteria pump_to_pressure_time = 60 pump_pressure = 40 pump_pressure_acceptable_bound = 2 pressure_tank_start = 0 # Beginning pressure while testing for tank pressure pressure_tank_end = 30 # Highest pressure reached while testing on tank pressure pressure_interval = 5 # Interval in which the pressure increases between bounds global current_ramp_cycle with cd(path): g = self.g task = AnalogInputTask() self.close_house_air() for i in range(0, self.pressure_ramp_cycles): # Ensure solenoid is closed at start self.close_solenoid() # Set tank pressure to pump pressure self.pneumatics.setPumpPressure(pump_pressure) # Wait for pump to reach pressure for i in range(pump_to_pressure_time): p = self.pneumatics.readPumpPressure() if p > pump_pressure - pump_pressure_acceptable_bound: break if i is pump_to_pressure_time - 1: t.fail("Didn't reach pump pressure") return t sleep(1) logging.debug("Pump Pressure: {}".format(p)) logging.info("Testing Output Pressure (Source: Tank)") current_ramp_cycle = i # Interval added / subtracted to help make range function more # intuitive for p in range(pressure_tank_start, pressure_tank_end + pressure_interval, pressure_interval): logging.debug(p) self.record_solenoid_pressure(p) if self.daq.u.failed: self.close_house_air() self.pneumatics.setRegulatorPressure(0) self.pneumatics.setPumpPressure(0) if (p >= 10 or p <= 25): t = self.daq.u return t for p in range(pressure_tank_end, pressure_tank_start - pressure_interval, -pressure_interval): logging.debug(p) self.record_solenoid_pressure(p) if self.daq.u.failed: self.close_house_air() self.pneumatics.setRegulatorPressure(0) self.pneumatics.setPumpPressure(0) print(self.daq.u.data.split()) t = self.daq.u return t self.close_house_air() self.daq.display_test_results() t.success("Pressure test run successfully") return t
def test_Diagnostics_trial_house(self): t = ResponseData() # Test Failure Criteria pressure_house_start = 30 # Beginning of house air pressure test pressure_house_end = 80 # Highest pressure reached while testing house air pressure_interval = 5 # Interval in which the pressure increases between bounds global current_ramp_cycle with cd(path): g = self.g task = AnalogInputTask() self.close_house_air() for i in range(0, self.pressure_ramp_cycles): # Ensure solenoid is closed at start # Ensure Solenoid is closed self.close_solenoid() # Set tank pressure to 40psi self.pneumatics.setPumpPressure(40) logging.info("Testing Output Pressure (Source: House Air)") self.open_house_air() for i in range(0, self.pressure_ramp_cycles): # Ensure solenoid is closed at start # Ensure Solenoid is closed self.close_solenoid() # Set tank pressure to 40psi self.pneumatics.setPumpPressure(40) current_ramp_cycle = i # Interval added / subtracted to help make range function more # intuitive for p in range(pressure_house_start, pressure_house_end + pressure_interval, pressure_interval): logging.debug(p) self.record_solenoid_pressure(p) if self.daq.u.failed: self.close_house_air() self.pneumatics.setRegulatorPressure(0) self.pneumatics.setPumpPressure(0) for p in range(pressure_house_end, pressure_house_start - pressure_interval, -pressure_interval): logging.debug(p) self.record_solenoid_pressure(p) if self.daq.u.failed: self.close_house_air() self.pneumatics.setRegulatorPressure(0) self.pneumatics.setPumpPressure(0) self.close_house_air() self.daq.display_test_results() t.success("Pressure test run successfully") return t