Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cutin options #1495

Merged
merged 2 commits into from
Jul 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions smarts/core/local_traffic_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,9 @@ def __init__(self, flow: Dict[str, Any], owner: LocalTrafficProvider):
self._imperfection = float(self._vtype.get("sigma", 0.5))

self._cutting_into = None
self._cutting_in = False
self._in_front_after_cutin_secs = 0
self._cutin_hold_secs = 3
self._cutin_hold_secs = float(self._vtype.get("lcHoldPeriod", 3.0))
self._target_cutin_gap = 2.5 * self._min_space_cush
self._aggressiveness = float(self._vtype.get("lcAssertive", 1.0))
if self._aggressiveness <= 0:
Expand All @@ -456,7 +457,11 @@ def __init__(self, flow: Dict[str, Any], owner: LocalTrafficProvider):
"illegal probability {self._cutin_prob} for 'cutin_prob' lane-changing parameter will be ignored"
)
self._cutin_prob = 0.0
self._dogmatic = bool(self._vtype.get("lcDogmatic", False))
self._dogmatic = self._vtype.get("lcDogmatic", "False") == "True"
self._cutin_slow_down = float(self._vtype.get("lcSlowDownAfter", 1.0))
if self._cutin_slow_down < 0:
self._cutin_slow_down = 0
self._multi_lane_cutin = self._vtype.get("lcMultiLaneCutin", "False") == "True"

self._max_angular_velocity = 26 # arbitrary, based on limited testing
self._prev_angular_err = None
Expand Down Expand Up @@ -936,14 +941,14 @@ def _crossing_time_into(self, target_idx: int) -> Tuple[float, bool]:
return cross_time, True

def _should_cutin(self, lw: _LaneWindow) -> bool:
if lw.lane.index == self._lane.index:
target_ind = lw.lane.index
if target_ind == self._lane.index:
return False
if not self._multi_lane_cutin and abs(target_ind - self._lane.index) > 1:
return False
min_gap = self._target_cutin_gap / self._aggressiveness
max_gap = self._target_cutin_gap + 2
if (
min_gap < lw.agent_gap < max_gap
and self._crossing_time_into(lw.lane.index)[1]
):
if min_gap < lw.agent_gap < max_gap and self._crossing_time_into(target_ind)[1]:
return random.random() < self._cutin_prob
return False

Expand Down Expand Up @@ -977,10 +982,12 @@ def _pick_lane(self, dt: float):
if self._in_front_after_cutin_secs < self._cutin_hold_secs:
break
self._cutting_into = None
self._cutting_in = False
self._in_front_secs = 0
if lw.agent_gap and self._should_cutin(lw):
best_lw = lw
self._cutting_into = lw
self._cutting_in = True
elif lw.adj_time_left > best_lw.adj_time_left or (
lw.adj_time_left == best_lw.adj_time_left
and (
Expand Down Expand Up @@ -1033,9 +1040,8 @@ def _check_speed(self):
return
self._target_speed = target_lane.speed_limit
self._target_speed *= self._speed_factor
# TAI: consider going faster the further left the target lane
# ... or let scenario creator manage this via flows?
# self._target_speed *= 1.0 + .05 * self._target_lane_win.lane.index
if self._cutting_in:
self._target_speed *= self._cutin_slow_down
self._slow_for_curves()
max_speed = float(self._vtype.get("maxSpeed", 55.55))
if self._target_speed >= max_speed:
Expand Down
27 changes: 25 additions & 2 deletions smarts/sstudio/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,35 @@ class SmartsLaneChangingModel(LaneChangingModel):
If True, will cutin when a suitable opportunity presents itself based on the above parameters,
even if it means the risk of not not completing the assigned route; otherwise, will forego
the chance.
hold_period:
The minimum amount of time (in seconds) to remain in the agent's lane after cutting into it
(including the time it takes within the lane to complete the maneuver). Must be non-negative.
default: 3.0.
slow_down_after:
Target speed during the hold_period will be scaled by this value.
Must be non-negative. default: 1.0.
multi_lane_cutin:
If True, this vehicle will consider changing across multiple lanes at once in order
to cutin upon an agent vehicle when there's an opportunity. default: False.
"""

def __init__(
self, cutin_prob: float = 0.0, assertive: float = 1.0, dogmatic: bool = True
self,
cutin_prob: float = 0.0,
assertive: float = 1.0,
dogmatic: bool = True,
hold_period: float = 3.0,
slow_down_after: float = 1.0,
multi_lane_cutin: bool = False,
):
super().__init__(cutin_prob=cutin_prob, assertive=assertive, dogmatic=dogmatic)
super().__init__(
cutin_prob=cutin_prob,
assertive=assertive,
dogmatic=dogmatic,
hold_period=hold_period,
slow_down_after=slow_down_after,
multi_lane_cutin=multi_lane_cutin,
)


@dataclass(frozen=True)
Expand Down