3 Commits

2 changed files with 11 additions and 10 deletions

View File

@ -1,5 +1,3 @@
Archived due to codebase being integrated in [PG-RAD](https://github.com/pim-n/pg-rad).
# RoadGen # RoadGen
Generate road segments in a 2D Cartesian plane. Generate road segments in a 2D Cartesian plane.
@ -74,4 +72,4 @@ You can reproduce results by adding a seed with the `--seed` flag.
For more info, see `road-gen --help` or `road-gen random --help`. For more info, see `road-gen --help` or `road-gen random --help`.
There are some Jupyter notebooks explaining [roads as planar curves](docs/planar_curve.ipynb), as well as the actual implementation of [random segmented roads](docs/prefab_roads.ipynb) and [random roads from noise](docs/random_roads.ipynb). There are some Jupyter notebooks explaining [roads as planar curves](docs/planar_curve.ipynb), as well as the actual implementation of [random segmented roads](docs/prefab_roads.ipynb) and [random roads from noise](docs/random_roads.ipynb).

View File

@ -33,22 +33,26 @@ class SegmentedRoadGenerator(BaseRoadGenerator):
def generate( def generate(
self, self,
segments: list[str], segments: list[str],
alpha: float = 100 alpha: float = 100,
min_turn_angle: float = 15.,
max_turn_angle: float = 90.
) -> Tuple[np.ndarray, np.ndarray]: ) -> Tuple[np.ndarray, np.ndarray]:
"""Generate a curvature profile from a list of segments. """Generate a curvature profile from a list of segments.
Args: Args:
segments (list[str]): List of segments. segments (list[str]): List of segments.
alpha (float, optional): Dirichlet concentration parameter. A higher value leads to more uniform apportionment of the length amongst the segments, while a lower value allows more random apportionment. Defaults to 1.0. alpha (float, optional): Dirichlet concentration parameter. A higher value leads to more uniform apportionment of the length amongst the segments, while a lower value allows more random apportionment. Defaults to 1.0.
min_turn_angle (float, optional): Minimum turn angle in degrees for random sampling of turn radius. Does nothing if `angle_list` is provided or no `turn_*` segement is specified in the `segments` list.
min_turn_angle (float, optional): Maximum turn angle in degrees for random sampling of turn radius. Does nothing if `angle_list` is provided or no `turn_*` segement is specified in the `segments` list.
Raises: Raises:
ValueError: "No valid radius for this turn segment" means a turn is too tight given its segment length and the velocity. To fix this, you can try to reduce the amount of segments or increase length. Increasing alpha (Dirichlet concentration parameter) can also help because this reduces the odds of very small lengths being assigned to turn segments. ValueError: "No valid radius for this turn segment" means a turn is too tight given its segment length and the velocity. To fix this, you can try to reduce the amount of segments or increase length. Increasing alpha (Dirichlet concentration parameter) can also help because this reduces the odds of very small lengths being assigned to turn segments.
Returns: Returns:
Tuple[np.ndarray, np.ndarray]: x and y coordinates of the waypoints describing the random road. Tuple[np.ndarray, np.ndarray]: x and y coordinates of the waypoints describing the random road.
""" """
if not all(segment in prefabs.PREFABS.keys() for segment in segments): existing_prefabs = prefabs.PREFABS.keys()
raise ValueError(f"Invalid segment type provided. Available choices: {prefabs.SEGMENTS.keys()}") if not all(segment in existing_prefabs for segment in segments):
raise ValueError(f"Invalid segment type provided. Available choices: {existing_prefabs}")
self.segments = segments self.segments = segments
self.alpha = alpha self.alpha = alpha
@ -63,7 +67,6 @@ class SegmentedRoadGenerator(BaseRoadGenerator):
if sum(parts) != num_points: if sum(parts) != num_points:
parts[0] += num_points - sum(parts) parts[0] += num_points - sum(parts)
curvature = np.zeros(num_points) curvature = np.zeros(num_points)
current_index = 0 current_index = 0
@ -73,8 +76,8 @@ class SegmentedRoadGenerator(BaseRoadGenerator):
if seg_name == 'straight': if seg_name == 'straight':
curvature_s = seg_function(seg_length) curvature_s = seg_function(seg_length)
else: else:
R_min_angle = seg_length / (np.pi / 2) R_min_angle = seg_length / np.deg2rad(max_turn_angle)
R_max_angle = seg_length / (np.pi / 6) R_max_angle = seg_length / np.deg2rad(min_turn_angle)
# physics limit # physics limit
R_min = max(self.min_radius, R_min_angle) R_min = max(self.min_radius, R_min_angle)