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

feat: add purpose to storyboard entries and export segments to .skyc #30

Merged
merged 2 commits into from
Dec 21, 2024
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
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.3.5
rev: v0.8.4
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand Down
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ pyclean = "^2.0.0"
[tool.ruff]
lint.ignore = ["B027", "B905", "C901", "E402", "E501", "E731"]
lint.select = ["B", "C", "E", "F", "W"]
extend-exclude = ["src/modules/sbstudio/vendor"]
extend-exclude = [
"src/modules/sbstudio/vendor",
"src/modules/sbstudio/i18n/translations.py"
]

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
67 changes: 39 additions & 28 deletions src/modules/sbstudio/api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import re

from base64 import b64encode
from collections.abc import Iterator, Sequence
from contextlib import contextmanager
from gzip import compress
from http.client import HTTPResponse
Expand All @@ -10,7 +11,7 @@
from pathlib import Path
from shutil import copyfileobj
from ssl import create_default_context, CERT_NONE
from typing import Any, Dict, Iterator, List, Optional, Sequence, Tuple
from typing import Any, Optional
from urllib.error import HTTPError
from urllib.parse import urljoin
from urllib.request import Request, urlopen
Expand Down Expand Up @@ -321,7 +322,7 @@ def decompose_points(
*,
min_distance: float,
method: str = "greedy",
) -> List[int]:
) -> list[int]:
"""Decomposes a set of points into multiple groups while ensuring that
the minimum distance of points within the same group is at least as
large as the given threshold.
Expand All @@ -342,44 +343,51 @@ def decompose_points(

def export(
self,
*,
validation: SafetyCheckParams,
trajectories: Dict[str, Trajectory],
lights: Optional[Dict[str, LightProgram]] = None,
yaw_setpoints: Optional[Dict[str, YawSetpointList]] = None,
trajectories: dict[str, Trajectory],
lights: Optional[dict[str, LightProgram]] = None,
yaw_setpoints: Optional[dict[str, YawSetpointList]] = None,
output: Optional[Path] = None,
show_title: Optional[str] = None,
show_type: str = "outdoor",
show_segments: Optional[dict[str, tuple[float, float]]] = None,
ndigits: int = 3,
timestamp_offset: Optional[float] = None,
time_markers: Optional[TimeMarkers] = None,
cameras: Optional[list[Camera]] = None,
renderer: str = "skyc",
renderer_params: Optional[Dict[str, Any]] = None,
renderer_params: Optional[dict[str, Any]] = None,
) -> Optional[bytes]:
"""Export drone show data into Skybrush Compiled Format (.skyc).
"""
Export drone show data.

Parameters:
validation: safety check parameters
trajectories: dictionary of trajectories indexed by drone names
lights: dictionary of light programs indexed by drone names
yaw_setpoints: dictionary of yaw setpoints indexed by drone names
output: the file path where the output should be saved or `None`
if the output must be returned instead of saving it to a file
show_title: arbitrary show title; `None` if no title is needed
show_type: type of the show; must be one of `outdoor` or `indoor`
ndigits: round floats to this precision
timestamp_offset: when specified, adds this timestamp offset to the
metadata of the .skyc file, which is then used later for display
purposes in Skybrush Viewer
time_markers: when specified, time markers will be exported to the
.skyc file as temporal cues
cameras: when specified, list of cameras to include in the environment
validation: Safety check parameters.
trajectories: Dictionary of trajectories indexed by drone names.
lights: Dictionary of light programs indexed by drone names.
yaw_setpoints: Dictionary of yaw setpoints indexed by drone names.
output: The file path where the output should be saved or `None`
if the output must be returned instead of saving it to a file.
show_title: Arbitrary show title; `None` if no title is needed.
show_type: Type of the show; must be one of `outdoor` or `indoor`.
show_segments: Dictionary that maps show segment IDs to a start
(inclusive) and end (exclusive) timestamp pair.
ndigits: Round floats to this precision.
timestamp_offset: When specified, adds this timestamp offset to the
show metadata, which can later be used for display purposes in
Skybrush Viewer.
time_markers: When specified, time markers will be exported as
temporal cues.
cameras: When specified, list of cameras to include in the environment.
renderer: The renderer to use to export the show.
renderer_params: Extra parameters for the renderer.

Note: drone names must match in trajectories and lights

Returns:
the drone show data in .skyc format or `None` if an output filename
was specified
The exported drone show data or `None` if an `output` filename
was specified.
"""

meta = {}
Expand All @@ -389,6 +397,9 @@ def export(
if timestamp_offset is not None:
meta["timestampOffset"] = timestamp_offset

if show_segments is not None:
meta["segments"] = show_segments

if lights is None:
lights = {name: LightProgram() for name in trajectories.keys()}

Expand Down Expand Up @@ -451,7 +462,7 @@ def create_formation_from_svg(
num_points: int,
size: float,
angle: float,
) -> Tuple[List[Point3D], List[Color3D]]:
) -> tuple[list[Point3D], list[Color3D]]:
"""Samples the path objects of an SVG string into a list of coordinates
and corresponding colors.

Expand Down Expand Up @@ -490,7 +501,7 @@ def create_formation_from_svg(

def generate_plots(
self,
trajectories: Dict[str, Trajectory],
trajectories: dict[str, Trajectory],
output: Path,
validation: SafetyCheckParams,
plots: Sequence[str] = ("pos", "vel", "nn"),
Expand Down Expand Up @@ -563,7 +574,7 @@ def match_points(
target: Sequence[Coordinate3D],
*,
radius: Optional[float] = None,
) -> Tuple[Mapping, Optional[float]]:
) -> tuple[Mapping, Optional[float]]:
"""Matches the points of a source point set to the points of a
target point set in a way that ensures collision-free straight-line
trajectories between the matched points when neither the source nor the
Expand Down Expand Up @@ -594,7 +605,7 @@ def plan_landing(
velocity: float,
target_altitude: float = 0,
spindown_time: float = 5,
) -> Tuple[List[int], List[int]]:
) -> tuple[list[int], list[int]]:
"""Plans the landing trajectories for a set of drones, assuming that
they should maintain a given minimum distance while the motors are
running and that they land with constant speed.
Expand Down
27 changes: 8 additions & 19 deletions src/modules/sbstudio/plugin/model/light_effects.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,10 @@
import types
import bpy

from collections.abc import Callable, Iterable, Sequence
from functools import partial
from operator import itemgetter
from typing import (
cast,
Callable,
Iterable,
List,
Optional,
Sequence,
Tuple,
TYPE_CHECKING,
)
from typing import cast, Optional

from bpy.path import abspath
from bpy.props import (
Expand Down Expand Up @@ -54,9 +46,6 @@

from .mixins import ListMixin

if TYPE_CHECKING:
from sbstudio.api.types import Mapping
from sbstudio.plugin.model import StoryboardEntry

__all__ = ("ColorFunctionProperties", "LightEffect", "LightEffectCollection")

Expand Down Expand Up @@ -159,8 +148,8 @@ def test_is_in_front_of(plane: Optional[Plane], point: Coordinate3D) -> bool:
_always_true = constant(True)


def get_color_function_names(self, context: Context) -> List[Tuple[str, str, str]]:
names: List[str]
def get_color_function_names(self, context: Context) -> list[tuple[str, str, str]]:
names: list[str]

if self.path:
absolute_path = abspath(self.path)
Expand Down Expand Up @@ -398,7 +387,7 @@ def apply_on_colors(
self,
colors: Sequence[MutableRGBAColor],
positions: Sequence[Coordinate3D],
mapping: Optional[List[int]],
mapping: Optional[list[int]],
*,
frame: int,
random_seq: RandomSequence,
Expand All @@ -422,7 +411,7 @@ def get_output_based_on_output_type(
output_type: str,
mapping_mode: str,
output_function,
) -> Tuple[Optional[List[Optional[float]]], Optional[float]]:
) -> tuple[Optional[list[Optional[float]]], Optional[float]]:
"""Get the float output(s) for color ramp or image indexing based on the output type.

Args:
Expand All @@ -432,9 +421,9 @@ def get_output_based_on_output_type(
Returns:
individual and common outputs
"""
outputs: Optional[List[Optional[float]]] = None
outputs: Optional[list[Optional[float]]] = None
common_output: Optional[float] = None
order: Optional[List[int]] = None
order: Optional[list[int]] = None

if output_type == "FIRST_COLOR":
common_output = 0.0
Expand Down
Loading