aero-agent-roles 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/NOTICE +18 -0
  2. package/README.md +49 -0
  3. package/bin/aero-agent-roles.js +127 -0
  4. package/lib/catalog.js +97 -0
  5. package/lib/install.js +48 -0
  6. package/lib/mcp.js +199 -0
  7. package/manifest.json +516 -0
  8. package/package.json +44 -0
  9. package/roles/aerodynamics-engineer/ROLE.md +153 -0
  10. package/roles/aerodynamics-engineer/SOURCES.md +12 -0
  11. package/roles/aerodynamics-engineer/cli.py +143 -0
  12. package/roles/aerodynamics-engineer/core/aerodynamics_core.py +1218 -0
  13. package/roles/aerodynamics-engineer/templates/aero-design-report-template.md +72 -0
  14. package/roles/aerodynamics-engineer/tests/test_aerodynamics_core.py +227 -0
  15. package/roles/aerodynamics-engineer/tests/test_role_aerodynamics.py +94 -0
  16. package/roles/aircraft-design-engineer/ROLE.md +138 -0
  17. package/roles/aircraft-design-engineer/SOURCES.md +12 -0
  18. package/roles/aircraft-design-engineer/cli.py +152 -0
  19. package/roles/aircraft-design-engineer/core/aircraft_design_core.py +1278 -0
  20. package/roles/aircraft-design-engineer/templates/concept-design-template.md +99 -0
  21. package/roles/aircraft-design-engineer/tests/test_aircraft_design_core.py +269 -0
  22. package/roles/aircraft-design-engineer/tests/test_role_aircraft_design_engineer.py +106 -0
  23. package/roles/airworthiness-compliance-engineer/ROLE.md +122 -0
  24. package/roles/airworthiness-compliance-engineer/SOURCES.md +16 -0
  25. package/roles/airworthiness-compliance-engineer/cli.py +146 -0
  26. package/roles/airworthiness-compliance-engineer/core/airworthiness_core.py +894 -0
  27. package/roles/airworthiness-compliance-engineer/templates/compliance-matrix-template.md +46 -0
  28. package/roles/airworthiness-compliance-engineer/tests/test_airworthiness_core.py +224 -0
  29. package/roles/airworthiness-compliance-engineer/tests/test_role_airworthiness.py +85 -0
  30. package/roles/as9100-quality-auditor/ROLE.md +128 -0
  31. package/roles/as9100-quality-auditor/SOURCES.md +16 -0
  32. package/roles/as9100-quality-auditor/cli.py +136 -0
  33. package/roles/as9100-quality-auditor/core/as9100_core.py +857 -0
  34. package/roles/as9100-quality-auditor/templates/findings-report-template.md +119 -0
  35. package/roles/as9100-quality-auditor/tests/test_as9100_cli_profile.py +105 -0
  36. package/roles/as9100-quality-auditor/tests/test_as9100_core.py +204 -0
  37. package/roles/as9100-quality-auditor/tests/test_role_as9100.py +90 -0
  38. package/roles/data-bus-avionics-engineer/ROLE.md +146 -0
  39. package/roles/data-bus-avionics-engineer/SOURCES.md +23 -0
  40. package/roles/data-bus-avionics-engineer/cli.py +311 -0
  41. package/roles/data-bus-avionics-engineer/core/data_bus_avionics_core.py +1121 -0
  42. package/roles/data-bus-avionics-engineer/templates/bus-assessment-template.md +134 -0
  43. package/roles/data-bus-avionics-engineer/tests/test_bundle_protocol.py +137 -0
  44. package/roles/data-bus-avionics-engineer/tests/test_data_bus_avionics_core.py +261 -0
  45. package/roles/data-bus-avionics-engineer/tests/test_role_data_bus_avionics_engineer.py +121 -0
  46. package/roles/do160-environmental-engineer/ROLE.md +136 -0
  47. package/roles/do160-environmental-engineer/SOURCES.md +30 -0
  48. package/roles/do160-environmental-engineer/cli.py +147 -0
  49. package/roles/do160-environmental-engineer/core/do160_environmental_core.py +1246 -0
  50. package/roles/do160-environmental-engineer/templates/environmental-qualification-plan-template.md +114 -0
  51. package/roles/do160-environmental-engineer/tests/test_do160_environmental_core.py +312 -0
  52. package/roles/do160-environmental-engineer/tests/test_role_do160_environmental_engineer.py +281 -0
  53. package/roles/do178c-cert-engineer/ROLE.md +120 -0
  54. package/roles/do178c-cert-engineer/SOURCES.md +16 -0
  55. package/roles/do178c-cert-engineer/cli.py +129 -0
  56. package/roles/do178c-cert-engineer/core/do178c_core.py +411 -0
  57. package/roles/do178c-cert-engineer/templates/psac-template.md +74 -0
  58. package/roles/do178c-cert-engineer/tests/test_do178c_cert_engineer_core.py +91 -0
  59. package/roles/do178c-cert-engineer/tests/test_role_do178c.py +109 -0
  60. package/roles/do254-hardware-engineer/ROLE.md +127 -0
  61. package/roles/do254-hardware-engineer/SOURCES.md +19 -0
  62. package/roles/do254-hardware-engineer/cli.py +308 -0
  63. package/roles/do254-hardware-engineer/core/do254_hardware_core.py +761 -0
  64. package/roles/do254-hardware-engineer/templates/phac-template.md +87 -0
  65. package/roles/do254-hardware-engineer/tests/test_do254_bundle_profile.py +152 -0
  66. package/roles/do254-hardware-engineer/tests/test_do254_hardware_core.py +200 -0
  67. package/roles/do254-hardware-engineer/tests/test_role_do254_hardware.py +108 -0
  68. package/roles/engineering-analysis-engineer/ROLE.md +154 -0
  69. package/roles/engineering-analysis-engineer/SOURCES.md +15 -0
  70. package/roles/engineering-analysis-engineer/cli.py +151 -0
  71. package/roles/engineering-analysis-engineer/core/engineering_analysis_engineer_core.py +866 -0
  72. package/roles/engineering-analysis-engineer/templates/analysis-memo-template.md +73 -0
  73. package/roles/engineering-analysis-engineer/tests/test_engineering_analysis_engineer_core.py +367 -0
  74. package/roles/engineering-analysis-engineer/tests/test_role_engineering_analysis_engineer.py +113 -0
  75. package/roles/flight-management-engineer/ROLE.md +160 -0
  76. package/roles/flight-management-engineer/SOURCES.md +30 -0
  77. package/roles/flight-management-engineer/cli.py +258 -0
  78. package/roles/flight-management-engineer/core/flight_management_core.py +1473 -0
  79. package/roles/flight-management-engineer/templates/route-assessment-template.md +94 -0
  80. package/roles/flight-management-engineer/tests/test_flight_management_core.py +437 -0
  81. package/roles/flight-management-engineer/tests/test_role_flight_management_engineer.py +123 -0
  82. package/roles/flight-mechanics-engineer/ROLE.md +162 -0
  83. package/roles/flight-mechanics-engineer/SOURCES.md +51 -0
  84. package/roles/flight-mechanics-engineer/cli.py +149 -0
  85. package/roles/flight-mechanics-engineer/core/flight_mechanics_core.py +1507 -0
  86. package/roles/flight-mechanics-engineer/templates/perf-sc-report-template.md +82 -0
  87. package/roles/flight-mechanics-engineer/tests/test_flight_mechanics_core.py +277 -0
  88. package/roles/flight-mechanics-engineer/tests/test_role_flight_mechanics_engineer.py +141 -0
  89. package/roles/flight-test-engineer/ROLE.md +137 -0
  90. package/roles/flight-test-engineer/SOURCES.md +24 -0
  91. package/roles/flight-test-engineer/cli.py +135 -0
  92. package/roles/flight-test-engineer/core/flight_test_core.py +931 -0
  93. package/roles/flight-test-engineer/templates/flight-test-template.md +143 -0
  94. package/roles/flight-test-engineer/tests/test_flight_test_engineer_core.py +227 -0
  95. package/roles/flight-test-engineer/tests/test_role_flight_test_engineer.py +150 -0
  96. package/roles/flight-test-performance-engineer/ROLE.md +165 -0
  97. package/roles/flight-test-performance-engineer/SOURCES.md +20 -0
  98. package/roles/flight-test-performance-engineer/cli.py +319 -0
  99. package/roles/flight-test-performance-engineer/core/flight_test_performance_core.py +1398 -0
  100. package/roles/flight-test-performance-engineer/templates/performance-report-template.md +105 -0
  101. package/roles/flight-test-performance-engineer/tests/test_flight_test_performance_engineer_core.py +308 -0
  102. package/roles/flight-test-performance-engineer/tests/test_role_flight_test_performance_engineer.py +165 -0
  103. package/roles/gnc-engineer/ROLE.md +141 -0
  104. package/roles/gnc-engineer/SOURCES.md +35 -0
  105. package/roles/gnc-engineer/cli.py +141 -0
  106. package/roles/gnc-engineer/core/gnc_core.py +1074 -0
  107. package/roles/gnc-engineer/templates/gnc-report-template.md +105 -0
  108. package/roles/gnc-engineer/tests/test_gnc_engineer_core.py +238 -0
  109. package/roles/gnc-engineer/tests/test_role_gnc_engineer.py +142 -0
  110. package/roles/guidance-engineer/ROLE.md +156 -0
  111. package/roles/guidance-engineer/SOURCES.md +43 -0
  112. package/roles/guidance-engineer/cli.py +280 -0
  113. package/roles/guidance-engineer/core/guidance_core.py +820 -0
  114. package/roles/guidance-engineer/templates/guidance-report-template.md +70 -0
  115. package/roles/guidance-engineer/tests/test_guidance_engineer_core.py +269 -0
  116. package/roles/guidance-engineer/tests/test_role_guidance_engineer.py +146 -0
  117. package/roles/high-speed-aerodynamics-engineer/ROLE.md +161 -0
  118. package/roles/high-speed-aerodynamics-engineer/SOURCES.md +18 -0
  119. package/roles/high-speed-aerodynamics-engineer/cli.py +282 -0
  120. package/roles/high-speed-aerodynamics-engineer/core/high_speed_aero_core.py +1566 -0
  121. package/roles/high-speed-aerodynamics-engineer/templates/high-speed-memo-template.md +75 -0
  122. package/roles/high-speed-aerodynamics-engineer/tests/test_bundle_protocol.py +103 -0
  123. package/roles/high-speed-aerodynamics-engineer/tests/test_high_speed_aero_core.py +280 -0
  124. package/roles/high-speed-aerodynamics-engineer/tests/test_role_high_speed_aerodynamics.py +125 -0
  125. package/roles/ndt-engineer/ROLE.md +157 -0
  126. package/roles/ndt-engineer/SOURCES.md +18 -0
  127. package/roles/ndt-engineer/cli.py +316 -0
  128. package/roles/ndt-engineer/core/ndt_core.py +1590 -0
  129. package/roles/ndt-engineer/templates/ndt-plan-template.md +109 -0
  130. package/roles/ndt-engineer/tests/test_ndt_cli_bundle.py +183 -0
  131. package/roles/ndt-engineer/tests/test_ndt_core.py +437 -0
  132. package/roles/ndt-engineer/tests/test_role_ndt_engineer.py +148 -0
  133. package/roles/numerical-analysis-engineer/ROLE.md +158 -0
  134. package/roles/numerical-analysis-engineer/SOURCES.md +19 -0
  135. package/roles/numerical-analysis-engineer/cli.py +414 -0
  136. package/roles/numerical-analysis-engineer/core/numerical_analysis_core.py +1220 -0
  137. package/roles/numerical-analysis-engineer/templates/verification-memo-template.md +120 -0
  138. package/roles/numerical-analysis-engineer/tests/test_bundle_protocol.py +157 -0
  139. package/roles/numerical-analysis-engineer/tests/test_numerical_analysis_core.py +337 -0
  140. package/roles/numerical-analysis-engineer/tests/test_role_numerical_analysis_engineer.py +117 -0
  141. package/roles/propulsion-engineer/ROLE.md +163 -0
  142. package/roles/propulsion-engineer/SOURCES.md +15 -0
  143. package/roles/propulsion-engineer/cli.py +168 -0
  144. package/roles/propulsion-engineer/core/propulsion_core.py +1291 -0
  145. package/roles/propulsion-engineer/templates/propulsion-report-template.md +92 -0
  146. package/roles/propulsion-engineer/tests/test_propulsion_engineer_core.py +294 -0
  147. package/roles/propulsion-engineer/tests/test_role_propulsion_engineer.py +106 -0
  148. package/roles/space-systems-engineer/ROLE.md +161 -0
  149. package/roles/space-systems-engineer/SOURCES.md +49 -0
  150. package/roles/space-systems-engineer/cli.py +173 -0
  151. package/roles/space-systems-engineer/core/space_systems_core.py +980 -0
  152. package/roles/space-systems-engineer/templates/space-systems-template.md +88 -0
  153. package/roles/space-systems-engineer/tests/test_role_space_systems_engineer.py +117 -0
  154. package/roles/space-systems-engineer/tests/test_space_systems_engineer_core.py +247 -0
  155. package/roles/state-estimation-engineer/ROLE.md +154 -0
  156. package/roles/state-estimation-engineer/SOURCES.md +27 -0
  157. package/roles/state-estimation-engineer/cli.py +326 -0
  158. package/roles/state-estimation-engineer/core/state_estimation_core.py +958 -0
  159. package/roles/state-estimation-engineer/templates/nav-state-estimator-design-template.md +76 -0
  160. package/roles/state-estimation-engineer/tests/test_bundle_protocol.py +110 -0
  161. package/roles/state-estimation-engineer/tests/test_role_state_estimation_engineer.py +127 -0
  162. package/roles/state-estimation-engineer/tests/test_state_estimation_engineer_core.py +231 -0
  163. package/roles/structures-loads-engineer/ROLE.md +171 -0
  164. package/roles/structures-loads-engineer/SOURCES.md +44 -0
  165. package/roles/structures-loads-engineer/cli.py +219 -0
  166. package/roles/structures-loads-engineer/core/structures_loads_core.py +1112 -0
  167. package/roles/structures-loads-engineer/templates/loads-strength-report-template.md +96 -0
  168. package/roles/structures-loads-engineer/tests/test_bundle_protocol.py +101 -0
  169. package/roles/structures-loads-engineer/tests/test_role_structures_loads_engineer.py +147 -0
  170. package/roles/structures-loads-engineer/tests/test_structures_loads_core.py +261 -0
@@ -0,0 +1,88 @@
1
+ # Spacecraft Mission and Subsystem Design Report
2
+
3
+ **Spacecraft:** Aurora-1 Earth Observation Microsatellite
4
+ **Mission:** 600 km circular sun-synchronous Earth observation microsatellite, 5-year design life, 10:30 LTDN.
5
+ **Status:** draft-for-review
6
+
7
+ ## 1. Mission and orbit
8
+
9
+ - Orbit: circular, altitude 600.0 km, inclination 97.8 deg (sun-synchronous), e = 0.000.
10
+ - Orbit radius: 6978 km; period 96.7 min (5801 s); 14.9 orbits/day; circular velocity 7558 m/s.
11
+ - Launch: rideshare, direct injection; design life 5 years.
12
+
13
+ ## 2. Transfer / maneuvers and delta-v budget
14
+
15
+ - Injection: direct insertion (rideshare, direct injection); no interplanetary C3 or launch-window constraint applies (LEO circular mission).
16
+ - Delta-v contributions (m/s):
17
+ - Injection dispersion correction: 20.0
18
+ - Orbit maintenance (drag, 5 yr): 15.0
19
+ - Collision avoidance (2 maneuvers): 10.0
20
+ - End-of-life disposal (perigee lowering): 141.7
21
+ - Disposal leg is a single retrograde burn lowering perigee from 600 km to 100 km (Hohmann half-transfer, 141.7 m/s).
22
+ - Nominal total delta-v: 186.7 m/s; budgeted with 15% margin: **214.8 m/s**.
23
+ - Propellant (Isp 220 s, Tsiolkovsky): **15.7 kg**; wet mass 165.7 kg (9.5% propellant fraction).
24
+
25
+ ## 3. Environment
26
+
27
+ - Eclipse (worst case, beta = 0): shadow fraction 36.7%; eclipse time 35.5 min per orbit.
28
+ - Perturbations at 600 km SSO: J2 nodal precession used for the sun-synchronous plane; drag is the long-term orbit maintenance driver (budgeted above); three-body effects negligible at this altitude.
29
+ - Radiation/debris: 600 km SSO sits in the inner belt proton/electron environment; parts list to a 25-50 krad(Si) total dose class (ECSS-Q-ST-60-15C practice); conjunction screening budgeted as 2 avoidance maneuvers over life.
30
+
31
+ ## 4. ADCS
32
+
33
+ - Determination: star tracker (knowledge ~5 arcsec 1-sigma), sun sensors, 3-axis rate gyro, magnetometer; TRIAD/QUEST batch solutions on the C&DH.
34
+ - Control: 3 orthogonal wheels + 1 redundant reaction wheels, momentum capacity **1.0 N m s** each at 6000 rpm (wheel inertia 1.59 x 1e-3 kg m^2, h = J*omega); torque class 0.02 N m; magnetorquers for momentum desaturation.
35
+ - Sizing: slew 90 deg in 90 s -> slew momentum 0.349 N m s (J = 20 kg m^2 x omega 17.5 x 1e-3 rad/s); disturbance accumulation 0.0348 N m s/orbit; required with margin 0.58 N m s < capacity 1.0 N m s.
36
+ - Pointing error budget (3-sigma RSS): **0.048 deg** vs requirement 0.1 deg (margin x 2.1, meets).
37
+ - attitude determination (star tracker): 0.020 deg
38
+ - control error (deadband + PD residual): 0.030 deg
39
+ - wheel-induced jitter: 0.020 deg
40
+ - sensor/actuator alignment: 0.020 deg
41
+ - thermal distortion: 0.015 deg
42
+
43
+ ## 5. Power and thermal
44
+
45
+ | Item | Day power (W) | Eclipse power (W) |
46
+ |---|---|---|
47
+ | Payload (optical imager) | 60 | 0 |
48
+ | Avionics / C&DH | 30 | 30 |
49
+ | ADCS | 15 | 15 |
50
+ | Comms (S-band Rx + X-band Tx duty) | 20 | 10 |
51
+ | Thermal (heater duty) | 15 | 25 |
52
+ | **Total** | **140** | **80** |
53
+
54
+ - Orbit-average load: 118.0 W over a 96.7 min orbit (36.7% eclipse).
55
+ - Battery: 80 W x 35.5 min eclipse at 30% DoD / 90% efficiency requires **175.2 Wh**; sized **215 Wh** Li-ion (margin 23%).
56
+ - Solar array: daylight power 248.5 W; EOL specific power 315.1 W/m^2 (AM0 1367 W/m^2, 30% cells, packing 0.85, 2%/yr x 5 yr) -> array area **0.79 m^2**.
57
+ - Thermal balance: 55 W continuous dissipation rejected by a radiator at 20 deg C (eps 0.90) -> **0.15 m^2**; eclipse heater duty 25 W is in the load table.
58
+
59
+ ## 6. Comms
60
+
61
+ - Slant range at 5 deg elevation: 2329 km.
62
+ - Downlink (X-band 8.2 GHz, 150 Mbps): EIRP 31.0 dBW, path loss 178.1 dB, C/N0 98.8 dB-Hz, Eb/N0 17.0 dB vs 10.5 dB required -> **margin 6.5 dB**.
63
+ - Uplink (S-band 2.1 GHz, 4 kbps command): **margin 34.3 dB**.
64
+ - Data: 11.2 GB per 10 min pass x 6 passes/day = **67.5 GB/day** capacity vs 30 GB/day imaging need (margin x 2.2); on-board storage 256 GB.
65
+
66
+ ## 7. Propulsion and C&DH
67
+
68
+ - Propulsion: 15.7 kg hydrazine (Isp 220 s) at 1008 kg/m^3 -> 15.6 L propellant, 16.6 L spherical Ti tank (radius 15.8 cm, wall 0.33 mm, shell 0.51 kg, pressurant 3.9 g He); 4 x 1 N thrusters.
69
+ - C&DH: single rad-tolerant computer (LEON-class) with watchdog + triple-redundant command path; ECSS-E-ST-40 / ECSS-Q-ST-80 software and product assurance context; on-board storage solid-state recorder with EDAC.
70
+
71
+ ## 8. System budgets
72
+
73
+ | Budget | Value | Margin policy | Closes |
74
+ |---|---|---|---|
75
+ | mass (dry) | 150 kg (subsystems sum to stated 150 kg) | 20% at subsystem level in stated rows | YES |
76
+ | mass (wet) | 165.7 kg | propellant on top of dry budget | YES |
77
+ | power | 140 W day / 80 W eclipse | battery 23%, array 20% | YES |
78
+ | delta-v | 186.7 m/s nominal / 214.8 m/s budgeted | 15% | YES |
79
+ | pointing | 0.048 deg (3-sigma) | vs 0.1 deg requirement | YES |
80
+ | link margin | down 6.5 dB / up 34.3 dB | >= 3 dB | YES |
81
+
82
+ ## 9. Conclusions and open items
83
+
84
+ - Budgets close? **YES - all budgets close** (delta-v True, power True, pointing True, link True, mass True).
85
+ - Open items for detailed phase: refined disturbance torque model with beta-angle profile; flight-like array incidence/cosine losses; thermal model with component-level margins; star tracker alignment campaign; launch-vehicle interface agreement and actual dispersion.
86
+
87
+ ---
88
+ *Generated by Aero Agent Roles space-systems-engineer core (2026-09-05). DRAFT for human space systems lead review. Not launch readiness. Not an approval document.*
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env python3
2
+ """Role test: space-systems-engineer."""
3
+ import os
4
+ import re
5
+ import unittest
6
+
7
+ ROLES_REPO = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(
8
+ os.path.abspath(__file__)))))
9
+ AEROSKILLS = os.environ.get("AEROSKILLS_DEV", os.path.expanduser("~/AeroSkills"))
10
+ HAS_SKILLS = os.path.isdir(os.path.join(AEROSKILLS, "skills"))
11
+ ROLE_DIR = os.path.join(ROLES_REPO, "roles", "space-systems-engineer")
12
+ TEMPLATE = os.path.join(ROLE_DIR, "templates", "space-systems-template.md")
13
+
14
+ EXPECTED_BOUND = [
15
+ "space-systems/mission-design/mission-delta-v-budget",
16
+ "space-systems/mission-design/launch-window-analysis",
17
+ "space-systems/mission-design/c3-departure-energy",
18
+ "space-systems/mission-design/entry-descent-landing",
19
+ "space-systems/mission-design/radiation-debris",
20
+ "space-systems/orbit-mechanics/keplerian-elements",
21
+ "space-systems/orbit-mechanics/kepler-orbit-propagation",
22
+ "space-systems/orbit-mechanics/hohmann-transfer",
23
+ "space-systems/orbit-mechanics/bi-elliptic-transfer",
24
+ "space-systems/orbit-mechanics/plane-change-maneuver",
25
+ "space-systems/orbit-mechanics/lambert-transfer",
26
+ "space-systems/orbit-mechanics/gravity-assist-swingby",
27
+ "space-systems/orbit-mechanics/low-thrust-spiral",
28
+ "space-systems/orbit-mechanics/orbital-perturbations",
29
+ "space-systems/orbit-mechanics/sun-synchronous-inclination",
30
+ "space-systems/orbit-mechanics/ground-track-repeat",
31
+ "space-systems/orbit-mechanics/eclipse-time",
32
+ "space-systems/orbit-mechanics/satellite-coverage",
33
+ "space-systems/orbit-mechanics/walker-delta-constellation",
34
+ "space-systems/orbit-mechanics/geostationary-station-keeping",
35
+ "space-systems/orbit-mechanics/conjunction-assessment",
36
+ "space-systems/orbit-mechanics/three-body-libration",
37
+ "space-systems/orbit-mechanics/orbital-decay",
38
+ "space-systems/orbit-mechanics/clohessy-wiltshire",
39
+ "space-systems/adcs/attitude-determination-triad",
40
+ "space-systems/adcs/attitude-determination-quest",
41
+ "space-systems/adcs/star-tracker",
42
+ "space-systems/adcs/sun-pointing",
43
+ "space-systems/adcs/reaction-wheel-control",
44
+ "space-systems/adcs/control-moment-gyro",
45
+ "space-systems/adcs/magnetorquer-control",
46
+ "space-systems/adcs/attitude-control-sizing",
47
+ "space-systems/adcs/pointing-error-budget",
48
+ "space-systems/adcs/gyro-allan-variance",
49
+ "space-systems/subsystems/communication-link-budget",
50
+ "space-systems/subsystems/antenna-aperture-sizing",
51
+ "space-systems/subsystems/power-thermal-budget",
52
+ "space-systems/subsystems/solar-array-sizing",
53
+ "space-systems/subsystems/spacecraft-battery-sizing",
54
+ "space-systems/subsystems/thermal-design",
55
+ "space-systems/subsystems/propellant-tank-sizing",
56
+ "space-systems/subsystems/command-data-handling",
57
+ "space-systems/ecss/systems-engineering",
58
+ "space-systems/ecss/software-engineering",
59
+ "space-systems/ecss/software-verification"
60
+ ]
61
+
62
+ STAGES = [
63
+ "1. Mission delta-v",
64
+ "2. Transfers",
65
+ "3. Launch window",
66
+ "4. Constellation/coverage",
67
+ "5. Environment",
68
+ "6. Rendezvous",
69
+ "7. ADCS determination",
70
+ "8. ADCS control",
71
+ "9. Power/thermal",
72
+ "10. Comms",
73
+ "11. Propulsion/C&DH",
74
+ "12. ECSS context",
75
+ "13. Report"
76
+ ]
77
+
78
+
79
+ def role_text():
80
+ p = os.path.join(ROLE_DIR, "ROLE.md")
81
+ return open(p).read() if os.path.exists(p) else None
82
+
83
+
84
+ class TestSpaceSystemsEngineerRole(unittest.TestCase):
85
+
86
+ def test_bound_skills_resolve(self):
87
+ if not HAS_SKILLS:
88
+ self.skipTest("skills checkout absent (cross-repo dev check)")
89
+ for leaf in EXPECTED_BOUND:
90
+ self.assertTrue(
91
+ os.path.exists(os.path.join(AEROSKILLS, "skills", leaf, "SKILL.md")),
92
+ f"bound skill missing: {leaf}")
93
+
94
+ def test_stages_ordered(self):
95
+ role = role_text()
96
+ self.assertIsNotNone(role)
97
+ wf = role[role.find("## Workflow"):role.find("## Evidence gates")]
98
+ idx = [wf.find(s) for s in STAGES]
99
+ self.assertTrue(all(i >= 0 for i in idx), "stage missing in workflow")
100
+ self.assertEqual(idx, sorted(idx), "stage order not deterministic")
101
+
102
+ def test_template_present(self):
103
+ self.assertTrue(os.path.exists(TEMPLATE), "deliverable template missing")
104
+
105
+ def test_boundaries(self):
106
+ role = role_text()
107
+ self.assertIsNotNone(role)
108
+ for phrase in ["sign_off_required: true", "forbidden"]:
109
+ self.assertIn(phrase, role)
110
+
111
+ def test_sources(self):
112
+ self.assertTrue(os.path.exists(os.path.join(ROLE_DIR, "SOURCES.md")),
113
+ "SOURCES.md missing")
114
+
115
+
116
+ if __name__ == "__main__":
117
+ unittest.main()
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env python3
2
+ """Test space_systems_core: the executable engine of the Space Systems role.
3
+
4
+ Proves the role can DO its job standalone (no AeroSkills needed): orbit
5
+ mechanics, delta-v budgeting and propellant sizing, reaction wheel
6
+ sizing, power/thermal closure, comms link budget, report generation,
7
+ and evidence-gate checks. Anchor values come from the bound AeroSkills
8
+ space-systems leaves (hohmann-transfer, mission-delta-v-budget,
9
+ power-thermal-budget, solar-array-sizing, eclipse-time,
10
+ reaction-wheel-control, communication-link-budget).
11
+ """
12
+ import os
13
+ import sys
14
+ import unittest
15
+
16
+ sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "core"))
17
+ from space_systems_core import ( # noqa: E402
18
+ MU_EARTH, RE_EARTH, apply_margin,
19
+ battery_capacity_required, build_report, check_report,
20
+ check_report_markdown, circular_velocity, comms_link_budget,
21
+ eclipse_geometry, eol_specific_power, example_mission,
22
+ example_report_markdown, free_space_path_loss, hohmann_burn_delta_v,
23
+ mission_delta_v_budget, orbit_period_seconds, perigee_lowering_delta_v,
24
+ pointing_error_budget, power_and_thermal, propellant_mass,
25
+ radiator_area, reaction_wheel_sizing, render_report_markdown,
26
+ slant_range_m, solar_array_daylight_power, sum_delta_v, wet_mass,
27
+ )
28
+
29
+
30
+ class TestOrbitMechanics(unittest.TestCase):
31
+ """Domain rules: vis-viva, periods, Hohmann and disposal burns."""
32
+
33
+ def test_circular_velocity_anchors(self):
34
+ # hohmann-transfer leaf anchors: LEO 6878 km -> ~7613 m/s,
35
+ # GEO 42164 km -> ~3075 m/s.
36
+ self.assertAlmostEqual(circular_velocity(6878e3), 7612.7, delta=1.0)
37
+ self.assertAlmostEqual(circular_velocity(42164e3), 3074.7, delta=1.0)
38
+
39
+ def test_geostationary_period(self):
40
+ self.assertAlmostEqual(orbit_period_seconds(42164e3) / 3600.0,
41
+ 23.934, delta=0.05)
42
+
43
+ def test_hohmann_leo_to_geo_total(self):
44
+ # Leaf reference: LEO(Re+500 km) -> GEO totals about 3816 m/s.
45
+ dv = hohmann_burn_delta_v(RE_EARTH + 500e3, 42164e3)
46
+ self.assertAlmostEqual(dv["total_m_s"], 3816.0, delta=60.0)
47
+ self.assertEqual(dv["total_m_s"],
48
+ dv["dv1_m_s"] + dv["dv2_m_s"])
49
+
50
+ def test_disposal_burn_positive_and_bounded(self):
51
+ dv = perigee_lowering_delta_v(600.0, 100.0)
52
+ v_circ = circular_velocity(RE_EARTH + 600e3)
53
+ self.assertGreater(dv, 0.0)
54
+ self.assertLess(dv, v_circ)
55
+ # 600 km -> 100 km perigee is a ~140 m/s class burn.
56
+ self.assertAlmostEqual(dv, 141.7, delta=3.0)
57
+
58
+
59
+ class TestDeltaVAndPropellant(unittest.TestCase):
60
+ """Domain rules: rocket equation, margins (mission-delta-v-budget)."""
61
+
62
+ def test_propellant_mass_anchor(self):
63
+ # Leaf anchor: dv 2941.995 m/s, 1000 kg dry, 300 s -> ~1718.28 kg.
64
+ self.assertAlmostEqual(propellant_mass(2941.995, 1000.0, 300.0),
65
+ 1718.28, delta=0.5)
66
+ self.assertAlmostEqual(wet_mass(2941.995, 1000.0, 300.0),
67
+ 2718.28, delta=0.5)
68
+
69
+ def test_zero_dv_zero_propellant(self):
70
+ self.assertEqual(propellant_mass(0.0, 1000.0, 300.0), 0.0)
71
+
72
+ def test_sum_and_margin(self):
73
+ self.assertEqual(sum_delta_v([100.0, 200.0, 50.0]), 350.0)
74
+ self.assertAlmostEqual(apply_margin(350.0, 0.15), 402.5, places=6)
75
+ self.assertEqual(apply_margin(350.0, 0.0), 350.0)
76
+
77
+ def test_example_budget_structure(self):
78
+ budget = mission_delta_v_budget(example_mission())
79
+ self.assertAlmostEqual(
80
+ budget["nominal_dv_m_s"],
81
+ sum(budget["contributions"].values()), places=6)
82
+ self.assertAlmostEqual(budget["budgeted_dv_m_s"],
83
+ budget["nominal_dv_m_s"] * 1.15, places=6)
84
+ self.assertGreater(budget["propellant_mass_kg"], 0.0)
85
+ self.assertLess(budget["propellant_fraction"], 0.2)
86
+ # disposal dominates a 600 km mission budget (realism marker)
87
+ self.assertGreater(
88
+ budget["contributions"]["End-of-life disposal (perigee lowering)"],
89
+ budget["contributions"]["Injection dispersion correction"])
90
+
91
+
92
+ class TestEclipseAndPower(unittest.TestCase):
93
+ """Domain rules: eclipse geometry, battery and solar array sizing."""
94
+
95
+ def test_eclipse_geometry_600km(self):
96
+ g = eclipse_geometry(600.0)
97
+ self.assertAlmostEqual(g["period_s"], 5801.0, delta=20.0)
98
+ self.assertAlmostEqual(g["shadow_fraction"], 0.367, delta=0.005)
99
+ self.assertAlmostEqual(g["eclipse_time_min"], 35.5, delta=0.4)
100
+ self.assertAlmostEqual(g["daylight_fraction"],
101
+ 1.0 - g["shadow_fraction"], places=9)
102
+
103
+ def test_battery_capacity_required(self):
104
+ # 80 W over a 35.5 min eclipse at 30% DoD / 90% efficiency.
105
+ wh = battery_capacity_required(80.0, 35.5, 0.30, 0.90)
106
+ self.assertAlmostEqual(wh, 175.3, delta=0.2)
107
+
108
+ def test_solar_array_daylight_power_anchor(self):
109
+ # power-thermal-budget leaf anchor: 500 W, f=0.35, no margin.
110
+ self.assertAlmostEqual(solar_array_daylight_power(500.0, 0.35, 1.0),
111
+ 769.23, delta=0.5)
112
+ self.assertAlmostEqual(solar_array_daylight_power(500.0, 0.35, 1.0, 0.20),
113
+ 923.08, delta=0.5)
114
+
115
+ def test_eol_specific_power_anchor(self):
116
+ # solar-array-sizing leaf anchor: 1367*0.30*0.85*0.98^10.
117
+ self.assertAlmostEqual(eol_specific_power(1367.0, 0.30, 0.85, 0.02, 10),
118
+ 284.82, delta=0.05)
119
+
120
+ def test_radiator_area(self):
121
+ # 55 W at 293.15 K, eps 0.9 -> ~0.15 m^2.
122
+ self.assertAlmostEqual(radiator_area(55.0, 293.15, 3.0, 0.90),
123
+ 0.146, delta=0.01)
124
+
125
+ def test_example_power_closes(self):
126
+ pw = power_and_thermal(example_mission())
127
+ self.assertGreaterEqual(pw["battery_margin"], 0.20)
128
+ self.assertAlmostEqual(pw["array_area_m2"], 0.79, delta=0.03)
129
+ self.assertAlmostEqual(pw["battery_sized_wh"], 215.0, delta=1.0)
130
+
131
+
132
+ class TestAdcs(unittest.TestCase):
133
+ """Domain rules: wheel sizing h = J*omega and pointing RSS."""
134
+
135
+ def test_slew_momentum_is_j_times_omega(self):
136
+ ad = reaction_wheel_sizing(example_mission(), 5801.0)
137
+ omega = (3.141592653589793 / 2.0) / 90.0
138
+ self.assertAlmostEqual(ad["omega_slew_rad_s"], omega, places=9)
139
+ self.assertAlmostEqual(ad["slew_momentum_nms"], 20.0 * omega,
140
+ places=4)
141
+
142
+ def test_wheel_inertia_from_momentum_capacity(self):
143
+ ad = reaction_wheel_sizing(example_mission(), 5801.0)
144
+ # h = J_w * omega_max: 1.0 N m s at 6000 rpm.
145
+ self.assertAlmostEqual(ad["wheel_inertia_kgm2"], 1.0 / 628.3185,
146
+ delta=1e-6)
147
+ self.assertGreater(ad["required_momentum_nms"], 0.3)
148
+ self.assertLess(ad["required_momentum_nms"],
149
+ ad["wheel_momentum_capacity_nms"])
150
+
151
+ def test_pointing_budget_meets(self):
152
+ pt = pointing_error_budget(example_mission())
153
+ self.assertAlmostEqual(pt["rss_deg"], 0.0482, delta=0.001)
154
+ self.assertTrue(pt["meets"])
155
+ self.assertGreater(pt["margin"], 2.0)
156
+
157
+
158
+ class TestComms(unittest.TestCase):
159
+ """Domain rules: Friis path loss and link margins."""
160
+
161
+ def test_slant_range_600km_5deg(self):
162
+ self.assertAlmostEqual(slant_range_m(600.0, 5.0) / 1000.0,
163
+ 2329.0, delta=10.0)
164
+
165
+ def test_free_space_path_loss_x_band(self):
166
+ fsl = free_space_path_loss(2329e3, 8.2e9)
167
+ self.assertAlmostEqual(fsl, 178.1, delta=0.5)
168
+
169
+ def test_example_links_close(self):
170
+ cm = comms_link_budget(example_mission())
171
+ self.assertGreaterEqual(cm["downlink"]["margin_db"], 3.0)
172
+ self.assertGreaterEqual(cm["uplink"]["margin_db"], 3.0)
173
+ self.assertGreater(cm["daily_capacity_gb"],
174
+ cm["imaging_data_gb_per_day"])
175
+
176
+
177
+ class TestReportBuilderAndGates(unittest.TestCase):
178
+
179
+ def test_example_model_values(self):
180
+ model = build_report(example_mission())
181
+ self.assertEqual(model["status"], "draft-for-review")
182
+ self.assertEqual(model["orbit"]["altitude_km"], 600.0)
183
+ dv = model["delta_v"]
184
+ self.assertGreater(dv["nominal_dv_m_s"], 180.0)
185
+ self.assertAlmostEqual(dv["budgeted_dv_m_s"],
186
+ dv["nominal_dv_m_s"] * 1.15, places=6)
187
+ self.assertGreater(dv["propellant_mass_kg"], 15.0)
188
+ self.assertAlmostEqual(model["adcs"]["wheel_momentum_capacity_nms"],
189
+ 1.0, places=3)
190
+ self.assertLess(model["power"]["array_area_m2"], 1.0)
191
+ self.assertTrue(model["pointing"]["meets"])
192
+ self.assertTrue(model["comms"]["downlink_meets"])
193
+ self.assertTrue(model["mass"]["closes"])
194
+ self.assertTrue(all(model["verdicts"].values()), model["verdicts"])
195
+
196
+ def test_render_has_all_sections_and_markers(self):
197
+ md = example_report_markdown()
198
+ for n in range(1, 10):
199
+ self.assertIn(f"## {n}.", md, f"section {n} missing")
200
+ low = md.lower()
201
+ self.assertIn("draft", low)
202
+ self.assertIn("not an approval", low)
203
+ self.assertIn("not launch readiness", low)
204
+ self.assertGreater(len(md), 4000)
205
+
206
+ def test_core_gates_all_pass(self):
207
+ model = build_report(example_mission())
208
+ gates = check_report(model)
209
+ self.assertTrue(gates["all_pass"], gates)
210
+
211
+ def test_markdown_gates_all_pass(self):
212
+ md = example_report_markdown()
213
+ gates = check_report_markdown(md)
214
+ self.assertTrue(gates["all_pass"], gates)
215
+
216
+ def test_gate_fails_on_approval_status(self):
217
+ model = build_report(example_mission())
218
+ model["status"] = "approved"
219
+ gates = check_report(model)
220
+ self.assertFalse(gates["sign_off_honest"])
221
+ self.assertFalse(gates["all_pass"])
222
+
223
+ def test_gate_fails_when_pointing_exceeds(self):
224
+ model = build_report(example_mission())
225
+ model["pointing"]["requirement_deg"] = 0.01
226
+ model["pointing"]["meets"] = False
227
+ gates = check_report(model)
228
+ self.assertFalse(gates["pointing_meets"])
229
+ self.assertFalse(gates["all_pass"])
230
+
231
+ def test_deterministic_build(self):
232
+ a = build_report(example_mission())
233
+ b = build_report(example_mission())
234
+ self.assertEqual(a["delta_v"]["nominal_dv_m_s"],
235
+ b["delta_v"]["nominal_dv_m_s"])
236
+
237
+ def test_standalone_no_skills_repo(self):
238
+ # Core must work with no AeroSkills present.
239
+ os.environ["AEROSKILLS_DEV"] = "/nonexistent"
240
+ model = build_report(example_mission())
241
+ self.assertGreater(model["delta_v"]["budgeted_dv_m_s"], 0.0)
242
+ md = render_report_markdown(model)
243
+ self.assertGreater(len(md), 4000)
244
+
245
+
246
+ if __name__ == "__main__":
247
+ unittest.main()
@@ -0,0 +1,154 @@
1
+ ---
2
+ type: role
3
+ name: state-estimation-engineer
4
+ title: "State Estimation Engineer"
5
+ status: draft
6
+ domain: gnc-autonomy
7
+ deliverable_type: "navigation state estimator design report"
8
+ standards_bound:
9
+ - id: arp4754a
10
+ tier: TIER-2
11
+ reference-only: true
12
+ skills_bound:
13
+ - gnc-autonomy/estimation-filtering/alpha-beta-filter
14
+ - gnc-autonomy/estimation-filtering/complementary-filter
15
+ - gnc-autonomy/estimation-filtering/extended-kalman-filter
16
+ - gnc-autonomy/estimation-filtering/interacting-multiple-model-filter
17
+ - gnc-autonomy/estimation-filtering/particle-filter
18
+ - gnc-autonomy/estimation-filtering/rts-smoother
19
+ - gnc-autonomy/estimation-filtering/unscented-kalman-filter
20
+ tools_allowed: [stdlib, offline-file-processing]
21
+ forbidden:
22
+ - "release navigation/flight software"
23
+ - "authorize flight"
24
+ - "claim certification approval"
25
+ - "reproduce proprietary standard text"
26
+ - "assert estimator performance without a checkable noise model"
27
+ sign_off_required: true
28
+ license: Apache-2.0
29
+ compatibility: "agentskills.io ROLE.md; any SKILL.md host"
30
+ metadata:
31
+ version: 0.1.0
32
+ author: ashfordeOU
33
+ skills_release: "v1.3.0+"
34
+ ---
35
+
36
+ # State Estimation Engineer
37
+
38
+ ## Role identity
39
+
40
+ This role designs and analyzes navigation state estimators for aerospace
41
+ vehicles: the estimators that fuse inertial, GNSS, attitude-reference,
42
+ and aiding sensors into the continuous attitude, position, velocity, and
43
+ bias states a guidance or control loop consumes. Use when a project must
44
+ select and size an estimator (attitude observer, GNSS/INS navigation
45
+ filter, nonlinear tracking filter), choose process/measurement noise
46
+ models, verify observability and consistency, or design offline
47
+ post-processing. Do NOT use for pure control design (see GNC Engineer
48
+ role), for sensor hardware selection, or when the vehicle has no
49
+ navigation/estimation need. Bind the gnc-autonomy/estimation-filtering
50
+ cluster.
51
+
52
+ ## Deliverable contract
53
+
54
+ The role produces the **Navigation State Estimator Design Report** for a
55
+ reference item (an INS/GPS or attitude estimator), containing:
56
+
57
+ 1. **Architecture** — estimator class, channels (attitude complementary
58
+ filter; position/velocity Kalman recursion; nonlinear EKF/UKF
59
+ updates), sensor set, frames, sample rates, and design inputs
60
+ (noise model: process intensity q, measurement variance r).
61
+ 2. **Design numbers** — complementary-filter gains and drift/lag
62
+ anchors; discrete constant-velocity Kalman covariance/gain recursion
63
+ results; alpha-beta companion gains (Benedict-Bordner, Kalata);
64
+ EKF linearization (Jacobian, innovation, gain, corrected state);
65
+ NEES and particle ESS verification figures; RTS smoother covariance
66
+ reduction; observability determinant/rank.
67
+ 3. **Verification evidence + open items** — evidence-gate summary and
68
+ what the human navigation engineer must still resolve before
69
+ implementation.
70
+
71
+ ## Workflow (stages → bound skills)
72
+
73
+ | Stage | Loads skill | Produces |
74
+ |---|---|---|
75
+ | 1. Architecture + noise model | (all estimation-filtering leaves) | estimator class, channels, design inputs |
76
+ | 2. Attitude channel | complementary-filter | gains, drift/lag anchors, innovation tolerance |
77
+ | 3. Navigation channel | rts-smoother + interacting-multiple-model-filter | CV Kalman recursion numbers, model matrices |
78
+ | 4. Fixed-gain companion | alpha-beta-filter | Benedict-Bordner + Kalata gains from the tracking index |
79
+ | 5. Nonlinear updates | extended-kalman-filter + unscented-kalman-filter | linearized Jacobian, innovation, gain, corrected state, NEES |
80
+ | 6. Fallbacks | particle-filter + interacting-multiple-model-filter | SIR ESS rule, IMM maneuvering bank |
81
+ | 7. Offline post-processing | rts-smoother | fixed-interval smoothing covariance reduction |
82
+ | 8. Observability | (all) | observability matrix rank/verdict, bias-observability note |
83
+ | 9. Report | (all above) | the Navigation State Estimator Design Report |
84
+
85
+ ## Evidence gates
86
+
87
+ - Stage 2 done = complementary-filter gains numeric + drift/lag anchors
88
+ present.
89
+ - Stage 3 done = Kalman recursion produced gains and covariances over
90
+ the design horizon.
91
+ - Stage 4 done = alpha-beta gains computed from the tracking index and
92
+ consistent with the converged Kalman gain.
93
+ - Stage 5 done = EKF Jacobian/innovation/gain present and NEES finite.
94
+ - Stage 8 done = observability determinant/rank computed with a verdict.
95
+ - FINAL = every section has a number from the role core grounded in the
96
+ bound leaf equations or the leaf documentation; nothing asserted
97
+ without a checkable basis; output marked DRAFT.
98
+
99
+ ## Boundary / forbidden
100
+
101
+ - NEVER release navigation or flight software, and NEVER authorize
102
+ flight — implementation and flight release are human engineering
103
+ decisions.
104
+ - NEVER claim certification or regulatory approval.
105
+ - NEVER assert estimator performance without a checkable noise model
106
+ (the report's noise values are inputs that trace to sensor
107
+ datasheets).
108
+ - NEVER reproduce proprietary standard text (summary-not-copy).
109
+ - Output is a DRAFT for human review — mark it draft.
110
+
111
+ ## Verification
112
+
113
+ The role runs STANDALONE: `core/state_estimation_core.py` is an
114
+ executable engine that computes the complementary-filter design anchors,
115
+ runs the discrete constant-velocity Kalman recursion (same F/Q/H model
116
+ as the bound rts-smoother and IMM leaves), the alpha-beta
117
+ (Benedict-Bordner/Kalata) gains, the EKF linearization, NEES/ESS
118
+ consistency metrics, the RTS smoother reduction, and the observability
119
+ analysis, BUILDS the report, and gate-checks deliverables. No AeroSkills
120
+ checkout required.
121
+
122
+ Run the role:
123
+ ```bash
124
+ python3 cli.py build --out report.md # example item
125
+ python3 cli.py build --out report.md --bundle # + evidence bundle
126
+ python3 cli.py build --dt 0.5 --steps 120 --r 1.0 # variant facts
127
+ python3 cli.py build --profile program.json # program header
128
+ python3 cli.py check --file report.md # gate-check
129
+ ```
130
+
131
+ Tests:
132
+ - tests/test_state_estimation_engineer_core.py: domain rules (gains,
133
+ recursion, linearization, metrics, observability) + builder + gates +
134
+ standalone (no skills repo)
135
+ - tests/test_role_state_estimation_engineer.py: bound-skill resolution
136
+ (skips if the skills repo is absent) + workflow + template + boundaries
137
+ - tests/test_bundle_protocol.py: build --bundle emits the evidence
138
+ bundle, gates all pass, dispatch cross-checks agree when AeroSkills
139
+ is present, standalone is honest
140
+
141
+ Bound skills in Aero Agent Skills deepen individual stages when the
142
+ library is present (attitude filter logic, Kalman recursion,
143
+ alpha-beta gains, EKF Jacobian, NEES, ESS); the core engine does not
144
+ depend on them. With the library present, `--bundle` dispatches the
145
+ bound leaf logic and records core/skill agreement (delta) in
146
+ provenance.json — two independent implementations of the same
147
+ equations agreeing.
148
+
149
+ ## Compliance
150
+
151
+ - arp4754a TIER-2 reference-only per standards-map; no verbatim.
152
+ - SOURCES.md records acquisition/extraction/verification status.
153
+ - Estimator mathematics referenced in SOURCES.md are public-domain
154
+ educational texts and the bound leaf logic files.
@@ -0,0 +1,27 @@
1
+ # SOURCES.md - State Estimation Engineer
2
+
3
+ Standards and references this role draws on. Summary-not-copy: see
4
+ [STANDARDS.md](../../STANDARDS.md) for the full rule and purchase links.
5
+ No proprietary text is reproduced anywhere in this role.
6
+
7
+ | Source | Role use | Gated |
8
+ |---|---|---|
9
+ | SAE ARP4754A | development-assurance context for aircraft systems (reference-only; the estimator supports system functions whose assurance is managed at system level) | true |
10
+ | gnc-autonomy/estimation-filtering leaves (AeroSkills) | the role's equations are grounded in the leaf logic files: alpha-beta-filter (Benedict-Bordner beta = alpha^2/(2-alpha); Kalata gains from tracking index lambda = sigma_w*dt^2/sigma_v), rts-smoother (CV model F = [[1, dt],[0, 1]], discretized Q; forward Kalman recursion; backward smoothing gain G_k = P_filt F^T P_pred^-1; covariance-reduction verdict), extended-kalman-filter (central-difference Jacobians; EKF predict/update recursion; bearing/range measurement model), unscented-kalman-filter (scaled unscented transform; NEES = (x-p)^T P^-1 (x-p) with expected value n), particle-filter (bootstrap/SIR; ESS = (sum w)^2 / sum(w^2); resample when ESS < n/2), complementary-filter (Mahony-style explicit complementary filter on SO(3): cross-product innovation e = m x v, corrected rate omega_c = omega_m - b + k_p*e, bias step b <- b - k_i*e*dt, RK4 quaternion kinematics + renormalization; module gain defaults k_p = 2.0 1/s, k_i = 0.4 1/s^2; trailing-window innovation-norm tolerance 1e-3 rad), interacting-multiple-model-filter (two-mode CV/CA bank, Markov mode mixing, Bayesian mode-probability refresh) | false |
11
+ | Kalman, R. E., "A New Approach to Linear Filtering and Prediction Problems", ASME J. Basic Engineering 82 (1960) | the linear Kalman recursion the report is built on (public) | false |
12
+ | R. G. Brown & P. Y. C. Hwang, Introduction to Random Signals and Applied Kalman Filtering (Wiley) | discrete CV/CA modeling, Q discretization, steady-state behavior (public educational text) | false |
13
+ | Mahony, Hamel & Pflimlin, "Nonlinear Complementary Filters on the Special Orthogonal Group", IEEE Trans. Automatic Control 53(5), 2008 | explicit complementary filter / bias observability with two non-parallel reference vectors (public) | false |
14
+ | Kalata, P. R., "The Tracking Index: A Generalized Parameter for alpha-beta and alpha-beta-gamma Target Trackers", IEEE Trans. AES 20(2), 1984 | tracking-index gain selection (public) | false |
15
+
16
+ The complementary-filter gain defaults (k_p = 2.0 1/s, k_i = 0.4
17
+ 1/s^2), the steady-state innovation tolerance (1e-3 rad), the
18
+ uncompensated-bias drift anchor |b|*t, the discrete sampling-lag bound
19
+ |omega|*dt, the SIR ESS threshold n/2, and the NEES expected-value n
20
+ criterion are documented module defaults and worked-example anchors of
21
+ the bound leaf SKILL.md files - reproduced as numbers, not as text.
22
+ Noise-model values in the report (q, r, bias vector, rates) are DESIGN
23
+ INPUTS that trace to the item's sensor datasheets; the report labels
24
+ them as inputs.
25
+
26
+ The report template in `templates/` is an original structure produced
27
+ by the role core for the reference item.