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_INTERNAL
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) {}
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, "busStop", 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  const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
167  if (!ok || !myHandler->checkStopPos(frompos, topos, lane->getLength(), 10., friendlyPos)) {
168  throw InvalidArgument("Invalid position for bus stop '" + id + "'.");
169  }
170  // get the lines
171  std::vector<std::string> lines;
172  SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_LINES, id.c_str(), ok, ""), lines);
173  // build the bus stop
174  buildBusStop(net, id, lines, lane, frompos, topos);
175 }
176 
177 
178 #ifdef HAVE_INTERNAL
179 void
180 NLTriggerBuilder::parseAndBuildCalibrator(MSNet& net, const SUMOSAXAttributes& attrs,
181  const std::string& base) throw(InvalidArgument) {
182  bool ok = true;
183  // get the id, throw if not given or empty...
184  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
185  if (!ok) {
186  throw ProcessError();
187  }
188  // get the file name to read further definitions from
189  MSLane* lane = getLane(attrs, "calibrator", id);
190  const SUMOReal pos = getPosition(attrs, lane, "calibrator", id);
192  const SUMOTime freq = attrs.getOptSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok, DELTA_T); // !!! no error handling
193  std::string file = getFileName(attrs, base, true);
194  bool ok = true;
195  std::string outfile = attrs.getOptStringReporting(SUMO_ATTR_OUTPUT, 0, ok, "");
196  METriggeredCalibrator* trigger = buildCalibrator(net, id, &lane->getEdge(), pos, file, outfile, freq);
197  if (file == "") {
198  trigger->registerParent(SUMO_TAG_CALIBRATOR, myHandler);
199  }
200  }
201 }
202 #endif
203 
204 
205 void
207  const std::string& base) throw(InvalidArgument) {
208  bool ok = true;
209  // get the id, throw if not given or empty...
210  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
211  if (!ok) {
212  throw ProcessError();
213  }
214  // get the file name to read further definitions from
215  std::string file = getFileName(attrs, base, true);
216  std::string objectid = attrs.getStringReporting(SUMO_ATTR_EDGES, id.c_str(), ok);
217  if (!ok) {
218  throw InvalidArgument("The edge to use within MSTriggeredRerouter '" + id + "' is not known.");
219  }
220  std::vector<MSEdge*> edges;
221  std::vector<std::string> edgeIDs;
222  SUMOSAXAttributes::parseStringVector(objectid, edgeIDs);
223  for (std::vector<std::string>::iterator i = edgeIDs.begin(); i != edgeIDs.end(); ++i) {
224  MSEdge* edge = MSEdge::dictionary(*i);
225  if (edge == 0) {
226  throw InvalidArgument("The edge to use within MSTriggeredRerouter '" + id + "' is not known.");
227  }
228  edges.push_back(edge);
229  }
230  if (edges.size() == 0) {
231  throw InvalidArgument("No edges found for MSTriggeredRerouter '" + id + "'.");
232  }
233  SUMOReal prob = attrs.getOptSUMORealReporting(SUMO_ATTR_PROB, id.c_str(), ok, 1);
234  bool off = attrs.getOptBoolReporting(SUMO_ATTR_OFF, id.c_str(), ok, false);
235  if (!ok) {
236  throw InvalidArgument("Could not parse MSTriggeredRerouter '" + id + "'.");
237  }
238  MSTriggeredRerouter* trigger = buildRerouter(net, id, edges, prob, file, off);
239  if (file == "") {
240  trigger->registerParent(SUMO_TAG_REROUTER, myHandler);
241  }
242 }
243 
244 
245 // -------------------------
246 
247 
249 NLTriggerBuilder::buildLaneSpeedTrigger(MSNet& /*net*/, const std::string& id,
250  const std::vector<MSLane*>& destLanes,
251  const std::string& file) {
252  return new MSLaneSpeedTrigger(id, destLanes, file);
253 }
254 
255 
256 #ifdef HAVE_INTERNAL
257 METriggeredCalibrator*
258 NLTriggerBuilder::buildCalibrator(MSNet& net, const std::string& id,
259  const MSEdge* edge, SUMOReal pos,
260  const std::string& file,
261  const std::string& outfile,
262  const SUMOTime freq) {
263  return new METriggeredCalibrator(id, edge, pos, file, outfile, freq);
264 }
265 #endif
266 
267 
269 NLTriggerBuilder::buildRerouter(MSNet&, const std::string& id,
270  std::vector<MSEdge*>& edges,
271  SUMOReal prob, const std::string& file, bool off) {
272  return new MSTriggeredRerouter(id, edges, prob, file, off);
273 }
274 
275 
276 void
277 NLTriggerBuilder::buildBusStop(MSNet& net, const std::string& id,
278  const std::vector<std::string>& lines,
279  MSLane* lane, SUMOReal frompos, SUMOReal topos) throw(InvalidArgument) {
280  MSBusStop* stop = new MSBusStop(id, lines, *lane, frompos, topos);
281  if (!net.addBusStop(stop)) {
282  delete stop;
283  throw InvalidArgument("Could not build bus stop '" + id + "'; probably declared twice.");
284  }
285 }
286 
287 
288 
289 
290 std::string
292  const std::string& base,
293  const bool allowEmpty) throw(InvalidArgument) {
294  // get the file name to read further definitions from
295  bool ok = true;
296  std::string file = attrs.getOptStringReporting(SUMO_ATTR_FILE, 0, ok, "");
297  if (file == "") {
298  if (allowEmpty) {
299  return file;
300  }
301  throw InvalidArgument("No filename given.");
302  }
303  // check whether absolute or relative filenames are given
304  if (!FileHelpers::isAbsolute(file)) {
305  return FileHelpers::getConfigurationRelative(base, file);
306  }
307  return file;
308 }
309 
310 
311 MSLane*
313  const std::string& tt,
314  const std::string& tid) throw(InvalidArgument) {
315  bool ok = true;
316  std::string objectid = attrs.getStringReporting(SUMO_ATTR_LANE, tid.c_str(), ok);
317  MSLane* lane = MSLane::dictionary(objectid);
318  if (lane == 0) {
319  throw InvalidArgument("The lane " + objectid + " to use within the " + tt + " '" + tid + "' is not known.");
320  }
321  return lane;
322 }
323 
324 
325 SUMOReal
327  MSLane* lane,
328  const std::string& tt, const std::string& tid) throw(InvalidArgument) {
329  bool ok = true;
330  SUMOReal pos = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, 0, ok);
331  const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, 0, ok, false);
332  if (!ok) {
333  throw InvalidArgument("Error on parsing a position information.");
334  }
335  if (pos < 0) {
336  pos = lane->getLength() + pos;
337  }
338  if (pos > lane->getLength()) {
339  if (friendlyPos) {
340  pos = lane->getLength() - (SUMOReal) 0.1;
341  } else {
342  throw InvalidArgument("The position of " + tt + " '" + tid + "' lies beyond the lane's '" + lane->getID() + "' length.");
343  }
344  }
345  return pos;
346 }
347 
348 
349 
350 /****************************************************************************/