Eclipse SUMO - Simulation of Urban MObility
NIImporter_OpenDrive.h
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
21 // Importer for networks stored in openDrive format
22 /****************************************************************************/
23 #pragma once
24 #include <config.h>
25 
26 #include <string>
27 #include <map>
30 
31 
32 // ===========================================================================
33 // class declarations
34 // ===========================================================================
35 class NBNetBuilder;
36 class NBEdge;
37 class OptionsCont;
38 class NBNode;
39 class NBNodeCont;
40 
41 
42 #define UNSET_CONNECTION 100000
43 #define UNSET_LANEVALIDITY 100000
44 
45 // ===========================================================================
46 // class definitions
47 // ===========================================================================
54 public:
70  static void loadNetwork(const OptionsCont& oc, NBNetBuilder& nb);
71 
72 
73 protected:
74 
117  };
118 
119 
178  OPENDRIVE_ATTR_UNIT, // xodr v1.4
181  };
182 
183 
186  enum LinkType {
189  };
190 
191 
194  enum ElementType {
198  };
199 
200 
207  };
208 
217  OPENDRIVE_GT_PARAMPOLY3 // rev 1.4
218  };
219 
220 
221 
226  struct OpenDriveLink {
231  OpenDriveLink(LinkType linkTypeArg, const std::string& elementIDArg)
232  : linkType(linkTypeArg), elementID(elementIDArg),
234 
236  std::string elementID;
239  };
240 
241 
254  OpenDriveGeometry(double lengthArg, double sArg, double xArg, double yArg, double hdgArg)
255  : length(lengthArg), s(sArg), x(xArg), y(yArg), hdg(hdgArg),
257 
258  double length;
259  double s;
260  double x;
261  double y;
262  double hdg;
264  std::vector<double> params;
265  };
266 
271  struct Poly3 {
279  Poly3(double _s, double _a, double _b, double _c, double _d) :
280  s(_s), a(_a), b(_b), c(_c), d(_d) {}
281 
282  double computeAt(double pos) const {
283  const double ds = pos - s;
284  return a + b * ds + c * ds * ds + d * ds * ds * ds;
285  }
286 
287  double s;
288  double a;
289  double b;
290  double c;
291  double d;
292  };
293 
298 
308 
309  double speed;
310  std::vector<std::string> allowed;
311  std::vector<std::string> denied;
312  };
313 
314 
315 
320  struct OpenDriveLane {
326  OpenDriveLane(int idArg, const std::string& levelArg, const std::string& typeArg) :
327  id(idArg), level(levelArg), type(typeArg), successor(UNSET_CONNECTION), predecessor(UNSET_CONNECTION),
328  speed(0), width(NBEdge::UNSPECIFIED_WIDTH), permission(0) { }
329 
331  SVCPermissions computePermission(const NBTypeCont& tc, const std::vector<std::string>& allowed, const std::vector<std::string>& denied) const;
332 
333  int id;
334  std::string level;
335  std::string type;
336  int successor;
338  std::vector < std::pair<double, LaneAttributeChange> > attributeChanges;
339  double speed;
340  double width; //The lane's maximum width
342  std::vector<OpenDriveWidth> widthData;
343  };
344 
345 
354  OpenDriveLaneSection(double sArg);
355 
356 
363  void buildLaneMapping(const NBTypeCont& tc);
364 
365 
371  std::map<int, int> getInnerConnections(OpenDriveXMLTag dir, const OpenDriveLaneSection& prev);
372 
373 
374  bool buildAttributeChanges(const NBTypeCont& tc, std::vector<OpenDriveLaneSection>& newSections);
375  OpenDriveLaneSection buildLaneSection(const NBTypeCont& tc, double startPos);
377  double s;
379  double sOrig;
381  double length;
383  std::map<int, int> laneMap;
385  std::map<OpenDriveXMLTag, std::vector<OpenDriveLane> > lanesByDir;
387  std::string sumoID;
391  std::string rightType;
392  std::string leftType;
396  };
397 
398 
399 
413  OpenDriveSignal(const std::string& idArg, const std::string typeArg, const std::string nameArg,
414  int orientationArg, bool dynamicArg, double sArg) :
415  id(idArg), type(typeArg), name(nameArg),
416  orientation(orientationArg), dynamic(dynamicArg), s(sArg),
418  { }
419 
422 
423  std::string id;
424  std::string type;
425  std::string name;
427  bool dynamic;
428  double s;
430  int minLane;
431  int maxLane;
433  std::string controller;
434  };
435 
436 
446  OpenDriveController(const std::string& idArg, const std::string nameArg) :
447  id(idArg), name(nameArg) { }
448 
451 
452  std::string id;
453  std::string name;
454  std::vector<std::string> signalIDs;
455  std::string junction;
456  };
457 
462  struct Connection {
463  std::string fromEdge;
464  std::string toEdge;
465  int fromLane;
466  int toLane;
469  bool all;
470  std::string origID;
471  int origLane;
473 
474  std::string getDescription() const {
475  return "Connection from=" + fromEdge + "_" + toString(fromLane)
476  + " to=" + toEdge + "_" + toString(toLane)
477  + " fromCP=" + (fromCP == OPENDRIVE_CP_START ? "start" : fromCP == OPENDRIVE_CP_END ? "end" : "unknown")
478  + " toCP=" + (toCP == OPENDRIVE_CP_START ? "start" : toCP == OPENDRIVE_CP_END ? "end" : "unknown")
479  + " all=" + toString(all);
480  //+ " origID=" + origID + " origLane=" + toString(origLane);
481  }
482  };
483 
489  std::string type;
490  std::string name;
491  std::string id;
492  double s;
493  double t;
494  double zOffset;
495  double length;
496  double width;
497  double height;
498  double radius;
499  double hdg;
500  double pitch;
501  double roll;
502  };
503 
508  struct OpenDriveEdge {
509  OpenDriveEdge(const std::string& idArg, const std::string& streetNameArg, const std::string& junctionArg, double lengthArg) :
510  id(idArg),
511  streetName(streetNameArg),
512  junction(junctionArg),
513  length(lengthArg),
514  from(0),
515  to(0) {
516  isInner = junction != "" && junction != "-1";
517  }
518 
519 
526  int getPriority(OpenDriveXMLTag dir) const;
527 
528 
530  std::string id;
532  std::string streetName;
534  std::string junction;
536  double length;
537  std::vector<OpenDriveLink> links;
538  std::vector<OpenDriveGeometry> geometries;
539  std::vector<OpenDriveElevation> elevations;
540  std::vector<OpenDriveLaneOffset> offsets;
544  std::vector<double> laneOffsets;
545  std::vector<OpenDriveLaneSection> laneSections;
546  std::vector<OpenDriveSignal> signals;
547  std::set<Connection> connections;
548  std::vector<OpenDriveObject> objects;
549  bool isInner;
550  };
551 
552 
555  public:
557  explicit sections_by_s_sorter() { }
558 
561  return ls1.s < ls2.s;
562  }
563  };
564 
565  /* @brief A class for search in position/attribute change tuple vectors for the given position */
567  public:
569  explicit same_position_finder(double pos) : myPosition(pos) { }
570 
572  bool operator()(const std::pair<double, LaneAttributeChange>& ps) {
573  return ps.first == myPosition;
574  }
575 
576  private:
578  double myPosition;
579 
580  };
581 
582 protected:
587  NIImporter_OpenDrive(const NBTypeCont& tc, std::map<std::string, OpenDriveEdge*>& edges);
588 
589 
592 
593 
594 
596 
597 
608  void myStartElement(int element, const SUMOSAXAttributes& attrs);
609 
618  void myCharacters(int element, const std::string& chars);
619 
620 
627  void myEndElement(int element);
629 
630  std::map<std::string, OpenDriveSignal>& getSignals() {
631  return mySignals;
632  }
633 
634  std::map<std::string, OpenDriveController>& getControllers() {
635  return myControllers;
636  }
637 
638  std::map<std::string, std::vector<std::string>>& getJunctions2Controllers() {
640  }
641 
642  const OpenDriveController& getController(std::string signalID) {
643  if (mySignals.find(signalID) != mySignals.end() && myControllers.find(mySignals[signalID].controller) != myControllers.end()) {
644  return myControllers[mySignals[signalID].controller];
645  }
646  return myDummyController;
647  }
648 
649  int getTLIndexForController(std::string controllerID) {
650  // sort them by their id
651  std::string junctionID = myControllers[controllerID].junction;
652  std::vector<std::string> junctionControllers;
653  for (auto& it : myControllers) {
654  if (it.second.junction == junctionID) {
655  junctionControllers.push_back(it.first);
656  }
657  }
658  std::sort(junctionControllers.begin(), junctionControllers.end());
659  auto it = std::find(junctionControllers.begin(), junctionControllers.end(), controllerID);
660  return (int)(it - junctionControllers.begin());
661  }
662 
663 
664 private:
665  void addLink(LinkType lt, const std::string& elementType, const std::string& elementID,
666  const std::string& contactPoint);
667  void addGeometryShape(GeometryType type, const std::vector<double>& vals);
668  static void setEdgeLinks2(OpenDriveEdge& e, const std::map<std::string, OpenDriveEdge*>& edges);
669  static void buildConnectionsToOuter(const Connection& c,
670  const std::map<std::string, OpenDriveEdge*>& innerEdges,
671  const std::map<std::string, OpenDriveEdge*>& edges,
672  const NBTypeCont& tc,
673  std::vector<Connection>& into, std::set<Connection>& seen);
674  static bool laneSectionsConnected(OpenDriveEdge* edge, int in, int out);
675  friend bool operator<(const Connection& c1, const Connection& c2);
676  static std::string revertID(const std::string& id);
680 
681  std::map<std::string, OpenDriveEdge*>& myEdges;
682  std::vector<int> myElementStack;
684  std::string myCurrentJunctionID;
689  std::map<std::string, OpenDriveSignal> mySignals;
690  std::map<std::string, OpenDriveController> myControllers;
691  std::map<std::string, std::vector<std::string>> myJunctions2Controllers;
694 
695  static bool myImportAllTypes;
696  static bool myImportWidths;
697  static double myMinWidth;
701 
702 
703 protected:
717  static NBNode* getOrBuildNode(const std::string& id, const Position& pos, NBNodeCont& nc);
718 
719 
720  static PositionVector geomFromLine(const OpenDriveEdge& e, const OpenDriveGeometry& g, double resolution);
721  static PositionVector geomFromSpiral(const OpenDriveEdge& e, const OpenDriveGeometry& g, double resolution);
722  static PositionVector geomFromArc(const OpenDriveEdge& e, const OpenDriveGeometry& g, double resolution);
723  static PositionVector geomFromPoly(const OpenDriveEdge& e, const OpenDriveGeometry& g, double resolution);
724  static PositionVector geomFromParamPoly(const OpenDriveEdge& e, const OpenDriveGeometry& g, double resolution);
725  static Position calculateStraightEndPoint(double hdg, double length, const Position& start);
726  static void calculateCurveCenter(double* ad_x, double* ad_y, double ad_radius, double ad_hdg);
727  static void calcPointOnCurve(double* ad_x, double* ad_y, double ad_centerX, double ad_centerY,
728  double ad_r, double ad_length);
729 
730 
734  static void computeShapes(std::map<std::string, OpenDriveEdge*>& edges);
735 
736  static bool hasNonLinearElevation(OpenDriveEdge& e);
737 
739  static std::vector<double> discretizeOffsets(PositionVector& geom, const std::vector<OpenDriveLaneOffset>& offsets, const std::string& id);
740 
741  static void addOffsets(bool left, PositionVector& geom, const std::vector<OpenDriveLaneOffset>& offsets, const std::string& id, std::vector<double>& result);
742 
748  static void revisitLaneSections(const NBTypeCont& tc, std::map<std::string, OpenDriveEdge*>& edges);
749 
750  static void setNodeSecure(NBNodeCont& nc, OpenDriveEdge& e,
751  const std::string& nodeID, NIImporter_OpenDrive::LinkType lt, std::vector<NodeSet>& joinedNodeIDs);
752 
753  static NBTrafficLightDefinition* getTLSSecure(NBEdge* inEdge, /*const NBEdge::Connection& conn,*/ NBNetBuilder& nb);
754 
755 
756  static std::pair<NBEdge*, NBEdge*> retrieveSignalEdges(NBNetBuilder& nb, const std::string& fromID, const std::string& toID, const std::string& junction);
757 
758  static void splitMinWidths(OpenDriveEdge* e, const NBTypeCont& tc, double minDist);
759 
760  static void findWidthSplit(const NBTypeCont& tc, std::vector<OpenDriveLane>& lanes,
761  int section, double sectionStart, double sectionEnd,
762  std::vector<double>& splitPositions);
763 
764  static void sanitizeWidths(OpenDriveEdge* e);
765  static void sanitizeWidths(std::vector<OpenDriveLane>& lanes, double length);
766 
767  static void setStraightConnections(std::vector<OpenDriveLane>& lanes);
768  static void recomputeWidths(OpenDriveLaneSection& sec, double start, double end, double sectionStart, double sectionEnd);
769  static void recomputeWidths(std::vector<OpenDriveLane>& lanes, double start, double end, double sectionStart, double sectionEnd);
770  static void setLaneAttributes(const OpenDriveEdge* e, NBEdge::Lane& sumoLane, const OpenDriveLane& odLane, bool saveOrigIDs, const NBTypeCont& tc);
771  static void writeRoadObjects(const OpenDriveEdge* e);
772 
775 
778 
779  class LaneSorter {
780  public:
782  explicit LaneSorter() {}
783 
785  int operator()(const OpenDriveLane& a, const OpenDriveLane& b) const {
786  // sort from the reference line outwards (desceding order of sumo lane ids)
787  return abs(a.id) < abs(b.id);
788  }
789 
790  };
791 
792 };
#define UNSET_CONNECTION
#define UNSET_LANEVALIDITY
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A handler which converts occurring elements and attributes into enums.
The representation of a single edge during network building.
Definition: NBEdge.h:92
Instance responsible for building networks.
Definition: NBNetBuilder.h:107
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:57
Represents a single node (junction) during network building.
Definition: NBNode.h:66
The base class for traffic light logic definitions.
A storage for available edgeTypes of edges.
Definition: NBTypeCont.h:52
int operator()(const OpenDriveLane &a, const OpenDriveLane &b) const
comparing operation
double myPosition
The position to search for.
bool operator()(const std::pair< double, LaneAttributeChange > &ps)
the comparing function
A class for sorting lane sections by their s-value.
int operator()(const OpenDriveLaneSection &ls1, const OpenDriveLaneSection &ls2)
Sorting function; compares OpenDriveLaneSection::s.
Importer for networks stored in openDrive format.
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given SUMO file.
static void recomputeWidths(OpenDriveLaneSection &sec, double start, double end, double sectionStart, double sectionEnd)
static std::vector< double > discretizeOffsets(PositionVector &geom, const std::vector< OpenDriveLaneOffset > &offsets, const std::string &id)
transform Poly3 into a list of offsets, adding intermediate points to geom if needed
static void addOffsets(bool left, PositionVector &geom, const std::vector< OpenDriveLaneOffset > &offsets, const std::string &id, std::vector< double > &result)
std::map< std::string, OpenDriveSignal > & getSignals()
static void writeRoadObjects(const OpenDriveEdge *e)
static std::pair< NBEdge *, NBEdge * > retrieveSignalEdges(NBNetBuilder &nb, const std::string &fromID, const std::string &toID, const std::string &junction)
static PositionVector geomFromParamPoly(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
void myEndElement(int element)
Called when a closing tag occurs.
static void calcPointOnCurve(double *ad_x, double *ad_y, double ad_centerX, double ad_centerY, double ad_r, double ad_length)
OpenDriveXMLTag
Numbers representing openDrive-XML - element names.
void addGeometryShape(GeometryType type, const std::vector< double > &vals)
static void setStraightConnections(std::vector< OpenDriveLane > &lanes)
OpenDriveController myCurrentController
const OpenDriveController & getController(std::string signalID)
static void setLaneAttributes(const OpenDriveEdge *e, NBEdge::Lane &sumoLane, const OpenDriveLane &odLane, bool saveOrigIDs, const NBTypeCont &tc)
std::vector< int > myElementStack
ElementType
OpenDrive element type enumeration.
static void buildConnectionsToOuter(const Connection &c, const std::map< std::string, OpenDriveEdge * > &innerEdges, const std::map< std::string, OpenDriveEdge * > &edges, const NBTypeCont &tc, std::vector< Connection > &into, std::set< Connection > &seen)
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
static StringBijection< int >::Entry openDriveAttrs[]
The names of openDrive-XML attributes (for passing to GenericSAXHandler)
std::map< std::string, OpenDriveSignal > mySignals
static bool laneSectionsConnected(OpenDriveEdge *edge, int in, int out)
void addLink(LinkType lt, const std::string &elementType, const std::string &elementID, const std::string &contactPoint)
static OpenDriveController myDummyController
std::map< std::string, std::vector< std::string > > myJunctions2Controllers
OpenDriveXMLAttr
Numbers representing openDrive-XML - attributes.
static PositionVector geomFromSpiral(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
static PositionVector geomFromLine(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
static NBNode * getOrBuildNode(const std::string &id, const Position &pos, NBNodeCont &nc)
Builds a node or returns the already built.
const NBTypeCont & myTypeContainer
NIImporter_OpenDrive(const NBTypeCont &tc, std::map< std::string, OpenDriveEdge * > &edges)
Constructor.
static Position calculateStraightEndPoint(double hdg, double length, const Position &start)
OpenDriveXMLTag myCurrentLaneDirection
static PositionVector geomFromPoly(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
static void revisitLaneSections(const NBTypeCont &tc, std::map< std::string, OpenDriveEdge * > &edges)
Rechecks lane sections of the given edges.
static bool myIgnoreMisplacedSignals
static void sanitizeWidths(OpenDriveEdge *e)
GeometryType
OpenDrive geometry type enumeration.
static void computeShapes(std::map< std::string, OpenDriveEdge * > &edges)
Computes a polygon representation of each edge's geometry.
static void calculateCurveCenter(double *ad_x, double *ad_y, double ad_radius, double ad_hdg)
static std::string revertID(const std::string &id)
static void setEdgeLinks2(OpenDriveEdge &e, const std::map< std::string, OpenDriveEdge * > &edges)
static void splitMinWidths(OpenDriveEdge *e, const NBTypeCont &tc, double minDist)
friend bool operator<(const Connection &c1, const Connection &c2)
std::map< std::string, OpenDriveController > myControllers
void myCharacters(int element, const std::string &chars)
Callback method for characters to implement by derived classes.
static NBTrafficLightDefinition * getTLSSecure(NBEdge *inEdge, NBNetBuilder &nb)
static StringBijection< int >::Entry openDriveTags[]
The names of openDrive-XML elements (for passing to GenericSAXHandler)
Poly3 OpenDriveElevation
LaneOffset has the same fields as Elevation.
std::map< std::string, OpenDriveController > & getControllers()
ContactPoint myCurrentContactPoint
ContactPoint
OpenDrive contact type enumeration.
static void findWidthSplit(const NBTypeCont &tc, std::vector< OpenDriveLane > &lanes, int section, double sectionStart, double sectionEnd, std::vector< double > &splitPositions)
static PositionVector geomFromArc(const OpenDriveEdge &e, const OpenDriveGeometry &g, double resolution)
static void setNodeSecure(NBNodeCont &nc, OpenDriveEdge &e, const std::string &nodeID, NIImporter_OpenDrive::LinkType lt, std::vector< NodeSet > &joinedNodeIDs)
LinkType
OpenDrive link type enumeration.
static bool hasNonLinearElevation(OpenDriveEdge &e)
std::map< std::string, OpenDriveEdge * > & myEdges
int getTLIndexForController(std::string controllerID)
std::map< std::string, std::vector< std::string > > & getJunctions2Controllers()
A storage for options typed value containers)
Definition: OptionsCont.h:89
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A list of positions.
Encapsulated SAX-Attributes.
An (internal) definition of a single lane of an edge.
Definition: NBEdge.h:143
A connection between two roads.
Attribute set applied at a certain position along a lane.
Representation of a signal group.
OpenDriveController()
dummy constructor for use in maps
OpenDriveController(const std::string &idArg, const std::string nameArg)
Constructor.
Representation of an openDrive "link".
double length
The length of the edge.
std::string id
The id of the edge.
std::string junction
The id of the junction the edge belongs to.
std::string streetName
The road name of the edge.
int getPriority(OpenDriveXMLTag dir) const
Returns the edge's priority, regarding the direction.
OpenDriveEdge(const std::string &idArg, const std::string &streetNameArg, const std::string &junctionArg, double lengthArg)
std::vector< OpenDriveLink > links
std::vector< OpenDriveSignal > signals
std::vector< OpenDriveLaneSection > laneSections
std::vector< OpenDriveLaneOffset > offsets
std::vector< OpenDriveObject > objects
std::vector< OpenDriveGeometry > geometries
std::vector< OpenDriveElevation > elevations
Representation of an OpenDrive geometry part.
OpenDriveGeometry(double lengthArg, double sArg, double xArg, double yArg, double hdgArg)
Constructor.
int predecessor
The lane's predecessor lane.
OpenDriveLane(int idArg, const std::string &levelArg, const std::string &typeArg)
Constructor.
int successor
The lane's successor lane.
std::vector< OpenDriveWidth > widthData
std::string level
The lane's level (not used)
std::vector< std::pair< double, LaneAttributeChange > > attributeChanges
List of permission and speed changes.
double speed
The lane's speed (set in post-processing)
SVCPermissions computePermission(const NBTypeCont &tc, const std::vector< std::string > &allowed, const std::vector< std::string > &denied) const
compute the actual SUMO lane permissions given the lane type as a start solution
SVCPermissions permission
The access permissions (set in post-processing)
OpenDriveLaneSection buildLaneSection(const NBTypeCont &tc, double startPos)
bool buildAttributeChanges(const NBTypeCont &tc, std::vector< OpenDriveLaneSection > &newSections)
double length
The length of this lane section.
std::map< OpenDriveXMLTag, std::vector< OpenDriveLane > > lanesByDir
The lanes, sorted by their direction.
double discardedInnerWidthLeft
average width of removed inside lanes
std::map< int, int > laneMap
A mapping from OpenDrive to SUMO-index (the first is signed, the second unsigned)
std::string sumoID
The id (generic, without the optionally leading '-') of the edge generated for this section.
std::string rightType
the composite type built from all used lane types
int rightLaneNumber
The number of lanes on the right and on the left side, respectively.
double sOrig
The original starting offset of this lane section (differs from s if the section had to be split)
void buildLaneMapping(const NBTypeCont &tc)
Build the mapping from OpenDrive to SUMO lanes.
std::map< int, int > getInnerConnections(OpenDriveXMLTag dir, const OpenDriveLaneSection &prev)
Returns the links from the previous to this lane section.
double s
The starting offset of this lane section.
OpenDriveSignal(const std::string &idArg, const std::string typeArg, const std::string nameArg, int orientationArg, bool dynamicArg, double sArg)
Constructor.
std::string controller
the controller ID
OpenDriveSignal()
dummy constructor for use in maps
double computeAt(double pos) const
Poly3(double _s, double _a, double _b, double _c, double _d)
Constructor.