def dog_standing(dog_id, level=1): Logger.info("Phase Five: Level %s - Starting" % level) Logger.data(dog_id, 5, level, "starting") stand_time = 0 treat_timer = 1 treat_dispense_time = 0 if level == 2: stand_time = levels['1']['duration'] + 1 """ DOG IS STANDING """ while True: # If the program is calling for cancellation, just cancel whatever we are doing if not Config.RUN_FLAG: return False # If the dog has laid down, move to #D levels. if MoveUtil.is_dog_down: Logger.data(dog_id, 5, 1 if stand_time <= levels['1']['duration'] else 2, "dog_down") return dog_down(dog_id, '1D') # If the dog has barked, reset to level 1 if NoiseUtil.has_dog_barked: stand_time = 0 treat_timer = 1 continue # If the dog has completed Level 1, announce and save if stand_time == levels['1']['duration']: FileIOUtil.save(dog_id, 5, 1) Logger.info("Phase Five: Level 1 - Complete") Logger.data(dog_id, 5, 1, "complete") FileIOUtil.save(dog_id, 5, 1) Logger.info("Phase Five: Level 2 - Starting") Logger.data(dog_id, 5, 2, "starting") # If we just gave a treat, figure out the next time we should dispense one if treat_timer == 1: treat_dispense_time = random.randint( levels['1']['min'] if stand_time <= levels['1']['duration'] else levels['2']['min'], levels['1']['max'] if stand_time <= levels['1']['duration'] else levels['2']['max']) # Check if a treat should be dispensed if treat_timer == treat_dispense_time: dispense_treat() treat_timer = 0 # End stuff time.sleep(1) treat_timer += 1 stand_time += 1
def level_one(dog_id): Logger.info("Phase One: Level 1 - Starting") Logger.data(dog_id, 1, 1, "starting") scheduler.schedule(5, 150, dispense_treat) if not Config.RUN_FLAG: Logger.data(dog_id, 1, 1, "cancelled") return False FileIOUtil.save(dog_id, 1, 1) Logger.info("Phase One: Level 1 - Complete") Logger.data(dog_id, 1, 1, "complete") return True
def level_four(dog_id): Logger.info("Phase Two: Level 4 - Starting") Logger.data(dog_id, 3, 4, "starting") scheduler.schedule(12, 60, dispense_treat) if not Config.RUN_FLAG: Logger.data(dog_id, 2, 4, "cancelled") return False FileIOUtil.save(dog_id, 2, 4) Logger.info("Phase Two: Level 4 - Complete") Logger.data(dog_id, 3, 4, "complete") return True
def level_three(dog_id): Logger.info("Phase Two: Level 3 - Starting") Logger.data(dog_id, 2, 3, "starting") scheduler.schedule(8, 64, dispense_treat) if not Config.RUN_FLAG: Logger.data(dog_id, 2, 3, "cancelled") return False FileIOUtil.save(dog_id, 2, 3) Logger.info("Phase Two: Level 3 - Complete") Logger.data(dog_id, 2, 3, "complete") return level_four(dog_id)
def level_five(dog_id): Logger.info("Phase Three: Level 5 - Starting") Logger.data(dog_id, 3, 5, "starting") if Challenge.phase_three(dog_id=dog_id, level=5, treat_frequency_min=12, quiet_length=60, fail_max=3): FileIOUtil.save(dog_id, 3, 5) Logger.info("Phase Three: Level 5 - Complete") Logger.data(dog_id, 3, 5, "complete") return level_six(dog_id) else: if not Config.RUN_FLAG: Logger.info("Phase Three: Level 5 - Cancelled") return False Logger.info("Phase Three: Level 5 - Failed, regressing to Level 4") Logger.data(dog_id, 3, 5, "failed") return level_four(dog_id)
def level_two(dog_id): Logger.info("Phase Three: Level 2 - Starting") Logger.data(dog_id, 3, 2, "starting") if Challenge.phase_three(dog_id=dog_id, level=2, treat_frequency_min=3, quiet_length=30, fail_max=3): FileIOUtil.save(dog_id, 3, 2) Logger.info("Phase Three: Level 2 - Complete") Logger.data(dog_id, 3, 2, "complete") return level_three(dog_id) else: if not Config.RUN_FLAG: Logger.info("Phase Three: Level 2 - Cancelled") return False Logger.info("Phase Three: Level 2 - Failed, regressing to Level 2") Logger.data(dog_id, 3, 2, "failed") return level_two(dog_id)
def dog_down(dog_id, level="1D"): # How long the dog is laying down down_time = 0 # What time interval we will give the treat on treat_timer = 1 treat_dispense_time = 0 fail_count = 0 stand_timer = 0 level = int(level[0]) # Grace periods grace_down_timer = 0 grace_bark_timer = 0 dog_stand_state = False Logger.info("Phase Five: Level %sD - Starting" % level) Logger.data(dog_id, 5, "%sD" % level, "starting") while True: if not Config.RUN_FLAG: return False ''' Setup ''' if down_time >= levels["%sD" % level]['duration']: Logger.info("Phase Five: Level %sD - Complete" % level) Logger.data(dog_id, 5, "%sD" % level, "complete") FileIOUtil.save(dog_id, 5, "%sD" % level) if level >= 9: Logger.info("Phase Five: Complete.") return # Dog has passed Phase 5 level += 1 # Increase the level the dog is on Logger.info("Phase Five: Level %sD - Starting" % level) Logger.data(dog_id, 5, "%sD" % level, "starting") down_time = 0 # Start timer over for new level treat_timer = 1 # Calculate new treat time based on new level if treat_timer == 1: treat_dispense_time = random.randint(levels["%sD" % level]['min'], levels["%sD" % level]['max']) ''' Log what happened in the last second ''' if not MoveUtil.is_dog_down and not dog_stand_state: dog_stand_state = True Logger.data(dog_id, 5, "%sD" % level, "dog_stand") if MoveUtil.is_dog_down and dog_stand_state: dog_stand_state = False Logger.data(dog_id, 5, "%sD" % level, "dog_down") if NoiseUtil.has_dog_barked: Logger.data(dog_id, 5, "%sD" % level, "dog_bark") ''' manage stand timer ''' if not MoveUtil.is_dog_down: stand_timer += 1 else: stand_timer = 0 ''' Punishments for bad behavior ''' if grace_down_timer <= 0 and not MoveUtil.is_dog_down: NoiseUtil.reset_bark_status() if level < 8 or (level >= 8 and stand_timer > 10): Logger.info("Dog just stood, incrementing fail count.") fail_count += 1 grace_down_timer = 20 # Grace period down_time = 0 elif grace_bark_timer <= 0 and NoiseUtil.has_dog_barked: NoiseUtil.reset_bark_status() Logger.info("Dog just barked, incrementing fail count.") fail_count += 1 grace_bark_timer = 5 # Grace period down_time = 0 if fail_count >= 6: # Dog failed 2 levels in a row, go to level 1 Logger.info( "Phase Five: Level %sD and %sD - Failed, regressing to Level 1" % (level + 1, level)) Logger.data(dog_id, 5, level, "failed_restart") return dog_standing(dog_id, 1) if fail_count == 3: # Maximum number of fails before regressing level Logger.info( "Phase Five: Level %sD - Failed, regressing to Level %sD" % (level, level - 1 if level - 1 >= 1 else 1)) Logger.data(dog_id, 5, "%sD" % level, "failed") if level > 1: level -= 1 Logger.info("Phase Five: Level %sD - Starting" % level) Logger.data(dog_id, 5, "%sD" % level, "starting") down_time = 0 # Treat reset treat_timer = 1 treat_dispense_time = 0 # Grace periods reset grace_bark_timer = 0 grace_down_timer = 0 continue ''' Reset grace period once dog lays back down ''' if grace_down_timer > 0 and MoveUtil.is_dog_down: grace_down_timer = 0 down_time = 0 if treat_timer == treat_dispense_time: PetTutorUtil.dispense_treat() treat_timer = 0 fail_count = 0 # End stuff time.sleep(1) treat_timer += 1 down_time += 1 if grace_down_timer > 0: grace_down_timer -= 1 if grace_bark_timer > 0: grace_bark_timer -= 1
def main(): Logger.open_log_files() # This must be run before any logging is done Logger.info("P4E Training Protocol is Starting...") signal.signal(signal.SIGINT, handler) signal.signal(signal.SIGTERM, handler) # Read in Arguments parser = argparse.ArgumentParser() parser.add_argument( '--debug', default='False', dest='debug', help="Boolean whether debug is on or off. Default False", type=argbool) parser.add_argument('--com', default=Config.PETTUTOR_COMPORT, dest='comport', help="COM port to use. Default is %s" % Config.PETTUTOR_COMPORT, type=int) parser.add_argument( '--wait', default=Config.PETTUTOR_ERROR_WAIT_INTERVAL, dest='error_wait', help= "Number of seconds to wait if connection fails before retrying. -1 to not retry. Default is %s" % Config.PETTUTOR_ERROR_WAIT_INTERVAL, type=int) parser.add_argument( '--mic', default=Config.MIC_SENSITIVITY, dest='mic', type=float, help="Number in decibels for dog barking sensitivity. Default is %s" % Config.MIC_SENSITIVITY) parser.add_argument('--camera', default=Config.CAMERA_ID, dest='camera', type=int, help="Camera ID, generally 0 or 1. Default is %s" % Config.CAMERA_ID) parser.add_argument( '--disable-pettutor', default='False', dest='disable_pettutor', help="True to disable connection to PetTutor (testing purposes only)", type=argbool) # Set values argvalues = parser.parse_args() Config.PRINT_DEBUG = argvalues.debug Config.PETTUTOR_COMPORT = argvalues.comport Config.PETTUTOR_ERROR_WAIT_INTERVAL = argvalues.error_wait Config.MIC_SENSITIVITY = argvalues.mic Config.CAMERA_ID = argvalues.camera Config.DISABLE_PETTUTOR = argvalues.disable_pettutor # Log Configuration Logger.debug("Debug is %s" % Config.PRINT_DEBUG) Logger.debug("PetTutor Comport: %s" % Config.PETTUTOR_COMPORT) Logger.debug("PetTutor Wait Time: %s" % Config.PETTUTOR_ERROR_WAIT_INTERVAL) Logger.debug("Mic Sensitivity: %s" % Config.MIC_SENSITIVITY) # Connect to PetTutor PetTutorUtil.connect(Config.PETTUTOR_COMPORT) while True: Logger.prompt("Dog ID (-1 to Quit): ") dog_id = raw_input() Logger.debug("Dog ID is %s" % dog_id) if dog_id == '-1': break if re.match('^[\w-]+$', dog_id) is None: Logger.error( "'%s' is not a valid dog ID. Please only use alphanumeric characters." % dog_id) continue Config.RUN_FLAG = True data = FileIOUtil.load(dog_id) if data.get('dog_size') is None: Logger.prompt("Please enter dog's size (small/medium/large): ") dog_size = raw_input() Logger.debug("Dog Size is %s " % dog_size) if dog_size.lower() in ("small", "s", "0"): dog_size = 0 FileIOUtil.save_size(dog_id, 0) elif dog_size.lower() in ("medium", "m", "1"): dog_size = 1 FileIOUtil.save_size(dog_id, 1) elif dog_size.lower() in ("large", "l", "2"): dog_size = 2 FileIOUtil.save_size(dog_id, 2) else: Logger.error( "'%s' did not match expected input (small/medium/large)" % dog_size) continue else: dog_size = data["dog_size"] (phase, level) = find_next_level(data) input_required = False if phase != -1 and level != -1: Logger.info( "Dog %s's first incomplete level is Phase %s Level %s." % (dog_id, phase, level)) else: Logger.info("Dog %s has completed all Phases/Levels." % dog_id) input_required = True if not input_required: Logger.prompt("Continue? (Y/n): ") input_required = raw_input().lower() == 'n' Logger.debug("Continue is %s" % (not input_required)) if input_required: Logger.info("Please specify which Phase you want to run.") Logger.prompt("Enter a Phase Number (-1 to go back): ") try: phase = int(raw_input()) except ValueError: Logger.error("Phases can only be numbers.") continue Logger.debug("Selected phase is %d" % phase) if phase == -1: continue Logger.prompt("Enter a Level Number (-1 to go back): ") level = raw_input() Logger.debug("Selected level is %s" % level) if level == '-1': continue keyboard_thread = Thread(target=keyboard_listener) keyboard_thread.start() # Start a phase. if phase == 1: PhaseOne.start(dog_id, int(level)) Config.RUN_FLAG = False continue elif phase == 2: PhaseTwo.start(dog_id, int(level)) Config.RUN_FLAG = False continue elif phase == 3: PhaseThree.start(dog_id, int(level)) Config.RUN_FLAG = False continue elif phase == 4: PhaseFour.start(dog_id, dog_size, int(level)) Config.RUN_FLAG = False continue elif phase == 5: PhaseFive.start(dog_id, level.upper()) Config.RUN_FLAG = False continue Logger.error("You entered an invalid Phase.") Config.RUN_FLAG = False time.sleep(1) Logger.close_log_files()