SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NLTriggerBuilder.cpp
Go to the documentation of this file.
1 /****************************************************************************/
12 // Builds trigger objects for microsim
13 /****************************************************************************/
14 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
15 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
16 /****************************************************************************/
17 //
18 // This file is part of SUMO.
19 // SUMO is free software: you can redistribute it and/or modify
20 // it under the terms of the GNU General Public License as published by
21 // the Free Software Foundation, either version 3 of the License, or
22 // (at your option) any later version.
23 //
24 /****************************************************************************/
25 
26 
27 // ===========================================================================
28 // included modules
29 // ===========================================================================
30 #ifdef _MSC_VER
31 #include <windows_config.h>
32 #else
33 #include <config.h>
34 #endif
35 
36 #include <string>
38 #include <microsim/MSLane.h>
39 #include <microsim/MSEdge.h>
40 #include <microsim/MSGlobals.h>
51 #include "NLHandler.h"
52 #include "NLTriggerBuilder.h"
54 
55 
56 #ifdef HAVE_INTERNAL
57 #include <mesosim/MELoop.h>
58 #include <mesosim/METriggeredCalibrator.h>
59 #endif
60 
61 #ifdef CHECK_MEMORY_LEAKS
62 #include <foreign/nvwa/debug_new.h>
63 #endif // CHECK_MEMORY_LEAKS
64 
65 
66 // ===========================================================================
67 // method definitions
68 // ===========================================================================
70  : myHandler(0) {}
71 
72 
74 
75 void
77  myHandler = handler;
78 }
79 
80 
81 void
83  bool ok = true;
84  // get the id, throw if not given or empty...
85  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
86  if (!ok) {
87  return;
88  }
89  MSEdge* e = MSEdge::dictionary(id);
90  if (e == 0) {
91  WRITE_ERROR("Unknown edge ('" + id + "') referenced in a vaporizer.");
92  return;
93  }
94  SUMOTime begin = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, 0, ok);
95  SUMOTime end = attrs.getSUMOTimeReporting(SUMO_ATTR_END, 0, ok);
96  if (!ok) {
97  return;
98  }
99  if (begin < 0) {
100  WRITE_ERROR("A vaporization begin time is negative (edge id='" + id + "').");
101  return;
102  }
103  if (begin >= end) {
104  WRITE_ERROR("A vaporization ends before it starts (edge id='" + id + "').");
105  return;
106  }
107  if (end >= string2time(OptionsCont::getOptions().getString("begin"))) {
112  }
113 }
114 
115 
116 
117 void
119  const std::string& base) {
120  // get the id, throw if not given or empty...
121  bool ok = true;
122  // get the id, throw if not given or empty...
123  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
124  if (!ok) {
125  return;
126  }
127  // get the file name to read further definitions from
128  std::string file = getFileName(attrs, base, true);
129  std::string objectid = attrs.get<std::string>(SUMO_ATTR_LANES, id.c_str(), ok);
130  if (!ok) {
131  throw InvalidArgument("The lanes to use within MSLaneSpeedTrigger '" + id + "' are not known.");
132  }
133  std::vector<MSLane*> lanes;
134  std::vector<std::string> laneIDs;
135  SUMOSAXAttributes::parseStringVector(objectid, laneIDs);
136  for (std::vector<std::string>::iterator i = laneIDs.begin(); i != laneIDs.end(); ++i) {
137  MSLane* lane = MSLane::dictionary(*i);
138  if (lane == 0) {
139  throw InvalidArgument("The lane to use within MSLaneSpeedTrigger '" + id + "' is not known.");
140  }
141  lanes.push_back(lane);
142  }
143  if (lanes.size() == 0) {
144  throw InvalidArgument("No lane defined for MSLaneSpeedTrigger '" + id + "'.");
145  }
146  try {
147  MSLaneSpeedTrigger* trigger = buildLaneSpeedTrigger(net, id, lanes, file);
148  if (file == "") {
150  }
151  } catch (ProcessError& e) {
152  throw InvalidArgument(e.what());
153  }
154 }
155 
156 
157 void
159  bool ok = true;
160  // get the id, throw if not given or empty...
161  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
162  if (!ok) {
163  throw ProcessError();
164  }
165  // get the lane
166  MSLane* lane = getLane(attrs, "busStop", id);
167  // get the positions
168  SUMOReal frompos = attrs.getOpt<SUMOReal>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
169  SUMOReal topos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ENDPOS, id.c_str(), ok, lane->getLength());
170  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
171  if (!ok || !myHandler->checkStopPos(frompos, topos, lane->getLength(), POSITION_EPS, friendlyPos)) {
172  throw InvalidArgument("Invalid position for bus stop '" + id + "'.");
173  }
174  // get the lines
175  std::vector<std::string> lines;
176  SUMOSAXAttributes::parseStringVector(attrs.getOpt<std::string>(SUMO_ATTR_LINES, id.c_str(), ok, "", false), lines);
177  // build the bus stop
178  buildBusStop(net, id, lines, lane, frompos, topos);
179 }
180 
181 
182 void
184  const std::string& base) {
185  bool ok = true;
186  // get the id, throw if not given or empty...
187  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
188  if (!ok) {
189  throw ProcessError();
190  }
191  // get the file name to read further definitions from
192  MSLane* lane = getLane(attrs, "calibrator", id);
193  const SUMOReal pos = getPosition(attrs, lane, "calibrator", id);
194  const SUMOTime freq = attrs.getOptSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok, DELTA_T); // !!! no error handling
195  std::string file = getFileName(attrs, base, true);
196  std::string outfile = attrs.getOpt<std::string>(SUMO_ATTR_OUTPUT, id.c_str(), ok, "");
197  std::string routeProbe = attrs.getOpt<std::string>(SUMO_ATTR_ROUTEPROBE, id.c_str(), ok, "");
198  MSRouteProbe* probe = 0;
199  if (routeProbe != "") {
200  probe = dynamic_cast<MSRouteProbe*>(net.getDetectorControl().getTypedDetectors(SUMO_TAG_ROUTEPROBE).get(routeProbe));
201  }
203 #ifdef HAVE_INTERNAL
204  METriggeredCalibrator* trigger = buildMECalibrator(net, id, &lane->getEdge(), pos, file, outfile, freq, probe);
205  if (file == "") {
206  trigger->registerParent(SUMO_TAG_CALIBRATOR, myHandler);
207  }
208 #endif
209  } else {
210  MSCalibrator* trigger = buildCalibrator(net, id, &lane->getEdge(), pos, file, outfile, freq, probe);
211  if (file == "") {
213  }
214  }
215 }
216 
217 
218 void
220  const std::string& base) {
221  bool ok = true;
222  // get the id, throw if not given or empty...
223  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
224  if (!ok) {
225  throw ProcessError();
226  }
227  // get the file name to read further definitions from
228  std::string file = getFileName(attrs, base, true);
229  std::string objectid = attrs.get<std::string>(SUMO_ATTR_EDGES, id.c_str(), ok);
230  if (!ok) {
231  throw InvalidArgument("The edge to use within MSTriggeredRerouter '" + id + "' is not known.");
232  }
233  std::vector<MSEdge*> edges;
234  std::vector<std::string> edgeIDs;
235  SUMOSAXAttributes::parseStringVector(objectid, edgeIDs);
236  for (std::vector<std::string>::iterator i = edgeIDs.begin(); i != edgeIDs.end(); ++i) {
237  MSEdge* edge = MSEdge::dictionary(*i);
238  if (edge == 0) {
239  throw InvalidArgument("The edge to use within MSTriggeredRerouter '" + id + "' is not known.");
240  }
241  edges.push_back(edge);
242  }
243  if (edges.size() == 0) {
244  throw InvalidArgument("No edges found for MSTriggeredRerouter '" + id + "'.");
245  }
246  SUMOReal prob = attrs.getOpt<SUMOReal>(SUMO_ATTR_PROB, id.c_str(), ok, 1);
247  bool off = attrs.getOpt<bool>(SUMO_ATTR_OFF, id.c_str(), ok, false);
248  if (!ok) {
249  throw InvalidArgument("Could not parse MSTriggeredRerouter '" + id + "'.");
250  }
251  MSTriggeredRerouter* trigger = buildRerouter(net, id, edges, prob, file, off);
252  if (file == "") {
254  }
255 }
256 
257 
258 // -------------------------
259 
260 
262 NLTriggerBuilder::buildLaneSpeedTrigger(MSNet& /*net*/, const std::string& id,
263  const std::vector<MSLane*>& destLanes,
264  const std::string& file) {
265  return new MSLaneSpeedTrigger(id, destLanes, file);
266 }
267 
268 
269 #ifdef HAVE_INTERNAL
270 METriggeredCalibrator*
271 NLTriggerBuilder::buildMECalibrator(MSNet& /*net*/, const std::string& id,
272  const MSEdge* edge, SUMOReal pos,
273  const std::string& file,
274  const std::string& outfile,
275  const SUMOTime freq, MSRouteProbe* probe) {
276  return new METriggeredCalibrator(id, edge, pos, file, outfile, freq, MSGlobals::gMesoNet->getSegmentForEdge(*edge, pos)->getLength(), probe);
277 }
278 #endif
279 
280 
282 NLTriggerBuilder::buildCalibrator(MSNet& /*net*/, const std::string& id,
283  MSEdge* edge, SUMOReal pos,
284  const std::string& file,
285  const std::string& outfile,
286  const SUMOTime freq, MSRouteProbe* probe) {
287  return new MSCalibrator(id, edge, pos, file, outfile, freq, edge->getLength(), probe);
288 }
289 
290 
292 NLTriggerBuilder::buildRerouter(MSNet&, const std::string& id,
293  std::vector<MSEdge*>& edges,
294  SUMOReal prob, const std::string& file, bool off) {
295  return new MSTriggeredRerouter(id, edges, prob, file, off);
296 }
297 
298 
299 void
300 NLTriggerBuilder::buildBusStop(MSNet& net, const std::string& id,
301  const std::vector<std::string>& lines,
302  MSLane* lane, SUMOReal frompos, SUMOReal topos) {
303  MSBusStop* stop = new MSBusStop(id, lines, *lane, frompos, topos);
304  if (!net.addBusStop(stop)) {
305  delete stop;
306  throw InvalidArgument("Could not build bus stop '" + id + "'; probably declared twice.");
307  }
308 }
309 
310 
311 
312 
313 std::string
315  const std::string& base,
316  const bool allowEmpty) {
317  // get the file name to read further definitions from
318  bool ok = true;
319  std::string file = attrs.getOpt<std::string>(SUMO_ATTR_FILE, 0, ok, "");
320  if (file == "") {
321  if (allowEmpty) {
322  return file;
323  }
324  throw InvalidArgument("No filename given.");
325  }
326  // check whether absolute or relative filenames are given
327  if (!FileHelpers::isAbsolute(file)) {
328  return FileHelpers::getConfigurationRelative(base, file);
329  }
330  return file;
331 }
332 
333 
334 MSLane*
336  const std::string& tt,
337  const std::string& tid) {
338  bool ok = true;
339  std::string objectid = attrs.get<std::string>(SUMO_ATTR_LANE, tid.c_str(), ok);
340  MSLane* lane = MSLane::dictionary(objectid);
341  if (lane == 0) {
342  throw InvalidArgument("The lane " + objectid + " to use within the " + tt + " '" + tid + "' is not known.");
343  }
344  return lane;
345 }
346 
347 
348 SUMOReal
350  MSLane* lane,
351  const std::string& tt, const std::string& tid) {
352  bool ok = true;
353  SUMOReal pos = attrs.get<SUMOReal>(SUMO_ATTR_POSITION, 0, ok);
354  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, 0, ok, false);
355  if (!ok) {
356  throw InvalidArgument("Error on parsing a position information.");
357  }
358  if (pos < 0) {
359  pos = lane->getLength() + pos;
360  }
361  if (pos > lane->getLength()) {
362  if (friendlyPos) {
363  pos = lane->getLength() - (SUMOReal) 0.1;
364  } else {
365  throw InvalidArgument("The position of " + tt + " '" + tid + "' lies beyond the lane's '" + lane->getID() + "' length.");
366  }
367  }
368  return pos;
369 }
370 
371 
372 
373 /****************************************************************************/