Add RF antenna verify and design recipe to Impedance tab.

Detect matching toward ANT*/ANT_FEED, compute 50 Ω feed width from stackup, and optional λ/4 length from f0 — before auto-draw or F2 packing.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-13 18:57:59 +02:00
co-authored by Cursor
parent 68af0fd432
commit 1d3cf12482
9 changed files with 1055 additions and 29 deletions
+41
View File
@@ -14,6 +14,7 @@ import type {
ImpedanceNetsReport,
ImpedanceStackupResult,
ImpedanceTraceResult,
AntennaReport,
EdifSubDesign,
FindingComment,
FindingReview,
@@ -725,6 +726,46 @@ export async function analyzeImpedanceNets(
return res.json();
}
export async function fetchAntennaReport(
projectId: string,
): Promise<AntennaReport> {
const res = await authFetch(`${BASE}/api/projects/${projectId}/antenna`);
if (!res.ok) {
const detail = await res.json().catch(() => ({ detail: res.statusText }));
throw new Error(
typeof detail.detail === "string" ? detail.detail : "Antenna report failed",
);
}
return res.json();
}
export async function designAntenna(
projectId: string,
body: {
f0_mhz?: number | null;
target_z_ohm?: number;
h?: number | null;
er?: number | null;
t?: number | null;
},
): Promise<AntennaReport> {
const res = await authFetch(
`${BASE}/api/projects/${projectId}/antenna/design`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
},
);
if (!res.ok) {
const detail = await res.json().catch(() => ({ detail: res.statusText }));
throw new Error(
typeof detail.detail === "string" ? detail.detail : "Antenna design failed",
);
}
return res.json();
}
export async function fetchReport(
projectId: string,
): Promise<ValidationReport> {
+46
View File
@@ -451,6 +451,52 @@ export interface ImpedanceNetsReport {
skipped: string | null;
}
export interface AntennaVerifyRow {
ic_ref: string;
pin: string;
net: string;
topology: string;
parts: string[];
target_z_ohm: number;
status: "ok" | "warning" | "info";
detail: string;
feed_z0?: number | null;
feed_length_mm?: number | null;
marker_ref?: string | null;
}
export interface AntennaDesignRecipe {
status: "ready" | "need_pcb" | "need_stackup" | "need_marker";
feed_point?: Record<string, unknown> | null;
feed_line?: {
kind: string;
target_z_ohm: number;
w_mm?: number | null;
h_mm?: number | null;
er?: number | null;
t_mm?: number | null;
} | null;
radiator?: {
length_mm_suggest?: number | null;
f0_mhz?: number | null;
note?: string;
} | null;
zone?: {
net: string;
layer: string;
bbox_mm?: number[] | null;
area_mm2?: number | null;
} | null;
keepout_checklist: string[];
detail: string;
}
export interface AntennaReport {
verify: AntennaVerifyRow[];
design: AntennaDesignRecipe | null;
marker_help: string;
}
export interface NetlistPreviewDesignator {
ref: string;
pins: { number: string; net_name: string }[];