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