modspec 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +4 -0
  3. data/.github/workflows/release.yml +5 -0
  4. data/.rubocop.yml +16 -7
  5. data/.rubocop_todo.yml +67 -80
  6. data/CLAUDE.md +61 -0
  7. data/Gemfile +5 -3
  8. data/lib/modspec/conformance_class.rb +4 -4
  9. data/lib/modspec/conformance_test.rb +21 -6
  10. data/lib/modspec/normative_statement.rb +10 -3
  11. data/lib/modspec/normative_statements_class.rb +7 -5
  12. data/lib/modspec/suite.rb +86 -34
  13. data/lib/modspec/version.rb +1 -1
  14. data/lib/modspec.rb +1 -12
  15. data/modspec.gemspec +3 -2
  16. data/spec/conformance_class.liquid +2 -2
  17. data/spec/fixtures/advanced-json-rc.yaml +5 -7
  18. data/spec/fixtures/advanced-rc.yaml +12 -14
  19. data/spec/fixtures/basic-quaternion-json-rc.yaml +5 -7
  20. data/spec/fixtures/basic-quaternion-json-strict-rc.yaml +4 -5
  21. data/spec/fixtures/basic-quaternion-rc.yaml +7 -8
  22. data/spec/fixtures/basic-ypr-json-rc.yaml +5 -8
  23. data/spec/fixtures/basic-ypr-rc.yaml +7 -7
  24. data/spec/fixtures/chain-json-rc.yaml +5 -7
  25. data/spec/fixtures/chain-rc.yaml +11 -13
  26. data/spec/fixtures/frame-spec-rc.yaml +10 -10
  27. data/spec/fixtures/global-rc.yaml +7 -4
  28. data/spec/fixtures/graph-json-rc.yaml +5 -7
  29. data/spec/fixtures/graph-rc.yaml +11 -13
  30. data/spec/fixtures/series-irregular-json-rc.yaml +5 -7
  31. data/spec/fixtures/series-irregular-rc.yaml +13 -15
  32. data/spec/fixtures/series-regular-json-rc.yaml +5 -7
  33. data/spec/fixtures/series-regular-rc.yaml +15 -17
  34. data/spec/fixtures/stream-json-rc.yaml +9 -11
  35. data/spec/fixtures/stream-rc.yaml +10 -12
  36. data/spec/fixtures/tangent-point-rc.yaml +10 -11
  37. data/spec/fixtures/time-rc.yaml +6 -8
  38. data/spec/modspec/conformance_class_spec.rb +29 -27
  39. data/spec/modspec/conformance_test_spec.rb +6 -5
  40. data/spec/modspec/normative_statement_spec.rb +16 -12
  41. data/spec/modspec/normative_statements_class_spec.rb +4 -4
  42. data/spec/modspec/suite_spec.rb +26 -22
  43. data/spec/modspec_spec.rb +7 -7
  44. data/spec/spec_helper.rb +1 -0
  45. metadata +7 -5
data/lib/modspec/suite.rb CHANGED
@@ -6,40 +6,57 @@ module Modspec
6
6
  class Suite < Lutaml::Model::Serializable
7
7
  attribute :identifier, Identifier
8
8
  attribute :name, :string
9
- attribute :normative_statements_classes, NormativeStatementsClass, collection: true
9
+ attribute :normative_statements_classes, NormativeStatementsClass,
10
+ collection: true
10
11
  attribute :conformance_classes, ConformanceClass, collection: true
11
12
 
12
13
  xml do
13
- root "suite"
14
+ element "suite"
14
15
  map_attribute "identifier", to: :identifier
15
16
  map_element "name", to: :name
16
- map_element "normative-statements-classes", to: :normative_statements_classes
17
+ map_element "normative-statements-classes",
18
+ to: :normative_statements_classes
17
19
  map_element "conformance-classes", to: :conformance_classes
18
20
  end
19
21
 
20
22
  def validate
21
23
  setup_relationships
22
24
  self.all_identifiers = nil
23
- errors = super()
25
+ errors = super
24
26
  errors.concat(validate_cycles)
25
27
  errors.concat(validate_label_uniqueness)
26
28
  errors.concat(validate_dependencies)
27
- errors.concat(normative_statements_classes.flat_map { |n| n.validate(self) })
28
- errors.concat(conformance_classes.flat_map(&:validate))
29
+ unless normative_statements_classes.nil?
30
+ errors.concat(normative_statements_classes.flat_map do |n|
31
+ n.validate(self)
32
+ end)
33
+ end
34
+ errors.concat(conformance_classes.flat_map(&:validate)) unless conformance_classes.nil?
29
35
  errors
30
36
  end
31
37
 
32
38
  def combine(other_suite)
33
- raise ArgumentError, "Argument must be a Modspec::Suite" unless other_suite.is_a?(Modspec::Suite)
39
+ unless other_suite.is_a?(Modspec::Suite)
40
+ raise ArgumentError,
41
+ "Argument must be a Modspec::Suite"
42
+ end
34
43
 
35
44
  combined_suite = dup
36
45
  combined_suite.all_identifiers = nil
37
- combined_suite.normative_statements_classes += other_suite.normative_statements_classes
38
- combined_suite.conformance_classes += other_suite.conformance_classes
46
+ if other_suite.normative_statements_classes
47
+ combined_suite.normative_statements_classes ||= []
48
+ combined_suite.normative_statements_classes += other_suite.normative_statements_classes
49
+ end
50
+
51
+ if other_suite.conformance_classes
52
+ combined_suite.conformance_classes ||= []
53
+ combined_suite.conformance_classes += other_suite.conformance_classes
54
+ end
39
55
 
40
56
  # Ensure uniqueness of identifiers
41
- combined_suite.normative_statements_classes.uniq!(&:identifier)
42
- combined_suite.conformance_classes.uniq!(&:identifier)
57
+ combined_suite.normative_statements_classes&.uniq!(&:identifier)
58
+
59
+ combined_suite.conformance_classes&.uniq!(&:identifier)
43
60
 
44
61
  combined_suite.name = "#{name} + #{other_suite.name}"
45
62
 
@@ -47,17 +64,24 @@ module Modspec
47
64
  end
48
65
 
49
66
  def all_identifiers
50
- @all_identifiers ||= (normative_statements_classes.flat_map(&:normative_statements) +
51
- conformance_classes.flat_map(&:tests) +
52
- normative_statements_classes +
53
- conformance_classes).map(&:identifier)
67
+ return @all_identifiers if @all_identifiers
68
+
69
+ nsc = normative_statements_classes || []
70
+ cc = conformance_classes || []
71
+
72
+ @all_identifiers = (nsc.flat_map(&:normative_statements) +
73
+ cc.flat_map(&:tests) +
74
+ nsc +
75
+ cc).map(&:identifier)
54
76
  end
55
77
 
56
78
  attr_writer :all_identifiers
57
79
 
58
80
  def resolve_conflicts(other_suite)
59
- resolve_conflicts_for(normative_statements_classes, other_suite.normative_statements_classes)
60
- resolve_conflicts_for(conformance_classes, other_suite.conformance_classes)
81
+ resolve_conflicts_for(normative_statements_classes,
82
+ other_suite.normative_statements_classes)
83
+ resolve_conflicts_for(conformance_classes,
84
+ other_suite.conformance_classes)
61
85
  end
62
86
 
63
87
  def self.from_yaml_files(*files)
@@ -71,12 +95,18 @@ module Modspec
71
95
  end
72
96
 
73
97
  def setup_relationships
74
- all_requirements = normative_statements_classes.flat_map(&:normative_statements)
98
+ all_requirements = if normative_statements_classes
99
+ normative_statements_classes.flat_map(&:normative_statements)
100
+ else
101
+ []
102
+ end
103
+
104
+ return unless conformance_classes
75
105
 
76
106
  conformance_classes.each do |cc|
77
107
  cc.tests.each do |ct|
78
108
  ct.corresponding_requirements = all_requirements.select do |r|
79
- ct.targets.map(&:to_s).include?(r.identifier.to_s)
109
+ Array(ct.targets).map(&:to_s).include?(r.identifier.to_s)
80
110
  end
81
111
  ct.parent_class = cc
82
112
  end
@@ -86,8 +116,12 @@ module Modspec
86
116
  private
87
117
 
88
118
  def resolve_conflicts_for(self_collection, other_collection)
119
+ return if self_collection.nil? || other_collection.nil?
120
+
89
121
  other_collection.each do |other_item|
90
- existing_item = self_collection.find { |item| item.identifier == other_item.identifier }
122
+ existing_item = self_collection.find do |item|
123
+ item.identifier == other_item.identifier
124
+ end
91
125
  if existing_item
92
126
  # Merge attributes of conflicting items
93
127
  merge_attributes(existing_item, other_item)
@@ -112,21 +146,40 @@ module Modspec
112
146
  def validate_cycles
113
147
  graph = build_dependency_graph
114
148
  cycles = detect_cycles(graph)
115
- cycles.map { |cycle| "Cycle detected: #{cycle.join(" -> ")}" }
149
+ cycles.map { |cycle| "Cycle detected: #{cycle.join(' -> ')}" }
150
+ end
151
+
152
+ # Combine all statements into a single array
153
+ # This includes both normative statements and conformance tests
154
+ def all_statements
155
+ nsc = if normative_statements_classes
156
+ normative_statements_classes.flat_map(&:normative_statements)
157
+ else
158
+ []
159
+ end
160
+ cc = if conformance_classes
161
+ conformance_classes.flat_map(&:tests)
162
+ else
163
+ []
164
+ end
165
+
166
+ nsc + cc
116
167
  end
117
168
 
118
169
  def build_dependency_graph
119
170
  graph = {}
120
- all_statements = normative_statements_classes.flat_map(&:normative_statements) +
121
- conformance_classes.flat_map(&:tests)
122
171
 
123
172
  all_statements.each do |statement|
124
173
  id = statement.identifier.to_s
125
174
  graph[id] = Set.new
126
- graph[id].merge(statement.dependencies.map(&:to_s)) if statement.respond_to?(:dependencies)
127
- graph[id].merge(statement.indirect_dependency.map(&:to_s)) if statement.respond_to?(:indirect_dependency)
128
- graph[id].merge(statement.implements.map(&:to_s)) if statement.respond_to?(:implements)
129
- graph[id].merge(statement.targets.map(&:to_s)) if statement.respond_to?(:targets)
175
+
176
+ # Define all dependency-like properties to check
177
+ dependency_properties = %i[dependencies indirect_dependency implements
178
+ targets]
179
+
180
+ dependency_properties.each do |property|
181
+ graph[id].merge(statement.send(property).map(&:to_s)) if statement.respond_to?(property) && !statement.send(property).nil?
182
+ end
130
183
  end
131
184
 
132
185
  graph
@@ -156,7 +209,8 @@ module Modspec
156
209
  if graph[node]
157
210
  graph[node].each do |neighbor|
158
211
  if !visited.include?(neighbor)
159
- cycle = detect_cycle_util(neighbor, graph, visited, recursion_stack, path)
212
+ cycle = detect_cycle_util(neighbor, graph, visited,
213
+ recursion_stack, path)
160
214
  return cycle if cycle
161
215
  elsif recursion_stack.include?(neighbor)
162
216
  return path[path.index(neighbor)..] + [neighbor]
@@ -175,8 +229,6 @@ module Modspec
175
229
  def validate_label_uniqueness
176
230
  labels = {}
177
231
  errors = []
178
- all_statements = normative_statements_classes.flat_map(&:normative_statements) +
179
- conformance_classes.flat_map(&:tests)
180
232
  all_statements.each do |statement|
181
233
  if labels[statement.identifier]
182
234
  errors << "Duplicate identifier found: #{statement.identifier}"
@@ -191,14 +243,14 @@ module Modspec
191
243
  all_identifiers = collect_all_identifiers
192
244
 
193
245
  errors = []
194
- normative_statements_classes.each do |nsc|
246
+ normative_statements_classes&.each do |nsc|
195
247
  errors.concat(validate_class_dependencies(nsc, all_identifiers))
196
248
  nsc.normative_statements.each do |ns|
197
249
  errors.concat(validate_statement_dependencies(ns, all_identifiers))
198
250
  end
199
251
  end
200
252
 
201
- conformance_classes.each do |cc|
253
+ conformance_classes&.each do |cc|
202
254
  errors.concat(validate_class_dependencies(cc, all_identifiers))
203
255
  cc.tests.each do |ct|
204
256
  errors.concat(validate_test_targets(ct, all_identifiers))
@@ -211,14 +263,14 @@ module Modspec
211
263
  def collect_all_identifiers
212
264
  identifiers = {}
213
265
 
214
- normative_statements_classes.each do |nsc|
266
+ normative_statements_classes&.each do |nsc|
215
267
  identifiers[nsc.identifier.to_s] = nsc
216
268
  nsc.normative_statements.each do |ns|
217
269
  identifiers[ns.identifier.to_s] = ns
218
270
  end
219
271
  end
220
272
 
221
- conformance_classes.each do |cc|
273
+ conformance_classes&.each do |cc|
222
274
  identifiers[cc.identifier.to_s] = cc
223
275
  cc.tests.each do |ct|
224
276
  identifiers[ct.identifier.to_s] = ct
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Modspec
4
- VERSION = "0.1.3"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/modspec.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "modspec/version"
4
4
  require "lutaml/model"
5
+ require "set"
5
6
 
6
7
  module Modspec
7
8
  class Error < StandardError; end
@@ -15,15 +16,3 @@ require_relative "modspec/normative_statements_class"
15
16
  require_relative "modspec/conformance_test"
16
17
  require_relative "modspec/conformance_class"
17
18
  require_relative "modspec/suite"
18
-
19
- require "lutaml/model/xml_adapter/nokogiri_adapter"
20
- require "lutaml/model/json_adapter/standard_json_adapter"
21
- require "lutaml/model/toml_adapter/toml_rb_adapter"
22
- require "lutaml/model/yaml_adapter/standard_yaml_adapter"
23
-
24
- Lutaml::Model::Config.configure do |config|
25
- config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter
26
- config.yaml_adapter = Lutaml::Model::YamlAdapter::StandardYamlAdapter
27
- config.json_adapter = Lutaml::Model::JsonAdapter::StandardJsonAdapter
28
- config.toml_adapter = Lutaml::Model::TomlAdapter::TomlRbAdapter
29
- end
data/modspec.gemspec CHANGED
@@ -20,16 +20,17 @@ Gem::Specification.new do |spec|
20
20
  spec.metadata["homepage_uri"] = spec.homepage
21
21
  spec.metadata["source_code_uri"] = spec.homepage
22
22
  spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
23
+ spec.metadata["rubygems_mfa_required"] = "true"
23
24
 
24
25
  # Specify which files should be added to the gem when it is released.
25
26
  spec.files = all_files_in_git
26
- .reject { |f| f.match(%r{\A(?:test|features|bin|\.)/}) }
27
+ .reject { |f| f.match(%r{\A(?:test|features|bin|\.)/}) }
27
28
 
28
29
  spec.bindir = "exe"
29
30
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
31
  spec.require_paths = ["lib"]
31
32
 
32
- spec.add_dependency "lutaml-model", "~> 0.6"
33
+ spec.add_dependency "lutaml-model", "~> 0.8.0"
33
34
  spec.add_dependency "nokogiri"
34
35
  spec.add_dependency "toml-rb"
35
36
  end
@@ -80,11 +80,11 @@ guidance::
80
80
  test-purpose:: {{test.purpose}}
81
81
  {% endif %}
82
82
 
83
- {% if {{test.method}} %}
83
+ {% if {{test.test_method}} %}
84
84
  test-method::
85
85
  +
86
86
  --
87
- {{test.method}}
87
+ {{test.test_method}}
88
88
  --
89
89
  {% endif %}
90
90
 
@@ -1,16 +1,14 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: JSON encoding of Advanced SDU
4
- identifier: /req/advanced-encoding-json
5
- description: |
6
- Requirements for the JSON encoding of a Advanced SDU.
4
+ identifier: "/req/advanced-encoding-json"
5
+ description: 'Requirements for the JSON encoding of a Advanced SDU.'
7
6
  implements:
8
- - /req/advanced
9
-
7
+ - "/req/advanced"
10
8
  normative_statements:
11
-
12
9
  - name: Specification as JSON schema
13
- identifier: /req/advanced-encoding-json/definition
10
+ identifier: "/req/advanced-encoding-json/definition"
14
11
  statement: |
15
12
  A JSON-encoded Advanced GeoPose SHALL conform to the
16
13
  Advanced JSON-Schema 2019-9 definition (<<advanced_geopose_json_schema>>).
14
+ obligation: requirement
@@ -1,37 +1,34 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: Advanced logical model SDU
4
- identifier: /req/advanced
4
+ identifier: "/req/advanced"
5
5
  description: |
6
6
  The Advanced Target has a more general structure than Basic-YPR and
7
7
  Basic-Quaternion, supporting flexible specification of Outer Frame and a
8
8
  Valid Time.
9
-
10
9
  dependencies:
11
- - /req/global
12
- - /req/frame-spec
13
- - /req/time
10
+ - "/req/global"
11
+ - "/req/frame-spec"
12
+ - "/req/time"
14
13
  normative_statements:
15
-
16
14
  - name: Expression of valid time as GeoPose_Instant
17
- identifier: /req/advanced/valid-time
15
+ identifier: "/req/advanced/valid-time"
18
16
  dependencies:
19
- - /req/time/instant
20
-
17
+ - "/req/time/instant"
21
18
  statement: |
22
19
  The `Advanced.validTime` attribute shall be represented by a
23
20
  `GeoPose_Instant` object.
24
-
21
+ obligation: requirement
25
22
  - name: Expression of outer frame
26
- identifier: /req/advanced/frame-spec
23
+ identifier: "/req/advanced/frame-spec"
27
24
  dependencies:
28
- - /req/frame-spec
25
+ - "/req/frame-spec"
29
26
  statement: |
30
27
  The `Advanced.frameSpecification` attribute shall represent an explicit
31
28
  frame specification with the `ExplicitFrameSpec` object.
32
-
29
+ obligation: requirement
33
30
  - name: Expression of inner frame
34
- identifier: /req/advanced/quaternion
31
+ identifier: "/req/advanced/quaternion"
35
32
  statement: |
36
33
  The `Advanced.quaternion` attribute shall contain a quaternion expressed
37
34
  using the UnitQuaternion datatype value expressed as four real numbers,
@@ -41,3 +38,4 @@ normative_statements_classes:
41
38
  SHALL be applied to an initial reference frame oriented East-North-Up
42
39
  (ENU) coordinate system where the coordinate axes East, North, and Up
43
40
  correspond to the axes X, Y, Z.
41
+ obligation: requirement
@@ -1,17 +1,15 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: Permissive JSON encoding of Basic-Quaternion SDU
4
- identifier: /req/basic-quaternion-encoding-json
5
- description: |
6
- Requirements for the JSON encoding of a Basic-Quaternion SDU.
4
+ identifier: "/req/basic-quaternion-encoding-json"
5
+ description: 'Requirements for the JSON encoding of a Basic-Quaternion SDU.'
7
6
  implements:
8
- - /req/basic-quaternion
9
-
7
+ - "/req/basic-quaternion"
10
8
  normative_statements:
11
-
12
9
  - name: Specification as JSON schema
13
- identifier: /req/basic-quaternion-encoding-json/definition
10
+ identifier: "/req/basic-quaternion-encoding-json/definition"
14
11
  statement: |
15
12
  A JSON-encoded Basic-Quaternion GeoPose SHALL conform to the
16
13
  Basic-Quaternion JSON-Schema 2019-9 definition
17
14
  (<<basic_quaternion_permissive_json_schema>>).
15
+ obligation: requirement
@@ -1,19 +1,18 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: Strict JSON encoding of Basic-Quaternion SDU
4
- identifier: /req/basic-quaternion-encoding-json-strict
4
+ identifier: "/req/basic-quaternion-encoding-json-strict"
5
5
  description: |
6
6
  Requirements for the JSON encoding of a Basic-Quaternion SDU in strict mode.
7
7
  The strict encoding does not allow specification of JSON elements outside of
8
8
  the schema.
9
9
  implements:
10
- - /req/basic-quaternion
11
-
10
+ - "/req/basic-quaternion"
12
11
  normative_statements:
13
-
14
12
  - name: Specification as JSON schema
15
- identifier: /req/basic-quaternion-encoding-json-strict/definition
13
+ identifier: "/req/basic-quaternion-encoding-json-strict/definition"
16
14
  statement: |
17
15
  A JSON-encoded Basic-Quaternion GeoPose SHALL conform to the
18
16
  strict Basic-Quaternion JSON-Schema 2019-9 definition
19
17
  (<<basic_quaternion_strict_json_schema>>).
18
+ obligation: requirement
@@ -1,26 +1,24 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: Basic-Quaternion logical model SDU
4
- identifier: /req/basic-quaternion
4
+ identifier: "/req/basic-quaternion"
5
5
  description: |
6
6
  The Basic-Quaternion Target has a simple structure with no options. Position
7
7
  is specified as a point in an LTP-ENU frame and rotation is specified as a
8
8
  unit quaternion.
9
-
10
9
  dependencies:
11
- - /req/global
12
- - /req/tangent-point
10
+ - "/req/global"
11
+ - "/req/tangent-point"
13
12
  normative_statements:
14
-
15
13
  - name: Expression of outer frame
16
- identifier: /req/basic-quaternion/position
14
+ identifier: "/req/basic-quaternion/position"
17
15
  statement: |
18
16
  The `Basic_Quaternion.position` attribute shall represent the outer frame,
19
17
  specified by an implicit WGS-84 CRS and an implicit EPSG 4461-CS (LTP-ENU)
20
18
  coordinate system and explicit parameters to define the tangent point.
21
-
19
+ obligation: requirement
22
20
  - name: Expression of inner frame
23
- identifier: /req/basic-quaternion/quaternion
21
+ identifier: "/req/basic-quaternion/quaternion"
24
22
  statement: |
25
23
  The `Basic_Quaternion.quaternion` attribute shall represent the inner
26
24
  frame, which shall be a rotation-only transformation using a unit
@@ -32,3 +30,4 @@ normative_statements_classes:
32
30
  quaternion shall be applied to an initial reference frame oriented
33
31
  East-North-Up (ENU) coordinate system where the coordinate axes East,
34
32
  North, and Up correspond to the axes X, Y, Z.
33
+ obligation: requirement
@@ -1,21 +1,18 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: JSON encoding of Basic-YPR SDU
4
- identifier: /req/basic-ypr-encoding-json
5
- description: |
6
- Requirements for the JSON encoding of a Basic-YPR SDU.
4
+ identifier: "/req/basic-ypr-encoding-json"
5
+ description: 'Requirements for the JSON encoding of a Basic-YPR SDU.'
7
6
  implements:
8
- - /req/basic-ypr
9
-
7
+ - "/req/basic-ypr"
10
8
  normative_statements:
11
-
12
9
  - name: Specification as JSON schema
13
- identifier: /req/basic-ypr-encoding-json/definition
10
+ identifier: "/req/basic-ypr-encoding-json/definition"
14
11
  statement: |
15
12
  A JSON-encoded Basic-YPR GeoPose SHALL conform to the Basic-YPR
16
13
  JSON-Schema 2019-9 definition (<<basic_ypr_json_schema>>).
17
-
18
14
  guidance:
19
15
  - |
20
16
  This JSON encoding is extensible because the JSON-Schema
21
17
  "additionalProperties" property is set to the default value of *true*.
18
+ obligation: requirement
@@ -1,25 +1,24 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: Basic-YPR logical model SDU
4
- identifier: /req/basic-ypr
4
+ identifier: "/req/basic-ypr"
5
5
  description: |
6
6
  The Basic-YPR Target has a simple structure with no options. Position is
7
7
  specified as a point in an LTP-ENU frame and rotation is specified by yaw,
8
8
  pitch, and roll angles specified in decimal degrees.
9
9
  dependencies:
10
- - /req/global
11
- - /req/tangent-point
10
+ - "/req/global"
11
+ - "/req/tangent-point"
12
12
  normative_statements:
13
-
14
13
  - name: Expression of outer frame
15
- identifier: /req/basic-ypr/position
14
+ identifier: "/req/basic-ypr/position"
16
15
  statement: |
17
16
  The `Basic_YPR.position` attribute shall represent the outer frame,
18
17
  specified by an implicit WGS-84 CRS and an implicit EPSG 4461-CS (LTP-ENU)
19
18
  coordinate system and explicit parameters to define the tangent point.
20
-
19
+ obligation: requirement
21
20
  - name: Expression of inner frame
22
- identifier: /req/basic-ypr/angles
21
+ identifier: "/req/basic-ypr/angles"
23
22
  statement: |
24
23
  The `Basic_YPR.angles` attribute shall represent the inner frame,
25
24
  which is a rotation-only transformation with Yaw, Pitch, and Roll (YPR)
@@ -30,3 +29,4 @@ normative_statements_classes:
30
29
  x, applied in that order, corresponding to the conventional Yaw, Pitch,
31
30
  and Roll angles. The unit of measure SHALL be the degree and the angles
32
31
  represented as signed real number values.
32
+ obligation: requirement
@@ -1,16 +1,13 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: JSON encoding of Chain SDU
4
- identifier: /req/chain-encoding-json
5
- description: |
6
- Requirements for the JSON encoding of a Chain SDU.
4
+ identifier: "/req/chain-encoding-json"
5
+ description: 'Requirements for the JSON encoding of a Chain SDU.'
7
6
  implements:
8
- - /req/chain
9
-
7
+ - "/req/chain"
10
8
  normative_statements:
11
-
12
9
  - name: Specification as JSON schema
13
- identifier: /req/chain-encoding-json/definition
10
+ identifier: "/req/chain-encoding-json/definition"
14
11
  statement: |
15
12
  A JSON-encoded GeoPose Chain SHALL conform to the GeoPose Chain
16
13
  JSON-Schema 2019-9 definition (<<chain_json_schema>>).
@@ -18,3 +15,4 @@ normative_statements_classes:
18
15
  - |
19
16
  This JSON encoding is extensible because the JSON-Schema
20
17
  "additionalProperties" property is set to the default value of *true*.
18
+ obligation: requirement
@@ -1,36 +1,34 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: Chain logical model SDU
4
- identifier: /req/chain
4
+ identifier: "/req/chain"
5
5
  description: |
6
6
  The Chain Target supports relationships between a linear sequence of pose
7
7
  relationships. The first frame in the sequence must be an Outer Frame.
8
-
9
8
  dependencies:
10
- - /req/global
11
- - /req/frame-spec
12
- - /req/time
13
-
9
+ - "/req/global"
10
+ - "/req/frame-spec"
11
+ - "/req/time"
14
12
  normative_statements:
15
-
16
13
  - name: Expression of valid time as GeoPose_Instant
17
- identifier: /req/chain/valid-time
14
+ identifier: "/req/chain/valid-time"
18
15
  dependencies:
19
- - /req/time/instant
16
+ - "/req/time/instant"
20
17
  statement: |
21
18
  The `Chain.validTime` attribute shall be represented by a
22
19
  `GeoPose_Instant` object.
23
-
20
+ obligation: requirement
24
21
  - name: Specification of initial frame
25
- identifier: /req/chain/initial-frame
22
+ identifier: "/req/chain/initial-frame"
26
23
  statement: |
27
24
  The `Chain.outerFrame` attribute shall represent the first frame in the
28
25
  sequence with the `ExplicitFrameSpec` object.
29
-
26
+ obligation: requirement
30
27
  - name: Chain of frame specifications
31
- identifier: /req/chain/frame-chain
28
+ identifier: "/req/chain/frame-chain"
32
29
  statement: |
33
30
  The `Chain.frameChain` attribute shall represent a list of explicit
34
31
  frame specifications with an array of `ExplicitFrameSpec` objects.
35
32
  Each index value shall be a distinct integer value between 0 and one less
36
33
  than the number of elements in the frameChain property.
34
+ obligation: requirement
@@ -1,27 +1,27 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: Frame specification requirements
4
- identifier: /req/frame-spec
5
- description: |
6
- Common frame specification requirements for SDUs that include frames.
4
+ identifier: "/req/frame-spec"
5
+ description: 'Common frame specification requirements for SDUs that include frames.'
7
6
  normative_statements:
8
-
9
- - name: Frame specification authority uniquely specifies source of reference frame specification
10
- identifier: /req/frame-spec/authority
7
+ - name: Frame specification authority uniquely specifies source of reference frame
8
+ specification
9
+ identifier: "/req/frame-spec/authority"
11
10
  statement: |
12
11
  The FrameSpecification.authority attribute SHALL contain a string uniquely
13
12
  specifying a source of reference frame specifications.
14
-
13
+ obligation: requirement
15
14
  - name: Frame specification ID uniquely defines frame within authority
16
- identifier: /req/frame-spec/id
15
+ identifier: "/req/frame-spec/id"
17
16
  statement: |
18
17
  The FrameSpecification.ID attribute SHALL be a string uniquely defining a
19
18
  frame within the authority.
20
-
19
+ obligation: requirement
21
20
  - name: Frame specification parameter contains all parameters needed
22
- identifier: /req/frame-spec/parameters
21
+ identifier: "/req/frame-spec/parameters"
23
22
  statement: |
24
23
  The FrameSpecification.parameter attribute SHALL contain all parameters
25
24
  needed for the corresponding authority and ID.
26
25
  guidance:
27
26
  - The definition of these parameters is outside the scope of GeoPose.
27
+ obligation: requirement