diff --git a/requirements.txt b/requirements.txt index af2938a..af5cc38 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,5 @@ git+https://github.com/Open-MBEE/sysmlv2-python-client.git@main requests +pytest +pytest_check +pytest-timeout diff --git a/src/flexo_syside_lib/retriever.py b/src/flexo_syside_lib/retriever.py index 7f2a34b..8da729a 100644 --- a/src/flexo_syside_lib/retriever.py +++ b/src/flexo_syside_lib/retriever.py @@ -12,7 +12,7 @@ from typing import Tuple, Optional import os import pathlib - +print('Retriever is loading...') import syside_license from sysmlv2_client import SysMLV2Client from flexo_syside_lib.core import convert_json_to_sysml_textual @@ -81,6 +81,8 @@ def _default_base_and_token() -> Tuple[str, str]: # === Main Model Retrieval === def retrieve_latest_sysml_full_model( project_name: str = DEFAULT_PROJECT_NAME, + base_url:str = None, + bearer_token:str = None, verbose: bool = True, ) -> str: """ @@ -102,7 +104,8 @@ def retrieve_latest_sysml_full_model( EnvironmentError: if required environment variables are missing. RuntimeError: if the project cannot be found. """ - base_url, bearer_token = _default_base_and_token() + if base_url is None or bearer_token is None: + base_url, bearer_token = _default_base_and_token() if verbose: print(f"[Flexo] Base URL: {base_url}") @@ -125,9 +128,9 @@ def retrieve_latest_sysml_full_model( # --- Model retrieval --- elements = client.list_elements(project_id, latest_commit_id) - sysml_text, _ = convert_json_to_sysml_textual(elements) + (sysml_text, model), warnings = convert_json_to_sysml_textual(elements) - return sysml_text + return (sysml_text, model), warnings # === Entrypoint === diff --git a/tests/Drone2.sysml b/tests/Drone2.sysml new file mode 100644 index 0000000..fddabf6 --- /dev/null +++ b/tests/Drone2.sysml @@ -0,0 +1,15 @@ +package MechanicalObjectExample { + private import ScalarValues::*; + part def DroneSystem { + part def Drone { + part battery { + /*attribute mass:ISQ::MassValue = 2.5 [SI::kg];*/ + attribute m:Real=2.5; + } + part propulsionUnit { + attribute mass:ISQ::MassValue = 0.5 [SI::kg]; + } + } + } + +} \ No newline at end of file diff --git a/tests/Test1.sysml b/tests/Test1.sysml new file mode 100644 index 0000000..1ac5b3c --- /dev/null +++ b/tests/Test1.sysml @@ -0,0 +1,23 @@ +package MechanicalObjectExample { + abstract item def MechanicalObject { + attribute mass :> ISQ::mass; + } + + abstract item mechanicalObjects[*] : MechanicalObject; + + metadata def MechanicalObjectMetadata :> Metaobjects::SemanticMetadata { + :>> baseType = mechanicalObjects meta SysML::Usage; + } + + part def DroneSystem { + part def Drone { + #mec part battery { + attribute :>> mass = 2.5 [SI::kg]; + } + #mec part propulsionUnit { + attribute :>> mass = 0.5 [SI::kg]; + } + } + } + +} \ No newline at end of file diff --git a/tests/Test3.sysml b/tests/Test3.sysml new file mode 100644 index 0000000..6c2020b --- /dev/null +++ b/tests/Test3.sysml @@ -0,0 +1,9 @@ +package FlashlightStarterModel { + part flashlight { + exhibit state flashlightStates { + state off; + transition start then off; + } + } +} + diff --git a/tests/Test4.sysml b/tests/Test4.sysml new file mode 100644 index 0000000..d4e706e --- /dev/null +++ b/tests/Test4.sysml @@ -0,0 +1,15 @@ +package FlashlightStarterModel { + package FlashlightSpecificationAndDesign { + package Parts { + } + } + package Views1{ + //private import Views::*; + view flashlightPartsTree{ + expose FlashlightSpecificationAndDesign::Parts::**; + filter @SysML::PartUsage; + render Views::asTreeDiagram; + } + } +} + diff --git a/tests/Test5.sysml b/tests/Test5.sysml new file mode 100644 index 0000000..c1b8d38 --- /dev/null +++ b/tests/Test5.sysml @@ -0,0 +1,1416 @@ +package CometInceptorModified { + + /* Modification: Added short name to metadata definition cDFProduct and added root package CometInceptorModified */ + + /* + This model is based on the European Space Agency (ESA) Concurrent Design Facility (CDF) public report of the Comet Interceptor study (https://esamultimedia.esa.int/docs/cdf/CometInterceptor_CDF_Study_Report.pdf) + All contents come directly or are inferred from the information contained in this report, and do not take into account subsequent iterations of the mission design. + More information about the mission and the study and the list of acronyms can be found in the report. + */ + + private import ScalarValues::*; + private import RequirementDerivation::*; + private import SI::*; + private import CDFReferenceDataLibrary::*; + + + package 'Mission objectives' { + use case 'Assess the bulk shape of the nucleus and the morphology of its surface at a scale comparable to the best images returned by previous comet flyby missions, and those returned by New Horizons of Kuiper Belt Objects' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Determine the bulk composition of the nucleus’ surface' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Investigate activity in a fresh comet' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Assess the molecular composition of the coma simultaneously at multiple locations and the isotopic composition along one path' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + + use case 'Identify parent and daughter neutral and ion species and assess their relationship in the coma' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Characterise the dust in the coma' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Assess the structure of boundaries and regions in the plasma environment of a comet' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Assess the energy, mass and momentum transfer in the cometary environment, through the coma and across boundaries' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Assess how plasma and dust interact in various regions of the coma' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + } + + + package 'Mission requirements' { + requirement <'MIS-010'> { + doc /* The mission shall intercept a Long Period Comet (LPC) or an interstellar body in a fly-by scenario. */ + comment /* See science requirements for more details */ + } + requirement <'MIS-020'> { + doc /* The mission shall include one main S/C (ESA) (hereafter S/C A) and two probes (one JAXA and one ESA) (namely probes B1 and B2, respectively) + * in order to gather multi-point observations of the comet and its coma. */ + comment /* See science requirements for more details */ + } + requirement <'MIS-030'> { + doc /* The mission shall embark the instruments as specified in the relevant Instrument Interface Description Documents. */ + comment /* See science requirements for more details */ + } + requirement <'MIS-040'> { + doc /* The mission shall allow parking the spacecraft in a Halo orbit around the SEL2 point after launch, wait for a target of opportunity, and then intercept it. */ + comment /* Ability to find a suitable target comet */ + } + requirement <'MIS-050'> { + doc /* The mission shall allow a fly-by to backup target comets 73P/Schwassmann-Wachmann (TBC) and 26P/Grigg-Skjellerup (TBC) within the nominal mission lifetime. */ + comment /* Ability to find a suitable backup comet in case no other suitable target is found */ + } + requirement <'MIS-060'> { + doc /* The mission shall be compatible with a launch together with the ARIEL mission/spacecraft. */ + comment /* Mission constraint for a shared launch with ARIEL */ + } + requirement <'MIS-070'> { + doc /* The nominal mission lifetime shall be maximum 5 years (TBC). */ + comment /* F-class mission constraint */ + } + requirement <'MIS-080'> { + doc /* The mission shall be compatible with ESA's F-mission budget Cost to Completion (CaC) not exceeding 150 M€. */ + comment /* F-class mission constraint */ + } + } + + + package 'Mission requirement satisfaction' { + private import 'Mission requirements'::*; + + satisfy 'MIS-010' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-020' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-030' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-040' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-050' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-060' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-070' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-080' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + } + + + package 'System requirements' { + requirement <'SYS-010'> { + doc /* The Comet Interceptor S/C shall contain one main S/C (S/C A - ESA) and two probes (B2 - ESA and B1 - JAXA). */ + } + requirement <'SYS-020'> { + doc /* The Comet Interceptor S/C shall be launched by the Ariane 62 launcher from Kourou (Guiana Space Centre). */ + } + requirement <'SYS-030'> { + doc /* The Comet Interceptor S/C shall be launched in 2028. */ + } + requirement <'SYS-040'> { + doc /* The Comet Interceptor S/C nominal lifetime shall be maximum 5 years (TBC). */ + } + requirement <'SYS-050'> { + doc /* The Comet Interceptor S/C shall embark the instruments as specified in the relevant Instrument Interface Description Documents. */ + } + requirement <'SYS-060'> { + doc /* The Comet Interceptor S/C A post flyby phase duration shall be maximum 6 months. */ + } + requirement <'SYS-070'> { + doc /* All Comet Interceptor S/C equipment shall be TRL 6 by Mission Selection (Q1 2020) and TRL 7 by Mission Adoption (Q4 2022). */ + } + requirement <'SYS-080'> { + doc /* The Comet Interceptor S/C A shall provide the mechanical, thermal and electrical interfaces for both probes B1 and B2. */ + } + requirement <'SYS-090'> { + doc /* The S/C A, B1 and B2 configurations shall ensure unobstructed fields of view for the instruments for observation purposes and for the communication antennas. */ + } + requirement <'SYS-100'> { + doc /* The S/C A shall carry the probes (B1 and B2) from integration up to their separation before the flyby. */ + } + requirement <'SYS-101'> { + doc /* The mission shall allow a release of the probe B2 at least 24 hours (TBC) before the closest approach. */ + } + requirement <'SYS-102'> { + doc /* The mission shall allow a flyby altitude for the probe B2 of between 100 m to 400 m (TBC). */ + } + requirement <'SYS-103'> { + doc /* The mission shall allow a release of the probe B1 at least 48 hours (TBC) before the closest approach. */ + } + requirement <'SYS-104'> { + doc /* The mission shall allow a flyby altitude for the probe B1 of between 100 m to 400 m (TBC). */ + } + requirement <'SYS-110'> { + doc /* The instruments on B1 and B2 shall be used only after separation of the spacecraft from S/C A. */ + } + requirement <'SYS-120'> { + doc /* Check-out operation activities of the scientific instruments and the rest of equipment on-board the probes B1 and B2 shall be possible before their separation from S/C A. */ + } + requirement <'SYS-130'> { + doc /* The probe B2 shall be designed considering a design-to-cost approach. */ + } + requirement <'SYS-140'> { + doc /* The probe B2 shall be designed for a 24h (TBC) lifetime. */ + } + requirement <'SYS-150'> { + doc /* The probe B2 shall be spin-stabilised. */ + } + requirement <'SYS-160'> { // Requirement inferred from the system assumptions. Not a requirement in the report + doc /* The Comet Interceptor main S/C shall not exceed a wet mass of 650 kg (excluding adapter). */ + comment /* To be compatible with the use of a dual launch with ARIEL and the Dual Launch Structure (DLS) */ + + assume constraint { 'Comet Interceptor space segment (physical)'.'Main spacecraft'.wetMass <= 650 [kg] } + } + } + + + package 'System requirement satisfaction' { + private import 'System requirements'::*; + + satisfy 'SYS-010' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-020' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-030' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-040' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-050' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-060' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-070' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-080' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-090' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-100' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-101' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-102' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-103' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-104' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-110' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-120' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-130' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-140' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-150' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-160' by 'Comet Interceptor space segment (physical)'.'Main spacecraft'.wetMass; + } + + + package 'Mission to System requirement derivation' { + private import 'Mission requirements'::*; + private import 'System requirements'::*; + + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-010'; + } + #derivation connection { + end #original ::> 'MIS-060'; + end #derive ::> 'SYS-020'; + } + #derivation connection { + end #original ::> 'MIS-080'; + end #derive ::> 'SYS-030'; + } + #derivation connection { + end #original ::> 'MIS-070'; + end #derive ::> 'SYS-040'; + } + #derivation connection { + end #original ::> 'MIS-030'; + end #derive ::> 'SYS-050'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-060'; + } + #derivation connection { + end #original ::> 'MIS-070'; + end #derive ::> 'SYS-060'; + } + #derivation connection { + end #original ::> 'MIS-060'; + end #derive ::> 'SYS-070'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-080'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-090'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-100'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-101'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-102'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-103'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-104'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-110'; + } + #derivation connection { + end #original ::> 'MIS-030'; + end #derive ::> 'SYS-110'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-120'; + } + #derivation connection { + end #original ::> 'MIS-030'; + end #derive ::> 'SYS-120'; + } + #derivation connection { + end #original ::> 'MIS-080'; + end #derive ::> 'SYS-130'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-140'; + } + #derivation connection { + end #original ::> 'MIS-030'; + end #derive ::> 'SYS-140'; + } + #derivation connection { + end #original ::> 'MIS-080'; + end #derive ::> 'SYS-140'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-150'; + } + #derivation connection { + end #original ::> 'MIS-030'; + end #derive ::> 'SYS-150'; + } + #derivation connection { + end #original ::> 'MIS-060'; + end #derive ::> 'SYS-160'; + } + } + + + // Mission Architecture + part 'Comet Interceptor mission context' { + part 'Comet Interceptor space system' { + part 'Ariane 62 launcher'{ + comment /* Dual launch with ARIEL */ + } + part 'Comet Interceptor ground segment' { + part 'Mission Operations Centre'; + part <'JAXA MOC'> 'JAXA Mission Operations Centre'; + part 'ESTRACK ground station network'; + } + part 'Comet Interceptor space segment'; // System of Interest + + exhibit 'Mission phases'; + } + part 'Long Period Comet'; + part 'Science community'; + part Earth; + part Sun; + part 'Space environment'; + } + + + state 'Mission phases' { + entry; + then state 'Ariane 62 launch from Kourou'; + then state 'L2 transfer'; + then state 'Waiting at L2'; + then state 'Target transfer'; + then state 'Comet fly-by'; + then done; + } + + + state 'System modes'{ + state 'Launch mode' { + doc /* From launch to spacecraft separation. + * Most equipment OFF (OBC and receiver potentially ON) + */ + } + state 'Sun Acquisition Mode' { + doc /* From spacecraft separation up to Sun pointing attitude + * Minimum units are ON (Sun sensors, TT&C up- and down-link via LGA) + * Instruments are OFF + */ + } + state 'Safe Mode' { + doc /* Minimum units ON to ensure prolonged safe state and communications to facilitate coming back to a nominal mode + * Instruments are OFF + */ + } + state 'Standby Mode' { + doc /* Applicable when not thrusting, communicating with Earth, nor acquiring science data + * Instruments are OFF + * Most platform units are ON + */ + } + state 'Communication Mode' { + doc /* Applicable for communication with Earth + * Most platform units are ON and transmitter is ON + */ + } + state 'EP Thrusting Mode' { + doc /* Applicable for reaching the target object + * Instruments are OFF + * Most platform units are ON and EP thruster is ON + */ + } + state 'Science Mode' { + doc /* Applicable for science acquisition during the fly-by at encounter + * Instruments are ON + * Most platform units are ON + */ + } + + entry; + then LAU; + transition first LAU then SUN; + transition first SUN then STBY; + transition first STBY then SAFE; + transition first SAFE then STBY; + transition first STBY then SCI; + transition first SCI then STBY; + transition first STBY then COM; + transition first COM then STBY; + transition first STBY then EPTH; + transition first EPTH then STBY; + transition first SCI then SAFE; + transition first COM then SAFE; + transition first EPTH then SAFE; + } + + + state 'Equipment power modes' { + entry; + then state OFF; + then state 'Stand-by'; + then state ON; + transition first OFF then ON; + transition first STBY then OFF; + transition first ON then OFF; + transition first ON then STBY; + } + + + //* The function tree below has been generated with AI. It is presented here as it may be useful for some use cases, but will contain inaccuracies + + action 'Comet Interceptor space segment (functional)' { + action 'Mission System' { + action 'Mission Planning & Operations'; + action 'Science Data Acquisition'; + action 'Science Data Transmission'; + action 'Multi-Spacecraft Coordination'; + } + action 'Spacecraft Bus' { + action 'Power Subsystem' { + action 'Solar Power Generation'; + action 'Power Storage'; + action 'Power Distribution and Regulation'; + } + action 'Thermal Control' { + action 'Passive Thermal Control'; + action 'Active Thermal Control'; + } + action 'Attitude and Orbit Control System' { + action 'Attitude Determination'; + action 'Attitude Control'; + action 'Orbit Maneuvering'; + } + action 'Communication Subsystem' { + action <'TT&C'> 'Telemetry, Tracking & Command'; + action 'Science Data Downlink'; + action 'Inter-spacecraft Communication'; + } + action 'Onboard Data Handling' { + action 'Data Storage'; + action 'Data Processing'; + action 'Fault Detection, Isolation and Recovery'; + } + } + action 'Payload Module' { + action 'Scientific Instruments' { + action 'Visible and UV Imaging Systems'; + action 'Mass Spectrometers'; + action 'Dust Analyzers'; + action 'Plasma Instruments'; + } + action 'Payload Support Systems' { + action 'Instrument Mounting and Pointing'; + action 'Instrument Power and Data Interfaces'; + action 'Thermal Control for Instruments'; + } + } + action 'Multi-Spacecraft Configuration' { + action 'Spacecraft A' { + action 'Carrier for B1 and B2'; + action 'Primary Communication with Earth'; + } + action 'Spacecraft B1' { + action 'Close Flyby Observations'; + action 'Independent Navigation'; + } + action 'Spacecraft B2' { + action 'Complementary Observations'; + action 'Independent Navigation'; + } + } + } + + allocate 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment' to 'Comet Interceptor space segment (functional)'; + */ + + allocate 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment' to 'Comet Interceptor space segment (physical)'; + + + // Product tree + #cDFProduct part 'Comet Interceptor space segment (physical)' { + #cDFProduct part 'Probe B1' { + attribute :>> totalMass = 30.00 [kg]; + + exhibit 'System modes'; + } + #cDFProduct part 'Probe B2' { + attribute :>> totalMass = 40.47 [kg]; + attribute :>> powerInLAU = 0.00 [W]; + attribute :>> powerInSUN = 0.00 [W]; + attribute :>> powerInSAFE = 0.00 [W]; + attribute :>> powerInSTBY = 0.00 [W]; + attribute :>> powerInCOM = 0.00 [W]; + attribute :>> powerInEPTH = 0.00 [W]; + attribute :>> powerInSCI = 35.59 [W]; + + exhibit 'System modes'.SCI; + } + #cDFProduct part <'S/C A'> 'Main spacecraft' { + #cDFProduct part Payload { + #cDFProduct part 'Comet Camera' { + attribute :>> totalMass = 12.81 [kg]; + attribute :>> powerInLAU = 0.00 [W]; + attribute :>> powerInSUN = 0.00 [W]; + attribute :>> powerInSAFE = 0.00 [W]; + attribute :>> powerInSTBY = 0.00 [W]; + attribute :>> powerInCOM = 0.00 [W]; + attribute :>> powerInEPTH = 0.00 [W]; + attribute :>> powerInSCI = 14.40 [W]; + attribute :>> MinNOT = -20 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 25 ['°C_abs']; + attribute :>> MaxNOT = 35 ['°C_abs']; + } + #cDFProduct part 'Dust Field and Plasma package' { + attribute :>> totalMass = 10.788 [kg]; + attribute :>> powerInLAU = 0.00 [W]; + attribute :>> powerInSUN = 0.00 [W]; + attribute :>> powerInSAFE = 0.00 [W]; + attribute :>> powerInSTBY = 0.00 [W]; + attribute :>> powerInCOM = 0.00 [W]; + attribute :>> powerInEPTH = 0.00 [W]; + attribute :>> powerInSCI = 20.16 [W]; + attribute :>> MinNOT = -25 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 40 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'Mass Analyzer for Neutrals in a Coma' { + attribute :>> totalMass = 6.54 [kg]; + attribute :>> powerInLAU = 0.00 [W]; + attribute :>> powerInSUN = 0.00 [W]; + attribute :>> powerInSAFE = 0.00 [W]; + attribute :>> powerInSTBY = 0.00 [W]; + attribute :>> powerInCOM = 0.00 [W]; + attribute :>> powerInEPTH = 0.00 [W]; + attribute :>> powerInSCI = 27.60 [W]; + attribute :>> MinNOT = -30 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 40 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'Modular Infrared Molecules and Ice Sensor' { + attribute :>> totalMass = 6.93 [kg]; + attribute :>> powerInLAU = 0.00 [W]; + attribute :>> powerInSUN = 0.00 [W]; + attribute :>> powerInSAFE = 0.00 [W]; + attribute :>> powerInSTBY = 0.00 [W]; + attribute :>> powerInCOM = 0.00 [W]; + attribute :>> powerInEPTH = 0.00 [W]; + attribute :>> powerInSCI = 9.00 [W]; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + } + #cDFProduct part Platform { + #cDFProduct part 'Attitude, orbit, guidance, navigation control' { + #cDFProduct part 'A DTU Data Processing Unit' { + attribute :>> mass = 0.560 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 3.6 [W]; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -65 ['°C_abs']; + attribute :>> MinOT = -60 ['°C_abs']; + attribute :>> MaxOT = 35 ['°C_abs']; + attribute :>> MaxNOT = 40 ['°C_abs']; + } + #cDFProduct part 'AIMU Northrop Grumman LN200 Core' [2] { + attribute :>> mass = 0.750 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 12 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = -1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -59 ['°C_abs']; + attribute :>> MinOT = -54 ['°C_abs']; + attribute :>> MaxOT = 71 ['°C_abs']; + attribute :>> MaxNOT = 76 ['°C_abs']; + } + #cDFProduct part 'A DTU NAVCAM Optical Head' [2] { + attribute :>> mass = 0.376 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 0.7 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = -1; + attribute :>> DC_EPTH = -1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -65 ['°C_abs']; + attribute :>> MinOT = -60 ['°C_abs']; + attribute :>> MaxOT = 35 ['°C_abs']; + attribute :>> MaxNOT = 40 ['°C_abs']; + } + #cDFProduct part 'A DTU STR Optical Head' [2] { + attribute :>> mass = 0.350 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 0.7 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -60 ['°C_abs']; // was -40 in the report (incorrect) + attribute :>> MinOT = -60 ['°C_abs']; + attribute :>> MaxOT = 35 ['°C_abs']; + attribute :>> MaxNOT = 40 ['°C_abs']; + } + #cDFProduct part 'A SUN LENS Bison 64' [6] { + attribute :>> mass = 0.025 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -45 ['°C_abs']; + attribute :>> MinOT = -40 ['°C_abs']; + attribute :>> MaxOT = 80 ['°C_abs']; + attribute :>> MaxNOT = 85 ['°C_abs']; + } + #cDFProduct part 'A RW Rockwell Collins RSI 4-215' [4] { + attribute :>> mass = 5.400 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 20 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::active; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 3; + attribute :>> redundancyConceptN = 4; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = -1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 70 ['°C_abs']; + attribute :>> MaxNOT = 75 ['°C_abs']; + } + } + #cDFProduct part Communications { + #cDFProduct part 'X-Band DSTRASP' { // product artificially decomposed into receiver and transmitter, for a better calculation of power budget + #cDFProduct part 'Transponder Receiver' [2] { + attribute :>> mass = 3.600 [kg]; // full XDST mass is shown in RX element (artificial) + attribute :>> MM = 0.05; + attribute :>> P_stby = 16 [W]; + attribute :>> P_on = 16 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::active; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 65 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'Transponder Transmitter' [2] { + attribute :>> mass = 0 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 16 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = -1; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 65 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + } + #cDFProduct part 'X-Band HGA' { + attribute :>> mass = 6.050 [kg]; + attribute :>> MM = 0.1; + attribute :>> MinNOT = -155 ['°C_abs']; + attribute :>> MinOT = -150 ['°C_abs']; + attribute :>> MaxOT = 150 ['°C_abs']; + attribute :>> MaxNOT = 150 ['°C_abs']; + } + #cDFProduct part 'X-Band LGA' [2] { + attribute :>> mass = 0.300 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -155 ['°C_abs']; + attribute :>> MinOT = -150 ['°C_abs']; + attribute :>> MaxOT = 150 ['°C_abs']; + attribute :>> MaxNOT = 150 ['°C_abs']; + } + #cDFProduct part 'X-Band RFDN' { + attribute :>> mass = 10.000 [kg]; + attribute :>> MM = 0.2; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'X-Band TWT' [2] { + attribute :>> mass = 0.800 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 103.07 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 0.55; + attribute :>> DC_SAFE = 0.3; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 0; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'X-Band TWTA EPC' [2] { + attribute :>> mass = 1.400 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 9 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 0; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -30 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'A GOMx Electronics' [2] { + attribute :>> mass = 0.503 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 6.72 [W]; + attribute :>> P_on = 8.16 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = -1; + attribute :>> DC_EPTH = -1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 85 ['°C_abs']; + attribute :>> MaxNOT = 95 ['°C_abs']; + } + #cDFProduct part 'A GOMx Antenna Patch' [6] { + attribute :>> mass = 0.150 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 1 [W]; + attribute :>> P_on = 7.2 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 3; // was 1 in the report (incorrect) + attribute :>> redundancyConceptN = 6; // was 2 in the report (incorrect) + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = -1; + attribute :>> DC_EPTH = -1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 85 ['°C_abs']; + attribute :>> MaxNOT = 95 ['°C_abs']; + } + } + #cDFProduct part 'Data handling' { + #cDFProduct part 'A Onboard Computer' { + attribute :>> mass = 6.500 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 23 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::internal; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 75 ['°C_abs']; + } + #cDFProduct part 'A Remote Interface Unit' { + attribute :>> mass = 12.000 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 30 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::internal; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 75 ['°C_abs']; + } + } + #cDFProduct part Power { + #cDFProduct part 'A SolarArray' [2] { + attribute :>> mass = 14.630 [kg]; + attribute :>> MM = 0.1; + attribute :>> MinNOT = -150 ['°C_abs']; + attribute :>> MinOT = -150 ['°C_abs']; + attribute :>> MaxOT = 150 ['°C_abs']; + attribute :>> MaxNOT = 150 ['°C_abs']; + } + #cDFProduct part 'A Battery' { + attribute :>> mass = 4.900 [kg]; + attribute :>> MM = 0.1; + attribute :>> MinNOT = -10 ['°C_abs']; + attribute :>> MinOT = 10 ['°C_abs']; + attribute :>> MaxOT = 30 ['°C_abs']; + attribute :>> MaxNOT = 45 ['°C_abs']; + } + #cDFProduct part 'A PCDU' { + attribute :>> mass = 18.500 [kg]; + attribute :>> MM = 0.1; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 30 [W]; + attribute :>> DC_LAU = 0; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 60 ['°C_abs']; + } + } + #cDFProduct part 'Chemical propulsion'{ + #cDFProduct part 'A Latch Valves' [2] { + attribute :>> mass = 0.550 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 30 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; // was 2 in the report (incorrect) + attribute :>> redundancyConceptN = 2; // was 4 in the report (incorrect) + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 0.475; + attribute :>> DC_SAFE = 0.1; + attribute :>> DC_STBY = 0.01; + attribute :>> DC_COM = 0.01; + attribute :>> DC_EPTH = 0.0002; + attribute :>> DC_SCI = 0; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Passivation_Valve' { + attribute :>> mass = 0.070 [kg]; + attribute :>> MM = 0.05; + } + #cDFProduct part 'A Pipes' { + attribute :>> mass = 3.000 [kg]; + attribute :>> MM = 0.2; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Pressure Transducer' [3] { + attribute :>> mass = 0.220 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0.216 [W]; + attribute :>> P_on = 0.216 [W]; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Propellant Filter' { + attribute :>> mass = 0.110 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Fill Drain Valve' [2] { + attribute :>> mass = 0.070 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Test_Ports' [2] { + attribute :>> mass = 0.070 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Tank CPROP' [2] { + attribute :>> mass = 5.900 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -48 ['°C_abs']; + attribute :>> MinOT = -48 ['°C_abs']; + attribute :>> MaxOT = 200 ['°C_abs']; + attribute :>> MaxNOT = 200 ['°C_abs']; + } + #cDFProduct part 'A Thruster_MONARC 5N' [8] { + attribute :>> mass = 0.490 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 4.1 [W]; + attribute :>> P_on = 18 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 4; + attribute :>> redundancyConceptN = 8; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 0.475; + attribute :>> DC_SAFE = 0.1; + attribute :>> DC_STBY = 0.01; + attribute :>> DC_COM = 0.01; + attribute :>> DC_EPTH = 0.0002; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -48 ['°C_abs']; + attribute :>> MinOT = -48 ['°C_abs']; + attribute :>> MaxOT = 200 ['°C_abs']; + attribute :>> MaxNOT = 200 ['°C_abs']; + } + } + #cDFProduct part 'Electrical propulsion' { + #cDFProduct part 'A Power Processing Unit' { + attribute :>> mass = 10.660 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 1252 [W]; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = -1; + attribute :>> DC_EPTH = 0.64; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -45 ['°C_abs']; + attribute :>> MinOT = -25 ['°C_abs']; + attribute :>> MaxOT = 70 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'A Thruster PPS1350' { + attribute :>> mass = 4.350 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -48 ['°C_abs']; + attribute :>> MinOT = -48 ['°C_abs']; + attribute :>> MaxOT = 200 ['°C_abs']; + attribute :>> MaxNOT = 200 ['°C_abs']; + } + #cDFProduct part 'A BPRU' { + attribute :>> mass = 2.750 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -30 ['°C_abs']; + attribute :>> MinOT = 20 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A FU' { + attribute :>> mass = 0.675 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -45 ['°C_abs']; + attribute :>> MinOT = -40 ['°C_abs']; + attribute :>> MaxOT = 70 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'A Miscellaneous' { + attribute :>> mass = 3.500 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -30 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A PRE Card' { + attribute :>> mass = 1.270 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 70 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'A XFC' { + attribute :>> mass = 0.820 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -15 ['°C_abs']; + attribute :>> MinOT = -15 ['°C_abs']; + attribute :>> MaxOT = 95 ['°C_abs']; + attribute :>> MaxNOT = 95 ['°C_abs']; + } + #cDFProduct part 'A Propellant Tank' [2] { + attribute :>> mass = 6.350 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -20 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + } + #cDFProduct part 'Thermal control' { + #cDFProduct part 'A TC Thermal Filler' { + attribute :>> mass = 0.250 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Heater' { + attribute :>> mass = 0.500 [kg]; + attribute :>> MM = 0.2; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 115 [W]; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = 0.835; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 0.748; + attribute :>> DC_EPTH = 0.774; + attribute :>> DC_SCI = 0.5305; + } + #cDFProduct part 'A TC Multi Layer Insulation' { + attribute :>> mass = 5.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Paint' { + attribute :>> mass = 2.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Radiator Panel' { + attribute :>> mass = 1.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Stand Offs' { + attribute :>> mass = 0.050 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Thermal Strap' { + attribute :>> mass = 0.500 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Temperature Sensor' { + attribute :>> mass = 0.500 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Heat Pipes' { + attribute :>> mass = 1.000 [kg]; + attribute :>> MM = 0.2; + } + } + #cDFProduct part Structures { + #cDFProduct part 'A Miscellaneous STR' { + attribute :>> mass = 5.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A RCS Suport' { + attribute :>> mass = 0.770 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A Secondary Structure' { + attribute :>> mass = 10.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A Inserts' { + attribute :>> mass = 4.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A ShearWebs' { + attribute :>> mass = 3.810 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A Solar Array Yoke #1' [2] { + attribute :>> mass = 1.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'Baseplate' { + attribute :>> mass = 28.880 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A Closure Panels #1' { + attribute :>> mass = 19.606 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A ShieldingPanels #1' { + attribute :>> mass = 59.610 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'Payload Support Panel' { + attribute :>> mass = 3.000 [kg]; + attribute :>> MM = 0.2; + } + } + #cDFProduct part Mechanisms { + #cDFProduct part 'A Antenna Pointing Mechanisms Subsystem with Driver and HDRM' { + attribute :>> mass = 13.100 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 18 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::internal; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 0; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -45 ['°C_abs']; + attribute :>> MinOT = -45 ['°C_abs']; + attribute :>> MaxOT = 145 ['°C_abs']; + attribute :>> MaxNOT = 145 ['°C_abs']; + } + #cDFProduct part 'A SA HDRM' [8] { + attribute :>> mass = 0.500 [kg]; + attribute :>> MM = 0.1; + attribute :>> MinNOT = -120 ['°C_abs']; + attribute :>> MinOT = -120 ['°C_abs']; + attribute :>> MaxOT = 120 ['°C_abs']; + attribute :>> MaxNOT = 120 ['°C_abs']; + } + #cDFProduct part 'A SADM' [2] { + attribute :>> mass = 4.000 [kg]; + attribute :>> MM = 0.1; + attribute :>> P_stby = 1 [W]; + attribute :>> P_on = 15 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::internal; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 0.07; + attribute :>> DC_SAFE = 0.1; + attribute :>> DC_STBY = 0; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 0.1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -120 ['°C_abs']; + attribute :>> MinOT = -120 ['°C_abs']; + attribute :>> MaxOT = 120 ['°C_abs']; + attribute :>> MaxNOT = 120 ['°C_abs']; + } + #cDFProduct part 'A SA drive electronics' { + attribute :>> mass = 3.000 [kg]; + attribute :>> MM = 0.1; + attribute :>> P_stby = 1 [W]; + attribute :>> P_on = 5 [W]; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 0.5; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 0; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -50 ['°C_abs']; + attribute :>> MinOT = -50 ['°C_abs']; + attribute :>> MaxOT = 40 ['°C_abs']; + attribute :>> MaxNOT = 40 ['°C_abs']; + } + #cDFProduct part 'A Clamp Band Ejection System' { + attribute :>> mass = 3.000 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -40 ['°C_abs']; + attribute :>> MaxOT = 145 ['°C_abs']; + attribute :>> MaxNOT = 145 ['°C_abs']; + } + } + #cDFProduct part Harness { + attribute :>> totalMass = 26.00 [kg]; + } + #cDFProduct part Propellant { + #cDFProduct part 'CPROP Fuel' { + attribute :>> mass = 47.47 [kg]; + attribute margin redefines MM = 0.02; + } + #cDFProduct part 'CPROP Pressurant' { + attribute :>> mass = 0.80 [kg]; + attribute margin redefines MM = 0.02; + } + #cDFProduct part 'EPROP Fuel' { + attribute :>> mass = 90.06 [kg]; + attribute margin redefines MM = 0.02; + } + } + #cDFProduct part 'A_tank_shields' [4] { + attribute :>> mass = 0.800 [kg]; + attribute :>> MM = 0.2; + } + } + + attribute wetMass redefines totalMass = 796.42 [kg]; // /!\ wetMass=dryMass*(1+systemMargin)+massPropellant // value is presented here but hould be calculated + attribute systemMargin = 0.2; // both for mass and power (except for EPTH mode, see report) + attribute dryMass : MassValue; + + exhibit 'System modes'; + } + } + + + + library package CDFReferenceDataLibrary { + doc /* This library specialices a part/product by adding CDF-specific parameters. + * The explanation of the parameters can be found in + * https://comet.io.esa.int/content/2-domain-expert/05-add-equipment-from-cat.html#parameters-and-the-reference-data-library-rdl + * and https://comet.io.esa.int/content/2-domain-expert/06-provide-param-values.html + */ + + private import Metaobjects::SemanticMetadata; + private import ScalarValues::*; + private import SI::*; + + part def CDFProduct { + // cost, programmatics and risk + attribute heritage : String; + attribute heritageDetails : String; + attribute longLeadItem : String; + attribute manufacturer : String; + attribute maturityMargin : Real; + attribute modelType : String; + attribute redundancyConceptScheme : RedundancyConceptSchemes default RedundancyConceptSchemes::none; + attribute redundancyConceptType : RedundancyConceptTypes; + attribute redundancyConceptK : Integer; + attribute redundancyConceptN : Integer; + attribute supplier : String; + attribute TRL : Integer; + // geometry + attribute diameter : LengthValue; + attribute height : LengthValue; + attribute length : LengthValue; + attribute location : VectorValues::CartesianThreeVectorValue; + attribute shapeCDF : ShapeTypes; // items in SysML v2 already have a 'shape' attribute, so this attribute has been called 'shapeCDF' + attribute width : LengthValue; + // mass + attribute mass : MassValue; // before maturityMargin + attribute totalMass : MassValue; // derived + // power + attribute powerWhileON : PowerValue; // includes maturityMargin + attribute powerInStandby : PowerValue; // stand-by mode of the equipment // includes maturityMargin + attribute powerDutyCyleLAU : Real; + attribute powerDutyCyleSUN : Real; + attribute powerDutyCyleSAFE : Real; + attribute powerDutyCycleSTBY : Real; // stand-by mode of the spacecraft + attribute powerDutyCycleCOM : Real; + attribute powerDutyCycleEPTH : Real; + attribute powerDutyCycleSCI : Real; + attribute powerInLAU : PowerValue; // derived + attribute powerInSUN : PowerValue; // derived + attribute powerInSAFE : PowerValue; // derived + attribute powerInSTBY: PowerValue; // derived // stand-by mode of the spacecraft + attribute powerInCOM: PowerValue; // derived + attribute powerInEPTH : PowerValue; // derived + attribute powerInSCI : PowerValue; // derived + // thermal + attribute maximumNonOperationalTemperature : TemperatureValue; + attribute maximumOperationalTemperature : TemperatureValue; + attribute minimumOperationalTemperature : TemperatureValue; + attribute minimumNonOperationalTemperature : TemperatureValue; + } + + enum def RedundancyConceptSchemes { + active; + passive; + none; + } + + enum def RedundancyConceptTypes { + internal; + external; + } + + enum def ShapeTypes { + box; + cylinder; + cone; + sphere; + paraboloid; + triPrism; + quadPrism; + cappedCylinder; + polyPrism; + tetrahedron; + wedge; + capsule; + triangle; + cylinderSegment; + sphericalSegment; + planarQuadrilateral; + discSegment; + paraboloidSegment; + } + + + part cDFProducts : CDFProduct; + + metadata def CDFProductMetadata :> SemanticMetadata { + :>> baseType = cDFProducts meta SysML::PartUsage; + :> annotatedElement : SysML::PartUsage; + } + } + + + //* Improvement ideas + - Mission scenarios (page 150) - useful? + - Mission context - useful? + - System of Interest capabilities (use cases for the spacecraft) - would have to be inferred from the info available - useful? + - System of Interest context - useful? + - Function tree and allocation - not contained in report, partially generated with AI + - All other parameters (TRL, dimensions, etc.) - useful? + - Options and trade-offs + - Constraints (requirements and parameters in parts) - one done (wet mass) + - More requirements - useful? + */ + + //* SysML v2 doubts + - Difference between satisfy link and subject attribute of reqs + - Package or requirement to group requirements + */ +} \ No newline at end of file diff --git a/tests/Test6.sysml b/tests/Test6.sysml new file mode 100644 index 0000000..7f02f75 --- /dev/null +++ b/tests/Test6.sysml @@ -0,0 +1,29 @@ +package MechanicalObjectExample { + abstract item def MechanicalObject { + attribute mass :> ISQ::mass; + } + + abstract item mechanicalObjects[*] : MechanicalObject; + + metadata def MechanicalObjectMetadata :> Metaobjects::SemanticMetadata { + :>> baseType = mechanicalObjects meta SysML::Usage; + } + + part def DroneSystem { + part def Drone { + #mec part battery { + attribute :>> mass = 2.5 [SI::kg]; + item shape[1] : ShapeItems::Box :>> shape { + attribute :>> length = 10 [SI::cm]; + attribute :>> width = 4 [SI::cm]; + attribute :>> height = 3 [SI::cm]; + } + } + #mec part propulsionUnit { + attribute :>> mass = 0.5 [SI::kg]; + item shape[1] : ShapeItems::Cylinder :>> shape; + } + } + } + +} \ No newline at end of file diff --git a/tests/Test7.sysml b/tests/Test7.sysml new file mode 100644 index 0000000..c1b8d38 --- /dev/null +++ b/tests/Test7.sysml @@ -0,0 +1,1416 @@ +package CometInceptorModified { + + /* Modification: Added short name to metadata definition cDFProduct and added root package CometInceptorModified */ + + /* + This model is based on the European Space Agency (ESA) Concurrent Design Facility (CDF) public report of the Comet Interceptor study (https://esamultimedia.esa.int/docs/cdf/CometInterceptor_CDF_Study_Report.pdf) + All contents come directly or are inferred from the information contained in this report, and do not take into account subsequent iterations of the mission design. + More information about the mission and the study and the list of acronyms can be found in the report. + */ + + private import ScalarValues::*; + private import RequirementDerivation::*; + private import SI::*; + private import CDFReferenceDataLibrary::*; + + + package 'Mission objectives' { + use case 'Assess the bulk shape of the nucleus and the morphology of its surface at a scale comparable to the best images returned by previous comet flyby missions, and those returned by New Horizons of Kuiper Belt Objects' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Determine the bulk composition of the nucleus’ surface' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Investigate activity in a fresh comet' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Assess the molecular composition of the coma simultaneously at multiple locations and the isotopic composition along one path' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + + use case 'Identify parent and daughter neutral and ion species and assess their relationship in the coma' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Characterise the dust in the coma' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Assess the structure of boundaries and regions in the plasma environment of a comet' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Assess the energy, mass and momentum transfer in the cometary environment, through the coma and across boundaries' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + use case 'Assess how plasma and dust interact in various regions of the coma' { + subject ::> 'Comet Interceptor mission context'.'Comet Interceptor space system'; + actor ::> 'Comet Interceptor mission context'.LPC; + actor ::> 'Comet Interceptor mission context'.'Science community'; + } + } + + + package 'Mission requirements' { + requirement <'MIS-010'> { + doc /* The mission shall intercept a Long Period Comet (LPC) or an interstellar body in a fly-by scenario. */ + comment /* See science requirements for more details */ + } + requirement <'MIS-020'> { + doc /* The mission shall include one main S/C (ESA) (hereafter S/C A) and two probes (one JAXA and one ESA) (namely probes B1 and B2, respectively) + * in order to gather multi-point observations of the comet and its coma. */ + comment /* See science requirements for more details */ + } + requirement <'MIS-030'> { + doc /* The mission shall embark the instruments as specified in the relevant Instrument Interface Description Documents. */ + comment /* See science requirements for more details */ + } + requirement <'MIS-040'> { + doc /* The mission shall allow parking the spacecraft in a Halo orbit around the SEL2 point after launch, wait for a target of opportunity, and then intercept it. */ + comment /* Ability to find a suitable target comet */ + } + requirement <'MIS-050'> { + doc /* The mission shall allow a fly-by to backup target comets 73P/Schwassmann-Wachmann (TBC) and 26P/Grigg-Skjellerup (TBC) within the nominal mission lifetime. */ + comment /* Ability to find a suitable backup comet in case no other suitable target is found */ + } + requirement <'MIS-060'> { + doc /* The mission shall be compatible with a launch together with the ARIEL mission/spacecraft. */ + comment /* Mission constraint for a shared launch with ARIEL */ + } + requirement <'MIS-070'> { + doc /* The nominal mission lifetime shall be maximum 5 years (TBC). */ + comment /* F-class mission constraint */ + } + requirement <'MIS-080'> { + doc /* The mission shall be compatible with ESA's F-mission budget Cost to Completion (CaC) not exceeding 150 M€. */ + comment /* F-class mission constraint */ + } + } + + + package 'Mission requirement satisfaction' { + private import 'Mission requirements'::*; + + satisfy 'MIS-010' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-020' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-030' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-040' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-050' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-060' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-070' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + satisfy 'MIS-080' by 'Comet Interceptor mission context'.'Comet Interceptor space system'; + } + + + package 'System requirements' { + requirement <'SYS-010'> { + doc /* The Comet Interceptor S/C shall contain one main S/C (S/C A - ESA) and two probes (B2 - ESA and B1 - JAXA). */ + } + requirement <'SYS-020'> { + doc /* The Comet Interceptor S/C shall be launched by the Ariane 62 launcher from Kourou (Guiana Space Centre). */ + } + requirement <'SYS-030'> { + doc /* The Comet Interceptor S/C shall be launched in 2028. */ + } + requirement <'SYS-040'> { + doc /* The Comet Interceptor S/C nominal lifetime shall be maximum 5 years (TBC). */ + } + requirement <'SYS-050'> { + doc /* The Comet Interceptor S/C shall embark the instruments as specified in the relevant Instrument Interface Description Documents. */ + } + requirement <'SYS-060'> { + doc /* The Comet Interceptor S/C A post flyby phase duration shall be maximum 6 months. */ + } + requirement <'SYS-070'> { + doc /* All Comet Interceptor S/C equipment shall be TRL 6 by Mission Selection (Q1 2020) and TRL 7 by Mission Adoption (Q4 2022). */ + } + requirement <'SYS-080'> { + doc /* The Comet Interceptor S/C A shall provide the mechanical, thermal and electrical interfaces for both probes B1 and B2. */ + } + requirement <'SYS-090'> { + doc /* The S/C A, B1 and B2 configurations shall ensure unobstructed fields of view for the instruments for observation purposes and for the communication antennas. */ + } + requirement <'SYS-100'> { + doc /* The S/C A shall carry the probes (B1 and B2) from integration up to their separation before the flyby. */ + } + requirement <'SYS-101'> { + doc /* The mission shall allow a release of the probe B2 at least 24 hours (TBC) before the closest approach. */ + } + requirement <'SYS-102'> { + doc /* The mission shall allow a flyby altitude for the probe B2 of between 100 m to 400 m (TBC). */ + } + requirement <'SYS-103'> { + doc /* The mission shall allow a release of the probe B1 at least 48 hours (TBC) before the closest approach. */ + } + requirement <'SYS-104'> { + doc /* The mission shall allow a flyby altitude for the probe B1 of between 100 m to 400 m (TBC). */ + } + requirement <'SYS-110'> { + doc /* The instruments on B1 and B2 shall be used only after separation of the spacecraft from S/C A. */ + } + requirement <'SYS-120'> { + doc /* Check-out operation activities of the scientific instruments and the rest of equipment on-board the probes B1 and B2 shall be possible before their separation from S/C A. */ + } + requirement <'SYS-130'> { + doc /* The probe B2 shall be designed considering a design-to-cost approach. */ + } + requirement <'SYS-140'> { + doc /* The probe B2 shall be designed for a 24h (TBC) lifetime. */ + } + requirement <'SYS-150'> { + doc /* The probe B2 shall be spin-stabilised. */ + } + requirement <'SYS-160'> { // Requirement inferred from the system assumptions. Not a requirement in the report + doc /* The Comet Interceptor main S/C shall not exceed a wet mass of 650 kg (excluding adapter). */ + comment /* To be compatible with the use of a dual launch with ARIEL and the Dual Launch Structure (DLS) */ + + assume constraint { 'Comet Interceptor space segment (physical)'.'Main spacecraft'.wetMass <= 650 [kg] } + } + } + + + package 'System requirement satisfaction' { + private import 'System requirements'::*; + + satisfy 'SYS-010' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-020' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-030' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-040' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-050' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-060' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-070' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-080' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-090' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-100' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-101' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-102' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-103' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-104' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-110' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-120' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-130' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-140' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-150' by 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment'; + satisfy 'SYS-160' by 'Comet Interceptor space segment (physical)'.'Main spacecraft'.wetMass; + } + + + package 'Mission to System requirement derivation' { + private import 'Mission requirements'::*; + private import 'System requirements'::*; + + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-010'; + } + #derivation connection { + end #original ::> 'MIS-060'; + end #derive ::> 'SYS-020'; + } + #derivation connection { + end #original ::> 'MIS-080'; + end #derive ::> 'SYS-030'; + } + #derivation connection { + end #original ::> 'MIS-070'; + end #derive ::> 'SYS-040'; + } + #derivation connection { + end #original ::> 'MIS-030'; + end #derive ::> 'SYS-050'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-060'; + } + #derivation connection { + end #original ::> 'MIS-070'; + end #derive ::> 'SYS-060'; + } + #derivation connection { + end #original ::> 'MIS-060'; + end #derive ::> 'SYS-070'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-080'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-090'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-100'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-101'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-102'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-103'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-104'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-110'; + } + #derivation connection { + end #original ::> 'MIS-030'; + end #derive ::> 'SYS-110'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-120'; + } + #derivation connection { + end #original ::> 'MIS-030'; + end #derive ::> 'SYS-120'; + } + #derivation connection { + end #original ::> 'MIS-080'; + end #derive ::> 'SYS-130'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-140'; + } + #derivation connection { + end #original ::> 'MIS-030'; + end #derive ::> 'SYS-140'; + } + #derivation connection { + end #original ::> 'MIS-080'; + end #derive ::> 'SYS-140'; + } + #derivation connection { + end #original ::> 'MIS-020'; + end #derive ::> 'SYS-150'; + } + #derivation connection { + end #original ::> 'MIS-030'; + end #derive ::> 'SYS-150'; + } + #derivation connection { + end #original ::> 'MIS-060'; + end #derive ::> 'SYS-160'; + } + } + + + // Mission Architecture + part 'Comet Interceptor mission context' { + part 'Comet Interceptor space system' { + part 'Ariane 62 launcher'{ + comment /* Dual launch with ARIEL */ + } + part 'Comet Interceptor ground segment' { + part 'Mission Operations Centre'; + part <'JAXA MOC'> 'JAXA Mission Operations Centre'; + part 'ESTRACK ground station network'; + } + part 'Comet Interceptor space segment'; // System of Interest + + exhibit 'Mission phases'; + } + part 'Long Period Comet'; + part 'Science community'; + part Earth; + part Sun; + part 'Space environment'; + } + + + state 'Mission phases' { + entry; + then state 'Ariane 62 launch from Kourou'; + then state 'L2 transfer'; + then state 'Waiting at L2'; + then state 'Target transfer'; + then state 'Comet fly-by'; + then done; + } + + + state 'System modes'{ + state 'Launch mode' { + doc /* From launch to spacecraft separation. + * Most equipment OFF (OBC and receiver potentially ON) + */ + } + state 'Sun Acquisition Mode' { + doc /* From spacecraft separation up to Sun pointing attitude + * Minimum units are ON (Sun sensors, TT&C up- and down-link via LGA) + * Instruments are OFF + */ + } + state 'Safe Mode' { + doc /* Minimum units ON to ensure prolonged safe state and communications to facilitate coming back to a nominal mode + * Instruments are OFF + */ + } + state 'Standby Mode' { + doc /* Applicable when not thrusting, communicating with Earth, nor acquiring science data + * Instruments are OFF + * Most platform units are ON + */ + } + state 'Communication Mode' { + doc /* Applicable for communication with Earth + * Most platform units are ON and transmitter is ON + */ + } + state 'EP Thrusting Mode' { + doc /* Applicable for reaching the target object + * Instruments are OFF + * Most platform units are ON and EP thruster is ON + */ + } + state 'Science Mode' { + doc /* Applicable for science acquisition during the fly-by at encounter + * Instruments are ON + * Most platform units are ON + */ + } + + entry; + then LAU; + transition first LAU then SUN; + transition first SUN then STBY; + transition first STBY then SAFE; + transition first SAFE then STBY; + transition first STBY then SCI; + transition first SCI then STBY; + transition first STBY then COM; + transition first COM then STBY; + transition first STBY then EPTH; + transition first EPTH then STBY; + transition first SCI then SAFE; + transition first COM then SAFE; + transition first EPTH then SAFE; + } + + + state 'Equipment power modes' { + entry; + then state OFF; + then state 'Stand-by'; + then state ON; + transition first OFF then ON; + transition first STBY then OFF; + transition first ON then OFF; + transition first ON then STBY; + } + + + //* The function tree below has been generated with AI. It is presented here as it may be useful for some use cases, but will contain inaccuracies + + action 'Comet Interceptor space segment (functional)' { + action 'Mission System' { + action 'Mission Planning & Operations'; + action 'Science Data Acquisition'; + action 'Science Data Transmission'; + action 'Multi-Spacecraft Coordination'; + } + action 'Spacecraft Bus' { + action 'Power Subsystem' { + action 'Solar Power Generation'; + action 'Power Storage'; + action 'Power Distribution and Regulation'; + } + action 'Thermal Control' { + action 'Passive Thermal Control'; + action 'Active Thermal Control'; + } + action 'Attitude and Orbit Control System' { + action 'Attitude Determination'; + action 'Attitude Control'; + action 'Orbit Maneuvering'; + } + action 'Communication Subsystem' { + action <'TT&C'> 'Telemetry, Tracking & Command'; + action 'Science Data Downlink'; + action 'Inter-spacecraft Communication'; + } + action 'Onboard Data Handling' { + action 'Data Storage'; + action 'Data Processing'; + action 'Fault Detection, Isolation and Recovery'; + } + } + action 'Payload Module' { + action 'Scientific Instruments' { + action 'Visible and UV Imaging Systems'; + action 'Mass Spectrometers'; + action 'Dust Analyzers'; + action 'Plasma Instruments'; + } + action 'Payload Support Systems' { + action 'Instrument Mounting and Pointing'; + action 'Instrument Power and Data Interfaces'; + action 'Thermal Control for Instruments'; + } + } + action 'Multi-Spacecraft Configuration' { + action 'Spacecraft A' { + action 'Carrier for B1 and B2'; + action 'Primary Communication with Earth'; + } + action 'Spacecraft B1' { + action 'Close Flyby Observations'; + action 'Independent Navigation'; + } + action 'Spacecraft B2' { + action 'Complementary Observations'; + action 'Independent Navigation'; + } + } + } + + allocate 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment' to 'Comet Interceptor space segment (functional)'; + */ + + allocate 'Comet Interceptor mission context'.'Comet Interceptor space system'.'Comet Interceptor space segment' to 'Comet Interceptor space segment (physical)'; + + + // Product tree + #cDFProduct part 'Comet Interceptor space segment (physical)' { + #cDFProduct part 'Probe B1' { + attribute :>> totalMass = 30.00 [kg]; + + exhibit 'System modes'; + } + #cDFProduct part 'Probe B2' { + attribute :>> totalMass = 40.47 [kg]; + attribute :>> powerInLAU = 0.00 [W]; + attribute :>> powerInSUN = 0.00 [W]; + attribute :>> powerInSAFE = 0.00 [W]; + attribute :>> powerInSTBY = 0.00 [W]; + attribute :>> powerInCOM = 0.00 [W]; + attribute :>> powerInEPTH = 0.00 [W]; + attribute :>> powerInSCI = 35.59 [W]; + + exhibit 'System modes'.SCI; + } + #cDFProduct part <'S/C A'> 'Main spacecraft' { + #cDFProduct part Payload { + #cDFProduct part 'Comet Camera' { + attribute :>> totalMass = 12.81 [kg]; + attribute :>> powerInLAU = 0.00 [W]; + attribute :>> powerInSUN = 0.00 [W]; + attribute :>> powerInSAFE = 0.00 [W]; + attribute :>> powerInSTBY = 0.00 [W]; + attribute :>> powerInCOM = 0.00 [W]; + attribute :>> powerInEPTH = 0.00 [W]; + attribute :>> powerInSCI = 14.40 [W]; + attribute :>> MinNOT = -20 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 25 ['°C_abs']; + attribute :>> MaxNOT = 35 ['°C_abs']; + } + #cDFProduct part 'Dust Field and Plasma package' { + attribute :>> totalMass = 10.788 [kg]; + attribute :>> powerInLAU = 0.00 [W]; + attribute :>> powerInSUN = 0.00 [W]; + attribute :>> powerInSAFE = 0.00 [W]; + attribute :>> powerInSTBY = 0.00 [W]; + attribute :>> powerInCOM = 0.00 [W]; + attribute :>> powerInEPTH = 0.00 [W]; + attribute :>> powerInSCI = 20.16 [W]; + attribute :>> MinNOT = -25 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 40 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'Mass Analyzer for Neutrals in a Coma' { + attribute :>> totalMass = 6.54 [kg]; + attribute :>> powerInLAU = 0.00 [W]; + attribute :>> powerInSUN = 0.00 [W]; + attribute :>> powerInSAFE = 0.00 [W]; + attribute :>> powerInSTBY = 0.00 [W]; + attribute :>> powerInCOM = 0.00 [W]; + attribute :>> powerInEPTH = 0.00 [W]; + attribute :>> powerInSCI = 27.60 [W]; + attribute :>> MinNOT = -30 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 40 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'Modular Infrared Molecules and Ice Sensor' { + attribute :>> totalMass = 6.93 [kg]; + attribute :>> powerInLAU = 0.00 [W]; + attribute :>> powerInSUN = 0.00 [W]; + attribute :>> powerInSAFE = 0.00 [W]; + attribute :>> powerInSTBY = 0.00 [W]; + attribute :>> powerInCOM = 0.00 [W]; + attribute :>> powerInEPTH = 0.00 [W]; + attribute :>> powerInSCI = 9.00 [W]; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + } + #cDFProduct part Platform { + #cDFProduct part 'Attitude, orbit, guidance, navigation control' { + #cDFProduct part 'A DTU Data Processing Unit' { + attribute :>> mass = 0.560 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 3.6 [W]; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -65 ['°C_abs']; + attribute :>> MinOT = -60 ['°C_abs']; + attribute :>> MaxOT = 35 ['°C_abs']; + attribute :>> MaxNOT = 40 ['°C_abs']; + } + #cDFProduct part 'AIMU Northrop Grumman LN200 Core' [2] { + attribute :>> mass = 0.750 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 12 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = -1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -59 ['°C_abs']; + attribute :>> MinOT = -54 ['°C_abs']; + attribute :>> MaxOT = 71 ['°C_abs']; + attribute :>> MaxNOT = 76 ['°C_abs']; + } + #cDFProduct part 'A DTU NAVCAM Optical Head' [2] { + attribute :>> mass = 0.376 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 0.7 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = -1; + attribute :>> DC_EPTH = -1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -65 ['°C_abs']; + attribute :>> MinOT = -60 ['°C_abs']; + attribute :>> MaxOT = 35 ['°C_abs']; + attribute :>> MaxNOT = 40 ['°C_abs']; + } + #cDFProduct part 'A DTU STR Optical Head' [2] { + attribute :>> mass = 0.350 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 0.7 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -60 ['°C_abs']; // was -40 in the report (incorrect) + attribute :>> MinOT = -60 ['°C_abs']; + attribute :>> MaxOT = 35 ['°C_abs']; + attribute :>> MaxNOT = 40 ['°C_abs']; + } + #cDFProduct part 'A SUN LENS Bison 64' [6] { + attribute :>> mass = 0.025 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -45 ['°C_abs']; + attribute :>> MinOT = -40 ['°C_abs']; + attribute :>> MaxOT = 80 ['°C_abs']; + attribute :>> MaxNOT = 85 ['°C_abs']; + } + #cDFProduct part 'A RW Rockwell Collins RSI 4-215' [4] { + attribute :>> mass = 5.400 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 20 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::active; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 3; + attribute :>> redundancyConceptN = 4; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = -1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 70 ['°C_abs']; + attribute :>> MaxNOT = 75 ['°C_abs']; + } + } + #cDFProduct part Communications { + #cDFProduct part 'X-Band DSTRASP' { // product artificially decomposed into receiver and transmitter, for a better calculation of power budget + #cDFProduct part 'Transponder Receiver' [2] { + attribute :>> mass = 3.600 [kg]; // full XDST mass is shown in RX element (artificial) + attribute :>> MM = 0.05; + attribute :>> P_stby = 16 [W]; + attribute :>> P_on = 16 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::active; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 65 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'Transponder Transmitter' [2] { + attribute :>> mass = 0 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 16 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = -1; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 65 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + } + #cDFProduct part 'X-Band HGA' { + attribute :>> mass = 6.050 [kg]; + attribute :>> MM = 0.1; + attribute :>> MinNOT = -155 ['°C_abs']; + attribute :>> MinOT = -150 ['°C_abs']; + attribute :>> MaxOT = 150 ['°C_abs']; + attribute :>> MaxNOT = 150 ['°C_abs']; + } + #cDFProduct part 'X-Band LGA' [2] { + attribute :>> mass = 0.300 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -155 ['°C_abs']; + attribute :>> MinOT = -150 ['°C_abs']; + attribute :>> MaxOT = 150 ['°C_abs']; + attribute :>> MaxNOT = 150 ['°C_abs']; + } + #cDFProduct part 'X-Band RFDN' { + attribute :>> mass = 10.000 [kg]; + attribute :>> MM = 0.2; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'X-Band TWT' [2] { + attribute :>> mass = 0.800 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 103.07 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 0.55; + attribute :>> DC_SAFE = 0.3; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 0; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'X-Band TWTA EPC' [2] { + attribute :>> mass = 1.400 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 9 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 0; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -30 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'A GOMx Electronics' [2] { + attribute :>> mass = 0.503 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 6.72 [W]; + attribute :>> P_on = 8.16 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = -1; + attribute :>> DC_EPTH = -1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 85 ['°C_abs']; + attribute :>> MaxNOT = 95 ['°C_abs']; + } + #cDFProduct part 'A GOMx Antenna Patch' [6] { + attribute :>> mass = 0.150 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 1 [W]; + attribute :>> P_on = 7.2 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 3; // was 1 in the report (incorrect) + attribute :>> redundancyConceptN = 6; // was 2 in the report (incorrect) + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = -1; + attribute :>> DC_EPTH = -1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 85 ['°C_abs']; + attribute :>> MaxNOT = 95 ['°C_abs']; + } + } + #cDFProduct part 'Data handling' { + #cDFProduct part 'A Onboard Computer' { + attribute :>> mass = 6.500 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 23 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::internal; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 75 ['°C_abs']; + } + #cDFProduct part 'A Remote Interface Unit' { + attribute :>> mass = 12.000 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 30 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::internal; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 75 ['°C_abs']; + } + } + #cDFProduct part Power { + #cDFProduct part 'A SolarArray' [2] { + attribute :>> mass = 14.630 [kg]; + attribute :>> MM = 0.1; + attribute :>> MinNOT = -150 ['°C_abs']; + attribute :>> MinOT = -150 ['°C_abs']; + attribute :>> MaxOT = 150 ['°C_abs']; + attribute :>> MaxNOT = 150 ['°C_abs']; + } + #cDFProduct part 'A Battery' { + attribute :>> mass = 4.900 [kg]; + attribute :>> MM = 0.1; + attribute :>> MinNOT = -10 ['°C_abs']; + attribute :>> MinOT = 10 ['°C_abs']; + attribute :>> MaxOT = 30 ['°C_abs']; + attribute :>> MaxNOT = 45 ['°C_abs']; + } + #cDFProduct part 'A PCDU' { + attribute :>> mass = 18.500 [kg]; + attribute :>> MM = 0.1; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 30 [W]; + attribute :>> DC_LAU = 0; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 60 ['°C_abs']; + attribute :>> MaxNOT = 60 ['°C_abs']; + } + } + #cDFProduct part 'Chemical propulsion'{ + #cDFProduct part 'A Latch Valves' [2] { + attribute :>> mass = 0.550 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 30 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 1; // was 2 in the report (incorrect) + attribute :>> redundancyConceptN = 2; // was 4 in the report (incorrect) + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 0.475; + attribute :>> DC_SAFE = 0.1; + attribute :>> DC_STBY = 0.01; + attribute :>> DC_COM = 0.01; + attribute :>> DC_EPTH = 0.0002; + attribute :>> DC_SCI = 0; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Passivation_Valve' { + attribute :>> mass = 0.070 [kg]; + attribute :>> MM = 0.05; + } + #cDFProduct part 'A Pipes' { + attribute :>> mass = 3.000 [kg]; + attribute :>> MM = 0.2; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Pressure Transducer' [3] { + attribute :>> mass = 0.220 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0.216 [W]; + attribute :>> P_on = 0.216 [W]; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 1; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Propellant Filter' { + attribute :>> mass = 0.110 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Fill Drain Valve' [2] { + attribute :>> mass = 0.070 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Test_Ports' [2] { + attribute :>> mass = 0.070 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = 0 ['°C_abs']; + attribute :>> MinOT = 0 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A Tank CPROP' [2] { + attribute :>> mass = 5.900 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -48 ['°C_abs']; + attribute :>> MinOT = -48 ['°C_abs']; + attribute :>> MaxOT = 200 ['°C_abs']; + attribute :>> MaxNOT = 200 ['°C_abs']; + } + #cDFProduct part 'A Thruster_MONARC 5N' [8] { + attribute :>> mass = 0.490 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 4.1 [W]; + attribute :>> P_on = 18 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::external; + attribute :>> redundancyConceptK = 4; + attribute :>> redundancyConceptN = 8; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 0.475; + attribute :>> DC_SAFE = 0.1; + attribute :>> DC_STBY = 0.01; + attribute :>> DC_COM = 0.01; + attribute :>> DC_EPTH = 0.0002; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -48 ['°C_abs']; + attribute :>> MinOT = -48 ['°C_abs']; + attribute :>> MaxOT = 200 ['°C_abs']; + attribute :>> MaxNOT = 200 ['°C_abs']; + } + } + #cDFProduct part 'Electrical propulsion' { + #cDFProduct part 'A Power Processing Unit' { + attribute :>> mass = 10.660 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 1252 [W]; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = -1; + attribute :>> DC_EPTH = 0.64; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -45 ['°C_abs']; + attribute :>> MinOT = -25 ['°C_abs']; + attribute :>> MaxOT = 70 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'A Thruster PPS1350' { + attribute :>> mass = 4.350 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -48 ['°C_abs']; + attribute :>> MinOT = -48 ['°C_abs']; + attribute :>> MaxOT = 200 ['°C_abs']; + attribute :>> MaxNOT = 200 ['°C_abs']; + } + #cDFProduct part 'A BPRU' { + attribute :>> mass = 2.750 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -30 ['°C_abs']; + attribute :>> MinOT = 20 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A FU' { + attribute :>> mass = 0.675 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -45 ['°C_abs']; + attribute :>> MinOT = -40 ['°C_abs']; + attribute :>> MaxOT = 70 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'A Miscellaneous' { + attribute :>> mass = 3.500 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -30 ['°C_abs']; + attribute :>> MinOT = -30 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + #cDFProduct part 'A PRE Card' { + attribute :>> mass = 1.270 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 70 ['°C_abs']; + attribute :>> MaxNOT = 70 ['°C_abs']; + } + #cDFProduct part 'A XFC' { + attribute :>> mass = 0.820 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -15 ['°C_abs']; + attribute :>> MinOT = -15 ['°C_abs']; + attribute :>> MaxOT = 95 ['°C_abs']; + attribute :>> MaxNOT = 95 ['°C_abs']; + } + #cDFProduct part 'A Propellant Tank' [2] { + attribute :>> mass = 6.350 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -20 ['°C_abs']; + attribute :>> MinOT = -20 ['°C_abs']; + attribute :>> MaxOT = 50 ['°C_abs']; + attribute :>> MaxNOT = 50 ['°C_abs']; + } + } + #cDFProduct part 'Thermal control' { + #cDFProduct part 'A TC Thermal Filler' { + attribute :>> mass = 0.250 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Heater' { + attribute :>> mass = 0.500 [kg]; + attribute :>> MM = 0.2; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 115 [W]; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = 0.835; + attribute :>> DC_STBY = 1; + attribute :>> DC_COM = 0.748; + attribute :>> DC_EPTH = 0.774; + attribute :>> DC_SCI = 0.5305; + } + #cDFProduct part 'A TC Multi Layer Insulation' { + attribute :>> mass = 5.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Paint' { + attribute :>> mass = 2.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Radiator Panel' { + attribute :>> mass = 1.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Stand Offs' { + attribute :>> mass = 0.050 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Thermal Strap' { + attribute :>> mass = 0.500 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Temperature Sensor' { + attribute :>> mass = 0.500 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A TC Heat Pipes' { + attribute :>> mass = 1.000 [kg]; + attribute :>> MM = 0.2; + } + } + #cDFProduct part Structures { + #cDFProduct part 'A Miscellaneous STR' { + attribute :>> mass = 5.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A RCS Suport' { + attribute :>> mass = 0.770 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A Secondary Structure' { + attribute :>> mass = 10.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A Inserts' { + attribute :>> mass = 4.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A ShearWebs' { + attribute :>> mass = 3.810 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A Solar Array Yoke #1' [2] { + attribute :>> mass = 1.000 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'Baseplate' { + attribute :>> mass = 28.880 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A Closure Panels #1' { + attribute :>> mass = 19.606 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'A ShieldingPanels #1' { + attribute :>> mass = 59.610 [kg]; + attribute :>> MM = 0.2; + } + #cDFProduct part 'Payload Support Panel' { + attribute :>> mass = 3.000 [kg]; + attribute :>> MM = 0.2; + } + } + #cDFProduct part Mechanisms { + #cDFProduct part 'A Antenna Pointing Mechanisms Subsystem with Driver and HDRM' { + attribute :>> mass = 13.100 [kg]; + attribute :>> MM = 0.05; + attribute :>> P_stby = 0 [W]; + attribute :>> P_on = 18 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::internal; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = -1; + attribute :>> DC_SAFE = -1; + attribute :>> DC_STBY = -1; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 0; + attribute :>> DC_SCI = -1; + attribute :>> MinNOT = -45 ['°C_abs']; + attribute :>> MinOT = -45 ['°C_abs']; + attribute :>> MaxOT = 145 ['°C_abs']; + attribute :>> MaxNOT = 145 ['°C_abs']; + } + #cDFProduct part 'A SA HDRM' [8] { + attribute :>> mass = 0.500 [kg]; + attribute :>> MM = 0.1; + attribute :>> MinNOT = -120 ['°C_abs']; + attribute :>> MinOT = -120 ['°C_abs']; + attribute :>> MaxOT = 120 ['°C_abs']; + attribute :>> MaxNOT = 120 ['°C_abs']; + } + #cDFProduct part 'A SADM' [2] { + attribute :>> mass = 4.000 [kg]; + attribute :>> MM = 0.1; + attribute :>> P_stby = 1 [W]; + attribute :>> P_on = 15 [W]; + attribute :>> redundancyConceptScheme = RedundancyConceptSchemes::passive; + attribute :>> redundancyConceptType = RedundancyConceptTypes::internal; + attribute :>> redundancyConceptK = 1; + attribute :>> redundancyConceptN = 2; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 0.07; + attribute :>> DC_SAFE = 0.1; + attribute :>> DC_STBY = 0; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 0.1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -120 ['°C_abs']; + attribute :>> MinOT = -120 ['°C_abs']; + attribute :>> MaxOT = 120 ['°C_abs']; + attribute :>> MaxNOT = 120 ['°C_abs']; + } + #cDFProduct part 'A SA drive electronics' { + attribute :>> mass = 3.000 [kg]; + attribute :>> MM = 0.1; + attribute :>> P_stby = 1 [W]; + attribute :>> P_on = 5 [W]; + attribute :>> DC_LAU = -1; + attribute :>> DC_SUN = 0.5; + attribute :>> DC_SAFE = 1; + attribute :>> DC_STBY = 0; + attribute :>> DC_COM = 1; + attribute :>> DC_EPTH = 1; + attribute :>> DC_SCI = 1; + attribute :>> MinNOT = -50 ['°C_abs']; + attribute :>> MinOT = -50 ['°C_abs']; + attribute :>> MaxOT = 40 ['°C_abs']; + attribute :>> MaxNOT = 40 ['°C_abs']; + } + #cDFProduct part 'A Clamp Band Ejection System' { + attribute :>> mass = 3.000 [kg]; + attribute :>> MM = 0.05; + attribute :>> MinNOT = -40 ['°C_abs']; + attribute :>> MinOT = -40 ['°C_abs']; + attribute :>> MaxOT = 145 ['°C_abs']; + attribute :>> MaxNOT = 145 ['°C_abs']; + } + } + #cDFProduct part Harness { + attribute :>> totalMass = 26.00 [kg]; + } + #cDFProduct part Propellant { + #cDFProduct part 'CPROP Fuel' { + attribute :>> mass = 47.47 [kg]; + attribute margin redefines MM = 0.02; + } + #cDFProduct part 'CPROP Pressurant' { + attribute :>> mass = 0.80 [kg]; + attribute margin redefines MM = 0.02; + } + #cDFProduct part 'EPROP Fuel' { + attribute :>> mass = 90.06 [kg]; + attribute margin redefines MM = 0.02; + } + } + #cDFProduct part 'A_tank_shields' [4] { + attribute :>> mass = 0.800 [kg]; + attribute :>> MM = 0.2; + } + } + + attribute wetMass redefines totalMass = 796.42 [kg]; // /!\ wetMass=dryMass*(1+systemMargin)+massPropellant // value is presented here but hould be calculated + attribute systemMargin = 0.2; // both for mass and power (except for EPTH mode, see report) + attribute dryMass : MassValue; + + exhibit 'System modes'; + } + } + + + + library package CDFReferenceDataLibrary { + doc /* This library specialices a part/product by adding CDF-specific parameters. + * The explanation of the parameters can be found in + * https://comet.io.esa.int/content/2-domain-expert/05-add-equipment-from-cat.html#parameters-and-the-reference-data-library-rdl + * and https://comet.io.esa.int/content/2-domain-expert/06-provide-param-values.html + */ + + private import Metaobjects::SemanticMetadata; + private import ScalarValues::*; + private import SI::*; + + part def CDFProduct { + // cost, programmatics and risk + attribute heritage : String; + attribute heritageDetails : String; + attribute longLeadItem : String; + attribute manufacturer : String; + attribute maturityMargin : Real; + attribute modelType : String; + attribute redundancyConceptScheme : RedundancyConceptSchemes default RedundancyConceptSchemes::none; + attribute redundancyConceptType : RedundancyConceptTypes; + attribute redundancyConceptK : Integer; + attribute redundancyConceptN : Integer; + attribute supplier : String; + attribute TRL : Integer; + // geometry + attribute diameter : LengthValue; + attribute height : LengthValue; + attribute length : LengthValue; + attribute location : VectorValues::CartesianThreeVectorValue; + attribute shapeCDF : ShapeTypes; // items in SysML v2 already have a 'shape' attribute, so this attribute has been called 'shapeCDF' + attribute width : LengthValue; + // mass + attribute mass : MassValue; // before maturityMargin + attribute totalMass : MassValue; // derived + // power + attribute powerWhileON : PowerValue; // includes maturityMargin + attribute powerInStandby : PowerValue; // stand-by mode of the equipment // includes maturityMargin + attribute powerDutyCyleLAU : Real; + attribute powerDutyCyleSUN : Real; + attribute powerDutyCyleSAFE : Real; + attribute powerDutyCycleSTBY : Real; // stand-by mode of the spacecraft + attribute powerDutyCycleCOM : Real; + attribute powerDutyCycleEPTH : Real; + attribute powerDutyCycleSCI : Real; + attribute powerInLAU : PowerValue; // derived + attribute powerInSUN : PowerValue; // derived + attribute powerInSAFE : PowerValue; // derived + attribute powerInSTBY: PowerValue; // derived // stand-by mode of the spacecraft + attribute powerInCOM: PowerValue; // derived + attribute powerInEPTH : PowerValue; // derived + attribute powerInSCI : PowerValue; // derived + // thermal + attribute maximumNonOperationalTemperature : TemperatureValue; + attribute maximumOperationalTemperature : TemperatureValue; + attribute minimumOperationalTemperature : TemperatureValue; + attribute minimumNonOperationalTemperature : TemperatureValue; + } + + enum def RedundancyConceptSchemes { + active; + passive; + none; + } + + enum def RedundancyConceptTypes { + internal; + external; + } + + enum def ShapeTypes { + box; + cylinder; + cone; + sphere; + paraboloid; + triPrism; + quadPrism; + cappedCylinder; + polyPrism; + tetrahedron; + wedge; + capsule; + triangle; + cylinderSegment; + sphericalSegment; + planarQuadrilateral; + discSegment; + paraboloidSegment; + } + + + part cDFProducts : CDFProduct; + + metadata def CDFProductMetadata :> SemanticMetadata { + :>> baseType = cDFProducts meta SysML::PartUsage; + :> annotatedElement : SysML::PartUsage; + } + } + + + //* Improvement ideas + - Mission scenarios (page 150) - useful? + - Mission context - useful? + - System of Interest capabilities (use cases for the spacecraft) - would have to be inferred from the info available - useful? + - System of Interest context - useful? + - Function tree and allocation - not contained in report, partially generated with AI + - All other parameters (TRL, dimensions, etc.) - useful? + - Options and trade-offs + - Constraints (requirements and parameters in parts) - one done (wet mass) + - More requirements - useful? + */ + + //* SysML v2 doubts + - Difference between satisfy link and subject attribute of reqs + - Package or requirement to group requirements + */ +} \ No newline at end of file diff --git a/tests/geo.sysml b/tests/geo.sysml new file mode 100644 index 0000000..07f01d9 --- /dev/null +++ b/tests/geo.sysml @@ -0,0 +1,85 @@ + + part m0001_2N { + + part nx0001 { + port scp_outside2; + } + + part tcs0001{ + port scp; + } + + interface tcs0001.scp to nx0001.scp_outside2; + } + +package MyStructureC { + + part def Component{ + attribute tx; + attribute ty; + attribute tz; + + attribute rx; + attribute ry; + attribute rz; + + attribute typeID; + part children: Component[0..*]; + } + +part def Solari { +} + +part def PowerUnit :> Solari { +} + + part def Context { + part myStructureC :Component { + part nx0001g subsets children { + attribute :>> tx=1.0; + attribute :>> ty=1.0; + attribute :>> tz=1.0; + attribute :>> rx=1.0; + attribute :>> ry=1.0; + attribute :>> rz=1.0; + attribute :>> typeID = 100; + part pwr0001g:PowerUnit subsets children { + attribute :>> tx=1.0; + attribute :>> ty=2.0; + attribute :>> tz=1.0; + attribute :>> rx=1.0; + attribute :>> ry=2.0; + attribute :>> rz=1.0; + attribute :>> typeID = 0; + } + part cmp0001g subsets children { + attribute :>> tx=1.0; + attribute :>> ty=3.0; + attribute :>> tz=1.0; + attribute :>> rx=1.0; + attribute :>> ry=3.0; + attribute :>> rz=1.0; + attribute :>> typeID = 1; + } + } + part nx0002g subsets children { + attribute :>> tx=1.0; + attribute :>> ty=1.0; + attribute :>> tz=1.0; + attribute :>> rx=1.0; + attribute :>> ry=1.0; + attribute :>> rz=1.0; + attribute :>> typeID = 100; + part pwr0002g subsets children { + attribute :>> tx=1.0; + attribute :>> ty=2.0; + attribute :>> tz=1.0; + attribute :>> rx=1.0; + attribute :>> ry=2.0; + attribute :>> rz=1.0; + attribute :>> typeID = 0; + } + } + } + } +} \ No newline at end of file diff --git a/tests/library.sysml b/tests/library.sysml new file mode 100644 index 0000000..f30f11a --- /dev/null +++ b/tests/library.sysml @@ -0,0 +1,11 @@ + package lpkg { + part def A { + port p; + } +} + +package pkg { + private import lpkg::*; + + part a:A; +} \ No newline at end of file diff --git a/tests/pu-simple.sysml b/tests/pu-simple.sysml new file mode 100644 index 0000000..d435d13 --- /dev/null +++ b/tests/pu-simple.sysml @@ -0,0 +1,62 @@ +library package A { + attribute def Orbit { + attribute semiMajorAxis = 7000; + + attribute eccentricity = 0.01; + + attribute inclination = 28.5 { + assert constraint { that >= 0.0 and that <= 90.0 } + } + + attribute RAAN = 0.0; // Right Ascension of Ascending Node + attribute argumentOfPeriapsis = 0.0; + attribute trueAnomaly = 0.0; + } +} + +library package SDK { + private import A::*; + + // structure + + port def P; + + part def S { + port scp : P; + attribute uid; + attribute typeID; + } + + part def N { + port scp_outside2 : P; + attribute uid; + } + + part def M { + attribute uid; + part n : N [0..*]; + part s : S [0..*]; + } + + part def T :> S { + attribute :>> typeID = 2; + } +} + +package M1 { + private import SDK::*; + + part m0001_2N : M { + attribute :>> uid = "M0001_2N"; + + part nx0001 : N subsets n { + attribute :>> uid = "NX0001"; + } + + part tcs0001 : T subsets s { + attribute :>> uid = "TCS0001"; + } + + interface tcs0001.scp to nx0001.scp_outside2; + } +} \ No newline at end of file diff --git a/tests/pu.sysml b/tests/pu.sysml new file mode 100644 index 0000000..7a80606 --- /dev/null +++ b/tests/pu.sysml @@ -0,0 +1,69 @@ +library package A { + private import ScalarValues::*; + private import ISQ::*; + private import SI::*; + + attribute def Orbit { + attribute semiMajorAxis :> ISQ::length = 7000 [SI::km]; + + attribute eccentricity : ScalarValues::Real = 0.01; + + attribute inclination : ScalarValues::Real = 28.5 [SI::degree] { + assert constraint { that >= 0.0 and that <= 90.0 } + } + + attribute RAAN : ScalarValues::Real = 0.0 [SI::degree]; // Right Ascension of Ascending Node + attribute argumentOfPeriapsis : ScalarValues::Real = 0.0 [SI::degree]; + attribute trueAnomaly : ScalarValues::Real = 0.0 [SI::degree]; + } +} + +library package SDK { + private import ScalarValues::*; + private import ISQ::*; + private import SI::*; + private import A::*; + + // structure + + port def P; + + part def S { + port scp : P; + attribute uid; + attribute typeID; + } + + part def N { + port scp_outside2 : P; + attribute uid; + } + + part def M { + attribute uid; + part n : N [0..*]; + part s : S [0..*]; + } + + part def T :> S { + attribute :>> typeID = 2; + } +} + +package M1 { + private import SDK::*; + + part m0001_2N : M { + attribute :>> uid = "M0001_2N"; + + part nx0001 : N subsets n { + attribute :>> uid = "NX0001"; + } + + part tcs0001 : T subsets s { + attribute :>> uid = "TCS0001"; + } + + interface tcs0001.scp to nx0001.scp_outside2; + } +} diff --git a/tests/test2.sysml b/tests/test2.sysml new file mode 100644 index 0000000..47eef21 --- /dev/null +++ b/tests/test2.sysml @@ -0,0 +1,3 @@ +package pkg { + part def Robert{} +} diff --git a/tests/test_core.py b/tests/test_core.py index 8fdd0d8..7db0234 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -3,11 +3,14 @@ Tests the actual source code from src/ with proper license handling. """ import pytest -import json +import pytest_check as check import tempfile import os from unittest.mock import Mock, patch, MagicMock - +import json, pprint +import syside +import pathlib +from flexo_syside_lib.core import convert_sysml_file_textual_to_json, convert_sysml_string_textual_to_json, convert_json_to_sysml_textual class TestUtilityFunctions: """Test utility functions that don't require SysIDE.""" @@ -84,6 +87,173 @@ def test_make_root_namespace_first_no_namespace(self): with pytest.raises(ValueError, match="No root namespace found"): _make_root_namespace_first(s) + def test_serialize_deserialize1(self): + EXAMPLE_DIR = pathlib.Path(os.getcwd()) + MODEL_FILE_PATH = EXAMPLE_DIR / 'Test2.sysml' + + # use minimal = True to get the compact version + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(sysml_file_path=MODEL_FILE_PATH, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + assert sysml_text !=None + + MODEL_FILE_PATH = EXAMPLE_DIR / 'pu-simple.sysml' + + # use minimal = True to get the compact version + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(sysml_file_path=MODEL_FILE_PATH, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + assert sysml_text !=None + + MODEL_FILE_PATH = EXAMPLE_DIR / 'pu.sysml' + + # use minimal = True to get the compact version + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(sysml_file_path=MODEL_FILE_PATH, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + assert sysml_text !=None + + MODEL_FILE_PATH = EXAMPLE_DIR / 'library.sysml' + + # use minimal = True to get the compact version + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(sysml_file_path=MODEL_FILE_PATH, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + assert sysml_text !=None + + MODEL_FILE_PATH = EXAMPLE_DIR / 'geo.sysml' + + # use minimal = True to get the compact version + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(sysml_file_path=MODEL_FILE_PATH, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + assert sysml_text !=None + + def test_serialize_deserialize1a(self): + def find_attribute_values(element: syside.Element, level: int = 0) -> None: + + if element.try_cast(syside.AttributeUsage): + #if element.name is not None: print(" " * level, element.name) + attr = element.cast(syside.AttributeUsage) + expression = next(iter(attr.owned_elements), None) + if expression is not None and isinstance(expression, syside.OperatorExpression): + expression, units = expression.arguments.collect() + typecheckedunit = units.cast(syside.FeatureReferenceExpression).referent + print (f"units = {units.referent} {typecheckedunit}") + + print (f"units = {units} {units.qualified_name}") + if expression is not None and isinstance(expression, syside.LiteralRational): + print(f"{attr.declared_name}: {expression.value}") + + for child in element.owned_elements.collect(): + find_attribute_values(child, level + 1) + + thissrc=""" + package MechanicalObjectExample { + private import ScalarValues::*; + part def DroneSystem { + part def Drone { + part battery { + /*attribute mass:ISQ::MassValue = 2.5 [SI::kg];*/ + attribute m:Real=2.5; + } + part propulsionUnit { + attribute mass:ISQ::MassValue = 0.5 [SI::kg]; + } + } + } + + }""" + model, diagnostics = syside.load_model(sysml_source=thissrc) + for document_resource in model.documents: + with document_resource.lock() as document: + find_attribute_values(document.root_node) + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(thissrc, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + + find_attribute_values(model.document.root_node) + + def test_serialize_deserialize4(self): + EXAMPLE_DIR = pathlib.Path(os.getcwd()) + MODEL_FILE_PATH = EXAMPLE_DIR / 'Test4.sysml' + + # use minimal = True to get the compact version + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(sysml_file_path=MODEL_FILE_PATH, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + #assert sysml_text !=None + check.is_not(sysml_text,None) + + + def test_serialize_deserialize5(self): + EXAMPLE_DIR = pathlib.Path(os.getcwd()) + MODEL_FILE_PATH = EXAMPLE_DIR / 'Test5.sysml' + + # use minimal = True to get the compact version + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(sysml_file_path=MODEL_FILE_PATH, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + #assert sysml_text !=None + check.is_not(sysml_text,None) + + + def test_serialize_deserialize6(self): + EXAMPLE_DIR = pathlib.Path(os.getcwd()) + MODEL_FILE_PATH = EXAMPLE_DIR / 'Test6.sysml' + + # use minimal = True to get the compact version + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(sysml_file_path=MODEL_FILE_PATH, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + #assert sysml_text !=None + check.is_not(sysml_text,None) + + + def test_serialize_deserialize7(self): + EXAMPLE_DIR = pathlib.Path(os.getcwd()) + MODEL_FILE_PATH = EXAMPLE_DIR / 'Test7.sysml' + + # use minimal = True to get the compact version + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(sysml_file_path=MODEL_FILE_PATH, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + #assert sysml_text !=None + check.is_not(sysml_text,None) + + def test_serialize_deserialize8(self): + EXAMPLE_DIR = pathlib.Path(os.getcwd()) + MODEL_FILE_PATH = EXAMPLE_DIR / 'Test1.sysml' + + try: + # use minimal = True to get the compact version + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(sysml_file_path=MODEL_FILE_PATH, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + #assert sysml_text !=None + check.is_not(sysml_text,None) + except ValueError as e: + # Custom reporting or logging for the unexpected exception + print(f"Caught an unexpected ValueError: {e}") + pytest.fail(f"Test failed due to unexpected ValueError: {e}") + + def test_serialize_deserialize9(self): + EXAMPLE_DIR = pathlib.Path(os.getcwd()) + MODEL_FILE_PATH = EXAMPLE_DIR / 'Test3.sysml' + + try: + # use minimal = True to get the compact version + change_payload_file, raw_jsonf = convert_sysml_file_textual_to_json(sysml_file_path=MODEL_FILE_PATH, minimal=False) + data = json.loads(raw_jsonf) # parse JSON string into Python objects + (sysml_text, model), warnings = convert_json_to_sysml_textual(data) + #assert sysml_text !=None + check.is_not(sysml_text,None) + + except ValueError as e: + # Custom reporting or logging for the unexpected exception + print(f"Caught an unexpected ValueError: {e}") + pytest.fail(f"Test failed due to unexpected ValueError: {e}") + class TestSysIDEIntegration: """Test SysIDE-dependent functions with proper mocking."""