Skip to content

Commit

Permalink
feat(io): agent can now be duplicated using 'duplicates' attribute (#87)
Browse files Browse the repository at this point in the history
See new entry in Agent schema.
Duplicated agent ids are generated using the original id and the duplicate index.
  • Loading branch information
leo-desbureaux-tellae authored Nov 14, 2023
1 parent 2bff43e commit c13481a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
6 changes: 6 additions & 0 deletions starling_sim/basemodel/agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ class Agent(Traced):
"description": "Road network used by the agent",
},
"icon": {"type": "string", "title": "Agent icon", "description": "Display icon"},
"duplicates": {
"title": "Agent duplicates",
"description": "Generate duplicates of this agent",
"type": "integer",
"minimum": 1
}
},
"required": ["agent_id", "agent_type", "mode", "icon"],
}
Expand Down
35 changes: 33 additions & 2 deletions starling_sim/basemodel/input/dynamic_input.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import copy

from starling_sim.basemodel.trace.trace import Traced
from starling_sim.basemodel.trace.events import InputEvent
from starling_sim.basemodel.agent.operators.operator import Operator
Expand All @@ -21,6 +23,8 @@ class DynamicInput(Traced):
dynamically adds agents in the environment during the simulation.
"""

DUPLICATE_AGENT_ID_FORMAT = "{original_id}.{index}"

def __init__(self, agent_type_dict):
super().__init__("INPUT")

Expand Down Expand Up @@ -160,13 +164,40 @@ def new_agent_input(self, feature):
"""
Create and initialise a new agent, and add it to the simulation environment.
:param feature:
:return:
:param feature: agent feature (GeoJSON Feature)
:return: created agent or list of agents in case of "duplicates"
"""

# get the agent input dict
input_dict = feature["properties"]

# if 'duplicates', run new_agent_input recursively on duplicated features and return a list of new agents
if "duplicates" in input_dict:
new_agents = []
nb_duplicates = input_dict["duplicates"]
# check agent properties
assert (
isinstance(nb_duplicates, int) and nb_duplicates > 0
), "'duplicates' attribute must be a strictly positive integer"
assert "agent_id" in input_dict, "Duplicated agent misses agent_id attribute"

# create a new agent feature for each duplicate
for i in range(nb_duplicates):
duplicated_feature = copy.deepcopy(feature)
del duplicated_feature["properties"]["duplicates"]
# create a new id using the original agent id and the duplicate index
duplicated_feature["properties"][
"agent_id"
] = self.DUPLICATE_AGENT_ID_FORMAT.format(
original_id=input_dict["agent_id"], index=i
)

new_agents.append(self.new_agent_input(duplicated_feature))

# return a list of agents instead of a single object
return new_agents

if "operator_id" in input_dict:
# link with operator
self.add_key_operator(input_dict)
Expand Down

0 comments on commit c13481a

Please sign in to comment.