From f0a8ac2c7b71e7845fbeea5efa5dba4488c7a81a Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Sat, 14 Jun 2025 11:09:44 +0200 Subject: [PATCH 01/15] fix minor bugs --- .vscode/settings.json | 1 + models/example_family/family.sysml | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/models/example_family/family.sysml b/models/example_family/family.sysml index f52b657..b3588ad 100644 --- a/models/example_family/family.sysml +++ b/models/example_family/family.sysml @@ -1,6 +1,7 @@ package Family { doc /* This package defines a family */ + //verified with SysIDE Modeler //Import packages private import ScalarValues::Natural; @@ -38,7 +39,7 @@ package Family { item def AssertCertificate :> SoundWaveMessage; //parts definitions - part def Person{ + part def Person { doc /* Person is the most generic part representing people */ attribute name : Name; @@ -148,17 +149,18 @@ package Family { //constraints definition constraint minimumAgeForAdoptiveParenthood { - attribute adoptingPartyAge : Natural; - adoptingPartyAge >= 18 + attribute minAdoptingPartyAge : Natural; + minAdoptingPartyAge == 18 } //requirements definition requirement def LegalAdoptionParenthood { doc /* the age of a legal adoptive parent must be more than 18 years */ - attribute parentAge : Natural; - require minimumAgeForAdoptiveParenthood { - parentAge = adoptingPartyAge; + attribute parent1Age : Natural; + attribute parent2Age : Natural; + require minimumAgeForAdoptiveParenthood { + parent1Age >= minAdoptingPartyAge & parent2Age >= minAdoptingPartyAge } } //Interaction for the defined use case @@ -178,7 +180,7 @@ package Family { //Parts // Multiplicity [1] is default, but it is here displayed to emphasize the multiplicity. - part adult[*] : Person { + part adult[*] : Family::Person { :>> isAdult = true; event occurrence informationOfLaw; then event occurrence acknowledgmentOfLaw; @@ -225,10 +227,10 @@ package Family { //requirements requirement validAdoptionParenthood : LegalAdoptionParenthood { doc - /*the age of both adoptive parents in a parenthood certificate Type C shall be more than 18 years */ + /*the age of an adoptive parent in a parenthood certificate Type C shall be more than 18 years */ subject adoption_certificate_TypeC; - attribute :>> adoptiveParent_1.age = parentAge; - attribute :>> adoptiveParent_2.age = parentAge; + attribute :>> parent1Age = adoptiveParent_1.age; + attribute :>> parent2Age = adoptiveParent_2.age; } } \ No newline at end of file From 9f37b36c3d0dc87386295113d018f1812953afaf Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Sat, 14 Jun 2025 11:34:42 +0200 Subject: [PATCH 02/15] amend redefinition --- models/example_family/family.sysml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/example_family/family.sysml b/models/example_family/family.sysml index b3588ad..718cf07 100644 --- a/models/example_family/family.sysml +++ b/models/example_family/family.sysml @@ -181,7 +181,7 @@ package Family { //Parts // Multiplicity [1] is default, but it is here displayed to emphasize the multiplicity. part adult[*] : Family::Person { - :>> isAdult = true; + attribute isAdultPerson : Boolean :>> isAdult = true; event occurrence informationOfLaw; then event occurrence acknowledgmentOfLaw; then event occurrence receivalOfCertificate; From 5b40b75b1b102e6290d217db9a93af25a38953dc Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Sat, 14 Jun 2025 11:37:00 +0200 Subject: [PATCH 03/15] add diagram with SysIDE Modeler --- models/example_family/family.png | Bin 0 -> 104305 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 models/example_family/family.png diff --git a/models/example_family/family.png b/models/example_family/family.png new file mode 100644 index 0000000000000000000000000000000000000000..1a400a6cb97461189f03c4f6d02c8603ff298c7e GIT binary patch literal 104305 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 M49yI3_Z~U>56*t0#Q*>R literal 0 HcmV?d00001 From b293541a1c41035b2a6bd45a8c76a1608d712ccf Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Sat, 14 Jun 2025 13:09:08 +0200 Subject: [PATCH 04/15] add cause-effect confoguration item --- .../DomainModel/Domain.sysml | 39 +++++++-------- .../DomainModel/cause-effect.sysml | 48 +++++++++---------- 2 files changed, 44 insertions(+), 43 deletions(-) diff --git a/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml b/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml index b3c8610..89216e8 100644 --- a/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml +++ b/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml @@ -20,7 +20,9 @@ package Domain { part miningCorporation: MiningCorporation; part drone : Drone[1..*]; } - + part domain : Domain; + + // Definitions of domain objects part def Spaceship { #mop cargoCapacity : Real; // Maximum ore cargo capacity (m³) #mop survivalProbability : Real; // Probability of surviving an operation (%) @@ -33,8 +35,6 @@ package Domain { attribute dockingTime : Real; // seconds, the time required to dock and offload ore (STRQ08) attribute shieldStrength : Real ; //Strength of the core shield (STRQ03) } - - // Definitions of domain objects part def MiningCorporation { #moe minimumProfit : Real { @@ -132,25 +132,25 @@ package Domain { in miningFrigates = miningFrigate; } // Cause and Effect Occurrences - event occurrence MiningRateIncreases; - event occurrence CargoCapacityIncreases; - event occurrence ShieldStrengthIncreases; - event occurrence ThreatDetectionImproves; - event occurrence DroneOperationsImprove; - event occurrence WarpSpeedIncreases; - event occurrence FleetCoordinationImproves; - - event occurrence OreYieldIncreases; - event occurrence DowntimeReduces; - event occurrence SurvivabilityEnhances; - event occurrence ThreatResponseImproves; - event occurrence OperationalEfficiencyIncreases; - event occurrence OreExtractionEfficiencyIncreases; - event occurrence ProfitabilityMaximizes; + timeslice miningRateIncreases; + timeslice cargoCapacityIncreases; + timeslice shieldStrengthIncreases; + timeslice threatDetectionImproves; + timeslice droneOperationsImprove; + timeslice warpSpeedIncreases; + } part rorqual : Rorqual [1..*]; ref part pilotPod : PilotPod [1..*] ; - part fleet : Fleet [1..*]; + part fleet : Fleet [1..*]{ + timeslice fleetCoordinationImproves; + timeslice downtimeReduces; + timeslice survivabilityEnhances; + timeslice threatResponseImproves; + timeslice operationalEfficiencyIncreases; + timeslice oreExtractionEfficiencyIncreases; + timeslice profitabilityMaximizes; + } //interactions at the enterprise level occurrence def MiningAsteroid { @@ -241,6 +241,7 @@ package Domain { #mop oreContent : Real; // Quantity of ore available (m³) #mop depletionRate : Real; // Rate at which ore is extracted (m³/hour) port asteroidOrePort : AsteroidOrePort; + timeslice oreYieldIncreases; } part def HostileShip { diff --git a/models/example_EveOnlineMiningFrigate/DomainModel/cause-effect.sysml b/models/example_EveOnlineMiningFrigate/DomainModel/cause-effect.sysml index 4311104..82f51d3 100644 --- a/models/example_EveOnlineMiningFrigate/DomainModel/cause-effect.sysml +++ b/models/example_EveOnlineMiningFrigate/DomainModel/cause-effect.sysml @@ -1,34 +1,34 @@ package causeEffect { - private import Domain::MiningCorporation::miningFrigate; + private import Domain::*; + private import MiningFrigate::*; private import CauseAndEffect::*; - private import CausationConnections::*; //The cause-effect relationships //This section is not correctly parsed and needs further corrections - //#causation connect miningFrigate.MiningRateIncreases to miningFrigate.OreYieldIncreases; - //#causation connect miningFrigate.CargoCapacityIncreases to miningFrigate.DowntimeReduces; - //#causation connect miningFrigate.ShieldStrengthIncreases to miningFrigate.SurvivabilityEnhances; - //#causation connect miningFrigate.ThreatDetectionImproves to miningFrigate.ThreatResponseImproves; - //#causation connect miningFrigate.DroneOperationsImprove to miningFrigate.OperationalEfficiencyIncreases; - //#causation connect miningFrigate.WarpSpeedIncreases to miningFrigate.DowntimeReduces; - //#causation connect miningFrigate.FleetCoordinationImproves to miningFrigate.OperationalEfficiencyIncreases; + #causation connect Domain::domain.miningCorporation.miningFrigate.miningRateIncreases to Domain::domain.asteroid.oreYieldIncreases; + #causation connect Domain::domain.miningCorporation.miningFrigate.cargoCapacityIncreases to Domain::domain.miningCorporation.fleet.downtimeReduces; + #causation connect Domain::domain.miningCorporation.miningFrigate.shieldStrengthIncreases to Domain::domain.miningCorporation.fleet.survivabilityEnhances; + #causation connect Domain::domain.miningCorporation.miningFrigate.threatDetectionImproves to Domain::domain.miningCorporation.fleet.threatResponseImproves; + #causation connect Domain::domain.miningCorporation.miningFrigate.droneOperationsImprove to Domain::domain.miningCorporation.fleet.operationalEfficiencyIncreases; + #causation connect Domain::domain.miningCorporation.miningFrigate.warpSpeedIncreases to Domain::domain.miningCorporation.fleet.downtimeReduces; + #causation connect Domain::domain.miningCorporation.fleet.fleetCoordinationImproves to Domain::domain.miningCorporation.fleet.operationalEfficiencyIncreases; - //#multicausation connection { - // end #cause ::> miningFrigate.OreYieldIncreases; - // end #cause ::> miningFrigate.DowntimeReduces; - // end #effect ::> miningFrigate.OreExtractionEfficiencyIncreases; - //} + #multicausation connection { + end #cause ::> Domain::domain.asteroid.oreYieldIncreases; + end #cause ::> Domain::domain.miningCorporation.fleet.downtimeReduces; + end #effect ::> Domain::domain.miningCorporation.fleet.oreExtractionEfficiencyIncreases; + } - //#multicausation connection { - // end #cause ::> miningFrigate.SurvivabilityEnhances; - // end #cause ::> miningFrigate.ThreatResponseImproves; - // end #effect ::> miningFrigate.OperationalEfficiencyIncreases; - //} + #multicausation connection { + end #cause ::> Domain::domain.miningCorporation.fleet.survivabilityEnhances; + end #cause ::> Domain::domain.miningCorporation.fleet.threatResponseImproves; + end #effect ::> Domain::domain.miningCorporation.fleet.operationalEfficiencyIncreases; + } - //#multicausation connection { - // end #cause ::> miningFrigate.OperationalEfficiencyIncreases; - // end #cause ::> miningFrigate.OreExtractionEfficiencyIncreases; - // end #effect ::> miningFrigate.ProfitabilityMaximizes; - //} + #multicausation connection { + end #cause ::> Domain::domain.miningCorporation.fleet.operationalEfficiencyIncreases; + end #cause ::> Domain::domain.miningCorporation.fleet.oreExtractionEfficiencyIncreases; + end #effect ::> Domain::domain.miningCorporation.fleet.profitabilityMaximizes; + } } \ No newline at end of file From 37d9bce1e47e8c3efeed6812ce51ce01a8edb163 Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Sat, 14 Jun 2025 15:02:10 +0200 Subject: [PATCH 05/15] added CONOPS --- .../DomainModel/OPSCON.sysml | 129 ++++++++++++++++++ .../Libraries/DocumentStructure.sysml | 40 ++++++ 2 files changed, 169 insertions(+) create mode 100644 models/example_EveOnlineMiningFrigate/DomainModel/OPSCON.sysml create mode 100644 models/example_EveOnlineMiningFrigate/Libraries/DocumentStructure.sysml diff --git a/models/example_EveOnlineMiningFrigate/DomainModel/OPSCON.sysml b/models/example_EveOnlineMiningFrigate/DomainModel/OPSCON.sysml new file mode 100644 index 0000000..e4b5087 --- /dev/null +++ b/models/example_EveOnlineMiningFrigate/DomainModel/OPSCON.sysml @@ -0,0 +1,129 @@ +package OPSCON { + + private import DocumentStructureMetadata::*; + + // The OPSCON document instance + #document OPSCON { + title = "OPSCON for Mining Frigate-Based Resource Extraction"; + status = "Draft"; + + // Chapter 1 – Mission Overview + #chapter missionOverview { + title = "1. Mission Overview"; + #section overviewSection { + heading = "Overview"; + content = "The Mining Corporation operates fleets of mining frigates in + asteroid belts and wormholes. The goals are maximizing profitability, + ensuring operational safety, and sustaining long-term operations. The + central command coordinates deployments using PilotPods with tactical + oversight from Fleet Commanders."; + } + } + + // Chapter 2 – Operational Context + #chapter context { + title = "2. Operational Context"; + #section environment { + heading = "Operational Environment"; + content = "Operations take place in High Sec, Low Sec, Null Sec, and + Wormhole space, involving hostile encounters, asteroid depletion, and + resupply via stations or POS. System elements and context are defined + in Domain and ConceptOfOperations packages."; + } + } + + // Chapter 3 – Stakeholders and Roles + #chapter stakeholders { + title = "3. Actors and Roles"; + #section actorRoles { + heading = "Actor Definitions"; + content = "Actors include Mining CEO, Operations Manager, Fleet Commander, + Ship Engineer, and Market Analyst. Responsibilities span strategy, cost + control, fleet survivability, system design, and market alignment."; + } + } + + // Chapter 4 – System Elements + #chapter systemElements { + title = "4. System Elements"; + #section elementsOverview { + heading = "System Components"; + content = "Primary elements include MiningFrigate, PilotPod, Rorqual, + Drone, and Station. These components are defined in the Domain and MiningFrigate + packages."; + } + } + + // Chapter 5 – Use Cases + #chapter useCases { + title = "5. Use Case Overview"; + #section useCasesSummary { + heading = "Operational Use Cases"; + content = "Main use cases include Mine Asteroids, Plot Course and Navigate, + Detect Threats and Engage Defenses, Offload Ore and Resupply, and Deploy Drones. + Each is modeled in the MiningFrigateUseCases package and leverages reusable + included use cases."; + } + } + + // Chapter 6 – Operational Requirements + #chapter requirements { + title = "6. Operational Requirements"; + #section requirementSummary { + heading = "Performance and Capability Requirements"; + content = "MiningFrigates are required to extract ≥ 50 m³/min, have ≥ 5000 m³ + cargo capacity, survive 400 DPS, detect threats within 20 AU, warp at ≥ 5 AU/s, + align in ≤ 3 sec, and dock/unload in ≤ 60 sec. These are defined and bound + in MiningFrigateRequirements and MiningFrigateRequirementsDef."; + } + } + + // Chapter 7 – Verification Strategy + #chapter systemVerification { + title = "7. Verification Strategy"; + #section strategy { + heading = "Verification through Simulation and Testing"; + content = "Requirements are verified using formal verification definitions + (e.g., OreExtractionEfficiencyTest) implemented in MiningFrigateRequirementsVerification. + The MiningFrigateTestRig simulates conditions, logs data, and compares outcomes + against defined constraints."; + } + } + + // Chapter 8 – Measures of Effectiveness + #chapter moes { + title = "8. Measures of Effectiveness"; + #section moesSummary { + heading = "MoEs and Decision Criteria"; + content = "MoEs include profitability (ISK/hour), ore throughput, survivability, + threat response time, storage utilization, fleet deployment efficiency, and + adaptability. These are modeled in the Domain and BusinessRequirements packages + and trace to StakeholderConcerns."; + } + } + + // Chapter 9 – Risk Considerations + #chapter risk { + title = "9. Risk Considerations"; + #section riskAnalysis { + heading = "Risk-Adjusted Decision Making"; + content = "The analysisProblemSpace package provides a model-based method for + calculating profitability adjusted by risk factors like survival probability, + operational cost, and market ore prices across different zones."; + } + } + + // Chapter 10 – Lifecycle Considerations + #chapter lifecycle { + title = "10. Lifecycle Considerations"; + #section traceability { + heading = "Model Traceability and Lifecycle Use"; + content = "The full model supports requirement declaration, use case-driven + behavior, formal verification, and traceability across viewpoints. All aspects + are integrated through packages including MiningFrigateRequirementsDecl, + MiningFrigateRequirementsVerification, and StakeholderConcerns."; + } + } + + } +} diff --git a/models/example_EveOnlineMiningFrigate/Libraries/DocumentStructure.sysml b/models/example_EveOnlineMiningFrigate/Libraries/DocumentStructure.sysml new file mode 100644 index 0000000..40d66a8 --- /dev/null +++ b/models/example_EveOnlineMiningFrigate/Libraries/DocumentStructure.sysml @@ -0,0 +1,40 @@ +library package DocumentStructureLibrary { + private import ScalarValues::*; + + // A Document is a top-level semantic container + abstract part def Document { + attribute title : String; + attribute status : String; + part :>> chapters[*]; + } + + // Chapters define hierarchical sections + abstract part def Chapter { + attribute title : String; + part :>> sections[*]; + } + + // Sections provide the narrative or model references + abstract part def Section { + attribute heading : String; + attribute content : String; + } + abstract part documents : Document[*] nonunique; + abstract part chapters : Chapter[*] nonunique; + abstract part sections : Section[*] nonunique; + +} +library package DocumentStructureMetadata { + private import DocumentStructureLibrary::*; + private import Metaobjects::SemanticMetadata; + + metadata def document :> SemanticMetadata { + :>> baseType = documents meta SysML::Usage; + } + metadata def chapter :> SemanticMetadata { + :>> baseType = chapters meta SysML::Usage; + } + metadata def section :> SemanticMetadata { + :>> baseType = sections meta SysML::Usage; + } +} \ No newline at end of file From b4352a521453f60d7d2b8b1d5bdf06f72a8aff2c Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Sun, 15 Jun 2025 06:09:00 +0200 Subject: [PATCH 06/15] correct lybrary documents --- .../Libraries/DocumentStructure.sysml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/example_EveOnlineMiningFrigate/Libraries/DocumentStructure.sysml b/models/example_EveOnlineMiningFrigate/Libraries/DocumentStructure.sysml index 40d66a8..1c20905 100644 --- a/models/example_EveOnlineMiningFrigate/Libraries/DocumentStructure.sysml +++ b/models/example_EveOnlineMiningFrigate/Libraries/DocumentStructure.sysml @@ -5,13 +5,13 @@ library package DocumentStructureLibrary { abstract part def Document { attribute title : String; attribute status : String; - part :>> chapters[*]; + part chapters : Chapter[*]; } // Chapters define hierarchical sections abstract part def Chapter { attribute title : String; - part :>> sections[*]; + part sections : Section[*]; } // Sections provide the narrative or model references From 6c369351bb826a8ec384e3a642770f3300df0b47 Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Tue, 17 Jun 2025 11:19:37 +0200 Subject: [PATCH 07/15] add viewpoints and views --- .../DomainModel/Concerns.sysml | 39 ++++++++++++------- .../DomainModel/Domain.sysml | 13 ++++++- .../DomainModel/MiningFrigate.sysml | 4 +- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/models/example_EveOnlineMiningFrigate/DomainModel/Concerns.sysml b/models/example_EveOnlineMiningFrigate/DomainModel/Concerns.sysml index 206c315..4e87593 100644 --- a/models/example_EveOnlineMiningFrigate/DomainModel/Concerns.sysml +++ b/models/example_EveOnlineMiningFrigate/DomainModel/Concerns.sysml @@ -34,9 +34,10 @@ package StakeholderConcerns { private import StakeholdersDef::*; private import MiningFrigate::*; + // The concerns are directly declared without definition, beacuse they aren't going to be reused in the scope of this model. // Concerns Derived from the Business Case - concern def ProfitabilityConcern { + concern ProfitabilityConcern { subject miningCorporation : Domain::MiningCorporation; require constraint { @@ -47,7 +48,7 @@ package StakeholderConcerns { stakeholder miningCEO : MiningCEO; } - concern def OperationalCostsConcern { + concern OperationalCostsConcern { subject miningCorporation : Domain::MiningCorporation; require constraint { @@ -58,7 +59,7 @@ package StakeholderConcerns { stakeholder operationsManager : OperationsManager; } - concern def ScalabilityConcern { + concern ScalabilityConcern { subject miningCorporation : Domain::MiningCorporation; assume constraint { @@ -69,7 +70,7 @@ package StakeholderConcerns { stakeholder fleetCommander : FleetCommander; } - concern def MarketResponsivenessConcern { + concern MarketResponsivenessConcern { subject miningCorporation : Domain::MiningCorporation; require constraint { @@ -82,7 +83,7 @@ package StakeholderConcerns { // Concerns Derived from the ConOps - concern def SecurityConcern { + concern SecurityConcern { subject miningFrigate : MiningFrigate::MiningFrigate; require constraint { @@ -94,7 +95,7 @@ package StakeholderConcerns { stakeholder shipEngineer : ShipEngineer; } - concern def ResourceAvailabilityConcern { + concern ResourceAvailabilityConcern { subject miningCorporation : Domain::MiningCorporation; require constraint { @@ -105,7 +106,7 @@ package StakeholderConcerns { stakeholder fleetCommander : FleetCommander; } - concern def DeploymentEfficiencyConcern { + concern DeploymentEfficiencyConcern { subject miningFrigate : MiningFrigate::MiningFrigate; require constraint { @@ -116,7 +117,7 @@ package StakeholderConcerns { stakeholder operationsManager : OperationsManager; } - concern def ThreatNeutralizationConcern { + concern ThreatNeutralizationConcern { subject miningFrigate : MiningFrigate::MiningFrigate; require constraint { @@ -130,7 +131,7 @@ package StakeholderConcerns { // Concerns Derived from the MoEs - concern def TotalProfitabilityConcern { + concern TotalProfitabilityConcern { subject miningCorporation : Domain::MiningCorporation; require constraint { @@ -141,7 +142,7 @@ package StakeholderConcerns { stakeholder miningCEO : MiningCEO; } - concern def OreYieldConcern { + concern OreYieldConcern { subject miningFrigate : MiningFrigate::MiningFrigate; require constraint { @@ -152,7 +153,7 @@ package StakeholderConcerns { stakeholder operationsManager : OperationsManager; } - concern def SurvivabilityConcern { + concern SurvivabilityConcern { subject miningFrigate : MiningFrigate::MiningFrigate; require constraint { @@ -163,7 +164,7 @@ package StakeholderConcerns { stakeholder shipEngineer : ShipEngineer; } - concern def FleetDeploymentEfficiencyConcern { + concern FleetDeploymentEfficiencyConcern { subject miningCorporation : Domain::MiningCorporation; require constraint { @@ -175,7 +176,7 @@ package StakeholderConcerns { stakeholder operationsManager : OperationsManager; } - concern def OreDeliveryEfficiencyConcern { + concern OreDeliveryEfficiencyConcern { subject miningFrigate : MiningFrigate::MiningFrigate; require constraint { @@ -186,7 +187,7 @@ package StakeholderConcerns { stakeholder operationsManager : OperationsManager; } - concern def RiskAdjustedProfitabilityConcern { + concern RiskAdjustedProfitabilityConcern { subject miningCorporation : Domain::MiningCorporation; require constraint { @@ -198,4 +199,14 @@ package StakeholderConcerns { stakeholder fleetCommander : FleetCommander; } + //Viewpoints + viewpoint 'Operational profitability'{ + frame ProfitabilityConcern; + + require constraint { + doc /*TBD*/ + } + } + + } diff --git a/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml b/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml index 89216e8..8ce075a 100644 --- a/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml +++ b/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml @@ -374,5 +374,16 @@ package Domain { item def ScanSignature { attribute type: String; attribute priority: String; - } + } + + //Views and views definition + view def 'Domain Structure View'{ + satisfy StakeholderConcerns::'Operational profitability'; + + filter @SysML::PartUsage; + } + view 'Mining Frigate structure Table View' : 'Domain Structure View' { + expose MiningCorporation::miningFrigate::*; + //render asElementTable; + } } \ No newline at end of file diff --git a/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml b/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml index b45255c..a0601e2 100644 --- a/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml +++ b/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml @@ -6,6 +6,7 @@ private import ParametersOfInterestMetadata::*; private import OperationalUseCaseActions::*; private import Domain::*; + private import StakeholderConcerns::*; part def MiningFrigate :> Domain::Spaceship { @@ -220,5 +221,6 @@ part def NavigationModule { attribute agilityBonus : Real; // Improves ship align time attribute warpSpeedBonus : Real; // Boost to warp speed - } + } + } \ No newline at end of file From 8b6918c3b1846c694123296464fc06105b50913c Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Tue, 17 Jun 2025 13:47:22 +0200 Subject: [PATCH 08/15] add variants --- .../LogicalArchitecture/COTS.sysml | 47 ++++++++++++++++--- .../LogicalArchitecture/MiningFrigate.sysml | 8 +++- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml index 833e743..7854e3b 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml @@ -6,17 +6,50 @@ // **COTS Module Definitions with Conjugated Ports** - part def MinerI :> SimpleFrigateComponent { + abstract part def MinerModule :> SimpleFrigateComponent { doc /* Standard mining laser used on mining frigates for ore extraction. */ - attribute miningYield : Real = 40.0; - attribute cycleTime : Real = 60.0; - attribute capacitorUsage : Real = 5.0; - redefines mass : Real = 500.0; // Mass in kg - redefines powerUsage = 5.0; + attribute miningYield : Real; + attribute cycleTime : Real; + attribute capacitorUsage : Real; + attribute range : Real; + redefines mass : Real; + redefines powerUsage; port highSlot : ~HighSlotPort; } - + part def 'EP-S Gaussian Scoped Mining Laser' :> MinerModule { + doc /* Standard mining laser used on mining frigates for ore extraction. */ + redefines miningYield : Real = 50.0; + redefines cycleTime : Real = 60.0; + redefines capacitorUsage : Real = 5.0; + redefines range : Real = 16.0; + redefines mass : Real = 500.0; // Mass in kg + redefines powerUsage = 3.0; + } + part 'Mining Laser EP-S Gaussian Scoped' : 'EP-S Gaussian Scoped Mining Laser'; + + part def MinerI :> MinerModule { + doc /* Standard mining laser used on mining frigates for ore extraction. */ + redefines miningYield : Real = 40.0; + redefines cycleTime : Real = 60.0; + redefines capacitorUsage : Real = 5.0; + redefines range : Real = 10.0; + redefines mass : Real = 500.0; // Mass in kg + redefines powerUsage = 2.0; + } + part minerI : MinerI; + + part def 'Particle Bore Compact Mining Laser' :> MinerModule { + doc /* Standard mining laser used on mining frigates for ore extraction. */ + redefines miningYield : Real = 50.0; + redefines cycleTime : Real = 60.0; + redefines capacitorUsage : Real = 5.0; + redefines range : Real = 11.0; + redefines mass : Real = 500.0; // Mass in kg + redefines powerUsage = 2.0; + } + part 'Mining Laser Particle Bore Compact' : 'Particle Bore Compact Mining Laser'; + part def Afterburner :> SimpleFrigateComponent { doc /* Improves sublight speed by increasing thrust. */ attribute velocityBonus : Real = 112.5; diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml index e6fceb3..7520761 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml @@ -9,14 +9,18 @@ package MiningFrigateSolutionSpace { private import MiningFrigateHullHighLevelActions::*; // **Mining Frigate as the Core System** - part def MiningFrigate :> CompositeFrigateComponent { + abstract part def MiningFrigateConfiguration :> CompositeFrigateComponent { doc /* The Mining Frigate consists of a fixed hull structure with modular (COTS) components * that can be replaced or upgraded depending on operational needs. */ part hull : MiningFrigateHull; // **COTS Modules (Ref Parts - Exchangeable)** - ref part miningLaser : MinerI[2]; + variation ref part miningLaser : MinerModule[2]{ + variant 'Mining Laser EP-S Gaussian Scoped'; + variant 'Mining Laser Particle Bore Compact'; + variant minerI : MinerI; + } ref part propulsionModule : Afterburner[0..1]; ref part shieldModule : SmallShieldExtenderI[0..1]; ref part capacitorModule : SmallCapBatteryI[0..1]; From 670fe64a7ec1b623d9b73d24a022c24b23e011a9 Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Tue, 17 Jun 2025 15:31:52 +0200 Subject: [PATCH 09/15] add variants --- .../LogicalArchitecture/MiningFrigate.sysml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml index 7520761..cba8c00 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml @@ -52,6 +52,19 @@ package MiningFrigateSolutionSpace { modulePort ::> defensiveModule.lowSlot; } + //Three different configurations of mining frigatte are defined here + part noviceMiningFrigatte : MiningFrigateConfiguration{ + part redefines miningLaser = miningLaser::minerI; + } + + part trainerMiningFrigate : MiningFrigateConfiguration{ + part redefines miningLaser = miningLaser::'Mining Laser Particle Bore Compact'; + } + + part operationalMiningFrigate : MiningFrigateConfiguration{ + part redefines miningLaser = miningLaser::'Mining Laser EP-S Gaussian Scoped'; + } + // **Mining Frigate Hull (Black Box with Ports)** part def MiningFrigateHull :> SimpleFrigateComponent { doc /* The Venture-class Mining Frigate hull includes integrated features such as From db2bff10fe3a7e141a8a46f25b48b7608ef72bfd Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Tue, 17 Jun 2025 15:58:45 +0200 Subject: [PATCH 10/15] allocate logical system in solutin space --- .../DomainModel/MiningFrigate.sysml | 3 ++ .../LogicalArchitecture/MiningFrigate.sysml | 29 +++++++++++-------- .../LogicalArchitecture/UseCasesHull.sysml | 26 ++++++++--------- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml b/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml index a0601e2..53403f5 100644 --- a/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml +++ b/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml @@ -41,6 +41,9 @@ } } + + part miningFrigate:MiningFrigate; + // State Definition for the Mining Frigate state miningFrigatesStates { in miningFrigates : MiningFrigate; diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml index cba8c00..8b79731 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml @@ -8,12 +8,15 @@ package MiningFrigateSolutionSpace { private import FrigateRollupAnalysis::*; private import MiningFrigateHullHighLevelActions::*; + //allocate the logical mining frigate to the domain mining frigte + allocate logicalMiningFrigateConfiguration to MiningFrigate::miningFrigate; + // **Mining Frigate as the Core System** - abstract part def MiningFrigateConfiguration :> CompositeFrigateComponent { + abstract part def LogicalMiningFrigateConfiguration :> CompositeFrigateComponent { doc /* The Mining Frigate consists of a fixed hull structure with modular (COTS) components * that can be replaced or upgraded depending on operational needs. */ - part hull : MiningFrigateHull; + part logicalHull : LogicalMiningFrigateHull; // **COTS Modules (Ref Parts - Exchangeable)** variation ref part miningLaser : MinerModule[2]{ @@ -28,45 +31,47 @@ package MiningFrigateSolutionSpace { ref part defensiveModule : WarpCoreStabilizerI[0..2]; interface highSlotInterface1 : HighSlotInterface connect - hullPort ::> hull.highSlot1 to + hullPort ::> logicalHull.highSlot1 to modulePort ::> miningLaser.highSlot; interface highSlotInterface2 : HighSlotInterface connect - hullPort ::> hull.highSlot2 to + hullPort ::> logicalHull.highSlot2 to modulePort ::> miningLaser.highSlot; interface mediumSlotInterface1 : MediumSlotInterface connect - hullPort ::> hull.mediumSlot1 to + hullPort ::> logicalHull.mediumSlot1 to modulePort ::> propulsionModule.mediumSlot; interface mediumSlotInterface2 : MediumSlotInterface connect - hullPort ::> hull.mediumSlot2 to + hullPort ::> logicalHull.mediumSlot2 to modulePort ::> shieldModule.mediumSlot; interface lowSlotInterface1 : LowSlotInterface connect - hullPort ::> hull.lowSlot1 to + hullPort ::> logicalHull.lowSlot1 to modulePort ::> defensiveModule.lowSlot; interface lowSlotInterface2 : LowSlotInterface connect - hullPort ::> hull.lowSlot2 to + hullPort ::> logicalHull.lowSlot2 to modulePort ::> defensiveModule.lowSlot; } //Three different configurations of mining frigatte are defined here - part noviceMiningFrigatte : MiningFrigateConfiguration{ + abstract part logicalMiningFrigateConfiguration : LogicalMiningFrigateConfiguration; + + part logicalNoviceMiningFrigatte : LogicalMiningFrigateConfiguration{ part redefines miningLaser = miningLaser::minerI; } - part trainerMiningFrigate : MiningFrigateConfiguration{ + part logicalTrainerMiningFrigate : LogicalMiningFrigateConfiguration{ part redefines miningLaser = miningLaser::'Mining Laser Particle Bore Compact'; } - part operationalMiningFrigate : MiningFrigateConfiguration{ + part logicalOperationalMiningFrigate : LogicalMiningFrigateConfiguration{ part redefines miningLaser = miningLaser::'Mining Laser EP-S Gaussian Scoped'; } // **Mining Frigate Hull (Black Box with Ports)** - part def MiningFrigateHull :> SimpleFrigateComponent { + part def LogicalMiningFrigateHull :> SimpleFrigateComponent { doc /* The Venture-class Mining Frigate hull includes integrated features such as * a built-in warp core stabilizer, ore hold, and base resistances. */ diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml index 0e49b1e..19249f5 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml @@ -87,7 +87,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case: Withstand Incoming Damage** use case def WithstandIncomingDamage { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor hostileShip : Domain::HostileShip; actor pilotPod : Domain::PilotPod; @@ -100,7 +100,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case: Navigate and Warp to Destinations** use case def NavigateAndWarp { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; objective { @@ -112,7 +112,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case: Store and Transfer Mined Ore** use case def StoreAndTransferOre { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor station : Domain::Station; @@ -126,7 +126,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case: Dock and Undock from Stations** use case def DockAndUndock { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor station : Domain::Station; @@ -139,7 +139,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case: Manage Energy Supply and Recharge** use case def ManageEnergy { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor smallCapBatteryI : SmallCapBatteryI; @@ -152,7 +152,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case: Support High, Medium, and Low Slot Modules** use case def SupportModuleFitting { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor miningLaser : MinerI; @@ -165,7 +165,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case Definition: Detect Threat** use case def DetectThreat { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; objective { @@ -178,7 +178,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case Definition: Engage Defenses** use case def EngageDefenses { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor hostileShip : Domain::HostileShip; @@ -192,7 +192,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case Definition: Navigate to Destination** use case def NavigateToDestination { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; objective { @@ -205,7 +205,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case Definition: Transfer Ore** use case def TransferOre { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor station : Domain::Station; @@ -218,7 +218,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case Definition: Dock at Station** use case def DockAtStation { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor station : Domain::Station; @@ -232,7 +232,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case Definition: Resupply Capacitor** use case def ResupplyCapacitor { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor smallCapBatteryI : SmallCapBatteryI; @@ -245,7 +245,7 @@ package MiningFrigateHullUseCasesDef { // **Use Case Definition: Activate Mining Laser** use case def ActivateMiningLaser { - subject hull : MiningFrigateHull; + subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor miningLaser : MinerI; From 9bd34caf27ef1778795121018c3b594c34aacdcb Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Tue, 17 Jun 2025 16:29:00 +0200 Subject: [PATCH 11/15] amend actions --- .../LogicalArchitecture/ActionsHull.sysml | 67 +------ .../LogicalArchitecture/MiningFrigate.sysml | 25 ++- .../LogicalArchitecture/UseCasesHull.sysml | 178 ++---------------- 3 files changed, 31 insertions(+), 239 deletions(-) diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml index 4a3d42b..17e5e49 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml @@ -1,52 +1,8 @@ -package MiningFrigateHullHighLevelActions { +package MiningFrigateHullActions { - private import MiningFrigateHullIncludedActions::*; private import Domain::*; private import MiningFrigateSolutionSpace::*; - - // **Action: Withstand Incoming Damage** - action def WithstandIncomingDamage { - in scanCommand : Domain::ShipCommand; - out defenseStatus : Domain::ShipReport; - - bind detectThreat.scanCommand = scanCommand; - action detectThreat : DetectThreat { in scanCommand; out scanReport; } - flow from detectThreat.scanReport to engageDefenses.engageCommand; - first detectThreat then engageDefenses; - action engageDefenses : EngageDefenses { in engageCommand; out defenseStatus; } - bind engageDefenses.defenseStatus = defenseStatus; - } - - // **Action: Navigate and Warp to Destinations** - action def NavigateAndWarp { - in destinationCommand : Domain::ShipCommand; - out navigationStatus : Domain::ShipReport; - - bind navigate.destinationCommand = destinationCommand; - action navigate : NavigateToDestination { in destinationCommand; out navigationStatus; } - bind navigate.navigationStatus = navigationStatus; - } - - // **Action: Store and Transfer Mined Ore** - action def StoreAndTransferOre { - in transferCommand : Domain::ShipCommand; - out transferStatus : Domain::ShipReport; - - bind transferOre.transferCommand = transferCommand; - action transferOre : TransferOre { in transferCommand; out transferStatus; } - bind transferOre.transferStatus = transferStatus; - } - - // **Action: Dock and Undock from Stations** - action def DockAndUndock { - in dockingCommand : Domain::ShipCommand; - out dockingStatus : Domain::ShipReport; - - bind dock.dockingCommand = dockingCommand; - action dock : DockAtStation { in dockingCommand; out dockingStatus; } - bind dock.dockingStatus = dockingStatus; - } - + // **Action: Manage Energy Supply and Recharge** action def ManageEnergy { in rechargeCommand : Domain::ShipCommand; @@ -56,23 +12,6 @@ package MiningFrigateHullHighLevelActions { action resupplyCapacitor : ResupplyCapacitor { in rechargeCommand; out rechargeStatus; } bind resupplyCapacitor.rechargeStatus = rechargeStatus; } - - // **Action: Support High, Medium, and Low Slot Modules** - action def SupportModuleFitting { - in miningCommand : Domain::ShipCommand; - out miningStatus : Domain::ShipReport; - - bind activateMiningLaser.miningCommand = miningCommand; - action activateMiningLaser : ActivateMiningLaser { in miningCommand; out miningStatus; } - bind activateMiningLaser.miningStatus = miningStatus; - } -} - - -package MiningFrigateHullIncludedActions { - - private import Domain::*; - private import MiningFrigateSolutionSpace::*; // **Action: Detect Threat** action def DetectThreat { @@ -99,7 +38,7 @@ package MiningFrigateHullIncludedActions { } // **Action: Dock at Station** - action def DockAtStation { + action def DockToStation { in dockingCommand : Domain::ShipCommand; out dockingStatus : Domain::ShipReport; } diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml index 8b79731..82367d3 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml @@ -6,7 +6,7 @@ package MiningFrigateSolutionSpace { private import StdPortsAndInterfaces::*; private import ParametersOfInterestMetadata::*; private import FrigateRollupAnalysis::*; - private import MiningFrigateHullHighLevelActions::*; + private import MiningFrigateHullActions::*; //allocate the logical mining frigate to the domain mining frigte allocate logicalMiningFrigateConfiguration to MiningFrigate::miningFrigate; @@ -84,18 +84,17 @@ package MiningFrigateSolutionSpace { attribute capacitorCapacity : Real = 250.0; // Performed actions of the hull (executed by the ship's integrated systems) - perform action scanForThreats; - perform action engageDefenses; - perform action acceptDestination; - perform action plotOptimalCourse; - perform action engagePropulsion; - perform action monitorAndAdjustCourse; - perform action transferOre; - perform action verifyCargoTransfer; - perform action dockToStation; - perform action undockFromStation; - perform action resupplyCapacitor; - perform action activateMiningLaser; + perform action manageEnergy : MiningFrigateHullActions::ManageEnergy; + perform action detectThreat : MiningFrigateHullActions::DetectThreat; + perform action engageDefenses : MiningFrigateHullActions::EngageDefenses; + perform action navigateToDestination : MiningFrigateHullActions::NavigateToDestination; + perform action reportToPilot : MiningFrigateHullActions::ReportToPilot; + perform action transferOre : MiningFrigateHullActions::TransferOre; + perform action extractOre : MiningFrigateHullActions::ExtractOre; + perform action dockToStation : MiningFrigateHullActions::DockToStation; + perform action checkAsteroidStatus : MiningFrigateHullActions::CheckAsteroidStatus; + perform action resupplyCapacitor : MiningFrigateHullActions::ResupplyCapacitor; + perform action activateMiningLaser : MiningFrigateHullActions::ActivateMiningLaser; // **Ports for COTS Modules** port highSlot1 : HighSlotPort; diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml index 19249f5..801b0ee 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml @@ -1,144 +1,11 @@ -package MiningFrigateHullUseCasesUsage { - - private import MiningFrigateHullUseCasesDef::*; - private import Domain::*; - - // **Use Case Usage: Withstand Incoming Damage** - use case withstandIncomingDamage : WithstandIncomingDamage { - first start; - - then include use case detectThreat : DetectThreat { - actor :>> pilotPod = withstandIncomingDamage::pilotPod; - } - - then include use case engageDefenses : EngageDefenses { - actor :>> pilotPod = withstandIncomingDamage::pilotPod; - actor :>> hostileShip = withstandIncomingDamage::hostileShip; - } - - then done; - } - - // **Use Case Usage: Navigate and Warp to Destinations** - use case navigateAndWarp : NavigateAndWarp { - first start; - - then include use case navigateToDestination : NavigateToDestination { - actor :>> pilotPod = navigateAndWarp::pilotPod; - } - - then done; - } - - // **Use Case Usage: Store and Transfer Mined Ore** - use case storeAndTransferOre : StoreAndTransferOre { - first start; - - then include use case transferOre : TransferOre { - actor :>> pilotPod = storeAndTransferOre::pilotPod; - actor :>> station = storeAndTransferOre::station; - } - - then done; - } - - // **Use Case Usage: Dock and Undock from Stations** - use case dockAndUndock : DockAndUndock { - first start; - - then include use case dockAtStation : DockAtStation { - actor :>> pilotPod = dockAndUndock::pilotPod; - actor :>> station = dockAndUndock::station; - } - - then done; - } - - // **Use Case Usage: Manage Energy Supply and Recharge** - use case manageEnergy : ManageEnergy { - first start; - - then include use case resupplyCapacitor : ResupplyCapacitor { - actor :>> pilotPod = manageEnergy::pilotPod; - actor :>> smallCapBatteryI = manageEnergy::smallCapBatteryI; - } - - then done; - } - - // **Use Case Usage: Support High, Medium, and Low Slot Modules** - use case supportModuleFitting : SupportModuleFitting { - first start; - - then include use case activateMiningLaser : ActivateMiningLaser { - actor :>> miningLaser = supportModuleFitting::miningLaser; - } - - then done; - } -} - - -package MiningFrigateHullUseCasesDef { +package MiningFrigateHullUseCases { private import MiningFrigateSolutionSpace::*; private import Domain::*; private import COTS::*; - // **Use Case: Withstand Incoming Damage** - use case def WithstandIncomingDamage { - subject hull : LogicalMiningFrigateHull; - actor hostileShip : Domain::HostileShip; - actor pilotPod : Domain::PilotPod; - - objective { - doc /* - * The Mining Frigate Hull shall sustain damage from hostile ships while ensuring pilot safety. - */ - } - } - - // **Use Case: Navigate and Warp to Destinations** - use case def NavigateAndWarp { - subject hull : LogicalMiningFrigateHull; - actor pilotPod : Domain::PilotPod; - - objective { - doc /* - * The Mining Frigate Hull shall navigate between celestial bodies using its onboard navigation system. - */ - } - } - - // **Use Case: Store and Transfer Mined Ore** - use case def StoreAndTransferOre { - subject hull : LogicalMiningFrigateHull; - actor pilotPod : Domain::PilotPod; - actor station : Domain::Station; - - objective { - doc /* - * The Mining Frigate Hull shall store extracted ore in its ore hold - * and transfer it to a station or fleet hauler when required. - */ - } - } - - // **Use Case: Dock and Undock from Stations** - use case def DockAndUndock { - subject hull : LogicalMiningFrigateHull; - actor pilotPod : Domain::PilotPod; - actor station : Domain::Station; - - objective { - doc /* - * The Mining Frigate Hull shall support docking and undocking operations at stations or other docking structures. - */ - } - } - // **Use Case: Manage Energy Supply and Recharge** - use case def ManageEnergy { + use case ManageEnergy { subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor smallCapBatteryI : SmallCapBatteryI; @@ -150,21 +17,8 @@ package MiningFrigateHullUseCasesDef { } } - // **Use Case: Support High, Medium, and Low Slot Modules** - use case def SupportModuleFitting { - subject hull : LogicalMiningFrigateHull; - actor pilotPod : Domain::PilotPod; - actor miningLaser : MinerI; - - objective { - doc /* - * The Mining Frigate Hull shall host configurable module slots for different mission profiles. - */ - } - } - - // **Use Case Definition: Detect Threat** - use case def DetectThreat { + // **Use Case: Detect Threat** + use case DetectThreat { subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; @@ -176,8 +30,8 @@ package MiningFrigateHullUseCasesDef { } } - // **Use Case Definition: Engage Defenses** - use case def EngageDefenses { + // **Use Case: Engage Defenses** + use case EngageDefenses { subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor hostileShip : Domain::HostileShip; @@ -190,8 +44,8 @@ package MiningFrigateHullUseCasesDef { } } - // **Use Case Definition: Navigate to Destination** - use case def NavigateToDestination { + // **Use Case: Navigate to Destination** + use case NavigateToDestination { subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; @@ -203,8 +57,8 @@ package MiningFrigateHullUseCasesDef { } } - // **Use Case Definition: Transfer Ore** - use case def TransferOre { + // **Use Case: Transfer Ore** + use case TransferOre { subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor station : Domain::Station; @@ -216,8 +70,8 @@ package MiningFrigateHullUseCasesDef { } } - // **Use Case Definition: Dock at Station** - use case def DockAtStation { + // **Use Case: Dock to Station** + use case DockToStation { subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor station : Domain::Station; @@ -230,8 +84,8 @@ package MiningFrigateHullUseCasesDef { } } - // **Use Case Definition: Resupply Capacitor** - use case def ResupplyCapacitor { + // **Use Case: Resupply Capacitor** + use case ResupplyCapacitor { subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor smallCapBatteryI : SmallCapBatteryI; @@ -243,8 +97,8 @@ package MiningFrigateHullUseCasesDef { } } - // **Use Case Definition: Activate Mining Laser** - use case def ActivateMiningLaser { + // **Use Case: Activate Mining Laser** + use case ActivateMiningLaser { subject hull : LogicalMiningFrigateHull; actor pilotPod : Domain::PilotPod; actor miningLaser : MinerI; From 84733c88ad6439e33c02b38c8a17a76d0355e563 Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Tue, 17 Jun 2025 16:32:34 +0200 Subject: [PATCH 12/15] amend actions --- .../LogicalArchitecture/MiningFrigate.sysml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml index 82367d3..8017db0 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml @@ -19,6 +19,7 @@ package MiningFrigateSolutionSpace { part logicalHull : LogicalMiningFrigateHull; // **COTS Modules (Ref Parts - Exchangeable)** + //the mining laser is available in three variants variation ref part miningLaser : MinerModule[2]{ variant 'Mining Laser EP-S Gaussian Scoped'; variant 'Mining Laser Particle Bore Compact'; @@ -55,7 +56,7 @@ package MiningFrigateSolutionSpace { modulePort ::> defensiveModule.lowSlot; } - //Three different configurations of mining frigatte are defined here + //Three different configurations of mining frigatte are defined here that base on an abstract frigate abstract part logicalMiningFrigateConfiguration : LogicalMiningFrigateConfiguration; part logicalNoviceMiningFrigatte : LogicalMiningFrigateConfiguration{ From b0ae8c24b6690fc6d7adca1d24bcd5ffcc5de879 Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:19:47 +0200 Subject: [PATCH 13/15] several corrections --- .../DomainModel/Domain.sysml | 7 +- .../DomainModel/MiningFrigate.sysml | 272 +++++++++--------- .../ActionsFrigateLogical.sysml | 26 ++ .../LogicalArchitecture/COTS.sysml | 7 + .../LogicalArchitecture/MiningFrigate.sysml | 115 -------- .../MiningFrigateLogical.sysml | 254 ++++++++++++++++ .../UseCases/OperationalUseCaseActions.sysml | 1 - 7 files changed, 423 insertions(+), 259 deletions(-) create mode 100644 models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml delete mode 100644 models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml create mode 100644 models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml diff --git a/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml b/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml index 8ce075a..f14d195 100644 --- a/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml +++ b/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml @@ -126,11 +126,8 @@ package Domain { */ } // % - //exhibits a predefined state - part miningFrigate : MiningFrigate::MiningFrigate [1..*] { - exhibit MiningFrigate::miningFrigatesStates { - in miningFrigates = miningFrigate; - } + part miningFrigate : MiningFrigate::MiningFrigate [1..*]{ + // Cause and Effect Occurrences timeslice miningRateIncreases; timeslice cargoCapacityIncreases; diff --git a/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml b/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml index 53403f5..ddbc4b7 100644 --- a/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml +++ b/models/example_EveOnlineMiningFrigate/DomainModel/MiningFrigate.sysml @@ -25,150 +25,147 @@ part sensorModule: SensorModule; // Configurable sensor array part oreHoldExpander: OreHoldExpander [0..2]; // Optional cargo expander module part capacitorBooster: CapacitorBooster [0..1]; // Configurable capacitor booster - part defenseTurret: DefenseTurret [0..*]; // Optional defense modules + part warpCoreStabilizer: WarpCoreStabilizer [0..*]; // Optional defense modules ref part cargo : Domain::CargoContainer [0..*]; ref part charge : Domain::Power; ref part drone : Domain::Drone [0..5]; port controlPort : ~Domain::PodPort; port dockingPort : ~Domain::DockingPort; - port DefensePort : ~Domain::ThreatPort; + port defensePort : ~Domain::ThreatPort; port asteroidOrePort : ~Domain::AsteroidOrePort; - port droneControlPort: ~Domain::DroneControllerPort; - - //actions declaration - action activateMiningLaser : ActivateMiningLaser { - } - + port droneControlPort: ~Domain::DroneControllerPort; } + part miningFrigate : MiningFrigate{ + // State Definition for the Mining Frigate + state miningFrigatesStates { + + entry; + then Docked; //boarding a ship is not modeled. + + state Packaged { + doc /* The mining frigate is packaged inside a station and can be cargoed. */ + } + state Parked { + doc /* The mining frigate is parked inside a station, but not boarded by a pod. */ + } + state Docked { + doc /* The mining frigate is inside a station, available for refitting, resupply, or cargo transfer. */ + } + state InGrid { + doc /* The mining frigate is in open space, near asteroids, stations, or other celestial objects. */ + } + state OnWarp { + doc /* The mining frigate is in warp, traveling between locations. */ + } + + transition docked_to_inGrid + first Docked + accept pilotPodUndockCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action undockFromStation : UndockFromStation {in undockCommand = pilotPodUndockCommandSig;} + then InGrid; + + transition inGrid_to_docked + first InGrid + accept pilotPodDockCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action dockToStation : DockToStation {in dockCommand = pilotPodDockCommandSig;} + then Docked; + + transition inGrid_to_onWarp + first InGrid + accept warpCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action executeWarpDrive: ExecuteWarpDrive {in warpCommand = warpCommandSig;} + then OnWarp; + + transition onWarp_to_inGrid + first OnWarp + accept when miningFrigate.warpBubbleEnd + then InGrid; + + //Internal transitions + transition unloadCargo + first Docked + accept unloadCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action transferOre : TransferOre {in unloadCommand = unloadCommandSig;} + then Docked; + + transition cycleMining + first InGrid + accept miningCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action activateMiningLaser : ActivateMiningLaser + then InGrid; + + transition scanThreats + first InGrid + accept scanCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action scanForThreats : ScanForThreats {in scanCommand = scanCommandSig;} + then InGrid; + + transition prioritizeThreat + first InGrid + accept threatSignatureSig : Domain::ScanSignature via miningFrigate.controlPort + do action prioritizeThreats : PrioritizeThreats {in detectedThreats = threatSignatureSig;} + then InGrid; + + transition deployDrones + first InGrid + accept droneCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action selectDronesForDeployment : SelectDronesForDeployment {in droneCommand = droneCommandSig;} + then InGrid; + + transition navigation + first InGrid + accept destinationCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action acceptDestination : AcceptDestination {in destinationCommand = destinationCommandSig;} + then InGrid; + + transition coursePlot + first InGrid + accept courseCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action plotOptimalCourse : PlotOptimalCourse + then InGrid; + + transition engagingPropulsion + first InGrid + accept propulsionCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action engagePropulsion : EngagePropulsion { in engagePropulsion = propulsionCommandSig;} + then InGrid; + + transition adjustingCourse + first InGrid + accept courseCorrectionSig : Domain::ShipCommand via miningFrigate.controlPort + do action monitorAndAdjustCourse : MonitorAndAdjustCourse + then InGrid; + + transition cargoVerification + first Docked + accept warehouseStatusCommandSig : Domain::StationCommand via miningFrigate.controlPort + do action verifyCargoTransfer : VerifyCargoTransfer {in warehouseStatusCommand = warehouseStatusCommandSig;} + then Docked; + + transition detectingThreat + first InGrid + accept threatScanCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action detectThreat : DetectThreat {in scanCommand = threatScanCommandSig;} + then InGrid; + + transition engagingDefenses + first InGrid + accept defenseCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action engageDefenses : EngageDefenses {in engageCommand = defenseCommandSig;} + then InGrid; + + transition resupplying + first Docked + accept shipStatusCommandSig : Domain::ShipCommand via miningFrigate.controlPort + do action verifyResupply : VerifyResupply + then Docked; + } + + } - part miningFrigate:MiningFrigate; - // State Definition for the Mining Frigate - state miningFrigatesStates { - in miningFrigates : MiningFrigate; - - entry; - then Docked; //boarding a ship is not modeled. - - state Packaged { - doc /* The mining frigate is packaged inside a station and can be cargoed. */ - } - state Parked { - doc /* The mining frigate is parked inside a station, but not boarded by a pod. */ - } - state Docked { - doc /* The mining frigate is inside a station, available for refitting, resupply, or cargo transfer. */ - } - state InGrid { - doc /* The mining frigate is in open space, near asteroids, stations, or other celestial objects. */ - } - state OnWarp { - doc /* The mining frigate is in warp, traveling between locations. */ - } - - transition docked_to_inGrid - first Docked - accept pilotPodUndockCommand : Domain::ShipCommand via miningFrigates.controlPort - do action undockFromStation : UndockFromStation {in undockCommand = pilotPodUndockCommand;} - then InGrid; - - transition inGrid_to_docked - first InGrid - accept pilotPodDockCommand : Domain::ShipCommand via miningFrigates.controlPort - do action dockToStation : DockToStation {in dockCommand = pilotPodDockCommand;} - then Docked; - - transition inGrid_to_onWarp - first InGrid - accept warpCommand : Domain::ShipCommand via miningFrigates.controlPort - do action executeWarpDrive : ExecuteWarpDrive - then OnWarp; - transition onWarp_to_inGrid - first OnWarp - accept when miningFrigates.warpBubbleEnd - then InGrid; - - //Internal transitions - transition unloadCargo - first Docked - accept unloadCommand : Domain::ShipCommand via miningFrigates.controlPort - do action transferOre : TransferOre - then Docked; - - transition cycleMining - first InGrid - accept miningCommand : Domain::ShipCommand via miningFrigates.controlPort - do action activateMiningLaser : ActivateMiningLaser - then InGrid; - - transition scanThreats - first InGrid - accept scanCommand : Domain::ShipCommand via miningFrigates.controlPort - do action scanForThreats : ScanForThreats - then InGrid; - - transition prioritizeThreat - first InGrid - accept threatSignature : Domain::ScanSignature via miningFrigates.controlPort - do action prioritizeThreats : PrioritizeThreats - then InGrid; - - transition deployDrones - first InGrid - accept droneCommand : Domain::ShipCommand via miningFrigates.controlPort - do action selectDronesForDeployment : SelectDronesForDeployment - then InGrid; - - transition navigation - first InGrid - accept destinationCommand : Domain::ShipCommand via miningFrigates.controlPort - do action acceptDestination : AcceptDestination - then InGrid; - - transition coursePlot - first InGrid - accept courseCommand : Domain::ShipCommand via miningFrigates.controlPort - do action plotOptimalCourse : PlotOptimalCourse - then InGrid; - - transition engagePropulsion - first InGrid - accept propulsionCommand : Domain::ShipCommand via miningFrigates.controlPort - do action engagePropulsion : EngagePropulsion - then InGrid; - - transition adjustCourse - first InGrid - accept courseCorrection : Domain::ShipCommand via miningFrigates.controlPort - do action monitorAndAdjustCourse : MonitorAndAdjustCourse - then InGrid; - - transition cargoVerification - first Docked - accept warehouseStatusCommand : Domain::StationCommand via miningFrigates.controlPort - do action verifyCargoTransfer : VerifyCargoTransfer - then Docked; - - transition detectThreat - first InGrid - accept threatScanCommand : Domain::ShipCommand via miningFrigates.controlPort - do action detectThreat : DetectThreat - then InGrid; - - transition engageDefense - first InGrid - accept defenseCommand : Domain::ShipCommand via miningFrigates.controlPort - do action engageDefenses : EngageDefenses - then InGrid; - - transition resupply - first Docked - accept shipStatusCommand : Domain::ShipCommand via miningFrigates.controlPort - do action verifyResupply : VerifyResupply - then Docked; - } // Definitions for individual parts of the mining frigate part def SpaceshipModule { @@ -217,13 +214,12 @@ attribute optimalRange : Real; // Optimal engagement range } - part def DroneBay { - attribute maxDrones : Integer; // Maximum drones stored - } - part def NavigationModule { attribute agilityBonus : Real; // Improves ship align time attribute warpSpeedBonus : Real; // Boost to warp speed } -} \ No newline at end of file + part def WarpCoreStabilizer { + attribute warpCoreStrenght : Real; // Improves ship align time + } + } \ No newline at end of file diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml new file mode 100644 index 0000000..e7fd0a0 --- /dev/null +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml @@ -0,0 +1,26 @@ +package MiningFrigateActions_logical { + + //import packages + private import Domain::*; + private import ScalarValues::*; + private import OperationalUseCaseActions::*; + + //the actions of the LogicalMiningFrigateConfiguration are inherited form the problem space and redefined for the solution space + action def UndockFromStation_logical :> OperationalUseCaseActions::UndockFromStation; + action def DockToStation_logical :> OperationalUseCaseActions::DockToStation; + action def ExecuteWarpDrive_logical :> OperationalUseCaseActions::ExecuteWarpDrive; + action def TransferOre_logical :> OperationalUseCaseActions::TransferOre; + action def ActivateMiningLaser_logical :> OperationalUseCaseActions::ActivateMiningLaser; + action def ScanForThreats_logical :> OperationalUseCaseActions::ScanForThreats; + action def PrioritizeThreats_logical :> OperationalUseCaseActions::PrioritizeThreats; + action def SelectDronesForDeployment_logical :> OperationalUseCaseActions::SelectDronesForDeployment; + action def AcceptDestination_logical :> OperationalUseCaseActions::AcceptDestination; + action def PlotOptimalCourse_logical :> OperationalUseCaseActions::PlotOptimalCourse; + action def EngagePropulsion_logical :> OperationalUseCaseActions::EngagePropulsion; + action def MonitorAndAdjustCourse_logical :> OperationalUseCaseActions::MonitorAndAdjustCourse; + action def VerifyCargoTransfer_logical :> OperationalUseCaseActions::VerifyCargoTransfer; + action def DetectThreat_logical :> OperationalUseCaseActions::DetectThreat; + action def EngageDefenses_logical :> OperationalUseCaseActions::EngageDefenses; + action def VerifyResupply_logical :> OperationalUseCaseActions::VerifyResupply; + +} \ No newline at end of file diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml index 7854e3b..6d80066 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml @@ -101,4 +101,11 @@ port lowSlot : ~LowSlotPort; } + + part def DroneLinkAugmentor :> SimpleFrigateComponent { + doc /* These modules extend your drone control range. Drone Link Augmentors + * can be useful for drone ships and ships with nothing else to fit in their spare highslots. */ + + port highSlot : ~HighSlotPort; + } } \ No newline at end of file diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml deleted file mode 100644 index 8017db0..0000000 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigate.sysml +++ /dev/null @@ -1,115 +0,0 @@ -package MiningFrigateSolutionSpace { - - private import Domain::*; - private import ScalarValues::*; - private import COTS::*; - private import StdPortsAndInterfaces::*; - private import ParametersOfInterestMetadata::*; - private import FrigateRollupAnalysis::*; - private import MiningFrigateHullActions::*; - - //allocate the logical mining frigate to the domain mining frigte - allocate logicalMiningFrigateConfiguration to MiningFrigate::miningFrigate; - - // **Mining Frigate as the Core System** - abstract part def LogicalMiningFrigateConfiguration :> CompositeFrigateComponent { - doc /* The Mining Frigate consists of a fixed hull structure with modular (COTS) components - * that can be replaced or upgraded depending on operational needs. */ - - part logicalHull : LogicalMiningFrigateHull; - - // **COTS Modules (Ref Parts - Exchangeable)** - //the mining laser is available in three variants - variation ref part miningLaser : MinerModule[2]{ - variant 'Mining Laser EP-S Gaussian Scoped'; - variant 'Mining Laser Particle Bore Compact'; - variant minerI : MinerI; - } - ref part propulsionModule : Afterburner[0..1]; - ref part shieldModule : SmallShieldExtenderI[0..1]; - ref part capacitorModule : SmallCapBatteryI[0..1]; - ref part sensorModule : SurveyScannerI[0..1]; - ref part defensiveModule : WarpCoreStabilizerI[0..2]; - - interface highSlotInterface1 : HighSlotInterface connect - hullPort ::> logicalHull.highSlot1 to - modulePort ::> miningLaser.highSlot; - - interface highSlotInterface2 : HighSlotInterface connect - hullPort ::> logicalHull.highSlot2 to - modulePort ::> miningLaser.highSlot; - - interface mediumSlotInterface1 : MediumSlotInterface connect - hullPort ::> logicalHull.mediumSlot1 to - modulePort ::> propulsionModule.mediumSlot; - - interface mediumSlotInterface2 : MediumSlotInterface connect - hullPort ::> logicalHull.mediumSlot2 to - modulePort ::> shieldModule.mediumSlot; - - interface lowSlotInterface1 : LowSlotInterface connect - hullPort ::> logicalHull.lowSlot1 to - modulePort ::> defensiveModule.lowSlot; - - interface lowSlotInterface2 : LowSlotInterface connect - hullPort ::> logicalHull.lowSlot2 to - modulePort ::> defensiveModule.lowSlot; - } - - //Three different configurations of mining frigatte are defined here that base on an abstract frigate - abstract part logicalMiningFrigateConfiguration : LogicalMiningFrigateConfiguration; - - part logicalNoviceMiningFrigatte : LogicalMiningFrigateConfiguration{ - part redefines miningLaser = miningLaser::minerI; - } - - part logicalTrainerMiningFrigate : LogicalMiningFrigateConfiguration{ - part redefines miningLaser = miningLaser::'Mining Laser Particle Bore Compact'; - } - - part logicalOperationalMiningFrigate : LogicalMiningFrigateConfiguration{ - part redefines miningLaser = miningLaser::'Mining Laser EP-S Gaussian Scoped'; - } - - // **Mining Frigate Hull (Black Box with Ports)** - part def LogicalMiningFrigateHull :> SimpleFrigateComponent { - doc /* The Venture-class Mining Frigate hull includes integrated features such as - * a built-in warp core stabilizer, ore hold, and base resistances. */ - - attribute hullHP : Real = 400.0; - attribute armorHP : Real = 400.0; - attribute shieldHP : Real = 700.0; - attribute oreHoldCapacity : Real = 5000.0; - attribute maxVelocity : Real = 335.0; - attribute warpSpeed : Real = 5.0; - attribute capacitorCapacity : Real = 250.0; - - // Performed actions of the hull (executed by the ship's integrated systems) - perform action manageEnergy : MiningFrigateHullActions::ManageEnergy; - perform action detectThreat : MiningFrigateHullActions::DetectThreat; - perform action engageDefenses : MiningFrigateHullActions::EngageDefenses; - perform action navigateToDestination : MiningFrigateHullActions::NavigateToDestination; - perform action reportToPilot : MiningFrigateHullActions::ReportToPilot; - perform action transferOre : MiningFrigateHullActions::TransferOre; - perform action extractOre : MiningFrigateHullActions::ExtractOre; - perform action dockToStation : MiningFrigateHullActions::DockToStation; - perform action checkAsteroidStatus : MiningFrigateHullActions::CheckAsteroidStatus; - perform action resupplyCapacitor : MiningFrigateHullActions::ResupplyCapacitor; - perform action activateMiningLaser : MiningFrigateHullActions::ActivateMiningLaser; - - // **Ports for COTS Modules** - port highSlot1 : HighSlotPort; - port highSlot2 : HighSlotPort; - port mediumSlot1 : MediumSlotPort; - port mediumSlot2 : MediumSlotPort; - port lowSlot1 : LowSlotPort; - port lowSlot2 : LowSlotPort; - } - - // **Power and Control Interfaces Items inherited from the standardPorts items** - item def VenturePowerSupply :> PowerSupply ; - item def VentureHighSlotCommand :> HighSlotCommand ; - item def VentureMediumSlotCommand :> MediumSlotCommand ; - item def VentureLowSlotCommand :> LowSlotCommand ; - -} diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml new file mode 100644 index 0000000..7a757a5 --- /dev/null +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml @@ -0,0 +1,254 @@ +package MiningFrigateSolutionSpace { + + private import Domain::*; + private import MiningFrigate::*; + private import ScalarValues::*; + private import COTS::*; + private import StdPortsAndInterfaces::*; + private import ParametersOfInterestMetadata::*; + private import FrigateRollupAnalysis::*; + private import MiningFrigateHullActions::*; + private import MiningFrigateActions_logical::*; + + //The LogicalMiningFrigate is a spezialisation of the MiningFrigate and inherits all its features + abstract part def LogicalMiningFrigateConfiguration :> CompositeFrigateComponent, MiningFrigate::MiningFrigate { + doc /* The Mining Frigate consists of a fixed hull structure with modular (COTS) components + * that can be replaced or upgraded depending on operational needs. */ + + part logicalHull : LogicalMiningFrigateHull :> MiningFrigate::miningFrigate.coreSystem ; + + //The parts of the LogicalMiningFrigate are a subset of the parts of the MiningFrigate + // COTS Modules (Ref Parts - Exchangeable) + //the mining laser is available in three variants + variation ref part miningLaser : MinerModule[2] :> MiningFrigate::miningFrigate.miningLaser { + variant 'Mining Laser EP-S Gaussian Scoped'; + variant 'Mining Laser Particle Bore Compact'; + variant minerI : MinerI; + } + ref part propulsionModule : Afterburner[0..1] :> MiningFrigate::miningFrigate.propulsionModule; + ref part shieldModule : SmallShieldExtenderI[0..1] :> MiningFrigate::miningFrigate.shieldModule; + ref part capacitorModule : SmallCapBatteryI[0..1] :> MiningFrigate::miningFrigate.capacitorBooster; + ref part sensorModule : SurveyScannerI[0..1] :> MiningFrigate::miningFrigate.sensorModule; + ref part warpCoreStabilizer : WarpCoreStabilizerI[0..2] :> MiningFrigate::miningFrigate.warpCoreStabilizer; + + //internal conexions between parts of the LogicalMiningFrigateConfiguration + interface highSlotInterface1 : HighSlotInterface connect + hullPort ::> logicalHull.highSlot1 to + modulePort ::> miningLaser.highSlot; + + interface highSlotInterface2 : HighSlotInterface connect + hullPort ::> logicalHull.highSlot2 to + modulePort ::> miningLaser.highSlot; + + interface mediumSlotInterface1 : MediumSlotInterface connect + hullPort ::> logicalHull.mediumSlot1 to + modulePort ::> propulsionModule.mediumSlot; + + interface mediumSlotInterface2 : MediumSlotInterface connect + hullPort ::> logicalHull.mediumSlot2 to + modulePort ::> shieldModule.mediumSlot; + + interface lowSlotInterface1 : LowSlotInterface connect + hullPort ::> logicalHull.lowSlot1 to + modulePort ::> warpCoreStabilizer.lowSlot; + + //the ports of the LogicalMiningFrigateConfiguration are bound to the ports of the LogicalMiningFriagteHull + //the external ports of LogicalMiningFrigateConfiguration are not redefined because they must be same as the ones at the problem space. + bind controlPort = logicalHull.hullControlPort; + bind dockingPort = logicalHull.hullDockingPort; + bind defensePort = logicalHull.hullDefensePort; + bind droneControlPort = logicalHull.hullDroneControlPort; + + } + + //Three different configurations of mining frigatte are defined here that base on an abstract frigate + abstract part logicalMiningFrigateConfiguration : LogicalMiningFrigateConfiguration { + + //the state of the LogicalMiningFrigateConfiguration is redefined from the problem space + state logicalMiningFrigateStates :>> MiningFrigate::miningFrigate.miningFrigatesStates { + + entry; + then Docked; //boarding a ship is not modeled. + + state Packaged { + doc /* The mining frigate is packaged inside a station and can be cargoed. */ + } + state Parked { + doc /* The mining frigate is parked inside a station, but not boarded by a pod. */ + } + state Docked { + doc /* The mining frigate is inside a station, available for refitting, resupply, or cargo transfer. */ + } + state InGrid { + doc /* The mining frigate is in open space, near asteroids, stations, or other celestial objects. */ + } + state OnWarp { + doc /* The mining frigate is in warp, traveling between locations. */ + } + + transition docked_to_inGrid + first Docked + accept pilotPodUndockCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action undockFromStation_logical : UndockFromStation_logical {in undockCommand = pilotPodUndockCommandSig;} + then InGrid; + + transition inGrid_to_docked + first InGrid + accept pilotPodDockCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action dockToStation_logical : DockToStation_logical {in dockCommand = pilotPodDockCommandSig;} + then Docked; + + transition inGrid_to_onWarp + first InGrid + accept warpCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action executeWarpDrive_logical : ExecuteWarpDrive_logical {in warpCommand = warpCommandSig;} + then OnWarp; + + transition onWarp_to_inGrid + first OnWarp + accept when logicalMiningFrigateConfiguration.warpBubbleEnd + then InGrid; + + //Internal transitions + transition unloadCargo + first Docked + accept unloadCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action transferOre_logical : TransferOre_logical {in unloadCommand = unloadCommandSig;} + then Docked; + + transition cycleMining + first InGrid + accept miningCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action activateMiningLaser_logical : ActivateMiningLaser_logical + then InGrid; + + transition scanThreats + first InGrid + accept scanCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action scanForThreats_logical : ScanForThreats_logical {in scanCommand = scanCommandSig;} + then InGrid; + + transition prioritizeThreat + first InGrid + accept threatSignatureSig : Domain::ScanSignature via logicalMiningFrigateConfiguration.controlPort + do action prioritizeThreats_logical : PrioritizeThreats_logical {in detectedThreats = threatSignatureSig;} + then InGrid; + + transition deployDrones + first InGrid + accept droneCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action selectDronesForDeployment_logical : SelectDronesForDeployment_logical {in droneCommand = droneCommandSig;} + then InGrid; + + transition navigation + first InGrid + accept destinationCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action acceptDestination_logical : AcceptDestination_logical {in destinationCommand = destinationCommandSig;} + then InGrid; + + transition coursePlot + first InGrid + accept courseCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action plotOptimalCourse_logical : PlotOptimalCourse_logical + then InGrid; + + transition engagingPropulsion + first InGrid + accept propulsionCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action engagePropulsion_logical : EngagePropulsion_logical { in engagePropulsion = propulsionCommandSig;} + then InGrid; + + transition adjustingCourse + first InGrid + accept courseCorrectionSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action monitorAndAdjustCourse_logical : MonitorAndAdjustCourse_logical + then InGrid; + + transition cargoVerification + first Docked + accept warehouseStatusCommandSig : Domain::StationCommand via logicalMiningFrigateConfiguration.controlPort + do action verifyCargoTransfer_logical : VerifyResupply_logical {in warehouseStatusCommand = warehouseStatusCommandSig;} + then Docked; + + transition detectingThreat + first InGrid + accept threatScanCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action detectThreat_logical : DetectThreat_logical {in scanCommand = threatScanCommandSig;} + then InGrid; + + transition engagingDefenses + first InGrid + accept defenseCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action engageDefenses_logical : EngageDefenses_logical {in engageCommand = defenseCommandSig;} + then InGrid; + + transition resupplying + first Docked + accept shipStatusCommandSig : Domain::ShipCommand via logicalMiningFrigateConfiguration.controlPort + do action verifyResupply_logical : VerifyCargoTransfer_logical + then Docked; + } + + } + + part logicalNoviceMiningFrigatte :> logicalMiningFrigateConfiguration{ + part redefines miningLaser = miningLaser::minerI; + } + + part logicalTrainerMiningFrigate :> logicalMiningFrigateConfiguration{ + part redefines miningLaser = miningLaser::'Mining Laser Particle Bore Compact'; + } + + part logicalFieldMiningFrigate :> logicalMiningFrigateConfiguration{ + part redefines miningLaser = miningLaser::'Mining Laser EP-S Gaussian Scoped'; + } + + //Mining Frigate Hull (Black Box with Ports) + part def LogicalMiningFrigateHull :> SimpleFrigateComponent { + doc /* The Venture-class Mining Frigate hull includes integrated features such as + * a built-in warp core stabilizer, ore hold, and base resistances. */ + + attribute hullHP : Real = 400.0; + attribute armorHP : Real = 400.0; + attribute shieldHP : Real = 700.0; + attribute oreHoldCapacity : Real = 5000.0; + attribute maxVelocity : Real = 335.0; + attribute warpSpeed : Real = 5.0; + attribute capacitorSize : Real = 250.0; + attribute warpCoreStrenght : Real = 2.0; + + //Performed actions of the hull (executed by the ship's integrated systems) + perform action manageEnergy : MiningFrigateHullActions::ManageEnergy; + perform action detectThreat : MiningFrigateHullActions::DetectThreat; + perform action engageDefenses : MiningFrigateHullActions::EngageDefenses; + perform action navigateToDestination : MiningFrigateHullActions::NavigateToDestination; + perform action reportToPilot : MiningFrigateHullActions::ReportToPilot; + perform action transferOre : MiningFrigateHullActions::TransferOre; + perform action extractOre : MiningFrigateHullActions::ExtractOre; + perform action dockToStation : MiningFrigateHullActions::DockToStation; + perform action checkAsteroidStatus : MiningFrigateHullActions::CheckAsteroidStatus; + perform action resupplyCapacitor : MiningFrigateHullActions::ResupplyCapacitor; + perform action activateMiningLaser : MiningFrigateHullActions::ActivateMiningLaser; + + //Ports for COTS Modules + port highSlot1 : HighSlotPort; + port highSlot2 : HighSlotPort; + port mediumSlot1 : MediumSlotPort; + port mediumSlot2 : MediumSlotPort; + port lowSlot1 : LowSlotPort; + port lowSlot2 : LowSlotPort; + + //Ports bound to the LogicalMiningFrigateConfiguration + port hullControlPort : ~Domain::PodPort; + port hullDockingPort : ~Domain::DockingPort; + port hullDefensePort : ~Domain::ThreatPort; + port hullDroneControlPort: ~Domain::DroneControllerPort; + } + + //Power and Control Interfaces Items inherited from the standardPorts items + item def VenturePowerSupply :> PowerSupply ; + item def VentureHighSlotCommand :> HighSlotCommand ; + item def VentureMediumSlotCommand :> MediumSlotCommand ; + item def VentureLowSlotCommand :> LowSlotCommand ; + +} diff --git a/models/example_EveOnlineMiningFrigate/UseCases/OperationalUseCaseActions.sysml b/models/example_EveOnlineMiningFrigate/UseCases/OperationalUseCaseActions.sysml index 60fb37d..d3f9ed3 100644 --- a/models/example_EveOnlineMiningFrigate/UseCases/OperationalUseCaseActions.sysml +++ b/models/example_EveOnlineMiningFrigate/UseCases/OperationalUseCaseActions.sysml @@ -2,7 +2,6 @@ package OperationalUseCaseActions { private import Domain::*; private import ScalarValues::*; - private import MiningFrigate::*; // Operational Action Definitions for the Mining Frigate From f20464d83ccb4a9e05b3d579ab611219058bbbfe Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Thu, 26 Jun 2025 13:03:34 +0200 Subject: [PATCH 14/15] several adjustments --- .../DomainModel/Domain.sysml | 2 +- .../LogicalArchitecture/ActionsFrigateLogical.sysml | 2 +- .../LogicalArchitecture/ActionsHull.sysml | 13 ++++--------- .../LogicalArchitecture/COTS.sysml | 7 +++++++ .../LogicalArchitecture/MiningFrigateLogical.sysml | 6 +++--- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml b/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml index f14d195..eb59629 100644 --- a/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml +++ b/models/example_EveOnlineMiningFrigate/DomainModel/Domain.sysml @@ -285,7 +285,7 @@ package Domain { out item droneReport : DroneReport; } - // Interface definition + // Interfaces definition interface def CommandIF { end controlSend : PodPort; end controlReceive : ~PodPort; diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml index e7fd0a0..846d2b0 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml @@ -5,7 +5,7 @@ package MiningFrigateActions_logical { private import ScalarValues::*; private import OperationalUseCaseActions::*; - //the actions of the LogicalMiningFrigateConfiguration are inherited form the problem space and redefined for the solution space + //action parameters are inherited action def UndockFromStation_logical :> OperationalUseCaseActions::UndockFromStation; action def DockToStation_logical :> OperationalUseCaseActions::DockToStation; action def ExecuteWarpDrive_logical :> OperationalUseCaseActions::ExecuteWarpDrive; diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml index 17e5e49..142621d 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml @@ -2,6 +2,7 @@ package MiningFrigateHullActions { private import Domain::*; private import MiningFrigateSolutionSpace::*; + private import COTS::*; // **Action: Manage Energy Supply and Recharge** action def ManageEnergy { @@ -63,9 +64,9 @@ package MiningFrigateHullActions { decide; if checkAsteroidStatus.asteroidStatus == "depleted" then reportDepletion; - else continueMining; + else mineOre; - action continueMining : ExtractOre { + perform action mineOre references COTS::MinerModule::extractOre { in miningCommand; out miningStatus; } @@ -74,7 +75,7 @@ package MiningFrigateHullActions { in asteroidStatus; out report : Domain::ShipReport;} - bind continueMining.miningStatus = miningStatus; + bind mineOre.miningStatus = miningStatus; } // **Action: Check Asteroid Status** @@ -83,12 +84,6 @@ package MiningFrigateHullActions { out asteroidStatus : Domain::ShipReport; } - // **Action: Extract Ore (Standard Mining)** - action def ExtractOre { - in miningCommand : Domain::ShipCommand; - out miningStatus : Domain::ShipReport; - } - // **Action: Report Asteroid Depletion to Pilot** action def ReportToPilot { in asteroidStatus : Domain::ShipReport; diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml index 6d80066..274495a 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml @@ -16,7 +16,14 @@ redefines powerUsage; port highSlot : ~HighSlotPort; + + // **Action: Extract Ore + perform action extractOre { + in miningCommand : Domain::ShipCommand; + out miningStatus : Domain::ShipReport; + } } + part def 'EP-S Gaussian Scoped Mining Laser' :> MinerModule { doc /* Standard mining laser used on mining frigates for ore extraction. */ redefines miningYield : Real = 50.0; diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml index 7a757a5..fed1675 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml @@ -61,7 +61,7 @@ package MiningFrigateSolutionSpace { } - //Three different configurations of mining frigatte are defined here that base on an abstract frigate + //An abstract frigate is defined here, that will be used as a basis to define possible frigate configurations. abstract part logicalMiningFrigateConfiguration : LogicalMiningFrigateConfiguration { //the state of the LogicalMiningFrigateConfiguration is redefined from the problem space @@ -190,7 +190,8 @@ package MiningFrigateSolutionSpace { } } - + + //Three different configurations of mining frigatte are defined here that base on an abstract frigate part logicalNoviceMiningFrigatte :> logicalMiningFrigateConfiguration{ part redefines miningLaser = miningLaser::minerI; } @@ -224,7 +225,6 @@ package MiningFrigateSolutionSpace { perform action navigateToDestination : MiningFrigateHullActions::NavigateToDestination; perform action reportToPilot : MiningFrigateHullActions::ReportToPilot; perform action transferOre : MiningFrigateHullActions::TransferOre; - perform action extractOre : MiningFrigateHullActions::ExtractOre; perform action dockToStation : MiningFrigateHullActions::DockToStation; perform action checkAsteroidStatus : MiningFrigateHullActions::CheckAsteroidStatus; perform action resupplyCapacitor : MiningFrigateHullActions::ResupplyCapacitor; From 00f5701399d423cfb18eab1ba2c79a04b8edb24c Mon Sep 17 00:00:00 2001 From: Hugo Ormo <118672247+hugoormo@users.noreply.github.com> Date: Fri, 27 Jun 2025 14:33:01 +0200 Subject: [PATCH 15/15] refine actions --- .../ActionsFrigateLogical.sysml | 20 ++++++- .../LogicalArchitecture/ActionsHull.sysml | 35 +++---------- .../LogicalArchitecture/COTS.sysml | 17 ++++-- .../MiningFrigateHull.sysml | 52 +++++++++++++++++++ .../MiningFrigateLogical.sysml | 48 +---------------- .../LogicalArchitecture/UseCasesHull.sysml | 1 + .../UseCases/OperationalUseCaseActions.sysml | 2 + 7 files changed, 94 insertions(+), 81 deletions(-) create mode 100644 models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateHull.sysml diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml index 846d2b0..6c27b54 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsFrigateLogical.sysml @@ -3,14 +3,30 @@ package MiningFrigateActions_logical { //import packages private import Domain::*; private import ScalarValues::*; - private import OperationalUseCaseActions::*; + private import OperationalUseCaseActions::*; + private import COTS::*; //action parameters are inherited + + //Activate Mining Laser + action def PowerupHighPowerModule {in activateMiningLaser : Domain::ShipCommand; out highPowerSupply : Real; } + action def ActivateLaserTurret {in highPowerSupply : Real; in miningLaserTarget : COTS::ModuleCommand; out minigLaserReport : COTS::ModuleReport; } + action def ManageReports {in moduleReport : COTS::ModuleReport; out shipReport : Domain::ShipReport;} + action def ActivateMiningLaser_logical :> OperationalUseCaseActions::ActivateMiningLaser; + action activateMiningLaser_logical : ActivateMiningLaser_logical { + bind powerupHighPowerModule.activateMiningLaser = activateMiningLaser; + action powerupHighPowerModule : PowerupHighPowerModule {in activateMiningLaser : Domain::ShipCommand; out highPowerSupply; } + flow powerupHighPowerModule.highPowerSupply to activateLaserTurret.highPowerSupply; + action activateLaserTurret : ActivateLaserTurret {in highPowerSupply; in miningLaserTarget; out miningLaserReport; } + flow activateLaserTurret.miningLaserReport to manageLaserTurretReport.laserModuleReport; + action manageLaserTurretReport : ManageReports {in laserModuleReport : COTS::ModuleReport; out shipMiningReport : Domain::ShipReport;} + bind manageLaserTurretReport.shipMiningReport = miningCycleReport; + } + action def UndockFromStation_logical :> OperationalUseCaseActions::UndockFromStation; action def DockToStation_logical :> OperationalUseCaseActions::DockToStation; action def ExecuteWarpDrive_logical :> OperationalUseCaseActions::ExecuteWarpDrive; action def TransferOre_logical :> OperationalUseCaseActions::TransferOre; - action def ActivateMiningLaser_logical :> OperationalUseCaseActions::ActivateMiningLaser; action def ScanForThreats_logical :> OperationalUseCaseActions::ScanForThreats; action def PrioritizeThreats_logical :> OperationalUseCaseActions::PrioritizeThreats; action def SelectDronesForDeployment_logical :> OperationalUseCaseActions::SelectDronesForDeployment; diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml index 142621d..0231aa2 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/ActionsHull.sysml @@ -2,8 +2,15 @@ package MiningFrigateHullActions { private import Domain::*; private import MiningFrigateSolutionSpace::*; + private import MiningFrigateActions_logical::*; private import COTS::*; + // **Action: Activate Mining Laser** + action def PowerupHighPowerModule :> MiningFrigateActions_logical::PowerupHighPowerModule { + in miningCommand : Domain::ShipCommand; + out miningStatus : Domain::ShipReport; + } + // **Action: Manage Energy Supply and Recharge** action def ManageEnergy { in rechargeCommand : Domain::ShipCommand; @@ -50,34 +57,6 @@ package MiningFrigateHullActions { out rechargeStatus : Domain::ShipReport; } - // **Action: Activate Mining Laser** - action def ActivateMiningLaser { - in miningCommand : Domain::ShipCommand; - out miningStatus : Domain::ShipReport; - - bind checkAsteroidStatus.miningCommand = miningCommand; - - action checkAsteroidStatus : CheckAsteroidStatus { - in miningCommand; - out asteroidStatus; - } - - decide; - if checkAsteroidStatus.asteroidStatus == "depleted" then reportDepletion; - else mineOre; - - perform action mineOre references COTS::MinerModule::extractOre { - in miningCommand; - out miningStatus; - } - - action reportDepletion : ReportToPilot { - in asteroidStatus; - out report : Domain::ShipReport;} - - bind mineOre.miningStatus = miningStatus; - } - // **Action: Check Asteroid Status** action def CheckAsteroidStatus { in miningCommand : Domain::ShipCommand; diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml index 274495a..f74d819 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/COTS.sysml @@ -4,8 +4,16 @@ private import StdPortsAndInterfaces::*; private import FrigateRollupAnalysis::*; - // **COTS Module Definitions with Conjugated Ports** - + //COTS items + item def ModuleCommand { + attribute type: String; + } + item def ModuleReport { + attribute type: String; + } + + + // COTS Module Definitions with Conjugated Ports** abstract part def MinerModule :> SimpleFrigateComponent { doc /* Standard mining laser used on mining frigates for ore extraction. */ attribute miningYield : Real; @@ -19,8 +27,9 @@ // **Action: Extract Ore perform action extractOre { - in miningCommand : Domain::ShipCommand; - out miningStatus : Domain::ShipReport; + in miningLaserPowerSupply : Real; + in miningLaserTarget : ModuleCommand; + out miningLaserStatus : ModuleReport; } } diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateHull.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateHull.sysml new file mode 100644 index 0000000..26fa629 --- /dev/null +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateHull.sysml @@ -0,0 +1,52 @@ +package MiningFrigateHull { + + private import Domain::*; + private import MiningFrigate::*; + private import ScalarValues::*; + private import COTS::*; + private import StdPortsAndInterfaces::*; + private import FrigateRollupAnalysis::*; + private import MiningFrigateActions_logical::*; + + //Mining Frigate Hull (Black Box with Ports) + part def LogicalMiningFrigateHull :> SimpleFrigateComponent { + doc /* The Venture-class Mining Frigate hull includes integrated features such as + * a built-in warp core stabilizer, ore hold, and base resistances. */ + + attribute hullHP : Real = 400.0; + attribute armorHP : Real = 400.0; + attribute shieldHP : Real = 700.0; + attribute oreHoldCapacity : Real = 5000.0; + attribute maxVelocity : Real = 335.0; + attribute warpSpeed : Real = 5.0; + attribute capacitorSize : Real = 250.0; + attribute warpCoreStrenght : Real = 2.0; + + //Performed actions of the hull (executed by the ship's integrated systems) + + perform activateMiningLaser_logical.activateLaserTurret; + //perform action manageEnergy : MiningFrigateHullActions::ManageEnergy; + //perform action detectThreat : MiningFrigateHullActions::DetectThreat; + //perform action engageDefenses : MiningFrigateHullActions::EngageDefenses; + //perform action navigateToDestination : MiningFrigateHullActions::NavigateToDestination; + //perform action reportToPilot : MiningFrigateHullActions::ReportToPilot; + //perform action transferOre : MiningFrigateHullActions::TransferOre; + //perform action dockToStation : MiningFrigateHullActions::DockToStation; + //perform action checkAsteroidStatus : MiningFrigateHullActions::CheckAsteroidStatus; + //perform action resupplyCapacitor : MiningFrigateHullActions::ResupplyCapacitor; + + //Ports for COTS Modules + port highSlot1 : HighSlotPort; + port highSlot2 : HighSlotPort; + port mediumSlot1 : MediumSlotPort; + port mediumSlot2 : MediumSlotPort; + port lowSlot1 : LowSlotPort; + port lowSlot2 : LowSlotPort; + + //Ports bound to the LogicalMiningFrigateConfiguration + port hullControlPort : ~Domain::PodPort; + port hullDockingPort : ~Domain::DockingPort; + port hullDefensePort : ~Domain::ThreatPort; + port hullDroneControlPort: ~Domain::DroneControllerPort; + } +} \ No newline at end of file diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml index fed1675..94565a8 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/MiningFrigateLogical.sysml @@ -9,6 +9,7 @@ package MiningFrigateSolutionSpace { private import FrigateRollupAnalysis::*; private import MiningFrigateHullActions::*; private import MiningFrigateActions_logical::*; + private import MiningFrigateHull::*; //The LogicalMiningFrigate is a spezialisation of the MiningFrigate and inherits all its features abstract part def LogicalMiningFrigateConfiguration :> CompositeFrigateComponent, MiningFrigate::MiningFrigate { @@ -203,52 +204,5 @@ package MiningFrigateSolutionSpace { part logicalFieldMiningFrigate :> logicalMiningFrigateConfiguration{ part redefines miningLaser = miningLaser::'Mining Laser EP-S Gaussian Scoped'; } - - //Mining Frigate Hull (Black Box with Ports) - part def LogicalMiningFrigateHull :> SimpleFrigateComponent { - doc /* The Venture-class Mining Frigate hull includes integrated features such as - * a built-in warp core stabilizer, ore hold, and base resistances. */ - - attribute hullHP : Real = 400.0; - attribute armorHP : Real = 400.0; - attribute shieldHP : Real = 700.0; - attribute oreHoldCapacity : Real = 5000.0; - attribute maxVelocity : Real = 335.0; - attribute warpSpeed : Real = 5.0; - attribute capacitorSize : Real = 250.0; - attribute warpCoreStrenght : Real = 2.0; - - //Performed actions of the hull (executed by the ship's integrated systems) - perform action manageEnergy : MiningFrigateHullActions::ManageEnergy; - perform action detectThreat : MiningFrigateHullActions::DetectThreat; - perform action engageDefenses : MiningFrigateHullActions::EngageDefenses; - perform action navigateToDestination : MiningFrigateHullActions::NavigateToDestination; - perform action reportToPilot : MiningFrigateHullActions::ReportToPilot; - perform action transferOre : MiningFrigateHullActions::TransferOre; - perform action dockToStation : MiningFrigateHullActions::DockToStation; - perform action checkAsteroidStatus : MiningFrigateHullActions::CheckAsteroidStatus; - perform action resupplyCapacitor : MiningFrigateHullActions::ResupplyCapacitor; - perform action activateMiningLaser : MiningFrigateHullActions::ActivateMiningLaser; - - //Ports for COTS Modules - port highSlot1 : HighSlotPort; - port highSlot2 : HighSlotPort; - port mediumSlot1 : MediumSlotPort; - port mediumSlot2 : MediumSlotPort; - port lowSlot1 : LowSlotPort; - port lowSlot2 : LowSlotPort; - - //Ports bound to the LogicalMiningFrigateConfiguration - port hullControlPort : ~Domain::PodPort; - port hullDockingPort : ~Domain::DockingPort; - port hullDefensePort : ~Domain::ThreatPort; - port hullDroneControlPort: ~Domain::DroneControllerPort; - } - - //Power and Control Interfaces Items inherited from the standardPorts items - item def VenturePowerSupply :> PowerSupply ; - item def VentureHighSlotCommand :> HighSlotCommand ; - item def VentureMediumSlotCommand :> MediumSlotCommand ; - item def VentureLowSlotCommand :> LowSlotCommand ; } diff --git a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml index 801b0ee..4fc9194 100644 --- a/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml +++ b/models/example_EveOnlineMiningFrigate/LogicalArchitecture/UseCasesHull.sysml @@ -3,6 +3,7 @@ package MiningFrigateHullUseCases { private import MiningFrigateSolutionSpace::*; private import Domain::*; private import COTS::*; + private import MiningFrigateHull::*; // **Use Case: Manage Energy Supply and Recharge** use case ManageEnergy { diff --git a/models/example_EveOnlineMiningFrigate/UseCases/OperationalUseCaseActions.sysml b/models/example_EveOnlineMiningFrigate/UseCases/OperationalUseCaseActions.sysml index d3f9ed3..3a38b51 100644 --- a/models/example_EveOnlineMiningFrigate/UseCases/OperationalUseCaseActions.sysml +++ b/models/example_EveOnlineMiningFrigate/UseCases/OperationalUseCaseActions.sysml @@ -31,6 +31,8 @@ package OperationalUseCaseActions { * - If capacitor energy is insufficient, fail to activate laser and notify the pilot. * - If ECM interference disrupts target lock, pause extraction until lock is re-established. */ + in activateMiningLaser : Domain::ShipCommand; + out miningCycleReport : Domain::ShipReport; } // Main Use Case definition : Detect Threats and Engage Defenses