obu-firmware builds against vanetza-idf from microbu-esp32c5/external, but that tree was gitignored, so a clone of this repository could not build the firmware it ships. It is now committed here as ordinary files in its own folder, microbu-esp32c5/: the colleague's commit cf4b99f plus the V2X2MAP bridge's signature verification (--trust) used on the bench. Nothing is fetched from or pushed to the colleague's repository; this repository and its remotes carry everything. The folder's own .gitignore keeps build output, downloaded components and private key material out, as it did there; the committed file set is identical to that repository's tracked files. The ESP32-C5 is still flashed from obu-firmware/, which only takes vanetza-idf from microbu-esp32c5/, so the two stay separate folders. FLASHING.md says how to take a newer version of the colleague's tree (copy it over the folder, rebuild, test, commit).
112 lines
3.7 KiB
Python
112 lines
3.7 KiB
Python
"""
|
|
Generates ICO files for its-g5-bridge.exe and its-g5-setup.exe.
|
|
Run before building: python make_icons.py
|
|
Requires Pillow: pip install pillow
|
|
"""
|
|
import math
|
|
import os
|
|
from PIL import Image, ImageDraw
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Bridge icon — dark blue circle with WiFi/antenna waves
|
|
# ---------------------------------------------------------------------------
|
|
def make_bridge_icon(size: int = 256) -> Image.Image:
|
|
img = Image.new("RGBA", (size, size), (0, 0, 0, 0))
|
|
d = ImageDraw.Draw(img)
|
|
|
|
# Outer circle
|
|
p = int(size * 0.04)
|
|
d.ellipse([p, p, size - p, size - p], fill=(21, 101, 192, 255))
|
|
|
|
cx = size / 2
|
|
cy = size * 0.60 # arc origin slightly below centre
|
|
lw = max(4, int(size * 0.055))
|
|
|
|
# Three concentric WiFi arcs (opening downward)
|
|
for i, r_frac in enumerate([0.16, 0.28, 0.40]):
|
|
rp = r_frac * size
|
|
alpha = max(120, 255 - i * 40)
|
|
d.arc([cx - rp, cy - rp, cx + rp, cy + rp],
|
|
start=205, end=335,
|
|
fill=(255, 255, 255, alpha), width=lw)
|
|
|
|
# Centre dot
|
|
dr = int(size * 0.048)
|
|
d.ellipse([cx - dr, cy - dr, cx + dr, cy + dr],
|
|
fill=(255, 255, 255, 255))
|
|
|
|
# Mast line from dot upward
|
|
mw = max(3, int(size * 0.03))
|
|
d.rectangle([cx - mw // 2, cy - size * 0.36,
|
|
cx + mw // 2, cy - dr],
|
|
fill=(255, 255, 255, 230))
|
|
|
|
return img
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Setup icon — slate circle with amber gear
|
|
# ---------------------------------------------------------------------------
|
|
def make_setup_icon(size: int = 256) -> Image.Image:
|
|
img = Image.new("RGBA", (size, size), (0, 0, 0, 0))
|
|
d = ImageDraw.Draw(img)
|
|
|
|
# Outer circle
|
|
p = int(size * 0.04)
|
|
d.ellipse([p, p, size - p, size - p], fill=(55, 71, 79, 255))
|
|
|
|
cx, cy = size / 2, size / 2
|
|
teeth = 8
|
|
r_out = size * 0.34
|
|
r_in = size * 0.25
|
|
t_half = 0.18 # half angular width of tooth
|
|
|
|
pts = []
|
|
for i in range(teeth):
|
|
base = i * 2 * math.pi / teeth
|
|
mid = base + math.pi / teeth
|
|
# leading edge of tooth
|
|
pts += [(cx + r_out * math.cos(base - t_half),
|
|
cy + r_out * math.sin(base - t_half)),
|
|
(cx + r_out * math.cos(base + t_half),
|
|
cy + r_out * math.sin(base + t_half))]
|
|
# valley between teeth
|
|
pts += [(cx + r_in * math.cos(mid - t_half),
|
|
cy + r_in * math.sin(mid - t_half)),
|
|
(cx + r_in * math.cos(mid + t_half),
|
|
cy + r_in * math.sin(mid + t_half))]
|
|
|
|
d.polygon(pts, fill=(255, 193, 7, 255)) # amber gear
|
|
|
|
# Inner hole
|
|
hr = int(size * 0.13)
|
|
d.ellipse([cx - hr, cy - hr, cx + hr, cy + hr],
|
|
fill=(55, 71, 79, 255))
|
|
|
|
# Small centre highlight
|
|
hl = int(size * 0.055)
|
|
d.ellipse([cx - hl, cy - hl, cx + hl, cy + hl],
|
|
fill=(255, 224, 102, 255))
|
|
|
|
return img
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Save as multi-size ICO
|
|
# ---------------------------------------------------------------------------
|
|
SIZES = [(16, 16), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)]
|
|
|
|
def save_ico(img: Image.Image, path: str) -> None:
|
|
os.makedirs(os.path.dirname(path) or ".", exist_ok=True)
|
|
img.save(path, format="ICO", sizes=SIZES)
|
|
kb = os.path.getsize(path) // 1024
|
|
print(f" {path} ({kb} KB)")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("Generating icons ...")
|
|
save_ico(make_bridge_icon(256), "icons/its-g5-bridge.ico")
|
|
save_ico(make_setup_icon(256), "icons/its-g5-setup.ico")
|
|
print("Done.")
|