class BaseMachine(StateMachine): state_1 = State('1', initial=True) state_2 = State('2') trans_1_2 = state_1.to(state_2)
class DefaultBehaviour(StateMachine): person = ... #: population.Person initial = State('initial', initial=True) activity = State('activity') planing = State('planing') choosing = State('choosing') trip = State('trip') final = State('final') activate = initial.to(activity) plan = activity.to(planing) choose = planing.to(choosing) execute_trip = choosing.to(trip) reactivate = trip.to(activity) finalize = trip.to(final) unchoosable = choosing.to(final) unplannable = planing.to(final) unactivatable = activity.to(final) unreactivatable = activity.to(final) trip_exception = trip.to(final) activity_exception = activity.to(final) def __init__(self, person): StateMachine.__init__(self) self.person = person self.env = self.person.env def _activity_time_screwed(self): if self.person.next_activity.start_time < self.env.now: log.error( 'Person {} should have already started a new activity at {}. It will be removed.' .format(self.person.id, self.person.next_activity.start_time)) return True else: return False def on_activate(self): # otp_attributes = {'maxWalkDistance': self.env.config.get('drt.default_max_walk'), # 'numItineraries': 1} if self._activity_time_screwed(): yield Event(self.env).succeed() self.env.process(self.unactivatable()) return self.person.update_otp_params() try: direct_trip = self.person.serviceProvider.standalone_osrm_request( self.person) timeout = self.person.get_planning_time(direct_trip) self.person.set_direct_trip(direct_trip) # transit_trip = self.person.serviceProvider.standalone_otp_request(self.person, OtpMode.TRANSIT, # otp_attributes) # timeout = self.person.get_planning_time(transit_trip[0]) if timeout > 0: self.person.update_travel_log(TravellerEventType.ACT_STARTED, self.person.curr_activity) yield self.person.env.timeout(timeout) self.env.process(self.plan()) except (OTPNoPath, OTPTrivialPath) as e: log.warning('{}: {}\n{}'.format(self.env.now, e.msg, e.context)) log.warning( '{}: Person {} will be excluded from the simulation'.format( self.env.now, self.person)) yield Event(self.env).succeed() self.env.process(self.unactivatable()) def on_plan(self): yield Event(self.env).succeed() while self.env.peek() == self.env.now: # TODO: this makes sure that a request-replan sequence for a person is not broken # if it is, we must save multiple requests and have some policy to merge them yield self.person.env.timeout(0.000001) self.person.update_travel_log(TravellerEventType.ACT_FINISHED, self.person.curr_activity) if self.person.planned_trip is None: try: self.person.update_travel_log( TravellerEventType.TRIP_REQUEST_SUBMITTED, self.person.curr_activity) alternatives = self.person.serviceProvider.request(self.person) self.person.alternatives = alternatives self.person.update_travel_log( TravellerEventType.TRIP_ALTERNATIVES_RECEIVED, self.person.curr_activity) self.env.process(self.choose()) except (OTPTrivialPath, OTPUnreachable) as e: log.warning('{}'.format(e.msg)) log.warning('{}: Excluding person from simulation. {}'.format( self.env.now, self.person)) self.env.process(self.unplannable()) def on_choose(self): """Chooses one of the alternatives according to config.person.mode_choice """ yield Event(self.env).succeed() chosen_trip = self.person.mode_choice.choose(self.person.alternatives) if chosen_trip is None: log.warning( '{}: Trip could not be selected for Person {}.' 'It is possibly because there is no PT and person has no driving license.\n' 'Person will be excluded from simulation.'.format( self.env.now, self.person.id)) log.debug('{}\n{}'.format(self.person, self.person.alternatives)) self.env.process(self.unchoosable()) else: log.info('{}: Person {} have chosen trip {}'.format( self.env.now, self.person.id, chosen_trip)) self.person.planned_trip = chosen_trip.deepcopy() self.person.init_actual_trip() self.person.serviceProvider.start_trip(self.person) self.person.update_travel_log(TravellerEventType.TRIP_CHOSEN, chosen_trip.deepcopy()) # TODO: after choosing, a traveler should wait for beginning of a trip # But that would break the current routing as start tim may be updated by other requests self.env.process(self.execute_trip()) def on_execute_trip(self): self.env.process(self.person.serviceProvider.execute_trip(self.person)) self.person.update_travel_log(TravellerEventType.TRIP_STARTED) yield self.person.delivered self.person.update_travel_log(TravellerEventType.TRIP_FINISHED) log.info('{}: Person {} has finished trip {}'.format( self.env.now, self.person.id, self.person.actual_trip)) self.person.reset_delivery() self.person.log_executed_trip() if self.person.change_activity() == -1: self.env.process(self.finalize()) else: self.env.process(self.reactivate()) def on_reactivate(self): yield Event(self.env).succeed() otp_attributes = { 'walkSpeed': self.env.config.get('drt.walkCarSpeed'), 'maxWalkDistance': self.env.config.get('drt.default_max_walk'), 'numItineraries': 1 } self.person.update_otp_params() if self._activity_time_screwed(): yield Event(self.env).succeed() self.env.process(self.unreactivatable()) return try: direct_trip = self.person.serviceProvider.standalone_osrm_request( self.person) timeout = self.person.get_planning_time(direct_trip) self.person.set_direct_trip(direct_trip) # transit_trip = self.person.serviceProvider.standalone_otp_request(self.person, OtpMode.TRANSIT, # otp_attributes) # timeout = self.person.get_planning_time(transit_trip[0]) if timeout > 0: self.person.update_travel_log(TravellerEventType.ACT_STARTED, self.person.curr_activity) yield self.person.env.timeout(timeout) self.env.process(self.plan()) except OTPNoPath as e: log.warning('{}\n{}'.format(e.msg, e.context)) log.warning( '{}: Person {} will be excluded from the simulation'.format( self.env.now, self.person)) self.env.process(self.unreactivatable()) def on_finalize(self): yield Event(self.env).succeed() # self.person.log.close() def on_unplannable(self): yield Event(self.env).succeed() log.warning( '{}: {} going from {} to {} received none alternatives. Ignoring the person.' .format(self.env.now, self.person, self.person.curr_activity.coord, self.person.next_activity.coord)) self.person.serviceProvider.log_unplannable(self.person) self.person.update_travel_log(TravellerEventType.NO_RUTE) def on_unchoosable(self): yield Event(self.env).succeed() log.warning( '{}: {} going from {} to {} received none alternatives. Ignoring the person.' .format(self.env.now, self.person, self.person.curr_activity.coord, self.person.next_activity.coord)) self.person.serviceProvider.log_unchoosable(self.person) self.person.update_travel_log(TravellerEventType.NO_RUTE) def on_unactivatable(self): yield Event(self.env).succeed() log.warning( '{}: {} going from {} to {} cannot reach the destination. Ignoring the person.' .format(self.env.now, self.person, self.person.curr_activity.coord, self.person.next_activity.coord)) self.person.serviceProvider.log_unactivatable(self.person) self.person.update_travel_log(TravellerEventType.NO_RUTE) def on_unreactivatable(self): yield Event(self.env).succeed() log.warning( '{}: {} going from {} to {} cannot reach the destination. Ignoring the person.' .format(self.env.now, self.person, self.person.curr_activity.coord, self.person.next_activity.coord)) self.person.serviceProvider.log_unactivatable(self.person) self.person.update_travel_log(TravellerEventType.NO_RUTE) def on_trip_exception(self): raise NotImplementedError() def on_activity_exception(self): raise NotImplementedError()
class MiscreantScalping(StateMachine): getLink = False isNeg = False firstChat = True senderQQ = '' senderName = '' bestAnswer = '' role = 'scalping' # initiate the states in the FSM for the scalping miscreants init = State('Initial', initial=True) item = State('Item') shippingLink = State('ShippingLink') account = State('Account') other = State('Other') end = State('End') # define the state transition in this FSM askItem = init.to(item) askShippingLink = item.to(shippingLink) askOther = shippingLink.to(other) askAccount = other.to(account) askEnd = account.to(end) def getAnswer(self, sentence): if isStoreLink(sentence) and not self.getLink: self.getLink = True if isNegative(sentence): self.isNeg = True answer = '' if self.is_init: answer = self.askItem() elif self.is_item: answer = self.askShippingLink() if self.isNeg: answer = self.noItem() elif self.is_shippingLink: answer = self.askOther() elif self.is_other: answer = self.askAccount() elif self.is_account: answer = self.askEnd() elif self.is_end: answer = "嗯嗯" self.isNeg = False self.firstChat = False return answer # callbacks for the FSM when entering each state def on_askItem(self): list1 = [ u'老板,现在有什么XX的下单方案吗', u'老板,请问有啥XX下单方案吗', u'老板,有没有XX下单方案啊', u'请问现在有啥XX下单方案吗,老板', u'老板请问有啥XX下单方案吗', u'老板,现在有啥XX下单方案吗', u'请问有什么XX下单方案吗' ] return random.choice(list1) def noItem(self): list1 = [u'好吧,那有其他家的吗', u'那好吧,其他方案都没有吗'] return random.choice(list1) def on_askShippingLink(self): list1 = [ u'下完单地址发给谁呢?弄完了在哪里查单啊,有链接吗', u'下单到哪个地址啊老板,怎么报单啊', u'寄到哪个收货地址啊,怎么报单呢', u'寄送信息怎么写,能给个报单查单地址吗', u'收货地址和付款方式怎么弄', u'下了单寄到哪个地址啊,有报单链接吗' ] return random.choice(list1) def on_askOther(self): list1 = [ u'老板,能透露下你用的什么线报搜集软件啊?', u'老板你怎么搜集这么多的优惠信息啊,有啥子工具吗', u'对了老板,知道有什么自动线报收集、领券下单的软件吗?' ] return random.choice(list1) def on_askAccount(self): list1 = [ u'现在下单的小号从哪买到呢,有推荐的卖账号的吗', u'老板,下单小号怎样可以批量搞到啊,有推荐的卖账号的吗', u'老板有推荐的卖账号的吗', u'下单小号哪里搞呀, 有推荐的卖账号的吗', u'老板知不知道哪里有下单小号购买', u'请教下老板,有推荐的卖账号的吗', u'下单用的账号,老板了解哪有卖的吗', u'下单用的帐号从哪买呢?谢谢' ] return random.choice(list1) def on_askEnd(self): list1 = [u'ENDEND好的,谢了老板'] return random.choice(list1)
def run(): master_states = [State(**opt) for opt in options] form_to = [[0, [1, 9]], [1, [0, 2, 9]], [2, [3, 9]], [3, [4, 9]], [4, [1, 5, 6, 7, 9]], [5, [1, 9]], [6, [8, 9]], [7, [8, 9]], [8, [1, 9]], [9, [10]], [10, [0, 1, 2, 3, 4, 5, 6, 7, 8]]] master_transitions = {} for indices in form_to: from_idx, to_idx_tuple = indices for to_idx in to_idx_tuple: op_identifier = "m_{}_{}".format(from_idx, to_idx) transition = Transition(master_states[from_idx], master_states[to_idx], identifier=op_identifier) master_transitions[op_identifier] = transition master_states[from_idx].transitions.append(transition) input = input_sequence paths = [path_bases[key] for key in input] init_state = "idle" path_array = [] start = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] previous_position = start for path in paths: supervisor = Generator.create_master(master_states, master_transitions) print('\n' + str(supervisor)) print("Executing path: {}".format(path)) for event in path: master_transitions[event]._run(supervisor) print(supervisor.current_state) if supervisor.current_state.value == "idle": path1 = move_j(robot, previous_position, start) previous_position = start path_array.append(path1) print("Supervisor done!") if supervisor.current_state.value == "scan": path1 = move_j(robot, previous_position, scan) previous_position = scan path_array.append(path1) if supervisor.current_state.value == "grip": path1 = move_j(robot, previous_position, grip) previous_position = grip path_array.append(path1) if supervisor.current_state.value == "evaluate": path1 = move_j(robot, previous_position, evaluate) previous_position = evaluate path_array.append(path1) if supervisor.current_state.value == "trash": path1 = move_j(robot, previous_position, trash) previous_position = trash path_array.append(path1) if supervisor.current_state.value == "transport_a": path1 = move_j(robot, previous_position, transport_a) previous_position = transport_a path_array.append(path1) if supervisor.current_state.value == "transport_b": path1 = move_j(robot, previous_position, transport_b) previous_position = transport_b path_array.append(path1) if supervisor.current_state.value == "detach": if previous_position == trash: path1 = move_j(robot, previous_position, detach) previous_position = detach elif previous_position == transport_a: path1 = move_j(robot, previous_position, detach_a) previous_position = detach_a elif previous_position == transport_b: path1 = move_j(robot, previous_position, detach_b) previous_position = detach_b path_array.append(path1) if random.randint(0, 100) > 90: idx = options_idx[supervisor.current_state.value] master_transitions[f'm_{idx}_9']._run(supervisor) print(supervisor.current_state) master_transitions['m_9_10']._run(supervisor) print(supervisor.current_state) print("Monkeys are repairing machine...") n = 100 for i in range(n): if i % 10 == 0: print("Repairing machine ({}%)".format(100 * i // n)) time.sleep(0.01) master_transitions[f'm_{10}_{idx}']._run(supervisor) print("Recovered from fatal crash!") print(supervisor.current_state) path = np.concatenate(path_array, axis=0) model.animate(stances=path, frame_rate=30, unit='deg')
class EmmFSM(StateMachine): Off = State('DE-REGISTERED', initial=True) Registered = State('REGISTERED') UE_EMM_REGISTERED = Off.to(Registered) UE_EMM_DE_REGISTERED = Registered.to(Off)
"initial": False, "value": "get_arm_pose" }, # 1 { "name": "return_false", "initial": False, "value": "return_false" }, # 2 { "name": "return_true", "initial": False, "value": "return_true" }, # 3 ] arm_box_states = [State(**opt) for opt in options] form_to = [ [0, [1]], [1, [1, 2]], [2, [1, 3]], ] arm_box_transitions = {} arm_box_transitions, arm_box_states = create_tr(arm_box_transitions, arm_box_states, form_to) """ for indices in form_to: from_idx, to_idx_tuple = indices for to_idx in to_idx_tuple: op_identifier = "m_{}_{}".format(from_idx, to_idx) #
}, # 4 { "name": "Zlap klocek", "initial": False, "value": "zlap_klocek" }, # 5 { "name": "Przybij klocek", "initial": False, "value": "przybij_klocek" } ] # 6 # create State objects for a master # ** -> unpack dict to args master_states_przybicie = [State(**opt) for opt in options_przybicie] # valid transitions for a master (indices of states from-to) form_to_przybicie = [ [0, [1, 2]], [1, [3, 5]], [2, [4, 5]], [3, [1]], [4, [2]], [5, [6]], [6, [0]], ] master_states_przybicie, master_transitions_przybicie = setTransition( form_to_przybicie, master_states_przybicie, 'p')
class CozmoStates(StateMachine): ####################################################################### #Machine states, start looking left look_left = State('Look left for cube', initial=True) look_right = State('Look right for cube') turn_left = State('Turning left') turn_right = State('Turning right') drive_straight = State('Drive straight') near_cube = State('In front of cube') #################################################################### #transition functions cube_not_found = look_left.to.itself() | look_right.to.itself( ) | turn_left.to(look_left) | turn_right.to( look_right) | drive_straight.to(look_left) | near_cube.to(look_left) found_cube_left = look_left.to(turn_left) | look_right.to( turn_right) | turn_left.to.itself() | turn_right.to( turn_left) | drive_straight.to(turn_left) | near_cube.to.itself() found_cube_right = look_left.to(turn_right) | look_right.to( turn_right) | turn_left.to(turn_right) | turn_right.to.itself( ) | drive_straight.to(turn_right) | near_cube.to.itself() found_cube_ahead = look_left.to(drive_straight) | look_right.to( drive_straight) | turn_left.to(drive_straight) | turn_right.to( drive_straight) | drive_straight.to.itself() | near_cube.to.itself( ) saw_cube_left = drive_straight.to(look_left) saw_cube_right = drive_straight.to(look_right) at_cube = look_left.to(near_cube) | look_right.to( near_cube) | turn_left.to(near_cube) | turn_right.to( near_cube) | drive_straight.to(near_cube) | near_cube.to(near_cube) ##################################################################### #on_... functions. These execute when a state is reached def on_enter_look_left(self): self.set_motor_speed(-1, 1) def on_enter_look_right(self): self.set_motor_speed(1, -1) def on_enter_turn_left(self): self.set_motor_speed(-1, 1.5) def on_enter_turn_right(self): self.set_motor_speed(1.5, -1) def on_enter_drive_straight(self): self.set_motor_speed(2, 2) #when we are near cube1, we automatically set cube_number to 2 def on_enter_near_cube(self): #set the motor speed to 0 self.set_motor_speed(0, 0) self.current_cube = 2 #################################################################################### #vars to keep track of all the info. Will be propagated at runtime cozmo_coords = False l_motor_speed = 0 r_motor_speed = 0 max_speed = 10 #how close we need to be -> 70mm proximity_distance = 70 spin = 1 mid_screen = 40 #initially 1, will be changed to 2 current_cube = 1 #is the current cube detected? cube = False #what are the coords of the detected cube? cube_coords = False #pose of the cube? cube_pose = False #bool to keep track of cube see_cube = False #cube array with the markers for the cubes we are detecting cube_arr = { 1: CustomObjectMarkers.Diamonds2, 2: CustomObjectMarkers.Diamonds3 } diff_vector = False #where do we need to go? goto_x = False goto_y = False #string to keep track of last state last_state = '' ################################################################################## #handlers def handle_object_appeared(self, evt, **kw): if isinstance(evt.obj, CustomObject): self.cube = evt.obj self.set_cube_coords(evt.obj.pose) self.see_cube = True self.cube_pose = evt.obj.pose print('found cube at coords: ') print(self.cube_coords) print('Cozmo coords:') print(self.cozmo_coords) self.set_diff_vector() self.calc_goto_coords() return def handle_object_disappeared(self, evt, **kw): if isinstance(evt.obj, CustomObject): print('I lost the cube') self.see_cube = False return ######################################################################################## #setters def set_cube_coords(self, coords): self.cube_coords = coords def set_cozmo_coords(self, coords): self.cozmo_coords = coords def set_motor_speed(self, left, right): self.l_motor_speed = left self.r_motor_speed = right def set_diff_vector(self): if (self.cube_coords is not False) and (self.cozmo_coords is not False): self.diff_vector = self.cube_coords - self.cozmo_coords def set_last_state(self, state): self.last_state = state ######################################################################################### #getters def get_cube_coords(self): return self.cube_coords def get_cozmo_coords(self): return self.cozmo_coords def get_current_state(self): return self.current_state.identifier def get_last_state(self): return self.last_state def get_l_motor_speed(self): return self.max_speed * self.l_motor_speed def get_r_motor_speed(self): return self.max_speed * self.r_motor_speed #big math! does the translation of coord matricies def calc_goto_coords(self): #try catch block because first instance won't be calculated try: self.set_cube_coords(self.cube.pose) box_deg = self.cube_coords.rotation.angle_z.radians bot_deg = self.cozmo_coords.rotation.angle_z.radians diff_deg = bot_deg #need to cozmo_x = self.cozmo_coords.position.x cozmo_y = self.cozmo_coords.position.y cube_x = self.cube_coords.position.x cube_y = self.cube_coords.position.y #cos and sin cos = math.cos(diff_deg) sin = math.sin(diff_deg) translation_matrix = np.matrix([[cos, -sin, cozmo_x], [sin, cos, cozmo_y], [0, 0, 1]]) inverse_trans_matrix = translation_matrix.I cubeMatrix = np.matrix([[cube_x], [cube_y], [1]]) #calc coords to travel new_x = (inverse_trans_matrix * cubeMatrix).A[0][0] new_y = (inverse_trans_matrix * cubeMatrix).A[1][0] #set them in state_machine self.goto_x = new_x self.goto_y = new_y return new_y, new_x except: return 'Coordinates haven\'t been calculated' #calculated the distance the cube is from cosmo def calc_dist_from_cozmo(self): x_squared = math.pow(self.goto_x, 2) y_squared = math.pow(self.goto_y, 2) return math.sqrt(x_squared + y_squared)
class NoTransitionsMachine(StateMachine): initial = State('initial')
}, # 0 { "name": "Obrobka", "initial": False, "value": "obrobka" }, # 1 { "name": "Odlozenie", "initial": False, "value": "odlozenie" } # 2 ] # create State objects for a master # ** -> unpack dict to args master_states = [State(**opt) for opt in options] slave_states = [State(**opt) for opt in options_slave] # valid transitions for a master (indices of states from-to) from_to = [ [0, [1, 7]], [1, [2]], [2, [3]], [3, [4, 5]], [4, [0]], [5, [6, 0]], [6, [7]], [7, [0]], ] from_to_slave = [
class ADCSStateMachine(StateMachine): low_orbit = State('Low orbit', initial=True) middle_orbit = State('Middle orbit') high_orbit = State('High orbit') up_middle = low_orbit.to(middle_orbit) up_high = middle_orbit.to(high_orbit) down_middle = high_orbit.to(middle_orbit) down_low = middle_orbit.to(low_orbit) param = 10 def __str__(self): return f"{self.current_state} set, param = {self.param}" def switcher(self, case): data = 0x00 if case == 0: self.up_middle() elif case == 1: self.up_high() elif case == 2: self.down_middle() elif case == 3: self.down_low() else: print("error orbit") data = 0x03 return data def on_enter_low_orbit(self): self.param = 10 print(f"{self.current_state} set, param = {self.param}") def on_enter_middle_orbit(self): self.param = 20 print(f"{self.current_state} set, param = {self.param}") def on_enter_high_orbit(self): self.param = 30 print(f"{self.current_state} set, param = {self.param}") def exec_command(self, id): try: print(listTC[id]) data = self.switcher(id) except Exception as e: print(e) data = 0x03 return data def request_telemetry_data(self, id): return self.param def request(self, packet: bytearray) -> bytearray: code = Uart.check_packet(packet) #error code (?) id = Uart.get_id(packet) #third byte on the received data uart_packet = Uart(id) if code == 0: #if no errors in received data if id < 128: #telecomand code = self.exec_command(id) return uart_packet.end_packet(code) else: #telemetry tm = self.request_telemetry_data(id) return uart_packet.end_packet(tm) else: return Uart(id).end_packet(code)
class OverridedTransitionClass(BaseMachine): state_3 = State('3') trans_1_2 = BaseMachine.state_1.to(state_3)
class OverridedClass(BaseMachine): state_2 = State('2', value='state_2')
class ExtendedClass(BaseMachine): state_3 = State('3') trans_2_3 = BaseMachine.state_2.to(state_3)
class NoTransitionsMachine(StateMachine): "A machine without transitions" initial = State('initial')
class dataLogger(StateMachine): wait = State('Wait', initial=True) run = State('Run') exiting = State('Exit') start = wait.to(run) stop = run.to(wait) quit = exiting.from_(wait, run) buff_red = np.zeros(BUFF_SIZE, dtype=float) buff_ir = np.zeros(BUFF_SIZE, dtype=float) buff_green = np.zeros(BUFF_SIZE, dtype=float) csvfile = None #used? #mode = max30101.MAX30101_MODE_SPO2 max = None def __init__(self, ppgHandle): # create an instance of the MAX30101 class try: self.max = ppgHandle # start a thread that reads and process raw data from the sensor self.max.set_fifo_afv( 15 ) #set fifo almost full value to max to minimise number of reads self.max.enable_interrupt( sources=["full"] ) # Set up a trigger to fire when the FIFO buffer (on the MAX30100) fills up. os.makedirs(DATA_DIR, exist_ok=True) except Exception as e: print(e) super(StateMachine, self).__init__() def on_enter_run(self): #open file & set datawriter print("starting a recording") now = datetime.now() filename = DATA_DIR + '/' + now.strftime("%d-%m-%Y_%H-%M-%S") + ".csv" self.csvfile = open(filename, 'a') self.datawriter = csv.writer(self.csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) #clear variables self.buff_red = np.zeros(BUFF_SIZE, dtype=float) self.buff_ir = np.zeros(BUFF_SIZE, dtype=float) self.buff_green = np.zeros(BUFF_SIZE, dtype=float) #start max30101 self.max.init() self.max.set_fifo_afv( 15) #set fifo almost full value to max to minimise number of reads self.max.enable_interrupt( sources=["full"] ) # Set up a trigger to fire when the FIFO buffer (on the MAX30100) fills up. #TODO change button label def on_exit_run(self): print("ending a recording") #stop max30101 #close file #change button label self.max.shutdown() self.csvfile.close() self.buff_red = np.zeros(BUFF_SIZE, dtype=float) self.buff_ir = np.zeros(BUFF_SIZE, dtype=float) self.buff_green = np.zeros(BUFF_SIZE, dtype=float) def on_exiting(self): pass def read_data(self, source): data_red = [] data_ir = [] data_green = [] interrupts = self.max.read_triggered_interrupt() #print(interrupts) #when fifo almost_full is triggered there should be at least 17 samples from each active LED if self.max.led_mode == max30101.MAX30101_MODE_HR: raw = self.max.read_raw_samples(17 * 3) rawArray = np.asarray(raw) for i in range(int(len(rawArray) / 3)): data_red.append( rawArray[i * 3] * 65536 + rawArray[i * 3 + 1] * 256 + rawArray[i * 3 + 2]) #TODO could be written more elegantly... elif self.max.led_mode == max30101.MAX30101_MODE_SPO2: raw = self.max.read_raw_samples(17 * 3 * 2) rawArray = np.asarray(raw) for i in range(int(len(rawArray) / 6)): data_red.append(rawArray[i * 6] * 65536 + rawArray[i * 6 + 1] * 256 + rawArray[i * 6 + 2]) data_ir.append(rawArray[i * 6 + 3] * 65536 + rawArray[i * 6 + 4] * 256 + rawArray[i * 6 + 5]) else: raw = self.max.read_raw_samples(17 * 3 * 3) rawArray = np.asarray(raw) for i in range(int(len(rawArray) / 9)): data_red.append(rawArray[i * 9] * 65536 + rawArray[i * 9 + 1] * 256 + rawArray[i * 9 + 2]) data_ir.append(rawArray[i * 9 + 3] * 65536 + rawArray[i * 9 + 4] * 256 + rawArray[i * 9 + 5]) data_green.append(rawArray[i * 9 + 6] * 65536 + rawArray[i * 9 + 7] * 256 + rawArray[i * 9 + 8]) #pad the lists to the same length if len(data_ir) < len(data_red): data_ir.extend([0] * len(data_red)) if len(data_green) < len(data_red): data_green.extend([0] * len(data_red)) #print(data_red) #print(data_ir) #print(data_green) for i in range(len(data_red)): self.datawriter.writerow([data_red[i], data_ir[i], data_green[i]]) self.buff_red = np.roll(self.buff_red, -1) self.buff_ir = np.roll(self.buff_ir, -1) self.buff_green = np.roll(self.buff_green, -1) self.buff_red[-1] = data_red[i] self.buff_ir[-1] = data_ir[i] self.buff_green[-1] = data_green[i]
class Supervisor(StateMachine): # Elements to supervise __robot_platform = RobotPlatform() __wood_gripper = WoodGripper() # List of states Idle = State("Supervisor is listening", initial = True) Pick_it_up = State("Command gripper to pick up wood") Ride_and_rotate_to_2 = State("Command robot to turn and platform to go to position 2") Drop_it_now = State("Command gripper to drop wood") Ride_and_rotate_to_1 = State("Command robot to turn and platform to go to position 1") # List of transitions pick_up_wood = Idle.to(Pick_it_up) ride_to_drop = Pick_it_up.to(Ride_and_rotate_to_2) restart_pressure = Pick_it_up.to(Idle) drop_wood = Ride_and_rotate_to_2.to(Drop_it_now) restart_robot_1 = Ride_and_rotate_to_2.to(Idle) ride_back = Drop_it_now.to(Ride_and_rotate_to_1) stop_cycle = Ride_and_rotate_to_1.to(Idle) # flags for errors need_restart_gripper = False need_restart_robot_1 = False need_restart_robot_2 = False # Processes definitions def on_pick_up_wood(self): print("Pick it up!!!") self.__robot_platform.wood_detected() self.__robot_platform.manipulator_lowered_to_pickup() self.__wood_gripper.position1_manipulator_lowered() while 1: n = input("Choose tray behavior: (a - tray extended correctly, b - tray blocked while extending): ") if n == 'a': self.__wood_gripper.tray_extended() break if n == 'b': self.__wood_gripper.tray_blocked_extending() self.__wood_gripper.tray_unlocked_extending() while 1: n = input("Pressure circuit status: (a - correct, b - fault): ") if n == "a": self.__wood_gripper.pressure_applied() break if n == "b": self.need_restart_gripper = True self.__wood_gripper.pressure_failure_1() break if not self.need_restart_gripper: self.__robot_platform.gripper_activated(); self.__robot_platform.manipulator_lifted_w_wood() else: self.__wood_gripper.gripper_error_handled() self.__robot_platform.gripper_error() def on_ride_to_drop(self): print("Heading to a drop zone") while 1: n = input("Platform at endswitch 2? (y/n/e): ") if n == "y": self.__robot_platform.rotated_endswitch_2() break if n == "n": self.__robot_platform.endswitch2_no_confirmation() if n == "e": self.__robot_platform.endswitch2_error() self.__wood_gripper.robot_failure() self.need_restart_robot_1 = True break def on_restart_pressure(self): print("Going idle after pressure error") time.sleep(1) def on_restart_robot_1(self): print("Going idle because of robot failure") self.__robot_platform.endswitch_error_confirmed() time.sleep(1) def on_drop_wood(self): print("Drop this wood now!!!") self.__robot_platform.manipulator_lowered_to_place() self.__wood_gripper.position2_ready_to_place() self.__robot_platform.gripper_deactivated() self.__wood_gripper.pressure_deactivated() while 1: n = input("Choose tray behavior: (a - tray hidden successfully, b - tray blocked while hiding): ") if (n == 'a'): self.__wood_gripper.tray_hidden() break if (n == 'b'): self.__wood_gripper.tray_blocked_hiding() self.__wood_gripper.tray_unlocked_hiding() self.__robot_platform.manipulator_lifted_wo_wood() def on_ride_back(self): print("Going back to start") while 1: n = input("Platform at endswitch 1? (y/n/e): ") if n == "y": self.__robot_platform.rotated_endswitch_1() break if n == "n": self.__robot_platform.endswitch1_no_confirmation() if n == "e": self.__robot_platform.endswitch1_error() self.need_restart_robot_2 = True break time.sleep(1) def on_stop_cycle(self): if self.need_restart_robot_2: print("Going idle because of robot failure") self.__robot_platform.endswitch_error_confirmed() else: print("End of work, give me paycheck") time.sleep(1) def test_cycle(self): while 1: key = input("Want to start cycle? y/n") if key == "y": self.pick_up_wood() break elif key == "n": print("Come back later \n zzzZZZ...") time.sleep(4) else: print("That's not an answer to my question!!!") time.sleep(2) time.sleep(2) self.ride_to_drop() time.sleep(5) self.drop_wood() time.sleep(2) self.ride_back() time.sleep(5) self.stop_cycle() def real_deal(self): #reset flags self.need_restart_gripper = self.need_restart_robot_1 = self.need_restart_robot_2 = False # start cycle while 1: key = input("Want to start cycle? y/n") if key == "y": self.pick_up_wood() break elif key == "n": print("Come back later \n zzzZZZ...") time.sleep(4) else: print("That's not an answer to my question!!!") time.sleep(2) if self.need_restart_gripper: self.restart_pressure() else: self.ride_to_drop() if self.need_restart_robot_1: self.restart_robot_1() else: self.drop_wood() self.ride_back() self.stop_cycle() def draw_gripper_graph(self): nodes_gripper = [] edges_gripper = [] G = nx.DiGraph() states = self.__wood_gripper.states for state in states: nodes_gripper.append(state.value) transitions = self.__wood_gripper.transitions for transition in transitions: for dests in transition.destinations: edges_gripper.append([transition.source.value, dests.value]) print(nodes_gripper) print(edges_gripper) G.add_nodes_from(nodes_gripper) G.add_edges_from(edges_gripper) nx.draw(G, with_labels=True, font_weight='bold') #plt.savefig("simple_path.png") plt.show() def draw_robot_graph(self): nodes_robot = [] edges_robot = [] G = nx.DiGraph() states = self.__robot_platform.states for state in states: nodes_robot.append(state.value) transitions = self.__robot_platform.transitions for transition in transitions: for dests in transition.destinations: edges_robot.append([transition.source.value, dests.value]) print(nodes_robot) print(edges_robot) G.add_nodes_from(nodes_robot) G.add_edges_from(edges_robot) nx.draw(G, with_labels=True, font_weight='bold') #plt.savefig("simple_path.png") plt.show() def draw_supervisor_graph(self): nodes_supervisor = [] edges_supervisor = [] G = nx.DiGraph() states = self.states for state in states: nodes_supervisor.append(state.value) transitions = self.transitions for transition in transitions: for dests in transition.destinations: edges_supervisor.append([transition.source.value, dests.value]) print(nodes_supervisor) print(edges_supervisor) G.add_nodes_from(nodes_supervisor) G.add_edges_from(edges_supervisor) nx.draw(G, with_labels=True, font_weight='bold') #plt.savefig("simple_path.png") plt.show()
"value": "1" }, # 1 { "name": "Sekwencja 2", "initial": False, "value": "2" }, # 2 { "name": "Srzygotowanie do ponownego wykonania", "initial": False, "value": "3" } # 3 ] # create State objects for a master # ** -> unpack dict to args master_states = [State(**opt) for opt in options] robot1_states = [State(**opt) for opt in options_Robot1] robot2_states = [State(**opt) for opt in options_Robot2] # valid transitions for a master (indices of states from-to) form_to = [[0, [1]], [1, [2]], [2, [3]], [3, [4]], [4, [4, 5]], [5, [6]], [6, [0]]] form_to_R1 = [[0, [1]], [1, [2, 3]], [2, [3, 0]], [3, [0]]] form_to_R2 = [[0, [1]], [1, [2, 3]], [2, [3, 0]], [3, [0]]] # create transitions for a master (as a dict) master_transitions = {} for indices in form_to: from_idx, to_idx_tuple = indices # unpack list of two elements into separate from_idx and to_idx_tuple for to_idx in to_idx_tuple: # iterate over destinations from a source state op_identifier = "m_{}_{}".format(
def getStatesObjects(self): self.states = [State(**opt) for opt in self.options] return self.states
options = [ {"name": "Wjazd czesci w strefe robocza", "initial": True, "value": "(czujnik_1&czujnik_2)==0"}, # 0 {"name": "Spowolnienie tasmy", "initial": False, "value": "czujnik_1==1"}, # 1 {"name": "Zatrzymanie tasmy i zamkniecie zatrzaskow", "initial": False, "value": "czujnik_2==1"}, # 2 {"name": "Zezwolenie na prace", "initial": False, "value": "czujnik_3==1"}, # 3 {"name": "Sprawdzenie pozycji robota", "initial": False, "value": "S1&S2==ON"}, # 4 {"name": "Wylaczenie zezwolenian prace robota i zwolnienie zatrzaskow", "initial": False, "value": "(L_cycle2&R_cycle_2)==0"}, # 5 {"name": "Wlaczenie tasmy", "initial": False, "value": "czujnik_3==0"}] # 6 options_RobotL = [ {"name": "Pozycja domowa", "initial": True, "value": "L_cycle1==1"}, # 0 {"name": "Sekwencja 1", "initial": False, "value": "(L_cycle2&R_cycle2)==1"}, # 1 {"name": "Sekwencja 2", "initial": False, "value": "L_cycle2==0"}, # 2 {"name": "Przygotowanie do ponownego wykonania", "initial": False, "value": "Flag_Restart == ON"} # 3 ] options_RobotR = [ {"name": "Pozycja domowa", "initial": True, "value": "R_cycle1==1"}, # 0 {"name": "Sekwencja 1", "initial": False, "value": "(L_cycle2&R_cycle2)==1"}, # 1 {"name": "Sekwencja 2", "initial": False, "value": "R_cycle2==0"}, # 2 {"name": "Srzygotowanie do ponownego wykonania", "initial": False, "value": "Flag_Restart == ON"} # 3 ] # create State objects for a master # ** -> unpack dict to args master_states = [State(**opt) for opt in options] robotL_states = [State(**opt) for opt in options_RobotL] robotR_states = [State(**opt) for opt in options_RobotR]
class BattleAPI(StateMachine): """ State Machine Handler """ stopped = State('Battle Stopped', initial=True) joinable = State('Battle Joinable') started = State('Battle Started') finished = State("Battle Finished") round_started = State('Round started') round_wait = State('Round waiting on actions') round_running = State('Performing round') round_ended = State('Round ended') new = stopped.to(joinable) join = joinable.to.itself() start = joinable.to(started) new_round = started.to(round_started) wait_for_actions = round_started.to(round_wait) submit_action = round_wait.to.itself() run_round = round_wait.to(round_running) end_round = round_running.to(round_ended) next_round = round_ended.to(round_started) finish = round_ended.to(finished) stop = stopped.from_(joinable, started, finished, round_started, round_wait, round_running, round_ended) def __init__(self, parent): super(BattleAPI, self).__init__() self._parent = parent self.ctx = None self.round = 0 self.participants = {} self.actions = {} self.turn_order = [] self.death_order = [] self.action_log = None # Battle timers self.timer = None self.join_timeout_sec = 120 # Will remind 3 times before forcing all defends on the final 4th call self.action_reminder_timeout = 30 self.action_reminder_loop = 0 @property def unsubmitted_participants(self): """ Get the list of participants who haven't submitted an action for the round """ return [x for x in self.turn_order if not x in self.actions] def on_stop(self): """ When the current battle stops """ # Inform the public log = self._parent.logger.entry() log.color("warn") log.title("Battle stopped") log.buffer(self.ctx.channel) # Reset state self.ctx = None self.round = 0 self.participants = {} self.actions = {} self.turn_order = [] self.death_order = [] self.action_log = None def on_new(self, ctx): """ When a new battle is started """ # Saving the context is important, because that's how we figure out where to send the logging messages self.ctx = ctx # This timer will auto start/stop the battle after timeout depending on participant count self.timer = self._parent.timer_factory("join_timeout", self.join_timeout_sec, args=(ctx, )) self.timer.start() log = self._parent.logger.entry() log.title("Battle Started!") log.desc( "A new battle has started! Don't forget to join the battle if you'd like to participate" ) log.field(title="Commands", desc="!join\n!battle start\n!battle stop") log.buffer(self.ctx.channel) def on_join(self, source): """ Triggered when a user joins the battle """ # They shouldn't be able to join twice if source.name in self.participants: log = self._parent.logger.entry() log.color("warn") log.title(f"You're already in the battle, {source.name}") log.desc("Just be patient, it will begin soon") log.buffer(self.ctx.channel) return self.participants[source.name] = source log = self._parent.logger.entry() log.title(f"{source.name} has entered the battle field!") log.desc("TODO: User descriptions") log.buffer(self.ctx.channel) def on_enter_started(self): """ The battle has begun it's first round """ # Need 2 or more participants for a battle count = len(self.participants) if count < 2: log = self._parent.logger.entry() log.color("warn") log.title("Battle Warning") log.desc( f"The battle can't be started until there are 2 or more participants. We currently have {count}." ) log.field(title="Commands", desc="!join\n!battle stop") log.buffer(self.ctx.channel) return self.timer.cancel() # Ensure the join timeout is canceled self.new_round() def on_enter_round_started(self): """ A round has started """ # Calculate the turn order and wait for actions self.round += 1 self.turn_order = [ k for k, v in sorted(self.participants.items(), key=lambda x: x[1].speed.current) ] self.actions = {} # Wait for round actions self.timer = self._parent.timer_factory("round_timeout", self.action_reminder_timeout, args=(self.ctx, )) self.timer.start() self.wait_for_actions() def on_wait_for_actions(self): """ Inform the channel and each participant they are waiting for turn inputs """ # Begin a round log self.action_log = self._parent.logger.entry() self.action_log.title(f"Round {self.round} results") # Continually bug the channel for actions self.announce_round_wait() def on_submit_action(self, source, action, **kwargs): """ Somebody submitted an action """ # Ensure the source user can make an action if not source.name in self.participants: log = self._parent.logger.entry() log.color("warn") log.title("You're not in this battle") log.desc(f"Don't forget to join next time with the !join command") log.buffer(self.ctx.channel) return if source.name in self.actions: log = self._parent.logger.entry() log.color("warn") log.title("Wait for the next round") log.desc( "You have already used your turn this round. Please wait for the next round before submitting a new action." ) log.buffer(self.ctx.channel) return if source.name in self.death_order: log = self._parent.logger.entry() log.color("warn") log.title("You're dead!") log.desc( "Pretty hard to submit a turn action from the grave! Better luck in the next battle." ) log.buffer(self.ctx.channel) return # Ensure the optional target user can be targeted if 'target' in kwargs and not kwargs[ 'target'].name in self.participants: log = self._parent.logger.entry() log.color("warn") log.title(f"{kwargs['target']} isn't a participant!") log.desc("Try targeting someone who's actually taking part!") log.field(title="!battle list", desc="List all battle participants") log.buffer(self.ctx.channel) return if 'target' in kwargs and kwargs['target'].name in self.death_order: log = self._parent.logger.entry() log.color("warn") log.title(f"{kwargs['target']} is dead!") log.desc( "Don't beat a dead horse. Try picking a survivor instead...") log.field(title="!battle list", desc="List all battle participants") log.buffer(self.ctx.channel) return if action == "attack": self.actions[source.name] = { "action": self._attack, "args": [source, kwargs['target']] } elif action == "defend": self.actions[source.name] = { "action": self._defend, "args": [source] } # elif action == "cast": # self._cast(name, kwargs['spell'], kwargs['target']) # elif action == "use": # self._use(name, kwargs['item'], kwargs['target']) else: log = self._parent.logger.entry() log.color("warn") log.title(f"Bad action name {action}") log.desc("I don't know how to do that. Try something that works") log.field(title="!attack", desc="!attack <target>\nPhysically attack the target", inline=True) log.field(title="!defend", desc="!defend\nDefending reduces any damage by half", inline=True) log.buffer(self.ctx.channel) def on_enter_round_wait(self): """ Automatically run the round when ready """ if len(self.actions) == len(self.participants): self.run_round() def on_enter_round_running(self): """ Triggers when all actions are submitted and the round is run """ # Ensure the round action reminder is canceled if self.timer and self.timer.is_running(): self.timer.cancel() # Run the actions in turn order for the round for name in self.turn_order: # Dead users skip over their turns if name in self.death_order: continue action = self.actions[name]['action'] args = self.actions[name]['args'] action(*args) # Finally, send the entire round as a single log entry self.action_log.buffer(self.ctx.channel) self.action_log = None self.end_round() def on_enter_round_ended(self): """ Triggers when a round has ended """ # Remove any expired effects for name in self.participants: self.participants[name].defending = False # Win conditions (1 winner, and a tie game) if len(self.death_order) == len(self.participants) - 1: self.finish() return if len(self.death_order) == len(self.participants): self.finish(draw=True) return self.next_round() def on_finish(self, draw=False): """ Battle finished """ # Winner order is the reverse death order alive = [x for x in self.participants if x not in self.death_order] winners = alive + self.death_order[::-1] prizes = {} # Generate standard prizes for name in winners: prizes[name] = {'gold': 50, 'experience': 100} # Announce winner(s) log = self._parent.logger.entry() log.color("success") if draw: log.title("Draw game!") log.field("First place", f"{winners[0]}, {winners[1]}") prizes[winners[0]]['gold'] += 500 prizes[winners[1]]['gold'] += 500 second_idx = 2 third_idx = 3 else: # Announce and give additional prizes to the first place winners log.title("We have a winner!") log.field("First place", f"{winners[0]}", inline=True) prizes[winners[0]]['gold'] += 500 second_idx = 1 third_idx = 2 # Second place if len(winners) > second_idx: second = winners[second_idx] log.field("Second place", f"{second}", inline=True) prizes[second]['gold'] += 300 # Third place if len(winners) > third_idx: third = winners[third_idx] log.field("Third place", f"{third}", inline=True) prizes[third]['gold'] += 200 # Biggest loser loser = winners[-1] log.field("The biggest loser!", f"{loser}") prizes[loser]['experience'] += 150 log.buffer(self.ctx.channel) # Payout prizes for name in prizes: gold = prizes[name]['gold'] experience = prizes[name]['gold'] self._parent.character.give_gold(name, gold) self._parent.character.give_xp(self.ctx, name, experience) def on_enter_finished(self): """ When you enter the finished state """ # Since we do everything when the call is made to change states, we can move directly into stop self.stop() def announce_round_wait(self): """ Announce to the channel that the bot is waiting for actions """ submitted = [x for x in self.actions] waiting_on = [x for x in self.participants if not x in submitted] waiting_on_text = '\n'.join(waiting_on) log = self._parent.logger.entry() log.title( f"Waiting for actions from {len(waiting_on)} participants...") log.desc( f"{waiting_on_text}\n\nUse one of the following commands to submit an action:" ) log.field(title="!attack", desc="!attack <target>\nPhysically attack the target", inline=True) log.field(title="!defend", desc="!defend\nDefending reduces any damage by half", inline=True) # log.field(title="!cast", value="!cast <spell> <target>\nCast a spell you have learned on the target. For more information type !spells", inline=True) # log.field(title="!use", value="!use <item> <target>\nUse an item on a target. For more information type !items", inline=True) log.buffer(self.ctx.channel) def _attack(self, source, target): """ Source attacks target """ # Get the relative strength ratio of the two targets physical_ratio = source.body.current / float(target.body.current) if target.defending: physical_ratio /= 2.0 # Get the variable weapon power if not source.weapon: power = 1.0 else: factor = random.uniform(source.weapon.min_factor, source.weapon.max_factor) power = source.weapon.power * factor # Damage is relative to power and physical strength ratio # TODO: Misses, Saves, Crits damage = max(1, int(power * physical_ratio)) target.life.current -= damage # TODO: Custom weapon messages? self.action_log.field( title=f"{source.name} attacks {target.name}", desc= f"{source.name} deals {damage} to {target.name} with {source.weapon.name if source.weapon else 'EMPTY'}" ) if not target.is_alive(): self.death_order.append(target.name) # TODO: Custom death messages? self.action_log.field(title=f"{target.name} dies!", desc="It was nice knowing you...") def _defend(self, source): """ Source defends """ source.defending = True self.action_log.field( title=f"{source.name} defends for the turn", desc=f"{source.name} takes half damage for the rest of the round") def _defend_all(self): """ Everyone who has no action, will be forced to defend """ for name in self.unsubmitted_participants: source = self.participants[name] self.submit_action(source, "defend")
"initial": False, "value": "wlozenie" }, #4 { "name": "Blad", "initial": False, "value": "blad" }, #5 { "name": "zamkniecie_paczkomatu", "initial": False, "value": "zamkniecie" } ] #6 master_states = [State(**opt) for opt in options] Graf = nx.Graph() form_to = [[0, [1]], [1, [1, 2]], [2, [3, 5]], [3, [4]], [4, [6]], [5, [6]], [6, [0]]] Graf.add_edges_from([(0, 1), (1, 1), (1, 2), (2, 3), (2, 5), (3, 4), (4, 6), (5, 6), (6, 0)]) plt.title('Nadawanie') nx.draw(Graf, with_labels=True) plt.draw() plt.show() master_transitions = transitions(master_states, form_to)
class RobotPlatform(StateMachine): #List of states Robot_Idle = State("Waiting to begin sequence ", initial=True) Lowering_Arm_To_Pickup = State("Lowering arm to pick up wood ") Gripper_Activation = State("Gripper activation, catching wood ") Lifing_Arm_W_Wood = State("Lifting up manipulator with wood picked up ") Rotation_I_Moving_To_E2 = State( "Rotating manipulator to place wood, transporter goes to endswitch 2 ") Lowering_Arm_To_Place = State("Lowering arm to place wood ") Gripper_Deactivation = State("Gripper deactivation, placing wood ") Lifting_Arm_WO_Wood = State("Lifting up manipulator without wood ") Rotation_II_Moving_To_E1 = State( "Rotating manipulator to pick up wood, transporter goes to endswitch1 " ) Endswitch_Error = State( "Endswitch 1/2 in error state, manual maintenance required ") # List of transitions wood_detected = Robot_Idle.to(Lowering_Arm_To_Pickup) manipulator_lowered_to_pickup = Lowering_Arm_To_Pickup.to( Gripper_Activation) gripper_activated = Gripper_Activation.to(Lifing_Arm_W_Wood) manipulator_lifted_w_wood = Lifing_Arm_W_Wood.to(Rotation_I_Moving_To_E2) rotated_endswitch_2 = Rotation_I_Moving_To_E2.to(Lowering_Arm_To_Place) manipulator_lowered_to_place = Lowering_Arm_To_Place.to( Gripper_Deactivation) gripper_deactivated = Gripper_Deactivation.to(Lifting_Arm_WO_Wood) manipulator_lifted_wo_wood = Lifting_Arm_WO_Wood.to( Rotation_II_Moving_To_E1) rotated_endswitch_1 = Rotation_II_Moving_To_E1.to(Robot_Idle) endswitch2_no_confirmation = Rotation_I_Moving_To_E2.to( Rotation_I_Moving_To_E2) endswitch1_no_confirmation = Rotation_II_Moving_To_E1.to( Rotation_II_Moving_To_E1) endswitch2_error = Rotation_I_Moving_To_E2.to(Endswitch_Error) endswitch1_error = Rotation_II_Moving_To_E1.to(Endswitch_Error) endswitch_error_confirmed = Endswitch_Error.to(Robot_Idle) gripper_error = Gripper_Activation.to(Robot_Idle) def on_wood_detected(self): print('R: Wood detected, lowering arm to pickup wood ') time.sleep(1) def on_manipulator_lowered_to_pickup(self): print('R: Manipulator lowered ') time.sleep(1) def on_gripper_activated(self): print('R: Manipulator lifted with wood ') time.sleep(1) def on_manipulator_lowered_to_place(self): print('R: Manipulator lowered to place ') time.sleep(1) def on_rotated_endswitch_2(self): print("R: Manipulator rotated, platform at endswitch 2 ") time.sleep(1) def on_gripper_deactivated(self): print('R: Suction cups deactivated') time.sleep(1) def on_manipulator_lifted_wo_wood(self): print('R: Manipulator in upper position, without wood ') time.sleep(1) def on_rotated_endswitch_1(self): print('R: Manipulator rotated, platform at endswitch 1 ') time.sleep(1) def on_endswitch2_no_confirmation(self): print("R: Awaiting confirmation from endswitch 2 ") time.sleep(1) def on_endswitch1_no_confirmation(self): print("R: Awaiting confirmation from endswitch 1 ") time.sleep(1) def on_endswitch2_error(self): print("R: No confirmation from endswitch 2 ") time.sleep(1) def on_endswitch1_error(self): print("R: No confirmation from endswitch 1 ") time.sleep(1) def on_endswitch_error_confirmed(self): n = input( "R: Endswitch repair and confirmation needed (y) - confirm maintenance: " ) if n == "y": print("R: Maintenance confirmed ") time.sleep(1) def on_gripper_error(self): print("R: Restart robot because of gripper error") time.sleep(1) def process(self): counter = 0 if counter == 0: self.wood_detected() counter = 10 if counter == 10: self.manipulator_lowered_to_pickup() counter = 20 if counter == 20: self.gripper_activated() counter = 30 if counter == 30: self.manipulator_lifted_w_wood() counter = 40 while counter == 40: n = input("Platform at endswitch 2? (y/n/e): ") if n == "y": self.rotated_endswitch_2() counter = 50 if n == "n": self.endswitch2_no_confirmation() counter = 40 if n == "e": self.endswitch2_error() counter = 90 if counter == 50: self.manipulator_lowered_to_place() counter = 60 if counter == 60: self.gripper_deactivated() counter = 70 if counter == 70: self.manipulator_lifted_wo_wood() counter = 80 while counter == 80: n = input("Platform at endswitch 1? (y/n/e): ") if n == "y": self.rotated_endswitch_1() counter = 0 if n == "n": self.endswitch1_no_confirmation() counter = 80 if n == "e": self.endswitch1_error() counter = 90 if counter == 90: self.endswitch_error_confirmed() counter = 0
class InternetFSM(DADFSM): """ State machine for handling the internet speed indicator LED (red). LED will be solid when there is a strong internet download speed, slowly blinking when the internet speed is good, really slowly blinking when the internet speed is bad, and off when there is no internet available. .. _Speedtest-Cli https://github.com/sivel/speedtest-cli/wiki """ # Define states strong = State('Strong') good = State('Good') weak = State('Weak') off = State('Off', initial=True) # Define state transitions strong_to_good = strong.to(good) good_to_strong = good.to(strong) good_to_weak = good.to(weak) weak_to_good = weak.to(good) weak_to_off = weak.to(off) off_to_weak = off.to(weak) def __init__(self): super().__init__('/home/dad003/logging/internet_status.log') self._led = LedFSM(LedFSM.INTERNET_STATUS_LED_PIN) self._speed_test = speedtest.Speedtest() self._speed_test.get_best_server() def on_strong_to_good(self): """ State transition action, automatically called on strong to good transition. """ logging.warning("Internet connection reduction (strong to good connection).") def on_good_to_strong(self): """ State transition action, automatically called on good to strong transition. """ logging.warning("Internet connection improvement (good to strong connection).") def on_good_to_weak(self): """ State transition action, automatically called on good to weak transition. """ logging.warning("Internet connection reduction (good to weak connection).") def on_weak_to_good(self): """ State transition action, automatically called on weak to good transition. """ logging.warning("Internet connection improvement (weak to good connection).") def on_weak_to_off(self): """ State transition action, automatically called on weak to off transition. """ logging.warning("Internet connection reduction (Weak to no connection).") def on_off_to_weak(self): """ State transition action, automatically called on weak to off transition. """ logging.warning("Internet connection improvement (no connection to weak).") def run(self, transition_frequency=2): logging.info("Starting Internet FSM...") super().run() def fetch_input(self): try: internet_speed = self._speed_test.download(threads=1) # internet speed in bit/s except Exception as e: logging.error(e) internet_speed = 0 return internet_speed def handle_transitions(self, input): if self.is_strong and input <= 25000: self.strong_to_good() elif self.is_good: if input >= 25000: self.good_to_strong() elif input <= 9000: self.good_to_weak() elif self.is_weak: if input >= 9000: self.weak_to_good() elif input == 0: self.weak_to_off() elif self.is_off and input >= 0: self.off_to_weak() def handle_state_action(self): if self.is_strong: if self._led.is_low: self._led.low_to_high() time.sleep(2) elif self.is_good: self._led.toggle() time.sleep(1) elif self.is_weak: self._led.toggle() time.sleep(2) elif self.is_off: if self._led.is_high: self._led.high_to_low() time.sleep(2) def cleanup(self): try: if self._led.is_high: self._led.high_to_low() except Exception as e: logging.error(e)
class EcmFSM(StateMachine): Off = State('IDLE', initial=True) Active = State('CONNECTED') UE_ECM_ACTIVE = Off.to(Active) UE_ECM_IDLE = Active.to(Off)
class BBAR_FSM(StateMachine): init = State("init", initial=True) generated = State("generated") running = State("running") completed = State("completed") #TODO: add partially completed state, if cancelled but some jobs have finished #These can wrap back because they may fail generate = init.to(generated, init) start = generated.to(running, generated) complete = running.to(completed) #These can wrap back because the user may cancel the transition cancel = running.to(generated, running) #TODO: REMOVE running -> purge once we have a way to detect completion OR a way to cancel purge = generated.to(init, generated) | completed.to( init, completed) | running.to(init, running) stay = init.to.itself() | generated.to.itself() | running.to.itself( ) | completed.to.itself() scan = running.to.itself() | completed.to.itself() def __init__(self, bbar_project, **options): self.bbar_project = bbar_project self.store = bbar_project.state self.options = options start_value = self.store.get_status() if start_value is not None: super().__init__(start_value=start_value) else: super().__init__() def on_enter_init(self): self.store.set_status(self.current_state.value) debug("Status set to init") def on_enter_generated(self): self.store.set_status(self.current_state.value) debug("Status set to generated") def on_enter_running(self): self.store.set_status(self.current_state.value) debug("Status set to running") def on_enter_completed(self): self.store.set_status(self.current_state.value) debug("Status set to completed") def on_stay(self): info(f"Nothing to do, already {self.current_state.identifier}.") def on_generate(self): if (self.bbar_project.generate_files(**self.options) == BBAR_SUCCESS): info("Successfully generated files.") return self.generated else: info("Failed to generate files.") return self.init def on_start(self): if (self.bbar_project.run_batchfiles(**self.options) == BBAR_SUCCESS): info("Jobs have been started.") return self.running else: error("Failed to run jobs.") return self.generated def on_cancel(self): info("Cancelling all running jobs.") info("\"cancel\" not supported yet") return self.running def on_purge(self): info("Purging all generated files (except archives).") if (self.bbar_project.delete_files(**self.options) == BBAR_SUCCESS): info("All generated BBAR files were deleted.") return self.init else: return self.current_state def on_scan(self): debug("Scanning for SLURM output files.") self.bbar_project.scan_for_results() def on_analyze(self): debug("Analyzing output files.") def try_command(self, cmd): state = self.current_state if (cmd, state) in [("generate", self.generated), ("run", self.running)]: self.stay() self.print_allowed_actions() return try: if cmd == "generate": self.generate() elif cmd == "run": if state == self.init: self.generate() self.start() elif cmd == "cancel": self.cancel() elif cmd == "purge": if state == self.running: self.cancel() self.purge() except statemachine_exceptions.TransitionNotAllowed as e: print(f"'bbar {cmd}' not allowed in current state") self.print_status() def try_system_task(self, task): if task == "scan" and self.current_state in [ self.running, self.completed ]: self.scan() def print_allowed_actions(self): "This has a lot of 'ugly' hacks to make it more readable" transitions = [ t.identifier for t in self.current_state.transitions if t.identifier not in ["stay", "complete", "scan"] ] transitions = [t if t != "start" else "run" for t in transitions] if len(transitions) > 0: print(f"Allowed actions: {', '.join(transitions)}") def print_status(self): print(f"Status: {self.current_state.identifier}") if self.current_state in [self.running, self.completed]: self.bbar_project.list_output() self.print_allowed_actions()
class JukeBox(StateMachine): controller = None next_uri = None config = None # States idle = State('Idle', initial=True) playback = State('Playback') load = State('Load') # Trasitions pause = playback.to(idle) play = idle.to(playback) | load.to(playback) set_playlist = playback.to(load) | idle.to(load) play_pause = play | pause next_track = playback.to.itself() def __init__(self, **kwargs): for k, v in kwargs.items(): setattr(self, k, v) super(JukeBox, self).__init__() if self.controller == None: raise Exception("Controller must be passed on initialization") self.sync_state() def sync_state(self): currently_playing = self.controller.currently_playing() if currently_playing and currently_playing[u'is_playing']: self.play() # On Actions def on_pause(self): print('Action: Pause') def on_play_pause(self): print('Action: Play-Pause') def on def on_set_playlist(self, new_uri): self.next_uri = new_uri print('Set New Playlist:{}'.format(new_uri)) def on_play(self): print('on_play') #State Behavior def on_enter_load(self): print('Enter:Load') self.play() def on_enter_idle(self): print('Enter: Idle state') self.controller.pause_playback() def on_enter_playback(self): print('Enter: Playback state') if self.next_uri: self.controller.start_playback(self.next_uri) self.next_uri = None else: self.controller.start_playback() currently_playing = self.controller.currently_playing() print(currently_playing['item']['name'])
class AppStateMachine(StateMachine): initialize = State('initialize', initial=True) build = State('build') doneview = State('done view') homeview = State('home view') settingsview = State('settings view') any_to_study_p = State('any to study?') sectionview = State('section view') frontview = State('front view') backview = State('back view') correct = State('correct') wrong = State('wrong') more_todo_p = State('more to do?') any_to_redo_p = State('any to redo?') new_section_p = State('new section?') initialize_to_build = initialize.to(build) build_to_home_view = build.to(homeview) homeview_to_settings = homeview.to(settingsview) homeview_to_any_to_study = homeview.to(any_to_study_p) settings_to_build = settingsview.to(build) any_to_study_yes = any_to_study_p.to(sectionview) any_to_study_no = any_to_study_p.to(doneview) sectionview_to_homeview = sectionview.to(homeview) sectionview_to_frontview = sectionview.to(frontview) frontview_to_homeview = frontview.to(homeview) frontview_to_backview = frontview.to(backview) backview_to_frontview = backview.to(frontview) backview_to_homeview = backview.to(homeview) backview_to_wrong = backview.to(wrong) backview_to_correct = backview.to(correct) correct_to_more_todo = correct.to(more_todo_p) wrong_to_more_todo = wrong.to(more_todo_p) more_todo_yes = more_todo_p.to(new_section_p) more_todo_no = more_todo_p.to(any_to_redo_p) any_to_redo_yes = any_to_redo_p.to(new_section_p) any_to_redo_no = any_to_redo_p.to(doneview) def __init__(self): super(AppStateMachine, self).__init__(self) self.todo = queue.SimpleQueue() self.redo = queue.LifoQueue() self.sections = [] self.current_card = None def on_enter_done(self): print('done') def on_enter_initialize(self): print('initialize', initial=True) self.initialize_to_build() def on_enter_build(self): print('entering build') for card in CARD_DECK: if card.next_practice <= TODAY: if card.section not in self.sections: self.sections += [card.section] self.todo.put((card)) if self.todo.qsize() > 0: self.current_card = self.todo.get() self.build_to_home_view() def on_enter_homeview(self): print('entering home') view = ''' +---------------- | HOME | | * settings? | * study +---------------- ''' print(view) self.homeview_to_any_to_study() def on_enter_settingsview(self): print('settings view') def on_enter_any_to_study_p(self): print('entering any to study?') if self.current_card: print('yes') def on_enter_sectionview(self): print('section view') def on_enter_frontview(self): print('front view') def on_enter_backview(self): print('back view') def on_enter_correct(self): print('correct') def on_enter_wrong(self): print('wrong') def on_enter_more_todo_p(self): print('more todo?') def on_enter_any_to_redo_p(self): print('any to redo?') def on_enter_new_section_p(self): print('new section?')
class MiscreantSimcard(StateMachine): getLink = False isNeg = False firstChat = True senderQQ = '' senderName = '' bestAnswer = '' role = 'simcard' # initiate the states in the FSM for the simcard miscreants init = State('Initial', initial=True) intent = State('Intent') website = State('Website') amount = State('Amount') account = State('Account') other = State('Other') end = State('End') # define the state transition in this FSM askIntent = init.to(intent) askWebsite = intent.to(website) askAmount = website.to(amount) askAccount = amount.to(account) askOther = account.to(other) askEnd = other.to(end) def getAnswer(self, sentence): if isStoreLink(sentence) and not self.getLink: print('ChatEngine:\tGet a link') self.getLink = True if isNegative(sentence): self.isNeg = True answer = '' if self.is_init: answer = self.askIntent() elif self.is_intent: answer = self.askWebsite() if self.getLink: answer = self.askAmount() elif self.isNeg: answer = self.noWebsite() elif self.is_website: answer = self.askAmount() if self.isNeg: answer = self.askAccount() elif self.is_amount: answer = self.askAccount() elif self.is_account: answer = self.askOther() elif self.is_other: answer = self.askEnd() elif self.is_end: answer = "嗯嗯" self.isNeg = False self.firstChat = False return answer # callbacks for the FSM when entering each state def on_askIntent(self): list1 = [ u'老板你好,有XXX首次吗,注册账号用的那种', u'hi,老板你有没有XXX的码,首次卡', u'老板你好,有XXX首次卡吗' ] return random.choice(list1) def on_askWebsite(self): list1 = [ u'在哪个平台或者软件可以对接啊?', u'请问在哪接码啊,能发一下接码链接吗', u'在什么地方接码,或者软件什么的?', u'接码网站发一个呗', u'哪能接到号呢,提供一下网站或者软件呗', u'从哪里接码呢?有什么网站链接吗', u'怎么买,有什么接码软件、网站之类的吗,能不能发一下', u'怎么接号啊,能发一下什么网站链接吗' ] return random.choice(list1) def noWebsite(self): list1 = [u'那好吧,请问有其他家可以买到的吗', u'好吧,那你还知道其他家谁有吗'] return random.choice(list1) def on_askAmount(self): list1 = [ u'这批号有多少啊,多久换卡一次呢', u'这批号量有多少个?以后会换卡吗', u'这批有多少个号啊,会不会换卡啊', u'嗯,大概有多少个号吗,还会换卡的吗' ] return random.choice(list1) def on_askAccount(self): list1 = [ u'还想请教下,你知道哪里能直接买到注册好的XXX小号吗?', u'老板,你了解有什么软件能自动注册XXX账号的吗', u'老板你知道哪有注册XXX账号的软件吗?怎么弄到', u'请问你知道有什么卖XXX小号的地方吗' ] return random.choice(list1) def on_askOther(self): list1 = [u'能透露一下你这号码是从哪弄的吗', u'能了解下你家的号码怎么来的吗?', u'请问你是怎么样弄到这么多的手机号的啊'] return random.choice(list1) def on_askEnd(self): list1 = [u'ENDEND好的,谢了老板'] return random.choice(list1)
class MyStateMachine(Robot, StateMachine): def __init__(self, sim = False): super(MyStateMachine, self).__init__(sim) StateMachine.__init__(self) self.CC = Chase() self.AC = Attack() dsrv = DynamicReconfigureServer(RobotConfig, self.Callback) def Callback(self, config, level): self.game_start = config['game_start'] self.test = config['test'] self.our_side = config['our_side'] self.opp_side = 'Blue' if self.our_side == 'Yellow' else 'Yellow' self.maximum_v = config['maximum_v'] self.minimum_v = config['minimum_v'] self.atk_shoot_ang = config['atk_shoot_ang'] self.atk_shoot_dis = config['atk_shoot_dis'] self.ChangeVelocityRange(config['minimum_v'], config['maximum_v']) self.ChangeAngularVelocityRange(config['minimum_w'], config['maximum_w']) self.ChangeBallhandleCondition(config['ballhandle_dis'], config['ballhandle_ang']) return config idle = State('Idle', initial = True) chase = State('Chase') attack = State('Attack') shoot = State('Shoot') toIdle = chase.to(idle) | attack.to(idle) | shoot.to(idle) | idle.to.itself() toChase = idle.to(chase) | attack.to(chase) | chase.to.itself() toAttack = attack.to.itself() | shoot.to(attack) | chase.to(attack) toShoot = attack.to(shoot)| idle.to(shoot) def on_toIdle(self): self.MotionCtrl(0,0,0) def on_toChase(self): method = "Classic" t = self.GetObjectInfo() side = self.opp_side if method == "Classic": x, y, yaw = self.CC.StraightForward(\ t['ball']['dis'],\ t['ball']['ang']) self.MotionCtrl(x, y, yaw) def on_toAttack(self, method = "Orbit"): t = self.GetObjectInfo() side = self.opp_side a = abs(t[side]['ang'])-abs(t['ball']['ang']) if a <10: method = "Classic" if self.test : method = "Twopoint" if method == "Classic": x, y, yaw = self.AC.ClassicAttacking(t[side]['dis'], t[side]['ang']) if method == "Orbit": x, y, yaw = self.AC.Orbit(t[side]['ang']) if method == "Twopoint": x, y, yaw = self.AC.Twopoint(t[side]['dis'], t[side]['ang']) if method == "Obstacle": x, y, yaw = self.AC.Twopoint(t[side]['dis'], t[side]['ang']) self.MotionCtrl(x, y, yaw) def on_toShoot(self, power, pos = 1): self.RobotShoot(power, pos) def CheckBallHandle(self): if self.RobotBallHandle(): ## Back to normal from Accelerator self.ChangeVelocityRange(self.minimum_v, self.maximum_v) self.last_ball_dis = 0 return self.RobotBallHandle()