Module scenariogeneration.xodr.geometry
scenariogeneration https://github.com/pyoscx/scenariogeneration
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
Copyright (c) 2022 The scenariogeneration Authors.
Functions
def wrap_pi(angle)
-
Expand source code
def wrap_pi(angle): return angle % (2 * np.pi)
Classes
class AdjustablePlanview (left_lane_defs=None,
right_lane_defs=None,
center_road_mark=None,
lane_width=None,
lane_width_end=None)-
Expand source code
class AdjustablePlanview: """AdjustablePlanview can be used to fit a geometry between two fixed roads.""" def __init__( self, left_lane_defs=None, right_lane_defs=None, center_road_mark=None, lane_width=None, lane_width_end=None, ): self.fixed = False self.adjusted = False self.left_lane_defs = left_lane_defs self.right_lane_defs = right_lane_defs self.center_road_mark = center_road_mark self.lane_width = lane_width self.lane_width_end = lane_width_end
AdjustablePlanview can be used to fit a geometry between two fixed roads.
class Arc (curvature, length=None, angle=None)
-
Expand source code
class Arc(_BaseGeometry): """the Arc creates a arc type of geometry Parameters ---------- curvature (float): curvature of the arc length (float): length of the arc (optional or use angle) angle (float): angle of the arc (optional or use length) Attributes ---------- curvature (float): curvature of the arc length (float): length of the arc angle (float): angle of the arc Methods ------- get_element() Returns the full ElementTree of the class get_attributes() Returns a dictionary of all attributes of the class get_end_data(x,y,h) Returns the end point of the geometry """ def __init__(self, curvature, length=None, angle=None): """initalizes the Arc Parameters ---------- curvature (float): curvature of the arc length (float): length of the arc (optional or use angle) angle (float): angle of the arc (optional or use length) """ super().__init__() if length == None and angle == None: raise NotEnoughInputArguments("neither length nor angle defined, for arc") if length != None and angle != None: raise ToManyOptionalArguments( "both length and angle set, only one is requiered" ) self.length = length self.angle = angle if curvature == 0: raise ValueError( "You are creating a straight line, please use Line instead" ) self.curvature = curvature if self.length: self.angle = self.length * self.curvature if self.angle: _, _, _, self.length = self.get_end_data(0, 0, 0) def __eq__(self, other): if isinstance(other, Arc) and super().__eq__(other): if self.get_attributes() == other.get_attributes(): return True return False def get_end_data(self, x, y, h): """Returns information about the end point of the geometry Parameters ---------- x (float): x start point of the geometry y (float): y start point of the geometry h (float): start heading of the geometry Returns --------- x (float): the final x point y (float): the final y point h (float): the final heading length (float): length of the element """ radius = 1 / np.abs(self.curvature) if self.curvature < 0: phi_0 = h + np.pi / 2 x_0 = x - np.cos(phi_0) * radius y_0 = y - np.sin(phi_0) * radius else: phi_0 = h - np.pi / 2 x_0 = x - np.cos(phi_0) * radius y_0 = y - np.sin(phi_0) * radius if self.length: self.angle = self.length * self.curvature new_ang = self.angle + phi_0 if self.angle: self.length = np.abs(radius * self.angle) new_ang = self.angle + phi_0 new_h = h + self.angle new_x = np.cos(new_ang) * radius + x_0 new_y = np.sin(new_ang) * radius + y_0 return new_x, new_y, new_h, self.length def get_start_data(self, end_x, end_y, end_h): """Returns information about the end point of the geometry Parameters ---------- end_x (float): x final point of the geometry end_y (float): y final point of the geometry end_h (float): final heading of the geometry Returns --------- x (float): the start x point y (float): the start y point h (float): the start heading of the inverse geometry length (float): length of the element """ x = end_x y = end_y h = end_h inv_curv = -self.curvature radius = 1 / np.abs(inv_curv) if inv_curv < 0: phi_0 = h + np.pi / 2 x_0 = x - np.cos(phi_0) * radius y_0 = y - np.sin(phi_0) * radius else: phi_0 = h - np.pi / 2 x_0 = x - np.cos(phi_0) * radius y_0 = y - np.sin(phi_0) * radius if self.length: self.angle = self.length * inv_curv new_ang = self.angle + phi_0 if self.angle: self.length = np.abs(radius * self.angle) new_h = h + self.angle new_x = np.cos(new_ang) * radius + x_0 new_y = np.sin(new_ang) * radius + y_0 return new_x, new_y, new_h, self.length def get_attributes(self): """returns the attributes of the Arc as a dict""" return {"curvature": str(self.curvature)} def get_element(self): """returns the elementTree of the Arc""" element = ET.Element("arc", attrib=self.get_attributes()) self._add_additional_data_to_element(element) return element
the Arc creates a arc type of geometry
Parameters
curvature (float): curvature of the arc length (float): length of the arc (optional or use angle) angle (float): angle of the arc (optional or use length)
Attributes
curvature (float): curvature of the arc length (float): length of the arc angle (float): angle of the arc
Methods
get_element() Returns the full ElementTree of the class get_attributes() Returns a dictionary of all attributes of the class get_end_data(x,y,h) Returns the end point of the geometry
initalizes the Arc
Parameters
curvature (float): curvature of the arc length (float): length of the arc (optional or use angle) angle (float): angle of the arc (optional or use length)
Ancestors
- scenariogeneration.xodr.geometry._BaseGeometry
- XodrBase
Methods
def get_attributes(self)
-
Expand source code
def get_attributes(self): """returns the attributes of the Arc as a dict""" return {"curvature": str(self.curvature)}
returns the attributes of the Arc as a dict
def get_element(self)
-
Expand source code
def get_element(self): """returns the elementTree of the Arc""" element = ET.Element("arc", attrib=self.get_attributes()) self._add_additional_data_to_element(element) return element
returns the elementTree of the Arc
def get_end_data(self, x, y, h)
-
Expand source code
def get_end_data(self, x, y, h): """Returns information about the end point of the geometry Parameters ---------- x (float): x start point of the geometry y (float): y start point of the geometry h (float): start heading of the geometry Returns --------- x (float): the final x point y (float): the final y point h (float): the final heading length (float): length of the element """ radius = 1 / np.abs(self.curvature) if self.curvature < 0: phi_0 = h + np.pi / 2 x_0 = x - np.cos(phi_0) * radius y_0 = y - np.sin(phi_0) * radius else: phi_0 = h - np.pi / 2 x_0 = x - np.cos(phi_0) * radius y_0 = y - np.sin(phi_0) * radius if self.length: self.angle = self.length * self.curvature new_ang = self.angle + phi_0 if self.angle: self.length = np.abs(radius * self.angle) new_ang = self.angle + phi_0 new_h = h + self.angle new_x = np.cos(new_ang) * radius + x_0 new_y = np.sin(new_ang) * radius + y_0 return new_x, new_y, new_h, self.length
Returns information about the end point of the geometry
Parameters
x (float): x start point of the geometry y (float): y start point of the geometry h (float): start heading of the geometry
Returns
x (float): the final x point y (float): the final y point h (float): the final heading length (float): length of the element
def get_start_data(self, end_x, end_y, end_h)
-
Expand source code
def get_start_data(self, end_x, end_y, end_h): """Returns information about the end point of the geometry Parameters ---------- end_x (float): x final point of the geometry end_y (float): y final point of the geometry end_h (float): final heading of the geometry Returns --------- x (float): the start x point y (float): the start y point h (float): the start heading of the inverse geometry length (float): length of the element """ x = end_x y = end_y h = end_h inv_curv = -self.curvature radius = 1 / np.abs(inv_curv) if inv_curv < 0: phi_0 = h + np.pi / 2 x_0 = x - np.cos(phi_0) * radius y_0 = y - np.sin(phi_0) * radius else: phi_0 = h - np.pi / 2 x_0 = x - np.cos(phi_0) * radius y_0 = y - np.sin(phi_0) * radius if self.length: self.angle = self.length * inv_curv new_ang = self.angle + phi_0 if self.angle: self.length = np.abs(radius * self.angle) new_h = h + self.angle new_x = np.cos(new_ang) * radius + x_0 new_y = np.sin(new_ang) * radius + y_0 return new_x, new_y, new_h, self.length
Returns information about the end point of the geometry
Parameters
end_x (float): x final point of the geometry end_y (float): y final point of the geometry end_h (float): final heading of the geometry
Returns
x (float): the start x point y (float): the start y point h (float): the start heading of the inverse geometry length (float): length of the element
Inherited members
class Line (length)
-
Expand source code
class Line(_BaseGeometry): """the line class creates a line type of geometry Parameters ---------- length (float): length of the line Attributes ---------- length (float): length of the line Methods ------- get_element(elementname) Returns the full ElementTree of the class get_end_data(x,y,h) Returns the end point of the geometry """ def __init__(self, length): super().__init__() self.length = length def __eq__(self, other): return super().__eq__(other) def get_end_data(self, x, y, h): """Returns the end point of the geometry Parameters ---------- x (float): x start point of the geometry y (float): y start point of the geometry h (float): start heading of the geometry Returns ---------- x (float): the final x point y (float): the final y point h (float): the final heading length (float): length of the road """ new_x = self.length * np.cos(h) + x new_y = self.length * np.sin(h) + y new_h = h return new_x, new_y, new_h, self.length def get_start_data(self, end_x, end_y, end_h): """Returns the end point of the geometry Parameters ---------- end_x (float): x end point of the geometry end_y (float): y end point of the geometry end_h (float): end heading of the geometry Returns ---------- x (float): the start x point y (float): the start y point h (float): the start heading length (float): length of the road """ start_x = self.length * np.cos(end_h) + end_x start_y = self.length * np.sin(end_h) + end_y start_h = end_h return start_x, start_y, start_h, self.length def get_element(self): """returns the elementTree of the Line""" element = ET.Element("line") self._add_additional_data_to_element(element) return element
the line class creates a line type of geometry
Parameters
length (float): length of the line
Attributes
length (float): length of the line
Methods
get_element(elementname) Returns the full ElementTree of the class get_end_data(x,y,h) Returns the end point of the geometry
initalize the UserData
Ancestors
- scenariogeneration.xodr.geometry._BaseGeometry
- XodrBase
Methods
def get_element(self)
-
Expand source code
def get_element(self): """returns the elementTree of the Line""" element = ET.Element("line") self._add_additional_data_to_element(element) return element
returns the elementTree of the Line
def get_end_data(self, x, y, h)
-
Expand source code
def get_end_data(self, x, y, h): """Returns the end point of the geometry Parameters ---------- x (float): x start point of the geometry y (float): y start point of the geometry h (float): start heading of the geometry Returns ---------- x (float): the final x point y (float): the final y point h (float): the final heading length (float): length of the road """ new_x = self.length * np.cos(h) + x new_y = self.length * np.sin(h) + y new_h = h return new_x, new_y, new_h, self.length
Returns the end point of the geometry
Parameters
x (float): x start point of the geometry y (float): y start point of the geometry h (float): start heading of the geometry
Returns
x (float): the final x point y (float): the final y point h (float): the final heading length (float): length of the road
def get_start_data(self, end_x, end_y, end_h)
-
Expand source code
def get_start_data(self, end_x, end_y, end_h): """Returns the end point of the geometry Parameters ---------- end_x (float): x end point of the geometry end_y (float): y end point of the geometry end_h (float): end heading of the geometry Returns ---------- x (float): the start x point y (float): the start y point h (float): the start heading length (float): length of the road """ start_x = self.length * np.cos(end_h) + end_x start_y = self.length * np.sin(end_h) + end_y start_h = end_h return start_x, start_y, start_h, self.length
Returns the end point of the geometry
Parameters
end_x (float): x end point of the geometry end_y (float): y end point of the geometry end_h (float): end heading of the geometry
Returns
x (float): the start x point y (float): the start y point h (float): the start heading length (float): length of the road
Inherited members
class ParamPoly3 (au, bu, cu, du, av, bv, cv, dv, prange='normalized', length=None)
-
Expand source code
class ParamPoly3(_BaseGeometry): """the ParamPoly3 class creates a parampoly3 type of geometry, in the coordinate systeme U (along road), V (normal to the road) the polynomials are on the form uv(p) = a + b*p + c*p^2 + d*p^3 Parameters ---------- au (float): coefficient a of the u polynomial bu (float): coefficient b of the u polynomial cu (float): coefficient c of the u polynomial du (float): coefficient d of the u polynomial av (float): coefficient a of the v polynomial bv (float): coefficient b of the v polynomial cv (float): coefficient c of the v polynomial dv (float): coefficient d of the v polynomial prange (str): "normalized" or "arcLength" Default: "normalized" length (float): total length of arc, used if prange == arcLength Attributes ---------- au (float): coefficient a of the u polynomial bu (float): coefficient b of the u polynomial cu (float): coefficient c of the u polynomial du (float): coefficient d of the u polynomial av (float): coefficient a of the v polynomial bv (float): coefficient b of the v polynomial cv (float): coefficient c of the v polynomial dv (float): coefficient d of the v polynomial prange (str): "normalized" or "arcLength" Default: "normalized" length (float): total length of arc, used if prange == arcLength Methods ------- get_element(elementname) Returns the full ElementTree of the class get_attributes() Returns a dictionary of all attributes of the class get_end_coordinate(length,x,y,h) Returns the end point of the geometry """ def __init__( self, au, bu, cu, du, av, bv, cv, dv, prange="normalized", length=None ): """initalizes the ParamPoly3 Parameters ---------- au (float): coefficient a of the u polynomial bu (float): coefficient b of the u polynomial cu (float): coefficient c of the u polynomial du (float): coefficient d of the u polynomial av (float): coefficient a of the v polynomial bv (float): coefficient b of the v polynomial cv (float): coefficient c of the v polynomial dv (float): coefficient d of the v polynomial prange (str): "normalized" or "arcLength" Default: "normalized" length (float): total length of arc, used if prange == arcLength """ super().__init__() self.au = au self.bu = bu self.cu = cu self.du = du self.av = av self.bv = bv self.cv = cv self.dv = dv self.prange = prange if prange == "arcLength" and length == None: raise ValueError( "No length was provided for ParamPoly3 with arcLength option" ) if length: self.length = length else: _, _, _, self.length = self.get_end_data(0, 0, 0) def __eq__(self, other): if isinstance(other, ParamPoly3) and super().__eq__(other): if self.get_attributes() == other.get_attributes(): return True return False def _integrand(self, p): """integral function to calulate length of polynomial, #TODO: This is not tested or verified... """ return np.sqrt( (abs(3 * self.du * p**2 + 2 * self.cu * p + self.bu)) ** 2 + (abs(3 * self.dv * p**2 + 2 * self.cv * p + self.bv)) ** 2 ) def get_start_data(self, x, y, h): """Returns the start point of the geometry Parameters ---------- x (float): x end point of the geometry y (float): y end point of the geometry h (float): end heading of the geometry Returns --------- x (float): the start x point y (float): the start y point h (float): the start heading length (float): the length of the geometry """ if self.prange == "normalized": p = 1 I = quad(self._integrand, 0, 1) self.length = I[0] else: p = self.length newu = self.au + self.bu * p + self.cu * p**2 + self.du * p**3 newv = self.av + self.bv * p + self.cv * p**2 + self.dv * p**3 new_x = x - (newu * np.cos(h) - np.sin(h) * newv) new_y = y - (newu * np.sin(h) + np.cos(h) * newv) new_h = h - np.arctan2( self.bv + 2 * self.cv * p + 3 * self.dv * p**2, self.bu + 2 * self.cu * p + 3 * self.du * p**2, ) return new_x, new_y, new_h, self.length def get_end_data(self, x, y, h): """Returns the end point of the geometry Parameters ---------- x (float): x final point of the geometry y (float): y final point of the geometry h (float): final heading of the geometry Returns --------- x (float): the start x point y (float): the start y point h (float): the start heading of the inverse geometry length (float): length of the polynomial """ if self.prange == "normalized": p = 1 I = quad(self._integrand, 0, 1) self.length = I[0] else: p = self.length newu = self.au + self.bu * p + self.cu * p**2 + self.du * p**3 newv = self.av + self.bv * p + self.cv * p**2 + self.dv * p**3 new_x = x + newu * np.cos(h) - np.sin(h) * newv new_y = y + newu * np.sin(h) + np.cos(h) * newv new_h = h + np.arctan2( self.bv + 2 * self.cv * p + 3 * self.dv * p**2, self.bu + 2 * self.cu * p + 3 * self.du * p**2, ) return new_x, new_y, new_h, self.length def get_attributes(self): """returns the attributes of the ParamPoly3 as a dict""" retdict = {} retdict["aU"] = str(self.au) retdict["bU"] = str(self.bu) retdict["cU"] = str(self.cu) retdict["dU"] = str(self.du) retdict["aV"] = str(self.av) retdict["bV"] = str(self.bv) retdict["cV"] = str(self.cv) retdict["dV"] = str(self.dv) retdict["pRange"] = self.prange return retdict def get_element(self): """returns the elementTree of the ParamPoly3""" element = ET.Element("paramPoly3", attrib=self.get_attributes()) self._add_additional_data_to_element(element) return element
the ParamPoly3 class creates a parampoly3 type of geometry, in the coordinate systeme U (along road), V (normal to the road)
the polynomials are on the form uv(p) = a + bp + cp^2 + d*p^3
Parameters
au (float): coefficient a of the u polynomial bu (float): coefficient b of the u polynomial cu (float): coefficient c of the u polynomial du (float): coefficient d of the u polynomial av (float): coefficient a of the v polynomial bv (float): coefficient b of the v polynomial cv (float): coefficient c of the v polynomial dv (float): coefficient d of the v polynomial prange (str): "normalized" or "arcLength" Default: "normalized" length (float): total length of arc, used if prange == arcLength
Attributes
au (float): coefficient a of the u polynomial bu (float): coefficient b of the u polynomial cu (float): coefficient c of the u polynomial du (float): coefficient d of the u polynomial av (float): coefficient a of the v polynomial bv (float): coefficient b of the v polynomial cv (float): coefficient c of the v polynomial dv (float): coefficient d of the v polynomial prange (str): "normalized" or "arcLength" Default: "normalized" length (float): total length of arc, used if prange == arcLength
Methods
get_element(elementname) Returns the full ElementTree of the class get_attributes() Returns a dictionary of all attributes of the class get_end_coordinate(length,x,y,h) Returns the end point of the geometry
initalizes the ParamPoly3
Parameters
au (float): coefficient a of the u polynomial bu (float): coefficient b of the u polynomial cu (float): coefficient c of the u polynomial du (float): coefficient d of the u polynomial av (float): coefficient a of the v polynomial bv (float): coefficient b of the v polynomial cv (float): coefficient c of the v polynomial dv (float): coefficient d of the v polynomial prange (str): "normalized" or "arcLength" Default: "normalized" length (float): total length of arc, used if prange == arcLength
Ancestors
- scenariogeneration.xodr.geometry._BaseGeometry
- XodrBase
Methods
def get_attributes(self)
-
Expand source code
def get_attributes(self): """returns the attributes of the ParamPoly3 as a dict""" retdict = {} retdict["aU"] = str(self.au) retdict["bU"] = str(self.bu) retdict["cU"] = str(self.cu) retdict["dU"] = str(self.du) retdict["aV"] = str(self.av) retdict["bV"] = str(self.bv) retdict["cV"] = str(self.cv) retdict["dV"] = str(self.dv) retdict["pRange"] = self.prange return retdict
returns the attributes of the ParamPoly3 as a dict
def get_element(self)
-
Expand source code
def get_element(self): """returns the elementTree of the ParamPoly3""" element = ET.Element("paramPoly3", attrib=self.get_attributes()) self._add_additional_data_to_element(element) return element
returns the elementTree of the ParamPoly3
def get_end_data(self, x, y, h)
-
Expand source code
def get_end_data(self, x, y, h): """Returns the end point of the geometry Parameters ---------- x (float): x final point of the geometry y (float): y final point of the geometry h (float): final heading of the geometry Returns --------- x (float): the start x point y (float): the start y point h (float): the start heading of the inverse geometry length (float): length of the polynomial """ if self.prange == "normalized": p = 1 I = quad(self._integrand, 0, 1) self.length = I[0] else: p = self.length newu = self.au + self.bu * p + self.cu * p**2 + self.du * p**3 newv = self.av + self.bv * p + self.cv * p**2 + self.dv * p**3 new_x = x + newu * np.cos(h) - np.sin(h) * newv new_y = y + newu * np.sin(h) + np.cos(h) * newv new_h = h + np.arctan2( self.bv + 2 * self.cv * p + 3 * self.dv * p**2, self.bu + 2 * self.cu * p + 3 * self.du * p**2, ) return new_x, new_y, new_h, self.length
Returns the end point of the geometry
Parameters
x (float): x final point of the geometry y (float): y final point of the geometry h (float): final heading of the geometry
Returns
x (float): the start x point y (float): the start y point h (float): the start heading of the inverse geometry length (float): length of the polynomial
def get_start_data(self, x, y, h)
-
Expand source code
def get_start_data(self, x, y, h): """Returns the start point of the geometry Parameters ---------- x (float): x end point of the geometry y (float): y end point of the geometry h (float): end heading of the geometry Returns --------- x (float): the start x point y (float): the start y point h (float): the start heading length (float): the length of the geometry """ if self.prange == "normalized": p = 1 I = quad(self._integrand, 0, 1) self.length = I[0] else: p = self.length newu = self.au + self.bu * p + self.cu * p**2 + self.du * p**3 newv = self.av + self.bv * p + self.cv * p**2 + self.dv * p**3 new_x = x - (newu * np.cos(h) - np.sin(h) * newv) new_y = y - (newu * np.sin(h) + np.cos(h) * newv) new_h = h - np.arctan2( self.bv + 2 * self.cv * p + 3 * self.dv * p**2, self.bu + 2 * self.cu * p + 3 * self.du * p**2, ) return new_x, new_y, new_h, self.length
Returns the start point of the geometry
Parameters
x (float): x end point of the geometry y (float): y end point of the geometry h (float): end heading of the geometry
Returns
x (float): the start x point y (float): the start y point h (float): the start heading length (float): the length of the geometry
Inherited members
class PlanView (x_start=None, y_start=None, h_start=None)
-
Expand source code
class PlanView(XodrBase): """the PlanView is the geometrical description of a road, Parameters ---------- x_start (float): start x coordinate of the first geometry Default: None y_start (float): start y coordinate of the first geometry Default: None h_start (float): starting heading of the first geometry Default: None Attributes ---------- present_x (float): the start x coordinate of the next geometry added present_y (float): the y coordinate of the next geometry added present_h (float): the heading coordinate of the next geometry added present_s (float): the along road measure of the next geometry added Methods ------- get_element(elementname) Returns the full ElementTree of the class get_total_length() Returns the full length of the PlanView add_geometry(geom,lenght) adds a new geometry entry to the planeview set_start_point(x_start,y_start,h_start) sets the start point and heading of the planview adjust_geometries() based on the start point, it will adjust all geometries in the planview """ def __init__(self, x_start=None, y_start=None, h_start=None): """initalizes the PlanView Note: if multiple roads are used, the start values can be recalculated. """ super().__init__() self.present_x = 0 self.present_y = 0 self.present_h = 0 self.present_s = 0 self.fixed = False if all([x_start != None, y_start != None, h_start != None]): self.set_start_point(x_start, y_start, h_start) elif any([x_start != None, y_start != None, h_start != None]): raise NotEnoughInputArguments( "If a start position is wanted for the PlanView, all inputs must be used." ) self.x_start = None self.y_start = None self.h_start = None self.x_end = None self.y_end = None self.h_end = None self._raw_geometries = [] self._adjusted_geometries = [] self._overridden_headings = [] self.adjusted = False # variable to track what mode of adding geometries are used self._addition_mode = None def __eq__(self, other): if isinstance(other, PlanView) and super().__eq__(other): if self.adjusted and other.adjusted: if self._adjusted_geometries == other._adjusted_geometries: return True elif not self.adjusted and not other.adjusted: Warning( "Comparing non adjusted geometries, default value will always be False" ) return False return False def add_geometry(self, geom, heading=None): """add_geometry adds a geometry to the planview and will stich together all geometries (in order the order added) Should be used together with "adjust_roads_and_lanes" in the OpenDrive class. NOTE: DO NOT MIX WITH with add_fixed_geometry Parameters ---------- geom (_BaseGeometry): the type of geometry heading (float): override the previous heading (optional), not recommended if used, use for ALL geometries """ if self._addition_mode == "add_fixed_geometry": raise MixOfGeometryAddition( "A fixed geometry has already been added, please use either add_geometry or add_fixed_geometry" ) if heading is not None: self._overridden_headings.append(heading) if not isinstance(geom, _BaseGeometry): raise TypeError("geom_type is not of type _BaseGeometry.") self._raw_geometries.append(geom) self._addition_mode = "add_geometry" return self def add_fixed_geometry(self, geom, x_start, y_start, h_start, s=None): """add_fixed_geometry adds a geometry to a certain point to the planview if s is used, the values will be coded and is up to the user to make correct, not for a correct opendrive file please add the geometires in order if s is not used, the geometries are supposed to be added in order (and s will be calculated) NOTE: DO NOT MIX WITH the method add_geometry Parameters ---------- geom (Line, Spiral, ParamPoly3, or Arc): the geometry to add x_start (float): start x position of the geometry y_start (float): start y position of the geometry h_start (float): start heading of the geometry s (float): start s value of the geometry (optional) Default: None """ if self._addition_mode == "add_geometry": raise MixOfGeometryAddition( "A geometry has already been added with add_geometry, please use either add_geometry, or add_fixed_geometry not both" ) if s != None: pres_s = s else: pres_s = self.present_s if not self.fixed: self.x_start = x_start self.y_start = y_start self.h_start = h_start self.fixed = True newgeom = _Geometry(pres_s, x_start, y_start, h_start, geom) self._adjusted_geometries.append(newgeom) self.x_end, self.y_end, self.h_end, length = newgeom.get_end_data() self.present_s += length self.adjusted = True self._addition_mode = "add_fixed_geometry" return self def set_start_point(self, x_start=0, y_start=0, h_start=0): """sets the start point of the planview Parameters ---------- x_start (float): start x coordinate of the first geometry Default: 0 y_start (float): start y coordinate of the first geometry Default: 0 h_start (float): starting heading of the first geometry Default: 0 """ self.present_x = x_start self.present_y = y_start self.present_h = h_start self.fixed = True def get_start_point(self): """returns the start point of the planview Parameters ---------- """ return self.x_start, self.y_start, self.h_start # return self._adjusted_geometries[-1].get_end_point def get_end_point(self): """sets the start point of the planview Parameters ---------- x_start (float): start x coordinate of the first geometry Default: 0 y_start (float): start y coordinate of the first geometry Default: 0 h_start (float): starting heading of the first geometry Default: 0 """ return self.x_end, self.y_end, self.h_end def adjust_geometries(self, from_end=False): """Adjusts all geometries to have the correct start point and heading Parameters ---------- from_end ([optional]bool): states if (self.present_x, self.present_y, self.present_h) are being interpreted as starting point or ending point of the geometry """ if from_end == False: self.x_start = self.present_x self.y_start = self.present_y self.h_start = self.present_h for i in range(len(self._raw_geometries)): if len(self._overridden_headings) > 0: self.present_h = self._overridden_headings[i] newgeom = _Geometry( self.present_s, self.present_x, self.present_y, self.present_h, self._raw_geometries[i], ) ( self.present_x, self.present_y, self.present_h, length, ) = newgeom.get_end_data() self.present_s += length self._adjusted_geometries.append(newgeom) self.x_end = self.present_x self.y_end = self.present_y self.h_end = wrap_pi(self.present_h) else: self.x_end = self.present_x self.y_end = self.present_y self.h_end = self.present_h + np.pi lengths = [] for i in range(len(self._raw_geometries) - 1, -1, -1): newgeom = _Geometry( self.present_s, self.present_x, self.present_y, self.present_h, self._raw_geometries[i], ) ( self.present_x, self.present_y, self.present_h, partial_length, ) = newgeom.get_start_data() lengths.append(partial_length) self._adjusted_geometries.append(newgeom) self.x_start = self.present_x self.y_start = self.present_y self.h_start = wrap_pi(self.present_h + np.pi) length = sum(lengths) self.present_s = 0 for i in range(len(self._adjusted_geometries) - 1, -1, -1): self._adjusted_geometries[i].set_s(self.present_s) self.present_s += lengths[i] self._adjusted_geometries.reverse() self.h_start = wrap_pi(self.h_start) self.h_end = wrap_pi(self.h_end) self.adjusted = True def get_total_length(self): """returns the total length of the planView""" if self.adjusted: return self.present_s else: return sum([x.length for x in self._raw_geometries]) def get_element(self): """returns the elementTree of the WorldPostion""" element = ET.Element("planView") self._add_additional_data_to_element(element) for geom in self._adjusted_geometries: element.append(geom.get_element()) return element
the PlanView is the geometrical description of a road,
Parameters
x_start (float): start x coordinate of the first geometry Default: None y_start (float): start y coordinate of the first geometry Default: None h_start (float): starting heading of the first geometry Default: None
Attributes
present_x (float): the start x coordinate of the next geometry added present_y (float): the y coordinate of the next geometry added present_h (float): the heading coordinate of the next geometry added present_s (float): the along road measure of the next geometry added
Methods
get_element(elementname) Returns the full ElementTree of the class get_total_length() Returns the full length of the PlanView add_geometry(geom,lenght) adds a new geometry entry to the planeview set_start_point(x_start,y_start,h_start) sets the start point and heading of the planview adjust_geometries() based on the start point, it will adjust all geometries in the planview
initalizes the PlanView Note: if multiple roads are used, the start values can be recalculated.
Ancestors
Methods
def add_fixed_geometry(self, geom, x_start, y_start, h_start, s=None)
-
Expand source code
def add_fixed_geometry(self, geom, x_start, y_start, h_start, s=None): """add_fixed_geometry adds a geometry to a certain point to the planview if s is used, the values will be coded and is up to the user to make correct, not for a correct opendrive file please add the geometires in order if s is not used, the geometries are supposed to be added in order (and s will be calculated) NOTE: DO NOT MIX WITH the method add_geometry Parameters ---------- geom (Line, Spiral, ParamPoly3, or Arc): the geometry to add x_start (float): start x position of the geometry y_start (float): start y position of the geometry h_start (float): start heading of the geometry s (float): start s value of the geometry (optional) Default: None """ if self._addition_mode == "add_geometry": raise MixOfGeometryAddition( "A geometry has already been added with add_geometry, please use either add_geometry, or add_fixed_geometry not both" ) if s != None: pres_s = s else: pres_s = self.present_s if not self.fixed: self.x_start = x_start self.y_start = y_start self.h_start = h_start self.fixed = True newgeom = _Geometry(pres_s, x_start, y_start, h_start, geom) self._adjusted_geometries.append(newgeom) self.x_end, self.y_end, self.h_end, length = newgeom.get_end_data() self.present_s += length self.adjusted = True self._addition_mode = "add_fixed_geometry" return self
add_fixed_geometry adds a geometry to a certain point to the planview
if s is used, the values will be coded and is up to the user to make correct, not for a correct opendrive file please add the geometires in order if s is not used, the geometries are supposed to be added in order (and s will be calculated) NOTE: DO NOT MIX WITH the method add_geometry
Parameters
geom (Line, Spiral, ParamPoly3, or Arc): the geometry to add x_start (float): start x position of the geometry y_start (float): start y position of the geometry h_start (float): start heading of the geometry s (float): start s value of the geometry (optional) Default: None
def add_geometry(self, geom, heading=None)
-
Expand source code
def add_geometry(self, geom, heading=None): """add_geometry adds a geometry to the planview and will stich together all geometries (in order the order added) Should be used together with "adjust_roads_and_lanes" in the OpenDrive class. NOTE: DO NOT MIX WITH with add_fixed_geometry Parameters ---------- geom (_BaseGeometry): the type of geometry heading (float): override the previous heading (optional), not recommended if used, use for ALL geometries """ if self._addition_mode == "add_fixed_geometry": raise MixOfGeometryAddition( "A fixed geometry has already been added, please use either add_geometry or add_fixed_geometry" ) if heading is not None: self._overridden_headings.append(heading) if not isinstance(geom, _BaseGeometry): raise TypeError("geom_type is not of type _BaseGeometry.") self._raw_geometries.append(geom) self._addition_mode = "add_geometry" return self
add_geometry adds a geometry to the planview and will stich together all geometries (in order the order added)
Should be used together with "adjust_roads_and_lanes" in the OpenDrive class. NOTE: DO NOT MIX WITH with add_fixed_geometry
Parameters
geom (_BaseGeometry): the type of geometry heading (float): override the previous heading (optional), not recommended if used, use for ALL geometries
def adjust_geometries(self, from_end=False)
-
Expand source code
def adjust_geometries(self, from_end=False): """Adjusts all geometries to have the correct start point and heading Parameters ---------- from_end ([optional]bool): states if (self.present_x, self.present_y, self.present_h) are being interpreted as starting point or ending point of the geometry """ if from_end == False: self.x_start = self.present_x self.y_start = self.present_y self.h_start = self.present_h for i in range(len(self._raw_geometries)): if len(self._overridden_headings) > 0: self.present_h = self._overridden_headings[i] newgeom = _Geometry( self.present_s, self.present_x, self.present_y, self.present_h, self._raw_geometries[i], ) ( self.present_x, self.present_y, self.present_h, length, ) = newgeom.get_end_data() self.present_s += length self._adjusted_geometries.append(newgeom) self.x_end = self.present_x self.y_end = self.present_y self.h_end = wrap_pi(self.present_h) else: self.x_end = self.present_x self.y_end = self.present_y self.h_end = self.present_h + np.pi lengths = [] for i in range(len(self._raw_geometries) - 1, -1, -1): newgeom = _Geometry( self.present_s, self.present_x, self.present_y, self.present_h, self._raw_geometries[i], ) ( self.present_x, self.present_y, self.present_h, partial_length, ) = newgeom.get_start_data() lengths.append(partial_length) self._adjusted_geometries.append(newgeom) self.x_start = self.present_x self.y_start = self.present_y self.h_start = wrap_pi(self.present_h + np.pi) length = sum(lengths) self.present_s = 0 for i in range(len(self._adjusted_geometries) - 1, -1, -1): self._adjusted_geometries[i].set_s(self.present_s) self.present_s += lengths[i] self._adjusted_geometries.reverse() self.h_start = wrap_pi(self.h_start) self.h_end = wrap_pi(self.h_end) self.adjusted = True
Adjusts all geometries to have the correct start point and heading
Parameters
from_end ([optional]bool): states if (self.present_x, self.present_y, self.present_h) are being interpreted as starting point or ending point of the geometry
def get_element(self)
-
Expand source code
def get_element(self): """returns the elementTree of the WorldPostion""" element = ET.Element("planView") self._add_additional_data_to_element(element) for geom in self._adjusted_geometries: element.append(geom.get_element()) return element
returns the elementTree of the WorldPostion
def get_end_point(self)
-
Expand source code
def get_end_point(self): """sets the start point of the planview Parameters ---------- x_start (float): start x coordinate of the first geometry Default: 0 y_start (float): start y coordinate of the first geometry Default: 0 h_start (float): starting heading of the first geometry Default: 0 """ return self.x_end, self.y_end, self.h_end
sets the start point of the planview
Parameters
x_start (float): start x coordinate of the first geometry Default: 0
y_start (float): start y coordinate of the first geometry Default: 0
h_start (float): starting heading of the first geometry Default: 0
def get_start_point(self)
-
Expand source code
def get_start_point(self): """returns the start point of the planview Parameters ---------- """ return self.x_start, self.y_start, self.h_start # return self._adjusted_geometries[-1].get_end_point
returns the start point of the planview
Parameters
def get_total_length(self)
-
Expand source code
def get_total_length(self): """returns the total length of the planView""" if self.adjusted: return self.present_s else: return sum([x.length for x in self._raw_geometries])
returns the total length of the planView
def set_start_point(self, x_start=0, y_start=0, h_start=0)
-
Expand source code
def set_start_point(self, x_start=0, y_start=0, h_start=0): """sets the start point of the planview Parameters ---------- x_start (float): start x coordinate of the first geometry Default: 0 y_start (float): start y coordinate of the first geometry Default: 0 h_start (float): starting heading of the first geometry Default: 0 """ self.present_x = x_start self.present_y = y_start self.present_h = h_start self.fixed = True
sets the start point of the planview
Parameters
x_start (float): start x coordinate of the first geometry Default: 0
y_start (float): start y coordinate of the first geometry Default: 0
h_start (float): starting heading of the first geometry Default: 0
Inherited members
class Spiral (curvstart, curvend, length=None, angle=None, cdot=None)
-
Expand source code
class Spiral(_BaseGeometry): """the Spiral (Clothoid) creates a spiral type of geometry Parameters ---------- curvstart (float): starting curvature of the Spiral curvend (float): final curvature of the Spiral length (float): length of the spiral (optional, or use, angle, or cdot) angle (float): the angle of the spiral (optional, or use length, or cdot) cdot (float): the curvature change of the spiral (optional, or use length, or angle) Attributes ---------- curvstart (float): starting curvature of the Spiral curvend (float): final curvature of the Spiral Methods ------- get_element() Returns the full ElementTree of the class get_attributes() Returns a dictionary of all attributes of the class get_end_data(x,y,h) Returns the end point of the geometry """ def __init__(self, curvstart, curvend, length=None, angle=None, cdot=None): """initalizes the Spline Parameters ---------- curvstart (float): starting curvature of the Spiral curvend (float): final curvature of the Spiral length (float): length of the spiral (optional, or use, angle, or cdot) angle (float): the angle of the spiral (optional, or use length, or cdot) cdot (float): the curvature change of the spiral (optional, or use length, or angle) """ super().__init__() self.curvstart = curvstart self.curvend = curvend if length == None and angle == None and cdot == None: raise NotEnoughInputArguments("Spiral is underdefined") if sum([x != None for x in [length, angle, cdot]]) > 1: raise ToManyOptionalArguments( "Spiral is overdefined, please use only one of the optional inputs" ) if angle: self.length = 2 * abs(angle) / np.maximum(abs(curvend), abs(curvstart)) elif cdot: self.length = (self.curvend - self.curvstart) / cdot else: self.length = length def __eq__(self, other): if isinstance(other, Spiral) and super().__eq__(other): if self.get_attributes() == other.get_attributes(): return True return False def get_end_data(self, x, y, h): """Returns the end point of the geometry Parameters ---------- x (float): x start point of the geometry y (float): y start point of the geometry h (float): start heading of the geometry Returns --------- x (float): the final x point y (float): the final y point h (float): the final heading l (float): length of the spiral """ cloth = pcloth.Clothoid.StandardParams( x, y, h, self.curvstart, (self.curvend - self.curvstart) / self.length, self.length, ) return cloth.XEnd, cloth.YEnd, cloth.ThetaEnd, cloth.length def get_start_data(self, end_x, end_y, end_h): """Returns the end point of the geometry Parameters ---------- end_x (float): x end point of the geometry end_y (float): y end point of the geometry end_h (float): end heading of the geometry Returns --------- x (float): the start x point y (float): the start y point h (float): the start heading of the inverse geometry l (float): length of the spiral """ cloth = pcloth.Clothoid.StandardParams( end_x, end_y, end_h, -self.curvend, -(self.curvstart - self.curvend) / self.length, self.length, ) return cloth.XEnd, cloth.YEnd, cloth.ThetaEnd, cloth.length def get_attributes(self): """returns the attributes of the Line as a dict""" return {"curvStart": str(self.curvstart), "curvEnd": str(self.curvend)} def get_element(self): """returns the elementTree of the Line""" element = ET.Element("spiral", attrib=self.get_attributes()) self._add_additional_data_to_element(element) return element
the Spiral (Clothoid) creates a spiral type of geometry
Parameters
curvstart (float): starting curvature of the Spiral curvend (float): final curvature of the Spiral length (float): length of the spiral (optional, or use, angle, or cdot) angle (float): the angle of the spiral (optional, or use length, or cdot) cdot (float): the curvature change of the spiral (optional, or use length, or angle)
Attributes
curvstart (float): starting curvature of the Spiral curvend (float): final curvature of the Spiral
Methods
get_element() Returns the full ElementTree of the class get_attributes() Returns a dictionary of all attributes of the class get_end_data(x,y,h) Returns the end point of the geometry
initalizes the Spline
Parameters
curvstart (float): starting curvature of the Spiral curvend (float): final curvature of the Spiral length (float): length of the spiral (optional, or use, angle, or cdot) angle (float): the angle of the spiral (optional, or use length, or cdot) cdot (float): the curvature change of the spiral (optional, or use length, or angle)
Ancestors
- scenariogeneration.xodr.geometry._BaseGeometry
- XodrBase
Methods
def get_attributes(self)
-
Expand source code
def get_attributes(self): """returns the attributes of the Line as a dict""" return {"curvStart": str(self.curvstart), "curvEnd": str(self.curvend)}
returns the attributes of the Line as a dict
def get_element(self)
-
Expand source code
def get_element(self): """returns the elementTree of the Line""" element = ET.Element("spiral", attrib=self.get_attributes()) self._add_additional_data_to_element(element) return element
returns the elementTree of the Line
def get_end_data(self, x, y, h)
-
Expand source code
def get_end_data(self, x, y, h): """Returns the end point of the geometry Parameters ---------- x (float): x start point of the geometry y (float): y start point of the geometry h (float): start heading of the geometry Returns --------- x (float): the final x point y (float): the final y point h (float): the final heading l (float): length of the spiral """ cloth = pcloth.Clothoid.StandardParams( x, y, h, self.curvstart, (self.curvend - self.curvstart) / self.length, self.length, ) return cloth.XEnd, cloth.YEnd, cloth.ThetaEnd, cloth.length
Returns the end point of the geometry
Parameters
x (float): x start point of the geometry y (float): y start point of the geometry h (float): start heading of the geometry
Returns
x (float): the final x point y (float): the final y point h (float): the final heading l (float): length of the spiral
def get_start_data(self, end_x, end_y, end_h)
-
Expand source code
def get_start_data(self, end_x, end_y, end_h): """Returns the end point of the geometry Parameters ---------- end_x (float): x end point of the geometry end_y (float): y end point of the geometry end_h (float): end heading of the geometry Returns --------- x (float): the start x point y (float): the start y point h (float): the start heading of the inverse geometry l (float): length of the spiral """ cloth = pcloth.Clothoid.StandardParams( end_x, end_y, end_h, -self.curvend, -(self.curvstart - self.curvend) / self.length, self.length, ) return cloth.XEnd, cloth.YEnd, cloth.ThetaEnd, cloth.length
Returns the end point of the geometry
Parameters
end_x (float): x end point of the geometry end_y (float): y end point of the geometry end_h (float): end heading of the geometry
Returns
x (float): the start x point y (float): the start y point h (float): the start heading of the inverse geometry l (float): length of the spiral
Inherited members