Module scenariogeneration.xodr.elevation
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.
Classes
class ElevationCalculator (main_road)
-
Expand source code
class ElevationCalculator: """ElevationCalculator is a helper class to add elevation profiles to a road based on its neighbors elevations. Parameters ---------- main_road (Road): the road that an elevation should be added to Methods ------- add_successor(road) adds a successor road to the main_road (note, can be done multiple times for junctions) add_predecessor(road) adds a predecessor road to the main_road (note, can be done multiple times for junctions) create_profile(domain) tries to create an profile of the domain (elevation or superelevation) set_zero_elevation() sets a elevation at zero for the main_road """ def __init__(self, main_road): self.main_road = main_road self.successors = [] self.predecessors = [] self._super_elevation_needed = not self.main_road.is_adjusted("superelevation") self._elevation_needed = not self.main_road.is_adjusted("elevation") self._extra_elevation_needed = False self._reset_active_roads() def _reset_active_roads(self): """resets all active roads for a calculation""" self._successor_road = None self._predecessor_road = None self._predecessor_cp = None self._successor_cp = None self._successor_lateral_offset = 0 self._predecessor_lateral_offset = 0 def set_zero_elevation(self): """sets a elevation at zero for the main_road""" self.main_road.add_elevation(0, 0, 0, 0, 0) self._elevation_needed = False def _calculate_lateral_elevation_offset( self, road, lanesection, offsets, main_lanesection ): """method used to calculate an elevation offset needed if a direct junction is present Parameters ---------- road (_ElevationConnectionHelper): the road to calculate the offset from lanesection (int): the connected lanesection offsets (int): how many lanes the offset is main_lanesection (int): the lanesection of the main_road returns float: the elevation offset """ s_value = 0 tvalue = 0 if offsets == 0: return 0 sign = 1 # this is to find out if the main_road or the connected road has most lanes to calculate the offset if offsets < 0 and len( road.road.lanes.lanesections[lanesection].rightlanes ) < abs(offsets): road = self.main_road lanesection = main_lanesection offsets = -offsets elif offsets > 0 and len( road.road.lanes.lanesections[lanesection].leftlanes ) < abs(offsets): road = self.main_road lanesection = main_lanesection offsets = -offsets else: road = road.road if lanesection == -1: s_value = road.planview.get_total_length() if offsets < 0: for lane_iter in range(abs(offsets)): tvalue += ( road.lanes.lanesections[lanesection] .rightlanes[lane_iter] .get_width(s_value) ) else: for lane_iter in range(abs(offsets)): tvalue -= ( road.lanes.lanesections[lanesection] .leftlanes[lane_iter] .get_width(s_value) ) if tvalue != 0: self._extra_elevation_needed = True return road.lateralprofile.eval_t_superelevation_at_s(s_value, tvalue) def _calculate_lateral_offsets_based_on_superelevation(self): """method used to calculate the elevation offsets based on superelevation, this has to be run as soon as any road might have been updated to get correct offsets """ for successor_road in self.successors: if ( successor_road.road.predecessor and successor_road.road.predecessor.element_type == ElementType.junction and self.main_road.id in list(successor_road.road.pred_direct_junction.keys()) ): lane_offsets = successor_road.road.pred_direct_junction[ self.main_road.id ] successor_road.lateral_offset = ( self._calculate_lateral_elevation_offset( successor_road, 0, lane_offsets, -1 ) ) elif ( successor_road.road.successor and successor_road.road.successor.element_type == ElementType.junction and self.main_road.id in list(successor_road.road.succ_direct_junction.keys()) ): lane_offsets = successor_road.road.succ_direct_junction[ self.main_road.id ] successor_road.lateral_offset = ( self._calculate_lateral_elevation_offset( successor_road, -1, lane_offsets, -1 ) ) for predecessor_road in self.predecessors: if ( predecessor_road.road.successor and predecessor_road.road.successor.element_type == ElementType.junction and self.main_road.id in list(predecessor_road.road.succ_direct_junction.keys()) ): lane_offsets = predecessor_road.road.succ_direct_junction[ self.main_road.id ] predecessor_road.lateral_offset = ( self._calculate_lateral_elevation_offset( predecessor_road, -1, lane_offsets, 0 ) ) elif ( predecessor_road.road.predecessor and predecessor_road.road.predecessor.element_type == ElementType.junction and self.main_road.id in list(predecessor_road.road.pred_direct_junction.keys()) ): lane_offsets = predecessor_road.road.pred_direct_junction[ self.main_road.id ] predecessor_road.lateral_offset = ( self._calculate_lateral_elevation_offset( predecessor_road, -1, lane_offsets, 0 ) ) def add_successor(self, successor_road): """adds a succeeding road to the main_road, can be called multiple times for junctions Parameters successor_road (Road): a road succeeding the main_road """ successor_lateral_offset = 0 if successor_road.predecessor is not None and ( successor_road.predecessor.element_type == ElementType.road and successor_road.predecessor.element_id == self.main_road.id or successor_road.predecessor.element_type == ElementType.junction and successor_road.pred_direct_junction and self.main_road.id in list(successor_road.pred_direct_junction.keys()) or successor_road.predecessor.element_type == ElementType.junction and not successor_road.pred_direct_junction and self.main_road.road_type == successor_road.predecessor.element_id ): successor_cp = ContactPoint.start elif successor_road.successor is not None and ( successor_road.successor.element_type == ElementType.road and successor_road.successor.element_id == self.main_road.id or successor_road.successor.element_type == ElementType.junction and successor_road.succ_direct_junction and self.main_road.id in list(successor_road.succ_direct_junction.keys()) or successor_road.successor.element_type == ElementType.junction and not successor_road.succ_direct_junction and self.main_road.road_type == successor_road.successor.element_id ): successor_cp = ContactPoint.end else: raise ValueError("could not figure out the contact point") self.successors.append( _ElevationConnectionHelper( successor_road, "successor", successor_cp, successor_lateral_offset ) ) self._calculate_lateral_offsets_based_on_superelevation() def add_predecessor(self, predecessor_road): """adds a predeceeding road to the main_road, can be called multiple times for junctions Parameters predecessor_road (Road): a road predeceeding the main_road """ predecessor_lateral_offset = 0 if predecessor_road.predecessor is not None and ( predecessor_road.predecessor.element_type == ElementType.road and predecessor_road.predecessor.element_id == self.main_road.id or predecessor_road.predecessor.element_type == ElementType.junction and predecessor_road.pred_direct_junction and self.main_road.id in list(predecessor_road.pred_direct_junction.keys()) or predecessor_road.predecessor.element_type == ElementType.junction and not predecessor_road.pred_direct_junction and self.main_road.road_type == predecessor_road.predecessor.element_id ): predecessor_cp = ContactPoint.start if predecessor_road.predecessor.element_type == ElementType.junction: pass elif predecessor_road.successor is not None and ( predecessor_road.successor.element_type == ElementType.road and predecessor_road.successor.element_id == self.main_road.id or predecessor_road.successor.element_type == ElementType.junction and predecessor_road.succ_direct_junction and self.main_road.id in list(predecessor_road.succ_direct_junction.keys()) or predecessor_road.successor.element_type == ElementType.junction and not predecessor_road.succ_direct_junction and self.main_road.road_type == predecessor_road.successor.element_id ): predecessor_cp = ContactPoint.end if predecessor_road.successor.element_type == ElementType.junction: pass else: raise ValueError("could not figure out the contact point") self.predecessors.append( _ElevationConnectionHelper( predecessor_road, "predecessor", predecessor_cp, predecessor_lateral_offset, ) ) self._calculate_lateral_offsets_based_on_superelevation() def _set_active_roads(self, domain): """checks what successors/predecessor roads are adjusted in the wanted domain and set those for calculations Parameters ---------- domain (str): the domain (elevation, or superelevation) """ for successor in self.successors: if successor.road.is_adjusted(domain): self._successor_road = successor.road self._successor_cp = successor.contact_point self._successor_lateral_offset = successor.lateral_offset for predecessor in self.predecessors: if predecessor.road.is_adjusted(domain): self._predecessor_road = predecessor.road self._predecessor_cp = predecessor.contact_point self._predecessor_lateral_offset = predecessor.lateral_offset def _create_elevation(self): """method that calculates and adds the elevation profile to the main_road based on the elevations on the predecessor or successor roads """ self._calculate_lateral_offsets_based_on_superelevation() self._set_active_roads("elevation") if self._successor_road and self._predecessor_road: ( pre_s, pre_sign, suc_s, suc_sign, A, ) = self._get_related_data_for_double_connection() if self.main_road.road_type != -1: warn( "Having automatic elevation adjustment for junction roads will yeild in ambigious results, please set the elevation for the connecting roads." ) B = np.array( [ self._predecessor_road.elevationprofile.eval_at_s(pre_s) + self._predecessor_lateral_offset, pre_sign * self._predecessor_road.elevationprofile.eval_derivative_at_s( pre_s ), self._successor_road.elevationprofile.eval_at_s(suc_s) + self._successor_lateral_offset, suc_sign * self._successor_road.elevationprofile.eval_derivative_at_s(suc_s), ] ) coeffs = np.linalg.solve(A, B) self.main_road.add_elevation(0, coeffs[0], coeffs[1], coeffs[2], coeffs[3]) self._elevation_needed = False elif self._successor_road or self._predecessor_road: if self.main_road.road_type != -1: warn( "Having automatic elevation adjustment for junction roads will yeild in ambigious results, please set the elevation for the connecting roads." ) ( related_road, neighbor_s, sign, main_s, ) = self._get_related_data_for_single_connection() b = sign * related_road.elevationprofile.eval_derivative_at_s(neighbor_s) a = ( related_road.elevationprofile.eval_at_s(neighbor_s) - b * main_s + self._successor_lateral_offset + self._predecessor_lateral_offset ) self.main_road.add_elevation(0, a, b, 0, 0) self._elevation_needed = False self._reset_active_roads() def _get_related_data_for_single_connection(self): """common functionality for both elevation and superelevation For a road that has elevations on one side to adjust to Returns ------- related_road - the road to adjust to neighbor_s - s value to be used on the related_road sign - sign switch main_s - s to be used on the main_road """ if self._successor_road: main_s = self.main_road.planview.get_total_length() related_road = self._successor_road if self._successor_cp == ContactPoint.start: neighbor_s = 0 sign = 1 else: neighbor_s = related_road.planview.get_total_length() sign = -1 else: main_s = 0 related_road = self._predecessor_road if self._predecessor_cp == ContactPoint.start: neighbor_s = 0 sign = -1 else: neighbor_s = related_road.planview.get_total_length() sign = 1 return related_road, neighbor_s, sign, main_s def _get_related_data_for_double_connection(self): """common functionality for both elevation and superelevation For a road that has elevations on both sides to adjust to Returns ------- pre_s - s of the predecessor pre_sign - sign switch of predecessor suc_s - s of the successor suc_sign - sign switch of successor A - Matrix for solving continuous derivative and value """ if self._predecessor_cp == ContactPoint.start: pre_s = 0 pre_sign = -1 else: pre_s = self._predecessor_road.planview.get_total_length() pre_sign = 1 if self._successor_cp == ContactPoint.start: suc_s = 0 suc_sign = 1 else: suc_s = self._successor_road.planview.get_total_length() suc_sign = -1 main_s = self.main_road.planview.get_total_length() A = np.array( [ [1, 0, 0, 0], [0, 1, 0, 0], [1, main_s, main_s**2, main_s**3], [0, 1, 2 * main_s, 3 * main_s**2], ] ) return pre_s, pre_sign, suc_s, suc_sign, A def _create_super_elevation(self): self._set_active_roads("superelevation") if self._successor_road and self._predecessor_road: ( pre_s, pre_sign, suc_s, suc_sign, A, ) = self._get_related_data_for_double_connection() if self.main_road.road_type != -1: warn( "Having automatic elevation adjustment for junction roads will yeild in ambigious results, please set the elevation for the connecting roads." ) B = np.array( [ pre_sign * self._predecessor_road.lateralprofile.eval_superelevation_at_s( pre_s ), self._predecessor_road.lateralprofile.eval_superelevation_derivative_at_s( pre_s ), suc_sign * self._successor_road.lateralprofile.eval_superelevation_at_s( suc_s ), self._successor_road.lateralprofile.eval_superelevation_derivative_at_s( suc_s ), ] ) coeffs = np.linalg.solve(A, B) self.main_road.add_superelevation( 0, coeffs[0], coeffs[1], coeffs[2], coeffs[3] ) self._super_elevation_needed = False elif self._successor_road or self._predecessor_road: ( related_road, neighbor_s, sign, _, ) = self._get_related_data_for_single_connection() if self.main_road.road_type != -1: warn( "Having automatic elevation adjustment for junction roads will yeild in ambigious results, please set the elevation for the connecting roads." ) a = sign * related_road.lateralprofile.eval_superelevation_at_s(neighbor_s) self.main_road.add_superelevation(0, a, 0, 0, 0) self._super_elevation_needed = False self._reset_active_roads() def create_profile(self, domain="elevation"): """main method to try to calculate an elevation or superelevation Parameters ---------- domain (str): what domain to calculate (elevation or superelevation) Default: elevation """ if domain == "elevation": if self._elevation_needed: self._create_elevation() elif domain == "superelevation": if self._super_elevation_needed: self._create_super_elevation() self._calculate_lateral_offsets_based_on_superelevation() elif domain == "shape": raise NotImplementedError("shape adjustment is not implemented yet") else: raise ValueError( "domain can only be: geometry, elevation, superelevation, or shape , not " + domain )
ElevationCalculator is a helper class to add elevation profiles to a road based on its neighbors elevations.
Parameters
main_road (Road): the road that an elevation should be added to
Methods
add_successor(road) adds a successor road to the main_road (note, can be done multiple times for junctions) add_predecessor(road) adds a predecessor road to the main_road (note, can be done multiple times for junctions) create_profile(domain) tries to create an profile of the domain (elevation or superelevation) set_zero_elevation() sets a elevation at zero for the main_road
Methods
def add_predecessor(self, predecessor_road)
-
Expand source code
def add_predecessor(self, predecessor_road): """adds a predeceeding road to the main_road, can be called multiple times for junctions Parameters predecessor_road (Road): a road predeceeding the main_road """ predecessor_lateral_offset = 0 if predecessor_road.predecessor is not None and ( predecessor_road.predecessor.element_type == ElementType.road and predecessor_road.predecessor.element_id == self.main_road.id or predecessor_road.predecessor.element_type == ElementType.junction and predecessor_road.pred_direct_junction and self.main_road.id in list(predecessor_road.pred_direct_junction.keys()) or predecessor_road.predecessor.element_type == ElementType.junction and not predecessor_road.pred_direct_junction and self.main_road.road_type == predecessor_road.predecessor.element_id ): predecessor_cp = ContactPoint.start if predecessor_road.predecessor.element_type == ElementType.junction: pass elif predecessor_road.successor is not None and ( predecessor_road.successor.element_type == ElementType.road and predecessor_road.successor.element_id == self.main_road.id or predecessor_road.successor.element_type == ElementType.junction and predecessor_road.succ_direct_junction and self.main_road.id in list(predecessor_road.succ_direct_junction.keys()) or predecessor_road.successor.element_type == ElementType.junction and not predecessor_road.succ_direct_junction and self.main_road.road_type == predecessor_road.successor.element_id ): predecessor_cp = ContactPoint.end if predecessor_road.successor.element_type == ElementType.junction: pass else: raise ValueError("could not figure out the contact point") self.predecessors.append( _ElevationConnectionHelper( predecessor_road, "predecessor", predecessor_cp, predecessor_lateral_offset, ) ) self._calculate_lateral_offsets_based_on_superelevation()
adds a predeceeding road to the main_road, can be called multiple times for junctions
Parameters predecessor_road (Road): a road predeceeding the main_road
def add_successor(self, successor_road)
-
Expand source code
def add_successor(self, successor_road): """adds a succeeding road to the main_road, can be called multiple times for junctions Parameters successor_road (Road): a road succeeding the main_road """ successor_lateral_offset = 0 if successor_road.predecessor is not None and ( successor_road.predecessor.element_type == ElementType.road and successor_road.predecessor.element_id == self.main_road.id or successor_road.predecessor.element_type == ElementType.junction and successor_road.pred_direct_junction and self.main_road.id in list(successor_road.pred_direct_junction.keys()) or successor_road.predecessor.element_type == ElementType.junction and not successor_road.pred_direct_junction and self.main_road.road_type == successor_road.predecessor.element_id ): successor_cp = ContactPoint.start elif successor_road.successor is not None and ( successor_road.successor.element_type == ElementType.road and successor_road.successor.element_id == self.main_road.id or successor_road.successor.element_type == ElementType.junction and successor_road.succ_direct_junction and self.main_road.id in list(successor_road.succ_direct_junction.keys()) or successor_road.successor.element_type == ElementType.junction and not successor_road.succ_direct_junction and self.main_road.road_type == successor_road.successor.element_id ): successor_cp = ContactPoint.end else: raise ValueError("could not figure out the contact point") self.successors.append( _ElevationConnectionHelper( successor_road, "successor", successor_cp, successor_lateral_offset ) ) self._calculate_lateral_offsets_based_on_superelevation()
adds a succeeding road to the main_road, can be called multiple times for junctions
Parameters successor_road (Road): a road succeeding the main_road
def create_profile(self, domain='elevation')
-
Expand source code
def create_profile(self, domain="elevation"): """main method to try to calculate an elevation or superelevation Parameters ---------- domain (str): what domain to calculate (elevation or superelevation) Default: elevation """ if domain == "elevation": if self._elevation_needed: self._create_elevation() elif domain == "superelevation": if self._super_elevation_needed: self._create_super_elevation() self._calculate_lateral_offsets_based_on_superelevation() elif domain == "shape": raise NotImplementedError("shape adjustment is not implemented yet") else: raise ValueError( "domain can only be: geometry, elevation, superelevation, or shape , not " + domain )
main method to try to calculate an elevation or superelevation
Parameters
domain (str): what domain to calculate (elevation or superelevation) Default: elevation
def set_zero_elevation(self)
-
Expand source code
def set_zero_elevation(self): """sets a elevation at zero for the main_road""" self.main_road.add_elevation(0, 0, 0, 0, 0) self._elevation_needed = False
sets a elevation at zero for the main_road
class ElevationProfile
-
Expand source code
class ElevationProfile(XodrBase): """the ElevationProfile creates the elevationProfile element of the road in opendrive, Attributes ---------- elevations (list of _Poly3Profile): Methods ------- get_element(elementname) Returns the full ElementTree of the class add_elevation(elevation) adds an elevation profile to the road """ def __init__(self): """initalize the ElevationProfile class""" self.elevations = [] super().__init__() def __eq__(self, other): if isinstance(other, ElevationProfile) and super().__eq__(other): if self.elevations == other.elevations: return True return False def eval_at_s(self, s): return self.elevations[ [i for i, x in enumerate(self.elevations) if x.s <= s][-1] ].eval_at_s(s) def eval_derivative_at_s(self, s): return self.elevations[ [i for i, x in enumerate(self.elevations) if x.s <= s][-1] ].eval_derivative_at_s(s) def add_elevation(self, elevation): """adds an elevation to the ElevationProfile Parameters ---------- elevation (_Poly3Profile): the elevation profile to add to the ElevationProfile """ if not isinstance(elevation, _Poly3Profile): raise TypeError( "add_elevation requires an _Poly3Profile as input, not " + str(type(elevation)) ) self.elevations.append(elevation) return self def get_element(self): """returns the elementTree of the ElevationProfile""" element = ET.Element("elevationProfile") self._add_additional_data_to_element(element) for i in self.elevations: element.append(i.get_element("elevation")) return element
the ElevationProfile creates the elevationProfile element of the road in opendrive,
Attributes
elevations (list of _Poly3Profile):
Methods
get_element(elementname) Returns the full ElementTree of the class add_elevation(elevation) adds an elevation profile to the road
initalize the ElevationProfile class
Ancestors
Methods
def add_elevation(self, elevation)
-
Expand source code
def add_elevation(self, elevation): """adds an elevation to the ElevationProfile Parameters ---------- elevation (_Poly3Profile): the elevation profile to add to the ElevationProfile """ if not isinstance(elevation, _Poly3Profile): raise TypeError( "add_elevation requires an _Poly3Profile as input, not " + str(type(elevation)) ) self.elevations.append(elevation) return self
adds an elevation to the ElevationProfile
Parameters
elevation (_Poly3Profile): the elevation profile to add to the ElevationProfile
def eval_at_s(self, s)
-
Expand source code
def eval_at_s(self, s): return self.elevations[ [i for i, x in enumerate(self.elevations) if x.s <= s][-1] ].eval_at_s(s)
def eval_derivative_at_s(self, s)
-
Expand source code
def eval_derivative_at_s(self, s): return self.elevations[ [i for i, x in enumerate(self.elevations) if x.s <= s][-1] ].eval_derivative_at_s(s)
def get_element(self)
-
Expand source code
def get_element(self): """returns the elementTree of the ElevationProfile""" element = ET.Element("elevationProfile") self._add_additional_data_to_element(element) for i in self.elevations: element.append(i.get_element("elevation")) return element
returns the elementTree of the ElevationProfile
Inherited members
class LateralProfile
-
Expand source code
class LateralProfile(XodrBase): """the LateralProfile creates the elevationProfile element of the road in opendrive, Attributes ---------- superelevation (list of _Poly3Profile): list of superelevations of the road shape (list of _Poly3Profile): list of shapes for the road Methods ------- get_element(elementname) Returns the full ElementTree of the class add_superelevation(superelevation) adds an superelevation profile to the road add_shape(shape) adds a shape to the lateral profile """ def __init__(self): """initalize the LateralProfile class""" super().__init__() self.superelevations = [] self.shapes = [] def __eq__(self, other): if isinstance(other, LateralProfile) and super().__eq__(other): if ( self.superelevations == other.superelevations and self.shapes == other.shapes ): return True return False def add_superelevation(self, superelevation): """adds an elevation to the LateralProfile Parameters ---------- superelevation (_Poly3Profile): the elevation profile to add to the LateralProfile """ if not isinstance(superelevation, _Poly3Profile): raise TypeError( "add_elevation requires an _Poly3Profile as input, not " + str(type(superelevation)) ) self.superelevations.append(superelevation) return self def eval_superelevation_at_s(self, s): if self.superelevations: return self.superelevations[ [i for i, x in enumerate(self.superelevations) if x.s <= s][-1] ].eval_at_s(s) return 0 def eval_t_superelevation_at_s(self, s, t): if self.superelevations: return self.superelevations[ [i for i, x in enumerate(self.superelevations) if x.s <= s][-1] ].eval_t_at_s(s, t) return 0 def eval_superelevation_derivative_at_s(self, s): if self.superelevations: return self.superelevations[ [i for i, x in enumerate(self.superelevations) if x.s <= s][-1] ].eval_derivative_at_s(s) return 0 def add_shape(self, shape): """adds an elevation to the LateralProfile Parameters ---------- shape (_Poly3Profile): the elevation profile to add to the LateralProfile """ if not isinstance(shape, _Poly3Profile): raise TypeError( "add_elevation requires an _Poly3Profile as input, not " + str(type(shape)) ) self.shapes.append(shape) return self def get_element(self): """returns the elementTree of the LateralProfile""" element = ET.Element("lateralProfile") self._add_additional_data_to_element(element) for i in self.superelevations: element.append(i.get_element("superelevation")) for i in self.shapes: element.append(i.get_element("shape")) return element
the LateralProfile creates the elevationProfile element of the road in opendrive,
Attributes
superelevation (list of _Poly3Profile): list of superelevations of the road shape (list of _Poly3Profile): list of shapes for the road
Methods
get_element(elementname) Returns the full ElementTree of the class add_superelevation(superelevation) adds an superelevation profile to the road add_shape(shape) adds a shape to the lateral profile
initalize the LateralProfile class
Ancestors
Methods
def add_shape(self, shape)
-
Expand source code
def add_shape(self, shape): """adds an elevation to the LateralProfile Parameters ---------- shape (_Poly3Profile): the elevation profile to add to the LateralProfile """ if not isinstance(shape, _Poly3Profile): raise TypeError( "add_elevation requires an _Poly3Profile as input, not " + str(type(shape)) ) self.shapes.append(shape) return self
adds an elevation to the LateralProfile
Parameters
shape (_Poly3Profile): the elevation profile to add to the LateralProfile
def add_superelevation(self, superelevation)
-
Expand source code
def add_superelevation(self, superelevation): """adds an elevation to the LateralProfile Parameters ---------- superelevation (_Poly3Profile): the elevation profile to add to the LateralProfile """ if not isinstance(superelevation, _Poly3Profile): raise TypeError( "add_elevation requires an _Poly3Profile as input, not " + str(type(superelevation)) ) self.superelevations.append(superelevation) return self
adds an elevation to the LateralProfile
Parameters
superelevation (_Poly3Profile): the elevation profile to add to the LateralProfile
def eval_superelevation_at_s(self, s)
-
Expand source code
def eval_superelevation_at_s(self, s): if self.superelevations: return self.superelevations[ [i for i, x in enumerate(self.superelevations) if x.s <= s][-1] ].eval_at_s(s) return 0
def eval_superelevation_derivative_at_s(self, s)
-
Expand source code
def eval_superelevation_derivative_at_s(self, s): if self.superelevations: return self.superelevations[ [i for i, x in enumerate(self.superelevations) if x.s <= s][-1] ].eval_derivative_at_s(s) return 0
def eval_t_superelevation_at_s(self, s, t)
-
Expand source code
def eval_t_superelevation_at_s(self, s, t): if self.superelevations: return self.superelevations[ [i for i, x in enumerate(self.superelevations) if x.s <= s][-1] ].eval_t_at_s(s, t) return 0
def get_element(self)
-
Expand source code
def get_element(self): """returns the elementTree of the LateralProfile""" element = ET.Element("lateralProfile") self._add_additional_data_to_element(element) for i in self.superelevations: element.append(i.get_element("superelevation")) for i in self.shapes: element.append(i.get_element("shape")) return element
returns the elementTree of the LateralProfile
Inherited members