TraceMaker
C++ API of the engine
Loading...
Searching...
No Matches
advice.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2#pragma once
3// The advice file (design doc 17, issue #26): typed hints for the router, written by a person, a script or a language
4// model, and read by the engine like any other input. The engine never talks to a model; a model is one possible writer
5// of this file.
6//
7// {
8// "version": 1,
9// "note": "free text, logged and never acted on",
10// "variants": 4, // advised variants added to the portfolio (default 4)
11// "first_nets": ["USB_DP", "USB_DM"], // routed first; other nets do not rip them
12// "priority": [["U1.A1", "J2.3"]], // connections (pad to pad, either order) routed first
13// "layers": {"no_tracks": ["In2.Cu"], // no new tracks on these copper layers (vias still pass)
14// "cost": {"F.Cu": 1.5}}, // track cost factor per layer (1 to 1000)
15// "regions": [{"name": "north channel", // a region of the board (millimetres, the board file's axes)
16// "rect": [10, 10, 20, 14], // or "polygon": [[x, y], ...]
17// "layers": ["F.Cu"], // default: every copper layer
18// "reserve_for": ["NET1", "NET2"], // only these nets may put copper there ...
19// "avoid_nets": ["NET3"], // ... or: these nets may not (exactly one of the two)
20// "tracks": true, "vias": true}] // which copper is kept out (both by default)
21// }
22//
23// Advice never contains copper and never changes a rule's value: it changes the order of the connections, the cost of
24// a layer, and where some nets may not go, all inside the router's search. Every route is still judged by the exact check,
25// and the advised attempts run as extra portfolio variants next to the unadvised ones, so the winner can only be better.
26//
27// Reading is strict, as for the rule overrides (doc 15 §6.3): an unknown key, a wrong type or a value out of range is an
28// error naming the file and the entry, never ignored (a typo must not silently drop a hint). Names are checked against the
29// board by check_advice_refs; entries that have no effect are warnings.
30#include <cstdint>
31#include <map>
32#include <string>
33#include <string_view>
34#include <utility>
35#include <vector>
36
37#include <nlohmann/json.hpp>
38
39#include "geom/point.hpp"
40#include "model/board.hpp"
41#include "model/rules.hpp"
42#include "route/router.hpp"
43
44namespace tmk::advice {
45
46// Upper bounds on what one file may ask for (an advisor is not trusted to be sensible, doc 17 §6).
47inline constexpr std::size_t kMaxFirstNets = 64;
48inline constexpr std::size_t kMaxPriority = 512;
49inline constexpr std::size_t kMaxRegions = 24;
50inline constexpr std::size_t kMaxPolygon = 64;
51inline constexpr std::size_t kMaxRegionNets = 64;
52inline constexpr std::size_t kMaxNote = 2000;
53inline constexpr int kMaxVariants = 8;
54inline constexpr int kDefaultVariants = 4;
55
56struct Region {
57 std::string name; // "" = numbered
58 std::vector<std::string> layers; // copper layer names; empty = every copper layer
59 std::vector<geom::Point> polygon; // nm, the board file's axes
60 bool tracks = true, vias = true;
61 std::vector<std::string> reserve_for; // only these nets may enter
62 std::vector<std::string> avoid_nets; // these nets may not enter
63 std::string where; // "regions[2]" in messages
64};
65
66struct Advice {
67 std::string source; // file name, for messages
68 int version = 1;
69 std::string note;
71 std::vector<std::string> first_nets;
72 std::vector<std::pair<std::string, std::string>> priority; // "REF.NUM" pairs
73 std::vector<std::string> no_tracks; // copper layer names
74 std::vector<std::pair<std::string, double>> layer_cost;
75 std::vector<Region> regions;
76 bool empty() const { return first_nets.empty() && priority.empty() && no_tracks.empty() && layer_cost.empty() && regions.empty(); }
77};
78
79// Parses and validates the text of an advice file. Throws std::runtime_error naming `source` and the entry ("regions[1].rect").
80Advice parse_advice(std::string_view json_text, const std::string& source = "advice");
81// Reads a file (size-limited); throws on a missing file or a syntax or content error.
82Advice load_advice_file(const std::string& path);
83// Checks every name against the board: nets, pads (REF.NUM, on one net), copper layers. Throws std::runtime_error listing
84// the unknown ones with a "did you mean" where one is close. Warnings (entries without effect) go to `warnings`.
85void check_advice_refs(const Advice& a, const model::Board& b, std::vector<std::string>* warnings = nullptr);
86
87// What the router is given for an advice file, and what each hint became (for the log, the summary and the viewer).
88struct Applied {
90 nlohmann::json report; // {"source", "note", "hints": [{"kind", "text", "applied"}], "variants"}
91 std::vector<std::string> warnings;
92};
93// check_advice_refs, then the RouterOptions::AdviceSet: layer masks and costs, and for each region a rule area plus
94// disallow rules (doc 05 §34) that name its nets. `a` is not changed.
96
97// The advice as JSON, with the board's real names: what is saved beside the output so that `--advice FILE` repeats a run.
98nlohmann::json advice_to_json(const Advice& a);
99
100// The hint types an advisor may use, as JSON (goes into the stuck report so an advisor adapts to the engine it talks to).
101nlohmann::json advice_schema();
102
103// Aliases for net names and part references (a redacted stuck report): the advice an advisor writes uses the aliases, and
104// unalias puts the board's names back before the references are checked. Unknown aliases stay as they are (and fail the check).
105struct AliasMap {
106 std::map<std::string, std::string> net; // alias -> net name
107 std::map<std::string, std::string> part; // alias -> reference
108 bool empty() const { return net.empty() && part.empty(); }
109};
110void unalias(Advice& a, const AliasMap& m);
111
112} // namespace tmk::advice
The board model (design doc 02 §3): every object TraceMaker reads from a .kicad_pcb,...
constexpr std::size_t kMaxFirstNets
Upper bounds on what one file may ask for (an advisor is not trusted to be sensible,...
Definition advice.hpp:47
constexpr int kDefaultVariants
Definition advice.hpp:54
Advice load_advice_file(const std::string &path)
Reads a file (size-limited); throws on a missing file or a syntax or content error.
constexpr std::size_t kMaxRegions
Definition advice.hpp:49
constexpr std::size_t kMaxRegionNets
Definition advice.hpp:51
nlohmann::json advice_schema()
The hint types an advisor may use, as JSON (goes into the stuck report so an advisor adapts to the en...
void unalias(Advice &a, const AliasMap &m)
constexpr int kMaxVariants
Definition advice.hpp:53
Advice parse_advice(std::string_view json_text, const std::string &source="advice")
Parses and validates the text of an advice file. Throws std::runtime_error naming source and the entr...
constexpr std::size_t kMaxPriority
Definition advice.hpp:48
Applied apply_advice(const Advice &a, const model::Board &b)
check_advice_refs, then the RouterOptions::AdviceSet: layer masks and costs, and for each region a ru...
constexpr std::size_t kMaxPolygon
Definition advice.hpp:50
nlohmann::json advice_to_json(const Advice &a)
The advice as JSON, with the board's real names: what is saved beside the output so that --advice FIL...
void check_advice_refs(const Advice &a, const model::Board &b, std::vector< std::string > *warnings=nullptr)
Checks every name against the board: nets, pads (REF.NUM, on one net), copper layers.
constexpr std::size_t kMaxNote
Definition advice.hpp:52
Integer-nanometre points and KiCad-compatible rotation.
TraceMaker's detailed router, version 1 (roadmap M4; design doc 05 §2, §5).
Design rules as KiCad defines them (design doc 08 §3–4): board minimums and net classes from the ....
std::string note
Definition advice.hpp:69
std::vector< std::pair< std::string, double > > layer_cost
Definition advice.hpp:74
std::vector< std::string > first_nets
Definition advice.hpp:71
std::string source
file name, for messages
Definition advice.hpp:67
std::vector< Region > regions
Definition advice.hpp:75
std::vector< std::string > no_tracks
copper layer names
Definition advice.hpp:73
bool empty() const
Definition advice.hpp:76
std::vector< std::pair< std::string, std::string > > priority
"REF.NUM" pairs
Definition advice.hpp:72
Aliases for net names and part references (a redacted stuck report): the advice an advisor writes use...
Definition advice.hpp:105
std::map< std::string, std::string > part
alias -> reference
Definition advice.hpp:107
std::map< std::string, std::string > net
alias -> net name
Definition advice.hpp:106
bool empty() const
Definition advice.hpp:108
What the router is given for an advice file, and what each hint became (for the log,...
Definition advice.hpp:88
std::vector< std::string > warnings
Definition advice.hpp:91
route::RouterOptions::AdviceSet set
Definition advice.hpp:89
nlohmann::json report
{"source", "note", "hints": [{"kind", "text", "applied"}], "variants"}
Definition advice.hpp:90
std::string where
"regions[2]" in messages
Definition advice.hpp:63
std::vector< std::string > avoid_nets
these nets may not enter
Definition advice.hpp:62
std::vector< std::string > reserve_for
only these nets may enter
Definition advice.hpp:61
std::string name
"" = numbered
Definition advice.hpp:57
std::vector< std::string > layers
copper layer names; empty = every copper layer
Definition advice.hpp:58
std::vector< geom::Point > polygon
nm, the board file's axes
Definition advice.hpp:59
Hints from an advice file (src/advice, doc 17).
Definition router.hpp:237