Skip to content
Open
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
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,6 @@ third_party/bootstrap/bootstrap-icons.ttf -filter -diff -merge

# BluePilot custom sounds: store directly in Git, not upstream GitLab LFS.
selfdrive/assets/sounds/bluepilot/*.wav -filter -diff -merge

# Theme pack assets: store directly in Git, not upstream GitLab LFS.
selfdrive/assets/bp_themes/** -filter -diff -merge
2 changes: 1 addition & 1 deletion bluepilot/selfdrive/car/bp_card_publisher.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def _refresh_settings_cache() -> dict:
"bmsHideOnroadBorder": _get_bool(p, "BPHideOnroadBorder"),
"bmsDisableLaneLineStatusColor": _get_bool(p, "BPDisableLaneLineStatusColor"),
"bmsMinimalDrivingView": _get_bool(p, "BPHideCameraView"),
"bmsEightBitRacerTheme": _get_bool(p, "BPRadRacerTheme"),
"bmsEightBitRacerTheme": _get_str(p, "BPThemePack").strip().lower() == "rad_racer",
"bmsRainbowLaneLines": _get_bool(p, "BPRainbowLines"),
"bmsShowBlindspotOverlay": _get_bool(p, "ShowBlindspotOverlay", True),
"bmsShowBrakeStatus": _get_bool(p, "ShowBrakeStatus"),
Expand Down
2 changes: 2 additions & 0 deletions common/params_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"BPHideOnroadBorder", {PERSISTENT | BACKUP, BOOL, "0"}},
{"BPHideCameraView", {PERSISTENT | BACKUP, BOOL, "0"}},
{"BPRadRacerTheme", {PERSISTENT | BACKUP, BOOL, "0"}},
{"BPThemePack", {PERSISTENT | BACKUP, STRING, ""}},
{"BPThemeAutoSeasonal", {PERSISTENT | BACKUP, BOOL, "0"}},
{"BPRainbowLines", {PERSISTENT | BACKUP, BOOL, "0"}},
{"BPShowConfidenceBall", {PERSISTENT | BACKUP, BOOL, "1"}},
{"BPAnimateSteeringWheel", {PERSISTENT | BACKUP, BOOL, "1"}},
Expand Down
80 changes: 80 additions & 0 deletions selfdrive/assets/bp_themes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# BluePilot seasonal theme packs

Asset-only theme packs loaded by `selfdrive/ui/bp/lib/theme_pack.py` and selected with
the `BPThemePack` param (Settings → Visuals → Theme, on both the comma 3X and comma
four UIs). The same selector also carries the built-in 8-Bit Racer code theme, so one
param controls all theming.

```
<pack_name>/
colors/colors.json # RGBA: Path, PathEdge, LaneLines, LeadMarker, RoadEdges, Accent, Background
scene.json # optional: animated + static scene layers (see below)
sounds/<name>.wav # optional: overrides stock alert sounds by filename (mono 16-bit 48kHz)
steering_wheel/wheel.png # optional: steering wheel icon override
```

`Path`/`PathEdge` color the path ribbon, `LaneLines` the lane lines, `RoadEdges` the
road boundary lines, `LeadMarker` the vision-lead chevron and its info box, `Accent`
the torque-bar fill and set-speed value, and `Background` paints a sky gradient behind
the road when Minimal Driving View hides the camera. Every key is optional; missing
keys keep the stock color.

The bundled packs cover the seasonal holidays: New Year's, Valentine's, St. Patrick's,
April Fools, Easter, Cinco de Mayo, Fourth of July, Halloween, Thanksgiving, and
Christmas. Palettes are original; steering-wheel icons are from
[OpenMoji](https://openmoji.org) (CC BY-SA 4.0).

User packs can be dropped into `/data/bp_themes/` on the device — same layout, no code
or reinstall needed; same-name user packs shadow bundled ones. Malformed or missing
pieces degrade gracefully (bad wavs fall back to stock sounds, missing entries leave
stock visuals in place).

## scene.json — animated and static scene layers

A pack may ship a `scene.json` describing what the theme draws around the road: falling
snow, rising hearts, firework bursts, string lights, garlands. One generic engine
(`selfdrive/ui/bp/lib/theme_scene.py`) renders every pack; sprites are procedurally
generated (no images needed). Scenes render at full strength in Minimal Driving View
and subtly over the live camera; alerts always render on top. A pack without
`scene.json` is colors-only, exactly as before — and a user pack in `/data/bp_themes`
shadowing a bundled name without its scene.json disables that pack's animation.

```jsonc
{
"version": 1,
"sky": {"camera_tint_alpha": 40}, // 0-120: Background-color tint over live camera
"layers": [
{ "type": "particles",
"sprite": "snowflake", // snowflake | heart | leaf | petal | clover |
// bat | firefly | spark | bulb | pennant |
// pumpkin | garland
"mode": "fall", // fall | rise | wander | flutter
"count": 44, // minimal-view count (aggregate cap 60)
"camera_count_scale": 0.4, // over-camera count multiplier (cap 24)
"size_px": [10, 24], // at 1080p; scaled by screen height
"fall_speed": [0.05, 0.11], // screen fractions per second
"sway_amp": [0.004, 0.018], "sway_freq_hz": [0.15, 0.5],
"spin_dps": [-30, 30],
"tints": ["#FFFFFF", [221, 232, 255], "colors:Accent"],
"minimal_alpha": 235, "camera_alpha": 110,
"speed_scale": 0.5, // extra fall/drift with vehicle speed
"depth_split": 0.6, // fraction drawn BEHIND the road (smaller/dimmer)
"blend": "alpha" }, // or "additive" (glows, sparks)
{ "type": "burst", // fireworks: periodic radial explosions
"period_s": [1.5, 3.0], "particles_per_burst": 24,
"radial_speed": [0.10, 0.22], "gravity": 0.12, "fade_s": [1.0, 1.6],
"region": [0.1, 0.05, 0.8, 0.35], "tints": ["#FFD700", "#FFFFFF"] },
{ "type": "decor", // static decoration, optional gentle idle
"sprite": "bulb", "anchor": "top_edge",// top_edge | top_left | top_right |
// bottom_left | bottom_right
"size_frac": 0.030, "spacing_frac": 0.045, "droop_frac": 0.030,
"tints": ["#FF4040", "#FFD24A", "#39C25C", "#3E7BFF"],
"idle": "twinkle", // none | twinkle | pulse | sway
"alpha_minimal": 220, "alpha_camera": 90 }
],
"foreground": {"particles_over_hud": true, "corner_accents": true, "corner_alpha": 55}
}
```

All values are validated and clamped; invalid layers are dropped and a malformed file
falls back to colors-only, so experimentation on-device is safe.
44 changes: 44 additions & 0 deletions selfdrive/assets/bp_themes/april_fools/colors/colors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"Background": {
"red": 30,
"green": 15,
"blue": 40,
"alpha": 255
},
"Path": {
"red": 180,
"green": 70,
"blue": 210,
"alpha": 255
},
"PathEdge": {
"red": 0,
"green": 200,
"blue": 200,
"alpha": 255
},
"LaneLines": {
"red": 255,
"green": 240,
"blue": 120,
"alpha": 220
},
"RoadEdges": {
"red": 255,
"green": 140,
"blue": 0,
"alpha": 255
},
"LeadMarker": {
"red": 0,
"green": 190,
"blue": 190,
"alpha": 255
},
"Accent": {
"red": 0,
"green": 190,
"blue": 190,
"alpha": 255
}
}
85 changes: 85 additions & 0 deletions selfdrive/assets/bp_themes/april_fools/scene.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"version": 1,
"sky": {
"camera_tint_alpha": 40
},
"layers": [
{
"type": "backdrop",
"style": "zigzag",
"tint": "#3C1450",
"horizon_frac": 0.46,
"height_frac": 0.24,
"alpha_minimal": 235,
"alpha_camera": 70
},
{
"type": "particles",
"sprite": "pennant",
"mode": "fall",
"count": 44,
"camera_count_scale": 0.4,
"size_px": [
17,
34
],
"fall_speed": [
0.08,
0.16
],
"sway_amp": [
0.008,
0.025
],
"sway_freq_hz": [
0.15,
0.5
],
"spin_dps": [
-180,
180
],
"tints": [
"#B446D2",
"#00C8C8",
"#FFF078",
"#FF8C00"
],
"minimal_alpha": 225,
"camera_alpha": 110,
"speed_scale": 0.5,
"depth_split": 0.6,
"blend": "alpha"
},
{
"type": "decor",
"sprite": "pennant",
"anchor": "top_edge",
"size_frac": 0.03,
"spacing_frac": 0.05,
"droop_frac": 0.028,
"tints": [
"#B446D2",
"#00C8C8",
"#FFF078",
"#FF8C00"
],
"alpha_minimal": 225,
"alpha_camera": 90,
"idle": "none"
},
{
"type": "hero",
"x_frac": 0.5,
"y_frac": 0.8,
"alpha_minimal": 235,
"alpha_camera": 120,
"sprite": "jester_hat",
"size_frac": 0.15
}
],
"foreground": {
"particles_over_hud": true,
"corner_accents": false
}
}
4 changes: 4 additions & 0 deletions selfdrive/assets/bp_themes/april_fools/season.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"start": "03-30",
"end": "04-02"
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions selfdrive/assets/bp_themes/christmas_week/colors/colors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"Background": {
"red": 6,
"green": 26,
"blue": 16,
"alpha": 255
},
"Path": {
"red": 30,
"green": 150,
"blue": 70,
"alpha": 255
},
"PathEdge": {
"red": 220,
"green": 50,
"blue": 60,
"alpha": 255
},
"LaneLines": {
"red": 255,
"green": 245,
"blue": 230,
"alpha": 230
},
"RoadEdges": {
"red": 200,
"green": 35,
"blue": 50,
"alpha": 255
},
"LeadMarker": {
"red": 220,
"green": 50,
"blue": 60,
"alpha": 255
},
"Accent": {
"red": 255,
"green": 200,
"blue": 90,
"alpha": 255
}
}
Loading