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.sourceforge.net/
15 // Copyright (C) 2001-2012 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>
48 #include "NLHandler.h"
49 #include "NLTriggerBuilder.h"
51 
52 
53 #ifdef HAVE_MESOSIM
54 #include <mesosim/METriggeredCalibrator.h>
55 #endif
56 
57 #ifdef CHECK_MEMORY_LEAKS
58 #include <foreign/nvwa/debug_new.h>
59 #endif // CHECK_MEMORY_LEAKS
60 
61 
62 // ===========================================================================
63 // method definitions
64 // ===========================================================================
66  : myHandler(0), myHaveWarnedAboutDeprecatedFriendlyPos(false) {}
67 
68 
70 
71 void
73  myHandler = handler;
74 }
75 
76 
77 void
79  bool ok = true;
80  // get the id, throw if not given or empty...
81  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
82  if (!ok) {
83  return;
84  }
85  MSEdge* e = MSEdge::dictionary(id);
86  if (e == 0) {
87  WRITE_ERROR("Unknown edge ('" + id + "') referenced in a vaporizer.");
88  return;
89  }
90  SUMOTime begin = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, 0, ok);
91  SUMOTime end = attrs.getSUMOTimeReporting(SUMO_ATTR_END, 0, ok);
92  if (!ok) {
93  return;
94  }
95  if (begin < 0) {
96  WRITE_ERROR("A vaporization begin time is negative (edge id='" + id + "').");
97  return;
98  }
99  if (begin >= end) {
100  WRITE_ERROR("A vaporization ends before it starts (edge id='" + id + "').");
101  return;
102  }
103  if (end >= string2time(OptionsCont::getOptions().getString("begin"))) {
108  }
109 }
110 
111 
112 
113 void
115  const std::string& base) throw(InvalidArgument) {
116  // get the id, throw if not given or empty...
117  bool ok = true;
118  // get the id, throw if not given or empty...
119  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
120  if (!ok) {
121  return;
122  }
123  // get the file name to read further definitions from
124  std::string file = getFileName(attrs, base, true);
125  std::string objectid = attrs.getStringReporting(SUMO_ATTR_LANES, id.c_str(), ok);
126  if (!ok) {
127  throw InvalidArgument("The lanes to use within MSLaneSpeedTrigger '" + id + "' are not known.");
128  }
129  std::vector<MSLane*> lanes;
130  std::vector<std::string> laneIDs;
131  SUMOSAXAttributes::parseStringVector(objectid, laneIDs);
132  for (std::vector<std::string>::iterator i = laneIDs.begin(); i != laneIDs.end(); ++i) {
133  MSLane* lane = MSLane::dictionary(*i);
134  if (lane == 0) {
135  throw InvalidArgument("The lane to use within MSLaneSpeedTrigger '" + id + "' is not known.");
136  }
137  lanes.push_back(lane);
138  }
139  if (lanes.size() == 0) {
140  throw InvalidArgument("No lane defined for MSLaneSpeedTrigger '" + id + "'.");
141  }
142  try {
143  MSLaneSpeedTrigger* trigger = buildLaneSpeedTrigger(net, id, lanes, file);
144  if (file == "") {
145  trigger->registerParent(SUMO_TAG_VSS, myHandler);
146  }
147  } catch (ProcessError& e) {
148  throw InvalidArgument(e.what());
149  }
150 }
151 
152 
153 void
155  bool ok = true;
156  // get the id, throw if not given or empty...
157  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
158  if (!ok) {
159  throw ProcessError();
160  }
161  // get the lane
162  MSLane* lane = getLane(attrs, "bus_stop", id);
163  // get the positions
164  SUMOReal frompos = attrs.getOptSUMORealReporting(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
165  SUMOReal topos = attrs.getOptSUMORealReporting(SUMO_ATTR_ENDPOS, id.c_str(), ok, lane->getLength());
166  if (attrs.hasAttribute(SUMO_ATTR_FROM) || attrs.hasAttribute(SUMO_ATTR_TO)) {
167  WRITE_WARNING("Deprecated attribute 'from' or 'to' in description of bus stop '" + id + "'.");
168  frompos = attrs.getOptSUMORealReporting(SUMO_ATTR_FROM, id.c_str(), ok, 0);
169  topos = attrs.getOptSUMORealReporting(SUMO_ATTR_TO, id.c_str(), ok, lane->getLength());
170  }
171  if (attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) && !myHaveWarnedAboutDeprecatedFriendlyPos) {
172  myHaveWarnedAboutDeprecatedFriendlyPos = true;
173  WRITE_WARNING("'" + toString(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) + "' is deprecated, use '" + toString(SUMO_ATTR_FRIENDLY_POS) + "' instead.");
174  }
175  const bool friendlyPos = attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED)
176  ? attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS__DEPRECATED, id.c_str(), ok, false)
177  : attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
178  if (!ok || !myHandler->checkStopPos(frompos, topos, lane->getLength(), 10., friendlyPos)) {
179  throw InvalidArgument("Invalid position for bus stop '" + id + "'.");
180  }
181  // get the lines
182  std::vector<std::string> lines;
183  SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_LINES, id.c_str(), ok, ""), lines);
184  // build the bus stop
185  buildBusStop(net, id, lines, lane, frompos, topos);
186 }
187 
188 
189 #ifdef HAVE_MESOSIM
190 void
191 NLTriggerBuilder::parseAndBuildCalibrator(MSNet& net, const SUMOSAXAttributes& attrs,
192  const std::string& base) throw(InvalidArgument) {
193  bool ok = true;
194  // get the id, throw if not given or empty...
195  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
196  if (!ok) {
197  throw ProcessError();
198  }
199  // get the file name to read further definitions from
200  MSLane* lane = getLane(attrs, "calibrator", id);
201  const SUMOReal pos = getPosition(attrs, lane, "calibrator", id);
203  const SUMOTime freq = attrs.getOptSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok, DELTA_T); // !!! no error handling
204  std::string file = getFileName(attrs, base, true);
205  bool ok = true;
206  std::string outfile = attrs.getOptStringReporting(SUMO_ATTR_OUTPUT, 0, ok, "");
207  METriggeredCalibrator* trigger = buildCalibrator(net, id, &lane->getEdge(), pos, file, outfile, freq);
208  if (file == "") {
209  trigger->registerParent(SUMO_TAG_CALIBRATOR, myHandler);
210  }
211  }
212 }
213 #endif
214 
215 
216 void
218  const std::string& base) throw(InvalidArgument) {
219  bool ok = true;
220  // get the id, throw if not given or empty...
221  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
222  if (!ok) {
223  throw ProcessError();
224  }
225  // get the file name to read further definitions from
226  std::string file = getFileName(attrs, base, true);
227  std::string objectid = attrs.getStringReporting(SUMO_ATTR_EDGES, id.c_str(), ok);
228  if (!ok) {
229  throw InvalidArgument("The edge to use within MSTriggeredRerouter '" + id + "' is not known.");
230  }
231  std::vector<MSEdge*> edges;
232  std::vector<std::string> edgeIDs;
233  SUMOSAXAttributes::parseStringVector(objectid, edgeIDs);
234  for (std::vector<std::string>::iterator i = edgeIDs.begin(); i != edgeIDs.end(); ++i) {
235  MSEdge* edge = MSEdge::dictionary(*i);
236  if (edge == 0) {
237  throw InvalidArgument("The edge to use within MSTriggeredRerouter '" + id + "' is not known.");
238  }
239  edges.push_back(edge);
240  }
241  if (edges.size() == 0) {
242  throw InvalidArgument("No edges found for MSTriggeredRerouter '" + id + "'.");
243  }
244  SUMOReal prob = attrs.getOptSUMORealReporting(SUMO_ATTR_PROB, id.c_str(), ok, 1);
245  bool off = attrs.getOptBoolReporting(SUMO_ATTR_OFF, id.c_str(), ok, false);
246  if (!ok) {
247  throw InvalidArgument("Could not parse MSTriggeredRerouter '" + id + "'.");
248  }
249  MSTriggeredRerouter* trigger = buildRerouter(net, id, edges, prob, file, off);
250  if (file == "") {
251  trigger->registerParent(SUMO_TAG_REROUTER, myHandler);
252  }
253 }
254 
255 
256 // -------------------------
257 
258 
260 NLTriggerBuilder::buildLaneSpeedTrigger(MSNet& /*net*/, const std::string& id,
261  const std::vector<MSLane*> &destLanes,
262  const std::string& file) {
263  return new MSLaneSpeedTrigger(id, destLanes, file);
264 }
265 
266 
267 #ifdef HAVE_MESOSIM
268 METriggeredCalibrator*
269 NLTriggerBuilder::buildCalibrator(MSNet& net, const std::string& id,
270  const MSEdge* edge, SUMOReal pos,
271  const std::string& file,
272  const std::string& outfile,
273  const SUMOTime freq) {
274  return new METriggeredCalibrator(id, edge, pos, file, outfile, freq);
275 }
276 #endif
277 
278 
280 NLTriggerBuilder::buildRerouter(MSNet&, const std::string& id,
281  std::vector<MSEdge*> &edges,
282  SUMOReal prob, const std::string& file, bool off) {
283  return new MSTriggeredRerouter(id, edges, prob, file, off);
284 }
285 
286 
287 void
288 NLTriggerBuilder::buildBusStop(MSNet& net, const std::string& id,
289  const std::vector<std::string> &lines,
290  MSLane* lane, SUMOReal frompos, SUMOReal topos) throw(InvalidArgument) {
291  MSBusStop* stop = new MSBusStop(id, lines, *lane, frompos, topos);
292  if (!net.addBusStop(stop)) {
293  delete stop;
294  throw InvalidArgument("Could not build bus stop '" + id + "'; probably declared twice.");
295  }
296 }
297 
298 
299 
300 
301 std::string
303  const std::string& base,
304  const bool allowEmpty) throw(InvalidArgument) {
305  // get the file name to read further definitions from
306  bool ok = true;
307  std::string file = attrs.getOptStringReporting(SUMO_ATTR_FILE, 0, ok, "");
308  if (file == "") {
309  if (allowEmpty) {
310  return file;
311  }
312  throw InvalidArgument("No filename given.");
313  }
314  // check whether absolute or relative filenames are given
315  if (!FileHelpers::isAbsolute(file)) {
316  return FileHelpers::getConfigurationRelative(base, file);
317  }
318  return file;
319 }
320 
321 
322 MSLane*
324  const std::string& tt,
325  const std::string& tid) throw(InvalidArgument) {
326  bool ok = true;
327  std::string objectid = attrs.getStringReporting(SUMO_ATTR_LANE, tid.c_str(), ok);
328  MSLane* lane = MSLane::dictionary(objectid);
329  if (lane == 0) {
330  throw InvalidArgument("The lane " + objectid + " to use within the " + tt + " '" + tid + "' is not known.");
331  }
332  return lane;
333 }
334 
335 
336 SUMOReal
338  MSLane* lane,
339  const std::string& tt, const std::string& tid) throw(InvalidArgument) {
340  if (attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) && !myHaveWarnedAboutDeprecatedFriendlyPos) {
341  myHaveWarnedAboutDeprecatedFriendlyPos = true;
342  WRITE_WARNING("'" + toString(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) + "' is deprecated, use '" + toString(SUMO_ATTR_FRIENDLY_POS) + "' instead.");
343  }
344  bool ok = true;
345  SUMOReal pos = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, 0, ok);
346  const bool friendlyPos = attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED)
347  ? attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS__DEPRECATED, 0, ok, false)
348  : attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, 0, ok, false);
349  if (!ok) {
350  throw InvalidArgument("Error on parsing a position information.");
351  }
352  if (pos < 0) {
353  pos = lane->getLength() + pos;
354  }
355  if (pos > lane->getLength()) {
356  if (friendlyPos) {
357  pos = lane->getLength() - (SUMOReal) 0.1;
358  } else {
359  throw InvalidArgument("The position of " + tt + " '" + tid + "' lies beyond the lane's '" + lane->getID() + "' length.");
360  }
361  }
362  return pos;
363 }
364 
365 
366 
367 /****************************************************************************/