Skip to content
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
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,46 @@ dsc-toolkit render_orthophoto \
--save_dir /tmp/output
```

## OpenDRIVE Map Visualization

To visualize an OpenDRIVE map in `plot_annotations_3d`, you need to first convert it to [OBJ format](https://en.wikipedia.org/wiki/Wavefront_.obj_file). Choose one of the following methods:

### Method 1: Online Conversion

1. Navigate to [odrviewer.io](https://odrviewer.io/)
2. In **"Parse Options"**, disable **"Center Map"**
3. Click **"Open .xodr"** and select your OpenDRIVE file
4. Click **"Export .obj"** to download the converted file

### Method 2: Offline Conversion

This method relies on [esmini](https://github.com/esmini/esmini) and [OpenSceneGraph](https://openscenegraph.github.io/openscenegraph.io/):

#### Prerequisites
```bash
# Install OpenSceneGraph
sudo apt install openscenegraph

# Download and set up esmini
wget https://github.com/esmini/esmini/releases/latest/download/esmini-demo_ubuntu-latest.zip
unzip esmini-demo_ubuntu-latest.zip
export PATH=$PATH:$(pwd)/esmini/bin
```

#### Conversion Steps

1. **Generate OpenSceneGraph model** from your OpenDRIVE file:
```bash
odrviewer --odr map.xodr --save_generated_model --headless --duration 0 --disable_log --disable_stdout
```

2. **Convert to OBJ format**:
```bash
osgconv generated_road.osgb map.obj --use-world-frame
```

The resulting `map.obj` file can now be used with `plot_annotations_3d`.

## License

This project is licensed under the Apache License 2.0. See [LICENSE.txt](LICENSE.txt) for details.
Expand Down
2 changes: 1 addition & 1 deletion dsc_toolkit/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""DeepScenario Toolkit for visualizing and working with DeepScenario datasets."""

__version__ = '1.0.2'
__version__ = '1.0.3'
24 changes: 15 additions & 9 deletions dsc_toolkit/plot_annotations_3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
get_look_at_transform,
)
from dsc_toolkit.utils.io import load_data_meta
from dsc_toolkit.utils.map import DiscretizedMap
from dsc_toolkit.utils.visuals import get_ann_visuals, set_camera_transform


Expand Down Expand Up @@ -67,6 +66,16 @@ def animate_fn(event: vedo.plotter.Event) -> None:
return animate_fn


def load_obj(obj_path: str) -> list[vedo.Mesh]:
assert os.path.isfile(obj_path), f'File not found: {obj_path}'
assert (ext := os.path.splitext(obj_path)[1]) == '.obj', f'Invalid format for {obj_path}: expected .obj, got {ext}'

visuals = vedo.load_obj(obj_path, texture_path=os.path.dirname(obj_path))
for visual in visuals:
visual.lighting(style='ambient')
return visuals


def set_initial_camera_pose(plotter: vedo.Plotter, anns_df: pd.DataFrame, relative_altitude: float) -> None:
anns_center = anns_df[['translation_x', 'translation_y', 'translation_z']].mean().to_numpy()
eye = anns_center + np.array([0, 0, relative_altitude])
Expand Down Expand Up @@ -112,15 +121,12 @@ def plot_annotations_3d(
plotter.background(background_color)

if mesh_path is not None:
textured_mesh_visuals = vedo.load_obj(mesh_path, texture_path=os.path.dirname(mesh_path))
for mesh_visual in textured_mesh_visuals:
mesh_visual.lighting(style='ambient')
plotter.add(textured_mesh_visuals)
mesh_visuals = load_obj(mesh_path)
plotter.add(mesh_visuals)

if map_path is not None:
road_map = DiscretizedMap.load_from_file(map_path)
lane_visuals = road_map.get_lane_visuals()
plotter.add(lane_visuals)
map_visuals = load_obj(map_path)
plotter.add(map_visuals)

if save_dir is not None:
print(f'Screenshots will be saved in {save_dir}')
Expand Down Expand Up @@ -149,7 +155,7 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser.add_argument('--data_dir', help='Directory that contains the released data', type=str, required=True)
parser.add_argument('--recording', help='Recording to plot', type=str, dest='recording_id', required=True)
parser.add_argument('--save_dir', help='Directory where the rendered images are saved', type=str)
parser.add_argument('--map', help='Path to the OpenDRIVE map', dest='map_path', type=str)
parser.add_argument('--map', help='Path to the OpenDRIVE map in .obj format', dest='map_path', type=str)
parser.add_argument('--mesh', help='Path to the textured mesh', dest='mesh_path', type=str)
parser.add_argument('--relative_altitude', help='Relative altitude of camera [m]', type=float, default=100)
parser.add_argument('--headless', help='Do not show the visualizer', action='store_true')
Expand Down
116 changes: 0 additions & 116 deletions dsc_toolkit/utils/map.py

This file was deleted.

1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ dependencies = [
"pyproj (>=3.6,<4.0)",
"open3d (>=0.19,<1.0)",
"scipy (>=1.14,<2.0)",
"opendrive2lanelet (>=1.2,<2.0)",
]

[project.urls]
Expand Down
Loading