pycityagent 1.1.9__py3-none-any.whl → 1.1.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pycityagent/__init__.py +2 -1
- pycityagent/ac/__init__.py +1 -1
- pycityagent/ac/citizen_actions/trip.py +2 -3
- pycityagent/ac/hub_actions.py +216 -16
- pycityagent/agent.py +2 -0
- pycityagent/agent_citizen.py +10 -2
- pycityagent/agent_func.py +93 -13
- pycityagent/agent_group.py +84 -0
- pycityagent/brain/brain.py +1 -0
- pycityagent/brain/memory.py +15 -15
- pycityagent/brain/scheduler.py +1 -1
- pycityagent/brain/sence.py +74 -140
- pycityagent/hubconnector/__init__.py +1 -1
- pycityagent/hubconnector/hubconnector.py +353 -8
- pycityagent/simulator.py +149 -7
- pycityagent/urbanllm/urbanllm.py +305 -5
- pycityagent/utils.py +178 -0
- {pycityagent-1.1.9.dist-info → pycityagent-1.1.11.dist-info}/METADATA +11 -11
- {pycityagent-1.1.9.dist-info → pycityagent-1.1.11.dist-info}/RECORD +22 -20
- {pycityagent-1.1.9.dist-info → pycityagent-1.1.11.dist-info}/WHEEL +1 -1
- {pycityagent-1.1.9.dist-info → pycityagent-1.1.11.dist-info}/LICENSE +0 -0
- {pycityagent-1.1.9.dist-info → pycityagent-1.1.11.dist-info}/top_level.txt +0 -0
pycityagent/utils.py
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
def get_angle(x, y):
|
|
4
|
+
return math.atan2(y, x)*180/math.pi
|
|
5
|
+
|
|
6
|
+
def point_on_line_given_distance(start_node, end_node, distance):
|
|
7
|
+
"""
|
|
8
|
+
Given two points (start_point and end_point) defining a line, and a distance s to travel along the line,
|
|
9
|
+
return the coordinates of the point reached after traveling s units along the line, starting from start_point.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
start_point (tuple): Tuple of (x, y) representing the starting point on the line.
|
|
13
|
+
end_point (tuple): Tuple of (x, y) representing the ending point on the line.
|
|
14
|
+
distance (float): Distance to travel along the line, starting from start_point.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
tuple: Tuple of (x, y) representing the new point reached after traveling s units along the line.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
x1, y1 = start_node['x'], start_node['y']
|
|
21
|
+
x2, y2 = end_node['x'], end_node['y']
|
|
22
|
+
|
|
23
|
+
# Calculate the slope m and the y-intercept b of the line
|
|
24
|
+
if x1 == x2:
|
|
25
|
+
# Vertical line, distance is only along the y-axis
|
|
26
|
+
return (x1, y1 + distance if distance >= 0 else y1 - abs(distance))
|
|
27
|
+
else:
|
|
28
|
+
m = (y2 - y1) / (x2 - x1)
|
|
29
|
+
b = y1 - m * x1
|
|
30
|
+
|
|
31
|
+
# Calculate the direction vector (dx, dy) along the line
|
|
32
|
+
dx = (x2 - x1) / math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
|
|
33
|
+
dy = (y2 - y1) / math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
|
|
34
|
+
|
|
35
|
+
# Scale the direction vector by the given distance
|
|
36
|
+
scaled_dx = dx * distance
|
|
37
|
+
scaled_dy = dy * distance
|
|
38
|
+
|
|
39
|
+
# Calculate the new point's coordinates
|
|
40
|
+
x = x1 + scaled_dx
|
|
41
|
+
y = y1 + scaled_dy
|
|
42
|
+
|
|
43
|
+
return [x, y]
|
|
44
|
+
|
|
45
|
+
def get_keyindex_in_lane(nodes, distance, direction:str='front'):
|
|
46
|
+
temp_sum = 0
|
|
47
|
+
if direction == 'front':
|
|
48
|
+
# 顺道路方向前进
|
|
49
|
+
if distance == 0:
|
|
50
|
+
return [nodes[0]['x'], nodes[0]['y']]
|
|
51
|
+
key_index = 0 # first node
|
|
52
|
+
for i in range(1, len(nodes)):
|
|
53
|
+
x1, y1 = nodes[i-1]['x'], nodes[i-1]['y']
|
|
54
|
+
x2, y2 = nodes[i]['x'], nodes[i]['y']
|
|
55
|
+
temp_sum += math.sqrt((x2 - x1)**2 + (y2-y1)**2)
|
|
56
|
+
if temp_sum > distance:
|
|
57
|
+
remain_s = distance - (temp_sum - math.sqrt((x2 - x1)**2 + (y2-y1)**2))
|
|
58
|
+
break;
|
|
59
|
+
key_index += 1
|
|
60
|
+
else:
|
|
61
|
+
# 逆道路方向前进
|
|
62
|
+
if distance == 0:
|
|
63
|
+
return [nodes[-1]['x'], nodes[-1]['y']]
|
|
64
|
+
key_index = len(nodes)-1 # last node
|
|
65
|
+
for i in range(len(nodes)-1, 0, -1):
|
|
66
|
+
x1, y1 = nodes[i]['x'], nodes[i]['y']
|
|
67
|
+
x2, y2 = nodes[i-1]['x'], nodes[i-1]['y']
|
|
68
|
+
temp_sum += math.sqrt((x2 - x1)**2 + (y2-y1)**2)
|
|
69
|
+
if temp_sum > distance:
|
|
70
|
+
remain_s = distance - (temp_sum - math.sqrt((x2 - x1)**2 + (y2-y1)**2))
|
|
71
|
+
break;
|
|
72
|
+
key_index -= 1
|
|
73
|
+
return key_index
|
|
74
|
+
|
|
75
|
+
def get_xy_in_lane(nodes, distance, direction:str='front'):
|
|
76
|
+
temp_sum = 0
|
|
77
|
+
remain_s = 0
|
|
78
|
+
if direction == 'front':
|
|
79
|
+
# 顺道路方向前进
|
|
80
|
+
if distance == 0:
|
|
81
|
+
return [nodes[0]['x'], nodes[0]['y']]
|
|
82
|
+
key_index = 0 # first node
|
|
83
|
+
for i in range(1, len(nodes)):
|
|
84
|
+
x1, y1 = nodes[i-1]['x'], nodes[i-1]['y']
|
|
85
|
+
x2, y2 = nodes[i]['x'], nodes[i]['y']
|
|
86
|
+
temp_sum += math.sqrt((x2 - x1)**2 + (y2-y1)**2)
|
|
87
|
+
if temp_sum > distance:
|
|
88
|
+
remain_s = distance - (temp_sum - math.sqrt((x2 - x1)**2 + (y2-y1)**2))
|
|
89
|
+
break;
|
|
90
|
+
key_index += 1
|
|
91
|
+
if remain_s < 0.5:
|
|
92
|
+
return [nodes[key_index]['x'], nodes[key_index]['y']]
|
|
93
|
+
xy = point_on_line_given_distance(nodes[key_index], nodes[key_index+1], remain_s)
|
|
94
|
+
return xy
|
|
95
|
+
else:
|
|
96
|
+
# 逆道路方向前进
|
|
97
|
+
if distance == 0:
|
|
98
|
+
return [nodes[-1]['x'], nodes[-1]['y']]
|
|
99
|
+
key_index = len(nodes)-1 # last node
|
|
100
|
+
for i in range(len(nodes)-1, 0, -1):
|
|
101
|
+
x1, y1 = nodes[i]['x'], nodes[i]['y']
|
|
102
|
+
x2, y2 = nodes[i-1]['x'], nodes[i-1]['y']
|
|
103
|
+
temp_sum += math.sqrt((x2 - x1)**2 + (y2-y1)**2)
|
|
104
|
+
if temp_sum > distance:
|
|
105
|
+
remain_s = distance - (temp_sum - math.sqrt((x2 - x1)**2 + (y2-y1)**2))
|
|
106
|
+
break;
|
|
107
|
+
key_index -= 1
|
|
108
|
+
if remain_s < 0.5:
|
|
109
|
+
return [nodes[key_index]['x'], nodes[key_index]['y']]
|
|
110
|
+
xy = point_on_line_given_distance(nodes[key_index], nodes[key_index-1], remain_s)
|
|
111
|
+
return xy
|
|
112
|
+
|
|
113
|
+
def get_direction_by_s(nodes, distance, direction:str='front'):
|
|
114
|
+
temp_sum = 0
|
|
115
|
+
if direction == 'front':
|
|
116
|
+
# 顺道路方向前进
|
|
117
|
+
if distance == 0:
|
|
118
|
+
return [nodes[0]['x'], nodes[0]['y']]
|
|
119
|
+
key_index = 0 # first node
|
|
120
|
+
for i in range(1, len(nodes)):
|
|
121
|
+
x1, y1 = nodes[i-1]['x'], nodes[i-1]['y']
|
|
122
|
+
x2, y2 = nodes[i]['x'], nodes[i]['y']
|
|
123
|
+
temp_sum += math.sqrt((x2 - x1)**2 + (y2-y1)**2)
|
|
124
|
+
if temp_sum > distance:
|
|
125
|
+
break;
|
|
126
|
+
key_index += 1
|
|
127
|
+
if key_index == len(nodes)-1:
|
|
128
|
+
# 端点
|
|
129
|
+
x = nodes[key_index]['x']-nodes[key_index-1]['x']
|
|
130
|
+
y = nodes[key_index]['y']-nodes[key_index-1]['y']
|
|
131
|
+
return get_angle(x, y)
|
|
132
|
+
else:
|
|
133
|
+
# 中间点
|
|
134
|
+
x = nodes[key_index+1]['x'] - nodes[key_index]['x']
|
|
135
|
+
y = nodes[key_index+1]['y'] - nodes[key_index]['y']
|
|
136
|
+
return get_angle(x, y)
|
|
137
|
+
elif direction == 'back':
|
|
138
|
+
# 逆道路方向前进
|
|
139
|
+
if distance == 0:
|
|
140
|
+
return [nodes[-1]['x'], nodes[-1]['y']]
|
|
141
|
+
key_index = len(nodes)-1 # last node
|
|
142
|
+
for i in range(len(nodes)-1, 0, -1):
|
|
143
|
+
x1, y1 = nodes[i]['x'], nodes[i]['y']
|
|
144
|
+
x2, y2 = nodes[i-1]['x'], nodes[i-1]['y']
|
|
145
|
+
temp_sum += math.sqrt((x2 - x1)**2 + (y2-y1)**2)
|
|
146
|
+
if temp_sum > distance:
|
|
147
|
+
break;
|
|
148
|
+
key_index -= 1
|
|
149
|
+
if key_index == 0:
|
|
150
|
+
x = nodes[key_index]['x'] - nodes[key_index+1]['x']
|
|
151
|
+
y = nodes[key_index]['y'] - nodes[key_index+1]['y']
|
|
152
|
+
return get_angle(x, y)
|
|
153
|
+
else:
|
|
154
|
+
x = nodes[key_index-1]['x'] - nodes[key_index]['x']
|
|
155
|
+
y = nodes[key_index-1]['y'] - nodes[key_index]['y']
|
|
156
|
+
return get_angle(x, y)
|
|
157
|
+
else:
|
|
158
|
+
print("Warning: wroing direction, 'front' instead")
|
|
159
|
+
if distance == 0:
|
|
160
|
+
return [nodes[0]['x'], nodes[0]['y']]
|
|
161
|
+
key_index = 0 # first node
|
|
162
|
+
for i in range(1, len(nodes)):
|
|
163
|
+
x1, y1 = nodes[i-1]['x'], nodes[i-1]['y']
|
|
164
|
+
x2, y2 = nodes[i]['x'], nodes[i]['y']
|
|
165
|
+
temp_sum += math.sqrt((x2 - x1)**2 + (y2-y1)**2)
|
|
166
|
+
if temp_sum > distance:
|
|
167
|
+
break;
|
|
168
|
+
key_index += 1
|
|
169
|
+
if key_index == len(nodes)-1:
|
|
170
|
+
# 端点
|
|
171
|
+
x = nodes[key_index]['x']-nodes[key_index-1]['x']
|
|
172
|
+
y = nodes[key_index]['y']-nodes[key_index-1]['y']
|
|
173
|
+
return get_angle(x, y)
|
|
174
|
+
else:
|
|
175
|
+
# 中间点
|
|
176
|
+
x = nodes[key_index+1]['x'] - nodes[key_index]['x']
|
|
177
|
+
y = nodes[key_index+1]['y'] - nodes[key_index]['y']
|
|
178
|
+
return get_angle(x, y)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pycityagent
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.11
|
|
4
4
|
Summary: LLM-based城市模拟器agent构建库
|
|
5
5
|
Author-email: Yuwei Yan <pinkgranite86@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -34,16 +34,16 @@ Classifier: Operating System :: OS Independent
|
|
|
34
34
|
Requires-Python: >=3.8
|
|
35
35
|
Description-Content-Type: text/markdown
|
|
36
36
|
License-File: LICENSE
|
|
37
|
-
Requires-Dist: dashscope
|
|
38
|
-
Requires-Dist: geojson
|
|
39
|
-
Requires-Dist: numpy
|
|
40
|
-
Requires-Dist: openai
|
|
41
|
-
Requires-Dist: Pillow
|
|
42
|
-
Requires-Dist: pycitysim
|
|
43
|
-
Requires-Dist: citystreetview
|
|
44
|
-
Requires-Dist: PyYAML
|
|
45
|
-
Requires-Dist: Requests
|
|
46
|
-
Requires-Dist: transitions
|
|
37
|
+
Requires-Dist: dashscope>=1.14.0
|
|
38
|
+
Requires-Dist: geojson>=3.1.0
|
|
39
|
+
Requires-Dist: numpy>=1.26.3
|
|
40
|
+
Requires-Dist: openai>=1.8.0
|
|
41
|
+
Requires-Dist: Pillow>=10.2.0
|
|
42
|
+
Requires-Dist: pycitysim>=1.12.2
|
|
43
|
+
Requires-Dist: citystreetview>=1.1.0
|
|
44
|
+
Requires-Dist: PyYAML>=6.0.1
|
|
45
|
+
Requires-Dist: Requests>=2.31.0
|
|
46
|
+
Requires-Dist: transitions>=0.9.0
|
|
47
47
|
|
|
48
48
|
# Pycityagent
|
|
49
49
|
|
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
pycityagent/__init__.py,sha256=
|
|
2
|
-
pycityagent/agent.py,sha256=
|
|
3
|
-
pycityagent/agent_citizen.py,sha256=
|
|
4
|
-
pycityagent/agent_func.py,sha256=
|
|
5
|
-
pycityagent/
|
|
6
|
-
pycityagent/
|
|
1
|
+
pycityagent/__init__.py,sha256=Sod9d8kCbUtmiLbuQDly0PVrycvrG4vly05ZmmTRAJc,284
|
|
2
|
+
pycityagent/agent.py,sha256=cLUXPAx4RJ6LDZZ-9sY1XDZ4uKG6rn3rdfV15H9Flpk,8814
|
|
3
|
+
pycityagent/agent_citizen.py,sha256=TigLZHHompzcbhdd4sbpH9AaDDmC3IDWg3Uwaxv67No,5631
|
|
4
|
+
pycityagent/agent_func.py,sha256=C9OCiMdiuP3CW0RQ8G37zkUl7ULS5HxGYoh0SzNWzqY,8901
|
|
5
|
+
pycityagent/agent_group.py,sha256=Te4eOvZBYqHF33HhAw6gtiXGrtnYdv7wcKEk9Vdx7lE,2771
|
|
6
|
+
pycityagent/simulator.py,sha256=gcTetyMh4HX4X-pmP6E7kOKWdIHT5I_MkfMPq5EvzwI,11711
|
|
7
|
+
pycityagent/utils.py,sha256=bOPURrDOZGryZ-h09SPp1hML2_6cvMy-z2DscYlWZ1g,7111
|
|
8
|
+
pycityagent/ac/__init__.py,sha256=v6QqrWtw11f1NbPifcGyTPI6wpPmn-S3zG0bMdWUWdc,314
|
|
7
9
|
pycityagent/ac/ac.py,sha256=K4LNrGOxGLH5_WOWCu9yZavbZdFAnzmAYA8rkz6kwjk,2267
|
|
8
10
|
pycityagent/ac/action.py,sha256=82HUiQzOCr1vE91ooq9ETWBvy_dapywNAiZXu0eMLa8,2095
|
|
9
11
|
pycityagent/ac/action_stream.py,sha256=cUqLWBVbluIhuvTVi6kh2GWXuE1tHERRRa29OtvMchA,783
|
|
10
|
-
pycityagent/ac/hub_actions.py,sha256=
|
|
12
|
+
pycityagent/ac/hub_actions.py,sha256=9GACIlPavA1V3it9dD-0ks2QnJyXjBxPcsx77PJ6xlo,14658
|
|
11
13
|
pycityagent/ac/sim_actions.py,sha256=01M8ceSCSNKW5PwqJpvqVB2gAi0I1cvHqVAbbA9IEsk,3880
|
|
12
14
|
pycityagent/ac/citizen_actions/controled.py,sha256=co0YG7QMMpX-tpbbW_MasoPGm4RzDxkj3IkXFnsuxss,718
|
|
13
15
|
pycityagent/ac/citizen_actions/converse.py,sha256=ocMFvw-_sOUJmucgQjI87NNTZT9dj9svloiiU2zWDBE,1431
|
|
14
16
|
pycityagent/ac/citizen_actions/idle.py,sha256=zrKx8k6-YyT-4i-ZE8BuhsOJIJmCYGEO1WpUaPxWVWw,683
|
|
15
17
|
pycityagent/ac/citizen_actions/shop.py,sha256=lhrVelTVWF_9oAENStcX2YBgz6-fQaK3hL1OL9cl8uY,4273
|
|
16
|
-
pycityagent/ac/citizen_actions/trip.py,sha256=
|
|
18
|
+
pycityagent/ac/citizen_actions/trip.py,sha256=MyvYFd4_EgIdHmsBpUT9fa-YNrY8GTZaLwrLPDPKODM,1769
|
|
17
19
|
pycityagent/brain/__init__.py,sha256=9K8nPU-xoAyN--1eRdttRUyf-Swu5MXSmEzdSSJj6YM,359
|
|
18
|
-
pycityagent/brain/brain.py,sha256=
|
|
20
|
+
pycityagent/brain/brain.py,sha256=UtV7wgBEb_QR5xg863utUQ1QWQZ1RlRyw07tQHEGDr4,1088
|
|
19
21
|
pycityagent/brain/brainfc.py,sha256=E1N9Kdjjmo7S_kgvv8pr_gFDbQvRmXxEn1BVn85hd1s,280
|
|
20
|
-
pycityagent/brain/memory.py,sha256=
|
|
21
|
-
pycityagent/brain/scheduler.py,sha256=
|
|
22
|
-
pycityagent/brain/sence.py,sha256=
|
|
22
|
+
pycityagent/brain/memory.py,sha256=Blqm6Wwyy4EmzsQLrluKMJ-Wni_GfNViZRKwY7dqGv4,22097
|
|
23
|
+
pycityagent/brain/scheduler.py,sha256=FS9IBQg0rJWJucS12OJhhObCxZAzrrfzFyFHjhOknHk,18625
|
|
24
|
+
pycityagent/brain/sence.py,sha256=qYnwQ3xQxBL_E7WzO3Za1pPwcaXxOnqUYDNow22ILtk,26365
|
|
23
25
|
pycityagent/brain/static.py,sha256=fdBjHKacNiDCKhvQkc9WgEYYSO0peMC5lb8CcXl9iNc,29101
|
|
24
26
|
pycityagent/brain/persistence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
27
|
pycityagent/brain/persistence/social.py,sha256=6hJi14sFm4LOU1JlnX8Vq_jFv7VII1uHDM9lrt7-JDA,27
|
|
@@ -38,16 +40,16 @@ pycityagent/cc/idle.py,sha256=RbqwG4BdSpLdZ-_13mLMbUs20q8r5drKB4wNIGWPOZw,474
|
|
|
38
40
|
pycityagent/cc/shop.py,sha256=9c8XTcUZBV90N_0MF3Gi9jlUS0LqNR3vIazEkK8tA28,149
|
|
39
41
|
pycityagent/cc/trip.py,sha256=ayTUnED7Kq6qiwEfCO_u-Hz6rRFNzBI25dZGUSV5dJY,312
|
|
40
42
|
pycityagent/cc/user.py,sha256=nS9NFfZypvXf-vLzqnYzLc6ek-CS8WALtEb00s1nREI,285
|
|
41
|
-
pycityagent/hubconnector/__init__.py,sha256=
|
|
42
|
-
pycityagent/hubconnector/hubconnector.py,sha256
|
|
43
|
+
pycityagent/hubconnector/__init__.py,sha256=agM9SRqOZUpG6L3VkALOMj02lzyWwzHzrnaQkodVyes,86
|
|
44
|
+
pycityagent/hubconnector/hubconnector.py,sha256=-OULEn4v0Ce0nkzqxa4Msurvr6pCK_7CN1DBUMVzags,16483
|
|
43
45
|
pycityagent/image/__init__.py,sha256=u_kDcScyo66FQs98aXo64h-aNBC1YqdEgB7hMhXtU2E,101
|
|
44
46
|
pycityagent/image/image.py,sha256=ymOkow9rvWQ7oq4rynVFmHEPqp0BbxMRJLmkRX1nVyA,5501
|
|
45
47
|
pycityagent/st/__init__.py,sha256=LN9UMUUI_tZKAW-cUHszpRA8MjP4KL3RM0YQJY1ugVs,108
|
|
46
48
|
pycityagent/st/st.py,sha256=PxNsy_BEZng2mOETKCK0ira98p4LjGluM17W3QZ_9Xw,5210
|
|
47
49
|
pycityagent/urbanllm/__init__.py,sha256=ew7bS1-jaRf_MDTkDxvTup9a9-9FLqL0SLoloxrNDkU,85
|
|
48
|
-
pycityagent/urbanllm/urbanllm.py,sha256=
|
|
49
|
-
pycityagent-1.1.
|
|
50
|
-
pycityagent-1.1.
|
|
51
|
-
pycityagent-1.1.
|
|
52
|
-
pycityagent-1.1.
|
|
53
|
-
pycityagent-1.1.
|
|
50
|
+
pycityagent/urbanllm/urbanllm.py,sha256=q5-1xoLtrBHiN8_1KG5M_eqD9hgx9WllOZrqFrZsOPM,21113
|
|
51
|
+
pycityagent-1.1.11.dist-info/LICENSE,sha256=Yo9QmwLDFU3VoOc0W8aYSCa5Yj5sJyqM3FEcbC2jMQQ,1063
|
|
52
|
+
pycityagent-1.1.11.dist-info/METADATA,sha256=cJcCGFUyDMcSyASYua01LjYHJtTbWLNDaxn1QeMMPOA,8240
|
|
53
|
+
pycityagent-1.1.11.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
54
|
+
pycityagent-1.1.11.dist-info/top_level.txt,sha256=mf70CsOn3eVJBwHQ_TjCesoc-elD0Bj2WLsi5APRjlU,12
|
|
55
|
+
pycityagent-1.1.11.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|