def __init__(self): self.idle_timeout = 30 self.bb = Blackboard() #self.mem_manager = MemoryManager(self) self.planner = plan self.current_goal = None self.goals = [] # all goals this instance can use self.filters = [] # list of methods to use as a filter self.actions = [] # all actions this npc can perform self.plan = [] # list of actions to perform # '-1' will be the action currently used # this special filter will prevent time precepts from being stored self.filters.append(time_filter)
def self_test(self): """ make sure the goal is sane """ bb = Blackboard() self.touch(bb) assert self.test(bb) == True
def __init__(self, parent, action, bb=None): self.parent = parent self.action = action self.bb = Blackboard() self.delta = Blackboard() #self.cost = action.calc_cost() self.cost = 1 self.g = calcG(self) self.h = 1 if not parent == None: self.bb.update(parent.bb) elif not bb == None: self.bb.update(bb) action.touch(self.delta) self.bb.update(self.delta)
class PlanningNode(object): """ each node has a copy of a bb (self.bb) in order to simulate a plan. """ def __init__(self, parent, action, bb=None): self.parent = parent self.action = action self.bb = Blackboard() self.delta = Blackboard() #self.cost = action.calc_cost() self.cost = 1 self.g = calcG(self) self.h = 1 if not parent == None: self.bb.update(parent.bb) elif not bb == None: self.bb.update(bb) action.touch(self.delta) self.bb.update(self.delta) def __eq__(self, other): if isinstance(other, PlanningNode): #if DEBUG: print "[cmp] {} {}".format(self.delta.memory, other.delta.memory) return self.delta == other.delta else: return False def __repr__(self): try: return "<PlanNode: '%s', cost: %s, p: %s>" % \ (self.action.__name__, self.cost, self.parent.action.__class__.__name__) except AttributeError: return "<PlanNode: '%s', cost: %s, p: None>" % \ (self.action.__class__.__name__, self.cost)
class GoapAgent(ObjectBase): """ AI Agent inventories will be implemented using precepts and a list. currently, only one action running concurrently is supported. """ # this will set this class to listen for this type of precept # not implemented yet interested = [] def __init__(self): self.idle_timeout = 30 self.bb = Blackboard() #self.mem_manager = MemoryManager(self) self.planner = plan self.current_goal = None self.goals = [] # all goals this instance can use self.filters = [] # list of methods to use as a filter self.actions = [] # all actions this npc can perform self.plan = [] # list of actions to perform # '-1' will be the action currently used # this special filter will prevent time precepts from being stored self.filters.append(time_filter) def add(self, other, origin): # we simulate the agent's knowledge of its inventory with precepts p = Precept(sense="inventory") # do the actual add super(GoapAgent, self).add(other, origin) def remove(self, obj): # we simulate the agent's knowledge of its inventory with precepts p = Precept(sense="inventory") # do the actual remove super(GoapAgent, self).remove(other, origin) def add_goal(self, goal): self.goals.append(goal) def remove_goal(self, goal): self.goals.remove(goal) def add_action(self, action): self.actions.append(action) def remove_action(self, action): self.actions.remove(action) def filter_precept(self, precept): """ precepts can be put through filters to change them. this can be used to simulate errors in judgement by the agent. """ for f in self.filters: precept = f(precept) if precept == None: break return precept def handle_precept(self, pct): """ used by the environment to feed the agent precepts. agents can respond by sending back an action to take. """ # give our filters a chance to change the precept pct = self.filter_precept(pct) # our filters may have caused us to ignore the precept if pct == None: return None print "[agent] {} recv'd pct {}".format(self, pct) # this line has been added for debugging purposes self.plan = [] if pct.sense == "position": self.bb.post(Tag(position=pct.position, obj=pct.thing)) return self.next_action() def replan(self): """ force agent to re-evaluate goals and to formulate a plan """ # get the relevancy of each goal according to the state of the agent s = [ (g.get_relevancy(self.bb), g) for g in self.goals ] s = [ g for g in s if g[0] > 0 ] s.sort(reverse=True) print "[agent] goals {}".format(s) # starting for the most relevant goal, attempt to make a plan for score, goal in s: ok, plan = self.planner( self, self.actions, self.current_action(), self.bb, goal) if ok: print "[agent] {} has planned to {}".format(self, goal) pretty = list(reversed(plan[:])) print "[agent] {} has plan {}".format(self, pretty) return plan else: print "[agent] {} cannot {}".format(self, goal) return [] def current_action(self): try: return self.plan[-1] except IndexError: return NullAction def running_actions(self): return self.current_action() def next_action(self): """ get the next action of the current plan """ if self.plan == []: self.plan = self.replan() current_action = self.current_action() # this action is done, so return the next one if current_action.state == ACTIONSTATE_FINISHED: return self.plan.pop() # this action failed somehow elif current_action.state == ACTIONSTATE_FAILED: raise Exception, "action failed, don't know what to do now!" # our action is still running, just run that elif current_action.state == ACTIONSTATE_RUNNING: return current_action
class GoapAgent(ObjectBase): """ AI Agent inventories will be implemented using precepts and a list. currently, only one action running concurrently is supported. """ # this will set this class to listen for this type of precept # not implemented yet interested = [] def __init__(self): self.idle_timeout = 30 self.bb = Blackboard() #self.mem_manager = MemoryManager(self) self.planner = plan self.current_goal = None self.goals = [] # all goals this instance can use self.filters = [] # list of methods to use as a filter self.actions = [] # all actions this npc can perform self.plan = [] # list of actions to perform # '-1' will be the action currently used # this special filter will prevent time precepts from being stored self.filters.append(time_filter) def add(self, other, origin): # we simulate the agent's knowledge of its inventory with precepts p = Precept(sense="inventory") # do the actual add super(GoapAgent, self).add(other, origin) def remove(self, obj): # we simulate the agent's knowledge of its inventory with precepts p = Precept(sense="inventory") # do the actual remove super(GoapAgent, self).remove(other, origin) def add_goal(self, goal): self.goals.append(goal) def remove_goal(self, goal): self.goals.remove(goal) def add_action(self, action): self.actions.append(action) def remove_action(self, action): self.actions.remove(action) def filter_precept(self, precept): """ precepts can be put through filters to change them. this can be used to simulate errors in judgement by the agent. """ for f in self.filters: precept = f(precept) if precept == None: break return precept def handle_precept(self, pct): """ used by the environment to feed the agent precepts. agents can respond by sending back an action to take. """ # give our filters a chance to change the precept pct = self.filter_precept(pct) # our filters may have caused us to ignore the precept if pct == None: return None print "[agent] {} recv'd pct {}".format(self, pct) # this line has been added for debugging purposes self.plan = [] if pct.sense == "position": self.bb.post(Tag(position=pct.position, obj=pct.thing)) return self.next_action() def replan(self): """ force agent to re-evaluate goals and to formulate a plan """ # get the relevancy of each goal according to the state of the agent s = [(g.get_relevancy(self.bb), g) for g in self.goals] s = [g for g in s if g[0] > 0] s.sort(reverse=True) print "[agent] goals {}".format(s) # starting for the most relevant goal, attempt to make a plan for score, goal in s: ok, plan = self.planner(self, self.actions, self.current_action(), self.bb, goal) if ok: print "[agent] {} has planned to {}".format(self, goal) pretty = list(reversed(plan[:])) print "[agent] {} has plan {}".format(self, pretty) return plan else: print "[agent] {} cannot {}".format(self, goal) return [] def current_action(self): try: return self.plan[-1] except IndexError: return NullAction def running_actions(self): return self.current_action() def next_action(self): """ get the next action of the current plan """ if self.plan == []: self.plan = self.replan() current_action = self.current_action() # this action is done, so return the next one if current_action.state == ACTIONSTATE_FINISHED: return self.plan.pop() # this action failed somehow elif current_action.state == ACTIONSTATE_FAILED: raise Exception, "action failed, don't know what to do now!" # our action is still running, just run that elif current_action.state == ACTIONSTATE_RUNNING: return current_action
temp_offset = -1.5 # serial port for connection to the PT8005 sound_serial_port = "/dev/ttyUSB0" parser = ArgumentParser() parser.add_argument("-v", action="store_true") options = parser.parse_args() if options.v: log_level = logging.DEBUG if __name__ == "__main__": log_format = "%(asctime)s: %(message)s" logging.basicConfig(format=log_format, level=log_level, datefmt="%H:%M:%S") blackboard = Blackboard() gas = GasReader(blackboard) temperature = TemperatureReader(blackboard, temp_offset=temp_offset) sound = SoundReader(blackboard, serial_port=sound_serial_port) exporter = PrometheusExporter(blackboard) threads.append(threading.Thread(target=gas.measure, daemon=True)) threads.append(threading.Thread(target=gas.set_baseline, daemon=True)) threads.append(threading.Thread(target=gas.calibrate, daemon=True)) threads.append(threading.Thread(target=temperature.measure, daemon=True)) threads.append(threading.Thread(target=sound.measure, daemon=True)) threads.append(threading.Thread(target=exporter.fill_gauges, daemon=True)) exporter.start_prometheus_http_server()