pycityagent 1.0.0__py3-none-any.whl → 1.1.1__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/agent.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Optional, Union
2
+ from typing import Optional, Union, Callable
3
3
  import PIL.Image as Image
4
4
  from PIL.Image import Image
5
5
  import asyncio
@@ -10,22 +10,30 @@ from pycityagent.urbanllm import UrbanLLM
10
10
  from .urbanllm import UrbanLLM
11
11
  from .brain.brain import Brain
12
12
  from .hubconnector.hubconnector import HubConnector
13
- from .image.image import AgentImage
14
- from .ac.ac import ActionController
15
- from .cc.cc import CommondController
16
- from .st.st import StateTransformer
13
+ from .ac import ActionController
14
+ from .cc import CommandController
15
+ from .st import StateTransformer
17
16
 
17
+ class AgentType:
18
+ """
19
+ Agent类型
20
+
21
+ - Citizen = 1, 指城市居民类型agent——行动受城市规则限制
22
+ - Func = 2, 功能型agent——行动规则宽松——本质上模拟器无法感知到Func类型的agent
23
+ """
24
+ Citizen = 1
25
+ Func = 2
18
26
 
19
27
  class Template:
20
28
  """
21
29
  The basic template of Agent
22
30
  """
23
- def __init__(self, name, server, soul:UrbanLLM=None, simulator=None, id:int=None) -> None:
24
- self.agent_name = name
31
+ def __init__(self, name, server, type:AgentType, soul:UrbanLLM=None, simulator=None) -> None:
32
+ self._name = name
25
33
  self._client = CityClient(server)
34
+ self._type = type
26
35
  self._soul = soul
27
36
  self._simulator = simulator
28
- self._id = id
29
37
 
30
38
  def add_soul(self, llm_engine:UrbanLLM):
31
39
  """
@@ -59,69 +67,46 @@ class Agent(Template):
59
67
  self,
60
68
  name:str,
61
69
  server:str,
70
+ type:AgentType,
62
71
  soul:UrbanLLM=None,
63
- simulator=None,
64
- id:int=None,
65
- base=None,
66
- motion=None,
67
- scratch_file:str=None,
68
- selfie:bool = False,
69
- connect_to_hub:bool=False,
70
- hub_url:str=None,
71
- app_id:int=None,
72
- app_secret:str=None,
73
- profile_img:str=None
72
+ simulator=None
74
73
  ) -> None:
75
- super().__init__(name, server, soul, simulator, id)
76
- self.base = base
77
- """
78
- Agent/Person的基本属性, Agent指被代理的Person, Person指模拟器中的背景人
79
- The base attributes of Agent/Person. Agent is the Person being represented. Persons are background persons in simulator
80
- - https://cityproto.sim.fiblab.net/#city.agent.v2.Agent
81
- """
82
- self.motion = motion
83
- """
84
- Agent/Person的运动信息
85
- The motion information of Agent/Person
86
- - https://cityproto.sim.fiblab.net/#city.agent.v2.AgentMotion
87
- """
88
- if connect_to_hub:
89
- self._hub_connector = HubConnector(
90
- hub_url=hub_url,
91
- app_id=app_id,
92
- app_secret=app_secret,
93
- agent=self,
94
- profile_img=profile_img
95
- )
96
- else:
97
- self._hub_connector = None
98
- self._image = AgentImage(self, scratch_file, selfie)
74
+ super().__init__(name, server, type, soul, simulator)
75
+
76
+ self._hub_connector = None
99
77
  """
100
- Agent画像
101
- The Agent's Image
78
+ HubConnector: 用于和AppHub对接——可以通过Agent.connectToHub进行绑定
79
+ HubConnector: the connection between agent and AppHub, you can use 'Agent.connectToHub' to create the connection
102
80
  """
81
+
103
82
  self._brain = Brain(self)
104
83
  """
105
84
  Agent的大脑
106
85
  The Agent's Brain
107
86
  """
108
- self._ac = ActionController(self)
109
- """
110
- Agent的行为控制器
111
- The Agent's ActionController
112
- """
113
- self._cc = CommondController(self)
87
+
88
+ self._cc = CommandController(self)
114
89
  """
115
90
  Agent的命令控制器
116
91
  The Agent's CommondController
117
92
  """
93
+
118
94
  self._st = StateTransformer()
119
95
  """
120
96
  与Agent关联的状态转移器
121
97
  The related StateTransformer
122
98
  """
123
- # * 默认trip构建
124
- self.Scheduler.schedule_init()
99
+
100
+ self._ac = ActionController(self)
101
+ """
102
+ Agent的行为控制器
103
+ The Agent's ActionController
104
+ """
105
+
106
+ self._step_with_action = True
107
+ """
108
+ Step函数是否包含action执行 —— 当有自定义action需求(特指包含没有指定source的Action)时可置该选项为False并通过自定义方法执行action操作
109
+ """
125
110
 
126
111
  def ConnectToHub(self, config:dict):
127
112
  """
@@ -141,6 +126,31 @@ class Agent(Template):
141
126
  agent=self,
142
127
  profile_img=profile_img
143
128
  )
129
+
130
+ def set_streetview_config(self, config:dict):
131
+ """
132
+ 街景感知配置
133
+ - engine: baidumap / googlemap
134
+ - mapAK: your baidumap AK (if baidumap)
135
+ - proxy: your googlemap proxy (if googlemap, optional)
136
+ """
137
+ if 'engine' in config:
138
+ if config['engine'] == 'baidumap':
139
+ self.Brain.Sence._engine = config['engine']
140
+ if 'mapAK' in config:
141
+ self.Brain.Sence._baiduAK = config['mapAK']
142
+ else:
143
+ print("ERROR: Please Provide a baidumap AK")
144
+ elif config['engine'] == 'googlemap':
145
+ self.Brain.Sence._engine = config['engine']
146
+ if 'proxy' in config:
147
+ self.Brain.Sence._googleProxy = config['proxy']
148
+ else:
149
+ print("ERROR: Please provide a googlemap proxy")
150
+ else:
151
+ print("ERROR: Wrong engine, only baidumap / googlemap are available")
152
+ else:
153
+ print("ERROR: Please provide a streetview engine, baidumap / googlemap")
144
154
 
145
155
  def enable_streetview(self):
146
156
  """
@@ -170,51 +180,36 @@ class Agent(Template):
170
180
  """
171
181
  self._brain.Memory.Working.enable_user_interaction = False
172
182
 
173
- def enable_economy_behavior(self):
174
- """
175
- 开启经济模拟相关功能(例如购物)
176
- Enable Economy function. Shopping for instance.
183
+ def set_step_with_action(self, flag:bool = None):
177
184
  """
178
- self.Brain.Memory.Working.enable_economy = True
179
-
180
- def disable_economy_behavior(self):
185
+ 默认情况置反step_with_action属性: 即True->False, False->True
186
+ 否则根据传入的flag进行设置
181
187
  """
182
- 关闭经济模拟相关功能
183
- Disable Economy function
184
- """
185
- self.Brain.Memory.Working.enable_economy = False
186
-
187
- def enable_social_behavior(self):
188
- """
189
- 开启社交相关功能
190
- Enable Social function
191
- """
192
- self.Brain.Memory.Working.enable_social = True
193
-
194
- def diable_social_behavior(self):
195
- """
196
- 关闭社交相关功能
197
- Disable Social function
198
- """
199
- self.Brain.Memory.Working.enable_social = False
200
-
201
- async def Pause(self):
202
- """
203
- 暂停Agent行为使Agent进入'pause'状态
204
- Pause the Agent, making the agent 'pause'
188
+ if flag != None:
189
+ self._step_with_action = flag
190
+ else:
191
+ self._step_with_action = not self._step_with_action
192
+
205
193
 
206
- """
207
- req = {'person_id': self.base['id'], 'schedules': []}
208
- await self._client.person_service.SetSchedule(req)
209
- self.Scheduler.unset_schedule()
210
- self._st.trigger('pause')
194
+ def sence_config(self, sence_content:Optional[list]=None, sence_radius:int=None):
195
+ '''
196
+ 感知配置
211
197
 
212
- async def Active(self):
213
- """
214
- 恢复Agent行为
215
- Recover from 'pause'
216
- """
217
- self._st.pause_back()
198
+ Args:
199
+ - config: 配置选项——包含需要感知的数据类型
200
+ - time: 时间
201
+ - poi: 感兴趣地点
202
+ - position: 可达地点
203
+ - lane: 周围道路
204
+ - person: 周围活动person
205
+ - streetview: 街景
206
+ - user_message: 用户交互信息
207
+ - agent_message: 智能体交互信息
208
+ '''
209
+ if sence_content != None:
210
+ self._brain._sence.set_sence(sence_content)
211
+ if sence_radius != None:
212
+ self._brain._sence.set_sence_radius(sence_radius)
218
213
 
219
214
  async def Run(self, round:int=1, interval:int=1, log:bool=True):
220
215
  """
@@ -238,49 +233,8 @@ class Agent(Template):
238
233
  单步Agent执行流
239
234
  Single step entrance
240
235
  (Not recommended, use Run() method)
241
-
242
- Args:
243
- - log (bool): 是否输出log信息. Whether console log message
244
- """
245
- if self.state != 'paused':
246
- # * 1. 模拟器时间更新
247
- await self._simulator.GetTime()
248
- # * 2. 拉取Agent最新状态
249
- resp = await self._client.person_service.GetPerson({'person_id':self._id})
250
- self.base = resp['base']
251
- self.motion = resp['motion']
252
- # * 3. Brain工作流
253
- await self._brain.Run()
254
- # * 4. Commond Controller工作流
255
- commond = await self._cc.Run()
256
- # * 5. State Transformer工作流
257
- self._st.trigger(commond)
258
- # * 6. Action Controller工作流
259
- await self._ac.Run()
260
- if log:
261
- print(f"---------------------- SIM TIME: {self._simulator.time} ----------------------")
262
- self.show_yourself()
263
-
264
- def show_yourself(self):
265
- """
266
- Log信息输出
267
- Pring log message
268
236
  """
269
- print(f"【State Message】: {self.state}")
270
- motion_message = ''''''
271
- motion_message += f'''行为状态: {self.motion['status']}, '''
272
- if 'lane_position' in self.motion['position'].keys():
273
- motion_message += f'''位置信息: lane-{self.motion['position']['lane_position']['lane_id']}'''
274
- else:
275
- motion_message += f'''位置信息: aoi-{self.motion['position']['aoi_position']['aoi_id']}'''
276
- motion_message += f'''-[x: {self.motion['position']['xy_position']['x']}, y: {self.motion['position']['xy_position']['y']}]'''
277
- print(f'【Simulator Motion Message】: \n{motion_message}')
278
- print(self.Scheduler)
279
-
280
- @property
281
- def Image(self):
282
- """The Agent's Image"""
283
- return self._image
237
+ pass
284
238
 
285
239
  @property
286
240
  def Soul(self):
@@ -296,16 +250,11 @@ class Agent(Template):
296
250
  def ActionController(self):
297
251
  """The Agents's ActionController"""
298
252
  return self._ac
299
-
300
- @property
301
- def Scheduler(self):
302
- """The Agent's Scheduler"""
303
- return self._brain.Memory.Working.scheduler
304
253
 
305
254
  @property
306
255
  def state(self):
307
256
  """The state of the Agent"""
308
- return self._st.state
257
+ return self._st.machine.state
309
258
 
310
259
  @property
311
260
  def StateTransformer(self):
@@ -315,4 +264,9 @@ class Agent(Template):
315
264
  @property
316
265
  def Hub(self):
317
266
  """The connected AppHub"""
318
- return self._hub_connector
267
+ return self._hub_connector
268
+
269
+ @property
270
+ def CommandController(self):
271
+ """The command controller"""
272
+ return self._cc
@@ -0,0 +1,158 @@
1
+ from pycityagent.urbanllm import UrbanLLM
2
+ from .urbanllm import UrbanLLM
3
+ from .agent import Agent, AgentType
4
+ from .image.image import CitizenImage
5
+
6
+ class CitizenAgent(Agent):
7
+ """
8
+ Citizen Agent
9
+ 城市居民智能体
10
+ """
11
+
12
+ def __init__(
13
+ self,
14
+ name:str,
15
+ server:str,
16
+ id:int,
17
+ soul:UrbanLLM=None,
18
+ simulator=None,
19
+ base=None,
20
+ motion=None
21
+ ) -> None:
22
+ super().__init__(name, server, AgentType.Citizen, soul, simulator)
23
+ self._id = id
24
+ self.base = base
25
+ """
26
+ Agent/Person的基本属性, Agent指被代理的Person, Person指模拟器中的背景人
27
+ The base attributes of Agent/Person. Agent is the Person being represented. Persons are background persons in simulator
28
+ - https://cityproto.sim.fiblab.net/#city.agent.v2.Agent
29
+ """
30
+ self.motion = motion
31
+ """
32
+ Agent/Person的运动信息
33
+ The motion information of Agent/Person
34
+ - https://cityproto.sim.fiblab.net/#city.agent.v2.AgentMotion
35
+ """
36
+
37
+ self._image = CitizenImage(self)
38
+ """
39
+ Agent画像
40
+ The Agent's Image
41
+ """
42
+
43
+ self.Scheduler.schedule_init()
44
+ """
45
+ 行程初始化
46
+ """
47
+
48
+ def Bind(self):
49
+ """
50
+ 将智能体绑定到AppHub
51
+ Bind Agent with AppHub
52
+ """
53
+ if self._hub_connector == None:
54
+ print("ERROR: connect with apphub first")
55
+ else:
56
+ self._hub_connector.BindCitizenAgent()
57
+
58
+
59
+ def enable_economy_behavior(self):
60
+ """
61
+ 开启经济模拟相关功能(例如购物)
62
+ Enable Economy function. Shopping for instance.
63
+ """
64
+ self.Brain.Memory.Working.enable_economy = True
65
+
66
+ def disable_economy_behavior(self):
67
+ """
68
+ 关闭经济模拟相关功能
69
+ Disable Economy function
70
+ """
71
+ self.Brain.Memory.Working.enable_economy = False
72
+
73
+ def enable_social_behavior(self):
74
+ """
75
+ 开启社交相关功能
76
+ Enable Social function
77
+ """
78
+ self.Brain.Memory.Working.enable_social = True
79
+
80
+ def diable_social_behavior(self):
81
+ """
82
+ 关闭社交相关功能
83
+ Disable Social function
84
+ """
85
+ self.Brain.Memory.Working.enable_social = False
86
+
87
+ async def Pause(self):
88
+ """
89
+ 暂停Agent行为使Agent进入'pause'状态
90
+ Pause the Agent, making the agent 'pause'
91
+
92
+ """
93
+ req = {'person_id': self.base['id'], 'schedules': []}
94
+ await self._client.person_service.SetSchedule(req)
95
+ self.Scheduler.unset_schedule()
96
+ self._st.trigger('pause')
97
+
98
+ async def Active(self):
99
+ """
100
+ 恢复Agent行为
101
+ Recover from 'pause'
102
+ """
103
+ self._st.pause_back()
104
+
105
+ async def Step(self, log:bool):
106
+ """
107
+ 单步Agent执行流
108
+ Single step entrance
109
+ (Not recommended, use Run() method)
110
+
111
+ Args:
112
+ - log (bool): 是否输出log信息. Whether console log message
113
+ """
114
+ if self.state != 'paused':
115
+ # * 1. 模拟器时间更新
116
+ await self._simulator.GetTime()
117
+ # * 2. 拉取Agent最新状态
118
+ resp = await self._client.person_service.GetPerson({'person_id':self._id})
119
+ self.base = resp['base']
120
+ self.motion = resp['motion']
121
+ # * 3. Brain工作流
122
+ await self._brain.Run()
123
+ # * 4. Commond Controller工作流
124
+ commond = await self._cc.Run()
125
+ # * 5. State Transformer工作流
126
+ self._st.trigger(commond)
127
+ # * 6. Action Controller工作流
128
+ if self._step_with_action:
129
+ await self._ac.Run()
130
+ if log:
131
+ print(f"---------------------- SIM TIME: {self._simulator.time} ----------------------")
132
+ self.show_yourself()
133
+
134
+ def show_yourself(self):
135
+ """
136
+ Log信息输出
137
+ Pring log message
138
+ """
139
+ print(f"【State Message】: {self.state}")
140
+ motion_message = ''''''
141
+ motion_message += f'''行为状态: {self.motion['status']}, '''
142
+ if 'lane_position' in self.motion['position'].keys():
143
+ motion_message += f'''位置信息: lane-{self.motion['position']['lane_position']['lane_id']}'''
144
+ else:
145
+ motion_message += f'''位置信息: aoi-{self.motion['position']['aoi_position']['aoi_id']}'''
146
+ motion_message += f'''-[x: {self.motion['position']['xy_position']['x']}, y: {self.motion['position']['xy_position']['y']}]'''
147
+ print(f'【Simulator Motion Message】: \n{motion_message}')
148
+ print(self.Scheduler)
149
+
150
+ @property
151
+ def Image(self):
152
+ """The Agent's Image"""
153
+ return self._image
154
+
155
+ @property
156
+ def Scheduler(self):
157
+ """The Agent's Scheduler"""
158
+ return self._brain.Memory.Working.scheduler
@@ -0,0 +1,115 @@
1
+ from pycityagent.urbanllm import UrbanLLM
2
+ from .urbanllm import UrbanLLM
3
+ from .agent import Agent, AgentType
4
+ from .image.image import Image
5
+ from .ac.hub_actions import PositionUpdate
6
+
7
+ class FuncAgent(Agent):
8
+ """
9
+ Fuctional Agent
10
+ 功能型Agent
11
+ """
12
+
13
+ def __init__(
14
+ self,
15
+ name:str,
16
+ id: int,
17
+ server:str,
18
+ soul:UrbanLLM=None,
19
+ simulator=None,
20
+ ) -> None:
21
+ super().__init__(name, server, AgentType.Func, soul, simulator)
22
+ self._id = id
23
+ self._image = Image(self)
24
+ """
25
+ Func Agent画像——支持自定义内容
26
+ """
27
+
28
+ self.motion = {'id': id, 'position': {}, 'direction': 0}
29
+ """
30
+ Func Agent状态信息——与agent的sence高度相关
31
+ - id (int): 即agent id
32
+ - position (https://cityproto.sim.fiblab.net/#city.geo.v2.Position): 即agent当前的位置描述信息
33
+ - lane_position (dict): 当position中包含该key时表示agent当前位于lane上——与aoi_position不可同时存在
34
+ - lane_id (int)
35
+ - s (double)
36
+ - aoi_position (dict): 当position中包含该key时表示agent当前位于aoi中——与lane_position不可同时存在
37
+ - aoi_id (int)
38
+ - poi_id (optional[int])
39
+ - longlat_position (dict): WGS84经纬度坐标位置
40
+ - longitude (double): 经度
41
+ - latitude (double): 纬度
42
+ - z (optional[double]): 高程信息
43
+ - xy_position (dict): 坐标系表示的位置
44
+ - x (double)
45
+ - y (double)
46
+ - z (double)
47
+ - direction (double): 方向角
48
+ """
49
+
50
+ async def init_position_aoi(self, aoi_id:int):
51
+ """
52
+ 将agent的位置初始化到指定aoi
53
+ 根据指定aoi设置aoi_position, longlat_position以及xy_position
54
+ """
55
+ if aoi_id in self._simulator.map.aois:
56
+ aoi = self._simulator.map.aois[aoi_id]
57
+ self.motion['position']['aoi_position'] = {'aoi_id': aoi_id}
58
+ self.motion['position']['longlat_position'] = {'longitude': aoi['shapely_lnglat'].centroid.coords[0][0], 'latitude': aoi['shapely_lnglat'].centroid.coords[0][1]}
59
+ x, y = self._simulator.map.lnglat2xy(lng=self.motion['position']['longlat_position']['longitude'],
60
+ lat=self.motion['position']['longlat_position']['latitude'])
61
+ self.motion['position']['xy_position'] = {'x': x, 'y': y}
62
+ pos = PositionUpdate(self)
63
+ await pos.Forward(longlat=[self.motion['position']['longlat_position']['longitude'], self.motion['position']['longlat_position']['latitude']])
64
+
65
+ def Bind(self):
66
+ """
67
+ 将智能体绑定到AppHub
68
+ Bind the Agent with AppHub
69
+ """
70
+ if self._hub_connector == None:
71
+ print("ERROR: connect with apphub first")
72
+ else:
73
+ self._hub_connector.InsertFuncAgent()
74
+
75
+ def set_image(self, image: Image):
76
+ """
77
+ 设置image——支持自由扩展Image
78
+ """
79
+ self._image = image
80
+
81
+ async def Step(self, log:bool):
82
+ """
83
+ 单步Agent执行流
84
+ Single step entrance
85
+ (Not recommended, use Run() method)
86
+
87
+ Args:
88
+ - log (bool): 是否输出log信息. Whether console log message
89
+ """
90
+ # * 1. 模拟器时间更新
91
+ await self._simulator.GetTime()
92
+ # * 2. Brain工作流
93
+ await self._brain.Run()
94
+ # * 3. Commond Controller工作流
95
+ command = await self._cc.Run()
96
+ # * 4. State Transformer工作流
97
+ self._st.trigger(command)
98
+ # * 5. Action Controller工作流
99
+ if self._step_with_action:
100
+ await self._ac.Run()
101
+ if log:
102
+ print(f"---------------------- SIM TIME: {self._simulator.time} ----------------------")
103
+ self.show_yourself()
104
+
105
+ def show_yourself(self):
106
+ """
107
+ Log信息输出
108
+ Pring log message
109
+ """
110
+ pass
111
+
112
+ @property
113
+ def Image(self):
114
+ """The Agent's Image"""
115
+ return self._image
@@ -7,4 +7,4 @@ from .scheduler import *
7
7
  from .sence import *
8
8
  from .static import *
9
9
 
10
- __all__ = [Brain, BrainFunction, MemoryController, Memory, MemoryPersistence, MemoryRetrive, MemoryReason, MemoryType, ScheduleType, Scheduler, Sence, SencePlug, POI_TYPE_DICT]
10
+ __all__ = [Brain, BrainFunction, MemoryController, Memory, WorkingMemory, LTMemory, MemoryPersistence, MemoryRetrive, MemoryReason, MemoryType, ScheduleType, Scheduler, Sence, SencePlug, POI_TYPE_DICT]