STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
vehicle.py
Go to the documentation of this file.
1"""Which part of a drawing is the vehicle.
2
3A stand drawing can carry its ground support on the same sheet: pid-designer draws the rocket on one
4page and the GSE on another, joined only by quick-disconnects paired across the pages
5(``options.pairedWith``). The feed twin mates those pairs into one network, because filling the
6vehicle is what the GSE is for. Layer X burns the vehicle: its propellant tanks are the tanks that
7feed the engine and its pressurant bottle is the bottle that presses them, not a GSE fuel-transfer
8tank or a 49 L K-bottle on the cart that happen to hold the same fluids.
9
10The vehicle is everything joined to the engine by a drawn line, walked through any symbol. A paired
11disconnect is not a drawn line, so the walk stops at the coupling, which is where the vehicle ends.
12A drawing whose GSE is drawn with lines into the vehicle, or that has no GSE, is one piece and the
13whole drawing is the vehicle: every drawing that ran before reads exactly as it did.
14"""
15
16from __future__ import annotations
17
18import copy
19from typing import Any, Dict, FrozenSet, Iterable, List, Optional, Tuple
20
21
22def vehicle_ids(diagram: Any) -> Optional[FrozenSet[str]]:
23 """The ids of every symbol joined to an ENGINE by drawn lines, or None without an engine.
24
25 The physics library's rule (:func:`feedtwin.pid.roles.vehicle_ids`), so the cockpit and Layer X
26 never disagree about which tank is the vehicle's.
27 """
28 from feedtwin.pid.roles import vehicle_ids as library_vehicle_ids
29
30 return library_vehicle_ids(diagram)
31
32
33def on_vehicle(nodes: Iterable[Any], vehicle: Optional[FrozenSet[str]]) -> List[Any]:
34 """``nodes`` that are on the vehicle; all of them when the drawing has no engine to scope by."""
35 nodes = list(nodes)
36 return nodes if vehicle is None else [n for n in nodes if n.id in vehicle]
37
38
39def off_vehicle(nodes: Iterable[Any], vehicle: Optional[FrozenSet[str]]) -> List[Any]:
40 """``nodes`` that are ground support (not joined to the engine by a line)."""
41 return [] if vehicle is None else [n for n in nodes if n.id not in vehicle]
42
43
44def vehicle_payload(payload: Dict[str, Any]) -> Tuple[Dict[str, Any], List[str]]:
45 """``payload`` cut to the vehicle, and the labels of the ground-support vessels left out.
46
47 Layer X primes the vehicle itself -- the loads, the bottle's fill, the regulator's dome -- which
48 is what the GSE is for, and then fires it. Left in, a GSE page mated through its paired
49 disconnects keeps working the vehicle during the burn: on LE4 the GSE dome regulator, mated to
50 the vehicle's dome line, loaded the press regulator past Layer X's lockup and tripped the LOX
51 tank at 802 psig before T-0. Cut, each vehicle-side disconnect half is capped, as a stand with
52 its GSE unplugged has it. A drawing that is one piece comes back unchanged (the same object).
53 """
54 from feedtwin.pid import read_diagram
55
56 diagram = read_diagram(payload, name="vehicle")
57 vehicle = vehicle_ids(diagram)
58 if vehicle is None or len(vehicle) == len(diagram.nodes):
59 return payload, []
60 ground = [n.label or n.id for n in diagram.nodes
61 if n.id not in vehicle and n.type in ("TANK", "KBOTTLE", "DEWAR")]
62 out = copy.deepcopy(payload)
63 out["nodes"] = [n for n in out.get("nodes") or [] if isinstance(n, dict) and str(n.get("id")) in vehicle]
64 out["edges"] = [e for e in out.get("edges") or [] if isinstance(e, dict)
65 and str(e.get("source")) in vehicle and str(e.get("target")) in vehicle]
66 for node in out["nodes"]:
67 options = (node.get("data") or {}).get("options")
68 if isinstance(options, dict) and str(options.get("pairedWith") or "") not in ("", "none") \
69 and str(options["pairedWith"]) not in vehicle:
70 options["pairedWith"] = "" # its mate is ground support: a capped half
71 return out, ground
Optional[FrozenSet[str]] vehicle_ids(Any diagram)
Definition vehicle.py:22
List[Any] off_vehicle(Iterable[Any] nodes, Optional[FrozenSet[str]] vehicle)
Definition vehicle.py:39
List[Any] on_vehicle(Iterable[Any] nodes, Optional[FrozenSet[str]] vehicle)
Definition vehicle.py:33
Tuple[Dict[str, Any], List[str]] vehicle_payload(Dict[str, Any] payload)
Definition vehicle.py:44