All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tools.aqua.stars.data.av.dataclasses.Lane.kt Maven / Gradle / Ivy

/*
 * Copyright 2023-2024 The STARS Project Authors
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package tools.aqua.stars.data.av.dataclasses

/**
 * Data class for lanes.
 *
 * @property laneId The identifier of the [Lane].
 * @property road The identifier of the [Road].
 * @property laneType The [LaneType] of the [Lane].
 * @property laneWidth The width of the [Lane].
 * @property laneLength The length of the [Lane].
 * @property predecessorLanes List of [ContactLaneInfo]s for preceding [Lane]s.
 * @property successorLanes List of [ContactLaneInfo]s for successive [Lane]s.
 * @property intersectingLanes List of [ContactLaneInfo]s for intersecting [Lane]s.
 * @property yieldLanes List of [Lane]s that this [Lane] yields to. Lanes that this lane must yield
 *   to according to the "right before left" rule, i.e., traffic signs or lights are not taken into
 *   account. it is always a subset of [intersectingLanes]
 * @property laneMidpoints List of [LaneMidpoint]s for [Lane] midpoints.
 * @property speedLimits List of [SpeedLimit]s for the speed limits.
 * @property landmarks List of [Landmark]s on list [Lane].
 * @property contactAreas List of [ContactArea]s on this [Lane].
 * @property trafficLights List of [StaticTrafficLight]s on this [Lane].
 * @property laneDirection The [LaneDirection] of this [Lane].
 */
@Suppress("MemberVisibilityCanBePrivate")
data class Lane(
    val laneId: Int,
    var road: Road,
    val laneType: LaneType,
    val laneWidth: Double,
    val laneLength: Double,
    var predecessorLanes: List,
    var successorLanes: List,
    var intersectingLanes: List,
    var yieldLanes: List,
    val laneMidpoints: List,
    var speedLimits: List,
    val landmarks: List,
    var contactAreas: List,
    var trafficLights: List,
    var laneDirection: LaneDirection,
) {

  /** Whether this [Lane] turns left. */
  val isTurningLeft: Boolean
    get() = laneDirection == LaneDirection.LEFT_TURN

  /** Whether this [Lane] turns right. */
  val isTurningRight: Boolean
    get() = laneDirection == LaneDirection.RIGHT_TURN

  /** Whether this [Lane] is straight. */
  val isStraight: Boolean
    get() = laneDirection == LaneDirection.STRAIGHT

  /** Whether this [Lane] has stop signs. */
  val hasStopSign: Boolean
    get() =
        landmarks.any { it.type == LandmarkType.StopSign && it.s > laneLength - 10.0 } ||
            successorLanes.any {
              it.lane.landmarks.any { l -> l.type == LandmarkType.StopSign && l.s < 10.0 }
            }

  /** Whether this [Lane] has yield signs. */
  val hasYieldSign: Boolean
    get() =
        landmarks.any { it.type == LandmarkType.YieldSign && it.s > laneLength - 10.0 } ||
            successorLanes.any {
              it.lane.landmarks.any { l -> l.type == LandmarkType.YieldSign && l.s < 10.0 }
            }

  /** Whether this [Lane] has stop or yield signs. */
  val hasStopOrYieldSign: Boolean
    get() = hasStopSign || hasYieldSign

  /** Whether this [Lane] has traffic lights. */
  val hasTrafficLight: Boolean
    get() = trafficLights.isNotEmpty()

  /**
   * Returns the speed limit for the current position in mph or 30mph if no speed sign is available.
   */
  fun speedAt(vPos: Double): Double =
      speedLimits
          .firstOrNull { it.fromDistanceFromStart <= vPos && vPos < it.toDistanceFromStart }
          ?.speedLimit ?: 30.0

  /**
   * Retrieve the position (relative to this lane's start) where [otherLane] is crossed. if the
   * lanes do not cross, return -1.0
   */
  fun contactPointPos(otherLane: Lane): Double? {
    // collect all positions where this lane crosses other lane; should yield 0 or 1 results
    val positions =
        contactAreas.mapNotNull {
          // I am lane 1, check if (and where) lane 2 contacts
          if (this == it.lane1 && otherLane == it.lane2) {
            it.lane1StartPos
          }
          // I am lane 2, check if (and where) lane 1 contacts
          else if (this == it.lane2 && otherLane == it.lane1) {
            it.lane2StartPos
          } else {
            // the two lanes have no contact; do not include in mapping
            null
          }
        }
    return if (positions.isNotEmpty()) positions[0] else null
  }

  override fun toString(): String = "Lane(road=${road.id}, id=$laneId)"

  override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (javaClass != other?.javaClass) return false

    other as Lane

    if (laneId != other.laneId) return false
    if (road != other.road) return false

    return true
  }

  override fun hashCode(): Int = this.toString().hashCode()
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy