diff --git a/doc/1-Kernel_Modeling_Language.pdf b/doc/1-Kernel_Modeling_Language.pdf index 32a3f79d..fc1caed0 100644 Binary files a/doc/1-Kernel_Modeling_Language.pdf and b/doc/1-Kernel_Modeling_Language.pdf differ diff --git a/doc/2-OMG_Systems_Modeling_Language.pdf b/doc/2-OMG_Systems_Modeling_Language.pdf index bc460693..67b97824 100644 Binary files a/doc/2-OMG_Systems_Modeling_Language.pdf and b/doc/2-OMG_Systems_Modeling_Language.pdf differ diff --git a/doc/3-Systems_Modeling_API_and_Services.pdf b/doc/3-Systems_Modeling_API_and_Services.pdf index 14155dca..73e55b18 100644 Binary files a/doc/3-Systems_Modeling_API_and_Services.pdf and b/doc/3-Systems_Modeling_API_and_Services.pdf differ diff --git a/doc/Intro to the SysML v2 Language-Textual Notation.pdf b/doc/Intro to the SysML v2 Language-Textual Notation.pdf index 9bba81f8..4fa08379 100644 Binary files a/doc/Intro to the SysML v2 Language-Textual Notation.pdf and b/doc/Intro to the SysML v2 Language-Textual Notation.pdf differ diff --git a/install/eclipse/org.omg.sysml.site.zip b/install/eclipse/org.omg.sysml.site.zip index 0fd40575..3f4dbfe2 100644 Binary files a/install/eclipse/org.omg.sysml.site.zip and b/install/eclipse/org.omg.sysml.site.zip differ diff --git a/install/jupyter/README.pdf b/install/jupyter/README.pdf index 7466d329..2af07857 100644 Binary files a/install/jupyter/README.pdf and b/install/jupyter/README.pdf differ diff --git a/install/jupyter/install.bat b/install/jupyter/install.bat index 531fef7c..05bd0474 100755 --- a/install/jupyter/install.bat +++ b/install/jupyter/install.bat @@ -20,7 +20,7 @@ @echo off -set /A SYSML_VERSION="0.19.0" +set /A SYSML_VERSION="0.20.0" echo --- Step 1: Testing Conda installation --- where conda diff --git a/install/jupyter/install.sh b/install/jupyter/install.sh index 11b68141..e2ce6d06 100755 --- a/install/jupyter/install.sh +++ b/install/jupyter/install.sh @@ -21,7 +21,7 @@ set -e -SYSML_VERSION="0.19.0" +SYSML_VERSION="0.20.0" echo "--- Step 1: Testing Conda installation ---" command -v conda || (echo "Conda is not installed. Please install Conda and re-run." && return 1) diff --git a/kerml/src/examples/Simple Tests/Elements.kerml b/kerml/src/examples/Simple Tests/Elements.kerml index 95c98f94..2ce188f3 100644 --- a/kerml/src/examples/Simple Tests/Elements.kerml +++ b/kerml/src/examples/Simple Tests/Elements.kerml @@ -1,13 +1,15 @@ -element ; - -element <'1.2.4'> MyName; - -element { - doc /* Element A is related to element B. */ - relationship to B; -} - -element { - language "HTML" - /* */ +package Elements { + element ; + + element <'1.2.4'> MyName; + + element { + doc /* Element A is related to element B. */ + relationship to B; + } + + element { + language "HTML" + /* */ + } } \ No newline at end of file diff --git a/kerml/src/examples/Simple Tests/Expressions.kerml b/kerml/src/examples/Simple Tests/Expressions.kerml index 45a20c34..c469897d 100644 --- a/kerml/src/examples/Simple Tests/Expressions.kerml +++ b/kerml/src/examples/Simple Tests/Expressions.kerml @@ -21,7 +21,7 @@ package Expressions { out v_decr : Integer = v - 1; } succession decrement then update; - step update : FeatureAccessPerformances::FeatureWritePerformance { + step update : FeatureReferencingPerformances::FeatureWritePerformance { in redefines onOccurrence = w::self { feature redefines startingAt : w { feature redefines accessedFeature redefines v; diff --git a/kerml/src/examples/Simple Tests/Relationships.kerml b/kerml/src/examples/Simple Tests/Relationships.kerml index 21eb7f8e..cc62f7a3 100644 --- a/kerml/src/examples/Simple Tests/Relationships.kerml +++ b/kerml/src/examples/Simple Tests/Relationships.kerml @@ -1,12 +1,31 @@ -element <'1'> A; -element <'2'> B; -element <'3'> C; -relationship <'4'> R from A to B, C; - -package P1 { - element S; -} -package P2 { - element T; -} -relationship from P1::S to P2::T; \ No newline at end of file +package Relationships { + namespace { + element <'1'> A; + element <'2'> B; + element <'3'> C; + relationship <'4'> R from A to B, C; + } + + namespace { + package P1 { + element S; + } + package P2 { + element T; + } + relationship from P1::S to P2::T; + } + + namespace N { + element A; + element B { + relationship { + element ; // Owned related Element + relationship from A to B; // Relationship as owned related Element + } + } + relationship R from A to B { + doc /* This relationship has no owned related Elements. */ + } + } +} \ No newline at end of file diff --git a/sysml.library/Domain Libraries/Quantities and Units/ISQ.sysml b/sysml.library/Domain Libraries/Quantities and Units/ISQ.sysml index 0237d2fb..9b69666c 100644 --- a/sysml.library/Domain Libraries/Quantities and Units/ISQ.sysml +++ b/sysml.library/Domain Libraries/Quantities and Units/ISQ.sysml @@ -18,4 +18,24 @@ package ISQ { import ISQCharacteristicNumbers::*; // ISO 80000-11 "Characteristic numbers" import ISQCondensedMatter::*; // ISO 80000-12 "Condensed matter physics" import ISQInformation::*; // IEC 80000-13 "Information science and technology" + + /* Additional quantity declarations */ + + /** + * temperature difference + * + * A separate temperature difference quantity and unit are needed in order to support °C, °F and centrigrade temperature differences + */ + attribute def TemperatureDifferenceUnit :> SimpleUnit { + private attribute thermodynamicTemperaturePF: QuantityPowerFactor[1] { :>> quantity = isq.'Θ'; :>> exponent = 1; } + attribute :>> quantityDimension { :>> quantityPowerFactors = thermodynamicTemperaturePF; } + } + + attribute def TemperatureDifferenceValue :> ScalarQuantityValue { + attribute :>> num: Real; + attribute :>> mRef: TemperatureDifferenceUnit[1]; + } + + attribute temperatureDifference: TemperatureDifferenceValue [*] nonunique :> scalarQuantities; + } diff --git a/sysml.library/Domain Libraries/Quantities and Units/ISQBase.sysml b/sysml.library/Domain Libraries/Quantities and Units/ISQBase.sysml index 1a19ae34..b94ecad8 100644 --- a/sysml.library/Domain Libraries/Quantities and Units/ISQBase.sysml +++ b/sysml.library/Domain Libraries/Quantities and Units/ISQBase.sysml @@ -178,8 +178,7 @@ package ISQBase { * Declaration of the International System of Quantities (ISQ), * including its base quantities and symbols as specified in ISO 80000-1:2009. */ - attribute isq: SystemOfQuantities { - attribute :>> longName = "International System of Quantities"; + attribute 'International System of Quantities': SystemOfQuantities { attribute :>> baseQuantities = ( L, M, T, I, 'Θ', N, J ); attribute L: LengthValue[1]; diff --git a/sysml.library/Domain Libraries/Quantities and Units/Quantities.sysml b/sysml.library/Domain Libraries/Quantities and Units/Quantities.sysml index 0c947f12..5706c48b 100644 --- a/sysml.library/Domain Libraries/Quantities and Units/Quantities.sysml +++ b/sysml.library/Domain Libraries/Quantities and Units/Quantities.sysml @@ -3,7 +3,12 @@ */ package Quantities { private import Collections::*; - private import ScalarValues::ScalarValue; + private import ScalarValues::NumericalValue; + private import ScalarValues::Number; + private import ScalarValues::Real; + private import ScalarValues::Natural; + private import ScalarValues::Boolean; + private import ScalarValues::String; /** * The value of a quantity is a tuple of one or more numbers (i.e. mathematical number values) and a reference to a measurement reference. @@ -14,14 +19,13 @@ package Quantities { * and a ScalarQuantityValue a ScalarMeasurementReference. See package UnitsAndScales for details. */ abstract attribute def TensorQuantityValue :> Array { - attribute isBound: ScalarValues::Boolean; - attribute num: ScalarValues::Number[1..*] ordered nonunique :>> elements; + attribute isBound: Boolean; + attribute num: Number[1..*] ordered nonunique :>> elements; attribute mRef: UnitsAndScales::TensorMeasurementReference; - attribute measure: UnitsAndScales::TensorMeasurementReference; attribute :>> dimensions = mRef.dimensions; attribute order :>> rank = mRef.order; - attribute contravariantOrder: ScalarValues::Natural; - attribute covariantOrder: ScalarValues::Natural; + attribute contravariantOrder: Natural; + attribute covariantOrder: Natural; assert constraint orderSum { contravariantOrder + covariantOrder == order } assert constraint boundMatch { (isBound == mRef.isBound) || (!isBound && mRef.isBound) } @@ -31,7 +35,7 @@ package Quantities { attribute :>> mRef: UnitsAndScales::VectorMeasurementReference; } - abstract attribute def ScalarQuantityValue :> VectorQuantityValue, ScalarValue { + abstract attribute def ScalarQuantityValue :> VectorQuantityValue, NumericalValue { attribute :>> mRef: UnitsAndScales::ScalarMeasurementReference; } @@ -57,7 +61,6 @@ package Quantities { * completed by adding derived quantities which are products of powers of the base quantities. */ attribute def SystemOfQuantities { - attribute longName: ScalarValues::String; attribute baseQuantities: ScalarQuantityValue[*] ordered :> scalarQuantities; } @@ -68,7 +71,7 @@ package Quantities { */ attribute def QuantityPowerFactor { attribute quantity: ScalarQuantityValue[1]; - attribute exponent: ScalarValues::Real[1]; + attribute exponent: Real[1]; } /** diff --git a/sysml.library/Domain Libraries/Quantities and Units/QuantityCalculations.sysml b/sysml.library/Domain Libraries/Quantities and Units/QuantityCalculations.sysml index f147126b..393590a6 100644 --- a/sysml.library/Domain Libraries/Quantities and Units/QuantityCalculations.sysml +++ b/sysml.library/Domain Libraries/Quantities and Units/QuantityCalculations.sysml @@ -1,11 +1,10 @@ package QuantityCalculations { import ScalarValues::*; - import Quantities::*; + import Quantities::ScalarQuantityValue; import UnitsAndScales::ScalarMeasurementReference; - import UnitsAndScales::MeasurementReference; import UnitsAndScales::DimensionOneValue; - calc def '[' specializes BaseFunctions::'[' (x: NumericalValue, y: ScalarMeasurementReference): QuantityValue; + calc def '[' specializes BaseFunctions::'[' (x: NumericalValue, y: ScalarMeasurementReference): ScalarQuantityValue; calc def Abs specializes NumericalFunctions::Abs (x: ScalarQuantityValue): ScalarQuantityValue; diff --git a/sysml.library/Domain Libraries/Quantities and Units/SI.sysml b/sysml.library/Domain Libraries/Quantities and Units/SI.sysml index 74e7c64a..f563e6cd 100644 --- a/sysml.library/Domain Libraries/Quantities and Units/SI.sysml +++ b/sysml.library/Domain Libraries/Quantities and Units/SI.sysml @@ -1,17 +1,16 @@ /** * International System of (Measurement) Units -- Système International d'Unités (SI), as defined in ISO/IEC 80000 * - * Note 1: In accordance with ISO/IEC 80000 en-GB spelling is used for the longNames and definitions of the units. + * Note 1: In accordance with ISO/IEC 80000 en-GB spelling is used for the names and definitions of the units. * Note 2: This is a representative but not yet complete list of measurement units. */ package SI { private import UnitsAndScales::*; import ISQ::*; import SIPrefixes::*; - import QuantityCalculations::*; /* - * SI simple units needed before creation of base units + * SI simple unit needed in support of creation of the base units */ attribute gram : MassUnit; @@ -22,7 +21,7 @@ package SI { attribute kilogram : MassUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = kilo; :>> referenceUnit = g; } } attribute second : DurationUnit; attribute ampere : ElectricCurrentUnit; - attribute kelvin : ThermodynamicTemperatureUnit { + attribute kelvin : ThermodynamicTemperatureUnit, TemperatureDifferenceUnit { attribute temperatureOfWaterAtTriplePointInK: DefinitionalQuantityValue { :>> num = 27316/100; :>> definition = "temperature in kelvin of pure water at the triple point"; @@ -34,8 +33,10 @@ package SI { /* * Declare the SI system of units with its explicit base units + * and its associated system of quantities, the ISQ. */ attribute 'ISO/IEC 80000 International System of Units' : SystemOfUnits { + :>> systemOfQuantities = isq; :>> baseUnits = (m, kg, s, A, K, mol, cd); } @@ -56,6 +57,7 @@ package SI { attribute hartley : InformationContentUnit = one; attribute hertz : FrequencyUnit = s^-1; attribute joule : EnergyUnit = N*m; + //attribute katal : CatalyticActivityUnit = mol/s; attribute lumen : LuminousFluxUnit = cd*sr; attribute lux : IlluminanceUnit = lm/m^2; attribute newton : ForceUnit = kg*m/s^2; @@ -75,19 +77,26 @@ package SI { attribute <'Ω'> ohm : ResistanceUnit = V/A; /* - * Units recognized in SI + * Units recognized in SI as specified in ISO 80000-1:2009 */ + attribute <'Å'> 'ångström' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.0e-10; } } attribute barn : AreaUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = 'm²'; :>> conversionFactor = 1.0e-28; } } - attribute dalton : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 1.66053906660e-27; } } - attribute electronvolt : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.602176487e-19; } } + attribute day: DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = hour; :>> conversionFactor = 24; } } + attribute dalton : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 1.66053906660e-27; :>> isExact = false; } } + attribute electronvolt : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.602176487e-19; :>> isExact = false; } } + attribute hour: DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = min; :>> conversionFactor = 60; } } + attribute minute : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 60; } } + attribute litre : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = 'm³'; :>> conversionFactor = 1.0e-3; } } + attribute tonne : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 1.0e-3; } } + alias 'metric ton' for tonne; attribute 'atomic mass unit' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Da; :>> conversionFactor = 1.0; } } - attribute 'astronomical unit' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 149597870691e11; } } + attribute 'astronomical unit' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 149597870691e11; :>> isExact = false; } } attribute 'volt ampere reactive' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = V*A; :>> conversionFactor = 1.0; } } - attribute <'°'> degree : AngularMeasureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = rad; :>> conversionFactor = 3.141592653589793/180; } } // conversionFactor should become pi/180 - attribute <'Å'> 'ångström' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.0e-10; } } - - attribute litre : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = 'm³'; :>> conversionFactor = 1.0e-3; } } - attribute millilitre : VolumeUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = milli; :>> referenceUnit = L; } } + attribute <'°'> degree : AngularMeasureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = rad; :>> conversionFactor = 1.745329E-02; :>> isExact = false; } } // conversionFactor should become pi/180 + attribute <'′'> 'minute (angle)' : AngularMeasureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = rad; :>> conversionFactor = 2.908882E-04; :>> isExact = false; } } + alias arcmin for '′'; + attribute <'″'> 'second (angle)' : AngularMeasureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = rad; :>> conversionFactor = 4.848137E-06; :>> isExact = false; } } + alias arcsec for '″'; /* * Derived units used in parts 3 to 12 of ISO/IEC 80000 @@ -287,37 +296,44 @@ package SI { /* * Prefixed units */ + + /* Length */ attribute nanometre : LengthUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = nano; :>> referenceUnit = m; } } attribute millimetre : LengthUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = milli; :>> referenceUnit = m; } } attribute centimetre : LengthUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = centi; :>> referenceUnit = m; } } attribute kilometre : LengthUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = kilo; :>> referenceUnit = m; } } + + /* Volume */ + attribute millilitre : VolumeUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = milli; :>> referenceUnit = L; } } + + /* Force */ attribute millinewton : ForceUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = milli; :>> referenceUnit = N; } } + + /* Energy */ attribute kilojoule : EnergyUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = kilo; :>> referenceUnit = J; } } attribute megajoule : EnergyUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = mega; :>> referenceUnit = J; } } attribute gigajoule : EnergyUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = giga; :>> referenceUnit = J; } } + + /* Power */ attribute kilowatt : PowerUnit { :>> unitConversion: ConversionByPrefix { :>> prefix = kilo; :>> referenceUnit = W; } } - /* - * Non-standard conversion based units that are accepted in SI - */ - attribute minute : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 60; } } - attribute hour: DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = min; :>> conversionFactor = 60; } } + /* Speed */ attribute <'km/h'> 'kilometre per hour': SpeedUnit = km/h; /* - * degree Celsius unit for temperature difference quantities + * degree Celsius unit for temperature interval (i.e. temperature difference) quantities */ - attribute <'°C_unit'> 'degree celsius (unit)' : TemperatureUnit { + attribute <'°C'> 'degree celsius (temperature interval)' : TemperatureDifferenceUnit { attribute :>> unitConversion: ConversionByConvention { :>> referenceUnit = K; :>> conversionFactor = 1; } } /* * degree Celsius interval scale for absolute temperature quantities * - * The interval scale is defined with an explicit mapping to the kelvin ratio scale from which the offset between the scales can be computed. + * The interval scale is defined with an explicit mapping to the kelvin thermodynamic temperature ratio scale from which the offset between the scales can be computed. */ - attribute <'°C_scale'> 'degree celsius scale' : IntervalScale { - attribute :>> unit = '°C_unit'; + attribute <'°C_abs'> 'degree celsius (temperature scale)' : IntervalScale { + attribute :>> unit = '°C'; attribute temperatureWaterAtFreezingPointInC: DefinitionalQuantityValue { :>> num = 0; :>> definition = "temperature in degree Celsius of pure water at freezing point"; } @@ -329,11 +345,10 @@ package SI { } attribute :>> definitionalQuantityValues = (temperatureWaterAtTriplePointInC, temperatureWaterAtFreezingPointInC); attribute :>> quantityValueMapping = celsiusToKelvinScaleMapping; - // Experimental zero shift w.r.t. to K (kelvin) thermodynamic temperature ratio scale - // Such CoordinateTransformation can be used instead of the celsiusToKelvinScaleMapping + + /* CoordinateTransformation (zero shift) w.r.t. thermodynamic temperature in kelvin */ private attribute zeroDegreeCelsiusInKelvin: ThermodynamicTemperatureValue = 273.15 [K]; - attribute zeroShift : CoordinateTransformation { :>> source = K; :>> target = self; :>> origin = zeroDegreeCelsiusInKelvin; } + attribute zeroShift : CoordinateTransformation { :>> source = K; :>> target = self; :>> origin = zeroDegreeCelsiusInKelvin; :>> basisDirections = 1 [K]; } attribute :>> placement = zeroShift; } - alias '°C' for '°C_scale'; } diff --git a/sysml.library/Domain Libraries/Quantities and Units/Time.sysml b/sysml.library/Domain Libraries/Quantities and Units/Time.sysml index 29f7bdab..91e87469 100644 --- a/sysml.library/Domain Libraries/Quantities and Units/Time.sysml +++ b/sysml.library/Domain Libraries/Quantities and Units/Time.sysml @@ -1,23 +1,57 @@ /** - * Specifications for time instant and various time scales + * This package specifies concepts to support time-related quantities and metrology, beyond + * the quantities duration and time as defined in [ISO 80000-3]. Representations of the + * Gregorian calendar date and time of day as specified by the [ISO 8601-1] standard are used. */ - package Time { - import ScalarValues::Real; - import ScalarValues::Integer; - import ScalarValues::Natural; - import ScalarValues::String; - import Quantities::ScalarQuantityValue; - import Quantities::scalarQuantities; - import UnitsAndScales::*; + private import Occurrences::Occurrence; + private import ScalarValues::Real; + private import ScalarValues::Integer; + private import ScalarValues::Natural; + private import ScalarValues::String; + private import Quantities::ScalarQuantityValue; + private import Quantities::scalarQuantities; + private import UnitsAndScales::*; import ISQBase::DurationValue; import ISQBase::DurationUnit; import ISQBase::duration; import ISQSpaceTime::TimeValue; import ISQSpaceTime::TimeUnit; import ISQSpaceTime::time; + + /** + * defaultClock is a single Clock that can be used as a default. + */ + readonly part defaultClock : Clock[1] = Clocks::defaultClock; + /** + * A Clock provides a currentTime as a TimeInstantValue that advances montonically over its lifetime. + */ + part def Clock :> Clocks::Clock { + attribute :>> currentTime : TimeInstantValue; + } + + /** + * TimeOf returns a TimeInstantValue for a given Occurrence relative to a given Clock. This TimeInstantValue is the + * time of the start of the Occurrence, which is considered to be synchronized with the snapshot of the Clock with a + * currentTime equal to the returned timeInstant. + */ + calc def TimeOf :> Clocks::TimeOf { + in o : Occurrence[1]; + in clock : Clock[1] default defaultClock; + return timeInstant : TimeInstantValue[1]; + } + /** + * DurationOf returns the duration of a given Occurrence relative to a given Clock, which is equal to the TimeOf + * the end snapshot of the Occurrence minus the TimeOf its start snapshot. + */ + calc def DurationOf :> Clocks::DurationOf { + in o : Occurrence[1]; + in clock : Clock[1] default defaultClock; + return duration : DurationValue; + } + /** * Generic time scale to express a time instant, including a textual definition of the meaning of zero time instant value * @@ -81,7 +115,7 @@ package Time { * Representation of a time instant expressed on the Coordinated Universal Time (UTC) time scale */ attribute def UtcTimeInstantValue :> DateTime { :>> mRef = UTC; } - attribute utcTimeInstant: UtcTimeInstantValue; + attribute utcTimeInstant: UtcTimeInstantValue :> timeInstant; /** * Representations of a Gregorian calendar date and time of day as specified by the ISO 8601-1 standard. @@ -142,8 +176,8 @@ package Time { * Representation of an ISO 8601-1 date and time in extended string format */ attribute def Iso8601DateTime :> UtcTimeInstantValue { - attribute :>> num = getElapsedUtcTime(val); attribute val: Iso8601DateTimeEncoding; + attribute :>> num = getElapsedUtcTime(val); private calc getElapsedUtcTime(iso8601DateTime: Iso8601DateTimeEncoding) : Real { doc /** Return the number of seconds elapsed since the UTC epoch. Can be negative when the date and time is earlier than the epoch. */ attribute x: Real; @@ -161,8 +195,6 @@ package Time { * The total time offset is equal to the summation of hourOffset and minuteOffset. */ attribute def Iso8601DateTimeStructure :> UtcTimeInstantValue { - attribute :>> num = getElapsedUtcTime(year, month, day, hour, minute, second, microsecond, hourOffset, minuteOffest); - attribute :>> mRef = UTC; attribute year: Integer; attribute month: Natural; attribute day: Natural; @@ -172,6 +204,8 @@ package Time { attribute microsecond: Natural; attribute hourOffset: Integer; attribute minuteOffest: Integer; + attribute :>> num = getElapsedUtcTime(year, month, day, hour, minute, second, microsecond, hourOffset, minuteOffest); + attribute :>> mRef = UTC; private calc getElapsedUtcTime(year: Integer, month: Natural, day: Natural, hour: Natural, minute: Natural, second: Natural, microsecond: Natural, hourOffset: Integer, minuteOffest: Integer) : Real { attribute x: Real; diff --git a/sysml.library/Domain Libraries/Quantities and Units/USCustomaryUnits.sysml b/sysml.library/Domain Libraries/Quantities and Units/USCustomaryUnits.sysml index c9b74485..0feaa1a5 100644 --- a/sysml.library/Domain Libraries/Quantities and Units/USCustomaryUnits.sysml +++ b/sysml.library/Domain Libraries/Quantities and Units/USCustomaryUnits.sysml @@ -1,100 +1,23 @@ /** - * US customary units defined w.r.t. SI units - * Conversion factors are taken from NIST SP 811 Appendix B - * See https://www.nist.gov/physical-measurement-laboratory/nist-guide-si-appendix-b + * Measurement unit declarations generated from NIST SP811 Appendix B + * + * See https://www.nist.gov/pml/special-publication-811/nist-guide-si-appendix-b-conversion-factors/nist-guide-si-appendix-b8 */ -package USCustomaryUnits { - private import UnitsAndScales::*; - import ISQ::*; - private import SI::*; +package USCustomaryUnits { + private import UnitsAndScales::*; + import ISQ::*; + private import SI::*; - attribute foot : LengthUnit { - :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 3048/10000; } - } - - attribute <'in'> inch : LengthUnit { - :>> unitConversion: ConversionByConvention { :>> referenceUnit = ft; :>> conversionFactor = 1/12; } - } - - attribute mile : LengthUnit { - :>> unitConversion: ConversionByConvention { :>> referenceUnit = ft; :>> conversionFactor = 5280; } - } - - attribute 'pound (avoirdupois)' : MassUnit { - :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 4535924/10000000; } - } - - attribute <'mi/h'> 'mile per hour' : SpeedUnit = mi/h; - - attribute 'pound-force' : ForceUnit { - :>> unitConversion: ConversionByConvention { :>> referenceUnit = SI::N; :>> conversionFactor = 4448222/1000000; } - } - - /* - * Definition of an alias for 'mi/h' ("mile per hour") - */ - alias mph for 'mi/h'; - - /* - * degree Fahrenheit unit for relative temperature (i.e. temperature difference) quantities - */ - attribute <'°F_unit'> 'degree fahrenheit (relative)' : TemperatureUnit { - :>> unitConversion: ConversionByConvention { :>> referenceUnit = K; :>> conversionFactor = 5/9; } - } - - /* - * degree Fahrenheit interval scale for absolute temperature quantities - * - * The interval scale is defined with an explicit mapping to the degree Celsius interval scale from which the offset between the scales can be computed. - */ - attribute <'°F_scale'> 'degree fahrenheit (absolute)' : IntervalScale { - :>> unit = '°F_unit'; - private attribute temperatureWaterAtFreezingPointInF: DefinitionalQuantityValue { - :>> num = 32.0; - :>> definition = "temperature in degree Fahrenheit of pure water at freezing point"; - } - private attribute fahrenheitToCelsiusScaleMapping: QuantityValueMapping { - :>> mappedQuantityValue = temperatureWaterAtFreezingPointInF; - :>> referenceQuantityValue = '°C_scale'.temperatureWaterAtFreezingPointInC; - - } - attribute :>> definitionalQuantityValues = temperatureWaterAtFreezingPointInF; - attribute :>> quantityValueMapping = fahrenheitToCelsiusScaleMapping; - } - //alias '°F' for '°F_scale'; - - /* - * US Customary Units generated after transformation from NIST SP811 Appendix B - * See https://www.nist.gov/pml/special-publication-811/nist-guide-si-appendix-b-conversion-factors/nist-guide-si-appendix-b8 - * Generated at 2022-01-10T00:45:14Z - */ - - attribute 'abampere' : ElectricCurrentUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = A; :>> conversionFactor = 1.0E+01; } } - attribute 'abcoulomb' : ElectricChargeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = C; :>> conversionFactor = 1.0E+01; } } - attribute 'abfarad' : CapacitanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = F; :>> conversionFactor = 1.0E+09; } } - attribute 'abhenry' : InductanceUnit, PermeanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = H; :>> conversionFactor = 1.0E-09; } } - attribute 'abmho' : ConductanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = S; :>> conversionFactor = 1.0E+09; } } - attribute 'abohm' : ResistanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = 'Ω'; :>> conversionFactor = 1.0E-09; } } - attribute 'abvolt' : ElectricPotentialUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = V; :>> conversionFactor = 1.0E-08; } } - attribute 'acceleration of free fall, standard' : AccelerationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m/s^2; :>> conversionFactor = 9.80665E+00; } } - attribute 'acre (based on US survey foot)' : AreaUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2; :>> conversionFactor = 4.046873E+03; } } - attribute 'acre foot (based on US survey foot)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.233489E+03; } } - attribute <'A⋅h'> 'ampere hour' : ElectricChargeUnit = A*h; - attribute <'Å'> 'ångström' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.0E-10; } } - attribute 'are' : AreaUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2; :>> conversionFactor = 1.0E+02; } } - attribute 'astronomical unit' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.495979E+11; } } - attribute 'atmosphere, standard' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 1.01325E+05; } } - attribute 'atmosphere, technical' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 9.80665E+04; } } - attribute 'bar' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 1.0E+05; } } - attribute 'barn' : AreaUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2; :>> conversionFactor = 1.0E-28; } } - attribute 'barrel (for petroleum, 42 gallons (US))' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.589873E-01; } } - attribute 'biot' : ElectricCurrentUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = A; :>> conversionFactor = 1.0E+01; } } - attribute 'British thermal unit (IT)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.055056E+03; } } - attribute 'British thermal unit (th)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.054350E+03; } } - attribute 'British thermal unit (mean)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.05587E+03; } } - attribute 'British thermal unit (39 °F)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.05967E+03; } } - attribute 'British thermal unit (59 °F)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.05480E+03; } } - attribute 'British thermal unit (60 °F)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.05468E+03; } } + attribute 'acre (based on US survey foot)' : AreaUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2; :>> conversionFactor = 4.046873E+03; :>> isExact = false; } } + attribute 'acre foot (based on US survey foot)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.233489E+03; :>> isExact = false; } } + attribute 'barrel (for petroleum, 42 gallons (US))' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.589873E-01; :>> isExact = false; } } + attribute 'British thermal unit (IT)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.055056E+03; :>> isExact = false; } } + alias Btu for Btu_IT; + attribute 'British thermal unit (th)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.054350E+03; :>> isExact = false; } } + attribute 'British thermal unit (mean)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.05587E+03; :>> isExact = false; } } + attribute <'Btu_39°F'> 'British thermal unit (39 °F)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.05967E+03; :>> isExact = false; } } + attribute <'Btu_59°F'> 'British thermal unit (59 °F)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.05480E+03; :>> isExact = false; } } + attribute <'Btu_60°F'> 'British thermal unit (60 °F)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.05468E+03; :>> isExact = false; } } attribute <'Btu_IT⋅ft/(h⋅ft²⋅°F)'> 'British thermal unit (IT) foot per hour square foot degree Fahrenheit' : ThermalConductivityUnit = Btu_IT*ft/(h*ft^2*'°F'); attribute <'Btu_th⋅ft/(h⋅ft²⋅°F)'> 'British thermal unit (th) foot per hour square foot degree Fahrenheit' : ThermalConductivityUnit = Btu_th*ft/(h*ft^2*'°F'); attribute <'Btu_IT⋅in/(h⋅ft²⋅°F)'> 'British thermal unit (IT) inch per hour square foot degree Fahrenheit' : ThermalConductivityUnit = Btu_IT*'in'/(h*ft^2*'°F'); @@ -130,39 +53,12 @@ package USCustomaryUnits { attribute <'Btu_IT/(ft²⋅s)'> 'British thermal unit (IT) per square foot second' : DensityOfHeatFlowRateUnit = Btu_IT/(ft^2*s); attribute <'Btu_th/(ft²⋅s)'> 'British thermal unit (th) per square foot second' : DensityOfHeatFlowRateUnit = Btu_th/(ft^2*s); attribute <'Btu_th/(in²⋅s)'> 'British thermal unit (th) per square inch second' : DensityOfHeatFlowRateUnit = Btu_th/('in'^2*s); - attribute 'bushel (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 3.523907E-02; } } - attribute 'calorie (IT)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.1868E+00; } } - attribute 'calorie (th)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.184E+00; } } - attribute 'calorie (mean)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.19002E+00; } } - attribute 'calorie (15 °C)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.18580E+00; } } - attribute 'calorie (20 °C)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.18190E+00; } } - attribute 'calorie (IT), kilogram (nutrition)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.1868E+03; } } - attribute 'calorie (th), kilogram (nutrition)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.184E+03; } } - attribute 'calorie (mean), kilogram (nutrition)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.19002E+03; } } - attribute <'cal_th/(cm⋅s⋅°C)'> 'calorie (th) per centimeter second degree Celsius' : ThermalConductivityUnit = cal_th/(cm*s*'°C'); - attribute <'cal_IT/g'> 'calorie (IT) per gram' : SpecificEnergyUnit = cal_IT/g; - attribute <'cal_th/g'> 'calorie (th) per gram' : SpecificEnergyUnit = cal_th/g; - attribute <'cal_IT/(g⋅°C)'> 'calorie (IT) per gram degree Celsius' : SpecificHeatCapacityUnit = cal_IT/(g*'°C'); - attribute <'cal_th/(g⋅°C)'> 'calorie (th) per gram degree Celsius' : SpecificHeatCapacityUnit = cal_th/(g*'°C'); - attribute <'cal_IT/(g⋅K)'> 'calorie (IT) per gram kelvin' : SpecificHeatCapacityUnit = cal_IT/(g*K); - //attribute <'cal_th/(g·K)'> 'calorie (th) per gram kelvin' : SpecificHeatCapacityUnit = cal_th/('g·K'); - attribute <'cal_th/min'> 'calorie (th) per minute' : PowerUnit = cal_th/min; - attribute <'cal_th/s'> 'calorie (th) per second' : PowerUnit = cal_th/s; - //attribute <'cal_th/cm²'> 'calorie (th) per square centimeter' : SurfaceHeatDensityUnit = cal_th/cm^2; - attribute <'cal_th/(cm²⋅min)'> 'calorie (th) per square centimeter minute' : DensityOfHeatFlowRateUnit = cal_th/(cm^2*min); - attribute <'cal_th/(cm²⋅s)'> 'calorie (th) per square centimeter second' : DensityOfHeatFlowRateUnit = cal_th/(cm^2*s); + attribute 'bushel (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 3.523907E-02; :>> isExact = false; } } attribute <'cd/in²'> 'candela per square inch' : LuminanceUnit = cd/'in'^2; - attribute 'carat, metric' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 2.0E-04; } } - attribute 'centimeter of mercury (0 °C)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 1.33322E+03; } } - attribute 'centimeter of mercury, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 1.333224E+03; } } - attribute 'centimeter of water (4 °C)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 9.80638E+01; } } - attribute 'centimeter of water, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 9.80665E+01; } } - attribute 'centipoise' : DynamicViscosityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa*s; :>> conversionFactor = 1.0E-03; } } - attribute 'centistokes' : KinematicViscosityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2/s; :>> conversionFactor = 1.0E-06; } } - attribute 'chain (based on US survey foot)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 2.011684E+01; } } - attribute 'circular mil' : AreaUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2; :>> conversionFactor = 5.067075E-10; } } - attribute 'clo' : ThermalInsulanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2*K/W; :>> conversionFactor = 1.55E-01; } } - attribute 'cord (128 ft^3)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 3.624556E+00; } } + attribute 'chain (based on US survey foot)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 2.011684E+01; :>> isExact = false; } } + attribute 'circular mil' : AreaUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2; :>> conversionFactor = 5.067075E-10; :>> isExact = false; } } + attribute 'clo' : ThermalInsulanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2*K/W; :>> conversionFactor = 1.55E-01; :>> isExact = false; } } + attribute 'cord (128 ft^3)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 3.624556E+00; :>> isExact = false; } } attribute <'ft³'> 'cubic foot' : VolumeUnit = ft^3; attribute <'ft³/min'> 'cubic foot per minute' : VolumeFlowRateUnit = ft^3/min; attribute <'ft³/s'> 'cubic foot per second' : VolumeFlowRateUnit = ft^3/s; @@ -171,19 +67,8 @@ package USCustomaryUnits { attribute <'mi³'> 'cubic mile' : VolumeUnit = mi^3; attribute <'yd³'> 'cubic yard' : VolumeUnit = yd^3; attribute <'yd³/min'> 'cubic yard per minute' : VolumeFlowRateUnit = yd^3/min; - attribute 'cup (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 2.365882E-04; } } - attribute 'curie' : NuclearActivityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Bq; :>> conversionFactor = 3.7E+10; } } - attribute 'darcy' : AreaUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2; :>> conversionFactor = 9.869233E-13; } } - attribute 'day' : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 8.64E+04; } } - attribute 'day (sidereal)' : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 8.616409E+04; } } - attribute 'debye' : ElectricDipoleMomentUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = C*m; :>> conversionFactor = 3.335641E-30; } } - attribute <'°'> 'degree (angle)' : AngularMeasureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = rad; :>> conversionFactor = 1.745329E-02; } } - attribute <'°C'> 'degree Celsius (temperature)' : TemperatureUnit; // conversion TBD - attribute 'degree Celsius (temperature interval)' : TemperatureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = K; :>> conversionFactor = 1.0E+00; } } - attribute 'degree centigrade (temperature)' : TemperatureUnit; // conversion TBD - attribute 'degree centigrade (temperature interval)' : TemperatureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = '°C'; :>> conversionFactor = 1.0E+00; } } - attribute <'°F'> 'degree Fahrenheit (temperature)' : TemperatureUnit; // conversion TBD - attribute 'degree Fahrenheit (temperature interval)' : TemperatureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = '°C'; :>> conversionFactor = 5.555556E-01; } } + attribute 'cup (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 2.365882E-04; :>> isExact = false; } } + attribute <'°F'> 'degree Fahrenheit (temperature interval)' : TemperatureDifferenceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = K; :>> conversionFactor = 5/9; :>> isExact = true; } } attribute <'°F⋅h/Btu_IT'> 'degree Fahrenheit hour per British thermal unit (IT)' : ThermalResistanceUnit = '°F'*h/Btu_IT; attribute <'°F⋅h/Btu_th'> 'degree Fahrenheit hour per British thermal unit (th)' : ThermalResistanceUnit = '°F'*h/Btu_th; attribute <'°F⋅h⋅ft²/Btu_IT'> 'degree Fahrenheit hour square foot per British thermal unit (IT)' : ThermalInsulanceUnit = '°F'*h*ft^2/Btu_IT; @@ -192,165 +77,90 @@ package USCustomaryUnits { //attribute <'°F⋅h⋅ft²/(Btu_th⋅in)'> 'degree Fahrenheit hour square foot per British thermal unit (th) inch' : ThermalResistivityUnit = '°F'*h*ft^2/(Btu_th*'in'); attribute <'°F⋅s/Btu_IT'> 'degree Fahrenheit second per British thermal unit (IT)' : ThermalResistanceUnit = '°F'*s/Btu_IT; attribute <'°F⋅s/Btu_th'> 'degree Fahrenheit second per British thermal unit (th)' : ThermalResistanceUnit = '°F'*s/Btu_th; - attribute <'°R'> 'degree Rankine' : TemperatureUnit; // conversion TBD - attribute 'degree Rankine (temperature interval)' : TemperatureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = K; :>> conversionFactor = 5.555556E-01; } } - attribute 'denier' : LinearMassDensityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/m; :>> conversionFactor = 1.111111E-07; } } - attribute 'dyne' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 1.0E-05; } } - attribute <'dyn⋅cm'> 'dyne centimeter' : MomentOfForceUnit = dyn*cm; - attribute <'dyn/cm²'> 'dyne per square centimeter' : PressureUnit = dyn/cm^2; - attribute 'electronvolt' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.602177E-19; } } - //attribute 'EMU of capacitance' : CapacitanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = F; :>> conversionFactor = 1.0E+09; } } - //attribute 'EMU of current' : ElectricCurrentUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = A; :>> conversionFactor = 1.0E+01; } } - //attribute 'EMU of electric potential' : ElectricPotentialUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = V; :>> conversionFactor = 1.0E-08; } } - //attribute 'EMU of inductance' : InductanceUnit, PermeanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = H; :>> conversionFactor = 1.0E-09; } } - //attribute 'EMU of resistance' : ResistanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = 'Ω'; :>> conversionFactor = 1.0E-09; } } - attribute 'erg' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.0E-07; } } - attribute <'erg/s'> 'erg per second' : PowerUnit = erg/s; - attribute <'erg/(cm²⋅s)'> 'erg per square centimeter second' : DensityOfHeatFlowRateUnit = erg/(cm^2*s); - attribute 'ESU of capacitance' : CapacitanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = F; :>> conversionFactor = 1.112650E-12; } } - attribute 'ESU of current' : ElectricCurrentUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = A; :>> conversionFactor = 3.335641E-10; } } - attribute 'ESU of electric potential' : ElectricPotentialUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = V; :>> conversionFactor = 2.997925E+02; } } - attribute 'ESU of inductance' : InductanceUnit, PermeanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = H; :>> conversionFactor = 8.987552E+11; } } - attribute 'ESU of resistance' : ResistanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = 'Ω'; :>> conversionFactor = 8.987552E+11; } } - attribute 'faraday (based on carbon 12)' : ElectricChargeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = C; :>> conversionFactor = 9.648531E+04; } } - attribute 'fathom (based on US survey foot)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.828804E+00; } } - attribute 'fermi' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.0E-15; } } - attribute 'fluid ounce (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 2.957353E-05; } } - //attribute 'foot' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 3.048E-01; } } - attribute 'foot (US survey)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 3.048006E-01; } } - attribute 'footcandle' : IlluminanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = lx; :>> conversionFactor = 1.076391E+01; } } - attribute 'footlambert' : LuminanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = cd/m^2; :>> conversionFactor = 3.426259E+00; } } - attribute 'foot of mercury, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 4.063666E+04; } } - attribute 'foot of water (39.2 °F)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 2.98898E+03; } } - attribute 'foot of water, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 2.989067E+03; } } + attribute <'°R'> 'degree Rankine' : ThermodynamicTemperatureUnit, TemperatureDifferenceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = K; :>> conversionFactor = 5/9; :>> isExact = true; } } + attribute 'fathom (based on US survey foot)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.828804E+00; :>> isExact = false; } } + attribute 'fluid ounce (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 2.957353E-05; :>> isExact = false; } } + attribute 'foot' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 3.048E-01; } } + attribute 'foot (US survey)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 3.048006E-01; :>> isExact = false; } } + attribute 'footcandle' : IlluminanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = lx; :>> conversionFactor = 1.076391E+01; :>> isExact = false; } } + attribute 'footlambert' : LuminanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = cd/m^2; :>> conversionFactor = 3.426259E+00; :>> isExact = false; } } + attribute 'foot of mercury, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 4.063666E+04; :>> isExact = false; } } + attribute 'foot of water (39.2 °F)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 2.98898E+03; :>> isExact = false; } } + attribute 'foot of water, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 2.989067E+03; :>> isExact = false; } } attribute <'ft/h'> 'foot per hour' : SpeedUnit = ft/h; attribute <'ft/min'> 'foot per minute' : SpeedUnit = ft/min; attribute <'ft/s'> 'foot per second' : SpeedUnit = ft/s; attribute <'ft/s²'> 'foot per second squared' : AccelerationUnit = ft/s^2; - attribute 'foot poundal' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.214011E-02; } } + attribute 'foot poundal' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.214011E-02; :>> isExact = false; } } attribute <'ft⋅lbf'> 'foot pound-force' : EnergyUnit = ft*lbf; attribute <'ft⋅lbf/h'> 'foot pound-force per hour' : PowerUnit = ft*lbf/h; attribute <'ft⋅lbf/min'> 'foot pound-force per minute' : PowerUnit = ft*lbf/min; attribute <'ft⋅lbf/s'> 'foot pound-force per second' : PowerUnit = ft*lbf/s; attribute <'ft⁴'> 'foot to the fourth power' : SecondAxialMomentOfAreaUnit = ft^4; - attribute 'franklin' : ElectricChargeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = C; :>> conversionFactor = 3.335641E-10; } } - //attribute 'gal' : AccelerationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m/s^2; :>> conversionFactor = 1.0E-02; } } - attribute 'gallon (Canadian and UK (Imperial))' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 4.54609E-03; } } - attribute 'gallon (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 3.785412E-03; } } + attribute 'gallon (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 3.785412E-03; :>> isExact = false; } } attribute <'gal/d'> 'gallon (US) per day' : VolumeFlowRateUnit = gal/d; //attribute <'gal/(hp⋅h)'> 'gallon (US) per horsepower hour' : EnergySpecificVolumeUnit = gal/(hp*h); attribute <'gal/min'> 'gallon (US) per minute (gpm)' : VolumeFlowRateUnit = gal/min; - attribute <'γ'> 'gamma' : MagneticFluxDensityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = T; :>> conversionFactor = 1.0E-09; } } - attribute 'gauss' : MagneticFluxDensityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = T; :>> conversionFactor = 1.0E-04; } } - attribute 'gilbert' : ElectricCurrentUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = A; :>> conversionFactor = 7.957747E-01; } } - attribute 'gill (Canadian and UK (Imperial))' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.420653E-04; } } - attribute 'gill (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.182941E-04; } } - attribute 'gon (also called grade)' : AngularMeasureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = rad; :>> conversionFactor = 1.570796E-02; } } + attribute 'gill (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.182941E-04; :>> isExact = false; } } attribute 'grain' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 6.479891E-05; } } attribute <'gr/gal'> 'grain per gallon (US)' : MassDensityUnit = gr/gal; - //attribute <'gf/cm²'> 'gram-force per square centimeter' : PressureUnit = gf/cm^2; - attribute <'g/cm³'> 'gram per cubic centimeter' : MassDensityUnit = g/cm^3; - attribute 'hectare' : AreaUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2; :>> conversionFactor = 1.0E+04; } } - attribute 'horsepower (550 ft*lbf/s)' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = W; :>> conversionFactor = 7.456999E+02; } } - attribute 'horsepower (boiler)' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = W; :>> conversionFactor = 9.80950E+03; } } + attribute 'horsepower (550 ft*lbf/s)' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = W; :>> conversionFactor = 7.456999E+02; :>> isExact = false; } } + attribute 'horsepower (boiler)' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = W; :>> conversionFactor = 9.80950E+03; :>> isExact = false; } } attribute 'horsepower (electric)' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = W; :>> conversionFactor = 7.46E+02; } } - attribute 'horsepower (metric)' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = W; :>> conversionFactor = 7.354988E+02; } } - attribute 'horsepower (UK)' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = W; :>> conversionFactor = 7.4570E+02; } } - attribute 'horsepower (water)' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = W; :>> conversionFactor = 7.46043E+02; } } - attribute 'hour' : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 3.6E+03; } } - attribute 'hour (sidereal)' : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 3.590170E+03; } } - attribute 'hundredweight (long, 112 lb)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 5.080235E+01; } } - attribute 'hundredweight (short, 100 lb)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 4.535924E+01; } } - //attribute <'in'> 'inch' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 2.54E-02; } } - attribute 'inch of mercury (32 °F)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 3.38638E+03; } } - attribute 'inch of mercury (60 °F)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 3.37685E+03; } } - attribute 'inch of mercury, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 3.386389E+03; } } - attribute 'inch of water (39.2 °F)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 2.49082E+02; } } - attribute 'inch of water (60 °F)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 2.4884E+02; } } - attribute 'inch of water, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 2.490889E+02; } } + attribute 'horsepower (water)' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = W; :>> conversionFactor = 7.46043E+02; :>> isExact = false; } } + attribute 'hundredweight (long, 112 lb)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 5.080235E+01; :>> isExact = false; } } + attribute 'hundredweight (short, 100 lb)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 4.535924E+01; :>> isExact = false; } } + attribute <'in'> 'inch' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 2.54E-02; } } + attribute 'inch of mercury (32 °F)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 3.38638E+03; :>> isExact = false; } } + attribute 'inch of mercury (60 °F)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 3.37685E+03; :>> isExact = false; } } + attribute 'inch of mercury, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 3.386389E+03; :>> isExact = false; } } + attribute 'inch of water (39.2 °F)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 2.49082E+02; :>> isExact = false; } } + attribute 'inch of water (60 °F)' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 2.4884E+02; :>> isExact = false; } } + attribute 'inch of water, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 2.490889E+02; :>> isExact = false; } } attribute <'in/s'> 'inch per second' : SpeedUnit = 'in'/s; attribute <'in/s²'> 'inch per second squared' : AccelerationUnit = 'in'/s^2; attribute <'in⁴'> 'inch to the fourth power' : SecondAxialMomentOfAreaUnit = 'in'^4; - attribute 'kayser' : CurvatureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^-1; :>> conversionFactor = 1.0E+02; } } - attribute 'kelvin' : TemperatureUnit; // conversion TBD - attribute 'kilocalorie (IT)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.1868E+03; } } - attribute 'kilocalorie (th)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.184E+03; } } - attribute 'kilocalorie (mean)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.19002E+03; } } - attribute <'kcal_th/min'> 'kilocalorie (th) per minute' : PowerUnit = kcal_th/min; - attribute <'kcal_th/s'> 'kilocalorie (th) per second' : PowerUnit = kcal_th/s; - attribute 'kilogram-force' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 9.80665E+00; } } - attribute <'kgf⋅m'> 'kilogram-force meter' : MomentOfForceUnit = kgf*m; - attribute <'kgf/cm²'> 'kilogram-force per square centimeter' : PressureUnit = kgf/cm^2; - attribute <'kgf/m²'> 'kilogram-force per square meter' : PressureUnit = kgf/m^2; - attribute <'kgf/mm²'> 'kilogram-force per square millimeter' : PressureUnit = kgf/mm^2; - attribute <'kgf⋅s²/m'> 'kilogram-force second squared per meter' : MassUnit = kgf*s^2/m; - attribute <'km/h'> 'kilometer per hour' : SpeedUnit = km/h; - attribute 'kilopond (kilogram-force)' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 9.80665E+00; } } - attribute <'kW⋅h'> 'kilowatt hour' : EnergyUnit = kW*h; - attribute 'kip (1 kip = 1000 lbf)' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 4.448222E+03; } } + attribute 'kip (1 kip = 1000 lbf)' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 4.448222E+03; :>> isExact = false; } } attribute <'kip/in²'> 'kip per square inch (ksi)' : PressureUnit = kip/'in'^2; - attribute 'knot (nautical mile per hour)' : SpeedUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m/s; :>> conversionFactor = 5.144444E-01; } } - attribute 'lambert' : LuminanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = cd/m^2; :>> conversionFactor = 3.183099E+03; } } - //attribute 'langley' : SurfaceHeatDensityUnit = cal_th/cm^2; - attribute <'l.y.'> 'light year' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 9.46073E+15; } } - attribute 'liter' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.0E-03; } } + attribute 'knot (nautical mile per hour)' : SpeedUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m/s; :>> conversionFactor = 5.144444E-01; :>> isExact = false; } } + //attribute <'cal_th/cm²'> 'langley' : SurfaceHeatDensityUnit = cal_th/cm^2; attribute <'lm/ft²'> 'lumen per square foot' : IlluminanceUnit = lm/ft^2; - attribute 'maxwell' : MagneticFluxUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Wb; :>> conversionFactor = 1.0E-08; } } - attribute 'mho' : ConductanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = S; :>> conversionFactor = 1.0E+00; } } attribute 'microinch' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 2.54E-08; } } - attribute <'μ'> 'micron' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.0E-06; } } - attribute 'mil (0.001 in)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 2.54E-05; } } - attribute 'mil (angle)' : AngularMeasureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = rad; :>> conversionFactor = 9.817477E-04; } } - //attribute 'mile' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.609344E+03; } } - attribute 'mile (based on US survey foot)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.609347E+03; } } - attribute 'mile, nautical' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.852E+03; } } - //attribute <'mi/gal'> 'mile per gallon (US) (mpg)' : FuelEconomyUnit = mi/gal; - //attribute <'mi/h'> 'mile per hour' : SpeedUnit = mi/h; + attribute 'mil (0.001 in)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 2.54E-05; } } + attribute 'mile' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.609344E+03; } } + attribute 'mile (based on US survey foot)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.609347E+03; :>> isExact = false; } } + attribute 'mile, nautical' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 1.852E+03; } } + alias NM for nmi; + //attribute <'mi/gal'> 'mile per gallon (US)' : FuelEconomyUnit = mi/gal; + //alias mpg for 'mi/gal'; + attribute <'mi/h'> 'mile per hour' : SpeedUnit = mi/h; + alias mph for 'mi/h'; attribute <'mi/min'> 'mile per minute' : SpeedUnit = mi/min; attribute <'mi/s'> 'mile per second' : SpeedUnit = mi/s; - attribute 'millibar' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 1.0E+02; } } - attribute 'millimeter of mercury, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 1.333224E+02; } } - attribute 'millimeter of water, conventional' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 9.80665E+00; } } - attribute <'′'> 'minute (angle)' : AngularMeasureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = rad; :>> conversionFactor = 2.908882E-04; } } - attribute 'minute' : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 6.0E+01; } } - attribute 'minute (sidereal)' : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 5.983617E+01; } } - attribute 'oersted' : LinearElectricCurrentDensityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = A/m; :>> conversionFactor = 7.957747E+01; } } - attribute <'Ω⋅cm'> 'ohm centimeter' : ResistivityUnit = 'Ω'*cm; - attribute 'ohm circular-mil per foot' : ResistivityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = 'Ω'*m; :>> conversionFactor = 1.662426E-09; } } - attribute 'ounce (avoirdupois)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 2.834952E-02; } } - attribute 'ounce (troy or apothecary)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 3.110348E-02; } } - attribute 'ounce (Canadian and UK fluid (Imperial))' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 2.841306E-05; } } - attribute 'ounce (US fluid)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 2.957353E-05; } } - attribute 'ounce (avoirdupois)-force' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 2.780139E-01; } } + attribute 'ohm circular-mil per foot' : ResistivityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = 'Ω'*m; :>> conversionFactor = 1.662426E-09; :>> isExact = false; } } + attribute 'ounce (avoirdupois)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 2.834952E-02; :>> isExact = false; } } + attribute 'ounce (US fluid)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 2.957353E-05; :>> isExact = false; } } + attribute 'ounce (avoirdupois)-force' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 2.780139E-01; :>> isExact = false; } } attribute <'ozf⋅in'> 'ounce (avoirdupois)-force inch' : MomentOfForceUnit = ozf*'in'; attribute <'oz/in³'> 'ounce (avoirdupois) per cubic inch' : MassDensityUnit = oz/'in'^3; - attribute <'oz/gal'> 'ounce (avoirdupois) per gallon (Canadian and UK (Imperial))' : MassDensityUnit = oz/gal; - attribute 'ounce (avoirdupois) per gallon (US)' : MassDensityUnit = oz/gal; + attribute <'oz/gal'> 'ounce (avoirdupois) per gallon (US)' : MassDensityUnit = oz/gal; attribute <'oz/ft²'> 'ounce (avoirdupois) per square foot' : SurfaceMassDensityUnit = oz/ft^2; attribute <'oz/in²'> 'ounce (avoirdupois) per square inch' : SurfaceMassDensityUnit = oz/'in'^2; attribute <'oz/yd²'> 'ounce (avoirdupois) per square yard' : SurfaceMassDensityUnit = oz/yd^2; - attribute 'parsec' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 3.085678E+16; } } - attribute 'peck (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 8.809768E-03; } } - attribute 'pennyweight' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 1.555174E-03; } } - //attribute 'perm (0 °C)' : VapourTransmissionUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/(Pa*s*m^2); :>> conversionFactor = 5.72135E-11; } } - //attribute 'perm (23 °C)' : VapourTransmissionUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/(Pa*s*m^2); :>> conversionFactor = 5.74525E-11; } } - //attribute 'perm inch (0 °C)' : VapourTransmissionUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/('Pa·s·m'); :>> conversionFactor = 1.45322E-12; } } - //attribute 'perm inch (23 °C)' : VapourTransmissionUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/('Pa·s·m'); :>> conversionFactor = 1.45929E-12; } } - attribute 'phot' : IlluminanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = lx; :>> conversionFactor = 1.0E+04; } } - attribute 'pica (computer) (1/6 in)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 4.233333E-03; } } - attribute 'pica (printers)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 4.217518E-03; } } - attribute 'pint (US dry)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 5.506105E-04; } } - attribute 'pint (US liquid)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 4.731765E-04; } } - attribute 'point (computer) (1/72 in)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 3.527778E-04; } } - //attribute 'point (printer's)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 3.514598E-04; } } - attribute

'poise' : DynamicViscosityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa*s; :>> conversionFactor = 1.0E-01; } } - //attribute 'pound (avoirdupois)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 4.535924E-01; } } - attribute 'pound (troy or apothecary)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 3.732417E-01; } } - attribute 'poundal' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 1.382550E-01; } } - attribute 'poundal per square foot' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 1.488164E+00; } } - attribute 'poundal second per square foot' : DynamicViscosityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa*s; :>> conversionFactor = 1.488164E+00; } } + attribute 'peck (US)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 8.809768E-03; :>> isExact = false; } } + //attribute 'perm (0 °C)' : VapourTransmissionUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/(Pa*s*m^2); :>> conversionFactor = 5.72135E-11; :>> isExact = false; } } + //attribute 'perm (23 °C)' : VapourTransmissionUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/(Pa*s*m^2); :>> conversionFactor = 5.74525E-11; :>> isExact = false; } } + //attribute 'perm inch (0 °C)' : VapourTransmissionUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/('Pa·s·m'); :>> conversionFactor = 1.45322E-12; :>> isExact = false; } } + //attribute 'perm inch (23 °C)' : VapourTransmissionUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/('Pa·s·m'); :>> conversionFactor = 1.45929E-12; :>> isExact = false; } } + attribute 'pica (computer) (1/6 in)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 4.233333E-03; :>> isExact = false; } } + attribute 'pica (printer′s)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 4.217518E-03; :>> isExact = false; } } + attribute 'pint (US dry)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 5.506105E-04; :>> isExact = false; } } + attribute 'pint (US liquid)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 4.731765E-04; :>> isExact = false; } } + attribute 'point (computer) (1/72 in)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 3.527778E-04; :>> isExact = false; } } + attribute 'point (printer′s)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 3.514598E-04; :>> isExact = false; } } + attribute 'pound (avoirdupois)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 4.535924E-01; :>> isExact = false; } } attribute <'lb⋅ft²'> 'pound foot squared' : MomentOfInertiaUnit = lb*ft^2; - //attribute 'pound-force' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 4.448222E+00; } } + attribute 'pound-force' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 4.448222E+00; :>> isExact = false; } } attribute <'lbf⋅ft'> 'pound-force foot' : MomentOfForceUnit = lbf*ft; attribute <'lbf⋅ft/in'> 'pound-force foot per inch' : ForceUnit = lbf*ft/'in'; attribute <'lbf⋅in'> 'pound-force inch' : MomentOfForceUnit = lbf*'in'; @@ -359,7 +169,8 @@ package USCustomaryUnits { attribute <'lbf/in'> 'pound-force per inch' : SurfaceTensionUnit = lbf/'in'; //attribute 'pound-force per pound (lbf/lb) (thrust to mass ratio)' : ThrustToMassRatioUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N/kg; :>> conversionFactor = 9.80665E+00; } } attribute <'lbf/ft²'> 'pound-force per square foot' : PressureUnit = lbf/ft^2; - attribute <'lbf/in²'> 'pound-force per square inch (psi)' : PressureUnit = lbf/'in'^2; + attribute <'lbf/in²'> 'pound-force per square inch' : PressureUnit = lbf/'in'^2; + alias psi for 'lbf/in²'; attribute <'lbf⋅s/ft²'> 'pound-force second per square foot' : DynamicViscosityUnit = lbf*s/ft^2; attribute <'lbf⋅s/in²'> 'pound-force second per square inch' : DynamicViscosityUnit = lbf*s/'in'^2; attribute <'lb⋅in²'> 'pound inch squared' : MomentOfInertiaUnit = lb*'in'^2; @@ -369,8 +180,7 @@ package USCustomaryUnits { attribute <'lb/ft'> 'pound per foot' : LinearMassDensityUnit = lb/ft; attribute <'lb/(ft⋅h)'> 'pound per foot hour' : DynamicViscosityUnit = lb/(ft*h); attribute <'lb/(ft⋅s)'> 'pound per foot second' : DynamicViscosityUnit = lb/(ft*s); - attribute <'lb/gal'> 'pound per gallon (Canadian and UK (Imperial))' : MassDensityUnit = lb/gal; - attribute 'pound per gallon (US)' : MassDensityUnit = lb/gal; + attribute <'lb/gal'> 'pound per gallon (US)' : MassDensityUnit = lb/gal; //attribute <'lb/(hp⋅h)'> 'pound per horsepower hour' : FuelConsumptionUnit = lb/(hp*h); attribute <'lb/h'> 'pound per hour' : MassFlowRateUnit = lb/h; attribute <'lb/in'> 'pound per inch' : LinearMassDensityUnit = lb/'in'; @@ -379,22 +189,12 @@ package USCustomaryUnits { attribute <'lb/ft²'> 'pound per square foot' : SurfaceMassDensityUnit = lb/ft^2; attribute <'lb/in²'> 'pound per square inch (not pound-force)' : SurfaceMassDensityUnit = lb/'in'^2; attribute <'lb/yd'> 'pound per yard' : LinearMassDensityUnit = lb/yd; - attribute 'psi (pound-force per square inch)' : PressureUnit = lbf/'in'^2; - attribute 'quad (10^15 Btu_IT)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.055056E+18; } } - attribute 'quart (US dry)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.101221E-03; } } - attribute 'quart (US liquid)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 9.463529E-04; } } - attribute 'rad (absorbed dose)' : AbsorbedDoseUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Gy; :>> conversionFactor = 1.0E-02; } } - attribute 'rem' : DoseEquivalentUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Sv; :>> conversionFactor = 1.0E-02; } } - attribute 'revolution' : AngularMeasureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = rad; :>> conversionFactor = 6.283185E+00; } } - attribute <'r/min'> 'revolution per minute (rpm)' : AngularVelocityUnit = r/min; - //attribute 'rhe' : ReciprocalDynamicViscosityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa^-1*s^-1; :>> conversionFactor = 1.0E+01; } } - attribute 'rod (based on US survey foot)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 5.029210E+00; } } - attribute 'roentgen' : ExposureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = C/kg; :>> conversionFactor = 2.58E-04; } } - attribute 'rpm (revolution per minute)' : AngularVelocityUnit = r/min; - attribute <'″'> 'second (angle)' : AngularMeasureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = rad; :>> conversionFactor = 4.848137E-06; } } - attribute 'second (sidereal)' : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 9.972696E-01; } } - attribute 'shake' : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 1.0E-08; } } - attribute 'slug' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 1.459390E+01; } } + attribute 'pound-force per square inch (psi)' : PressureUnit = lbf/'in'^2; + attribute 'quad (10^15 Btu_IT)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.055056E+18; :>> isExact = false; } } + attribute 'quart (US dry)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.101221E-03; :>> isExact = false; } } + attribute 'quart (US liquid)' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 9.463529E-04; :>> isExact = false; } } + attribute 'rod (based on US survey foot)' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 5.029210E+00; :>> isExact = false; } } + attribute 'slug' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 1.459390E+01; :>> isExact = false; } } attribute <'slug/ft³'> 'slug per cubic foot' : MassDensityUnit = slug/ft^3; attribute <'slug/(ft⋅s)'> 'slug per foot second' : DynamicViscosityUnit = slug/(ft*s); attribute <'ft²'> 'square foot' : AreaUnit = ft^2; @@ -402,44 +202,49 @@ package USCustomaryUnits { attribute <'ft²/s'> 'square foot per second' : KinematicViscosityUnit = ft^2/s; attribute <'in²'> 'square inch' : AreaUnit = 'in'^2; attribute <'mi²'> 'square mile' : AreaUnit = mi^2; - attribute 'square mile (based on US survey foot)' : AreaUnit = mi^2; + attribute 'square mile (based on US survey foot)' : AreaUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2; :>> conversionFactor = 2.589998E+06; :>> isExact = false; } } attribute <'yd²'> 'square yard' : AreaUnit = yd^2; - //attribute 'statampere' : ElectricCurrentUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = A; :>> conversionFactor = 3.335641E-10; } } - attribute 'statcoulomb' : ElectricChargeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = C; :>> conversionFactor = 3.335641E-10; } } - //attribute 'statfarad' : CapacitanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = F; :>> conversionFactor = 1.112650E-12; } } - //attribute 'stathenry' : InductanceUnit, PermeanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = H; :>> conversionFactor = 8.987552E+11; } } - attribute 'statmho' : ConductanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = S; :>> conversionFactor = 1.112650E-12; } } - //attribute 'statohm' : ResistanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = 'Ω'; :>> conversionFactor = 8.987552E+11; } } - //attribute 'statvolt' : ElectricPotentialUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = V; :>> conversionFactor = 2.997925E+02; } } - attribute 'stere' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.0E+00; } } - attribute 'stilb' : LuminanceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = cd/m^2; :>> conversionFactor = 1.0E+04; } } - attribute 'stokes' : KinematicViscosityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^2/s; :>> conversionFactor = 1.0E-04; } } - attribute 'tablespoon' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.478676E-05; } } - attribute 'teaspoon' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 4.928922E-06; } } - attribute 'tex' : LinearMassDensityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/m; :>> conversionFactor = 1.0E-06; } } + attribute 'tablespoon' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 1.478676E-05; :>> isExact = false; } } + attribute 'teaspoon' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 4.928922E-06; :>> isExact = false; } } attribute 'therm (EC)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.05506E+08; } } attribute 'therm (US)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 1.054804E+08; } } - attribute 'ton, assay' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 2.916667E-02; } } - attribute 'ton-force (2000 lbf)' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 8.896443E+03; } } - attribute 'ton, long (2240 lb)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 1.016047E+03; } } - attribute 'ton, long, per cubic yard' : MassDensityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/m^3; :>> conversionFactor = 1.328939E+03; } } - attribute 'ton, metric' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 1.0E+03; } } - attribute 'tonne (called "metric ton" in US)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 1.0E+03; } } - attribute 'ton of refrigeration (12 000 Btu_IT/h)' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = W; :>> conversionFactor = 3.516853E+03; } } - attribute 'ton of TNT (energy equivalent)' : EnergyUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = J; :>> conversionFactor = 4.184E+09; } } - attribute 'ton, register' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 2.831685E+00; } } - attribute 'ton, short (2000 lb)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 9.071847E+02; } } - attribute 'ton, short, per cubic yard' : MassDensityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/m^3; :>> conversionFactor = 1.186553E+03; } } - attribute 'ton, short, per hour' : MassFlowRateUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/s; :>> conversionFactor = 2.519958E-01; } } - attribute 'torr' : PressureUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Pa; :>> conversionFactor = 1.333224E+02; } } - attribute 'unit pole' : MagneticFluxUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Wb; :>> conversionFactor = 1.256637E-07; } } - attribute <'W⋅h'> 'watt hour' : EnergyUnit = W*h; - attribute <'W/cm²'> 'watt per square centimeter' : DensityOfHeatFlowRateUnit = W/cm^2; + attribute 'ton, assay' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 2.916667E-02; :>> isExact = false; } } + attribute 'ton-force (2000 lbf)' : ForceUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = N; :>> conversionFactor = 8.896443E+03; :>> isExact = false; } } + attribute 'ton, long (2240 lb)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 1.016047E+03; :>> isExact = false; } } + attribute 'ton, long, per cubic yard' : MassDensityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/m^3; :>> conversionFactor = 1.328939E+03; :>> isExact = false; } } + attribute 'ton of refrigeration (12 000 Btu_IT/h)' : PowerUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = W; :>> conversionFactor = 3.516853E+03; :>> isExact = false; } } + attribute 'ton, register' : VolumeUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m^3; :>> conversionFactor = 2.831685E+00; :>> isExact = false; } } + attribute 'ton, short (2000 lb)' : MassUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg; :>> conversionFactor = 9.071847E+02; :>> isExact = false; } } + attribute 'ton, short, per cubic yard' : MassDensityUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/m^3; :>> conversionFactor = 1.186553E+03; :>> isExact = false; } } + attribute 'ton, short, per hour' : MassFlowRateUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = kg/s; :>> conversionFactor = 2.519958E-01; :>> isExact = false; } } + attribute 'unit pole' : MagneticFluxUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = Wb; :>> conversionFactor = 1.256637E-07; :>> isExact = false; } } attribute <'W/in²'> 'watt per square inch' : DensityOfHeatFlowRateUnit = W/'in'^2; - attribute <'W⋅s'> 'watt second' : EnergyUnit = W*s; attribute 'yard' : LengthUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = m; :>> conversionFactor = 9.144E-01; } } - attribute 'year (365 days)' : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 3.1536E+07; } } - attribute 'year (sidereal)' : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 3.155815E+07; } } - attribute 'year (tropical)' : DurationUnit { :>> unitConversion: ConversionByConvention { :>> referenceUnit = s; :>> conversionFactor = 3.155693E+07; } } + + + /* + * degree Fahrenheit interval scale for absolute (thermodynamic) temperature quantities + * + * The scale is defined with an explicit mapping to the degree Celsius interval scale and a coordinate transformation w.r.t. the kelvin scale + */ + attribute <'°F_abs'> 'degree fahrenheit (absolute)' : IntervalScale { + :>> unit = '°F'; + private attribute temperatureWaterAtFreezingPointInF: DefinitionalQuantityValue { + :>> num = 32.0; + :>> definition = "temperature in degree Fahrenheit of pure water at freezing point"; + } + private attribute fahrenheitToCelsiusScaleMapping: QuantityValueMapping { + :>> mappedQuantityValue = temperatureWaterAtFreezingPointInF; + :>> referenceQuantityValue = '°C_abs'.temperatureWaterAtFreezingPointInC; + + } + attribute :>> definitionalQuantityValues = temperatureWaterAtFreezingPointInF; + attribute :>> quantityValueMapping = fahrenheitToCelsiusScaleMapping; + + /* CoordinateTransformation (zero shift) w.r.t. thermodynamic temperature in kelvin */ + private attribute zeroDegreeFahrenheitInKelvin: ThermodynamicTemperatureValue = 229835/900 [K]; + attribute zeroShift : CoordinateTransformation { :>> source = K; :>> target = self; :>> origin = zeroDegreeFahrenheitInKelvin; :>> basisDirections = 1 [K]; } + attribute :>> placement = zeroShift; + } } diff --git a/sysml.library/Domain Libraries/Quantities and Units/UnitsAndScales.sysml b/sysml.library/Domain Libraries/Quantities and Units/UnitsAndScales.sysml index 1af1510a..cf4a8601 100644 --- a/sysml.library/Domain Libraries/Quantities and Units/UnitsAndScales.sysml +++ b/sysml.library/Domain Libraries/Quantities and Units/UnitsAndScales.sysml @@ -22,14 +22,15 @@ package UnitsAndScales { * to a single dimensional measurement reference for a scalar quantity. The measurement references for all dimensions of a * quantity are specified through the mRefs attribute. Each element of mRefs is a ScalarMeasurementReference. * - * The longName of a TensorMeasurementReference is the spelled-out human readable name of the measurement reference. - * For example, typical measurement units for the speed quantity would have the longName "metre per second", "kilometre per hour", - * "mile per hour". + * The humanId of a TensorMeasurementReference is the unique symbol by which the measurement reference is known. + * The name of a TensorMeasurementReference is spelled-out human readable name of the measurement reference. + * For example, typical measurement units for the speed quantity would have the respective humanId and name: + * <'m/s'> and 'metre per second', + * <'km/h'> and 'kilometre per hour', + * <'mi/h'> and 'mile per hour'. * * A measurement reference can have zero or more definitionalQuantityValues that allows to specify * quantity values that carry a particular meaning or relevance for the measurement reference. - * - * To stress the generality of the TensorMeasurementReference the alias MeasurementReference is defined. */ attribute def TensorMeasurementReference :> Array { attribute isBound: Boolean[1] default false; @@ -37,7 +38,6 @@ package UnitsAndScales { attribute mRefs: ScalarMeasurementReference[1..*] :>> elements; attribute definitionalQuantityValues: DefinitionalQuantityValue[0..*]; } - alias MeasurementReference for TensorMeasurementReference; /** * A VectorMeasurementReference is a specialization of TensorMeasurementReference for vector quantities that are @@ -45,8 +45,8 @@ package UnitsAndScales { * The `n` basis unit vectors that span the vector space are defined by the mRefs which each are * a ScalarMeasurementReference, typically a MeasurementUnit or an IntervalScale. * - * Pairwise VectorQuantityValue and VectorMeasurementReference specializations can also be used to define a vector space - * for state vectors as used in state-space representation models. + * A pair of a specialization of VectorQuantityValue and a specialization of VectorMeasurementReference can also be used to + * define a vector space for state vectors as used in state-space representation models. * * Attribute isOrthogonal declares whether the basis vectors of the vector space are orthogonal, i.e. whether the * inner products of any pair of basis vectors yield zero. @@ -140,10 +140,13 @@ package UnitsAndScales { /** * Representation of the linear conversion relationship between one measurement unit and another measurement unit, that acts as a reference. + * + * Attribute isExact asserts whether the conversionFactor is exact or not. By default it is set true. */ abstract attribute def UnitConversion { attribute referenceUnit: MeasurementUnit; attribute conversionFactor: Real; + attribute isExact: Boolean default true; } /** @@ -249,7 +252,7 @@ package UnitsAndScales { } /** - * Representation of a particular quantity value that is used in the definition of a MeasurementReference + * Representation of a particular quantity value that is used in the definition of a TensorMeasurementReference * * Typically such a particular value is defined by convention. It can be used to define a selected reference value, * such as the meaning of zero on a measurement scale or the origin of a top-level coordinate system. @@ -292,9 +295,12 @@ package UnitsAndScales { * for a given system of quantities". * The base units are a particular selection of measurement units for each of the base quantities of a system of quantities, * that form the basis on top of which all other (derived) units are defined. + * + * Attribute systemOfQuantities speficies the associated SystemOfQuantities. */ attribute def SystemOfUnits { attribute longName: String[1]; + attribute systemOfQuantities : SystemOfQuantities[1]; attribute baseUnits: SimpleUnit[1..*] ordered; } diff --git a/sysml.library/Domain Libraries/Quantities and Units/VectorCalculations.sysml b/sysml.library/Domain Libraries/Quantities and Units/VectorCalculations.sysml index e74e2a4e..736d2e76 100644 --- a/sysml.library/Domain Libraries/Quantities and Units/VectorCalculations.sysml +++ b/sysml.library/Domain Libraries/Quantities and Units/VectorCalculations.sysml @@ -1,6 +1,6 @@ package VectorCalculations { import ScalarValues::*; - import Quantities::*; + import Quantities::VectorQuantityValue; /* Vector addition and subtraction */ calc def '+' specializes NumericalFunctions::'+' (x: VectorQuantityValue, y: VectorQuantityValue): VectorQuantityValue; diff --git a/sysml.library/Kernel Library/Clocks.kerml b/sysml.library/Kernel Library/Clocks.kerml new file mode 100644 index 00000000..35b3dccc --- /dev/null +++ b/sysml.library/Kernel Library/Clocks.kerml @@ -0,0 +1,112 @@ +/* + * This package models Clocks that provide an advancing numerical reference + * usable for quantifying the time of an Occurrence. + */ +package Clocks { + private import ScalarValues::NumericalValue; + private import ScalarValues::Real; + private import Occurrences::Occurrence; + private import ControlFunctions::forAll; + + /** + * defaultClock is a single Clock that can be used as a default. + */ + readonly feature defaultClock : Clock[1]; + + /** + * A Clock provides a numerical currentTime that advances montonically + * over its lifetime. Clock is an abstract base Structure that can be + * specialized for different kinds of time quantification (e.g., discrete + * time, continuous time, time with units, etc.). + */ + abstract struct Clock { + private thisClock : Clock :>> self; + /** + * A scalar time reference that advances over the lifetime of the Clock. + */ + readonly feature currentTime : NumericalValue[1]; + + /** + * The currentTime of a snapshot of a Clock is equal to + * the TimeOf the snapshot relative to that Clock. + */ + inv timeFlowConstraint { + snapshots->forAll{in s : Clock; + TimeOf(s, thisClock) == s.currentTime + } + } + } + + /** + * TimeOf returns a numerical timeInstant for a given Occurrence relative to + * a given Clock. The timeInstant is the time of the start of the Occurrence, + * which is considered to be synchronized with the snapshot of the Clock + * with a currentTime equal to the returned timeInstant. + */ + abstract function TimeOf { + in o : Occurrence[1]; + in clock : Clock[1] default defaultClock; + return timeInstant : NumericalValue[1]; + + /** + * The TimeOf an Occurrence is equal to the time of its start snapshot. + */ + inv startTimeConstraint { + timeInstant == TimeOf(o.startShot, clock) + } + + /** + * If one Occurrence happens before another, then the TimeOf the end + * snapshot of the first Occurrence is no greater than the TimeOf the + * second Occurrence. + */ + inv timeOrderingConstraint { + o.predecessors->forAll{in p : Occurrence; + TimeOf(p.endShot, clock) <= timeInstant + } + } + + /** + * If one Occurrence happens immediately before another, then the TimeOf + * the end snapshot of the first Occurrence equals the TimeOf the second + * Occurrence. + */ + inv timeContinuityConstraint { + o.immediatePredecessors->forAll{in p : Occurrence; + TimeOf(p.endShot, clock) == timeInstant + } + } + } + + /** + * DurationOf returns the duration of a given Occurrence relative to a + * given Clock, which is equal to the TimeOf the end snapshot of the + * Occurrence minus the TimeOf its start snapshot. + */ + function DurationOf { + in o : Occurrence[1]; + in clock : Clock[1] default defaultClock; + return duration : NumericalValue = + TimeOf(o.endShot, clock) - TimeOf(o.startShot, clock); + } + + /** + * A BasicClock is a Clock whose currentTime is a Real number. + */ + struct BasicClock :> Clock { + readonly feature :>> currentTime : Real; + } + + /** + * BasicTimeOf returns the TimeOf an Occurrence as a Real number relative + * to a BasicClock. + */ + function BasicTimeOf :> TimeOf(o : Occurrence[1], clock : BasicClock[1]) : Real[1]; + + /** + * BasicDurationOf returns the DurationOf an Occurrence as a Real number relative + * to a BasicClock. + */ + function BasicDurationOf :> DurationOf(o : Occurrence[1], clock : BasicClock[1]) : Real[1]; + +} \ No newline at end of file diff --git a/sysml.library/Kernel Library/FeatureAccessPerformances.kerml b/sysml.library/Kernel Library/FeatureAccessPerformances.kerml deleted file mode 100644 index 6ef306b5..00000000 --- a/sysml.library/Kernel Library/FeatureAccessPerformances.kerml +++ /dev/null @@ -1,71 +0,0 @@ -/** - * This package defines Behaviors used to read and write values of a referenced Feature of an Occurrence - * as of the time the Performance of the Behavior ends. - */ -package FeatureAccessPerformances { - private import Base::Anything; - private import Base::things; - private import Occurrences::Occurrence; - private import Occurrences::HappensWhile; - private import Occurrences::SelfSameLifeLink; - private import Performances::Performance; - private import Performances::Evaluation; - - /** - * A FeatureReferencingPerformance is the base Performance for specialized behaviors related - * to values of one more more referenced Features, as identified in specializations of this - * Behavior. - */ - abstract behavior FeatureReferencingPerformance specializes Performance { - - /** - * Occurrence with values for the referenced feature in specializations of this behavior. - */ - in abstract feature onOccurrence : Occurrence [1]; - - /** - * Values of the referenced feature, as specified in specializations of this behavior. - */ - inout feature values : Anything [*] nonunique; - } - - /** - * A FeatureAccessPerformance is a FeatureReferencingPerformance where the result values - * are all the values of a feature of onOccurrence at the time the Performance ends. The - * feature is specified by restricting accessedFeature in specializations or usages. - */ - abstract behavior FeatureAccessPerformance specializes FeatureReferencingPerformance { - - in abstract feature onOccurrence : Occurrence { - abstract feature startingAt : Occurrence [1] subsets timeSlices { - abstract feature accessedFeature : Anything [*] nonunique; - } - } - - /** - * Requires some time slice of onOccurrence to start when this performance - * ends (this connector), with particular feature values (following connector). - * The feature is specified by restricting the onOccurrence::accessedFeature - * on usages of this behavior. - */ - connector :HappensWhile from onOccurrence.startingAt.startShot to endShot; - connector :SelfSameLifeLink from onOccurrence.startingAt.accessedFeature to values; - } - - /** - * A FeatureReadEvaluation is a FeatureAccessPerformance that is a function providing as - * its result the values of a feature on an occurrence at the time its evaluation ends. - */ - abstract function FeatureReadEvaluation specializes FeatureAccessPerformance, Evaluation - (onOccurrence: Occurrence [1]) - resultValues : Anything [*] nonunique redefines result redefines values; - - /** - * A FeatureWritePerformance is a FeatureAccessPerformance that assigns the values of a - * feature on an occurrence to the given replacementValues at time its performance ends. - */ - abstract behavior FeatureWritePerformance specializes FeatureAccessPerformance { - in feature onOccurrence : Occurrence[1] redefines onOccurrence; - inout feature replacementValues : Anything redefines values [*] nonunique; - } -} \ No newline at end of file diff --git a/sysml.library/Kernel Library/FeatureReferencingPerformances.kerml b/sysml.library/Kernel Library/FeatureReferencingPerformances.kerml new file mode 100644 index 00000000..80fb50e9 --- /dev/null +++ b/sysml.library/Kernel Library/FeatureReferencingPerformances.kerml @@ -0,0 +1,160 @@ +/** + * This package defines Behaviors used to read, write and monitor values of a referenced Feature of an + * Occurrence. + */ +package FeatureReferencingPerformances { + private import Base::Anything; + private import Base::things; + private import Occurrences::Occurrence; + private import Occurrences::HappensWhile; + private import Occurrences::HappensBefore; + private import Occurrences::HappensJustBefore; + private import Occurrences::SelfSameLifeLink; + private import Performances::Performance; + private import Performances::Evaluation; + private import ScalarValues::Boolean; + private import SequenceFunctions::isEmpty; + private import SequenceFunctions::equals; + + /** + * A FeatureReferencingPerformance is the base Performance for specialized behaviors related + * to values of a referenced Feature of a given Occurrence, as identified in specializations + * of this Behavior. + */ + abstract behavior FeatureReferencingPerformance specializes Performance { + + /** + * Occurrence with values for the referenced feature in specializations of this behavior. + */ + in abstract feature onOccurrence : Occurrence [1]; + + /** + * Values of the referenced feature, as specified in specializations of this behavior. + */ + inout feature values : Anything [*] nonunique; + } + + /** + * A FeatureAccessPerformance is a FeatureReferencingPerformance where the result values + * are all the values of a feature of onOccurrence at the time the Performance ends. The + * feature is specified by restricting accessedFeature in specializations or usages. + */ + abstract behavior FeatureAccessPerformance specializes FeatureReferencingPerformance { + + in abstract feature onOccurrence : Occurrence { + abstract feature startingAt : Occurrence [1] subsets timeSlices { + abstract feature accessedFeature : Anything [*] nonunique; + } + } + + /** + * Requires some time slice of onOccurrence to start when this performance + * ends (this connector), with particular feature values (following connector). + * The feature is specified by restricting the onOccurrence::accessedFeature + * on usages of this behavior. + */ + connector :HappensWhile from onOccurrence.startingAt.startShot to endShot; + connector :SelfSameLifeLink from onOccurrence.startingAt.accessedFeature to values; + } + + /** + * A FeatureReadEvaluation is a FeatureAccessPerformance that is a function providing as + * its result the values of a feature on an occurrence at the time its evaluation ends. + */ + abstract function FeatureReadEvaluation specializes FeatureAccessPerformance, Evaluation + (onOccurrence: Occurrence [1]) + resultValues : Anything [*] nonunique redefines result redefines values; + + /** + * A FeatureWritePerformance is a FeatureAccessPerformance that assigns the values of a + * feature on an occurrence to the given replacementValues at time its performance ends. + */ + abstract behavior FeatureWritePerformance specializes FeatureAccessPerformance { + in feature onOccurrence : Occurrence[1] redefines onOccurrence; + inout feature replacementValues : Anything redefines values [*] nonunique; + } + + /** + * A FeatureMonitorPerformance is a FeatureReferencingPerformance that waits for values + * of monitoredFeature to change on onOccurrence from what they were when the performance + * started. The values before and after the change are given by beforeValues and afterValues. + */ + abstract behavior FeatureMonitorPerformance specializes FeatureReferencingPerformance { + in feature redefines onOccurrence { + feature monitoredOccurrence : Occurrence [1] subsets timeSlices { + abstract feature monitoredFeature : Anything[*] nonunique; + feature beforeTimeSlice : Occurrence [1] subsets timeSlices { + feature redefines monitoredFeature; + } + feature afterSnapshot : Occurrence [1] subsets snapshots { + feature redefines monitoredFeature; + } + connector :HappensJustBefore from beforeTimeSlice to afterSnapshot; + } + } + out feature afterValues redefines values; + out feature beforeValues : Anything[*] nonunique; + inv { not beforeValues->equals(afterValues) } + + private connector : HappensWhile + from onOccurrence.monitoredOccurrence.beforeTimeSlice.startShot[1] to startShot[1]; + private connector : SelfSameLifeLink + from onOccurrence.monitoredOccurrence.beforeTimeSlice.monitoredFeature[1] to beforeValues[1]; + private connector : SelfSameLifeLink + from onOccurrence.monitoredOccurrence.afterSnapshot.monitoredFeature[1] to afterValues[1]; + protected connector endWhen : HappensBefore + from onOccurrence.monitoredOccurrence.afterSnapshot[1] to endShot[1]; + } + + /** + * An EvaluationResultMonitorPerformance is a FeatureMonitorPerformance that waits for changes + * in the result of an Evaluation identified by onOccurrence. The Predicate being evaluated must + * be able to produce multiple results over time, for example by only using BindingConnectors + * between Steps, rather than Successions or ItemFlows, including in its Step behaviors. + */ + + behavior EvaluationResultMonitorPerformance specializes FeatureMonitorPerformance { + in feature onOccurrence : Evaluation redefines onOccurrence { + protected monitoredOccurrence : Evaluation [1] redefines monitoredOccurrence { + out result : Anything[*] redefines result, monitoredFeature; + } + } + } + + /** + * A BooleanEvaluationResultMonitorPerformance is a EvaluationResultMonitorPerformance + * that waits for changes in the result of a BooleanEvaluation identified by onOccurrence. + */ + behavior BooleanEvaluationResultMonitorPerformance specializes EvaluationResultMonitorPerformance { + in bool redefines onOccurrence { + protected bool redefines monitoredOccurrence[1]; + } + out redefines afterValues : Boolean [1]; + out redefines beforeValues : Boolean [1]; + } + + /** + * A BooleanEvaluationResultToMonitorPerformance is a FeatureReferencingPerformance that waits + * for the result of a BooleanEvaluation (identified by onOccurrence) to change to either true + * or false, as indicated by isToTrue (defaulting to true). If the result is already true (or false), + * the performance waits for the result to become false (or true) before waiting again for it to + * change back. + */ + behavior BooleanEvaluationResultToMonitorPerformance specializes FeatureReferencingPerformance { + in bool redefines onOccurrence; + feature isToTrue : Boolean [1] default true; + out afterValues: Boolean[1] redefines values = isToTrue; + private feature monitor1 : BooleanEvaluationResultMonitorPerformance [1] { + feature redefines endWhen : HappensJustBefore; + } + private feature monitor2 : BooleanEvaluationResultMonitorPerformance [1] { + feature redefines endWhen : HappensJustBefore; + } + + private connector : HappensJustBefore from monitor1 [1] to monitor2 [0..1]; + inv { isEmpty(monitor2) == (monitor1.afterValues == isToTrue) } + + private binding monitor1.onOccurrence[1] = onOccurrence[1]; + private binding monitor2.onOccurrence[1] = onOccurrence[1]; + } +} \ No newline at end of file diff --git a/sysml.library/Kernel Library/Observation.kerml b/sysml.library/Kernel Library/Observation.kerml new file mode 100644 index 00000000..e45c698c --- /dev/null +++ b/sysml.library/Kernel Library/Observation.kerml @@ -0,0 +1,125 @@ + +/* + * This package models a framework for monitoring Boolean conditions and notifying + * registered observers when they change from false to true. + */ +package Observation { + private import ScalarValues::Boolean; + private import Occurrences::Occurrence; + private import SequenceFunctions::including; + private import SequenceFunctions::excluding; + private import ControlFunctions::select; + private import ControlPerformances::DecisionPerformance; + private import ControlPerformances::IfThenPerformance; + private import FeatureReferencingPerformances::FeatureWritePerformance; + private import FeatureReferencingPerformances::BooleanEvaluationResultToMonitorPerformance; + private import Transfers::TransferBefore; + + /** + * defaultMonitor is a single ChangeMonitor that can be used as a default. + */ + readonly feature defaultMonitor[1] : ChangeMonitor; + + /** + * A ChangeSignal is a signal to be sent when the Boolean result of its + * changeCondition Expression changes from false to true. + */ + struct ChangeSignal { + /** + * A BooleanExpression whose result is being monitored. + */ + bool signalCondition; + + /** + * The ChangeMonitor responsible for monitoring the signalCondition. + */ + feature signalMonitor : ChangeMonitor; + } + + /** + * Each Performance of ObserveChange waits for the result of the Boolean + * condition of a given ChangeSignal to change from false to true, and, when + * it does, sends the ChangeSignal to a given observer Occurrence. + */ + private behavior ObserveChange { + in feature changeObserver : Occurrence[1]; + in feature changeSignal : ChangeSignal[1]; + + /** + * If the result of the changeSignal.signalCondition is false, then wait for + * it to become true. + */ + composite step wait : IfThenPerformance { + in bool redefines ifTest { + not changeSignal.signalCondition() + } + in step redefines thenClause : BooleanEvaluationResultToMonitorPerformance { + in bool onOccurrence = changeSignal.signalCondition; + } + } + + succession wait then transfer; + + /** + * Then send changeSignal to changeObserver. + */ + step transfer : TransferBefore[1] + redefines outgoingTransfersFromSelf + subsets changeObserver.incomingTransfers { + feature redefines source { + feature redefines sourceOutput = changeSignal; + } + } + } + + /** + * A ChangeMonitor is a collection of ongoing ChangeSignal observations + * for various observer Occurrences. It provides convenient operations for + * starting and canceling the observations it manages. + */ + struct ChangeMonitor { + private thisMonitor : ChangeMonitor redefines self; + private composite feature observations[0..*] : ObserveChange; + + /** + * Assign a replacement set of observations as those being managed by a + * given ChangeMonitor. + */ + private behavior AssignObservations specializes FeatureWritePerformance { + in feature monitor : ChangeMonitor redefines onOccurrence { + feature redefines startingAt { + feature redefines accessedFeature, observations; + } + } + inout feature redefines replacementValues[0..*] : ObserveChange; + } + + /** + * Start an observation of a given ChangeSignal for a given Occurrence. + */ + step startObservation(in observer : Occurrence[1], in signal : ChangeSignal[1]) { + private composite step observation : ObserveChange { + in changeObserver = observer; + in changeSignal = signal; + } + private composite step addObservation : AssignObservations[1] { + in monitor = thisMonitor; + inout replacementValues = observations->including(observation); + } + } + + /** + * Cancel all observations of a given ChangeSignal for a given Occurrence. + */ + step cancelObservation(in observer : Occurrence[1], in signal : ChangeSignal[1]) { + private feature observations[0..*] : ObserveChange = + observations->select{in observation : ObserveChange; + observation.changeObserver == observer and observation.changeSignal == signal + }; + private composite step removeObservation : AssignObservations[1] { + in monitor = thisMonitor; + inout replacementValues = observations->excluding(observations); + } + } + } +} \ No newline at end of file diff --git a/sysml.library/Kernel Library/Triggers.kerml b/sysml.library/Kernel Library/Triggers.kerml new file mode 100644 index 00000000..9e13119a --- /dev/null +++ b/sysml.library/Kernel Library/Triggers.kerml @@ -0,0 +1,138 @@ +/** + * This package contains functions that return ChangeSignals for triggering + * when a Boolean condition changes from false to true, at a specific time + * or after a specific time delay. + */ +package Triggers { + private import ScalarValues::Boolean; + private import ScalarValues::NumericalValue; + private import Occurrences::Occurrence; + + import Clocks::*; + import Observation::*; + + /** + * A TimeSignal is a ChangeSignal whose condition is the currentTime + * of a given Clock reaching a specific signalTime. + */ + struct TimeSignal :> ChangeSignal { + /** + * The time at which the TimeSignal should be sent. + */ + feature signalTime : NumericalValue[1]; + + /** + * The Clock whose currentTime is being monitored. + */ + feature signalClock : Clock[1]; + + /** + * The Boolean condition of the currentTime of the signalClock being + * equal to the signalTime. + */ + private bool :>> signalCondition { + signalClock.currentTime == signalTime + } + } + + /** + * TriggerWhen returns a monitored ChangeSignal for a given condition, + * to be sent to a given receiver when the condition occurs. + */ + function TriggerWhen { + /** + * The BooleanExpression to be monitored for changing from + * false to true. + */ + in bool condition[1]; + + /** + * The Occurrence to which the ChangeSignal is to be sent. + */ + in feature receiver : Occurrence [1]; + + /** + * The ChangeMonitor to be used to monitor the ChangeSignal condition. + * The default is the Observation::defaultMonitor. + */ + in feature monitor : ChangeMonitor[1] default defaultMonitor; + + /** + * The ChangeSignal for the condition, as monitored by the monitor. + */ + return feature signal : ChangeSignal[1] = ChangeSignal(condition, monitor); + + step :> monitor.startObservation(receiver, signal); + } + + /** + * TriggerAt returns a monitored TimeSignal to be sent to a receiver when + * the currentTime of a given Clock reaches a specific timeInstant. + */ + function TriggerAt { + /** + * The time instant, relative to the clock, at which the TimeSignal should be sent. + */ + in feature timeInstant : NumericalValue[1]; + + /** + * The Occurrence to which the TimeSignal is to be sent. + */ + in feature receiver : Occurrence[1]; + + /** + * The Clock to be used as the reference for the timeInstant. The default is + * the Clocks::defaultClock. + */ + in feature clock : Clock[1] default defaultClock; + + /** + * The ChangeMonitor to be used to monitor the TimeSignal condition. + * The default is the Observation::defaultMonitor. + */ + in feature monitor : ChangeMonitor[1] default defaultMonitor; + + /** + * The TimeSignal for the given timeInstant, as monitored by the monitor. + */ + return feature signal : TimeSignal[1] = TimeSignal(timeInstant, clock, monitor); + + step :> monitor.startObservation(receiver, signal); + } + + /** + * TriggerAfter returns a monitored TimeSignal to be sent to a receiver after + * a certain time delay relative to a given Clock. + */ + function TriggerAfter { + /** + * The time duration, relative to the clock, after which the TimeSignal is sent. + */ + in feature delay : NumericalValue[1]; + + /** + * The Occurrence to which the TimeSignal is to be sent. + */ + in feature receiver : Occurrence[1]; + + /** + * The Clock to be used as the reference for the time delay. The default is + * the Clocks::defaultClock. + */ + in feature clock : Clock[1] default defaultClock; + + /** + * The ChangeMonitor to be used to monitor the TimeSignal condition. + * The default is the Observation::defaultMonitor. + */ + in feature monitor : ChangeMonitor[1] default defaultMonitor; + + /** + * The TimeSignal for the currentTime of the clock when the function is invoked + * plus the given time delay, as monitored by the monitor. + */ + return signal : TimeSignal[1] = + TriggerAt(clock.currentTime + delay, receiver, clock, monitor); + } + +} \ No newline at end of file diff --git a/sysml.library/Systems Library/Actions.sysml b/sysml.library/Systems Library/Actions.sysml index c71f9d95..76fd5f38 100644 --- a/sysml.library/Systems Library/Actions.sysml +++ b/sysml.library/Systems Library/Actions.sysml @@ -9,7 +9,7 @@ package Actions { private import Occurrences::Occurrence; private import Performances::Performance; private import Performances::performances; - private import FeatureAccessPerformances::FeatureWritePerformance; + private import FeatureReferencingPerformances::FeatureWritePerformance; private import Transfers::TransferBefore; private import ControlPerformances::MergePerformance; private import ControlPerformances::DecisionPerformance; @@ -135,7 +135,7 @@ package Actions { * incomingTransferFromSelf that is one of the incomingTransfers of a given receiver Occurrence, * outputting the payload from the Transfer. */ - action def AcceptAction(out payload[0..*], in receiver: Occurrence[1]) { + action def AcceptAction(inout payload[0..*], in receiver: Occurrence[1]) { ref incomingTransfer: TransferBefore[1] :>> incomingTransfersToSelf :> receiver.incomingTransfers { ref :>> target: AcceptAction { ref :>> targetInput = payload; diff --git a/sysml.library/Systems Library/SysML.sysml b/sysml.library/Systems Library/SysML.sysml index 5429ebb8..4c117885 100644 --- a/sysml.library/Systems Library/SysML.sysml +++ b/sysml.library/Systems Library/SysML.sysml @@ -61,6 +61,7 @@ package SysML { abstract item def LoopActionUsage :> ActionUsage; item def WhileLoopActionUsage :> LoopActionUsage; item def ForLoopActionUsage :> LoopActionUsage; + item def TriggerInvocationExpression :> InvocationExpression; item def StateDefinition :> ActionDefinition; item def StateUsage :> ActionUsage; diff --git a/sysml/src/examples/Analysis Examples/Vehicle Analysis Demo.sysml b/sysml/src/examples/Analysis Examples/Vehicle Analysis Demo.sysml index 85121d2d..1e988beb 100644 --- a/sysml/src/examples/Analysis Examples/Vehicle Analysis Demo.sysml +++ b/sysml/src/examples/Analysis Examples/Vehicle Analysis Demo.sysml @@ -12,7 +12,7 @@ package 'Vehicle Analysis Demo' { attribute :>> quantityDimension { :>> quantityPowerFactors = (distancePF, volumePF); } } - attribute def DistancePerVolumeValue :> QuantityValue { + attribute def DistancePerVolumeValue :> ScalarQuantityValue { :>> num : Real; :>> mRef : DistancePerVolumeUnit; } diff --git a/sysml/src/examples/Individuals Examples/AnalysisIndividualExample.sysml b/sysml/src/examples/Individuals Examples/AnalysisIndividualExample.sysml index 98021c56..9065fb56 100644 --- a/sysml/src/examples/Individuals Examples/AnalysisIndividualExample.sysml +++ b/sysml/src/examples/Individuals Examples/AnalysisIndividualExample.sysml @@ -12,7 +12,7 @@ package AnalysisIndividualExample { attribute :>> quantityDimension { :>> quantityPowerFactors = (distancePF, volumePF); } } - attribute def DistancePerVolumeValue :> QuantityValue { + attribute def DistancePerVolumeValue :> ScalarQuantityValue { :>> num : Real; :>> mRef : DistancePerVolumeUnit; } diff --git a/sysml/src/examples/Simple Tests/ActionTest.sysml b/sysml/src/examples/Simple Tests/ActionTest.sysml index 4a7942d0..f6905b51 100644 --- a/sysml/src/examples/Simple Tests/ActionTest.sysml +++ b/sysml/src/examples/Simple Tests/ActionTest.sysml @@ -4,14 +4,19 @@ package ActionTest { action a { first start; then merge m; - then accept S; + then accept S; + then accept sig after 10[SI::s]; + then accept at Time::Iso8601DateTime("2022-01-30T01:00:00Z"); - then send S() to B(); + then send S() to b; + then accept when b.f; then decide; if true then m; else done; } - action def B; + action b { + attribute f : ScalarValues::Boolean; + } } \ No newline at end of file diff --git a/sysml/src/examples/Simple Tests/AliasTest.sysml b/sysml/src/examples/Simple Tests/AliasTest.sysml index 1d6df37e..fed5aa3c 100644 --- a/sysml/src/examples/Simple Tests/AliasTest.sysml +++ b/sysml/src/examples/Simple Tests/AliasTest.sysml @@ -1,6 +1,6 @@ package AliasTest { - import Quantities::quantities; // import of an alias - attribute q :> quantities; + import ISQSpaceTime::breadth; // import of an alias + attribute b :> breadth; part def P1 { port porig1; diff --git a/sysml/src/examples/Simple Tests/ImportTest.sysml b/sysml/src/examples/Simple Tests/ImportTest.sysml new file mode 100644 index 00000000..6bbe7377 --- /dev/null +++ b/sysml/src/examples/Simple Tests/ImportTest.sysml @@ -0,0 +1,18 @@ +package ImportTest { + package Pkg1 { + import Pkg2::Pkg21::Pkg211::P211; + import Pkg2::Pkg21::*; + import Pkg211::*::**; + part p11 : Pkg211::P211; + part def P12; + } + + package Pkg2 { + import Pkg1::*; + package Pkg21 { + package Pkg211 { + part def P211 :> P12; + } + } + } +} \ No newline at end of file diff --git a/sysml/src/examples/Vehicle Example/VehicleModel_1_Simplified.sysml b/sysml/src/examples/Vehicle Example/VehicleModel_1_Simplified.sysml new file mode 100644 index 00000000..efcfad46 --- /dev/null +++ b/sysml/src/examples/Vehicle Example/VehicleModel_1_Simplified.sysml @@ -0,0 +1,1797 @@ +package VehicleModel_1_simplified{ + import Definitions::*; + import ModelingMetadata::*; + import RiskMetadata::*; + import RiskLevelEnum::*; + package Documentation{ + package VersionUpdates{ + /* 2021-12-16: Update to 2021-11 release including: + * qaulifyinjg with VerificatioMethodKind + * objectiveFunction to evaluationFunction + * riskLevels (low, medium, high) + * 2021-12-30: Allocated flow to interface and mass requirement to vehicle.mass + */ + } + } + package Definitions{ + //these imports eliminate the need to import into each nested package + import PartDefinitions::*; + import PortDefinitions::*; + import ItemDefinitions::*; + import SignalDefinitions::*; + import InterfaceDefinitions::*; + import ActionDefinitions::*; + import StateDefinitions::*; + import RequirementDefinitions::*; + import AttributeDefinitions::*; + import IndividualDefinitions::*; + import AnnotationDefinitions::**; + package PartDefinitions{ + part def Vehicle:>PhysicalComponent { + attribute mass :> ISQ::mass; + attribute dryMass:>ISQ::mass; + attribute cargoMass:>ISQ::mass; + //attribute position:ISQ::LengthValue; + attribute position:>ISQ::length; + attribute velocity:>ISQ::speed; + attribute acceleration:>ISQ::acceleration; + attribute electricalPower:>ISQ::power; + attribute Tmax:>ISQ::temperature; + attribute maintenanceTime: Time::DateTime; + attribute brakePedalDepressed: Boolean; + port ignitionCmdPort:IgnitionCmdPort; + port pwrCmdPort:PwrCmdPort; + port vehicleToRoadPort:VehicleToRoadPort; + perform action providePower; + perform action provideBraking; + perform action controlDirection; + perform action performSelfTest; + perform action applyParkingBrake; + perform action senseTemperature; + //the following uses a single concept of event for signal, change, and time event + //the time event will be replaced by when eventname + exhibit state vehicleStates parallel { + ref controller : VehicleController; + state operatingStates { + entry action initial; + state off; + state starting; + state on { + entry performSelfTest; + do providePower; + exit applyParkingBrake; + constraint {electricalPower<=500[W]} + } + + transition initial then off; + + transition off_To_starting + first off + accept ignitionCmd:IgnitionCmd via ignitionCmdPort + if ignitionCmd.ignitionOnOff==IgnitionOnOff::on and brakePedalDepressed + do send StartSignal() to controller + then starting; + + transition starting_To_on + first starting + accept VehicleOnSignal + then on; + + transition on_To_off + first on + accept VehicleOffSignal + do send OffSignal() to controller + then off; + } + + state healthStates { + entry action initial; + do senseTemperature (out temp); + + state normal; + state maintenance; + state degraded; + + transition initial then normal; + + transition normal_To_maintenance + first normal + accept at maintenanceTime + then maintenance; + + transition normal_To_degraded + first normal + accept when senseTemperature.temp > Tmax + do send OverTemp() to controller + then degraded; + + transition maintenance_To_normal + first maintenance + accept ReturnToNormal + then normal; + + transition degraded_To_normal + first degraded + accept ReturnToNormal + then normal; + } + } + } + part def Engine{ + attribute mass :> ISQ::mass; + attribute peakHorsePower:>ISQ::power; + attribute fuelEfficiency:Real; + attribute cost:Real; + attribute displacement :> ISQ::volume; + port engineControlPort: ~ControlPort; + port fuelInPort: ~ FuelPort{ + in item fuel redefines fuel; + } + port fuelCmdPort:FuelCmdPort{ + in item redefines fuelCmd; + } + port drivePwrPort:DrivePwrPort{ + out redefines torque; + } + port ignitionCmdPort:IgnitionCmdPort; + port flyWheelPort; + perform action generateTorque; + exhibit state engineStates; + } + part def StarterMotor{ + port gearPort:GearPort; + } + part def Cylinder; + part def Transmission{ + attribute gearRation:Real; + port clutchPort:ClutchPort{ + in redefines torque; + } + exhibit state transmissionStates; + } + part def Driveshaft; + part def AxleAssembly; + part def Axle{ + attribute mass:>ISQ::mass; + } + part def FrontAxle:>Axle{ + attribute steeringAngle:>ISQ::planeAngle; + } + part def HalfAxle; + part def Differential; + part def Wheel { + attribute diameter:LengthValue; + } + part def Hub; + abstract part def Software; + part def VehicleSoftware:>Software; + part def VehicleController:>Software { + port controlPort:ControlPort; + exhibit state controllerStates parallel { + state operatingStates { + entry action initial; + state off; + state on; + transition initial then off; + transition 'off-on' + first off + accept StartSignal + then on; + transition 'on-off' + first on + accept OffSignal + then off; + } + } + } + part def CruiseController:>Software { + port setSpeedPort:~SetSpeedPort; + port speedSensorPort:~SpeedSensorPort; + port cruiseControlPort:CruiseControlPort; + exhibit state cruiseControllerStates; + } + part def SpeedSensor{ + port speedSensorPort:SpeedSensorPort; + } + part def FuelTank{ + attribute mass :> ISQ::mass; + // should use fuel volume instead of fuel mass and fuelCopacity instead of fuelMassMax + ref item fuel:Fuel{ + attribute :>> fuelMass; + } + attribute fuelMassMax:>ISQ::mass; + assert constraint {fuel.fuelMass<=fuelMassMax} + port fuelOutPort:FuelPort; + } + part def BodyAssy; + part def Body{ + attribute color:Colors; + } + part def Road{ + attribute incline:Real; + attribute friction:Real; + } + //part def VehicleRoadContext{ + // attribute time:TimeValue; + //} + // Used for Specifying Context for Individuals + // replace SpatialTemporalReference by GenericContext::Context + //part def SpatialTemporalReference; + + // Used for Defining Variants for Superset Model + part def Engine4Cyl; + part def Engine6Cyl; + part def TransmissionChoices; + part def TransmissionAutomatic; + part def TransmissionManual; + part def Sunroof; + + //create abstract physical element to support allocation def from logical to Physical + // Parts::Part is a work around on both Physical Component and Logical Component until 2021-05 release + part def PhysicalComponent:>PhysicalItem, Parts::Part; + //logical Components + part def LogicalComponent:>LogicalItem, Parts::Part; + part def VehicleLogical:>LogicalComponent; + + part def ElectricalGenerator; + part def TorqueGenerator; + part def SteeringSubsystem; + part def BrakingSubsystem; + } + package PortDefinitions{ + port def IgnitionCmdPort{ + in item ignitionCmd:IgnitionCmd; + } + //port on starter motor that connects to flywheel on engine + port def GearPort; + port def PwrCmdPort{ + in item pwrCmd:PwrCmd; + } + port def FuelCmdPort:>PwrCmdPort{ + in item fuelCmd:FuelCmd redefines pwrCmd; + } + port def FuelPort{ + out item fuel:Fuel; + } + port def DrivePwrPort{ + out torque:Torque; + } + port def ClutchPort{ + in torque:Torque; + } + port def ShaftPort_a; + port def ShaftPort_b; + port def ShaftPort_c; + port def ShaftPort_d; + port def DiffPort; + port def AxlePort; + port def AxleToWheelPort; + port def WheelToAxlePort; + port def WheelToRoadPort; + port def LugNutPort; + port def ShankPort; + port def VehicleToRoadPort; + port def ControlPort; + port def CruiseControlPort; + port def SpeedSensorPort; + port def SetSpeedPort; + + // User port definitions + port def DriverCmdPort{ + out item driverCmd[*]:DriverCmd; + } + port def HandPort :> DriverCmdPort { + out item ignitionCmd:IgnitionCmd subsets driverCmd; + out item pwrCmd:PwrCmd subsets driverCmd; + } + } + package ItemDefinitions{ + item def Fuel{ + attribute fuelMass:>ISQ::mass; + } + // should FuelCmd and PwrCmd be attributes vs items + item def FuelCmd:>PwrCmd; + + item def SensedSpeed{ + attribute speed:>ISQ::speed; + } + + item def PwrCmd{ + attribute throttleLevel:Real; + } + item def LogicalItem; + item def PhysicalItem; + item def GenericItem; + } + package SignalDefinitions{ + item def Cmd{ + } + item def DriverCmd; + item def IgnitionCmd:>DriverCmd{ + attribute ignitionOnOff:IgnitionOnOff; + } + + //change the following signals to be item def vs attribute def per above + attribute def VehicleStartSignal; + attribute def VehicleOnSignal; + attribute def VehicleOffSignal; + attribute def StartSignal; + attribute def OffSignal; + attribute def OverTemp; + attribute def ReturnToNormal; + // the following are work arounds until time events and change events are available + attribute def 'at(vehicle::maintenanceTime)'; + attribute def 'when(temp>vehicle::Tmax)'; + //attribute def SensedSpeed:>Real; + attribute def SetSpeed:>Real; + } + package InterfaceDefinitions{ + interface def EngineToTransmissionInterface{ + end p1:DrivePwrPort; + end p2:ClutchPort; + flow p1.torque to p2.torque; + } + interface def FuelInterface { + end fuelOutPort:FuelPort; + end fuelInPort:~FuelPort; + flow fuelOutPort.fuel to fuelInPort.fuel; + } + interface def WheelFastenerInterface{ + end lugNutPort:LugNutPort; + end shankPort:ShankPort; + attribute threadDia = 14 [mm]; + attribute threadPitch = 1.5 [mm]; + attribute shaftLength = 70 [mm]; + attribute maxTorque; + } + interface def WheelHubInterface{ + end lugNutPorts:LugNutPort [5]; + end shankPorts:ShankPort [5]; + interface wheelFastenerInterface:WheelFastenerInterface [5] + connect lugNutPorts to shankPorts; + + /* the following does not work + interface wheelFastenerInterface1:WheelFastenerInterface + connect lugNutPort1[1]:>lugNutPorts to shankPort1[1]:>shankPorts; + */ + } + connection def GenericConnection { + end genericItem1:GenericItem; + end genericItem2:GenericItem; + } + } + package AllocationDefinitions{ + allocation def LogicalToPhysicalItem{ + end logicalItem:LogicalItem; + end physicalItem:PhysicalItem; + } + allocation def ConnectionToConnection{ + end genericConnection1:GenericConnection; + end genericConnection2:GenericConnection; + } + } + package ActionDefinitions{ + // why is item key word not required here for fuelCmd + action def ProvidePower { + in item pwrCmd:PwrCmd; + out wheelToRoadTorque:Torque[2]; + } + action def GenerateTorque { + in item fuelCmd:FuelCmd; + out engineTorque:Torque; + } + action def AmplifyTorque { + in engineTorque:Torque; + out transmissionTorque:Torque; + } + action def TransferTorque { + in transmissionTorque:Torque; + out driveshaftTorque:Torque; + } + action def DistributeTorque { + in driveshaftTorque:Torque; + out wheelToRoadTorque:Torque[2]; + } + action def PerformSelfTest; + action def ApplyParkingBrake; + action def SenseTemperature{ + out temp: ISQ::TemperatureValue; + } + } + package StateDefinitions { + state def VehicleStates; + state def ControllerStates; + state def CruiseControllerStates; + } + package RequirementDefinitions{ + requirement def MassRequirement{ + doc /*The actual mass shall be less than the required mass*/ + attribute massRequired:>ISQ::mass; + attribute massActual:>ISQ::mass; + require constraint {massActual<=massRequired} + } + requirement def ReliabilityRequirement{ + doc /*The actual reliability shall be greater than the required reliability*/ + attribute reliabilityRequired:Real; + attribute reliabilityActual:Real; + require constraint {reliabilityActual>=reliabilityRequired} + } + requirement def TorqueGenerationRequirement { + doc /* The engine shall generate torque as a function of RPM as shown in Table 1. */ + subject generateTorque:ActionDefinitions::GenerateTorque; + } + requirement def DrivePowerOutputRequirement { + doc /* The engine shall provide a connection point to transfer torque to the transmission.*/ + } + requirement def FuelEconomyRequirement { + doc /* The vehicle shall maintain an average fuel economomy of at least x miles per gallon for the nominal + driving scenario */ + //attribute actualFuelEconomy : DistancePerVolumeValue; + //attribute requiredFuelEconomy : DistancePerVolumeValue; + attribute actualFuelEconomy :> distancePerVolume; + attribute requiredFuelEconomy :> distancePerVolume; + require constraint {actualFuelEconomy >= requiredFuelEconomy} + } + } + package AttributeDefinitions{ + import ScalarValues::*; + // Scalar Functions provides Sum expression + import ScalarFunctions::*; + import ISQ::*; + import SI::*; + import USCustomaryUnits::*; + alias Torque for ISQ::TorqueValue; + + //examples of enumerations + enum def Colors {black;grey;red;} + enum def DiameterChoices:>ISQ::LengthValue{ + enum = 60 [mm]; + enum = 80 [mm]; + enum = 100 [mm]; + } + attribute cylinderDiameter: DiameterChoices = 80 [mm]; + enum def IgnitionOnOff {on;off;} + + + // (from Ed's model) the following defines new quantities and units used in fuel economy reqts and analysis + import Quantities::*; + import UnitsAndScales::DerivedUnit; + import SIPrefixes::kilo; + + /* should we add quantity and unit as key words? */ + distancePerVolume :> scalarQuantities = distance / volume; + timePerDistance :> scalarQuantities = time / distance; + volumePerDistance :> scalarQuantities = volume / distance; + volumePerTime :> scalarQuantities = volume / time; + + // kpl is approx .425 * mpg + kpl : DerivedUnit = km / L; + rpm : DerivedUnit = 1 / min; + kW : DerivedUnit = kilo * W; + // + } + package IndividualDefinitions{ + //individual def SpatialTemporalReference_1:>SpatialTemporalReference; + individual def VehicleRoadContext_1:>GenericContext::Context; + individual def Vehicle_1:>Vehicle; + individual def FrontAxleAssembly_1:>AxleAssembly; + individual def FrontAxle_1:>FrontAxle; + individual def Wheel_1:>Wheel; + individual def Wheel_2:>Wheel; + individual def RearAxleAssembly_1:>AxleAssembly; + individual def Road_1:>Road; + } + package AnnotationDefinitions { + + import AnalysisTooling::*; + //define the metadata as follows if not included in the AnalysisTooling library + /* + attribute def ToolExecution { + attribute toolName:String; + attribute uri:String; + } + */ + + attribute def Safety { + attribute isMandatory : Boolean; + } + attribute def Security; + } + package GenericContext { + //import ISQ::*; + //import SI::*; + //import USCustomaryUnits::*; + + part def Context { + attribute time:TimeValue; + attribute spatialCS: Cartesian3dSpatialCoordinateSystem[1] { :>> mRefs = (m, m, m); } + attribute velocityCS: Cartesian3dVelocityCoordinateSystem[1] = spatialCS/s { :>> isBound = false; } + attribute accelarationCS: Cartesian3dAccelerationCoordinateSystem[1] = velocityCS/s { :>> isBound = false; } + } + // consider including in the Context + // the following should replace startShot and endShot with start and done respectively + occurrence starting_Ending_Conditions { + timeslice starting_Ending { + snapshot starting = startShot { + attribute tstart :>ISQ::time default 0 [s]; + } + snapshot ending = endShot { + attribute tend :>ISQ::time [s]; + } + attribute tstart_To_tend :>ISQ::time [s] = ending.tend - starting.tstart; + } + } + } + } + package VehicleLogicalConfiguration{ + package PartsTree{ + part vehicleLogical:VehicleLogical{ + part torqueGenerator:TorqueGenerator{ + action generateTorque; + } + part electricalGenerator:ElectricalGenerator{ + action generateElectricity; + } + part steeringSystem:SteeringSubsystem; + part brakingSubsystem:BrakingSubsystem; + } + } + } + package VehicleLogicalToPhysicalAllocation{ + import VehicleLogicalConfiguration::PartsTree::*; + import VehicleConfigurations::VehicleConfiguration_b::PartsTree::**; + allocation vehicleLogicalToPhysicalAllocation:AllocationDefinitions::LogicalToPhysicalItem + allocate vehicleLogical to vehicle_b{ + allocate vehicleLogical.torqueGenerator to vehicle_b.engine{ + allocate vehicleLogical.torqueGenerator.generateTorque to vehicle_b.engine.generateTorque; + } + allocate vehicleLogical.electricalGenerator to vehicle_b.engine{ + allocate vehicleLogical.electricalGenerator.generateElectricity to vehicle_b.engine.alternator.generateElectricity; + } + } + } + package VehicleConfigurations{ + package VehicleConfiguration_a{ + package PartsTree{ + part vehicle_a:Vehicle{ + attribute mass redefines Vehicle::mass=dryMass+cargoMass+fuelTank.fuel.fuelMass; + attribute dryMass redefines Vehicle::dryMass=sum(partMasses); + attribute redefines Vehicle::cargoMass=0 [kg]; + attribute partMasses [*] nonunique :>ISQ::mass; + //attribute partMasses={fuelTank::mass,frontAxleAssembly::mass,rearAxleAssembly::mass}; + part fuelTank:FuelTank{ + attribute redefines mass=75[kg]; + ref item redefines fuel{ + attribute redefines fuelMass=50[kg]; + } + } + part frontAxleAssembly:AxleAssembly{ + attribute mass :> ISQ::mass=800[kg]; + part frontAxle:Axle; + part frontWheels:Wheel[2]; + } + part rearAxleAssembly:AxleAssembly{ + attribute mass :> ISQ::mass=875[kg]; + attribute driveTrainEfficiency:Real = 0.6; + part rearAxle:Axle; + part rearWheels:Wheel[2]{ + attribute redefines diameter; + } + } + } + } + package ActionTree{ + } + } + package VehicleConfiguration_b{ + package PartsTree{ + part vehicle_b : Vehicle{ + attribute mass redefines mass=dryMass+cargoMass+fuelTank.fuel.fuelMass; + attribute dryMass redefines dryMass=sum(partMasses); + attribute redefines cargoMass default 0 [kg]; + attribute partMasses=(fuelTank.mass,frontAxleAssembly.mass,rearAxleAssembly.mass,engine.mass,transmission.mass,driveshaft.mass); + attribute avgFuelEconomy :> distancePerVolume; + port fuelCmdPort: FuelCmdPort redefines pwrCmdPort { + in item redefines fuelCmd; + } + port setSpeedPort:~SetSpeedPort; + port vehicleToRoadPort redefines vehicleToRoadPort{ + port wheelToRoadPort1:WheelToRoadPort; + port wheelToRoadPort2:WheelToRoadPort; + } + perform ActionTree::providePower redefines providePower; + perform ActionTree::performSelfTest redefines performSelfTest; + perform ActionTree::applyParkingBrake redefines applyParkingBrake; + perform ActionTree::senseTemperature redefines senseTemperature; + exhibit state vehicleStates redefines vehicleStates; + /* + exhibit States::vehicleStates redefines vehicleStates { + ref vehicle redefines vehicle = vehicle_b; + } + */ + part fuelTank:FuelTank{ + attribute redefines mass=75[kg]; + ref item redefines fuel{ + attribute redefines fuelMass=60[kg]; + } + attribute redefines fuelMassMax=60 [kg]; + } + part frontAxleAssembly:AxleAssembly{ + attribute mass :> ISQ::mass=800[kg]; + port shaftPort_d:ShaftPort_d; + part frontAxle:FrontAxle; + part frontWheels:Wheel[2]; + } + part rearAxleAssembly:AxleAssembly{ + attribute mass :> ISQ::mass=875[kg]; + attribute driveTrainEfficiency:Real = 0.6; + port shaftPort_d:ShaftPort_d; + perform ActionTree::providePower::distributeTorque; + part rearWheel1:Wheel{ + attribute redefines diameter; + port wheelToAxlePort:WheelToAxlePort; + port wheelToRoadPort:WheelToRoadPort; + } + part rearWheel2:Wheel{ + attribute redefines diameter; + port wheelToRoadPort:WheelToRoadPort; + port wheelToAxlePort:WheelToAxlePort; + } + part differential:Differential{ + port shaftPort_d:ShaftPort_d; + port leftDiffPort:DiffPort; + port rightDiffPort:DiffPort; + } + part rearAxle{ + part leftHalfAxle:HalfAxle{ + port leftAxleToDiffPort:AxlePort; + port leftAxleToWheelPort:AxlePort; + } + part rightHalfAxle:HalfAxle{ + port rightAxleToDiffPort:AxlePort; + port rightAxleToWheelPort:AxlePort; + } + } + + bind shaftPort_d=differential.shaftPort_d; + connect differential.leftDiffPort to rearAxle.leftHalfAxle.leftAxleToDiffPort; + connect differential.rightDiffPort to rearAxle.rightHalfAxle.rightAxleToDiffPort; + connect rearAxle.leftHalfAxle.leftAxleToWheelPort to rearWheel1.wheelToAxlePort; + connect rearAxle.rightHalfAxle.rightAxleToWheelPort to rearWheel2.wheelToAxlePort; + } + part starterMotor:StarterMotor; + part engine:Engine{ + perform ActionTree::providePower::generateTorque redefines generateTorque; + part cylinders:Cylinder[4..6]; + part alternator{ + action generateElectricity; + } + satisfy Requirements::engineSpecification by vehicle_b.engine{ + //subject engine1 = vehicle_b::engine; + requirement torqueGenerationRequirement :>> torqueGenerationRequirement{ + subject generateTorque redefines generateTorque = vehicle_b.engine.generateTorque; + } + requirement drivePowerOuputRequirement :>> drivePowerOutputRequirement{ + port torqueOutPort redefines torqueOutPort=vehicle_b.engine.drivePwrPort; + } + } + } + part transmission:Transmission{ + attribute mass :> ISQ::mass=100[kg]; + //conjugate notation ~ + //port clutchPort:~DrivePwrPort; + port shaftPort_a:ShaftPort_a; + perform ActionTree::providePower::amplifyTorque; + } + part driveshaft:Driveshaft{ + attribute mass :> ISQ::mass=100[kg]; + port shaftPort_b:ShaftPort_b; + port shaftPort_c:ShaftPort_c; + perform ActionTree::providePower::transferTorque; + } + part vehicleSoftware:VehicleSoftware{ + part vehicleController: VehicleController { + exhibit state controllerStates redefines controllerStates; + part cruiseController:CruiseController; + } + } + part speedSensor:SpeedSensor; + + // parts in bodyAssy and interioer are marked as safety or security features + part bodyAssy:BodyAssy{ + part body:Body{ + attribute :>> color = Colors::red; + } + part bumper {@Safety{isMandatory = true;}} + part keylessEntry {@Security;} + } + part interior { + part alarm {@Security;} + part seatBelt[2] {@Safety{isMandatory = true;}} + part frontSeat[2]; + part driverAirBag {@Safety{isMandatory = false;}} + } + + //Example: the following identifies an issue with the interface + // Issue is in the ModelingMetadata library + metadata InterfaceCompatibilityIssue : Issue about engineToTransmissionInterface { + text = "This issue is about the interface compatability between the engine and transmission." + + "The CAD model inidcates tolerances are not properly specified"; + } + + + //connections + bind engine.fuelCmdPort=fuelCmdPort; + + //connect engine.drivePwrPort to transmission.clutchPort; + /* the following interface replaces the above connect statement. */ + interface engineToTransmissionInterface:EngineToTransmissionInterface + connect engine.drivePwrPort to transmission.clutchPort; + //can ref or allocate the flow - generateToAmplify :> ActionTree::providePower.generateToAmplify; + interface fuelInterface:FuelInterface + connect fuelTank.fuelOutPort to engine.fuelInPort; + //allocate flow from action flows to connections + + allocate ActionTree::providePower.generateToAmplify to engineToTransmissionInterface; + + bind engine.ignitionCmdPort=ignitionCmdPort; + connect starterMotor.gearPort to engine.flyWheelPort; + connect vehicleSoftware.vehicleController.controlPort to engine.engineControlPort; + bind vehicle_b.setSpeedPort = vehicleSoftware.vehicleController.cruiseController.setSpeedPort; + connect speedSensor.speedSensorPort to vehicleSoftware.vehicleController.cruiseController.speedSensorPort; + connect vehicleSoftware.vehicleController.cruiseController.cruiseControlPort to engine.engineControlPort; + connect transmission.shaftPort_a to driveshaft.shaftPort_b; + connect driveshaft.shaftPort_c to rearAxleAssembly.shaftPort_d; + bind rearAxleAssembly.rearWheel1.wheelToRoadPort=vehicleToRoadPort.wheelToRoadPort1; + bind rearAxleAssembly.rearWheel2.wheelToRoadPort=vehicleToRoadPort.wheelToRoadPort2; + + // assert the vehicle features (e.g, mass, reliability) satisfy the requirements + satisfy Requirements::vehicleSpecification by vehicle_b{ + // attribute redefines vehicleMassRequirement.massActual = vehicle_b.mass; + requirement vehicleMassRequirement:>>vehicleMassRequirement{ + attribute redefines massActual=vehicle_b.mass; + attribute redefines fuelMassActual = vehicle_b.fuelTank.fuel.fuelMass; + } + } + } + } + package ActionTree{ + action providePower:ProvidePower{ + in item fuelCmd:FuelCmd redefines pwrCmd; + out wheelToRoadTorque redefines wheelToRoadTorque [2] = distributeTorque.wheelToRoadTorque; + /* No successions (control flows) between these actions, because the input/outputs are continuous flows.*/ + action generateTorque:GenerateTorque { + in item = providePower.fuelCmd; + } + action amplifyTorque:AmplifyTorque; + action transferTorque:TransferTorque; + action distributeTorque:DistributeTorque; + + flow generateToAmplify from generateTorque.engineTorque to amplifyTorque.engineTorque; + flow amplifyTorque.transmissionTorque to transferTorque.transmissionTorque; + flow transferTorque.driveshaftTorque to distributeTorque.driveshaftTorque; + } + action performSelfTest: PerformSelfTest; + action applyParkingBrake: ApplyParkingBrake; + action senseTemperature: SenseTemperature; + } + //package States{} + package DiscreteInteractions{ + occurrence CruiseControl1{ + part vehicle_b:>PartsTree::vehicle_b{ + port redefines setSpeedPort{ + event occurrence setSpeedReceived; + } + part redefines speedSensor{ + port redefines speedSensorPort{ + event occurrence sensedSpeedSent; + } + } + part redefines vehicleSoftware{ + part redefines vehicleController{ + part redefines cruiseController{ + /* introduce loop operand with test when available so that + sensedSpeedSent continues at periodic intervals until cancelSpeedReceived */ + port redefines setSpeedPort{ + //analagous to gate: event occurrence bound but may not need this since the port is bound + event occurrence setSpeedReceived = vehicle_b.setSpeedPort.setSpeedReceived; + } + port redefines speedSensorPort{ + event occurrence sensedSpeedReceived; + } + port redefines cruiseControlPort{ + event occurrence fuelCmdSent; + } + } + } + } + part redefines engine{ + port redefines fuelCmdPort{ + event occurrence fuelCmdReceived; + } + } + message sendSensedSpeed of SensedSpeed + from speedSensor.speedSensorPort.sensedSpeedSent to vehicleSoftware.vehicleController.cruiseController.speedSensorPort.sensedSpeedReceived; + message sendFuelCmd of FuelCmd + from vehicleSoftware.vehicleController.cruiseController.cruiseControlPort.fuelCmdSent to engine.fuelCmdPort.fuelCmdReceived; + } + } + occurrence CruiseControl2{ + part vehicle_b:>PartsTree::vehicle_b{ + port redefines setSpeedPort{ + event occurrence setSpeedReceived; + } + part redefines speedSensor{ + port redefines speedSensorPort{ + event sendSensedSpeed.source; + } + } + part redefines vehicleSoftware{ + part redefines vehicleController{ + part redefines cruiseController{ + /* introduce loop operand with test when available so that + sensedSpeedSent continues at periodic intervals until cancelSpeedReceived */ + port redefines setSpeedPort{ + //analagous to gate: event occurrence bound but may not need this since the port is bound + event occurrence setSpeedReceived = vehicle_b.setSpeedPort.setSpeedReceived; + } + port redefines speedSensorPort{ + event occurrence setSpeedReceived=setSpeedPort.setSpeedReceived; + then event sendSensedSpeed.target; + } + port redefines cruiseControlPort{ + //event occurrence sensedSpeedReceived=speedSensorPort.sensedSpeedReceived; + //event occurrence = speedSensorPort::sendSensedSpeed::target; + + event sendFuelCmd.source; + } + } + } + } + part redefines engine{ + port redefines fuelCmdPort{ + event sendFuelCmd.target; + } + } + message sendSensedSpeed of SensedSpeed; + message sendFuelCmd of FuelCmd; + } + } + occurrence CruiseControl3{ + //create example using interface pattern for sending and receiving messages per Conrad + } + occurrence TestScenario1{ + part vehicle_c:>PartsTree::vehicle_b{ + event occurrence on = vehicleStates.operatingStates.on; + then event occurrence on_To_off = vehicleStates.operatingStates.on_To_off; + then event occurrence off = vehicleStates.operatingStates.off; + + /* + port redefines setSpeedPort{ + event occurrence setSpeedReceived; + } + part redefines speedSensor{ + port redefines speedSensorPort{ + event occurrence sensedSpeedSent; + } + } + part redefines vehicleSoftware{ + part redefines vehicleController{ + part redefines cruiseController{ + port redefines setSpeedPort{ + event occurrence setSpeedReceived = vehicle_b.setSpeedPort.setSpeedReceived; + } + port redefines speedSensorPort{ + event occurrence sensedSpeedReceived; + } + port redefines cruiseControlPort{ + event occurrence fuelCmdSent; + } + } + } + } + part redefines engine{ + port redefines fuelCmdPort{ + event occurrence fuelCmdReceived; + } + } + + message sendSensedSpeed of SensedSpeed + from speedSensor.speedSensorPort.sensedSpeedSent to vehicleSoftware.vehicleController.cruiseController.speedSensorPort.sensedSpeedReceived; + message sendFuelCmd of FuelCmd + from vehicleSoftware.vehicleController.cruiseController.cruiseControlPort.fuelCmdSent to engine.fuelCmdPort.fuelCmdReceived; + */ + } + } + } + package Requirements{ + item marketSurvey; + dependency from vehicleSpecification to marketSurvey; + + requirement vehicleSpecification{ + subject vehicle:Vehicle; + requirement <'1'> vehicleMassRequirement: MassRequirement { + doc /* The total mass of the vehicle shall be less than or equal to the required mass. + Assume total mass includes a full tank of gas of 60 kg*/ + attribute redefines massRequired=2000 [kg]; + attribute redefines massActual = vehicle.dryMass + fuelMassActual; + attribute fuelMassActual:>ISQ::mass; + attribute fuelMassMax:>ISQ::mass = 60 [kg]; + assume constraint {fuelMassActual==fuelMassMax} + } + + /* allocate requirement is an assignment of responsibility that is + less formal than satisfy, which asserts the requirement is met */ + + allocate vehicleMassRequirement to PartsTree::vehicle_b.mass; + + requirement <'2'> vehicleFuelEconomyRequirements{ + doc /* fuel economy requirements group */ + attribute assumedCargoMass:>ISQ::mass; + requirement <'2_1'> cityFuelEconomyRequirement:FuelEconomyRequirement{ + redefines requiredFuelEconomy= 10 [km / L]; + assume constraint {assumedCargoMass<=500 [kg]} + } + requirement <'2_2'> highwayFuelEconomyRequirement:FuelEconomyRequirement{ + redefines requiredFuelEconomy= 12.75 [km / L]; + assume constraint {assumedCargoMass<=500 [kg]} + + //StatusInfo is contained in ModelingMetadata library + // StatusKind has values for open, closed, tbd, tbr, tbd + @StatusInfo { + status = StatusKind::closed; + originator = "Bob"; + owner = "Mary"; + } + } + } + } + requirement engineSpecification { + subject engine1:Engine; + requirement torqueGenerationRequirement : TorqueGenerationRequirement{ + subject generateTorque = engine1.generateTorque; + } + + requirement drivePowerOutputRequirement : DrivePowerOutputRequirement{ + port torqueOutPort{ + out torque:Torque; + } + } + } + } + } + // the following shows the vehicle decomposition using part definitions similar to SysML v1 + package VehicleConfiguration_B{ + package VehicleDecomposition{ + part def Vehicle_B:>Vehicle{ + port fuelCmdPort: FuelCmdPort redefines pwrCmdPort { + in item redefines fuelCmd; + } + port vehicleToRoadPort redefines vehicleToRoadPort{ + port wheelToRoadPort1:WheelToRoadPort; + port wheelToRoadPort2:WheelToRoadPort; + } + part fuelTank:FuelTank_B{ + port fuelOutPort redefines fuelOutPort{ + out item redefines fuel; + } + } + part frontAxleAssy:FrontAxleAssy_B; + part rearAxleAssy:RearAxleAssy_B; + part engine:Engine_B{ + port engineControlPort:>> engineControlPort; + port fuelInPort:>> fuelInPort{ + in item fuel redefines fuel; + } + port fuelCmdPort:>> fuelCmdPort { + in item redefines fuelCmd; + } + port drivePwrPort:>> drivePwrPort { + out redefines torque; + } + } + part transmission:Transmission_B{ + port clutchPort:>>clutchPort; + port shaftPort_a:>>shaftPort_a; + } + part driveshaft:Driveshaft_B{ + port shaftPort_b:>>shaftPort_b; + port shaftPort_c:>>shaftPort_c; + } + part vehicleSoftware:VehicleSoftware_B; + part bodyAssy:BodyAssy_B; + part interior{ + part alarm {@Security;} + part seatBelt[2] {@Safety{isMandatory = true;}} + part frontSeat[2]; + part driverAirBag {@Safety{isMandatory = false;}} + } + bind engine.fuelCmdPort=fuelCmdPort; + connect fuelTank.fuelOutPort to engine.fuelInPort; + connect engine.drivePwrPort to transmission.clutchPort; + connect transmission.shaftPort_a to driveshaft.shaftPort_b; + } + part def FuelTank_B:>FuelTank; + part def FrontAxleAssy_B:>AxleAssembly{ + part frontWheels:Wheel_B[2]; + part frontAxle:FrontAxle_B; + } + part def RearAxleAssy_B:>AxleAssembly{ + part rearWheel1:Wheel_B; + part rearWheel2:Wheel_B; + part rearAxle{ + part leftHalfAxle:HalfAxle_B; + part rightHalfAxle:HalfAxle_B; + } + } + part def FrontAxle_B:>FrontAxle; + part def HalfAxle_B:>HalfAxle; + part def Differential_B:>Differential; + part def Wheel_B:>Wheel; + part def Engine_B:>Engine{ + port engineControlPort:>> engineControlPort; + port fuelInPort:>> fuelInPort{ + in item fuel redefines fuel; + } + port fuelCmdPort:>> fuelCmdPort { + in item redefines fuelCmd; + } + port drivePwrPort:>> drivePwrPort { + out redefines torque; + } + part cylinders:Cylinder_B[4..6]; + } + part def Cylinder_B:>Cylinder; + part def Transmission_B:>Transmission{ + //port clutchPort:~DrivePwrPort; + port shaftPort_a:ShaftPort_a; + } + part def Driveshaft_B:>Driveshaft{ + port shaftPort_b:ShaftPort_b; + port shaftPort_c:ShaftPort_c; + } + part def VehicleSoftware_B:>VehicleSoftware{ + part vehicleController:VehicleController_B; + } + part def VehicleController_B:>VehicleController{ + port controlPort redefines controlPort; + } + part def BodyAssy_B:>BodyAssy{ + part body:Body_B; + part bumper; + part keylessEntry; + } + part def Body_B:>Body; + } + } + package engine4Cyl_Variant{ + part engine{ + part cylinders:Cylinder[4..8] ordered; + } + part engine4Cyl:>engine{ + part redefines cylinders [4]; + part cylinder1 subsets cylinders[1]; + part cylinder2 subsets cylinders[1]; + part cylinder3 subsets cylinders[1]; + part cylinder4 subsets cylinders[1]; + } + } + package WheelHubAssemblies{ + part wheelHubAssy{ + part wheel1:Wheel{ + port lugNutPorts:LugNutPort[5]; + } + part hub1:Hub{ + port shankPorts:ShankPort[5]; + } + interface wheelHubInterface:WheelHubInterface [5] + connect wheel1.lugNutPorts [1] to hub1.shankPorts [1]; + } + part wheelHubAssy1{ + part wheel1:Wheel{ + port lugNutPort1:LugNutPort; + port lugNutPort2:LugNutPort; + port lugNutPort3:LugNutPort; + } + part hub1:Hub{ + port shankPort1:ShankPort; + port shankPort2:ShankPort; + port shankPort3:ShankPort; + } + interface wheelHubInterface1:WheelHubInterface + connect wheel1.lugNutPort1 to hub1.shankPort1; + interface wheelHubInterface2:WheelHubInterface + connect wheel1.lugNutPort2 to hub1.shankPort2; + interface wheelHubInterface3:WheelHubInterface + connect wheel1.lugNutPort3 to hub1.shankPort3; + } + } + } + package VehicleAnalysis{ + // recursive import uses double asterisk ** + import VehicleConfigurations::VehicleConfiguration_b::**; + package FuelEconomyAnalysisModel_ModelCenter{ + // metadata library + import AnalysisTooling::*; + + // create indviduals to record analysis results (e.g., output values) + individual def Vehicle_2:>Vehicle; + individual def Engine_2:>Engine; + //individual vehicle_b2:Vehicle_2{ + individual vehicle_b2:Vehicle_2:>PartsTree::vehicle_b{ + //attribute fuelEconomy:Real; + attribute :>>avgFuelEconomy; + attribute distanceTraveled:LengthValue = 1000 [m]; + individual engine_b2:Engine_2 redefines PartsTree::vehicle_b::engine { + attribute :>> peakHorsePower = 200*745.7[W]; + attribute :>> fuelEfficiency = .4; + } + } + analysis fuelEconomyAnalysis { + //return attribute calculatedFuelEconomy:KilometersPerLitre; + return attribute calculatedFuelEconomy:>distancePerVolume; + subject v:>vehicle_b2; + + objective fuelEconomyAnalysisObjective { + /* the objective of this analysis is to determine whether the vehicle design configuration can + satisfy the fuel economy requirements */ + require vehicleSpecification::vehicleFuelEconomyRequirements; + } + + action fuelConsumption { + metadata ToolExecution { + toolName = "ModelCenter"; + uri = "aserv://localhost/sysml2/vehicleModel/fuelConsumption"; + } + in power:PowerValue=v.engine_b2.peakHorsePower { @ToolVariable { name = "pv"; } } + in fuelEfficiency:Real=v.engine_b2.fuelEfficiency { @ToolVariable { name = "fuelEff"; } } + in distanceTraveled:LengthValue=v.distanceTraveled { @ToolVariable { name = "distance"; } } + out fuelEconomy:>distancePerVolume=v.avgFuelEconomy { @ToolVariable { name = "fuelEconomy"; }} + } + } + } + package FuelEconomyAnalysisModel{ + import SampledFunctions::SampledFunction; + + /* + This analysis model was provided by Hisashi Miyashita on January 27, 2021 + We use the simplest fuel consumption analysis model introduced in: + Akcelik, R. "Fuel efficiency and other objectives in traffic system management." Traffic Engineering and Control 22.2 (1981): 54-65. + + Fuel consumption rate f can be decomposed to: + f = f_a + f_b * tpd_avg, + where tpd_avg is average interrupted travel time per unit distance, actually the inverse of the average velocity [t/km]; + f_a is the best fuel consumption per distance; and + f_b is the additional fuel consumption per distance and average travel time, which can be regarded as the idling fuel consumption. + Approximately, it is proportional to engine displacement and it ranges from 0.5 to 0.6 [l/hour/litre of engine displacement] + according to: + Review of the Incidence, Energy Use and Costs of Passenger Vehicle Idling; Gordon W. Taylor, P.Eng. Prepared for the Office of Energy Efficiency, Natural Resources Canada, 2003 + + We assume f_a can be approximated to + fuel_consumption / distance = BSFC * SGG * required_power_avg * tpd_avg, + where required_power_avg is the required power, and it can be approximately derived from: + total_energy == P_req * tpd_avg * distance == 1/2 * mass / tpd_avg^2 + This part is computed with BestFuelConsumptionPerDistance calc def. + + BSFC means Brake-Specific Fuel Consumption, defined as gram/power. SGG is the specific gravity of gasoline. + The high octane gasoline is about 0.76[l/kg]. + */ + + attribute def Scenario :> SampledFunction { + attribute wayPoint[1..*] { + attribute elapseTime[1] :> ISQ::time; + attribute position[1] :> ISQ::distance; + } + } + + //calc def FuelConsumption (bestFuelConsumption: Real, idlingFuelConsumption: Real, tpd_avg: Real) : KilometersPerLitre { + calc def FuelConsumption (bestFuelConsumption: Real, idlingFuelConsumption: Real, tpd_avg:>timePerDistance) :> distancePerVolume { + attribute f = bestFuelConsumption + idlingFuelConsumption * tpd_avg; + 1/f + } + calc def AverageTravelTimePerDistance(scenario: Scenario) tpd_avg:>timePerDistance; + calc def TraveledDistance(scenario: Scenario) distance:> length; + calc def IdlingFuelConsumptionPerTime(engine: Engine) f_a : Real { + attribute idlingFuelConsumptionPerDisplacement: Real = 0.5; + engine.displacement * idlingFuelConsumptionPerDisplacement + } + + attribute specificGravityOfGasoline: Real = 0.76; + calc def BestFuelConsumptionPerDistance(mass: MassValue, bsfc: Real, tpd_avg:> timePerDistance, distance:>length) f_b : Real { + attribute required_power_avg:> ISQ::power; + constraint { + required_power_avg == 1/2 * mass * tpd_avg **(-3) / distance + } + bsfc * specificGravityOfGasoline * required_power_avg * tpd_avg + } + + calc def ComputeBSFC(engine: Engine): Real; + + analysis fuelEconomyAnalysis { + + // metadata defined in Annotation Definitions + metadata ToolExecution { + toolName = "ModelCenter"; + uri = "aserv://localhost/Vehicle/Equation1"; + } + + in attribute scenario: Scenario; + // define a series of waypoints + + subject = vehicle_b; + + objective fuelEconomyAnalysisObjective { + doc /*the objective of this analysis is to determine whether the vehicle design configuration can + satisfy the fuel economy requirements*/ + require vehicleSpecification::vehicleFuelEconomyRequirements; + } + /* this is the longhand for a calc + calc calc1:TraveledDistance(in=scenario) result; + attribute distance=calc1::result; + */ + + // specify vehicle_b.engine.displacement; + + attribute distance = TraveledDistance(scenario); + attribute tpd_avg = AverageTravelTimePerDistance(scenario); + attribute bsfc = ComputeBSFC(vehicle_b.engine); + attribute f_a = BestFuelConsumptionPerDistance(vehicle_b.mass, bsfc, tpd_avg, distance); + attribute f_b = IdlingFuelConsumptionPerTime(vehicle_b.engine); + + //return attribute calculatedFuelEconomy:KilometersPerLitre=FuelConsumption(f_a, f_b, tpd_avg) ; + return attribute calculatedFuelEconomy:>distancePerVolume=FuelConsumption(f_a, f_b, tpd_avg); + } + } + package ElectricalPowerAnalysis{ + } + package ReliabilityAnalyis{ + } + package VehicleTradeOffAnalysis{ + /* The following example provides the rationale for selecting the engine4cyl. + The rationale could be contained in the vehicle configuration with the selected engine. + The rationale and risk are contained in a metadata library. */ + + @Rationale about engineTradeOffAnalysis::vehicle_b_engine4cyl{ + explanation = VehicleAnalysis::VehicleTradeOffAnalysis::engineTradeOffAnalysis; + text = "the engine4cyl was evaluated to have a higher objective function compared to the engine6cyl based on the trade-off analyiss"; + } + + // The following risk for the engine4cyl could have been included as part of the objective evaluaiton criteria + + @Risk about engineTradeOffAnalysis::vehicle_b_engine4cyl { + totalRisk = medium; + technicalRisk = medium; + scheduleRisk = medium; + costRisk = RiskLevelEnum::low; + } + @RiskLevel about engineTradeOffAnalysis::vehicle_b_engine4cyl::engine::fuelEfficiency { + Risk::technicalRisk.probability = 0.3; + Risk::technicalRisk.impact = 0.5; + } + + /* + The following did not parse. + + @Risk about engineTradeOffAnalysis::vehicle_b_engine4cyl::engine::fuelEfficiency { + technicalRisk { + technicalRisk.probability = 0.3; + technicalRisk.impact = 0.5; + } + } + */ + + + import TradeStudies::*; + //objective function with criterion engine mass, engine power, and engine cost + calc def EngineEvaluation (engineMass:>ISQ::mass, enginePower:>ISQ::power, engineFuelEfficiency:Real,engineCost:Real) eval:Real; + calc def EngineEvaluation_4cyl (engineMass:>ISQ::mass, enginePower:>ISQ::power, engineFuelEfficiency:Real,engineCost:Real) eval:Real; + calc def EngineEvaluation_6cyl (engineMass:>ISQ::mass, enginePower:>ISQ::power, engineFuelEfficiency:Real,engineCost:Real) eval:Real; + analysis engineTradeOffAnalysis:TradeStudy{ + subject vehicleAlternatives[2]:>vehicle_b; + + part vehicle_b_engine4cyl:>vehicleAlternatives{ + part engine redefines engine{ + part cylinders :>> cylinders [4]; + attribute mass redefines mass=180 [kg]; + attribute peakHorsePower redefines peakHorsePower = 180 [W]; + attribute fuelEfficiency redefines fuelEfficiency=.6; + attribute cost redefines cost = 1000; + } + } + part vehicle_b_engine6cyl:>vehicleAlternatives{ + part engine redefines engine{ + part cylinders redefines cylinders [6]; + attribute mass redefines mass=220 [kg]; + attribute peakHorsePower redefines peakHorsePower = 220 [W]; + attribute fuelEfficiency redefines fuelEfficiency=.5; + attribute cost redefines cost = 1500; + } + } + + // the objective includes the objectiveFunction to select the maximum + objective :MaximizeObjective; + /*Select vehicle alternative with the engine whose evaluation function returns the max value*/ + + // Use the following if the evaluation function is the same for each alternative + /* + calc :>> objectiveFunction { + in part vehicle:>vehicle_b; + return attribute eval:Real=EngineEvaluation (vehicle::engine::mass, vehicle::engine::peakHorsePower, vehicle::engine::fuelEfficiency, vehicle::engine::cost); + } + */ + + // Use the following if the evaluation function is different for each alternative + calc :> evaluationFunction{ + in part vehicle:>vehicle_b_engine4cyl; + return attribute eval:Real=EngineEvaluation_4cyl (vehicle.engine.mass, vehicle.engine.peakHorsePower, vehicle.engine.fuelEfficiency, vehicle.engine.cost); + } + calc :> evaluationFunction{ + in part vehicle:>vehicle_b_engine6cyl; + return attribute eval:Real=EngineEvaluation_6cyl (vehicle.engine.mass, vehicle.engine.peakHorsePower, vehicle.engine.fuelEfficiency, vehicle.engine.cost); + } + return part selectedVehicle:>vehicle_b; + } + } + } + package VehicleVerification{ + import VehicleConfigurations::VehicleConfiguration_b::**; + import VerificationCaseDefinitions::*; + import VerificationCases1::*; + // the following is a model library which contains VerfictKind + import VerificationCases::*; + package VerificationCaseDefinitions{ + verification def MassTest; + verification def AccelerationTest; + verification def ReliabilityTest; + } + package VerificationCases1{ + verification massTests:MassTest { + subject = vehicle_b; + objective { + verify vehicleSpecification.vehicleMassRequirement{ + redefines massActual=weighVehicle.massMeasured; + } + } + // @ is shorthand for metadata + // method kindes are test, demo, analyze, should also include inspection, similarity + @ VerificationMethod{ + kind = (VerificationMethodKind::test, VerificationMethodKind::analyze); + } + action weighVehicle ( + out massMeasured:>ISQ::mass); + then action evaluatePassFail { + in massMeasured:>ISQ::mass; + out verdict = PassIf(vehicleSpecification.vehicleMassRequirement(vehicle_b)); + } + //return :>> verdict = PassIf(vehicleSpecification::vehicleMassRequirement(vehicle_b)); + } + } + package VerificationSystem{ + part massVerificationSystem{ + perform massTests; + part scale{ + perform massTests.weighVehicle; + } + part operator{ + perform massTests.evaluatePassFail; + } + } + } + } + package VehicleIndividuals{ + // VehicleRoadContext_1 subclasses GenericContext::Context with spatial reference and time attribute + individual a:VehicleRoadContext_1{ + //timeslice t0_t2:VehicleRoadContext_1{ + timeslice t0_t2_a{ + /* + snapshot start redefines start{ + attribute t0:TimeValue=0; + } + snapshot done redefines done{ + attribute t2:TimeValue=2; + } + */ + + //snapshot t0:VehicleRoadContext_1{ + snapshot t0_a { + attribute t0 redefines time=0 [s]; + snapshot t0_r:Road_1{ + :>>Road::incline =0; + :>>Road::friction=.1; + } + snapshot t0_v:Vehicle_1{ + :>>Vehicle::position=0 [m]; + :>>Vehicle::velocity=0 [m]; + :>>Vehicle::acceleration=1.96 [m/s**2]; + // .2 g where 1 g = 9.8 meters/sec^2 + // how do you represent state=on; + snapshot t0_fa:FrontAxleAssembly_1{ + snapshot t0_leftFront:Wheel_1; + snapshot t0_rightFront:Wheel_2; + } + } + } + snapshot t1_a{ + attribute t1 redefines time=1 [s]; + snapshot t1_r:Road_1{ + :>>Road::incline =0; + :>>Road::friction=.1; + } + snapshot t1_v:Vehicle_1{ + :>>Vehicle::position=.98 [m]; + :>>Vehicle::velocity=1.96 [m/s]; + :>>Vehicle::acceleration=1.96 [m/s**2]; + // .2 g where 1 g = 9.8 meters/sec^2 + // how do you represent state=on; + snapshot t1_fa:FrontAxleAssembly_1{ + snapshot t1_leftFront:Wheel_1; + snapshot t1_rightFront:Wheel_2; + } + } + } + snapshot t2_a{ + attribute t2 redefines time=2 [s]; + snapshot t2_r:Road_1{ + :>>Road::incline =0; + :>>Road::friction=.1; + } + snapshot t2_v:Vehicle_1{ + :>>Vehicle::position=3.92 [m]; + :>>Vehicle::velocity=3.92 [m/s]; + :>>Vehicle::acceleration=1.96 [m/s**2]; + // .2 g where 1 g = 9.8 meters/sec^2 + // how do you represent state=on; + snapshot t2_fa:FrontAxleAssembly_1{ + snapshot t2_leftFront:Wheel_1; + snapshot t2_rightFront:Wheel_2; + } + } + } + } + } + } + package MissionContext{ + /* Define mission context with mission use cases for vehicle_b */ + import VehicleConfigurations::VehicleConfiguration_b::**; + //import VehicleConfigurations::VehicleConfiguration_b::PartsTree::*; + //import VehicleConfigurations::VehicleConfiguration_b::ActionTree::*; + import TransportPassengerScenario::*; + package ContextDefinitions{ + part def MissionContext:>GenericContext::Context; + part def Road; + part def Driver{ + port handPort:HandPort{ + } + exhibit state driverStates{ + state initial; + state wait; + transition initial then wait; + //ignition on + transition 'wait-wait-1' + first wait + do send IgnitionCmd (ignitionOnOff=IgnitionOnOff::on) to handPort + then wait; + // ignition off + transition 'wait-wait-2' + first wait + do send IgnitionCmd (ignitionOnOff=IgnitionOnOff::off) to handPort + then wait; + } + } + part def Passenger; + // replace action def with use case def where vehicle_b is subject and objective is defined + + requirement transportRequirements; + use case def TransportPassenger{ + objective TransportObjective { + doc /*deliver passenger to destination safely, comfortably, and within acceptable time*/ + require transportRequirements; + } + subject vehicle:Vehicle; + actor environment; + actor road; + actor driver; + actor passenger [0..4]; + include use case getInVehicle_a:>getInVehicle [1..5]; + include use case getOutOfVehicle_a:>getOutOfVehicle [1..5]; + } + + use case getInVehicle:GetInVehicle { + action unlockDoor_in [0..1]; + then action openDoor_in; + then action enterVehicle; + then action closeDoor_in; + } + use case def GetInVehicle{ + subject vehicle:Vehicle; + actor driver [0..1]; + actor passenger [0..1]; + assert constraint {driver[1] xor passenger[1]} + } + + use case getOutOfVehicle:GetOutOfVehicle { + action openDoor_out; + then action exitVehicle; + then action closeDoor_out; + then action lockDoor_out; + } + use case def GetOutOfVehicle{ + subject vehicle:Vehicle; + actor driver [0..1]; + actor passenger [0..1]; + assert constraint {driver[1] xor passenger[1]} + } + } + package TransportPassengerScenario{ + import ContextDefinitions::TransportPassenger; + + // action defined by Use Case Def + // this version uses nesting vs fork and join for concurrent actions + action transportPassenger:TransportPassenger{ + first start; + then action a{ + action driverGetInVehicle subsets getInVehicle_a[1]; + action passenger1GetInVehicle subsets getInVehicle_a[1]; + } + then action trigger accept ignitionCmd:IgnitionCmd; + then action b{ + action driveVehicleToDestination; + action providePower; + } + then action c{ + action driverGetOutOfVehicle subsets getOutOfVehicle_a[1]; + action passenger1GetOutOfVehicle subsets getOutOfVehicle_a[1]; + } + then done; + } + + //this version uses forks and joins + action transportPassenger_1:TransportPassenger{ + // declare actions + action driverGetInVehicle subsets getInVehicle_a[1]; + action passenger1GetInVehicle subsets getInVehicle_a[1]; + action driverGetOutOfVehicle subsets getOutOfVehicle_a[1]; + action passenger1GetOutOfVehicle subsets getOutOfVehicle_a[1]; + action driveVehicleToDestination; + action providePower; + item def VehicleOnSignal; + join join1; + join join2; + join join3; + action trigger accept ignitionCmd:IgnitionCmd; + + // define control flow + first start; + then fork fork1; + then driverGetInVehicle; + then passenger1GetInVehicle; + first driverGetInVehicle then join1; + first passenger1GetInVehicle then join1; + first join1 then trigger; + first trigger then fork2; + //succession trigger if trigger.ignitionCmd.ignitionOnOff==IgnitionOnOff::on then fork2; + + fork fork2; + then driveVehicleToDestination; + then providePower; + first driveVehicleToDestination then join2; + first providePower then join2; + first join2 then fork3; + + fork fork3; + then driverGetOutOfVehicle; + then passenger1GetOutOfVehicle; + first driverGetOutOfVehicle then join3; + first passenger1GetOutOfVehicle then join3; + + first join3 then done; + } + } + + part missionContext:ContextDefinitions::MissionContext{ + perform transportPassenger; + part road:ContextDefinitions::Road; + part driver:ContextDefinitions::Driver{ + perform transportPassenger.a.driverGetInVehicle.unlockDoor_in; + perform transportPassenger.a.driverGetInVehicle.openDoor_in; + perform transportPassenger.a.driverGetInVehicle.enterVehicle; + perform transportPassenger.a.driverGetInVehicle.closeDoor_in; + perform transportPassenger.c.driverGetOutOfVehicle.openDoor_out; + perform transportPassenger.c.driverGetOutOfVehicle.exitVehicle; + perform transportPassenger.c.driverGetOutOfVehicle.closeDoor_out; + perform transportPassenger.c.driverGetOutOfVehicle.lockDoor_out; + perform transportPassenger.b.driveVehicleToDestination; + } + part passenger1:ContextDefinitions::Passenger{ + perform transportPassenger.a.passenger1GetInVehicle.unlockDoor_in; + perform transportPassenger.a.passenger1GetInVehicle.openDoor_in; + perform transportPassenger.a.passenger1GetInVehicle.enterVehicle; + perform transportPassenger.a.passenger1GetInVehicle.closeDoor_in; + perform transportPassenger.c.passenger1GetOutOfVehicle.openDoor_out; + perform transportPassenger.c.passenger1GetOutOfVehicle.exitVehicle; + perform transportPassenger.c.passenger1GetOutOfVehicle.closeDoor_out; + perform transportPassenger.c.passenger1GetOutOfVehicle.lockDoor_out; + } + part vehicle_b_1:>vehicle_b { + attribute :>> positionVector = (0,0,0) [spatialCS]; + perform transportPassenger.b.providePower redefines providePower; + perform transportPassenger.trigger; + } + connect driver.handPort to vehicle_b_1.ignitionCmdPort; + connect road to vehicle_b_1.vehicleToRoadPort; + } + } + package VehicleSuperSetModel{ + //recursive import with ** + import VehicleConfigurations::VehicleConfiguration_a::**; + /* all of vehicle_b must be included in the superset modelto make vehicle_b a specific vehicle configuration + from this product family instead of a subset of vehicle_a*/ + package VariationPointDefinitions { + variation part def TransmissionChoices:>Transmission { + variant part transmissionAutomatic:TransmissionAutomatic; + variant part transmissionManual:TransmissionManual; + } + } + package VehiclePartsTree{ + import VariationPointDefinitions::*; + abstract part vehicleFamily:>vehicle_a{ + // variation with nested variation + variation part engine:Engine{ + variant part engine4Cyl:Engine4Cyl; + variant part engine6Cyl:Engine6Cyl{ + part cylinder:Cylinder [6]{ + variation attribute diameter:LengthValue{ + variant attribute smallDiameter:LengthValue; + variant attribute largeDiagmeter:LengthValue; + } + } + } + } + // varaition point based on variation of part definition + variation part transmissionChoices:TransmissionChoices; + // optional variation point + variation part sunroof:Sunroof; + // selection constraint + assert constraint { + (engine==engine::engine4Cyl and transmissionChoices==TransmissionChoices::transmissionManual) xor + (engine==engine::engine6Cyl and transmissionChoices==TransmissionChoices::transmissionAutomatic) + } + } + } + } + package SafetyandSecurityGroups { + import VehicleConfigurations::VehicleConfiguration_b::PartsTree::*; + package SafetyGroup { + /* Parts that contribute to safety. */ + import vehicle_b::**; + filter @Safety; + } + package SecurityGroup { + /* Parts that contribute to security. */ + import vehicle_b::**; + filter @Security; + } + package SafetyandSecurityGroup { + /* Parts that contribute to safety OR security. */ + import vehicle_b::**; + filter @Safety or @Security; + } + package MandatorySafetyGroup { + /* Parts that contribute to safety AND are mandatory. */ + import vehicle_b::**; + filter @Safety && Safety::isMandatory; + } + } + package Views_Viewpoints{ + package ViewpointDefinitions{ + viewpoint def BehaviorViewpoint; + viewpoint def SafetyViewpoint{ + frame concern vs:VehicleSafety; + } + part def SafetyEngineer; + concern def VehicleSafety { + doc /* clarify how system is decomposed */ + stakeholder se:SafetyEngineer; + } + } + package ViewDefinitions{ + //Import Views to access rendering method library + import Views::*; + view def TreeView{ + render asTreeDiagram; + } + view def NestedView; + view def RelationshipView; + view def TableView; + view def PartsTreeView:>TreeView { + // include query expression + filter @SysML::PartUsage; + //* + view attributes[*]{ + }*/ + } + view def PartsInterconnection:>NestedView; + } + package VehicleViews{ + import ViewpointDefinitions::*; + import ViewDefinitions::*; + import VehicleConfigurations::VehicleConfiguration_b::*; + view vehiclePartsTree_Safety:PartsTreeView{ + // if safetyViewpoint is a usage, statement can be satisfy safetyViewpoint + satisfy requirement sv:SafetyViewpoint; + expose PartsTree::**; + filter @Safety; + } + } + } + package OtherFunctionality{ + package NotOperator{ + attribute a; + attribute b; + assert not constraint {a>b} + /* + constraint constraint1 {a>b} + assert not constraint1; + */ + } + package ImpliesOperator{ + attribute a; + attribute b; + attribute c; + attribute d; + constraint {(a>b) => (d>c)} + + constraint constraint1 {a>b} + constraint constraint2 {d>c} + constraint {constraint1 () => constraint2()} + //constraint {constraint1() implies constraint2()} + } + package RedundancyExample{ + import SequenceFunctions::size; + part part0{ + part part1{ + port p1; + } + part part2{ + port p2_1; + port p2_2; + } + part part3{ + port p3_1; + port p3_2; + } + part part4{ + port p4; + } + connect part1.p1 to part2.p2_1; + connect part1.p1 to part3.p3_1; + connection connection1 connect part2.p2_2 to part4.p4; + connection connection2 connect part3.p3_2 to part4.p4; + //assert constraint connectXor {connection1==null xor connection2==null} + constraint connectXor1 {size (connection1)==1 xor size(connection2)==1} + } + } + package NamingExperiment{ + import A::*; + import B::*; + + package A{ + part def X{ + attribute i; + } + } + package B{ + part def X{ + attribute j; + } + } + package C{ + part x:X{ + attribute :>>i; + //the following causes an error + //attribute :>>j; + } + } + } + } +} \ No newline at end of file diff --git a/sysml/src/training/24. Transitions/Change and Time Triggers.sysml b/sysml/src/training/24. Transitions/Change and Time Triggers.sysml new file mode 100644 index 00000000..265ae1fc --- /dev/null +++ b/sysml/src/training/24. Transitions/Change and Time Triggers.sysml @@ -0,0 +1,43 @@ +package 'Change and Time Triggers' { + import ISQ::TemperatureValue; + import ISQ::DurationValue; + import Time::TimeInstantValue; + import SI::h; + + attribute def OverTemp; + + part def Vehicle { + attribute maintenanceTime : TimeInstantValue; + attribute maintenanceInterval : DurationValue; + attribute maxTemperature : TemperatureValue; + } + + part def VehicleController; + + action senseTemperature (out temp : TemperatureValue); + + state healthStates { + in vehicle : Vehicle; + in controller : VehicleController; + + entry; then normal; + do senseTemperature (out temp); + + state normal; + accept at vehicle.maintenanceTime + then maintenance; + accept when senseTemperature.temp > vehicle.maxTemperature + do send OverTemp() to controller + then degraded; + + state maintenance { + entry assign vehicle.maintenanceTime := vehicle.maintenanceTime + vehicle.maintenanceInterval; + } + accept after 48 [h] + then normal; + + state degraded; + accept when senseTemperature.temp <= vehicle.maxTemperature + then normal; + } +} \ No newline at end of file diff --git a/sysml/src/training/30. Constraints/Time Constraints.sysml b/sysml/src/training/30. Constraints/Time Constraints.sysml new file mode 100644 index 00000000..bd2fde1b --- /dev/null +++ b/sysml/src/training/30. Constraints/Time Constraints.sysml @@ -0,0 +1,37 @@ +package 'Time Constraints' { + import ISQ::TemperatureValue; + import ISQ::DurationValue; + import Time::TimeInstantValue; + import Time::TimeOf; + import Time::DurationOf; + import SI::h; + import SI::s; + + attribute def MaintenanceDone; + + part def Vehicle { + attribute maintenanceTime : TimeInstantValue; + attribute maintenanceInterval : DurationValue; + attribute maxTemperature : TemperatureValue; + } + + state healthStates { + in vehicle : Vehicle; + + entry; then normal; + + state normal; + accept at vehicle.maintenanceTime + then maintenance; + + state maintenance { + assert constraint { TimeOf(maintenance) > vehicle.maintenanceTime } + assert constraint { TimeOf(maintenance) - TimeOf(normal.done) < 2 [s] } + entry assign vehicle.maintenanceTime := vehicle.maintenanceTime + vehicle.maintenanceInterval; + } + accept MaintenanceDone + then normal; + + constraint { DurationOf(maintenance) <= 48 [h] } + } +} \ No newline at end of file diff --git a/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-1.sysml b/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-1.sysml index 44fb8f73..131a6430 100644 --- a/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-1.sysml +++ b/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-1.sysml @@ -39,15 +39,6 @@ package '5-State-based Behavior-1' { attribute def 'Off Signal'; attribute def 'Over Temp'; attribute def 'Return to Normal'; - - /* - * The following attribute defs are used to fill in for the - * current lack of support for time events and change events, - * respectively. - */ - - attribute def 'at(vehicle.maintenanceTime)'; - attribute def 'when(temp>vehicle.Tmax)'; } package Usages { @@ -67,6 +58,7 @@ package '5-State-based Behavior-1' { * Note that it depends specifically on on the part 'vehicle1_c1'. */ state 'vehicle states': 'Vehicle States' parallel { + ref vehicle : VehicleA; /** * The state definition for this usage is implicit. @@ -138,12 +130,12 @@ package '5-State-based Behavior-1' { transition 'normal-maintenance' first normal - accept 'at(vehicle.maintenanceTime)' // Should be a time event trigger. + accept at vehicle1_c1.maintenanceTime then maintenance; transition 'normal-degraded' first normal - accept 'when(temp>vehicle.Tmax)' // Should be a change event trigger. + accept when 'sense temperature'.temp > vehicle1_c1.Tmax do send 'Over Temp'() to vehicle1_c1.vehicleController then degraded; diff --git a/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-1a.sysml b/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-1a.sysml index 846b1cbb..d29b7ff3 100644 --- a/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-1a.sysml +++ b/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-1a.sysml @@ -41,15 +41,6 @@ package '5-State-based Behavior-1a' { attribute def 'Off Signal'; attribute def 'Over Temp'; attribute def 'Return to Normal'; - - /* - * The following attribute defs are used to fill in for the - * current lack of support for time events and change events, - * respectively. - */ - - attribute def 'at(vehicle.maintenanceTime)'; - attribute def 'when(temp>vehicle.Tmax)'; } package Usages { @@ -141,12 +132,12 @@ package '5-State-based Behavior-1a' { transition 'normal-maintenance' first normal - accept 'at(vehicle.maintenanceTime)' // Should be a time event trigger. + accept at vehicle1_c1.maintenanceTime then maintenance; transition 'normal-degraded' first normal - accept 'when(temp>vehicle.Tmax)' // Should be a change event trigger. + accept when 'sense temperature'.temp > vehicle1_c1.Tmax do send 'Over Temp'() to vehicle1_c1.vehicleController then degraded; diff --git a/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-2.sysml b/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-2.sysml index c0473237..b27fd908 100644 --- a/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-2.sysml +++ b/sysml/src/validation/05-State-based Behavior/5-State-based Behavior-2.sysml @@ -28,9 +28,6 @@ package '5-State-based Behavior-2' { attribute def 'Off Signal'; attribute def 'Over Temp'; attribute def 'Return to Normal'; - - attribute def 'at(vehicle.maintenanceTime)'; - attribute def 'when(temp>vehicle.Tmax)'; } package Usages { @@ -77,9 +74,9 @@ package '5-State-based Behavior-2' { * a single state. */ state normal; - accept 'at(vehicle.maintenanceTime)' + accept at vehicle1_c1.maintenanceTime then maintenance; - accept 'when(temp>vehicle.Tmax)' + accept when 'sense temperature'.temp > vehicle1_c1.Tmax do send 'Over Temp'() to vehicle1_c1.vehicleController then degraded; diff --git a/sysml/src/validation/10-Analysis and Trades/10c-Fuel Economy Analysis.sysml b/sysml/src/validation/10-Analysis and Trades/10c-Fuel Economy Analysis.sysml index c986f4bc..da161988 100644 --- a/sysml/src/validation/10-Analysis and Trades/10c-Fuel Economy Analysis.sysml +++ b/sysml/src/validation/10-Analysis and Trades/10c-Fuel Economy Analysis.sysml @@ -5,7 +5,7 @@ package '10c-Fuel Economy Analysis' { import ISQ::*; import USCustomaryUnits::*; - attribute distancePerVolume : QuantityValue = length / volume; + attribute distancePerVolume : ScalarQuantityValue = length / volume; attribute gallon : MeasurementUnit = 231.0 * 'in'^3; package FuelEconomyRequirementsModel { @@ -76,7 +76,7 @@ package '10c-Fuel Economy Analysis' { subject vehicle : Vehicle; in calc scenario : NominalScenario; in requirement fuelEconomyRequirement : FuelEconomyRequirement; - return calculatedFuelEconomy : QuantityValue; + return calculatedFuelEconomy : ScalarQuantityValue; objective fuelEconomyAnalysisObjective { doc /*