19 package org.matsim.core.mobsim.hermes;
21 import org.apache.logging.log4j.LogManager;
22 import org.apache.logging.log4j.Logger;
38 import java.util.ArrayDeque;
39 import java.util.ArrayList;
42 private final ScenarioImporter si;
45 private final HLink[] links;
48 private final ArrayList<ArrayDeque<HLink>> delayedLinksByWakeupTime;
50 private final ArrayList<ArrayDeque<Agent>> delayedAgentsByWakeupTime;
53 private final IdMap<TransitStopFacility, IntArrayMap<ArrayDeque<Agent>>> agent_stops;
55 protected int[][] route_stops_by_route_no;
57 private final int[] line_of_route;
59 private EventArray sortedEvents;
61 private final EventsManager eventsManager;
64 Logger log = LogManager.getLogger(Realm.class);
66 public Realm(ScenarioImporter scenario, EventsManager eventsManager) {
68 this.links = scenario.hermesLinks;
70 this.delayedLinksByWakeupTime =
new ArrayList<>();
71 this.delayedAgentsByWakeupTime =
new ArrayList<>();
72 this.agent_stops = scenario.agentStops;
73 this.route_stops_by_route_no = scenario.routeStopsByRouteNo;
74 this.line_of_route = scenario.lineOfRoute;
75 this.sortedEvents =
new EventArray();
76 this.eventsManager = eventsManager;
79 for (
int i = 0; i <= HermesConfigGroup.SIM_STEPS + 1; i++) {
80 delayedLinksByWakeupTime.add(
new ArrayDeque<>());
81 delayedAgentsByWakeupTime.add(
new ArrayDeque<>());
85 public void log(
int time, String s) {
86 if (HermesConfigGroup.DEBUG_REALMS) {
87 log.debug(String.format(
"Hermes [ time = %d ] %s", time, s));
91 private void addDelayedAgent(Agent agent,
int until) {
92 if (HermesConfigGroup.DEBUG_REALMS) log(secs, String.format(
"agent %d delayed until %d", agent.id, until));
93 delayedAgentsByWakeupTime.get(Math.min(until, HermesConfigGroup.SIM_STEPS + 1)).add(agent);
96 private void addDelayedLink(HLink link,
int until) {
97 if (HermesConfigGroup.DEBUG_REALMS)
98 log(secs, String.format(
"link %d delayed until %d size %d peek agent %d", link.id(), until, link.queue().size(), link.queue().peek().id));
99 delayedLinksByWakeupTime.get(Math.min(until, HermesConfigGroup.SIM_STEPS + 1)).add(link);
102 private void advanceAgentandSetEventTime(Agent agent) {
105 setEventTime(agent, Agent.getPlanEvent(agent.currPlan()), secs,
false);
108 private void advanceAgent(Agent agent) {
109 if (HermesConfigGroup.DEBUG_REALMS) {
110 long centry = agent.currPlan();
111 log(secs, String.format(
"agent %d finished %s (prev plan index is %d)", agent.id, Agent.toString(centry), agent.planIndex));
114 if (HermesConfigGroup.DEBUG_REALMS) {
115 long nentry = agent.currPlan();
116 log(secs, String.format(
"agent %d starting %s (new plan index is %d)", agent.id, Agent.toString(nentry), agent.planIndex));
120 protected boolean processAgentLink(Agent agent,
long planentry,
int currLinkId) {
121 int linkid = Agent.getLinkPlanEntry(planentry);
122 double velocity = Agent.getVelocityPlanEntry(planentry);
123 HLink next = links[linkid];
124 int prev_finishtime = agent.linkFinishTime;
126 velocity = velocity == 0 ? next.velocity() : velocity;
128 int traveltime = (HermesConfigGroup.LINK_ADVANCE_DELAY + (int) Math.round(Math.max(1, next.length() / Math.min(velocity, next.velocity()))));
129 agent.linkFinishTime = secs + traveltime;
130 float storageCapacityPCU = agent.getStorageCapacityPCUE();
131 if (next.push(agent,secs,storageCapacityPCU)) {
132 advanceAgentandSetEventTime(agent);
134 if (currLinkId != next.id() && next.queue().peek() == agent) {
135 addDelayedLink(next, Math.max(agent.linkFinishTime, secs + 1));
139 agent.linkFinishTime = prev_finishtime;
144 protected boolean processAgentSleepFor(Agent agent,
long planentry) {
145 int sleep = Agent.getSleepPlanEntry(planentry);
146 return processAgentSleepUntil(agent, secs + Math.max(1, sleep));
149 protected boolean processAgentSleepUntil(Agent agent,
long planentry) {
150 int sleep = Agent.getSleepPlanEntry(planentry);
151 addDelayedAgent(agent, Math.max(sleep, secs + 1));
152 updateCapacities(agent);
153 advanceAgentandSetEventTime(agent);
157 private void updateCapacities(Agent agent) {
158 if (agent.isTransitVehicle()) {
163 if (agent.plan.size < agent.planIndex + 3) {
166 if (Agent.getPlanHeader(agent.plan.get(agent.planIndex + 2)) == Agent.LinkType) {
167 int category = Agent.getLinkPCEEntry(agent.nextPlan());
168 agent.setStorageCapacityPCUE(si.getStorageCapacityPCE(category));
169 agent.setFlowCapacityPCUE(si.getFlowCapacityPCE(category));
173 protected boolean processAgentWait(Agent agent,
long planentry) {
174 advanceAgentandSetEventTime(agent);
175 int routeNo = Agent.getRoutePlanEntry(planentry);
176 int accessStop = Agent.getStopPlanEntry(planentry);
178 int lineid = line_of_route[routeNo];
181 agent_stops.get(accessStop)
184 }
catch (NullPointerException npe) {
185 log.error(String.format(
"Hermes NPE agent=%d routeNo=%d accessStop=%d lineid=%d", agent.id, routeNo, accessStop, lineid), npe);
190 protected boolean processAgentStopArrive(Agent agent,
long planentry) {
191 addDelayedAgent(agent, secs + 1);
192 advanceAgentandSetEventTime(agent);
198 protected boolean processAgentStopDelay(Agent agent,
long planentry) {
199 int stopid = Agent.getStopPlanEntry(planentry);
200 int departure = Agent.getDeparture(planentry);
203 addDelayedAgent(agent, Math.max(secs + 1, departure));
207 for (Agent out : agent.egress(stopid)) {
208 addDelayedAgent(out, secs + 1);
210 advanceAgentandSetEventTime(out);
212 setEventVehicle(out, Agent.getPlanEvent(out.currPlan()), agent.id);
219 protected boolean processAgentStopDepart(Agent agent,
long planentry) {
220 int routeNo = Agent.getRoutePlanEntry(planentry);
221 int stopid = Agent.getStopPlanEntry(planentry);
222 int lineid = line_of_route[routeNo];
223 ArrayDeque<Agent> waiting_agents = agent_stops.get(stopid).get(lineid);
226 if (waiting_agents != null) {
227 ArrayList<Agent> removed =
new ArrayList<>();
228 for (Agent in : waiting_agents) {
230 int egressStop = in.getNextStopPlanEntry();
231 if (agent.willServeStop(egressStop)) {
232 if (agent.access(egressStop, in)) {
235 advanceAgentandSetEventTime(in);
237 setEventVehicle(in, Agent.getPlanEvent(in.currPlan()), agent.id);
247 waiting_agents.removeAll(removed);
249 advanceAgentandSetEventTime(agent);
255 protected boolean processAgent(Agent agent,
int currLinkId) {
257 long planentry = agent.plan.get(agent.planIndex + 1);
258 int type = Agent.getPlanHeader(planentry);
260 case Agent.LinkType:
return processAgentLink(agent, planentry, currLinkId);
261 case Agent.SleepForType:
return processAgentSleepFor(agent, planentry);
262 case Agent.SleepUntilType:
return processAgentSleepUntil(agent, planentry);
263 case Agent.StopArriveType:
return processAgentStopArrive(agent, planentry);
264 case Agent.StopDelayType:
return processAgentStopDelay(agent, planentry);
265 case Agent.StopDepartType:
return processAgentStopDepart(agent, planentry);
266 case Agent.WaitType:
return processAgentWait(agent, planentry);
267 case Agent.AccessType:
268 case Agent.EgressType:
271 "unknown plan element type %d, agent %d plan index %d",
272 type, agent.id, agent.planIndex + 1));
276 protected int processAgentActivities(Agent agent) {
277 boolean finished = agent.finished();
280 setEventTime(agent, agent.events().size() - 1, secs,
true);
283 if (!finished && !processAgent(agent, -1)) {
284 addDelayedAgent(agent, secs + 1);
290 protected int processLinks(HLink link) {
292 Agent agent = link.queue().peek();
293 while (agent.linkFinishTime <= secs && link.flow(secs, agent.getFlowCapacityPCUE())) {
294 boolean finished = agent.finished();
297 setEventTime(agent, agent.events().size() - 1, secs,
true);
299 if (finished || processAgent(agent, link.id())) {
300 float storageCapacityPCE = agent.getStorageCapacityPCUE();
301 link.pop(storageCapacityPCE);
303 if ((agent = link.queue().peek()) == null) {
313 addDelayedLink(link, Math.max(agent.linkFinishTime, secs + 1));
323 while (secs != HermesConfigGroup.SIM_STEPS) {
324 if (secs % 3600 == 0) {
325 log.info(
"Hermes running at " + Time.writeTime(secs));
327 while ((agent = delayedAgentsByWakeupTime.get(secs).poll()) != null) {
328 if (HermesConfigGroup.DEBUG_REALMS) {
329 log(secs, String.format(
"Processing agent %d", agent.id));
331 routed += processAgentActivities(agent);
334 delayedAgentsByWakeupTime.set(secs, null);
335 if (si.isDeterministicPt()) {
336 for (Event e : si.getDeterministicPtEvents().get(secs)) {
339 si.getDeterministicPtEvents().get(secs).clear();
342 while ((link = delayedLinksByWakeupTime.get(secs).poll()) != null) {
343 if (HermesConfigGroup.DEBUG_REALMS) {
344 log(secs, String.format(
"Processing link %d", link.id()));
346 routed += processLinks(link);
348 delayedLinksByWakeupTime.set(secs, null);
349 if (HermesConfigGroup.DEBUG_REALMS && routed > 0) {
350 log(secs, String.format(
"Processed %d agents", routed));
352 if (HermesConfigGroup.CONCURRENT_EVENT_PROCESSING && secs % 3600 == 0 && sortedEvents.size() > 0) {
353 eventsManager.processEvents(sortedEvents);
354 sortedEvents =
new EventArray();
362 public void setEventTime(Agent agent,
int agentId,
int time,
boolean lastEvent) {
364 EventArray agentEvents = agent.events();
365 Event
event = agentEvents.get(agentId);
367 for (; agent.eventsIndex <= agentId; agent.eventsIndex++) {
368 agentEvents.get(agent.eventsIndex).setTime(time);
369 if (HermesConfigGroup.DEBUG_REALMS)
370 log(secs, String.format(
"agent %d setEventTime (eventsIndex=%d) %s", agent.id, agent.eventsIndex, agentEvents.get(agent.eventsIndex).toString()));
371 sortedEvents.add(agentEvents.get(agent.eventsIndex));
375 if (event instanceof VehicleArrivesAtFacilityEvent vaafe) {
376 vaafe.setDelay(vaafe.getTime() - vaafe.getDelay());
378 }
else if (event instanceof VehicleDepartsAtFacilityEvent vdafe) {
379 vdafe.setDelay(vdafe.getTime() - vdafe.getDelay());
382 else if (lastEvent && event instanceof ActivityEndEvent) {
383 sortedEvents.removeLast();
388 public void setEventVehicle(Agent agent,
int eventId,
int vehicleId) {
390 Event
event = agent.events().get(eventId);
391 Id<Vehicle> vid = Id.get(si.matsim_id(vehicleId,
true), Vehicle.class);
392 if (event instanceof PersonEntersVehicleEvent) {
393 ((PersonEntersVehicleEvent) event).setVehicleId(vid);
394 }
else if (event instanceof PersonLeavesVehicleEvent) {
395 ((PersonLeavesVehicleEvent) event).setVehicleId(vid);
398 String.format(
"vehicle id could not be set for event: %d", eventId));
403 ArrayList<ArrayDeque<HLink>> delayedLinks() {
return this.delayedLinksByWakeupTime; }
405 ArrayList<ArrayDeque<Agent>> delayedAgents() {
406 return this.delayedAgentsByWakeupTime;
409 EventArray getSortedEvents() {
410 return this.sortedEvents;