1 """
2 PsychSim specification of the robot grid meeting problem
3 """
4 from teamwork.agent.AgentClasses import classHierarchy
5 from teamwork.math.Keys import ObservationKey
6 from teamwork.math.probability import Distribution
7 from teamwork.math.KeyedVector import ThresholdRow
8 from teamwork.math.KeyedMatrix import IdentityMatrix,IncrementMatrix
9 from teamwork.math.KeyedTree import KeyedPlane
10 from teamwork.math.ProbabilityTree import ProbabilityTree,createBranchTree
11
12
13 Omega = {'left': ObservationKey({'type':'wall left'}),
14 'right': ObservationKey({'type':'wall right'}),
15 }
16
18 width = 2
19 height = 2
20 classHierarchy['Robot'] = {
21 'parent': ['Entity'],
22 'state': {},
23 'dynamics': {'x': {}, 'y': {}},
24 }
25
26 dist = {0.: 1.,1.:0.}
27 for x in range(1,width-1):
28 dist[float(x)/float(width-1)] = 0.
29 dist[1.] = 0.
30 classHierarchy['Robot']['state']['x'] = Distribution(dist)
31
32 dist = {0.: 1.,1.: 0.}
33 for y in range(1,height-1):
34 dist[float(y)/float(height-1)] = 0.
35 classHierarchy['Robot']['state']['y'] = Distribution(dist)
36
37 directions = ['up','down','left','right']
38 actions = {'type': 'XOR','key':'type',
39 'values': []}
40 for action in directions:
41 actions['values'].append({'type':'literal','value':action})
42 actions['values'].append({'type': 'literal', 'value': 'stay'})
43 classHierarchy['Robot']['actions'] = actions
44
45 obs = {Omega['left']['type']: {},
46 Omega['right']['type']: {},
47 }
48 classHierarchy['Robot']['observations'] = obs
49
50 classHierarchy['Robot']['dynamics']['x']['up'] = move('x',0,width)
51 classHierarchy['Robot']['dynamics']['y']['up'] = move('y',1,height)
52 classHierarchy['Robot']['dynamics']['x']['down'] = move('x',0,width)
53 classHierarchy['Robot']['dynamics']['y']['down'] = move('y',-1,height)
54 classHierarchy['Robot']['dynamics']['x']['left'] = move('x',-1,width)
55 classHierarchy['Robot']['dynamics']['y']['left'] = move('y',0,height)
56 classHierarchy['Robot']['dynamics']['x']['right'] = move('x',1,width)
57 classHierarchy['Robot']['dynamics']['y']['right'] = move('y',0,height)
58
59 -def move(dimension,delta=0,span=2,escape=0.1):
60 """
61 Generates dynamics for an action that tries to move in the specified
62 dimension
63 @param dimension: the dimension of the intended move ('x' or 'y')
64 @type dimension: str
65 @param delta: the intended change in position (default is 0)
66 @type delta,span: int
67 @param span: the maximum length of the dimension (default is 2)
68 @param escape: the probability of making a given unintended change
69 @type escape: float
70 """
71 assert span == 2,'Unable to handle grids that are not 2x2. Sorry'
72
73 interval = 1./float(span-1)
74 stay = ProbabilityTree(IdentityMatrix(dimension))
75 if dimension == 'x':
76
77 moveUp = ProbabilityTree(IdentityMatrix(dimension))
78 moveDown = ProbabilityTree(IdentityMatrix(dimension))
79 moveLeft = ProbabilityTree(IncrementMatrix(dimension,value=-interval))
80 moveRight = ProbabilityTree(IncrementMatrix(dimension,value=interval))
81 else:
82 assert dimension == 'y','Unknown dimension: %s' % (dimension)
83
84 moveUp = ProbabilityTree(IncrementMatrix(dimension,value=interval))
85 moveDown = ProbabilityTree(IncrementMatrix(dimension,value=-interval))
86 moveLeft = ProbabilityTree(IdentityMatrix(dimension))
87 moveRight = ProbabilityTree(IdentityMatrix(dimension))
88
89 leftover = 1. - 5.*escape
90 if delta == 0:
91 intended = stay
92 elif dimension == 'x':
93 if delta == 1:
94 intended = moveRight
95 else:
96 assert delta == -1,'Unable to handle moves of %d spaces' % (delta)
97 intended = moveLeft
98 else:
99 if delta == 1:
100 intended = moveUp
101 else:
102 assert delta == -1,'Unable to handle moves of %d spaces' % (delta)
103 intended = moveDown
104
105 upperLeft = ProbabilityTree()
106 dist = {stay: escape, moveUp: escape, moveDown: escape,
107 moveLeft: escape, moveRight: escape}
108 dist[intended] += leftover
109 dist[stay] += dist[moveLeft] + dist[moveUp]
110 dist[moveLeft] = 0.
111 dist[moveUp] = 0.
112 upperLeft.branch(Distribution(dist))
113
114 upperRight = ProbabilityTree()
115 dist = {stay: escape, moveUp: escape, moveDown: escape,
116 moveLeft: escape, moveRight: escape}
117 dist[intended] += leftover
118 dist[stay] += dist[moveRight] + dist[moveUp]
119 dist[moveRight] = 0.
120 dist[moveUp] = 0.
121 upperRight.branch(Distribution(dist))
122
123 lowerLeft = ProbabilityTree()
124 dist = {stay: escape, moveUp: escape, moveDown: escape,
125 moveLeft: escape, moveRight: escape}
126 dist[intended] += leftover
127 dist[stay] += dist[moveLeft] + dist[moveDown]
128 dist[moveLeft] = 0.
129 dist[moveDown] = 0.
130 lowerLeft.branch(Distribution(dist))
131
132 lowerRight = ProbabilityTree()
133 dist = {stay: escape, moveUp: escape, moveDown: escape,
134 moveLeft: escape, moveRight: escape}
135 dist[intended] += leftover
136 dist[stay] += dist[moveRight] + dist[moveDown]
137 dist[moveRight] = 0.
138 dist[moveDown] = 0.
139 lowerRight.branch(Distribution(dist))
140
141 xRow = ThresholdRow(keys=[{'entity':'self','feature':'x'}])
142 yRow = ThresholdRow(keys=[{'entity':'self','feature':'y'}])
143 leftTree = createBranchTree(KeyedPlane(yRow,0.5),lowerLeft,upperLeft)
144 rightTree = createBranchTree(KeyedPlane(yRow,0.5),lowerRight,upperRight)
145 return createBranchTree(KeyedPlane(xRow,0.5),leftTree,rightTree)
146
147 if __name__ == '__main__':
148 import bz2
149 from teamwork.multiagent.GenericSociety import GenericSociety
150
151 society = GenericSociety()
152 try:
153 f = bz2.BZ2File('meeting.soc','r')
154 data = f.read()
155 f.close()
156 from xml.dom import minidom
157 doc = minidom.parseString(data)
158 society.parse(doc.documentElement)
159 except IOError:
160 setupMeeting()
161 society.importDict(classHierarchy)
162 society.save('meeting.soc')
163