Skip to content

Commit

Permalink
Update devkit v0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
patk-motional committed Jul 15, 2022
1 parent 7df9086 commit 3a4dba5
Show file tree
Hide file tree
Showing 352 changed files with 15,975 additions and 3,888 deletions.
10 changes: 10 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Common variables
NUPLAN_TEST_MAPS_VERSION="nuplan-maps-v1.0"

# Simulation variables
SIMULATION_CONTAINER_PORT=50050
SIMULATION_IMAGE="nuplan/nuplan"

# Submission variables
SUBMISSION_CONTAINER_PORT=50051
SUBMISSION_IMAGE="test-contestant/nuplan-test-submission"
49 changes: 49 additions & 0 deletions Dockerfile.submission
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
FROM ubuntu:20.04

RUN apt-get update \
&& apt-get install -y curl gnupg2 software-properties-common default-jdk

ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn

RUN curl -fsSL https://bazel.build/bazel-release.pub.gpg | apt-key add - \
&& curl -fsSL https://nvidia.github.io/nvidia-docker/gpgkey | apt-key add - \
&& curl -s -L https://nvidia.github.io/nvidia-docker/ubuntu20.04/nvidia-docker.list | tee /etc/apt/sources.list.d/nvidia-docker.list \
&& add-apt-repository "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" \
&& apt-get update \
&& apt-get install -y \
bazel \
file \
zip \
nvidia-container-toolkit \
software-properties-common \
&& rm -rf /var/lib/apt/lists/*

# Download miniconda and install silently.
ENV PATH /opt/conda/bin:$PATH
RUN curl -fsSLo Miniconda3-latest-Linux-x86_64.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
bash Miniconda3-latest-Linux-x86_64.sh -b -p /opt/conda && \
rm Miniconda3-latest-Linux-x86_64.sh && \
conda clean -a -y

# Setup working environement
ARG NUPLAN_HOME=/nuplan_devkit
WORKDIR $NUPLAN_HOME

COPY requirements.txt requirements_submission.txt $NUPLAN_HOME/

RUN bash -c "python -m pip install --upgrade pip --pre && \
pip install --no-cache-dir -r $NUPLAN_HOME/requirements.txt -f https://download.pytorch.org/whl/torch_stable.html && \
pip install --no-cache-dir -r $NUPLAN_HOME/requirements_submission.txt"

RUN mkdir -p $NUPLAN_HOME/nuplan

COPY setup.py $NUPLAN_HOME
COPY nuplan $NUPLAN_HOME/nuplan

RUN bash -c "pip install -e ."

ENV NUPLAN_MAPS_ROOT=/data/sets/nuplan/maps \
NUPLAN_DATA_ROOT=/data/sets/nuplan \
NUPLAN_EXP_ROOT=/data/exp/nuplan

CMD ["/bin/bash", "-c", "python nuplan/submission/submission_planner.py"]
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pipeline{
kubernetes(
jnlp.nuplan_devkit(
name: 'nuplan-devkit-tests',
tag: "v1.0.2",
tag: "v1.0.3",
cpu: 8, maxcpu: 8,
memory: "32G", maxmemory: "64G", yaml: """spec:
containers:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Stay tuned for the upcoming nuPlan ML planning challenges!
______________________________________________________________________

## Changelog
- Jul 15 2022
* v0.3 Devkit: Updates to the devit including but not limited to: nuBoard update, reduce RAM usage during caching and training, new map APIs, simulation and metrics runtime improvements.
- Jun 10 2022
* v1.0 Dataset: Full nuPlan dataset release with over 1,300 hours of driving data (15,000+ logs) across 4 cities (Las Vegas, Pittsburgh, Boston, Singapore).
* v0.2 Devkit: Multiple devkit updates with improvements across the whole framework (planning models, training, simulation, metrics, dashboard, tutorials and more).
Expand Down
33 changes: 33 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
version: "3.7"

x-nuplan-volumes: &x-nuplan-volumes
volumes:
- "$NUPLAN_DATA_ROOT:/data/sets/nuplan:rw"


services:
submission:
<<: *x-nuplan-volumes
container_name: "test-contestant_nuplan-test-submission"
image: ${SUBMISSION_IMAGE}
env_file:
- .env
ports:
- ${SUBMISSION_CONTAINER_PORT}:${SUBMISSION_CONTAINER_PORT}

tty: true

simulation:
<<: *x-nuplan-volumes
env_file:
- .env
environment:
'NUPLAN_CHALLENGE': $NUPLAN_CHALLENGE
'NUPLAN_PLANNER': $NUPLAN_PLANNER
image: ${SIMULATION_IMAGE}
ports:
- ${SIMULATION_CONTAINER_PORT}:${SIMULATION_CONTAINER_PORT}
tty: true
depends_on:
- submission
entrypoint: /nuplan_devkit/nuplan/entrypoint.sh
2 changes: 1 addition & 1 deletion docs/dataset_setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ The final hierarchy should look as follows (depending on the splits downloaded a
│   └── us-pa-pittsburgh-hazelwood
│   └── 9.17.1937
│   └── map.gpkg
└── nuplan-v1.0
└── nuplan_v1.0
   ├── mini
   │ ├── 2021.05.12.22.00.38_veh-35_01008_01518.db
   │ ├── 2021.06.09.17.23.18_veh-38_00773_01140.db
Expand Down
4 changes: 2 additions & 2 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ Next we setup a virtual environment. We recommend Conda for this purpose.
See the [official Miniconda page](https://conda.io/en/latest/miniconda.html).

### Create a Conda environment
We create a new Conda environment named `nuplan`.
We create a new Conda environment using environment.yml.
```
conda create --name nuplan python=3.9
conda env create -f environment.yml
```

### Activate the environment
Expand Down
10 changes: 10 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: nuplan
channels:
- conda-forge
dependencies:
- python=3.9
- pip=21.2.4
- nb_conda_kernels
- pip:
- -r requirements_torch.txt
- -r requirements.txt
23 changes: 23 additions & 0 deletions nuplan/common/actor_state/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ py_library(
name = "agent",
srcs = ["agent.py"],
deps = [
":agent_temporal_state",
":oriented_box",
":scene_object",
":state_representation",
Expand Down Expand Up @@ -128,3 +129,25 @@ py_library(
"//nuplan/common/utils:split_state",
],
)

py_library(
name = "agent_temporal_state",
srcs = ["agent_temporal_state.py"],
deps = [
"//nuplan/common/actor_state:oriented_box",
"//nuplan/common/actor_state:scene_object",
"//nuplan/common/actor_state:tracked_objects_types",
"//nuplan/planning/simulation/trajectory:predicted_trajectory",
],
)

py_library(
name = "ego_temporal_state",
srcs = ["ego_temporal_state.py"],
deps = [
"//nuplan/common/actor_state:agent_temporal_state",
"//nuplan/common/actor_state:ego_state",
"//nuplan/common/actor_state:tracked_objects_types",
"//nuplan/planning/simulation/trajectory:predicted_trajectory",
],
)
70 changes: 12 additions & 58 deletions nuplan/common/actor_state/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import copy
from typing import List, Optional

from nuplan.common.actor_state.agent_temporal_state import AgentTemporalState
from nuplan.common.actor_state.oriented_box import OrientedBox
from nuplan.common.actor_state.scene_object import SceneObject, SceneObjectMetadata
from nuplan.common.actor_state.state_representation import StateSE2, StateVector2D
from nuplan.common.actor_state.state_representation import StateSE2, StateVector2D, TimePoint
from nuplan.common.actor_state.tracked_objects_types import TrackedObjectType
from nuplan.planning.simulation.trajectory.predicted_trajectory import PredictedTrajectory


class Agent(SceneObject):
class Agent(AgentTemporalState, SceneObject):
"""Class describing Agents in the scene, representing Vehicles, Bicycles and Pedestrians"""

def __init__(
Expand All @@ -32,14 +33,18 @@ def __init__(
:param angular_velocity: The scalar angular velocity of the agent, if available
:param predictions: Optional list of (possibly multiple) predicted trajectories
"""
super().__init__(tracked_object_type, oriented_box, metadata)
AgentTemporalState.__init__(
self,
initial_time_stamp=TimePoint(metadata.timestamp_us),
predictions=predictions,
past_trajectory=past_trajectory,
)
SceneObject.__init__(
self, tracked_object_type=tracked_object_type, oriented_box=oriented_box, metadata=metadata
)
self._velocity = velocity
self._angular_velocity = angular_velocity

# Possible multiple predicted trajectories
self._predictions: List[PredictedTrajectory] = predictions if predictions is not None else []
self._past_trajectory = past_trajectory

@property
def velocity(self) -> StateVector2D:
"""
Expand All @@ -56,57 +61,6 @@ def angular_velocity(self) -> Optional[float]:
"""
return self._angular_velocity

@property
def predictions(self) -> List[PredictedTrajectory]:
"""
Getter for agents predicted trajectories
:return: Trajectories
"""
return self._predictions

@predictions.setter
def predictions(self, predicted_trajectories: List[PredictedTrajectory]) -> None:
"""
Setter for predicted trajectories, checks if the listed probabilities sum to one.
:param predicted_trajectories: List of Predicted trajectories
"""
# Sanity check that if predictions are provided, probabilities sum to 1
probability_sum = sum(prediction.probability for prediction in predicted_trajectories)
if not abs(probability_sum - 1) < 1e-6 and predicted_trajectories:
raise ValueError(f"The provided trajectory probabilities did not sum to one, but to {probability_sum:.2f}!")
self._predictions = predicted_trajectories

@property
def past_trajectory(self) -> Optional[PredictedTrajectory]:
"""
Getter for agents predicted trajectories
:return: Trajectories
"""
return self._past_trajectory

@past_trajectory.setter
def past_trajectory(self, past_trajectory: Optional[PredictedTrajectory]) -> None:
"""
Setter for predicted trajectories, checks if the listed probabilities sum to one.
:param past_trajectory: Driven Trajectory
"""
if not past_trajectory:
# In case it is none, no check is needed
self._past_trajectory = past_trajectory
return

# Make sure that the current state is set!
last_waypoint = past_trajectory.waypoints[-1]
if not last_waypoint:
raise RuntimeError(
f"Last waypoint represents current agent's {self.metadata.track_id} state, this should not be None!"
)

# Sanity check that last waypoint is at the same time index as the current one
if last_waypoint.time_us != self.metadata.timestamp_us:
raise ValueError("The provided trajectory does not end at current agent state!")
self._past_trajectory = past_trajectory

@classmethod
def from_new_pose(cls, agent: Agent, pose: StateSE2) -> Agent:
"""
Expand Down
86 changes: 86 additions & 0 deletions nuplan/common/actor_state/agent_temporal_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from __future__ import annotations

from typing import List, Optional

from nuplan.common.actor_state.state_representation import TimePoint
from nuplan.planning.simulation.trajectory.predicted_trajectory import PredictedTrajectory


class AgentTemporalState:
"""
Actor with current, multimodal future as well as past trajectory.
The future trajectory probabilities have to sum up to 1.0.
The past trajectory is only single modal with mode probability 1.0.
The last waypoint in past trajectory has to be the same as current position (we check only timestamp).
"""

def __init__(
self,
initial_time_stamp: TimePoint,
predictions: Optional[List[PredictedTrajectory]] = None,
past_trajectory: Optional[PredictedTrajectory] = None,
):
"""
Initialize actor temporal state which has past as well as future trajectory
:param initial_time_stamp: time stamp the current detections
:param predictions: future multimodal trajectory
:param past_trajectory: past trajectory transversed
"""
self._initial_time_stamp = initial_time_stamp
self.predictions: List[PredictedTrajectory] = predictions if predictions is not None else []
self.past_trajectory = past_trajectory

@property
def predictions(self) -> List[PredictedTrajectory]:
"""
Getter for agents predicted trajectories
:return: Trajectories
"""
return self._predictions

@predictions.setter
def predictions(self, predicted_trajectories: List[PredictedTrajectory]) -> None:
"""
Setter for predicted trajectories, checks if the listed probabilities sum to one.
:param predicted_trajectories: List of Predicted trajectories
"""
if not predicted_trajectories:
self._predictions = predicted_trajectories
return
# Sanity check that if predictions are provided, probabilities sum to 1
probability_sum = sum(prediction.probability for prediction in predicted_trajectories)
if not abs(probability_sum - 1) < 1e-6 and predicted_trajectories:
raise ValueError(f"The provided trajectory probabilities did not sum to one, but to {probability_sum:.2f}!")
self._predictions = predicted_trajectories

@property
def past_trajectory(self) -> Optional[PredictedTrajectory]:
"""
Getter for agents predicted trajectories
:return: Trajectories
"""
return self._past_trajectory

@past_trajectory.setter
def past_trajectory(self, past_trajectory: Optional[PredictedTrajectory]) -> None:
"""
Setter for predicted trajectories, checks if the listed probabilities sum to one.
:param past_trajectory: Driven Trajectory
"""
if not past_trajectory:
# In case it is none, no check is needed
self._past_trajectory = past_trajectory
return

# Make sure that the current state is set!
last_waypoint = past_trajectory.waypoints[-1]
if not last_waypoint:
raise RuntimeError("Last waypoint represents current agent's state, this should not be None!")

# Sanity check that last waypoint is at the same time index as the current one
if last_waypoint.time_point != self._initial_time_stamp:
raise ValueError(
"The provided trajectory does not end at current agent state!"
f" {last_waypoint.time_us} != {self._initial_time_stamp}"
)
self._past_trajectory = past_trajectory
Loading

0 comments on commit 3a4dba5

Please sign in to comment.