openc3 5.0.6

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 (307) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +18 -0
  3. data/Guardfile +35 -0
  4. data/LICENSE.txt +727 -0
  5. data/README.md +37 -0
  6. data/Rakefile +131 -0
  7. data/bin/cstol_converter +1178 -0
  8. data/bin/openc3cli +531 -0
  9. data/bin/rubysloc +139 -0
  10. data/data/config/_array_params.yaml +23 -0
  11. data/data/config/_id_items.yaml +24 -0
  12. data/data/config/_id_params.yaml +58 -0
  13. data/data/config/_interfaces.yaml +214 -0
  14. data/data/config/_interfaces.yaml.err +1017 -0
  15. data/data/config/_items.yaml +20 -0
  16. data/data/config/_params.yaml +60 -0
  17. data/data/config/cmd_tlm_server.yaml +136 -0
  18. data/data/config/command.yaml +44 -0
  19. data/data/config/command_modifiers.yaml +160 -0
  20. data/data/config/command_telemetry.yaml +3 -0
  21. data/data/config/interface_modifiers.yaml +104 -0
  22. data/data/config/item_modifiers.yaml +221 -0
  23. data/data/config/microservice.yaml +78 -0
  24. data/data/config/param_item_modifiers.yaml +52 -0
  25. data/data/config/parameter_modifiers.yaml +200 -0
  26. data/data/config/plugins.yaml +80 -0
  27. data/data/config/protocols.yaml +290 -0
  28. data/data/config/screen.yaml +147 -0
  29. data/data/config/table_manager.yaml +89 -0
  30. data/data/config/table_parameter_modifiers.yaml +9 -0
  31. data/data/config/target.yaml +142 -0
  32. data/data/config/target_config.yaml +94 -0
  33. data/data/config/telemetry.yaml +87 -0
  34. data/data/config/telemetry_modifiers.yaml +159 -0
  35. data/data/config/tool.yaml +63 -0
  36. data/data/config/unknown.yaml +3 -0
  37. data/data/config/widgets.yaml +1505 -0
  38. data/ext/mkrf_conf.rb +49 -0
  39. data/ext/openc3/ext/array/array.c +122 -0
  40. data/ext/openc3/ext/array/extconf.rb +13 -0
  41. data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
  42. data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
  43. data/ext/openc3/ext/config_parser/config_parser.c +280 -0
  44. data/ext/openc3/ext/config_parser/extconf.rb +13 -0
  45. data/ext/openc3/ext/crc/crc.c +351 -0
  46. data/ext/openc3/ext/crc/extconf.rb +13 -0
  47. data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
  48. data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
  49. data/ext/openc3/ext/packet/extconf.rb +13 -0
  50. data/ext/openc3/ext/packet/packet.c +318 -0
  51. data/ext/openc3/ext/platform/extconf.rb +13 -0
  52. data/ext/openc3/ext/platform/platform.c +134 -0
  53. data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
  54. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
  55. data/ext/openc3/ext/string/extconf.rb +13 -0
  56. data/ext/openc3/ext/string/string.c +63 -0
  57. data/ext/openc3/ext/structure/structure.c +1719 -0
  58. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
  59. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
  60. data/ext/openc3/ext/telemetry/extconf.rb +13 -0
  61. data/ext/openc3/ext/telemetry/telemetry.c +336 -0
  62. data/lib/cosmos.rb +20 -0
  63. data/lib/cosmosc2.rb +20 -0
  64. data/lib/openc3/api/api.rb +39 -0
  65. data/lib/openc3/api/authorized_api.rb +30 -0
  66. data/lib/openc3/api/cmd_api.rb +451 -0
  67. data/lib/openc3/api/config_api.rb +58 -0
  68. data/lib/openc3/api/interface_api.rb +117 -0
  69. data/lib/openc3/api/limits_api.rb +375 -0
  70. data/lib/openc3/api/router_api.rb +117 -0
  71. data/lib/openc3/api/settings_api.rb +70 -0
  72. data/lib/openc3/api/target_api.rb +78 -0
  73. data/lib/openc3/api/tlm_api.rb +455 -0
  74. data/lib/openc3/bridge/bridge.rb +54 -0
  75. data/lib/openc3/bridge/bridge_config.rb +167 -0
  76. data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
  77. data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
  78. data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
  79. data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
  80. data/lib/openc3/config/config_parser.rb +549 -0
  81. data/lib/openc3/config/meta_config_parser.rb +74 -0
  82. data/lib/openc3/conversions/conversion.rb +70 -0
  83. data/lib/openc3/conversions/generic_conversion.rb +83 -0
  84. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
  85. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
  86. data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
  87. data/lib/openc3/conversions/processor_conversion.rb +70 -0
  88. data/lib/openc3/conversions/received_count_conversion.rb +38 -0
  89. data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
  90. data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
  91. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
  92. data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
  93. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
  94. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
  95. data/lib/openc3/conversions.rb +34 -0
  96. data/lib/openc3/core_ext/array.rb +416 -0
  97. data/lib/openc3/core_ext/binding.rb +29 -0
  98. data/lib/openc3/core_ext/class.rb +72 -0
  99. data/lib/openc3/core_ext/exception.rb +61 -0
  100. data/lib/openc3/core_ext/file.rb +83 -0
  101. data/lib/openc3/core_ext/hash.rb +37 -0
  102. data/lib/openc3/core_ext/io.rb +134 -0
  103. data/lib/openc3/core_ext/kernel.rb +42 -0
  104. data/lib/openc3/core_ext/math.rb +128 -0
  105. data/lib/openc3/core_ext/matrix.rb +156 -0
  106. data/lib/openc3/core_ext/objectspace.rb +36 -0
  107. data/lib/openc3/core_ext/openc3_io.rb +57 -0
  108. data/lib/openc3/core_ext/range.rb +27 -0
  109. data/lib/openc3/core_ext/socket.rb +38 -0
  110. data/lib/openc3/core_ext/string.rb +389 -0
  111. data/lib/openc3/core_ext/stringio.rb +33 -0
  112. data/lib/openc3/core_ext/time.rb +508 -0
  113. data/lib/openc3/core_ext.rb +36 -0
  114. data/lib/openc3/interfaces/interface.rb +498 -0
  115. data/lib/openc3/interfaces/linc_interface.rb +475 -0
  116. data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
  117. data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
  118. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
  119. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
  120. data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
  121. data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
  122. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
  123. data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
  124. data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
  125. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
  126. data/lib/openc3/interfaces/serial_interface.rb +94 -0
  127. data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
  128. data/lib/openc3/interfaces/stream_interface.rb +81 -0
  129. data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
  130. data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
  131. data/lib/openc3/interfaces/udp_interface.rb +169 -0
  132. data/lib/openc3/interfaces.rb +44 -0
  133. data/lib/openc3/io/buffered_file.rb +109 -0
  134. data/lib/openc3/io/io_multiplexer.rb +80 -0
  135. data/lib/openc3/io/json_api_object.rb +208 -0
  136. data/lib/openc3/io/json_drb.rb +335 -0
  137. data/lib/openc3/io/json_drb_object.rb +114 -0
  138. data/lib/openc3/io/json_drb_rack.rb +84 -0
  139. data/lib/openc3/io/json_rpc.rb +420 -0
  140. data/lib/openc3/io/openc3_snmp.rb +58 -0
  141. data/lib/openc3/io/posix_serial_driver.rb +156 -0
  142. data/lib/openc3/io/raw_logger.rb +167 -0
  143. data/lib/openc3/io/raw_logger_pair.rb +77 -0
  144. data/lib/openc3/io/serial_driver.rb +105 -0
  145. data/lib/openc3/io/stderr.rb +43 -0
  146. data/lib/openc3/io/stdout.rb +43 -0
  147. data/lib/openc3/io/udp_sockets.rb +194 -0
  148. data/lib/openc3/io/win32_serial_driver.rb +196 -0
  149. data/lib/openc3/logs/log_writer.rb +302 -0
  150. data/lib/openc3/logs/packet_log_constants.rb +62 -0
  151. data/lib/openc3/logs/packet_log_reader.rb +345 -0
  152. data/lib/openc3/logs/packet_log_writer.rb +299 -0
  153. data/lib/openc3/logs/text_log_writer.rb +68 -0
  154. data/lib/openc3/logs.rb +25 -0
  155. data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
  156. data/lib/openc3/microservices/decom_microservice.rb +136 -0
  157. data/lib/openc3/microservices/interface_microservice.rb +532 -0
  158. data/lib/openc3/microservices/log_microservice.rb +108 -0
  159. data/lib/openc3/microservices/microservice.rb +204 -0
  160. data/lib/openc3/microservices/plugin_microservice.rb +43 -0
  161. data/lib/openc3/microservices/reaction_microservice.rb +541 -0
  162. data/lib/openc3/microservices/reducer_microservice.rb +313 -0
  163. data/lib/openc3/microservices/router_microservice.rb +44 -0
  164. data/lib/openc3/microservices/text_log_microservice.rb +84 -0
  165. data/lib/openc3/microservices/timeline_microservice.rb +363 -0
  166. data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
  167. data/lib/openc3/models/activity_model.rb +319 -0
  168. data/lib/openc3/models/auth_model.rb +65 -0
  169. data/lib/openc3/models/cvt_model.rb +185 -0
  170. data/lib/openc3/models/environment_model.rb +58 -0
  171. data/lib/openc3/models/gem_model.rb +137 -0
  172. data/lib/openc3/models/info_model.rb +31 -0
  173. data/lib/openc3/models/interface_model.rb +281 -0
  174. data/lib/openc3/models/interface_status_model.rb +117 -0
  175. data/lib/openc3/models/metadata_model.rb +139 -0
  176. data/lib/openc3/models/metric_model.rb +59 -0
  177. data/lib/openc3/models/microservice_model.rb +206 -0
  178. data/lib/openc3/models/microservice_status_model.rb +74 -0
  179. data/lib/openc3/models/model.rb +204 -0
  180. data/lib/openc3/models/note_model.rb +122 -0
  181. data/lib/openc3/models/notification_model.rb +40 -0
  182. data/lib/openc3/models/ping_model.rb +35 -0
  183. data/lib/openc3/models/plugin_model.rb +292 -0
  184. data/lib/openc3/models/process_status_model.rb +76 -0
  185. data/lib/openc3/models/reaction_model.rb +322 -0
  186. data/lib/openc3/models/reducer_model.rb +65 -0
  187. data/lib/openc3/models/router_model.rb +35 -0
  188. data/lib/openc3/models/router_status_model.rb +27 -0
  189. data/lib/openc3/models/scope_model.rb +153 -0
  190. data/lib/openc3/models/settings_model.rb +55 -0
  191. data/lib/openc3/models/sorted_model.rb +167 -0
  192. data/lib/openc3/models/target_model.rb +759 -0
  193. data/lib/openc3/models/timeline_model.rb +154 -0
  194. data/lib/openc3/models/tool_config_model.rb +38 -0
  195. data/lib/openc3/models/tool_model.rb +262 -0
  196. data/lib/openc3/models/trigger_group_model.rb +186 -0
  197. data/lib/openc3/models/trigger_model.rb +330 -0
  198. data/lib/openc3/models/widget_model.rb +138 -0
  199. data/lib/openc3/operators/microservice_operator.rb +128 -0
  200. data/lib/openc3/operators/operator.rb +277 -0
  201. data/lib/openc3/packets/binary_accessor.rb +1207 -0
  202. data/lib/openc3/packets/commands.rb +373 -0
  203. data/lib/openc3/packets/json_packet.rb +134 -0
  204. data/lib/openc3/packets/limits.rb +271 -0
  205. data/lib/openc3/packets/limits_response.rb +53 -0
  206. data/lib/openc3/packets/packet.rb +1168 -0
  207. data/lib/openc3/packets/packet_config.rb +625 -0
  208. data/lib/openc3/packets/packet_item.rb +586 -0
  209. data/lib/openc3/packets/packet_item_limits.rb +162 -0
  210. data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
  211. data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
  212. data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
  213. data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
  214. data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
  215. data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
  216. data/lib/openc3/packets/parsers/state_parser.rb +127 -0
  217. data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
  218. data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
  219. data/lib/openc3/packets/structure.rb +553 -0
  220. data/lib/openc3/packets/structure_item.rb +365 -0
  221. data/lib/openc3/packets/telemetry.rb +487 -0
  222. data/lib/openc3/processors/processor.rb +86 -0
  223. data/lib/openc3/processors/statistics_processor.rb +82 -0
  224. data/lib/openc3/processors/watermark_processor.rb +58 -0
  225. data/lib/openc3/processors.rb +24 -0
  226. data/lib/openc3/script/api_shared.rb +828 -0
  227. data/lib/openc3/script/calendar.rb +89 -0
  228. data/lib/openc3/script/commands.rb +227 -0
  229. data/lib/openc3/script/exceptions.rb +29 -0
  230. data/lib/openc3/script/extract.rb +161 -0
  231. data/lib/openc3/script/limits.rb +60 -0
  232. data/lib/openc3/script/script.rb +299 -0
  233. data/lib/openc3/script/script_runner.rb +238 -0
  234. data/lib/openc3/script/storage.rb +146 -0
  235. data/lib/openc3/script/suite.rb +542 -0
  236. data/lib/openc3/script/suite_results.rb +196 -0
  237. data/lib/openc3/script/suite_runner.rb +217 -0
  238. data/lib/openc3/script.rb +21 -0
  239. data/lib/openc3/streams/serial_stream.rb +167 -0
  240. data/lib/openc3/streams/stream.rb +63 -0
  241. data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
  242. data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
  243. data/lib/openc3/system/system.rb +127 -0
  244. data/lib/openc3/system/system_config.rb +411 -0
  245. data/lib/openc3/system/target.rb +269 -0
  246. data/lib/openc3/system.rb +24 -0
  247. data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
  248. data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
  249. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
  250. data/lib/openc3/tools/table_manager/table.rb +77 -0
  251. data/lib/openc3/tools/table_manager/table_config.rb +273 -0
  252. data/lib/openc3/tools/table_manager/table_item.rb +90 -0
  253. data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
  254. data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
  255. data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
  256. data/lib/openc3/tools/test_runner/test.rb +67 -0
  257. data/lib/openc3/top_level.rb +595 -0
  258. data/lib/openc3/topics/autonomic_topic.rb +52 -0
  259. data/lib/openc3/topics/calendar_topic.rb +44 -0
  260. data/lib/openc3/topics/command_decom_topic.rb +76 -0
  261. data/lib/openc3/topics/command_topic.rb +83 -0
  262. data/lib/openc3/topics/config_topic.rb +68 -0
  263. data/lib/openc3/topics/interface_topic.rb +73 -0
  264. data/lib/openc3/topics/limits_event_topic.rb +109 -0
  265. data/lib/openc3/topics/notifications_topic.rb +28 -0
  266. data/lib/openc3/topics/router_topic.rb +85 -0
  267. data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
  268. data/lib/openc3/topics/telemetry_topic.rb +36 -0
  269. data/lib/openc3/topics/timeline_topic.rb +45 -0
  270. data/lib/openc3/topics/topic.rb +53 -0
  271. data/lib/openc3/utilities/authentication.rb +141 -0
  272. data/lib/openc3/utilities/authorization.rb +51 -0
  273. data/lib/openc3/utilities/crc.rb +278 -0
  274. data/lib/openc3/utilities/csv.rb +153 -0
  275. data/lib/openc3/utilities/logger.rb +187 -0
  276. data/lib/openc3/utilities/message_log.rb +91 -0
  277. data/lib/openc3/utilities/metric.rb +141 -0
  278. data/lib/openc3/utilities/process_manager.rb +139 -0
  279. data/lib/openc3/utilities/quaternion.rb +257 -0
  280. data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
  281. data/lib/openc3/utilities/s3.rb +202 -0
  282. data/lib/openc3/utilities/s3_autoload.rb +9 -0
  283. data/lib/openc3/utilities/s3_file_cache.rb +274 -0
  284. data/lib/openc3/utilities/simulated_target.rb +117 -0
  285. data/lib/openc3/utilities/sleeper.rb +51 -0
  286. data/lib/openc3/utilities/store.rb +23 -0
  287. data/lib/openc3/utilities/store_autoload.rb +237 -0
  288. data/lib/openc3/utilities/zip.rb +21 -0
  289. data/lib/openc3/utilities.rb +35 -0
  290. data/lib/openc3/version.rb +14 -0
  291. data/lib/openc3/win32/excel.rb +132 -0
  292. data/lib/openc3/win32/win32.rb +402 -0
  293. data/lib/openc3/win32/win32_main.rb +333 -0
  294. data/lib/openc3.rb +49 -0
  295. data/tasks/gemfile_stats.rake +113 -0
  296. data/tasks/spec.rake +30 -0
  297. data/templates/plugin-template/README.md +15 -0
  298. data/templates/plugin-template/Rakefile +12 -0
  299. data/templates/plugin-template/plugin.gemspec +23 -0
  300. data/templates/plugin-template/plugin.txt +9 -0
  301. data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
  302. data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
  303. data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
  304. data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
  305. data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
  306. data/templates/plugin-template/targets/TARGET/target.txt +5 -0
  307. metadata +849 -0
@@ -0,0 +1,61 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ # OpenC3 specific additions to the Ruby Exception class
21
+ class Exception
22
+ # @param hide_runtime_error_class [Boolean] Whether to hide the Exception
23
+ # error class if the class is RuntimeError. Other classes will continue to
24
+ # be printed.
25
+ # @param include_backtrace [Boolean] Whether to include the full exception
26
+ # backtrace
27
+ # @return [String] The formatted Exception
28
+ def formatted(hide_runtime_error_class = false, include_backtrace = true)
29
+ if include_backtrace and self.backtrace
30
+ if hide_runtime_error_class and self.class == RuntimeError
31
+ "#{self.message}\n#{self.backtrace.join("\n")}"
32
+ else
33
+ "#{self.class.to_s.split('::')[-1]} : #{self.message}\n#{self.backtrace.join("\n")}"
34
+ end
35
+ else
36
+ if hide_runtime_error_class and self.class == RuntimeError
37
+ "#{self.message}"
38
+ else
39
+ "#{self.class.to_s.split('::')[-1]} : #{self.message}"
40
+ end
41
+ end
42
+ end
43
+
44
+ # @return [Array(String, Fixnum)] The filename and line number where the Exception
45
+ # occurred
46
+ def source
47
+ trace = self.backtrace[0]
48
+ split_trace = trace.split(':')
49
+ filename = ''
50
+ line_number = ''
51
+ if trace[1..1] == ':' # Windows Path
52
+ filename = split_trace[0] + ':' + split_trace[1]
53
+ line_number = split_trace[2].to_i
54
+ else
55
+ filename = split_trace[0]
56
+ line_number = split_trace[1].to_i
57
+ end
58
+
59
+ [filename, line_number]
60
+ end
61
+ end
@@ -0,0 +1,83 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ require 'find'
21
+
22
+ # OpenC3 specific additions to the Ruby File class
23
+ class File
24
+ # Non printable ASCII characters
25
+ NON_ASCII_PRINTABLE = /[^\x21-\x7e\s]/
26
+
27
+ # @return [Boolean] Whether the file only contains ASCII characters
28
+ def self.is_ascii?(filename)
29
+ return_value = true
30
+ File.open(filename) do |file|
31
+ while buf = file.read(1024)
32
+ if NON_ASCII_PRINTABLE.match?(buf)
33
+ return_value = false
34
+ break
35
+ end
36
+ end
37
+ end
38
+ return return_value
39
+ end
40
+
41
+ # Builds a String for use in creating a file. The time is formatted as
42
+ # YYYY_MM_DD_HH_MM_SS. The tags and joined with an underscore and appended to
43
+ # the date before appending the extension.
44
+ #
45
+ # For example:
46
+ # File.build_timestamped_filename(['test','only'], '.bin', Time.now.sys)
47
+ # # result is YYYY_MM_DD_HH_MM_SS_test_only.bin
48
+ #
49
+ # @param tags [Array<String>] An array of strings to be joined by underscores
50
+ # after the date. Pass nil or an empty array to use no tags.
51
+ # @param extension [String] The filename extension
52
+ # @param time [Time] The time to format into the filename
53
+ # @return [String] The filename string containing the timestamp, tags, and
54
+ # extension
55
+ def self.build_timestamped_filename(tags = nil, extension = '.txt', time = Time.now.sys)
56
+ timestamp = sprintf("%04u_%02u_%02u_%02u_%02u_%02u", time.year, time.month, time.mday, time.hour, time.min, time.sec)
57
+ tags ||= []
58
+ tags.compact!
59
+ combined_tags = tags.join("_")
60
+ if combined_tags.length > 0
61
+ filename = timestamp + "_" + combined_tags + extension
62
+ else
63
+ filename = timestamp + extension
64
+ end
65
+ return filename
66
+ end
67
+
68
+ # @param filename [String] The file to search for
69
+ # @return [String] The full path to the filename if it was found in the Ruby
70
+ # search path. nil if the fild was not found.
71
+ def self.find_in_search_path(filename)
72
+ $:.each do |load_path|
73
+ Find.find(load_path) do |path|
74
+ Find.prune if /\.svn/.match?(path)
75
+ return path if File.basename(path) == filename
76
+ end
77
+ rescue Errno::ENOENT
78
+ # Ignore non-existent folders
79
+ next
80
+ end
81
+ return nil
82
+ end
83
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ # OpenC3 specific additions to the Ruby Hash class
21
+ class Hash
22
+ # Redefine inspect to only print for small numbers of
23
+ # items. Prevents exceptions taking forever to be raised with
24
+ # large objects. See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/105145
25
+ alias old_inspect inspect
26
+
27
+ # @param max_elements [Integer] The maximum number of elements in the Hash to
28
+ # print out before simply displaying the Hash class and object id
29
+ # @return [String] String representation of the hash
30
+ def inspect(max_elements = 10)
31
+ if self.length <= max_elements
32
+ old_inspect()
33
+ else
34
+ '#<' + self.class.to_s + ':' + self.object_id.to_s + '>'
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,134 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ require 'openc3/core_ext/kernel'
21
+ require 'openc3/core_ext/openc3_io'
22
+
23
+ class IO
24
+ include OpenC3IO
25
+
26
+ # Initial timeout to call IO.select with. Timeouts are increased by doubling
27
+ # this value until the SELET_MAX_TIMEOUT value is reached.
28
+ SELECT_BASE_TIMEOUT = 0.0004
29
+ # The maximum timeout at which point we call IO.select with whatever
30
+ # remaining timeout is left.
31
+ SELECT_MAX_TIMEOUT = 0.016
32
+
33
+ class << self
34
+ # Alias the original IO.select method
35
+ alias_method :__select__, :select
36
+
37
+ # On Windows the IO.select function (when called with no timeout) takes
38
+ # a minimum of 10 msec to return, even if one of the IO objects is
39
+ # ready to read/write sooner than that.
40
+ #
41
+ # This method is identical to IO.select but instead of calling IO.select with
42
+ # the full timeout, it calls IO.select with a small timeout and then
43
+ # doubles the timeout twice until eventually it calls IO.select with the
44
+ # remaining passed in timeout value.
45
+ #
46
+ # @param read_sockets [Array<IO>] IO objects to wait to be ready to read
47
+ # @param write_sockets [Array<IO>] IO objects to wait to be ready to write
48
+ # @param error_array [Array<IO>] IO objects to wait for exceptions
49
+ # @param timeout [Numeric] Number of seconds to wait
50
+ def fast_select(read_sockets = nil, write_sockets = nil, error_array = nil, timeout = nil)
51
+ # Always try a zero timeout first
52
+ current_timeout = SELECT_BASE_TIMEOUT
53
+ total_timeout = 0.0
54
+
55
+ while true
56
+ begin
57
+ result = IO.__select__(read_sockets, write_sockets, error_array, current_timeout)
58
+ # All OS errors are subclassed to SystemCallError as Errno::<Subclass>
59
+ # See https://ruby-doc.org/core-3.1.0/Errno.html
60
+ rescue SystemCallError
61
+ return nil
62
+ end
63
+ return result if result or current_timeout.nil?
64
+ return nil if timeout and total_timeout >= timeout
65
+
66
+ if current_timeout <= 0.0001
67
+ # Always try the base timeout next
68
+ current_timeout = SELECT_BASE_TIMEOUT
69
+ total_timeout = SELECT_BASE_TIMEOUT
70
+ else
71
+ # Then start doubling the timeout
72
+ current_timeout = current_timeout * 2
73
+
74
+ # Until it is bigger than our max timeout
75
+ if current_timeout >= SELECT_MAX_TIMEOUT
76
+ if timeout
77
+ # Block for the remaining requested timeout
78
+ current_timeout = timeout - total_timeout
79
+ total_timeout = timeout
80
+ else
81
+ # Or block forever
82
+ current_timeout = nil
83
+ end
84
+ else
85
+ # Or it is bigger than the given timeout
86
+ if timeout and current_timeout >= timeout
87
+ # Block for the remaining requested timeout
88
+ current_timeout = timeout - total_timeout
89
+ total_timeout = timeout
90
+ else
91
+ # Up our total time in select
92
+ total_timeout += current_timeout
93
+ end
94
+ if timeout and total_timeout > timeout
95
+ # Block for the remaining requested timeout
96
+ current_timeout = timeout - total_timeout
97
+ total_timeout = timeout
98
+ end
99
+ end
100
+ return nil if current_timeout and current_timeout < 0
101
+ end
102
+ end # while true
103
+ end # fast_select
104
+
105
+ # For non-windows systems, leave IO.select alone, but for windows
106
+ # monkey-patch IO.select to use our fast-select implementation.
107
+ if Kernel.is_windows?
108
+ def select(read_sockets = nil, write_sockets = nil, error_array = nil, timeout = nil)
109
+ return fast_select(read_sockets, write_sockets, error_array, timeout)
110
+ end
111
+ end
112
+
113
+ # @param read_sockets [Array<IO>] IO objects to wait to be ready to read
114
+ # @param timeout [Numeric] Number of seconds to wait
115
+ def fast_read_select(read_sockets, timeout)
116
+ return fast_select(read_sockets, nil, nil, timeout)
117
+ end
118
+
119
+ # @param write_sockets [Array<IO>] IO objects to wait to be ready to write
120
+ # @param timeout [Numeric] Number of seconds to wait
121
+ def fast_write_select(write_sockets, timeout)
122
+ return fast_select(nil, write_sockets, nil, timeout)
123
+ end
124
+ end
125
+
126
+ # Alias the original close method
127
+ alias_method :__close__, :close
128
+
129
+ # Patch the close method so that it won't raise any exceptions
130
+ def close
131
+ __close__
132
+ rescue
133
+ end
134
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ # OpenC3 specific additions to the Ruby Kernel module
21
+ module Kernel
22
+ # @return [Boolean] Whether the current platform is Windows
23
+ def is_windows?
24
+ Gem.win_platform?
25
+ end
26
+
27
+ # @return [Boolean] Whether the current platform is Mac
28
+ def is_mac?
29
+ _, platform, *_ = RUBY_PLATFORM.split("-")
30
+ result = false
31
+ if /darwin/.match?(platform)
32
+ result = true
33
+ end
34
+ return result
35
+ end
36
+
37
+ # @param start [Integer] The number of stack entries to skip
38
+ # @return [Symbol] The name of the calling method
39
+ def calling_method(start = 1)
40
+ caller[start][/`([^']*)'/, 1].intern
41
+ end
42
+ end
@@ -0,0 +1,128 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ # OpenC3 specific additions to the Ruby Math module. The algorithms implemented
21
+ # here are based on standard deviation algorithms based on Wikipedia Algorithms
22
+ # for calculating variance, Section 3.
23
+ module Math
24
+ # Add all the module instance methods as module functions so we can call them
25
+ # either as Math.sin_squared or directly if we "include Math"
26
+ extend self
27
+
28
+ # Power reduction formula. Calculates sin squared which is
29
+ # (1 - cos(2 * angle)) / 2
30
+ #
31
+ # @param angle [Float] Angle in degrees
32
+ # @return [Float] sin(angle) squared
33
+ def sin_squared(angle)
34
+ return (1.0 - Math.cos(2.0 * angle)) / 2.0
35
+ end
36
+
37
+ # Power reduction formula. Calculates cos squared which is
38
+ # (1 + cos(2 * angle)) / 2
39
+ #
40
+ # @param angle [Float] Angle in degrees
41
+ # @return [Float] cos(angle) squared
42
+ def cos_squared(angle)
43
+ return (1.0 + Math.cos(2.0 * angle)) / 2.0
44
+ end
45
+
46
+ # Calculates the population variance of a group of numbers. If the population
47
+ # is finite the population variance is the variance of the underlying
48
+ # probability distribution.
49
+ #
50
+ # @param array [Array<Numeric>] Array of values
51
+ # @return [Float, Float] The first value is the mean and the second is the
52
+ # variance
53
+ def variance_population(array)
54
+ mean, m2, num_values = variance_generic(array)
55
+ if num_values != 0.0
56
+ return [mean, m2 / num_values]
57
+ else
58
+ return [mean, 0.0]
59
+ end
60
+ end
61
+
62
+ # Calculates the sample variance of a group of numbers. If the population of
63
+ # numbers is very large, it is not possible to count every value in the
64
+ # population, so the computation must be performed on a sample of the
65
+ # population.
66
+ #
67
+ # @param array [Array<Numeric>] Array of values
68
+ # @return [Float, Float] The first value is the mean and the second is the
69
+ # variance
70
+ def variance_sample(array)
71
+ mean, m2, num_values = variance_generic(array)
72
+ if num_values != 1.0
73
+ return [mean, m2 / (num_values - 1.0)]
74
+ else
75
+ return [mean, 0.0]
76
+ end
77
+ end
78
+
79
+ # Calculates the standard deviation of the population variation by taking the
80
+ # square root of the population variance.
81
+ #
82
+ # @param array [Array<Numeric>] Array of values
83
+ # @return [Float, Float] The first value is the mean and the second is the
84
+ # standard deviation
85
+ def stddev_population(array)
86
+ mean, variance = self.variance_population(array)
87
+ return [mean, Math.sqrt(variance)]
88
+ end
89
+
90
+ # Calculates the standard deviation of the sample variation by taking the
91
+ # square root of the sample variance.
92
+ #
93
+ # @param array [Array<Numeric>] Array of values
94
+ # @return [Float, Float] The first value is the mean and the second is the
95
+ # standard deviation
96
+ def stddev_sample(array)
97
+ mean, variance = self.variance_sample(array)
98
+ return [mean, Math.sqrt(variance)]
99
+ end
100
+
101
+ # Calculates luma, the brightness, given RGB values.
102
+ #
103
+ # @param red [Numeric] Red RGB value (0 - 255)
104
+ # @param green [Numeric] Green RGB value (0 - 255)
105
+ # @param blue [Numeric] Blue RGB value (0 - 255)
106
+ # @return [Float] The calculated luma
107
+ def luma_from_rgb_max_255(red, green, blue)
108
+ (0.2126 * (red.to_f / 255.0)) + (0.7152 * (green.to_f / 255.0)) + (0.0722 * (blue.to_f / 255.0))
109
+ end
110
+
111
+ protected
112
+
113
+ def variance_generic(array)
114
+ num_values = 0.0
115
+ mean = 0.0
116
+ m2 = 0.0
117
+
118
+ array.each do |value|
119
+ value = value.to_f # so we work for arrays of floats or ints
120
+ num_values += 1.0
121
+ delta = value - mean
122
+ mean = mean + (delta / num_values)
123
+ m2 = m2 + delta * (value - mean)
124
+ end
125
+
126
+ return [mean, m2, num_values]
127
+ end
128
+ end
@@ -0,0 +1,156 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ require 'matrix'
21
+ include Math
22
+
23
+ # OpenC3 specific additions to the Ruby Matrix class
24
+ class Matrix
25
+ old_verbose = $VERBOSE; $VERBOSE = nil
26
+ # Allow [i] to return an entire row instead of being forced to pass both the
27
+ # row and column (i.e [i,j]) to return an individual element.
28
+ #
29
+ # @param i [Integer] Row index
30
+ # @param j [Integer] Optional column index. Pass nil to return the entire row
31
+ # given by i.
32
+ # @return Either the row as an Array or the element
33
+ def [](i, j = nil)
34
+ if j
35
+ @rows[i][j]
36
+ else
37
+ @rows[i]
38
+ end
39
+ end
40
+ $VERBOSE = old_verbose
41
+
42
+ # Allow [i,j] = x to set the element at row i, column j to value x
43
+ #
44
+ # @param i [Integer] Row index
45
+ # @param j [Integer] Column index
46
+ # @param value [Object] The value to set
47
+ def []=(i, j, value)
48
+ @rows[i][j] = value
49
+ end
50
+
51
+ # Creates a rotation matrix around one axis as defined by:
52
+ # http://mathworld.wolfram.com/RotationMatrix.html
53
+ #
54
+ # @param axis [Symbol] Must be :X,:x,1, or :Y,:y,2, or :Z,:z,3
55
+ # @param rotation_angle_in_radians [Float] The rotation angle in radians to
56
+ # rotate the maxtrix about the given axis
57
+ #
58
+ def self.rot(axis, rotation_angle_in_radians)
59
+ rotation_matrix = Matrix.identity(3).to_a
60
+
61
+ case axis
62
+ when :X, :x, 1
63
+ rotation_matrix[1][1] = cos(rotation_angle_in_radians)
64
+ rotation_matrix[1][2] = sin(rotation_angle_in_radians)
65
+ rotation_matrix[2][2] = rotation_matrix[1][1]
66
+ rotation_matrix[2][1] = -(rotation_matrix[1][2])
67
+ when :Y, :y, 2
68
+ rotation_matrix[0][0] = cos(rotation_angle_in_radians)
69
+ rotation_matrix[2][0] = sin(rotation_angle_in_radians)
70
+ rotation_matrix[2][2] = rotation_matrix[0][0]
71
+ rotation_matrix[0][2] = -(rotation_matrix[2][0])
72
+ when :Z, :z, 3
73
+ rotation_matrix[0][0] = cos(rotation_angle_in_radians)
74
+ rotation_matrix[0][1] = sin(rotation_angle_in_radians)
75
+ rotation_matrix[1][1] = rotation_matrix[0][0]
76
+ rotation_matrix[1][0] = -(rotation_matrix[0][1])
77
+ end
78
+
79
+ return Matrix[*rotation_matrix]
80
+ end
81
+
82
+ # Sums the diagonal values of the matrix
83
+ def trace
84
+ sum = 0.0
85
+ @rows.length.times do |index|
86
+ value = @rows[index][index]
87
+ if not value.nil?
88
+ sum += value
89
+ else
90
+ break
91
+ end
92
+ end
93
+ return sum
94
+ end
95
+
96
+ def self.cfromq(quaternion)
97
+ result = Matrix.zero(3)
98
+
99
+ tx = 2.0 * quaternion.x
100
+ ty = 2.0 * quaternion.y
101
+ tz = 2.0 * quaternion.z
102
+ twx = tx * quaternion.w
103
+ twy = ty * quaternion.w
104
+ twz = tz * quaternion.w
105
+ txx = tx * quaternion.x
106
+ txy = ty * quaternion.x
107
+ txz = tz * quaternion.x
108
+ tyy = ty * quaternion.y
109
+ tyz = tz * quaternion.y
110
+ tzz = tz * quaternion.z
111
+
112
+ result[0][0] = 1.0 - tyy - tzz
113
+ result[0][1] = txy + twz
114
+ result[0][2] = txz - twy
115
+ result[1][0] = txy - twz
116
+ result[1][1] = 1.0 - txx - tzz
117
+ result[1][2] = tyz + twx
118
+ result[2][0] = txz + twy
119
+ result[2][1] = tyz - twx
120
+ result[2][2] = 1.0 - txx - tyy
121
+
122
+ return result
123
+ end
124
+
125
+ def trans4(x, y, z)
126
+ @rows[3][0] += x * @rows[0][0] + y * @rows[1][0] + z * @rows[2][0]
127
+ @rows[3][1] += x * @rows[0][1] + y * @rows[1][1] + z * @rows[2][1]
128
+ @rows[3][2] += x * @rows[0][2] + y * @rows[1][2] + z * @rows[2][2]
129
+ @rows[3][3] += x * @rows[0][3] + y * @rows[1][3] + z * @rows[2][3]
130
+ return self
131
+ end
132
+
133
+ def scale4(x, y, z)
134
+ @rows[0][0] *= x; @rows[0][1] *= x; @rows[0][2] *= x; @rows[0][3] *= x
135
+ @rows[1][0] *= y; @rows[1][1] *= y; @rows[1][2] *= y; @rows[1][3] *= y
136
+ @rows[2][0] *= z; @rows[2][1] *= z; @rows[2][2] *= z; @rows[2][3] *= z
137
+ return self
138
+ end
139
+
140
+ def rot4(quaternion)
141
+ # Get rotation matrix
142
+ r = Matrix.cfromq(quaternion)
143
+
144
+ 4.times do |row|
145
+ x = @rows[0][row]
146
+ y = @rows[1][row]
147
+ z = @rows[2][row]
148
+ 3.times do |i|
149
+ @rows[i][row] = x * r[i][0] + y * r[i][1] + z * r[i][2]
150
+ end
151
+ end
152
+ # Ensure the final row is floating point for consistency
153
+ @rows[3].map! { |x| x.to_f }
154
+ return self
155
+ end
156
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ # OpenC3 specific additions to the ObjectSpace class
21
+ module ObjectSpace
22
+ def self.find(klass)
23
+ ObjectSpace.each_object(klass) do |object|
24
+ return object
25
+ end
26
+ nil
27
+ end
28
+
29
+ def self.find_all(klass)
30
+ objects = []
31
+ ObjectSpace.each_object(klass) do |object|
32
+ objects << object
33
+ end
34
+ objects
35
+ end
36
+ end # class ObjectSpace