1 import tkMessageBox
2 from Tkinter import *
3 import Pmw
4 from teamwork.widgets.bigwidgets import *
5 from teamwork.widgets.fsa import *
6 from teamwork.math.matrices import epsilon
7
9 """Window that displays a MultiAgent Influence Diagram view of a L{scenario<teamwork.multiagent.PsychAgents.PsychAgents>}
10 """
11 colors = ['#ffff00','#ff00ff','#00ffff','#ffffff']
13 optiondefs = (
14 ('entities', {}, self.drawMAID),
15 )
16 self.defineoptions(kw, optiondefs)
17 Pmw.MegaWidget.__init__(self,frame)
18 self.frame = CanvasFrame(self.component('hull'),
19 width=self.winfo_screenwidth(),
20 height=self.winfo_screenheight())
21 self.frame.pack(expand = 'yes', fill = 'both', side='top')
22 self.dynamics = {}
23 self.initialiseoptions()
24
26 self.dynamics.clear()
27 canvas = self.frame.canvas()
28 states = {}
29 actions = {}
30 actionTypes = {}
31 utilities = {}
32 nodes = []
33 color = 0
34 for name,agent in self['entities'].items():
35
36 for key in agent.state.domainKeys():
37 if isinstance(key,StateKey) and key['entity'] == name:
38 label = TextWidget(canvas,str(key))
39 states[key] = OvalWidget(canvas,label,draggable=True,
40 fill=self.colors[color])
41 nodes.append(states[key])
42
43 for option in agent.actions.getOptions():
44 label = str(option)
45 actions[label] = BoxWidget(canvas,TextWidget(canvas,label),
46 draggable=True,
47 fill=self.colors[color])
48 nodes.append(actions[label])
49
50 for action in option:
51 if actionTypes.has_key(action['type']):
52 if not option in actionTypes[action['type']]:
53 actionTypes[action['type']].append(actions[label])
54 else:
55 actionTypes[action['type']] = [actions[label]]
56
57 utilities[name] = PolygonWidget(canvas,TextWidget(canvas,name),
58 draggable=True,
59 fill=self.colors[color])
60 nodes.append(utilities[name])
61 color = (color+1)%(len(self.colors))
62 edges = {}
63 for name,agent in self['entities'].items():
64
65 for feature,table in agent.dynamics.items():
66 key = StateKey({'entity':agent.name,'feature':feature})
67 for action,dynFun in table.items():
68 if isinstance(action,str):
69 continue
70
71 label = str([action])
72 origins = []
73 tree = dynFun.getTree()
74
75 for plane in tree.branches().values():
76 for other in plane.weights.keys():
77 if isinstance(other,StateKey) and \
78 abs(plane.weights[other]) > epsilon and \
79 not states[other] in origins:
80 origins.append(states[other])
81
82 for leaf in tree.leaves():
83 vector = leaf[key]
84 for other in vector.keys():
85 if other == key:
86 nochange = 1.
87 else:
88 nochange = 0.
89 if isinstance(other,StateKey) and \
90 abs(vector[other]-nochange) > epsilon and \
91 not states[other] in origins:
92 origins.append(states[other])
93 if len(origins) > 0:
94 origins.append(actions[label])
95
96 for node in origins:
97 edge = GraphEdgeWidget(canvas,0,0,0,0,
98 TextWidget(canvas,' '))
99 index = str(node)+str(key)
100 if not edges.has_key(index):
101 edges[index] = ((node,states[key],edge))
102 try:
103 self.dynamics[label].append(edge)
104 except KeyError:
105 self.dynamics[label] = [edge]
106
107 for goal in agent.getGoals():
108 if goal.type == 'state':
109
110 if len(goal.entity) == 1:
111 key = StateKey({'entity':goal.entity[0],
112 'feature':goal.key})
113 origins = [states[key]]
114 else:
115 raise NotImplementedError,'Unable to plot belief goals'
116 elif goal.type == 'action':
117
118 try:
119 origins = actionTypes[goal.key]
120 except KeyError:
121 origins = []
122 else:
123 raise NotImplementedError,'Unable to graph goals of type %s' % (goal.type)
124
125 for node in origins:
126 weight = agent.getGoalWeight(goal)
127 label = TextWidget(canvas,' ')
128 edge = GraphEdgeWidget(canvas,0,0,0,0,label)
129 if goal.direction == 'max':
130 color = '#00ff00'
131 else:
132 color = '#ff0000'
133 edge['color'] = color
134 edge['width'] = weight*10.
135 index = str(node)+str(name)
136 if not edges.has_key(index):
137 edges[index] = ((node,utilities[name],edge))
138 graph = GraphWidget(canvas,nodes,edges.values(),draggable=True)
139 for option,node in actions.items():
140 node.bind_click(self.viewDynamics)
141 self.frame.add_widget(graph)
142
152