mirror of
https://github.com/pim-n/road-gen.git
synced 2026-02-03 01:13:09 +01:00
Compare commits
6 Commits
2fde08cf21
...
feature-co
| Author | SHA1 | Date | |
|---|---|---|---|
| 619e4a6765 | |||
| 36f4abb425 | |||
| 784f22bd63 | |||
| 3b7c37f7c4 | |||
| 8a1fad0b94 | |||
| 0a6aa4a7fc |
@ -23,7 +23,11 @@
|
||||
"N = \\frac{L}{\\Delta s}.\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"Let $\\left( p_1, p_2, \\dots, p_K \\right)$ represent the proportion of $N$ that each prefab will be assigned, where $\\sum p_i = 1$. One useful distribution here is the [Dirichlet distribution](https://en.wikipedia.org/wiki/Dirichlet_distribution), which is parametrized by a vector $\\mathbf{\\alpha} = \\left(\\alpha_1, \\alpha_2, \\dots, \\alpha_K \\right)$, known as the *concentration factor*. Setting a uniform $\\alpha$ across the entire parameter space makes the distribution symmetric, meaning all components are equal.\n",
|
||||
"Let $\\left( p_1, p_2, \\dots, p_K \\right)$ represent the proportion of $N$ that each prefab will be assigned, where $\\sum p_i = 1$. One useful distribution here is the [Dirichlet distribution](https://en.wikipedia.org/wiki/Dirichlet_distribution), which is parametrized by a vector $\\mathbf{\\alpha} = \\left(\\alpha_1, \\alpha_2, \\dots, \\alpha_K \\right)$. The special case where all $\\alpha_i$, the scalar parameter $\\alpha$ is called a *concentration parameter*. Setting the same $\\alpha$ across the entire parameter space makes the distribution symmetric, meaning no prior assumptions are made regarding the proportion of $N$ that will be assigned to each segment. $\\alpha = 1$ leads to what is known as a flat Dirichlet distribution, whereas higher values lead to more dense and evenly distributed $\\left( p_1, p_2, \\dots, p_K \\right)$. On the other hand, keeping $\\alpha \\leq 1$ gives a sparser distribution which can lead to larger variance in apportioned number of waypoints to $\\left( p_1, p_2, \\dots, p_K \\right)$.\n",
|
||||
"\n",
|
||||
"#### Expectation value and variance of Dirichlet distribution\n",
|
||||
"\n",
|
||||
"Suppose we draw our samples for proportion of length from the Dirichlet distribution\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"(p_1, p_2, \\ldots, p_K) \\sim \\text{Dirichlet}(\\alpha, \\alpha, \\ldots, \\alpha)\n",
|
||||
@ -35,7 +39,7 @@
|
||||
"\\operatorname {E} [p_{i}]={\\frac {\\alpha _{i}}{\\alpha _{0}}}, \\; \\operatorname {Var} [p_{i}]={\\frac {\\alpha _{i}(\\alpha _{0}-\\alpha _{i})}{\\alpha _{0}^{2}(\\alpha _{0}+1)}}.\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"But, since $\\alpha_i$ is the same for all $i$,\n",
|
||||
"If $\\alpha$ is a scalar, then $\\alpha _{0}= K \\alpha$ and the above simplifies to\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\operatorname {E} [p_{i}]={\\frac {\\alpha}{K \\alpha}}={\\frac {1}{K}}, \\; \\operatorname {Var} [p_{i}]={\\frac {\\alpha(K \\alpha -\\alpha)}{(K \\alpha)^{2}(K \\alpha +1)}}.\n",
|
||||
@ -47,7 +51,7 @@
|
||||
"(N \\cdot p_1, N \\cdot p_2, \\ldots, N \\cdot p_K)\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"to get the randomly assigned number of waypoints for each prefab. We now have a distribution which can give randomly assigned lengths to a given list of prefabs, with a parameter to control the degree of randomness. With very high concentration factor $\\alpha$, the distribution of lengths will be uniform, with each prefab getting $N \\cdot \\operatorname {E} [p_{i}]={\\frac {N}{K}}$ waypoints assigned to it.\n",
|
||||
"to get the randomly assigned number of waypoints for each prefab. We now have a distribution which can give randomly assigned lengths to a given list of prefabs, with a parameter to control the degree of randomness. With a large concentration parameter $\\alpha$, the distribution of lengths will be more uniform, with each prefab getting $N \\cdot \\operatorname {E} [p_{i}]={\\frac {N}{K}}$ waypoints assigned to it. Likewise, keeping $\\alpha$ low increases variance and allows for a more random assignment of proportions of waypoints to each prefab segment.\n",
|
||||
"\n",
|
||||
"#### Random angles\n",
|
||||
"\n",
|
||||
|
||||
@ -33,22 +33,26 @@ class SegmentedRoadGenerator(BaseRoadGenerator):
|
||||
def generate(
|
||||
self,
|
||||
segments: list[str],
|
||||
alpha: float = 100
|
||||
alpha: float = 100,
|
||||
min_turn_angle: float = 15.,
|
||||
max_turn_angle: float = 90.
|
||||
) -> Tuple[np.ndarray, np.ndarray]:
|
||||
"""Generate a curvature profile from a list of segments.
|
||||
|
||||
Args:
|
||||
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.
|
||||
|
||||
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:
|
||||
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:
|
||||
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):
|
||||
raise ValueError(f"Invalid segment type provided. Available choices: {prefabs.SEGMENTS.keys()}")
|
||||
existing_prefabs = prefabs.PREFABS.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.alpha = alpha
|
||||
@ -63,7 +67,6 @@ class SegmentedRoadGenerator(BaseRoadGenerator):
|
||||
if sum(parts) != num_points:
|
||||
parts[0] += num_points - sum(parts)
|
||||
|
||||
|
||||
curvature = np.zeros(num_points)
|
||||
current_index = 0
|
||||
|
||||
@ -73,8 +76,8 @@ class SegmentedRoadGenerator(BaseRoadGenerator):
|
||||
if seg_name == 'straight':
|
||||
curvature_s = seg_function(seg_length)
|
||||
else:
|
||||
R_min_angle = seg_length / (np.pi / 2)
|
||||
R_max_angle = seg_length / (np.pi / 6)
|
||||
R_min_angle = seg_length / np.deg2rad(max_turn_angle)
|
||||
R_max_angle = seg_length / np.deg2rad(min_turn_angle)
|
||||
|
||||
# physics limit
|
||||
R_min = max(self.min_radius, R_min_angle)
|
||||
|
||||
Reference in New Issue
Block a user