cosmos 3.0.1 → 3.1.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 (912) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +48 -48
  4. data/.travis.yml +7 -7
  5. data/CONTRIBUTING.txt +50 -50
  6. data/Gemfile +6 -6
  7. data/Guardfile +27 -27
  8. data/LICENSE.txt +879 -879
  9. data/Manifest.txt +1116 -1114
  10. data/README.md +109 -107
  11. data/Rakefile +214 -214
  12. data/autohotkey/config/data/diamond.STL +57 -57
  13. data/autohotkey/config/system/system.txt +34 -34
  14. data/autohotkey/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  15. data/autohotkey/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  16. data/autohotkey/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  17. data/autohotkey/config/targets/COSMOS/target.txt +5 -5
  18. data/autohotkey/config/targets/INST/cmd_tlm/inst_cmds.txt +121 -121
  19. data/autohotkey/config/targets/INST/cmd_tlm/inst_tlm.txt +247 -247
  20. data/autohotkey/config/targets/INST/cmd_tlm_server.txt +5 -5
  21. data/autohotkey/config/targets/INST/lib/example_limits_response.rb +30 -30
  22. data/autohotkey/config/targets/INST/lib/sim_inst.rb +305 -294
  23. data/autohotkey/config/targets/INST/screens/adcs.txt +46 -46
  24. data/autohotkey/config/targets/INST/screens/array.txt +7 -7
  25. data/autohotkey/config/targets/INST/screens/block.txt +8 -8
  26. data/autohotkey/config/targets/INST/screens/commanding.txt +30 -30
  27. data/autohotkey/config/targets/INST/screens/graphs.txt +14 -14
  28. data/autohotkey/config/targets/INST/screens/ground.txt +25 -25
  29. data/autohotkey/config/targets/INST/screens/health_status.txt +33 -33
  30. data/autohotkey/config/targets/INST/screens/hs.txt +49 -49
  31. data/autohotkey/config/targets/INST/screens/image.txt +21 -21
  32. data/autohotkey/config/targets/INST/screens/latest.txt +23 -23
  33. data/autohotkey/config/targets/INST/screens/mech.txt +25 -25
  34. data/autohotkey/config/targets/INST/screens/other.txt +25 -25
  35. data/autohotkey/config/targets/INST/screens/params.txt +25 -25
  36. data/autohotkey/config/targets/INST/screens/tabs.txt +68 -68
  37. data/autohotkey/config/targets/INST/target.txt +26 -26
  38. data/autohotkey/config/targets/META/cmd_tlm/meta_cmd.txt +10 -10
  39. data/autohotkey/config/targets/META/cmd_tlm/meta_tlm.txt +9 -9
  40. data/autohotkey/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -7
  41. data/autohotkey/config/targets/SYSTEM/screens/error.txt +11 -11
  42. data/autohotkey/config/tools/cmd_tlm_server/cmd_tlm_server.txt +22 -22
  43. data/autohotkey/config/tools/data_viewer/data_viewer.txt +11 -11
  44. data/autohotkey/config/tools/handbook_creator/handbook_creator.txt +49 -49
  45. data/autohotkey/config/tools/handbook_creator/templates/command_packets.html.erb +86 -86
  46. data/autohotkey/config/tools/handbook_creator/templates/command_toc.html.erb +38 -38
  47. data/autohotkey/config/tools/handbook_creator/templates/footer.html.erb +9 -9
  48. data/autohotkey/config/tools/handbook_creator/templates/header.html.erb +25 -25
  49. data/autohotkey/config/tools/handbook_creator/templates/limits_groups.html.erb +13 -13
  50. data/autohotkey/config/tools/handbook_creator/templates/nav.html.erb +27 -27
  51. data/autohotkey/config/tools/handbook_creator/templates/overview.html.erb +1 -1
  52. data/autohotkey/config/tools/handbook_creator/templates/pdf_cover.html.erb +23 -23
  53. data/autohotkey/config/tools/handbook_creator/templates/pdf_footer.html.erb +33 -33
  54. data/autohotkey/config/tools/handbook_creator/templates/pdf_header.html.erb +41 -41
  55. data/autohotkey/config/tools/handbook_creator/templates/telemetry_packets.html.erb +80 -80
  56. data/autohotkey/config/tools/handbook_creator/templates/telemetry_toc.html.erb +38 -38
  57. data/autohotkey/config/tools/handbook_creator/templates/title.html.erb +1 -1
  58. data/autohotkey/config/tools/launcher/launcher.txt +38 -38
  59. data/autohotkey/config/tools/script_runner/script_runner.txt +3 -3
  60. data/autohotkey/config/tools/table_manager/ConfigTables_def.txt +8 -8
  61. data/autohotkey/config/tools/table_manager/OneDimensionalTable_def.txt +19 -19
  62. data/autohotkey/config/tools/table_manager/TwoDimensionalTable_def.txt +248 -248
  63. data/autohotkey/config/tools/test_runner/test_runner.txt +8 -8
  64. data/autohotkey/config/tools/test_runner/test_runner2.txt +11 -11
  65. data/autohotkey/config/tools/test_runner/test_runner3.txt +6 -6
  66. data/autohotkey/config/tools/test_runner/test_runner4.txt +1 -1
  67. data/autohotkey/config/tools/tlm_extractor/tlm_extractor.txt +13 -13
  68. data/autohotkey/config/tools/tlm_extractor/tlm_extractor2.txt +9 -9
  69. data/autohotkey/config/tools/tlm_grapher/bad.txt +50 -50
  70. data/autohotkey/config/tools/tlm_grapher/temp1-4.txt +51 -51
  71. data/autohotkey/config/tools/tlm_grapher/test2.txt +111 -111
  72. data/autohotkey/config/tools/tlm_viewer/tlm_viewer.txt +24 -24
  73. data/autohotkey/config/tools/tlm_viewer/tlm_viewer2.txt +4 -4
  74. data/autohotkey/config/tools/tlm_viewer/tlm_viewer3.txt +3 -3
  75. data/autohotkey/lib/example_background_task.rb +42 -42
  76. data/autohotkey/lib/user_version.rb +3 -3
  77. data/autohotkey/procedures/clear_util.rb +7 -7
  78. data/autohotkey/procedures/collect.rb +18 -18
  79. data/autohotkey/procedures/collect_util.rb +14 -14
  80. data/autohotkey/procedures/example_test.rb +67 -67
  81. data/autohotkey/procedures/example_test2.rb +74 -74
  82. data/autohotkey/procedures/script_test.rb +17 -17
  83. data/autohotkey/procedures/syntax_error.rb +18 -18
  84. data/autohotkey/tools/CmdExtractorAHK +16 -16
  85. data/autohotkey/tools/CmdSender +14 -14
  86. data/autohotkey/tools/CmdSenderAHK +18 -18
  87. data/autohotkey/tools/CmdTlmServer +14 -14
  88. data/autohotkey/tools/CmdTlmServerAHK +28 -28
  89. data/autohotkey/tools/CmdTlmServerAHK2 +17 -17
  90. data/autohotkey/tools/DataViewer +14 -14
  91. data/autohotkey/tools/DataViewerAHK +17 -17
  92. data/autohotkey/tools/HandbookCreatorAHK +20 -20
  93. data/autohotkey/tools/LauncherAHK +17 -17
  94. data/autohotkey/tools/LimitsMonitorAHK +20 -20
  95. data/autohotkey/tools/OpenGLBuilderAHK +20 -20
  96. data/autohotkey/tools/PacketViewer +14 -14
  97. data/autohotkey/tools/PacketViewerAHK +18 -18
  98. data/autohotkey/tools/PacketViewerAHK2 +17 -17
  99. data/autohotkey/tools/Replay +14 -14
  100. data/autohotkey/tools/Replay.bat +59 -59
  101. data/autohotkey/tools/ReplayAHK +17 -17
  102. data/autohotkey/tools/ScriptRunner +14 -14
  103. data/autohotkey/tools/ScriptRunnerAHK +20 -20
  104. data/autohotkey/tools/ScriptRunnerAHK2 +17 -17
  105. data/autohotkey/tools/TableManager +14 -14
  106. data/autohotkey/tools/TableManagerAHK +30 -30
  107. data/autohotkey/tools/TestRunner +15 -15
  108. data/autohotkey/tools/TestRunnerAHK +17 -17
  109. data/autohotkey/tools/TestRunnerAHK2 +17 -17
  110. data/autohotkey/tools/TestRunnerAHK3 +17 -17
  111. data/autohotkey/tools/TestRunnerAHK4 +17 -17
  112. data/autohotkey/tools/TlmExtractor +15 -15
  113. data/autohotkey/tools/TlmExtractorAHK +19 -19
  114. data/autohotkey/tools/TlmExtractorAHK2 +16 -16
  115. data/autohotkey/tools/TlmExtractorAHK3 +16 -16
  116. data/autohotkey/tools/TlmGrapher +14 -14
  117. data/autohotkey/tools/TlmGrapherAHK +19 -19
  118. data/autohotkey/tools/TlmGrapherAHK2 +23 -23
  119. data/autohotkey/tools/TlmGrapherAHK3 +17 -17
  120. data/autohotkey/tools/TlmGrapherAHK4 +17 -17
  121. data/autohotkey/tools/TlmViewer +14 -14
  122. data/autohotkey/tools/TlmViewerAHK +28 -28
  123. data/autohotkey/tools/TlmViewerAHK2 +18 -18
  124. data/autohotkey/tools/TlmViewerAHK3 +18 -18
  125. data/autohotkey/tools/TlmViewerAHK4 +18 -18
  126. data/autohotkey/tools/TlmViewerAHK5 +18 -18
  127. data/autohotkey/tools/autohotkey.rb +37 -37
  128. data/autohotkey/tools/cmd_extractor.ahk +27 -27
  129. data/autohotkey/tools/cmd_sender.ahk +182 -162
  130. data/autohotkey/tools/cmd_tlm_server.ahk +89 -89
  131. data/autohotkey/tools/cmd_tlm_server2.ahk +45 -45
  132. data/autohotkey/tools/data_viewer.ahk +135 -135
  133. data/autohotkey/tools/handbook_creator.ahk +23 -23
  134. data/autohotkey/tools/launcher.ahk +41 -41
  135. data/autohotkey/tools/limits_monitor.ahk +70 -70
  136. data/autohotkey/tools/open_gl_builder.ahk +134 -134
  137. data/autohotkey/tools/packet_viewer.ahk +143 -143
  138. data/autohotkey/tools/packet_viewer2.ahk +9 -9
  139. data/autohotkey/tools/replay.ahk +98 -98
  140. data/autohotkey/tools/script_runner.ahk +589 -589
  141. data/autohotkey/tools/script_runner2.ahk +34 -31
  142. data/autohotkey/tools/table_manager.ahk +220 -220
  143. data/autohotkey/tools/test_runner.ahk +262 -259
  144. data/autohotkey/tools/test_runner2.ahk +52 -52
  145. data/autohotkey/tools/test_runner3.ahk +13 -13
  146. data/autohotkey/tools/tlm_extractor.ahk +272 -272
  147. data/autohotkey/tools/tlm_grapher.ahk +642 -642
  148. data/autohotkey/tools/tlm_grapher2.ahk +115 -115
  149. data/autohotkey/tools/tlm_grapher3.ahk +24 -24
  150. data/autohotkey/tools/tlm_viewer.ahk +133 -133
  151. data/autohotkey/tools/tlm_viewer2.ahk +50 -49
  152. data/autohotkey/tools/tlm_viewer4.ahk +4 -4
  153. data/autohotkey/tools/tlm_viewer5.ahk +20 -20
  154. data/bin/cosmos +96 -96
  155. data/bin/cstol_converter +1166 -1166
  156. data/bin/rubysloc +85 -85
  157. data/cosmos.gemspec +98 -97
  158. data/data/about.txt +4 -4
  159. data/data/crc.txt +306 -305
  160. data/data/diamond.STL +57 -57
  161. data/data/legal.txt +9 -9
  162. data/demo/Gemfile +6 -6
  163. data/demo/Launcher +15 -15
  164. data/demo/Launcher.bat +59 -59
  165. data/demo/Rakefile +61 -61
  166. data/demo/config/data/crc.txt +222 -206
  167. data/demo/config/data/diamond.STL +57 -57
  168. data/demo/config/data/meta_init.txt +4 -4
  169. data/demo/config/system/system.txt +34 -34
  170. data/demo/config/system/system2.txt +33 -33
  171. data/demo/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  172. data/demo/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  173. data/demo/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  174. data/demo/config/targets/COSMOS/screens/limits_change.txt +20 -20
  175. data/demo/config/targets/COSMOS/screens/version.txt +19 -19
  176. data/demo/config/targets/COSMOS/target.txt +11 -11
  177. data/demo/config/targets/EXAMPLE/cmd_tlm/example_cmds.txt +2 -2
  178. data/demo/config/targets/EXAMPLE/cmd_tlm/example_tlm.txt +3 -3
  179. data/demo/config/targets/EXAMPLE/cmd_tlm_server.txt +6 -6
  180. data/demo/config/targets/EXAMPLE/lib/example_interface.rb +22 -22
  181. data/demo/config/targets/EXAMPLE/target.txt +6 -6
  182. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +121 -121
  183. data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +247 -247
  184. data/demo/config/targets/INST/cmd_tlm_server.txt +5 -5
  185. data/demo/config/targets/INST/lib/example_limits_response.rb +30 -30
  186. data/demo/config/targets/INST/lib/sim_inst.rb +305 -294
  187. data/demo/config/targets/INST/screens/adcs.txt +46 -46
  188. data/demo/config/targets/INST/screens/array.txt +15 -15
  189. data/demo/config/targets/INST/screens/block.txt +8 -8
  190. data/demo/config/targets/INST/screens/commanding.txt +30 -30
  191. data/demo/config/targets/INST/screens/graphs.txt +14 -14
  192. data/demo/config/targets/INST/screens/ground.txt +25 -25
  193. data/demo/config/targets/INST/screens/hs.txt +44 -44
  194. data/demo/config/targets/INST/screens/latest.txt +23 -23
  195. data/demo/config/targets/INST/screens/other.txt +29 -29
  196. data/demo/config/targets/INST/screens/tabs.txt +70 -70
  197. data/demo/config/targets/INST/target.txt +33 -33
  198. data/demo/config/targets/META/cmd_tlm/meta_cmd.txt +10 -10
  199. data/demo/config/targets/META/cmd_tlm/meta_tlm.txt +13 -13
  200. data/demo/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -7
  201. data/demo/config/targets/SYSTEM/cmd_tlm/override.txt +29 -29
  202. data/demo/config/targets/SYSTEM/screens/status.txt +12 -12
  203. data/demo/config/targets/TEMPLATED/cmd_tlm/templated_cmds.txt +13 -12
  204. data/demo/config/targets/TEMPLATED/cmd_tlm/templated_tlm.txt +3 -3
  205. data/demo/config/targets/TEMPLATED/cmd_tlm_server.txt +6 -6
  206. data/demo/config/targets/TEMPLATED/lib/templated_interface.rb +54 -48
  207. data/demo/config/targets/TEMPLATED/target.txt +6 -6
  208. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +33 -33
  209. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +29 -29
  210. data/demo/config/tools/data_viewer/data_viewer.txt +11 -11
  211. data/demo/config/tools/handbook_creator/handbook_creator.txt +66 -66
  212. data/demo/config/tools/handbook_creator/templates/command_packets.html.erb +86 -86
  213. data/demo/config/tools/handbook_creator/templates/command_toc.html.erb +38 -38
  214. data/demo/config/tools/handbook_creator/templates/footer.html.erb +9 -9
  215. data/demo/config/tools/handbook_creator/templates/header.html.erb +25 -25
  216. data/demo/config/tools/handbook_creator/templates/limits_groups.html.erb +13 -13
  217. data/demo/config/tools/handbook_creator/templates/nav.html.erb +27 -27
  218. data/demo/config/tools/handbook_creator/templates/overview.html.erb +1 -1
  219. data/demo/config/tools/handbook_creator/templates/pdf_cover.html.erb +23 -23
  220. data/demo/config/tools/handbook_creator/templates/pdf_footer.html.erb +33 -33
  221. data/demo/config/tools/handbook_creator/templates/pdf_header.html.erb +41 -41
  222. data/demo/config/tools/handbook_creator/templates/telemetry_packets.html.erb +80 -80
  223. data/demo/config/tools/handbook_creator/templates/telemetry_toc.html.erb +38 -38
  224. data/demo/config/tools/handbook_creator/templates/title.html.erb +1 -1
  225. data/demo/config/tools/launcher/launcher.txt +45 -45
  226. data/demo/config/tools/launcher/launcher2.txt +45 -45
  227. data/demo/config/tools/script_runner/script_runner.txt +3 -3
  228. data/demo/config/tools/table_manager/ConfigTables_def.txt +8 -8
  229. data/demo/config/tools/table_manager/ExampleTableDefinition.txt +24 -24
  230. data/demo/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +25 -25
  231. data/demo/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +25 -25
  232. data/demo/config/tools/table_manager/PPSSelectionTable_def.txt +8 -8
  233. data/demo/config/tools/table_manager/TLMMonitoringTable_def.txt +248 -248
  234. data/demo/config/tools/test_runner/test_runner.txt +17 -17
  235. data/demo/config/tools/tlm_extractor/tlm_extractor.txt +13 -13
  236. data/demo/config/tools/tlm_extractor/tlm_extractor2.txt +2 -2
  237. data/demo/config/tools/tlm_extractor/tlm_extractor3.txt +2 -2
  238. data/demo/config/tools/tlm_extractor/tlm_extractor4.txt +2 -2
  239. data/demo/config/tools/tlm_viewer/tlm_viewer.txt +41 -41
  240. data/demo/lib/example_background_task.rb +57 -52
  241. data/demo/lib/example_target.rb +113 -108
  242. data/demo/lib/scpi_target.rb +74 -74
  243. data/demo/lib/user_version.rb +3 -3
  244. data/demo/procedures/checks.rb +11 -11
  245. data/demo/procedures/clear_util.rb +7 -7
  246. data/demo/procedures/collect.rb +18 -18
  247. data/demo/procedures/collect_util.rb +14 -14
  248. data/demo/procedures/cosmos_api_test.rb +293 -293
  249. data/demo/procedures/disconnect.rb +29 -29
  250. data/demo/procedures/example_test.rb +182 -182
  251. data/demo/procedures/plot_test.rb +8 -8
  252. data/demo/procedures/run_example_test.rb +3 -3
  253. data/demo/procedures/test.rb +51 -51
  254. data/demo/tools/CmdExtractor +15 -15
  255. data/demo/tools/CmdExtractor.bat +59 -59
  256. data/demo/tools/CmdSender +15 -15
  257. data/demo/tools/CmdSender.bat +59 -59
  258. data/demo/tools/CmdTlmServer +15 -15
  259. data/demo/tools/CmdTlmServer.bat +59 -59
  260. data/demo/tools/DataViewer +15 -15
  261. data/demo/tools/DataViewer.bat +59 -59
  262. data/demo/tools/ExampleTarget +15 -15
  263. data/demo/tools/ExampleTarget.bat +59 -59
  264. data/demo/tools/HandbookCreator +15 -15
  265. data/demo/tools/HandbookCreator.bat +61 -61
  266. data/demo/tools/Launcher +15 -15
  267. data/demo/tools/Launcher.bat +59 -59
  268. data/demo/tools/LimitsMonitor +15 -15
  269. data/demo/tools/LimitsMonitor.bat +59 -59
  270. data/demo/tools/OpenGLBuilder +15 -15
  271. data/demo/tools/OpenGLBuilder.bat +59 -59
  272. data/demo/tools/PacketViewer +15 -15
  273. data/demo/tools/PacketViewer.bat +59 -59
  274. data/demo/tools/Replay +15 -15
  275. data/demo/tools/Replay.bat +59 -59
  276. data/demo/tools/ScpiTarget +15 -15
  277. data/demo/tools/ScpiTarget.bat +59 -59
  278. data/demo/tools/ScriptRunner +15 -15
  279. data/demo/tools/ScriptRunner.bat +59 -59
  280. data/demo/tools/TableManager +15 -15
  281. data/demo/tools/TableManager.bat +59 -59
  282. data/demo/tools/TestRunner +15 -15
  283. data/demo/tools/TestRunner.bat +59 -59
  284. data/demo/tools/TlmExtractor +15 -15
  285. data/demo/tools/TlmExtractor.bat +59 -59
  286. data/demo/tools/TlmGrapher +15 -15
  287. data/demo/tools/TlmGrapher.bat +59 -59
  288. data/demo/tools/TlmViewer +15 -15
  289. data/demo/tools/TlmViewer.bat +59 -59
  290. data/demo/tools/mac/CmdExtractor.app/Contents/Info.plist +38 -38
  291. data/demo/tools/mac/CmdExtractor.app/Contents/MacOS/CmdExtractor.rb +15 -15
  292. data/demo/tools/mac/CmdExtractor.app/Contents/MacOS/main.sh +6 -6
  293. data/demo/tools/mac/CmdSender.app/Contents/Info.plist +38 -38
  294. data/demo/tools/mac/CmdSender.app/Contents/MacOS/CmdSender.rb +15 -15
  295. data/demo/tools/mac/CmdSender.app/Contents/MacOS/main.sh +6 -6
  296. data/demo/tools/mac/CmdTlmServer.app/Contents/Info.plist +38 -38
  297. data/demo/tools/mac/CmdTlmServer.app/Contents/MacOS/CmdTlmServer.rb +15 -15
  298. data/demo/tools/mac/CmdTlmServer.app/Contents/MacOS/main.sh +6 -6
  299. data/demo/tools/mac/DataViewer.app/Contents/Info.plist +38 -38
  300. data/demo/tools/mac/DataViewer.app/Contents/MacOS/DataViewer.rb +15 -15
  301. data/demo/tools/mac/DataViewer.app/Contents/MacOS/main.sh +6 -6
  302. data/demo/tools/mac/HandbookCreator.app/Contents/Info.plist +38 -38
  303. data/demo/tools/mac/HandbookCreator.app/Contents/MacOS/HandbookCreator.rb +15 -15
  304. data/demo/tools/mac/HandbookCreator.app/Contents/MacOS/main.sh +6 -6
  305. data/demo/tools/mac/Launcher.app/Contents/Info.plist +38 -38
  306. data/demo/tools/mac/Launcher.app/Contents/MacOS/Launcher.rb +15 -15
  307. data/demo/tools/mac/Launcher.app/Contents/MacOS/main.sh +6 -6
  308. data/demo/tools/mac/LimitsMonitor.app/Contents/Info.plist +38 -38
  309. data/demo/tools/mac/LimitsMonitor.app/Contents/MacOS/LimitsMonitor.rb +15 -15
  310. data/demo/tools/mac/LimitsMonitor.app/Contents/MacOS/main.sh +6 -6
  311. data/demo/tools/mac/OpenGLBuilder.app/Contents/Info.plist +38 -38
  312. data/demo/tools/mac/OpenGLBuilder.app/Contents/MacOS/OpenGLBuilder.rb +15 -15
  313. data/demo/tools/mac/OpenGLBuilder.app/Contents/MacOS/main.sh +6 -6
  314. data/demo/tools/mac/PacketViewer.app/Contents/Info.plist +38 -38
  315. data/demo/tools/mac/PacketViewer.app/Contents/MacOS/PacketViewer.rb +15 -15
  316. data/demo/tools/mac/PacketViewer.app/Contents/MacOS/main.sh +6 -6
  317. data/demo/tools/mac/Replay.app/Contents/Info.plist +38 -38
  318. data/demo/tools/mac/Replay.app/Contents/MacOS/Replay.rb +15 -15
  319. data/demo/tools/mac/Replay.app/Contents/MacOS/main.sh +6 -6
  320. data/demo/tools/mac/ScriptRunner.app/Contents/Info.plist +38 -38
  321. data/demo/tools/mac/ScriptRunner.app/Contents/MacOS/ScriptRunner.rb +15 -15
  322. data/demo/tools/mac/ScriptRunner.app/Contents/MacOS/main.sh +6 -6
  323. data/demo/tools/mac/TableManager.app/Contents/Info.plist +38 -38
  324. data/demo/tools/mac/TableManager.app/Contents/MacOS/TableManager.rb +15 -15
  325. data/demo/tools/mac/TableManager.app/Contents/MacOS/main.sh +6 -6
  326. data/demo/tools/mac/TestRunner.app/Contents/Info.plist +38 -38
  327. data/demo/tools/mac/TestRunner.app/Contents/MacOS/TestRunner.rb +15 -15
  328. data/demo/tools/mac/TestRunner.app/Contents/MacOS/main.sh +6 -6
  329. data/demo/tools/mac/TlmExtractor.app/Contents/Info.plist +38 -38
  330. data/demo/tools/mac/TlmExtractor.app/Contents/MacOS/TlmExtractor.rb +15 -15
  331. data/demo/tools/mac/TlmExtractor.app/Contents/MacOS/main.sh +6 -6
  332. data/demo/tools/mac/TlmGrapher.app/Contents/Info.plist +38 -38
  333. data/demo/tools/mac/TlmGrapher.app/Contents/MacOS/TlmGrapher.rb +15 -15
  334. data/demo/tools/mac/TlmGrapher.app/Contents/MacOS/main.sh +6 -6
  335. data/demo/tools/mac/TlmViewer.app/Contents/Info.plist +38 -38
  336. data/demo/tools/mac/TlmViewer.app/Contents/MacOS/TlmViewer.rb +15 -15
  337. data/demo/tools/mac/TlmViewer.app/Contents/MacOS/main.sh +6 -6
  338. data/ext/cosmos/ext/array/array.c +111 -111
  339. data/ext/cosmos/ext/array/extconf.rb +13 -13
  340. data/ext/cosmos/ext/buffered_file/buffered_file.c +167 -167
  341. data/ext/cosmos/ext/buffered_file/extconf.rb +13 -13
  342. data/ext/cosmos/ext/config_parser/config_parser.c +237 -237
  343. data/ext/cosmos/ext/config_parser/extconf.rb +13 -13
  344. data/ext/cosmos/ext/cosmos_io/cosmos_io.c +117 -117
  345. data/ext/cosmos/ext/cosmos_io/extconf.rb +13 -13
  346. data/ext/cosmos/ext/crc/crc.c +341 -341
  347. data/ext/cosmos/ext/crc/extconf.rb +12 -12
  348. data/ext/cosmos/ext/line_graph/extconf.rb +13 -13
  349. data/ext/cosmos/ext/line_graph/line_graph.c +501 -501
  350. data/ext/cosmos/ext/low_fragmentation_array/extconf.rb +12 -12
  351. data/ext/cosmos/ext/low_fragmentation_array/low_fragmentation_array.c +261 -261
  352. data/ext/cosmos/ext/packet/extconf.rb +13 -13
  353. data/ext/cosmos/ext/packet/packet.c +339 -339
  354. data/ext/cosmos/ext/platform/extconf.rb +13 -13
  355. data/ext/cosmos/ext/platform/platform.c +81 -81
  356. data/ext/cosmos/ext/polynomial_conversion/extconf.rb +13 -13
  357. data/ext/cosmos/ext/polynomial_conversion/polynomial_conversion.c +73 -73
  358. data/ext/cosmos/ext/string/extconf.rb +13 -13
  359. data/ext/cosmos/ext/string/string.c +49 -49
  360. data/ext/cosmos/ext/structure/structure.c +894 -894
  361. data/ext/cosmos/ext/tabbed_plots_config/extconf.rb +13 -13
  362. data/ext/cosmos/ext/tabbed_plots_config/tabbed_plots_config.c +51 -51
  363. data/ext/cosmos/ext/telemetry/extconf.rb +13 -13
  364. data/ext/cosmos/ext/telemetry/telemetry.c +306 -306
  365. data/ext/mkrf_conf.rb +40 -40
  366. data/install/Gemfile +6 -6
  367. data/install/Launcher +14 -14
  368. data/install/Launcher.bat +59 -59
  369. data/install/Rakefile +61 -61
  370. data/install/config/data/crc.txt +134 -133
  371. data/install/config/system/system.txt +29 -29
  372. data/install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  373. data/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  374. data/install/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  375. data/install/config/targets/COSMOS/screens/limits_change.txt +20 -20
  376. data/install/config/targets/COSMOS/screens/version.txt +19 -19
  377. data/install/config/targets/COSMOS/target.txt +8 -8
  378. data/install/config/tools/cmd_tlm_server/cmd_tlm_server.txt +2 -2
  379. data/install/config/tools/data_viewer/data_viewer.txt +3 -3
  380. data/install/config/tools/handbook_creator/handbook_creator.txt +49 -49
  381. data/install/config/tools/handbook_creator/templates/command_packets.html.erb +86 -86
  382. data/install/config/tools/handbook_creator/templates/command_toc.html.erb +38 -38
  383. data/install/config/tools/handbook_creator/templates/footer.html.erb +9 -9
  384. data/install/config/tools/handbook_creator/templates/header.html.erb +25 -25
  385. data/install/config/tools/handbook_creator/templates/limits_groups.html.erb +13 -13
  386. data/install/config/tools/handbook_creator/templates/nav.html.erb +27 -27
  387. data/install/config/tools/handbook_creator/templates/overview.html.erb +1 -1
  388. data/install/config/tools/handbook_creator/templates/pdf_cover.html.erb +23 -23
  389. data/install/config/tools/handbook_creator/templates/pdf_footer.html.erb +33 -33
  390. data/install/config/tools/handbook_creator/templates/pdf_header.html.erb +41 -41
  391. data/install/config/tools/handbook_creator/templates/telemetry_packets.html.erb +80 -80
  392. data/install/config/tools/handbook_creator/templates/telemetry_toc.html.erb +38 -38
  393. data/install/config/tools/handbook_creator/templates/title.html.erb +1 -1
  394. data/install/config/tools/launcher/launcher.txt +39 -39
  395. data/install/config/tools/script_runner/script_runner.txt +3 -3
  396. data/install/config/tools/test_runner/test_runner.txt +8 -8
  397. data/install/config/tools/tlm_viewer/tlm_viewer.txt +5 -5
  398. data/install/lib/user_version.rb +3 -3
  399. data/install/tools/CmdExtractor +15 -15
  400. data/install/tools/CmdExtractor.bat +59 -59
  401. data/install/tools/CmdSender +15 -15
  402. data/install/tools/CmdSender.bat +59 -59
  403. data/install/tools/CmdTlmServer +15 -15
  404. data/install/tools/CmdTlmServer.bat +59 -59
  405. data/install/tools/DataViewer +15 -15
  406. data/install/tools/DataViewer.bat +59 -59
  407. data/install/tools/HandbookCreator +15 -15
  408. data/install/tools/HandbookCreator.bat +61 -61
  409. data/install/tools/Launcher +15 -15
  410. data/install/tools/Launcher.bat +59 -59
  411. data/install/tools/LimitsMonitor +15 -15
  412. data/install/tools/LimitsMonitor.bat +59 -59
  413. data/install/tools/OpenGLBuilder +15 -15
  414. data/install/tools/OpenGLBuilder.bat +59 -59
  415. data/install/tools/PacketViewer +15 -15
  416. data/install/tools/PacketViewer.bat +59 -59
  417. data/install/tools/Replay +15 -15
  418. data/install/tools/Replay.bat +59 -59
  419. data/install/tools/ScriptRunner +15 -15
  420. data/install/tools/ScriptRunner.bat +59 -59
  421. data/install/tools/TableManager +15 -15
  422. data/install/tools/TableManager.bat +59 -59
  423. data/install/tools/TestRunner +15 -15
  424. data/install/tools/TestRunner.bat +59 -59
  425. data/install/tools/TlmExtractor +15 -15
  426. data/install/tools/TlmExtractor.bat +59 -59
  427. data/install/tools/TlmGrapher +15 -15
  428. data/install/tools/TlmGrapher.bat +59 -59
  429. data/install/tools/TlmViewer +15 -15
  430. data/install/tools/TlmViewer.bat +59 -59
  431. data/install/tools/mac/CmdExtractor.app/Contents/Info.plist +38 -38
  432. data/install/tools/mac/CmdExtractor.app/Contents/MacOS/CmdExtractor.rb +15 -15
  433. data/install/tools/mac/CmdExtractor.app/Contents/MacOS/main.sh +6 -6
  434. data/install/tools/mac/CmdSender.app/Contents/Info.plist +38 -38
  435. data/install/tools/mac/CmdSender.app/Contents/MacOS/CmdSender.rb +15 -15
  436. data/install/tools/mac/CmdSender.app/Contents/MacOS/main.sh +6 -6
  437. data/install/tools/mac/CmdTlmServer.app/Contents/Info.plist +38 -38
  438. data/install/tools/mac/CmdTlmServer.app/Contents/MacOS/CmdTlmServer.rb +15 -15
  439. data/install/tools/mac/CmdTlmServer.app/Contents/MacOS/main.sh +6 -6
  440. data/install/tools/mac/DataViewer.app/Contents/Info.plist +38 -38
  441. data/install/tools/mac/DataViewer.app/Contents/MacOS/DataViewer.rb +15 -15
  442. data/install/tools/mac/DataViewer.app/Contents/MacOS/main.sh +6 -6
  443. data/install/tools/mac/HandbookCreator.app/Contents/Info.plist +38 -38
  444. data/install/tools/mac/HandbookCreator.app/Contents/MacOS/HandbookCreator.rb +15 -15
  445. data/install/tools/mac/HandbookCreator.app/Contents/MacOS/main.sh +6 -6
  446. data/install/tools/mac/Launcher.app/Contents/Info.plist +38 -38
  447. data/install/tools/mac/Launcher.app/Contents/MacOS/Launcher.rb +15 -15
  448. data/install/tools/mac/Launcher.app/Contents/MacOS/main.sh +6 -6
  449. data/install/tools/mac/LimitsMonitor.app/Contents/Info.plist +38 -38
  450. data/install/tools/mac/LimitsMonitor.app/Contents/MacOS/LimitsMonitor.rb +15 -15
  451. data/install/tools/mac/LimitsMonitor.app/Contents/MacOS/main.sh +6 -6
  452. data/install/tools/mac/OpenGLBuilder.app/Contents/Info.plist +38 -38
  453. data/install/tools/mac/OpenGLBuilder.app/Contents/MacOS/OpenGLBuilder.rb +15 -15
  454. data/install/tools/mac/OpenGLBuilder.app/Contents/MacOS/main.sh +6 -6
  455. data/install/tools/mac/PacketViewer.app/Contents/Info.plist +38 -38
  456. data/install/tools/mac/PacketViewer.app/Contents/MacOS/PacketViewer.rb +15 -15
  457. data/install/tools/mac/PacketViewer.app/Contents/MacOS/main.sh +6 -6
  458. data/install/tools/mac/Replay.app/Contents/Info.plist +38 -38
  459. data/install/tools/mac/Replay.app/Contents/MacOS/Replay.rb +15 -15
  460. data/install/tools/mac/Replay.app/Contents/MacOS/main.sh +6 -6
  461. data/install/tools/mac/ScriptRunner.app/Contents/Info.plist +38 -38
  462. data/install/tools/mac/ScriptRunner.app/Contents/MacOS/ScriptRunner.rb +15 -15
  463. data/install/tools/mac/ScriptRunner.app/Contents/MacOS/main.sh +6 -6
  464. data/install/tools/mac/TableManager.app/Contents/Info.plist +38 -38
  465. data/install/tools/mac/TableManager.app/Contents/MacOS/TableManager.rb +15 -15
  466. data/install/tools/mac/TableManager.app/Contents/MacOS/main.sh +6 -6
  467. data/install/tools/mac/TestRunner.app/Contents/Info.plist +38 -38
  468. data/install/tools/mac/TestRunner.app/Contents/MacOS/TestRunner.rb +15 -15
  469. data/install/tools/mac/TestRunner.app/Contents/MacOS/main.sh +6 -6
  470. data/install/tools/mac/TlmExtractor.app/Contents/Info.plist +38 -38
  471. data/install/tools/mac/TlmExtractor.app/Contents/MacOS/TlmExtractor.rb +15 -15
  472. data/install/tools/mac/TlmExtractor.app/Contents/MacOS/main.sh +6 -6
  473. data/install/tools/mac/TlmGrapher.app/Contents/Info.plist +38 -38
  474. data/install/tools/mac/TlmGrapher.app/Contents/MacOS/TlmGrapher.rb +15 -15
  475. data/install/tools/mac/TlmGrapher.app/Contents/MacOS/main.sh +6 -6
  476. data/install/tools/mac/TlmViewer.app/Contents/Info.plist +38 -38
  477. data/install/tools/mac/TlmViewer.app/Contents/MacOS/TlmViewer.rb +15 -15
  478. data/install/tools/mac/TlmViewer.app/Contents/MacOS/main.sh +6 -6
  479. data/lib/cosmos.rb +63 -63
  480. data/lib/cosmos/ccsds/ccsds_packet.rb +63 -63
  481. data/lib/cosmos/ccsds/ccsds_parser.rb +143 -143
  482. data/lib/cosmos/config/config_parser.rb +324 -324
  483. data/lib/cosmos/conversions.rb +13 -13
  484. data/lib/cosmos/conversions/conversion.rb +47 -47
  485. data/lib/cosmos/conversions/generic_conversion.rb +55 -55
  486. data/lib/cosmos/conversions/new_packet_log_conversion.rb +45 -45
  487. data/lib/cosmos/conversions/polynomial_conversion.rb +57 -57
  488. data/lib/cosmos/conversions/processor_conversion.rb +46 -46
  489. data/lib/cosmos/conversions/received_count_conversion.rb +33 -33
  490. data/lib/cosmos/conversions/received_time_formatted_conversion.rb +37 -37
  491. data/lib/cosmos/conversions/received_time_seconds_conversion.rb +37 -37
  492. data/lib/cosmos/conversions/segmented_polynomial_conversion.rb +128 -128
  493. data/lib/cosmos/conversions/unix_time_conversion.rb +50 -50
  494. data/lib/cosmos/conversions/unix_time_formatted_conversion.rb +44 -44
  495. data/lib/cosmos/conversions/unix_time_seconds_conversion.rb +44 -44
  496. data/lib/cosmos/core_ext.rb +18 -18
  497. data/lib/cosmos/core_ext/array.rb +354 -354
  498. data/lib/cosmos/core_ext/class.rb +51 -51
  499. data/lib/cosmos/core_ext/cosmos_io.rb +29 -29
  500. data/lib/cosmos/core_ext/exception.rb +52 -52
  501. data/lib/cosmos/core_ext/file.rb +75 -75
  502. data/lib/cosmos/core_ext/hash.rb +28 -28
  503. data/lib/cosmos/core_ext/io.rb +75 -75
  504. data/lib/cosmos/core_ext/kernel.rb +38 -38
  505. data/lib/cosmos/core_ext/math.rb +119 -119
  506. data/lib/cosmos/core_ext/matrix.rb +146 -146
  507. data/lib/cosmos/core_ext/objectspace.rb +29 -29
  508. data/lib/cosmos/core_ext/range.rb +22 -22
  509. data/lib/cosmos/core_ext/socket.rb +32 -32
  510. data/lib/cosmos/core_ext/string.rb +310 -310
  511. data/lib/cosmos/core_ext/stringio.rb +24 -24
  512. data/lib/cosmos/core_ext/time.rb +446 -446
  513. data/lib/cosmos/gui/choosers/combobox_chooser.rb +130 -130
  514. data/lib/cosmos/gui/choosers/file_chooser.rb +68 -68
  515. data/lib/cosmos/gui/choosers/float_chooser.rb +82 -82
  516. data/lib/cosmos/gui/choosers/integer_chooser.rb +80 -80
  517. data/lib/cosmos/gui/choosers/string_chooser.rb +53 -53
  518. data/lib/cosmos/gui/choosers/telemetry_chooser.rb +317 -317
  519. data/lib/cosmos/gui/dialogs/about_dialog.rb +128 -128
  520. data/lib/cosmos/gui/dialogs/calendar_dialog.rb +136 -136
  521. data/lib/cosmos/gui/dialogs/cmd_details_dialog.rb +52 -52
  522. data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +149 -149
  523. data/lib/cosmos/gui/dialogs/details_dialog.rb +174 -174
  524. data/lib/cosmos/gui/dialogs/exception_dialog.rb +97 -97
  525. data/lib/cosmos/gui/dialogs/exception_list_dialog.rb +59 -59
  526. data/lib/cosmos/gui/dialogs/find_replace_dialog.rb +196 -196
  527. data/lib/cosmos/gui/dialogs/legal_dialog.rb +169 -168
  528. data/lib/cosmos/gui/dialogs/packet_log_dialog.rb +118 -118
  529. data/lib/cosmos/gui/dialogs/progress_dialog.rb +270 -262
  530. data/lib/cosmos/gui/dialogs/pry_dialog.rb +165 -161
  531. data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +37 -37
  532. data/lib/cosmos/gui/dialogs/select_dialog.rb +54 -54
  533. data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +131 -131
  534. data/lib/cosmos/gui/dialogs/splash.rb +113 -113
  535. data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +206 -206
  536. data/lib/cosmos/gui/dialogs/tlm_edit_dialog.rb +81 -81
  537. data/lib/cosmos/gui/line_graph/line_graph.rb +456 -456
  538. data/lib/cosmos/gui/line_graph/line_graph_dialog.rb +34 -34
  539. data/lib/cosmos/gui/line_graph/line_graph_drawing.rb +494 -494
  540. data/lib/cosmos/gui/line_graph/line_graph_popups.rb +116 -116
  541. data/lib/cosmos/gui/line_graph/line_graph_scaling.rb +460 -460
  542. data/lib/cosmos/gui/line_graph/line_graph_script.rb +26 -26
  543. data/lib/cosmos/gui/line_graph/lines.rb +290 -290
  544. data/lib/cosmos/gui/line_graph/overview_graph.rb +459 -459
  545. data/lib/cosmos/gui/opengl/earth_model.rb +22 -22
  546. data/lib/cosmos/gui/opengl/gl_bounds.rb +67 -67
  547. data/lib/cosmos/gui/opengl/gl_light.rb +39 -39
  548. data/lib/cosmos/gui/opengl/gl_material.rb +29 -29
  549. data/lib/cosmos/gui/opengl/gl_scene.rb +72 -72
  550. data/lib/cosmos/gui/opengl/gl_shape.rb +146 -146
  551. data/lib/cosmos/gui/opengl/gl_viewer.rb +724 -712
  552. data/lib/cosmos/gui/opengl/gl_viewport.rb +35 -35
  553. data/lib/cosmos/gui/opengl/moon_model.rb +22 -22
  554. data/lib/cosmos/gui/opengl/opengl.rb +8 -8
  555. data/lib/cosmos/gui/opengl/stl_reader.rb +211 -211
  556. data/lib/cosmos/gui/opengl/stl_shape.rb +124 -124
  557. data/lib/cosmos/gui/opengl/texture_mapped_sphere.rb +202 -202
  558. data/lib/cosmos/gui/qt.rb +813 -786
  559. data/lib/cosmos/gui/qt_tool.rb +378 -373
  560. data/lib/cosmos/gui/text/completion.rb +381 -381
  561. data/lib/cosmos/gui/text/completion_line_edit.rb +30 -30
  562. data/lib/cosmos/gui/text/completion_text_edit.rb +179 -179
  563. data/lib/cosmos/gui/text/ruby_editor.rb +395 -395
  564. data/lib/cosmos/gui/utilities/screenshot.rb +25 -25
  565. data/lib/cosmos/gui/utilities/script_module_gui.rb +203 -203
  566. data/lib/cosmos/gui/widgets/full_text_search_line_edit.rb +161 -161
  567. data/lib/cosmos/gui/widgets/packet_log_frame.rb +305 -305
  568. data/lib/cosmos/gui/widgets/realtime_button_bar.rb +98 -98
  569. data/lib/cosmos/interfaces.rb +11 -11
  570. data/lib/cosmos/interfaces/cmd_tlm_server_interface.rb +153 -149
  571. data/lib/cosmos/interfaces/interface.rb +213 -213
  572. data/lib/cosmos/interfaces/linc_interface.rb +360 -360
  573. data/lib/cosmos/interfaces/serial_interface.rb +76 -76
  574. data/lib/cosmos/interfaces/simulated_target_interface.rb +129 -128
  575. data/lib/cosmos/interfaces/stream_interface.rb +156 -156
  576. data/lib/cosmos/interfaces/tcpip_client_interface.rb +60 -60
  577. data/lib/cosmos/interfaces/tcpip_server_interface.rb +154 -154
  578. data/lib/cosmos/interfaces/udp_interface.rb +173 -173
  579. data/lib/cosmos/io/buffered_file.rb +11 -11
  580. data/lib/cosmos/io/cosmos_snmp.rb +50 -50
  581. data/lib/cosmos/io/io_multiplexer.rb +89 -89
  582. data/lib/cosmos/io/json_drb.rb +344 -320
  583. data/lib/cosmos/io/json_drb_object.rb +137 -137
  584. data/lib/cosmos/io/json_rpc.rb +365 -365
  585. data/lib/cosmos/io/posix_serial_driver.rb +145 -145
  586. data/lib/cosmos/io/raw_logger.rb +174 -174
  587. data/lib/cosmos/io/raw_logger_pair.rb +71 -71
  588. data/lib/cosmos/io/serial_driver.rb +85 -85
  589. data/lib/cosmos/io/stderr.rb +36 -36
  590. data/lib/cosmos/io/stdout.rb +36 -36
  591. data/lib/cosmos/io/tcpip_server.rb +583 -532
  592. data/lib/cosmos/io/udp_sockets.rb +152 -152
  593. data/lib/cosmos/io/win32_serial_driver.rb +147 -147
  594. data/lib/cosmos/packet_logs.rb +6 -6
  595. data/lib/cosmos/packet_logs/meta_packet_log_writer.rb +107 -107
  596. data/lib/cosmos/packet_logs/packet_log_reader.rb +441 -439
  597. data/lib/cosmos/packet_logs/packet_log_writer.rb +321 -309
  598. data/lib/cosmos/packet_logs/packet_log_writer_pair.rb +30 -30
  599. data/lib/cosmos/packets/binary_accessor.rb +921 -921
  600. data/lib/cosmos/packets/commands.rb +291 -291
  601. data/lib/cosmos/packets/limits.rb +263 -263
  602. data/lib/cosmos/packets/limits_response.rb +38 -38
  603. data/lib/cosmos/packets/packet.rb +714 -699
  604. data/lib/cosmos/packets/packet_config.rb +1034 -1034
  605. data/lib/cosmos/packets/packet_item.rb +317 -317
  606. data/lib/cosmos/packets/packet_item_limits.rb +128 -128
  607. data/lib/cosmos/packets/structure.rb +421 -386
  608. data/lib/cosmos/packets/structure_item.rb +233 -233
  609. data/lib/cosmos/packets/telemetry.rb +317 -317
  610. data/lib/cosmos/processors.rb +6 -6
  611. data/lib/cosmos/processors/new_packet_log_processor.rb +34 -34
  612. data/lib/cosmos/processors/processor.rb +71 -71
  613. data/lib/cosmos/processors/statistics_processor.rb +65 -65
  614. data/lib/cosmos/processors/watermark_processor.rb +44 -44
  615. data/lib/cosmos/script.rb +9 -9
  616. data/lib/cosmos/script/extract.rb +115 -115
  617. data/lib/cosmos/script/script.rb +1513 -1493
  618. data/lib/cosmos/streams/burst_stream_protocol.rb +25 -25
  619. data/lib/cosmos/streams/fixed_stream_protocol.rb +111 -111
  620. data/lib/cosmos/streams/length_stream_protocol.rb +140 -140
  621. data/lib/cosmos/streams/preidentified_stream_protocol.rb +118 -118
  622. data/lib/cosmos/streams/serial_stream.rb +152 -143
  623. data/lib/cosmos/streams/stream.rb +57 -57
  624. data/lib/cosmos/streams/stream_protocol.rb +369 -369
  625. data/lib/cosmos/streams/tcpip_client_stream.rb +77 -77
  626. data/lib/cosmos/streams/tcpip_socket_stream.rb +139 -139
  627. data/lib/cosmos/streams/template_stream_protocol.rb +140 -140
  628. data/lib/cosmos/streams/terminated_stream_protocol.rb +81 -81
  629. data/lib/cosmos/system.rb +4 -4
  630. data/lib/cosmos/system/system.rb +558 -558
  631. data/lib/cosmos/system/target.rb +178 -178
  632. data/lib/cosmos/tools/cmd_extractor/cmd_extractor.rb +254 -253
  633. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +716 -716
  634. data/lib/cosmos/tools/cmd_sender/cmd_sender_item_delegate.rb +77 -77
  635. data/lib/cosmos/tools/cmd_sender/cmd_sender_text_edit.rb +70 -70
  636. data/lib/cosmos/tools/cmd_tlm_server/api.rb +936 -940
  637. data/lib/cosmos/tools/cmd_tlm_server/background_task.rb +46 -46
  638. data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +67 -63
  639. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +511 -497
  640. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +241 -241
  641. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +1033 -1008
  642. data/lib/cosmos/tools/cmd_tlm_server/commanding.rb +112 -112
  643. data/lib/cosmos/tools/cmd_tlm_server/connections.rb +176 -176
  644. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +241 -221
  645. data/lib/cosmos/tools/cmd_tlm_server/interfaces.rb +127 -127
  646. data/lib/cosmos/tools/cmd_tlm_server/packet_logging.rb +132 -132
  647. data/lib/cosmos/tools/cmd_tlm_server/router_thread.rb +66 -66
  648. data/lib/cosmos/tools/cmd_tlm_server/routers.rb +97 -97
  649. data/lib/cosmos/tools/data_viewer/data_viewer.rb +628 -600
  650. data/lib/cosmos/tools/data_viewer/data_viewer_component.rb +167 -167
  651. data/lib/cosmos/tools/data_viewer/dump_component.rb +40 -40
  652. data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +149 -149
  653. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +360 -360
  654. data/lib/cosmos/tools/launcher/launcher.rb +184 -184
  655. data/lib/cosmos/tools/launcher/launcher_config.rb +175 -167
  656. data/lib/cosmos/tools/launcher/launcher_multitool.rb +40 -41
  657. data/lib/cosmos/tools/launcher/launcher_tool.rb +104 -104
  658. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +796 -768
  659. data/lib/cosmos/tools/opengl_builder/opengl_builder.rb +416 -416
  660. data/lib/cosmos/tools/opengl_builder/scene_config.rb +118 -118
  661. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +525 -525
  662. data/lib/cosmos/tools/replay/replay.rb +495 -488
  663. data/lib/cosmos/tools/replay/replay_server.rb +91 -91
  664. data/lib/cosmos/tools/script_runner/script_audit.rb +147 -139
  665. data/lib/cosmos/tools/script_runner/script_runner.rb +914 -914
  666. data/lib/cosmos/tools/script_runner/script_runner_config.rb +40 -40
  667. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +1892 -1859
  668. data/lib/cosmos/tools/table_manager/table.rb +70 -70
  669. data/lib/cosmos/tools/table_manager/table_config.rb +764 -764
  670. data/lib/cosmos/tools/table_manager/table_item.rb +74 -74
  671. data/lib/cosmos/tools/table_manager/table_manager.rb +1065 -1065
  672. data/lib/cosmos/tools/table_manager/table_manager_core.rb +539 -539
  673. data/lib/cosmos/tools/test_runner/results_writer.rb +283 -283
  674. data/lib/cosmos/tools/test_runner/test.rb +480 -480
  675. data/lib/cosmos/tools/test_runner/test_runner.rb +1157 -1157
  676. data/lib/cosmos/tools/test_runner/test_runner_chooser.rb +338 -338
  677. data/lib/cosmos/tools/tlm_extractor/text_item_chooser.rb +60 -60
  678. data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +1008 -1008
  679. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +371 -371
  680. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +60 -60
  681. data/lib/cosmos/tools/tlm_grapher/data_object_adders/housekeeping_data_object_adder.rb +75 -75
  682. data/lib/cosmos/tools/tlm_grapher/data_object_adders/singlexy_data_object_adder.rb +44 -44
  683. data/lib/cosmos/tools/tlm_grapher/data_object_adders/xy_data_object_adder.rb +94 -94
  684. data/lib/cosmos/tools/tlm_grapher/data_object_editors/data_object_editor.rb +61 -61
  685. data/lib/cosmos/tools/tlm_grapher/data_object_editors/housekeeping_data_object_editor.rb +180 -180
  686. data/lib/cosmos/tools/tlm_grapher/data_object_editors/linegraph_data_object_editor.rb +141 -141
  687. data/lib/cosmos/tools/tlm_grapher/data_object_editors/singlexy_data_object_editor.rb +30 -30
  688. data/lib/cosmos/tools/tlm_grapher/data_object_editors/xy_data_object_editor.rb +173 -173
  689. data/lib/cosmos/tools/tlm_grapher/data_objects/data_object.rb +177 -177
  690. data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +412 -409
  691. data/lib/cosmos/tools/tlm_grapher/data_objects/linegraph_data_object.rb +176 -176
  692. data/lib/cosmos/tools/tlm_grapher/data_objects/singlexy_data_object.rb +25 -25
  693. data/lib/cosmos/tools/tlm_grapher/data_objects/xy_data_object.rb +323 -320
  694. data/lib/cosmos/tools/tlm_grapher/plot_editors/linegraph_plot_editor.rb +181 -181
  695. data/lib/cosmos/tools/tlm_grapher/plot_editors/plot_editor.rb +28 -28
  696. data/lib/cosmos/tools/tlm_grapher/plot_editors/singlexy_plot_editor.rb +30 -30
  697. data/lib/cosmos/tools/tlm_grapher/plot_editors/xy_plot_editor.rb +59 -59
  698. data/lib/cosmos/tools/tlm_grapher/plot_gui_objects/linegraph_plot_gui_object.rb +172 -172
  699. data/lib/cosmos/tools/tlm_grapher/plot_gui_objects/singlexy_plot_gui_object.rb +27 -27
  700. data/lib/cosmos/tools/tlm_grapher/plot_gui_objects/xy_plot_gui_object.rb +74 -74
  701. data/lib/cosmos/tools/tlm_grapher/plots/linegraph_plot.rb +201 -201
  702. data/lib/cosmos/tools/tlm_grapher/plots/plot.rb +69 -69
  703. data/lib/cosmos/tools/tlm_grapher/plots/singlexy_plot.rb +20 -20
  704. data/lib/cosmos/tools/tlm_grapher/plots/xy_plot.rb +61 -61
  705. data/lib/cosmos/tools/tlm_grapher/tabbed_plots/overview_tabbed_plots.rb +1278 -1278
  706. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +430 -430
  707. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_data_object_editor.rb +107 -107
  708. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_logfile_thread.rb +111 -95
  709. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_plot_editor.rb +101 -101
  710. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +72 -66
  711. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tab.rb +57 -57
  712. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +1004 -1004
  713. data/lib/cosmos/tools/tlm_grapher/tlm_grapher.rb +87 -87
  714. data/lib/cosmos/tools/tlm_viewer/screen.rb +486 -458
  715. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +563 -544
  716. data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +287 -287
  717. data/lib/cosmos/tools/tlm_viewer/widgets.rb +53 -53
  718. data/lib/cosmos/tools/tlm_viewer/widgets/aging_widget.rb +110 -110
  719. data/lib/cosmos/tools/tlm_viewer/widgets/array_widget.rb +70 -70
  720. data/lib/cosmos/tools/tlm_viewer/widgets/block_widget.rb +61 -61
  721. data/lib/cosmos/tools/tlm_viewer/widgets/button_widget.rb +39 -39
  722. data/lib/cosmos/tools/tlm_viewer/widgets/canvas_widget.rb +62 -62
  723. data/lib/cosmos/tools/tlm_viewer/widgets/canvasimage_widget.rb +41 -41
  724. data/lib/cosmos/tools/tlm_viewer/widgets/canvasimagevalue_widget.rb +57 -57
  725. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslabel_widget.rb +37 -37
  726. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslabelvalue_widget.rb +56 -56
  727. data/lib/cosmos/tools/tlm_viewer/widgets/canvasline_widget.rb +55 -55
  728. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslinevalue_widget.rb +66 -66
  729. data/lib/cosmos/tools/tlm_viewer/widgets/canvasvalue_widget.rb +124 -124
  730. data/lib/cosmos/tools/tlm_viewer/widgets/checkbutton_widget.rb +31 -31
  731. data/lib/cosmos/tools/tlm_viewer/widgets/combobox_widget.rb +30 -30
  732. data/lib/cosmos/tools/tlm_viewer/widgets/formatfontvalue_widget.rb +36 -36
  733. data/lib/cosmos/tools/tlm_viewer/widgets/formatvalue_widget.rb +35 -35
  734. data/lib/cosmos/tools/tlm_viewer/widgets/horizontal_widget.rb +27 -27
  735. data/lib/cosmos/tools/tlm_viewer/widgets/horizontalbox_widget.rb +31 -31
  736. data/lib/cosmos/tools/tlm_viewer/widgets/horizontalline_widget.rb +26 -26
  737. data/lib/cosmos/tools/tlm_viewer/widgets/label_widget.rb +29 -29
  738. data/lib/cosmos/tools/tlm_viewer/widgets/labelformatvalue_widget.rb +39 -39
  739. data/lib/cosmos/tools/tlm_viewer/widgets/labelprogressbar_widget.rb +38 -38
  740. data/lib/cosmos/tools/tlm_viewer/widgets/labeltrendlimitsbar_widget.rb +38 -38
  741. data/lib/cosmos/tools/tlm_viewer/widgets/labelvalue_widget.rb +39 -39
  742. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluedesc_widget.rb +42 -42
  743. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluelimitsbar_widget.rb +37 -37
  744. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluerangebar_widget.rb +37 -37
  745. data/lib/cosmos/tools/tlm_viewer/widgets/layout_widget.rb +34 -34
  746. data/lib/cosmos/tools/tlm_viewer/widgets/limitsbar_widget.rb +178 -178
  747. data/lib/cosmos/tools/tlm_viewer/widgets/linegraph_widget.rb +54 -54
  748. data/lib/cosmos/tools/tlm_viewer/widgets/matrixbycolumns_widget.rb +47 -47
  749. data/lib/cosmos/tools/tlm_viewer/widgets/multi_widget.rb +116 -116
  750. data/lib/cosmos/tools/tlm_viewer/widgets/progressbar_widget.rb +34 -34
  751. data/lib/cosmos/tools/tlm_viewer/widgets/radiobutton_widget.rb +30 -30
  752. data/lib/cosmos/tools/tlm_viewer/widgets/rangebar_widget.rb +57 -57
  753. data/lib/cosmos/tools/tlm_viewer/widgets/screenshotbutton_widget.rb +34 -34
  754. data/lib/cosmos/tools/tlm_viewer/widgets/scrollwindow_widget.rb +35 -35
  755. data/lib/cosmos/tools/tlm_viewer/widgets/sectionheader_widget.rb +33 -33
  756. data/lib/cosmos/tools/tlm_viewer/widgets/tabbook_widget.rb +26 -26
  757. data/lib/cosmos/tools/tlm_viewer/widgets/tabitem_widget.rb +28 -28
  758. data/lib/cosmos/tools/tlm_viewer/widgets/textbox_widget.rb +47 -47
  759. data/lib/cosmos/tools/tlm_viewer/widgets/textfield_widget.rb +26 -26
  760. data/lib/cosmos/tools/tlm_viewer/widgets/timegraph_widget.rb +88 -88
  761. data/lib/cosmos/tools/tlm_viewer/widgets/title_widget.rb +27 -27
  762. data/lib/cosmos/tools/tlm_viewer/widgets/trendbar_widget.rb +130 -130
  763. data/lib/cosmos/tools/tlm_viewer/widgets/trendlimitsbar_widget.rb +46 -46
  764. data/lib/cosmos/tools/tlm_viewer/widgets/value_widget.rb +43 -43
  765. data/lib/cosmos/tools/tlm_viewer/widgets/valuelimitsbar_widget.rb +37 -37
  766. data/lib/cosmos/tools/tlm_viewer/widgets/valuerangebar_widget.rb +37 -37
  767. data/lib/cosmos/tools/tlm_viewer/widgets/vertical_widget.rb +35 -35
  768. data/lib/cosmos/tools/tlm_viewer/widgets/verticalbox_widget.rb +37 -37
  769. data/lib/cosmos/tools/tlm_viewer/widgets/widget.rb +257 -257
  770. data/lib/cosmos/top_level.rb +647 -596
  771. data/lib/cosmos/utilities.rb +11 -10
  772. data/lib/cosmos/utilities/crc.rb +166 -166
  773. data/lib/cosmos/utilities/csv.rb +83 -83
  774. data/lib/cosmos/utilities/logger.rb +137 -137
  775. data/lib/cosmos/utilities/low_fragmentation_array.rb +11 -11
  776. data/lib/cosmos/utilities/message_log.rb +74 -74
  777. data/lib/cosmos/utilities/quaternion.rb +258 -258
  778. data/lib/cosmos/utilities/ruby_lex_utils.rb +313 -313
  779. data/lib/cosmos/utilities/simulated_target.rb +99 -99
  780. data/lib/cosmos/utilities/sleeper.rb +44 -0
  781. data/lib/cosmos/version.rb +12 -12
  782. data/lib/cosmos/win32/excel.rb +66 -66
  783. data/lib/cosmos/win32/win32.rb +387 -387
  784. data/lib/cosmos/win32/win32_main.rb +311 -311
  785. data/roodi.yml +24 -24
  786. data/run_gui_tests.bat +32 -32
  787. data/spec/ccsds/ccsds_packet_spec.rb +67 -67
  788. data/spec/ccsds/ccsds_parser_spec.rb +148 -148
  789. data/spec/config/config_parser_spec.rb +322 -322
  790. data/spec/conversions/conversion_spec.rb +31 -31
  791. data/spec/conversions/generic_conversion_spec.rb +45 -45
  792. data/spec/conversions/new_packet_log_conversion_spec.rb +39 -39
  793. data/spec/conversions/polynomial_conversion_spec.rb +40 -40
  794. data/spec/conversions/processor_conversion_spec.rb +45 -45
  795. data/spec/conversions/received_count_conversion_spec.rb +43 -43
  796. data/spec/conversions/received_time_formatted_conversion_spec.rb +49 -49
  797. data/spec/conversions/received_time_seconds_conversion_spec.rb +50 -50
  798. data/spec/conversions/segmented_polynomial_conversion_spec.rb +51 -51
  799. data/spec/conversions/unix_time_formatted_conversion_spec.rb +74 -74
  800. data/spec/conversions/unix_time_seconds_conversion_spec.rb +76 -76
  801. data/spec/core_ext/array_spec.rb +186 -186
  802. data/spec/core_ext/class_spec.rb +36 -36
  803. data/spec/core_ext/cosmos_io_spec.rb +77 -77
  804. data/spec/core_ext/exception_spec.rb +91 -91
  805. data/spec/core_ext/file_spec.rb +72 -72
  806. data/spec/core_ext/hash_spec.rb +24 -24
  807. data/spec/core_ext/io_spec.rb +46 -46
  808. data/spec/core_ext/kernel_spec.rb +54 -54
  809. data/spec/core_ext/math_spec.rb +116 -116
  810. data/spec/core_ext/matrix_spec.rb +66 -66
  811. data/spec/core_ext/objectspace_spec.rb +29 -29
  812. data/spec/core_ext/range_spec.rb +21 -21
  813. data/spec/core_ext/socket_spec.rb +32 -32
  814. data/spec/core_ext/string_spec.rb +223 -223
  815. data/spec/core_ext/stringio_spec.rb +21 -21
  816. data/spec/core_ext/time_spec.rb +151 -151
  817. data/spec/gui/line_graph/line_clip_spec.rb +322 -322
  818. data/spec/install/config/system/system.txt +33 -33
  819. data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +41 -41
  820. data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +15 -15
  821. data/spec/install/config/targets/COSMOS/cmd_tlm_server.txt +6 -6
  822. data/spec/install/config/targets/COSMOS/screens/limits_change.txt +20 -20
  823. data/spec/install/config/targets/COSMOS/screens/version.txt +19 -19
  824. data/spec/install/config/targets/COSMOS/target.txt +5 -5
  825. data/spec/install/config/targets/INST/cmd_tlm/inst_cmd_linc.txt +30 -30
  826. data/spec/install/config/targets/INST/cmd_tlm/inst_cmds.txt +111 -111
  827. data/spec/install/config/targets/INST/cmd_tlm/inst_tlm.txt +236 -236
  828. data/spec/install/config/targets/INST/cmd_tlm/inst_tlm_linc.txt +25 -25
  829. data/spec/install/config/targets/INST/cmd_tlm_server.txt +5 -5
  830. data/spec/install/config/targets/INST/lib/sim_inst.rb +305 -294
  831. data/spec/install/config/targets/INST/target.txt +10 -10
  832. data/spec/install/config/targets/META/cmd_tlm/meta_cmd.txt +4 -4
  833. data/spec/install/config/targets/META/cmd_tlm/meta_tlm.txt +4 -4
  834. data/spec/install/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -7
  835. data/spec/interfaces/cmd_tlm_server_interface_spec.rb +150 -150
  836. data/spec/interfaces/interface_spec.rb +130 -131
  837. data/spec/interfaces/linc_interface_spec.rb +199 -199
  838. data/spec/interfaces/serial_interface_spec.rb +56 -56
  839. data/spec/interfaces/simulated_target_interface_spec.rb +128 -128
  840. data/spec/interfaces/stream_interface_spec.rb +157 -157
  841. data/spec/interfaces/tcpip_client_interface_spec.rb +54 -54
  842. data/spec/interfaces/tcpip_server_interface_spec.rb +151 -151
  843. data/spec/interfaces/udp_interface_spec.rb +175 -177
  844. data/spec/io/buffered_file_spec.rb +113 -113
  845. data/spec/io/io_multiplexer_spec.rb +94 -94
  846. data/spec/io/json_drb_object_spec.rb +99 -99
  847. data/spec/io/json_drb_spec.rb +311 -311
  848. data/spec/io/json_rpc_spec.rb +264 -264
  849. data/spec/io/raw_logger_pair_spec.rb +76 -76
  850. data/spec/io/raw_logger_spec.rb +133 -133
  851. data/spec/io/serial_driver_spec.rb +61 -61
  852. data/spec/io/stderr_spec.rb +32 -32
  853. data/spec/io/stdout_spec.rb +32 -32
  854. data/spec/io/tcpip_server_spec.rb +338 -338
  855. data/spec/io/udp_sockets_spec.rb +94 -94
  856. data/spec/io/win32_serial_driver_spec.rb +88 -88
  857. data/spec/packet_logs/meta_packet_log_writer_spec.rb +170 -170
  858. data/spec/packet_logs/packet_log_reader_spec.rb +408 -408
  859. data/spec/packet_logs/packet_log_writer_pair_spec.rb +30 -30
  860. data/spec/packet_logs/packet_log_writer_spec.rb +223 -223
  861. data/spec/packets/binary_accessor_spec.rb +2073 -2073
  862. data/spec/packets/commands_spec.rb +369 -369
  863. data/spec/packets/limits_response_spec.rb +25 -25
  864. data/spec/packets/limits_spec.rb +326 -326
  865. data/spec/packets/packet_config_spec.rb +1620 -1620
  866. data/spec/packets/packet_item_limits_spec.rb +161 -161
  867. data/spec/packets/packet_item_spec.rb +386 -386
  868. data/spec/packets/packet_spec.rb +1057 -949
  869. data/spec/packets/structure_item_spec.rb +195 -195
  870. data/spec/packets/structure_spec.rb +419 -419
  871. data/spec/packets/telemetry_spec.rb +535 -535
  872. data/spec/processors/new_packet_log_processor_spec.rb +39 -39
  873. data/spec/processors/processor_spec.rb +55 -55
  874. data/spec/processors/statistics_processor_spec.rb +60 -60
  875. data/spec/processors/watermark_processor_spec.rb +51 -51
  876. data/spec/script/script_spec.rb +654 -654
  877. data/spec/spec_helper.rb +154 -148
  878. data/spec/streams/burst_stream_protocol_spec.rb +32 -32
  879. data/spec/streams/fixed_stream_protocol_spec.rb +110 -110
  880. data/spec/streams/length_stream_protocol_spec.rb +297 -297
  881. data/spec/streams/preidentified_stream_protocol_spec.rb +118 -118
  882. data/spec/streams/serial_stream_spec.rb +105 -105
  883. data/spec/streams/stream_protocol_spec.rb +332 -332
  884. data/spec/streams/stream_spec.rb +29 -29
  885. data/spec/streams/tcpip_client_stream_spec.rb +54 -54
  886. data/spec/streams/tcpip_socket_stream_spec.rb +146 -146
  887. data/spec/streams/template_stream_protocol_spec.rb +151 -151
  888. data/spec/streams/terminated_stream_protocol_spec.rb +123 -123
  889. data/spec/system/system_spec.rb +645 -645
  890. data/spec/system/target_spec.rb +248 -248
  891. data/spec/tools/cmd_tlm_server/api_spec.rb +1087 -1113
  892. data/spec/tools/cmd_tlm_server/background_task_spec.rb +32 -32
  893. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +81 -81
  894. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +411 -411
  895. data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +415 -415
  896. data/spec/tools/cmd_tlm_server/commanding_spec.rb +123 -123
  897. data/spec/tools/cmd_tlm_server/connections_spec.rb +147 -147
  898. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +306 -306
  899. data/spec/tools/cmd_tlm_server/interfaces_spec.rb +252 -238
  900. data/spec/tools/cmd_tlm_server/packet_logging_spec.rb +143 -143
  901. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +98 -101
  902. data/spec/tools/cmd_tlm_server/routers_spec.rb +223 -208
  903. data/spec/top_level/top_level_spec.rb +334 -321
  904. data/spec/utilities/crc_spec.rb +45 -45
  905. data/spec/utilities/csv_spec.rb +97 -97
  906. data/spec/utilities/logger_spec.rb +102 -102
  907. data/spec/utilities/message_log_spec.rb +89 -89
  908. data/spec/utilities/quaternion_spec.rb +107 -107
  909. data/spec/utilities/ruby_lex_utils_spec.rb +86 -86
  910. data/tasks/manifest.rake +22 -22
  911. data/tasks/spec.rake +23 -23
  912. metadata +18 -2
@@ -1,66 +1,66 @@
1
- # encoding: ascii-8bit
2
-
3
- # Copyright 2014 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 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
- require 'cosmos/tools/cmd_tlm_server/interface_thread'
12
-
13
- module Cosmos
14
-
15
- # Overrides the packet handling method in InterfaceThread to sends all
16
- # packets to {Commanding#send_command_to_interface}
17
- class RouterThread < InterfaceThread
18
-
19
- protected
20
-
21
- def handle_packet(packet)
22
- # Start out assuming we will route to all associated interfaces
23
- interfaces = @interface.interfaces
24
-
25
- # Identified packets we may handle differently...
26
- if packet.identified?
27
- target = System.targets[packet.target_name.upcase]
28
- if target
29
- if target.interface
30
- # If target exists and has an interface we will only send the packet to that interface
31
- interfaces = [target.interface]
32
- else
33
- # If target exists and has no interface we will not send the packet anywhere
34
- interfaces = []
35
- Logger.warn "Received command for target with no interface: #{packet.target_name} #{packet.packet_name}"
36
- end
37
- end
38
-
39
- # Make sure identified packet exists
40
- begin
41
- System.commands.packet(packet.target_name, packet.packet_name)
42
- rescue
43
- Logger.warn "Received unknown identified command: #{packet.target_name} #{packet.packet_name}"
44
-
45
- # Clear identification
46
- packet.target_name = nil
47
- packet.packet_name = nil
48
- end
49
- end
50
-
51
- interfaces.each do |interface|
52
- if interface.connected?
53
- begin
54
- CmdTlmServer.commanding.send_command_to_interface(interface, packet)
55
- rescue Exception => err
56
- Logger.error "Error routing command from #{@interface.name} to interface #{interface.name}\n#{err.formatted}"
57
- end
58
- else
59
- Logger.error "Attempted to route command from #{@interface.name} to disconnected interface #{interface.name}"
60
- end
61
- end
62
- end
63
-
64
- end # class RouterThread
65
-
66
- end # module Cosmos
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2014 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 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
+ require 'cosmos/tools/cmd_tlm_server/interface_thread'
12
+
13
+ module Cosmos
14
+
15
+ # Overrides the packet handling method in InterfaceThread to sends all
16
+ # packets to {Commanding#send_command_to_interface}
17
+ class RouterThread < InterfaceThread
18
+
19
+ protected
20
+
21
+ def handle_packet(packet)
22
+ # Start out assuming we will route to all associated interfaces
23
+ interfaces = @interface.interfaces
24
+
25
+ # Identified packets we may handle differently...
26
+ if packet.identified?
27
+ target = System.targets[packet.target_name.upcase]
28
+ if target
29
+ if target.interface
30
+ # If target exists and has an interface we will only send the packet to that interface
31
+ interfaces = [target.interface]
32
+ else
33
+ # If target exists and has no interface we will not send the packet anywhere
34
+ interfaces = []
35
+ Logger.warn "Received command for target with no interface: #{packet.target_name} #{packet.packet_name}"
36
+ end
37
+ end
38
+
39
+ # Make sure identified packet exists
40
+ begin
41
+ System.commands.packet(packet.target_name, packet.packet_name)
42
+ rescue
43
+ Logger.warn "Received unknown identified command: #{packet.target_name} #{packet.packet_name}"
44
+
45
+ # Clear identification
46
+ packet.target_name = nil
47
+ packet.packet_name = nil
48
+ end
49
+ end
50
+
51
+ interfaces.each do |interface|
52
+ if interface.connected?
53
+ begin
54
+ CmdTlmServer.commanding.send_command_to_interface(interface, packet)
55
+ rescue Exception => err
56
+ Logger.error "Error routing command from #{@interface.name} to interface #{interface.name}\n#{err.formatted}"
57
+ end
58
+ else
59
+ Logger.error "Attempted to route command from #{@interface.name} to disconnected interface #{interface.name}"
60
+ end
61
+ end
62
+ end
63
+
64
+ end # class RouterThread
65
+
66
+ end # module Cosmos
@@ -1,97 +1,97 @@
1
- # encoding: ascii-8bit
2
-
3
- # Copyright 2014 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 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
- require 'cosmos/tools/cmd_tlm_server/connections'
12
- require 'cosmos/tools/cmd_tlm_server/router_thread'
13
- require 'cosmos/interfaces/tcpip_server_interface'
14
-
15
- module Cosmos
16
-
17
- # Controls the routers as defined in the Command/Telemetry configuration
18
- # file. Routers are just interfaces which receive command packets from their
19
- # remote connection and send them out to their interfaces. They receive
20
- # telemetry packets from their interfaces and send them to their remote
21
- # connections. This allows them to be intermediaries between an external
22
- # client and the actual device.
23
- class Routers < Connections
24
- # @param cmd_tlm_server_config [CmdTlmServerConfig] The configuration which
25
- # defines all the routers
26
- def initialize(cmd_tlm_server_config)
27
- super(:ROUTERS, cmd_tlm_server_config)
28
- end
29
-
30
- # Adds a Preidentified router to the system with given name and port.
31
- # All interfaces defined by the Command/Telemetry configuration are
32
- # directed to this router for both commands and telemetry.
33
- #
34
- # @param router_name [String] Name of the router
35
- # @param port [Integer] Port to pass to the {TcpipServerInterface}
36
- def add_preidentified(router_name, port)
37
- router_name = router_name.upcase
38
- router = TcpipServerInterface.new(port, port, 10.0, nil, 'PREIDENTIFIED')
39
- router.name = router_name
40
- router.disable_disconnect = true
41
- @config.routers[router_name] = router
42
- @config.interfaces.each do |interface_name, interface|
43
- router.interfaces << interface
44
- interface.routers << router
45
- end
46
- end
47
-
48
- # Recreate a router with new initialization parameters
49
- #
50
- # @param router_name [String] Name of the router
51
- # @param params [Array] Array of parameters to pass to the router
52
- # constructor
53
- def recreate(router_name, *params)
54
- router = @config.routers[router_name.upcase]
55
- raise "Unknown router: #{router_name}" unless router
56
-
57
- # Build New Router
58
- new_router = router.class.new(*params)
59
- router.copy_to(new_router)
60
-
61
- # Remove old router and add new to each interface
62
- router.interfaces.each do |interface|
63
- interface.routers.delete(router)
64
- interface.routers << new_router
65
- end
66
-
67
- # Replace interface in @interfaces array
68
- @config.routers[router_name.upcase] = new_router
69
-
70
- # Make sure there is no thread
71
- stop_thread(router)
72
-
73
- return new_router
74
- end
75
-
76
- protected
77
-
78
- # Start an router's packet reading thread
79
- def start_thread(router)
80
- Logger.info "Creating thread for router #{router.name}"
81
- router_thread = RouterThread.new(router)
82
- router_thread.start
83
- end
84
-
85
- # Stop an router's packet reading thread
86
- def stop_thread(router)
87
- if router.thread
88
- Logger.info "Killing thread for router #{router.name}"
89
- to_stop = router.thread
90
- router.thread = nil
91
- to_stop.stop
92
- end
93
- end
94
-
95
- end # class Routers
96
-
97
- end # module Cosmos
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2014 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 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
+ require 'cosmos/tools/cmd_tlm_server/connections'
12
+ require 'cosmos/tools/cmd_tlm_server/router_thread'
13
+ require 'cosmos/interfaces/tcpip_server_interface'
14
+
15
+ module Cosmos
16
+
17
+ # Controls the routers as defined in the Command/Telemetry configuration
18
+ # file. Routers are just interfaces which receive command packets from their
19
+ # remote connection and send them out to their interfaces. They receive
20
+ # telemetry packets from their interfaces and send them to their remote
21
+ # connections. This allows them to be intermediaries between an external
22
+ # client and the actual device.
23
+ class Routers < Connections
24
+ # @param cmd_tlm_server_config [CmdTlmServerConfig] The configuration which
25
+ # defines all the routers
26
+ def initialize(cmd_tlm_server_config)
27
+ super(:ROUTERS, cmd_tlm_server_config)
28
+ end
29
+
30
+ # Adds a Preidentified router to the system with given name and port.
31
+ # All interfaces defined by the Command/Telemetry configuration are
32
+ # directed to this router for both commands and telemetry.
33
+ #
34
+ # @param router_name [String] Name of the router
35
+ # @param port [Integer] Port to pass to the {TcpipServerInterface}
36
+ def add_preidentified(router_name, port)
37
+ router_name = router_name.upcase
38
+ router = TcpipServerInterface.new(port, port, 10.0, nil, 'PREIDENTIFIED')
39
+ router.name = router_name
40
+ router.disable_disconnect = true
41
+ @config.routers[router_name] = router
42
+ @config.interfaces.each do |interface_name, interface|
43
+ router.interfaces << interface
44
+ interface.routers << router
45
+ end
46
+ end
47
+
48
+ # Recreate a router with new initialization parameters
49
+ #
50
+ # @param router_name [String] Name of the router
51
+ # @param params [Array] Array of parameters to pass to the router
52
+ # constructor
53
+ def recreate(router_name, *params)
54
+ router = @config.routers[router_name.upcase]
55
+ raise "Unknown router: #{router_name}" unless router
56
+
57
+ # Build New Router
58
+ new_router = router.class.new(*params)
59
+ router.copy_to(new_router)
60
+
61
+ # Remove old router and add new to each interface
62
+ router.interfaces.each do |interface|
63
+ interface.routers.delete(router)
64
+ interface.routers << new_router
65
+ end
66
+
67
+ # Replace interface in @interfaces array
68
+ @config.routers[router_name.upcase] = new_router
69
+
70
+ # Make sure there is no thread
71
+ stop_thread(router)
72
+
73
+ return new_router
74
+ end
75
+
76
+ protected
77
+
78
+ # Start an router's packet reading thread
79
+ def start_thread(router)
80
+ Logger.info "Creating thread for router #{router.name}"
81
+ router_thread = RouterThread.new(router)
82
+ router_thread.start
83
+ end
84
+
85
+ # Stop an router's packet reading thread
86
+ def stop_thread(router)
87
+ if router.thread
88
+ Logger.info "Killing thread for router #{router.name}"
89
+ to_stop = router.thread
90
+ router.thread = nil
91
+ to_stop.stop
92
+ end
93
+ end
94
+
95
+ end # class Routers
96
+
97
+ end # module Cosmos
@@ -1,600 +1,628 @@
1
- # encoding: ascii-8bit
2
-
3
- # Copyright 2014 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 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
- require 'cosmos'
12
- Cosmos.catch_fatal_exception do
13
- require 'cosmos/script'
14
- require 'cosmos/config/config_parser'
15
- require 'cosmos/gui/qt_tool'
16
- require 'cosmos/gui/dialogs/splash'
17
- require 'cosmos/gui/dialogs/progress_dialog'
18
- require 'cosmos/gui/dialogs/exception_dialog'
19
- require 'cosmos/gui/dialogs/packet_log_dialog'
20
- require 'cosmos/gui/dialogs/find_replace_dialog'
21
- require 'cosmos/gui/widgets/realtime_button_bar'
22
- require 'cosmos/tools/data_viewer/data_viewer_component'
23
- require 'cosmos/tools/data_viewer/dump_component'
24
- end
25
-
26
- module Cosmos
27
-
28
- class DataViewer < QtTool
29
- slots 'context_menu(const QPoint&)'
30
- slots 'handle_tab_change(int)'
31
-
32
- def initialize(options)
33
- super(options) # MUST BE FIRST - All code before super is executed twice in RubyQt Based classes
34
- Cosmos.load_cosmos_icon("data_viewer.png")
35
-
36
- initialize_actions()
37
- initialize_menus()
38
- initialize_central_widget()
39
- complete_initialize()
40
-
41
- # Initialize instance variables
42
- @auto_start = false
43
- @pause = false
44
- @log_file_directory = System.paths['LOGS']
45
- @tlm_log_system = nil
46
- @subscription_thread = nil
47
- @subscription_id = nil
48
- @packet_log_reader = System.default_packet_log_reader.new
49
- @time_start = nil
50
- @time_end = nil
51
- @log_filenames = []
52
-
53
- # Process config file and create a tab for each data viewer component
54
- @component_mutex = Mutex.new
55
- @components = []
56
- @packets = []
57
- @packet_to_components_mapping = {}
58
- @config_filename = File.join(Cosmos::USERPATH, 'config', 'tools', 'data_viewer', options.config_file)
59
- process_config()
60
-
61
- # Load System Definition and Event Data
62
- Splash.execute(self) do |splash|
63
- Qt.execute_in_main_thread(true) do
64
- ConfigParser.splash = splash
65
- System.telemetry
66
- @components.each do |component|
67
- # Create tab for each component
68
- component.initialize_gui
69
- @tab_book.addTab(component, component.tab_name)
70
- end
71
- if @auto_start
72
- handle_start()
73
- end
74
- ConfigParser.splash = nil
75
- end
76
- end
77
-
78
- # Add GUI Update Timeout
79
- @timer = Qt::Timer.new(self)
80
- @timer.connect(SIGNAL('timeout()')) { update_gui() }
81
- @timer.method_missing(:start, 100)
82
- end
83
-
84
- def initialize_actions
85
- super()
86
-
87
- # File Menu Actions
88
- @open_log = Qt::Action.new(tr('&Open Log File'), self)
89
- @open_log_keyseq = Qt::KeySequence.new(tr('Ctrl+O'))
90
- @open_log.shortcut = @open_log_keyseq
91
- @open_log.statusTip = tr('Open telemetry log file for processing')
92
- @open_log.connect(SIGNAL('triggered()')) { handle_open_log_file() }
93
-
94
- @handle_reset = Qt::Action.new(tr('&Reset'), self)
95
- @handle_reset_keyseq = Qt::KeySequence.new(tr('Ctrl+R'))
96
- @handle_reset.shortcut = @handle_reset_keyseq
97
- @handle_reset.statusTip = tr('Reset Components')
98
- @handle_reset.connect(SIGNAL('triggered()')) { handle_reset() }
99
-
100
- # Search Actions
101
- @search_find = Qt::Action.new(Cosmos.get_icon('search.png'), tr('&Find'), self)
102
- @search_find_keyseq = Qt::KeySequence.new(tr('Ctrl+F'))
103
- @search_find.shortcut = @search_find_keyseq
104
- @search_find.statusTip = tr('Find text')
105
- @search_find.connect(SIGNAL('triggered()')) { find() }
106
-
107
- @search_find_next = Qt::Action.new(tr('Find &Next'), self)
108
- @search_find_next_keyseq = Qt::KeySequence.new(tr('F3'))
109
- @search_find_next.shortcut = @search_find_next_keyseq
110
- @search_find_next.statusTip = tr('Find next instance')
111
- @search_find_next.connect(SIGNAL('triggered()')) { find_next() }
112
-
113
- @search_find_previous = Qt::Action.new(tr('Find &Previous'), self)
114
- @search_find_previous_keyseq = Qt::KeySequence.new(tr('Shift+F3'))
115
- @search_find_previous.shortcut = @search_find_previous_keyseq
116
- @search_find_previous.statusTip = tr('Find previous instance')
117
- @search_find_previous.connect(SIGNAL('triggered()')) { find_previous() }
118
-
119
- # Tab Menu Actions
120
- @delete_tab = Qt::Action.new(Cosmos.get_icon('delete_tab.png'), tr('&Delete Tab'), self)
121
- @delete_tab.statusTip = tr('Delete active tab')
122
- @delete_tab.connect(SIGNAL('triggered()')) { on_tab_delete() }
123
- end
124
-
125
- def initialize_menus
126
- # File Menu
127
- file_menu = menuBar.addMenu(tr('&File'))
128
- file_menu.addAction(@open_log)
129
- file_menu.addAction(@handle_reset)
130
- file_menu.addSeparator()
131
- file_menu.addAction(@exit_action)
132
-
133
- # Tab Menu
134
- @tab_menu = menuBar.addMenu(tr('&Tab'))
135
- @tab_menu.addAction(@delete_tab)
136
- @tab_menu.addSeparator()
137
- @tab_menu_actions = []
138
-
139
- # Search Menu
140
- view_menu = menuBar.addMenu(tr('&Search'))
141
- view_menu.addAction(@search_find)
142
- view_menu.addAction(@search_find_next)
143
- view_menu.addAction(@search_find_previous)
144
-
145
- # Help Menu
146
- @about_string = "Data Viewer is designed to allow users view data that is not easily displayed on telemetry screens."
147
- initialize_help_menu()
148
- end
149
-
150
- def initialize_central_widget
151
- # Create the central widget
152
- @central_widget = Qt::Widget.new
153
- setCentralWidget(@central_widget)
154
-
155
- # Create the top level vertical layout
156
- @top_layout = Qt::VBoxLayout.new(@central_widget)
157
-
158
- # Realtime Button Bar
159
- @realtime_button_bar = RealtimeButtonBar.new(self)
160
- @realtime_button_bar.start_callback = method(:handle_start)
161
- @realtime_button_bar.pause_callback = method(:handle_pause)
162
- @realtime_button_bar.stop_callback = method(:handle_stop)
163
- @realtime_button_bar.state = 'Stopped'
164
- @top_layout.addWidget(@realtime_button_bar)
165
-
166
- # Create tab book
167
- @tab_book = Qt::TabWidget.new
168
- @tab_book.setContextMenuPolicy(Qt::CustomContextMenu)
169
- connect(@tab_book, SIGNAL('currentChanged(int)'), self, SLOT('handle_tab_change(int)'))
170
- connect(@tab_book, SIGNAL('customContextMenuRequested(const QPoint&)'), self, SLOT('context_menu(const QPoint&)'))
171
- @top_layout.addWidget(@tab_book)
172
- end
173
-
174
- def current_component
175
- @component_mutex.synchronize do
176
- yield @components[@tab_book.currentIndex()]
177
- end
178
- end
179
-
180
- def find
181
- unless @find_dialog
182
- @find_dialog = FindReplaceDialog.new(@script, false)
183
- @find_dialog.connect(SIGNAL('find_next()')) do
184
- current_component do |component|
185
- component.find(@find_dialog)
186
- end
187
- end
188
- end
189
- @find_dialog.show
190
- @find_dialog.raise
191
- @find_dialog.activateWindow
192
- end
193
-
194
- def find_next
195
- current_component do |component|
196
- component.find_next(@find_dialog) if @find_dialog
197
- end
198
- end
199
-
200
- def find_previous
201
- current_component do |component|
202
- component.find_previous(@find_dialog) if @find_dialog
203
- end
204
- end
205
-
206
- def handle_tab_change(index)
207
- # Remove existing actions
208
- @tab_menu_actions.each do |action|
209
- @tab_menu.removeAction(action)
210
- action.dispose
211
- end
212
- @tab_menu_actions = []
213
-
214
- # Add new actions
215
- unless @components.empty?
216
- @component_mutex.synchronize do
217
- component = @components[index]
218
- component.packets.each do |target_name, packet_name|
219
- action = Qt::Action.new("#{target_name} #{packet_name}", @tab_menu)
220
- action.setCheckable(true)
221
- key = target_name + ' ' + packet_name
222
- components = @packet_to_components_mapping[key]
223
- if components.include?(component)
224
- action.setChecked(true)
225
- else
226
- action.setChecked(false)
227
- end
228
- action.connect(SIGNAL('triggered()')) { enable_disable_component_packet(index, target_name, packet_name, action.checked?) }
229
- @tab_menu.addAction(action)
230
- @tab_menu_actions << action
231
- end
232
- end
233
- end
234
- end
235
-
236
- def context_menu(point)
237
- index = 0
238
- (0..@tab_book.tabBar.count).each do |i|
239
- index = i if @tab_book.tabBar.tabRect(i).contains(point)
240
- end
241
-
242
- return if (index == @tab_book.tabBar.count)
243
-
244
- # Bring the right clicked tab to the front
245
- @tab_book.setCurrentIndex(index)
246
- @tab_menu.exec(@tab_book.mapToGlobal(point))
247
- end
248
-
249
- def start_subscription_thread
250
- unless @subscription_thread
251
- # Start Thread to Gather Events
252
- @subscription_thread = Thread.new do
253
- if !@packets.empty?
254
- begin
255
- while true
256
- begin
257
- @subscription_id = subscribe_packet_data(@packets, 10000)
258
- if @pause
259
- Qt.execute_in_main_thread(true) { @realtime_button_bar.state = 'Paused' }
260
- else
261
- Qt.execute_in_main_thread(true) { @realtime_button_bar.state = 'Running' }
262
- end
263
- Qt.execute_in_main_thread(true) { statusBar.showMessage("Connected to Command and Telemetry Server: #{Time.now.formatted}") }
264
- rescue DRb::DRbConnError
265
- Qt.execute_in_main_thread(true) do
266
- @realtime_button_bar.state = 'Connecting'
267
- statusBar.showMessage(tr("Error Connecting to Command and Telemetry Server"))
268
- end
269
- sleep(1)
270
- retry
271
- end
272
-
273
- while true
274
- begin
275
- # Get a subscribed to packet
276
- packet_data, target_name, packet_name, received_time, received_count = get_packet_data(@subscription_id)
277
-
278
- # Put packet data into its packet
279
- packet = System.telemetry.packet(target_name, packet_name)
280
- packet.buffer = packet_data
281
- packet.received_time = received_time
282
- packet.received_count = received_count
283
-
284
- # Route packet to its component(s)
285
- index = packet.target_name + ' ' + packet.packet_name
286
- @component_mutex.synchronize do
287
- components = @packet_to_components_mapping[index]
288
- if components
289
- components.each do |component|
290
- component.process_packet(packet)
291
- end
292
- end
293
- end
294
- rescue DRb::DRbConnError
295
- Qt.execute_in_main_thread(true) { statusBar.showMessage(tr("Error Connecting to Command and Telemetry Server")) }
296
- break # Let outer loop resubscribe
297
- rescue RuntimeError => error
298
- raise error unless error.message =~ /queue/
299
- Qt.execute_in_main_thread(true) { statusBar.showMessage(tr("Connection Dropped by Command and Telemetry Server: #{Time.now.formatted}")) }
300
- break # Let outer loop resubscribe
301
- end
302
- end
303
- end
304
- rescue Exception => error
305
- Qt.execute_in_main_thread(true) {|| ExceptionDialog.new(self, error, "Data Viewer : Subscription Thread")}
306
- end
307
- end # if !@packets.empty
308
- end
309
- else
310
- Qt.execute_in_main_thread(true) { @realtime_button_bar.state = 'Running' }
311
- end
312
- end
313
-
314
- def kill_subscription_thread
315
- @subscription_thread.kill if @subscription_thread
316
- @subscription_thread = nil
317
- end
318
-
319
- def handle_reset
320
- @component_mutex.synchronize do
321
- @components.each do |component|
322
- component.reset
323
- end
324
- end
325
- System.telemetry.reset
326
- end
327
-
328
- def handle_start
329
- if windowTitle() != 'Data Viewer'
330
- # Clear Title
331
- setWindowTitle('Data Viewer')
332
-
333
- # Return to default configuration
334
- # Show splash during possible reconfiguration
335
- Splash.execute(self) do |splash|
336
- ConfigParser.splash = splash
337
- System.load_configuration
338
- ConfigParser.splash = nil
339
- end
340
-
341
- # Reset Components
342
- handle_reset()
343
- end
344
-
345
- # Restart GUI Updates if necessary
346
- if @pause
347
- @pause = false
348
- @timer.method_missing(:start, 100)
349
- end
350
-
351
- # Restart Subscription Thread if necessary
352
- start_subscription_thread()
353
- end
354
-
355
- def handle_pause
356
- @pause = true
357
- if @subscription_thread
358
- @realtime_button_bar.state = 'Paused'
359
- end
360
- end
361
-
362
- def handle_stop
363
- # Shutdown packet subscription thread
364
- kill_subscription_thread()
365
-
366
- # Unsubscribe from subscription
367
- if @subscription_id
368
- begin
369
- unsubscribe_packet_data(@subscription_id)
370
- rescue DRb::DRbConnError
371
- # Do Nothing
372
- end
373
- end
374
-
375
- # Restart GUI Updates if necessary
376
- if @pause
377
- @pause = false
378
- @timer.method_missing(:start, 100)
379
- end
380
-
381
- @realtime_button_bar.state = 'Stopped'
382
- end
383
-
384
- def handle_open_log_file
385
- # Prompt user for filename
386
- packet_log_dialog = PacketLogDialog.new(self, 'Open Log File(s):', @log_file_directory, @packet_log_reader, [], nil, false, true, true, Cosmos::TLM_FILE_PATTERN)
387
- begin
388
- packet_log_dialog.time_start = @time_start
389
- packet_log_dialog.time_end = @time_end
390
- case packet_log_dialog.exec
391
- when Qt::Dialog::Accepted
392
- @packet_log_reader = packet_log_dialog.packet_log_reader
393
- @log_filenames = packet_log_dialog.filenames.sort
394
- @time_start = packet_log_dialog.time_start
395
- @time_end = packet_log_dialog.time_end
396
- @log_file_directory = File.dirname(@log_filenames[0])
397
- @log_file_directory += '/' unless @log_file_directory[-1..-1] == '\\'
398
-
399
- # Stop realtime collection
400
- handle_stop()
401
-
402
- # Reset components
403
- handle_reset()
404
-
405
- ProgressDialog.execute(self, 'Processing Log File', 500, 200, @log_filenames.length > 1, true, true, true, true) do |dialog|
406
- dialog.enable_cancel_button
407
-
408
- @log_filenames.each_with_index do |filename, file_index|
409
- Qt.execute_in_main_thread(true) do
410
- self.setWindowTitle("Data Viewer : #{filename}")
411
- end
412
-
413
- file_size = File.size(filename).to_f
414
- dialog.append_text("Processing: #{filename}")
415
-
416
- @packet_log_reader.each(filename, true, @time_start, @time_end) do |packet|
417
- progress = @packet_log_reader.bytes_read.to_f / file_size
418
- dialog.set_step_progress(progress)
419
-
420
- # Route packet to its component(s)
421
- index = packet.target_name + ' ' + packet.packet_name
422
- components = @packet_to_components_mapping[index]
423
- if components
424
- @component_mutex.synchronize do
425
- components.each do |component|
426
- component.process_packet(packet)
427
- end
428
- end
429
- end
430
- end
431
-
432
- dialog.set_overall_progress((file_index + 1).to_f / @log_filenames.length) if @log_filenames.length > 1
433
- end
434
-
435
- dialog.append_text("Done!")
436
- dialog.set_step_progress(1.0)
437
- dialog.set_overall_progress(1.0) if @log_filenames.length > 1
438
- dialog.complete
439
- end
440
- end
441
- ensure
442
- packet_log_dialog.dispose if packet_log_dialog
443
- end
444
- end
445
-
446
- def update_gui
447
- if @pause
448
- @timer.method_missing(:stop)
449
- else
450
- Qt.execute_in_main_thread(true) do
451
- @component_mutex.synchronize do
452
- @components.each do |component|
453
- break if @pause
454
- component.update_gui
455
- end
456
- end
457
- end
458
- end
459
- end
460
-
461
- def closeEvent(event)
462
- # Stop GUI update timeout
463
- @pause = true
464
-
465
- # Stop Processing Packets
466
- handle_stop()
467
-
468
- # Shutdown each component
469
- @component_mutex.synchronize do
470
- @components.each {|component| component.shutdown}
471
- end
472
-
473
- # Give things time to complete
474
- sleep(0.1)
475
-
476
- # Standard COSMOS Shutdown
477
- shutdown_cmd_tlm()
478
-
479
- # Accept closure
480
- super(event)
481
- end
482
-
483
- def process_config
484
- # ensure the file exists
485
- unless test ?f, @config_filename
486
- raise "Configuration File Does not Exist: #{@config_filename}"
487
- end
488
-
489
- parser = ConfigParser.new
490
- parser.parse_file(@config_filename) do |keyword, params|
491
- case keyword
492
-
493
- when 'AUTO_START'
494
- usage = "#{keyword}"
495
- parser.verify_num_parameters(0, 0, usage)
496
- @auto_start = true
497
-
498
- when 'COMPONENT'
499
- usage = "#{keyword} <tab name> <component class filename> <component specific options...>"
500
- parser.verify_num_parameters(2, nil, usage)
501
- component_class = Cosmos.require_class(params[1])
502
- if params.length >= 3
503
- @components << component_class.new(self, params[0], *params[2..-1])
504
- else
505
- @components << component_class.new(self, params[0])
506
- end
507
-
508
- when 'PACKET'
509
- usage = "#{keyword} <target_name> <packet_name>"
510
- parser.verify_num_parameters(2, 2, usage)
511
- target_name = params[0].upcase
512
- packet_name = params[1].upcase
513
- @packets << [target_name, packet_name]
514
- @components[-1].add_packet(target_name, packet_name)
515
- index = target_name + ' ' + packet_name
516
- @packet_to_components_mapping[index] ||= []
517
- @packet_to_components_mapping[index] << @components[-1]
518
-
519
- # Unknown keyword
520
- else
521
- raise "Unhandled keyword: #{keyword}" if keyword
522
- end
523
- end
524
- end
525
-
526
- def delete_component(index)
527
- @component_mutex.synchronize do
528
- # Get the component to be deleted
529
- component = @components[index]
530
-
531
- # Delete from the components array
532
- @components.delete_at(index)
533
-
534
- # Delete from mapping
535
- @packet_to_components_mapping.each do |key, components|
536
- components.delete(component)
537
- end
538
- end
539
- end
540
-
541
- def enable_disable_component_packet(index, target_name, packet_name, enabled)
542
- @component_mutex.synchronize do
543
- # Get the component to be deleted
544
- component = @components[index]
545
-
546
- key = target_name + ' ' + packet_name
547
- if enabled
548
- # Add to mapping
549
- components = @packet_to_components_mapping[key]
550
- components << component unless components.include?(component)
551
- else
552
- # Delete from mapping
553
- components = @packet_to_components_mapping[key]
554
- components.delete(component)
555
- end
556
- end
557
- end
558
-
559
- # Handles deleting the current tab
560
- def on_tab_delete
561
- if @tab_book.currentIndex() and @tab_book.currentIndex() >= 0
562
- case Qt::MessageBox.warning(self, 'Warning!', "Are you sure you want to delete the active tab?", Qt::MessageBox::Yes | Qt::MessageBox::No, Qt::MessageBox::No)
563
- when Qt::MessageBox::Yes
564
- # Remove component
565
- tab_index = @tab_book.currentIndex()
566
- delete_component(tab_index)
567
- @tab_book.removeTab(tab_index)
568
-
569
- statusBar.showMessage(tr("Tab Deleted"))
570
- end
571
- else
572
- Qt::MessageBox.information(self, 'Info', "No tabs exist")
573
- end
574
- end # def on_tab_delete
575
-
576
- #############################
577
- # Class methods
578
- #############################
579
-
580
- def self.run(option_parser = nil, options = nil)
581
- Cosmos.catch_fatal_exception do
582
- unless option_parser and options
583
- option_parser, options = create_default_options()
584
- options.width = 550
585
- options.height = 500
586
- options.title = "Data Viewer"
587
- options.config_file = 'data_viewer.txt'
588
- option_parser.separator "Data Viewer Specific Options:"
589
- option_parser.on("-c", "--config FILE", "Use the specified configuration file") do |arg|
590
- options.config_file = arg
591
- end
592
- end
593
-
594
- super(option_parser, options)
595
- end
596
- end
597
-
598
- end # class DataViewer
599
-
600
- end # module Cosmos
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2014 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 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
+ require 'cosmos'
12
+ Cosmos.catch_fatal_exception do
13
+ require 'cosmos/script'
14
+ require 'cosmos/config/config_parser'
15
+ require 'cosmos/gui/qt_tool'
16
+ require 'cosmos/gui/dialogs/splash'
17
+ require 'cosmos/gui/dialogs/progress_dialog'
18
+ require 'cosmos/gui/dialogs/exception_dialog'
19
+ require 'cosmos/gui/dialogs/packet_log_dialog'
20
+ require 'cosmos/gui/dialogs/find_replace_dialog'
21
+ require 'cosmos/gui/widgets/realtime_button_bar'
22
+ require 'cosmos/tools/data_viewer/data_viewer_component'
23
+ require 'cosmos/tools/data_viewer/dump_component'
24
+ end
25
+
26
+ module Cosmos
27
+
28
+ class DataViewer < QtTool
29
+ slots 'context_menu(const QPoint&)'
30
+ slots 'handle_tab_change(int)'
31
+
32
+ def initialize(options)
33
+ super(options) # MUST BE FIRST - All code before super is executed twice in RubyQt Based classes
34
+ Cosmos.load_cosmos_icon("data_viewer.png")
35
+
36
+ initialize_actions()
37
+ initialize_menus()
38
+ initialize_central_widget()
39
+ complete_initialize()
40
+
41
+ # Initialize instance variables
42
+ @auto_start = false
43
+ @pause = false
44
+ @log_file_directory = System.paths['LOGS']
45
+ @tlm_log_system = nil
46
+ @subscription_thread = nil
47
+ @subscription_id = nil
48
+ @packet_log_reader = System.default_packet_log_reader.new
49
+ @time_start = nil
50
+ @time_end = nil
51
+ @log_filenames = []
52
+ @cancel_thread = false
53
+ @sleeper = Sleeper.new
54
+
55
+ # Process config file and create a tab for each data viewer component
56
+ @component_mutex = Mutex.new
57
+ @components = []
58
+ @packets = []
59
+ @packet_to_components_mapping = {}
60
+ @config_filename = File.join(Cosmos::USERPATH, 'config', 'tools', 'data_viewer', options.config_file)
61
+ process_config()
62
+
63
+ # Load System Definition and Event Data
64
+ Splash.execute(self) do |splash|
65
+ Qt.execute_in_main_thread(true) do
66
+ ConfigParser.splash = splash
67
+ System.telemetry
68
+ @components.each do |component|
69
+ # Create tab for each component
70
+ component.initialize_gui
71
+ @tab_book.addTab(component, component.tab_name)
72
+ end
73
+ if @auto_start
74
+ handle_start()
75
+ end
76
+ ConfigParser.splash = nil
77
+ end
78
+ end
79
+
80
+ # Add GUI Update Timeout
81
+ @timer = Qt::Timer.new(self)
82
+ @timer.connect(SIGNAL('timeout()')) { update_gui() }
83
+ @timer.method_missing(:start, 100)
84
+ end
85
+
86
+ def initialize_actions
87
+ super()
88
+
89
+ # File Menu Actions
90
+ @open_log = Qt::Action.new(tr('&Open Log File'), self)
91
+ @open_log_keyseq = Qt::KeySequence.new(tr('Ctrl+O'))
92
+ @open_log.shortcut = @open_log_keyseq
93
+ @open_log.statusTip = tr('Open telemetry log file for processing')
94
+ @open_log.connect(SIGNAL('triggered()')) { handle_open_log_file() }
95
+
96
+ @handle_reset = Qt::Action.new(tr('&Reset'), self)
97
+ @handle_reset_keyseq = Qt::KeySequence.new(tr('Ctrl+R'))
98
+ @handle_reset.shortcut = @handle_reset_keyseq
99
+ @handle_reset.statusTip = tr('Reset Components')
100
+ @handle_reset.connect(SIGNAL('triggered()')) { handle_reset() }
101
+
102
+ # Search Actions
103
+ @search_find = Qt::Action.new(Cosmos.get_icon('search.png'), tr('&Find'), self)
104
+ @search_find_keyseq = Qt::KeySequence.new(tr('Ctrl+F'))
105
+ @search_find.shortcut = @search_find_keyseq
106
+ @search_find.statusTip = tr('Find text')
107
+ @search_find.connect(SIGNAL('triggered()')) { find() }
108
+
109
+ @search_find_next = Qt::Action.new(tr('Find &Next'), self)
110
+ @search_find_next_keyseq = Qt::KeySequence.new(tr('F3'))
111
+ @search_find_next.shortcut = @search_find_next_keyseq
112
+ @search_find_next.statusTip = tr('Find next instance')
113
+ @search_find_next.connect(SIGNAL('triggered()')) { find_next() }
114
+
115
+ @search_find_previous = Qt::Action.new(tr('Find &Previous'), self)
116
+ @search_find_previous_keyseq = Qt::KeySequence.new(tr('Shift+F3'))
117
+ @search_find_previous.shortcut = @search_find_previous_keyseq
118
+ @search_find_previous.statusTip = tr('Find previous instance')
119
+ @search_find_previous.connect(SIGNAL('triggered()')) { find_previous() }
120
+
121
+ # Tab Menu Actions
122
+ @delete_tab = Qt::Action.new(Cosmos.get_icon('delete_tab.png'), tr('&Delete Tab'), self)
123
+ @delete_tab.statusTip = tr('Delete active tab')
124
+ @delete_tab.connect(SIGNAL('triggered()')) { on_tab_delete() }
125
+ end
126
+
127
+ def initialize_menus
128
+ # File Menu
129
+ file_menu = menuBar.addMenu(tr('&File'))
130
+ file_menu.addAction(@open_log)
131
+ file_menu.addAction(@handle_reset)
132
+ file_menu.addSeparator()
133
+ file_menu.addAction(@exit_action)
134
+
135
+ # Tab Menu
136
+ @tab_menu = menuBar.addMenu(tr('&Tab'))
137
+ @tab_menu.addAction(@delete_tab)
138
+ @tab_menu.addSeparator()
139
+ @tab_menu_actions = []
140
+
141
+ # Search Menu
142
+ view_menu = menuBar.addMenu(tr('&Search'))
143
+ view_menu.addAction(@search_find)
144
+ view_menu.addAction(@search_find_next)
145
+ view_menu.addAction(@search_find_previous)
146
+
147
+ # Help Menu
148
+ @about_string = "Data Viewer is designed to allow users view data that is not easily displayed on telemetry screens."
149
+ initialize_help_menu()
150
+ end
151
+
152
+ def initialize_central_widget
153
+ # Create the central widget
154
+ @central_widget = Qt::Widget.new
155
+ setCentralWidget(@central_widget)
156
+
157
+ # Create the top level vertical layout
158
+ @top_layout = Qt::VBoxLayout.new(@central_widget)
159
+
160
+ # Realtime Button Bar
161
+ @realtime_button_bar = RealtimeButtonBar.new(self)
162
+ @realtime_button_bar.start_callback = method(:handle_start)
163
+ @realtime_button_bar.pause_callback = method(:handle_pause)
164
+ @realtime_button_bar.stop_callback = method(:handle_stop)
165
+ @realtime_button_bar.state = 'Stopped'
166
+ @top_layout.addWidget(@realtime_button_bar)
167
+
168
+ # Create tab book
169
+ @tab_book = Qt::TabWidget.new
170
+ @tab_book.setContextMenuPolicy(Qt::CustomContextMenu)
171
+ connect(@tab_book, SIGNAL('currentChanged(int)'), self, SLOT('handle_tab_change(int)'))
172
+ connect(@tab_book, SIGNAL('customContextMenuRequested(const QPoint&)'), self, SLOT('context_menu(const QPoint&)'))
173
+ @top_layout.addWidget(@tab_book)
174
+ end
175
+
176
+ def current_component
177
+ @component_mutex.synchronize do
178
+ yield @components[@tab_book.currentIndex()]
179
+ end
180
+ end
181
+
182
+ def find
183
+ unless @find_dialog
184
+ @find_dialog = FindReplaceDialog.new(@script, false)
185
+ @find_dialog.connect(SIGNAL('find_next()')) do
186
+ current_component do |component|
187
+ component.find(@find_dialog)
188
+ end
189
+ end
190
+ end
191
+ @find_dialog.show
192
+ @find_dialog.raise
193
+ @find_dialog.activateWindow
194
+ end
195
+
196
+ def find_next
197
+ current_component do |component|
198
+ component.find_next(@find_dialog) if @find_dialog
199
+ end
200
+ end
201
+
202
+ def find_previous
203
+ current_component do |component|
204
+ component.find_previous(@find_dialog) if @find_dialog
205
+ end
206
+ end
207
+
208
+ def handle_tab_change(index)
209
+ # Remove existing actions
210
+ @tab_menu_actions.each do |action|
211
+ @tab_menu.removeAction(action)
212
+ action.dispose
213
+ end
214
+ @tab_menu_actions = []
215
+
216
+ # Add new actions
217
+ unless @components.empty?
218
+ @component_mutex.synchronize do
219
+ component = @components[index]
220
+ component.packets.each do |target_name, packet_name|
221
+ action = Qt::Action.new("#{target_name} #{packet_name}", @tab_menu)
222
+ action.setCheckable(true)
223
+ key = target_name + ' ' + packet_name
224
+ components = @packet_to_components_mapping[key]
225
+ if components.include?(component)
226
+ action.setChecked(true)
227
+ else
228
+ action.setChecked(false)
229
+ end
230
+ action.connect(SIGNAL('triggered()')) { enable_disable_component_packet(index, target_name, packet_name, action.checked?) }
231
+ @tab_menu.addAction(action)
232
+ @tab_menu_actions << action
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ def context_menu(point)
239
+ index = 0
240
+ (0..@tab_book.tabBar.count).each do |i|
241
+ index = i if @tab_book.tabBar.tabRect(i).contains(point)
242
+ end
243
+
244
+ return if (index == @tab_book.tabBar.count)
245
+
246
+ # Bring the right clicked tab to the front
247
+ @tab_book.setCurrentIndex(index)
248
+ @tab_menu.exec(@tab_book.mapToGlobal(point))
249
+ end
250
+
251
+ def start_subscription_thread
252
+ unless @subscription_thread
253
+ # Start Thread to Gather Events
254
+ @subscription_thread = Thread.new do
255
+ @cancel_thread = false
256
+ @sleeper = Sleeper.new
257
+ if !@packets.empty?
258
+ begin
259
+ while true
260
+ break if @cancel_thread
261
+ begin
262
+ @subscription_id = subscribe_packet_data(@packets, 10000)
263
+ break if @cancel_thread
264
+ if @pause
265
+ Qt.execute_in_main_thread(true) { @realtime_button_bar.state = 'Paused' }
266
+ else
267
+ Qt.execute_in_main_thread(true) { @realtime_button_bar.state = 'Running' }
268
+ end
269
+ Qt.execute_in_main_thread(true) { statusBar.showMessage("Connected to Command and Telemetry Server: #{Time.now.formatted}") }
270
+ rescue DRb::DRbConnError
271
+ break if @cancel_thread
272
+ Qt.execute_in_main_thread(true) do
273
+ @realtime_button_bar.state = 'Connecting'
274
+ statusBar.showMessage(tr("Error Connecting to Command and Telemetry Server"))
275
+ end
276
+ break if @sleeper.sleep(1)
277
+ break if @cancel_thread
278
+ retry
279
+ end
280
+
281
+ while true
282
+ break if @cancel_thread
283
+ begin
284
+ # Get a subscribed to packet
285
+ packet_data, target_name, packet_name, received_time, received_count = get_packet_data(@subscription_id)
286
+
287
+ # Put packet data into its packet
288
+ packet = System.telemetry.packet(target_name, packet_name)
289
+ packet.buffer = packet_data
290
+ packet.received_time = received_time
291
+ packet.received_count = received_count
292
+
293
+ # Route packet to its component(s)
294
+ index = packet.target_name + ' ' + packet.packet_name
295
+ @component_mutex.synchronize do
296
+ components = @packet_to_components_mapping[index]
297
+ if components
298
+ components.each do |component|
299
+ component.process_packet(packet)
300
+ end
301
+ end
302
+ end
303
+ rescue DRb::DRbConnError
304
+ break if @cancel_thread
305
+ Qt.execute_in_main_thread(true) { statusBar.showMessage(tr("Error Connecting to Command and Telemetry Server")) }
306
+ break # Let outer loop resubscribe
307
+ rescue RuntimeError => error
308
+ raise error unless error.message =~ /queue/
309
+ break if @cancel_thread
310
+ Qt.execute_in_main_thread(true) { statusBar.showMessage(tr("Connection Dropped by Command and Telemetry Server: #{Time.now.formatted}")) }
311
+ break # Let outer loop resubscribe
312
+ end
313
+ end
314
+ end
315
+ rescue Exception => error
316
+ break if @cancel_thread
317
+ Qt.execute_in_main_thread(true) {|| ExceptionDialog.new(self, error, "Data Viewer : Subscription Thread")}
318
+ end
319
+ end # if !@packets.empty
320
+ end
321
+ else
322
+ Qt.execute_in_main_thread(true) { @realtime_button_bar.state = 'Running' }
323
+ end
324
+ end
325
+
326
+ def kill_subscription_thread
327
+ Cosmos.kill_thread(self, @subscription_thread)
328
+ @subscription_thread = nil
329
+ end
330
+
331
+ def graceful_kill
332
+ @cancel_thread = true
333
+ @sleeper.cancel
334
+ script_disconnect() # This will break out of get_packet_data
335
+ Qt::CoreApplication.processEvents
336
+ end
337
+
338
+ def handle_reset
339
+ @component_mutex.synchronize do
340
+ @components.each do |component|
341
+ component.reset
342
+ end
343
+ end
344
+ System.telemetry.reset
345
+ end
346
+
347
+ def handle_start
348
+ if windowTitle() != 'Data Viewer'
349
+ # Clear Title
350
+ setWindowTitle('Data Viewer')
351
+
352
+ # Return to default configuration
353
+ # Show splash during possible reconfiguration
354
+ Splash.execute(self) do |splash|
355
+ ConfigParser.splash = splash
356
+ System.load_configuration
357
+ ConfigParser.splash = nil
358
+ end
359
+
360
+ # Reset Components
361
+ handle_reset()
362
+ end
363
+
364
+ # Restart GUI Updates if necessary
365
+ if @pause
366
+ @pause = false
367
+ @timer.method_missing(:start, 100)
368
+ end
369
+
370
+ # Restart Subscription Thread if necessary
371
+ start_subscription_thread()
372
+ end
373
+
374
+ def handle_pause
375
+ @pause = true
376
+ if @subscription_thread
377
+ @realtime_button_bar.state = 'Paused'
378
+ end
379
+ end
380
+
381
+ def handle_stop
382
+ # Shutdown packet subscription thread
383
+ kill_subscription_thread()
384
+
385
+ # Unsubscribe from subscription
386
+ if @subscription_id
387
+ begin
388
+ unsubscribe_packet_data(@subscription_id)
389
+ rescue DRb::DRbConnError
390
+ # Do Nothing
391
+ end
392
+ end
393
+
394
+ # Restart GUI Updates if necessary
395
+ if @pause
396
+ @pause = false
397
+ @timer.method_missing(:start, 100)
398
+ end
399
+
400
+ @realtime_button_bar.state = 'Stopped'
401
+ end
402
+
403
+ def handle_open_log_file
404
+ # Prompt user for filename
405
+ packet_log_dialog = PacketLogDialog.new(self, 'Open Log File(s):', @log_file_directory, @packet_log_reader, [], nil, false, true, true, Cosmos::TLM_FILE_PATTERN)
406
+ begin
407
+ packet_log_dialog.time_start = @time_start
408
+ packet_log_dialog.time_end = @time_end
409
+ case packet_log_dialog.exec
410
+ when Qt::Dialog::Accepted
411
+ @packet_log_reader = packet_log_dialog.packet_log_reader
412
+ @log_filenames = packet_log_dialog.filenames.sort
413
+ @time_start = packet_log_dialog.time_start
414
+ @time_end = packet_log_dialog.time_end
415
+ @log_file_directory = File.dirname(@log_filenames[0])
416
+ @log_file_directory += '/' unless @log_file_directory[-1..-1] == '\\'
417
+
418
+ # Stop realtime collection
419
+ handle_stop()
420
+
421
+ # Reset components
422
+ handle_reset()
423
+
424
+ @cancel_progress = false
425
+ ProgressDialog.execute(self, 'Processing Log File', 500, 200, @log_filenames.length > 1, true, true, true, true) do |dialog|
426
+ dialog.cancel_callback = method(:cancel_callback)
427
+ dialog.enable_cancel_button
428
+
429
+ @log_filenames.each_with_index do |filename, file_index|
430
+ break if @cancel_progress
431
+ Qt.execute_in_main_thread(true) do
432
+ self.setWindowTitle("Data Viewer : #{filename}")
433
+ end
434
+
435
+ file_size = File.size(filename).to_f
436
+ dialog.append_text("Processing: #{filename}")
437
+
438
+ @packet_log_reader.each(filename, true, @time_start, @time_end) do |packet|
439
+ break if @cancel_progress
440
+ progress = @packet_log_reader.bytes_read.to_f / file_size
441
+ dialog.set_step_progress(progress)
442
+
443
+ # Route packet to its component(s)
444
+ index = packet.target_name + ' ' + packet.packet_name
445
+ components = @packet_to_components_mapping[index]
446
+ if components
447
+ @component_mutex.synchronize do
448
+ components.each do |component|
449
+ component.process_packet(packet)
450
+ end
451
+ end
452
+ end
453
+ end
454
+
455
+ dialog.set_overall_progress((file_index + 1).to_f / @log_filenames.length) if @log_filenames.length > 1
456
+ end
457
+
458
+ dialog.append_text("Done!")
459
+ dialog.set_step_progress(1.0)
460
+ dialog.set_overall_progress(1.0) if @log_filenames.length > 1
461
+ dialog.complete
462
+ end
463
+ end
464
+ ensure
465
+ packet_log_dialog.dispose if packet_log_dialog
466
+ end
467
+ end
468
+
469
+ def cancel_callback(progress_dialog = nil)
470
+ @cancel_progress = true
471
+ return true, false
472
+ end
473
+
474
+ def update_gui
475
+ if @pause
476
+ @timer.method_missing(:stop)
477
+ else
478
+ Qt.execute_in_main_thread(true) do
479
+ @component_mutex.synchronize do
480
+ @components.each do |component|
481
+ break if @pause
482
+ component.update_gui
483
+ end
484
+ end
485
+ end
486
+ end
487
+ end
488
+
489
+ def closeEvent(event)
490
+ # Stop GUI update timeout
491
+ @pause = true
492
+
493
+ # Stop Processing Packets
494
+ handle_stop()
495
+
496
+ # Shutdown each component
497
+ @component_mutex.synchronize do
498
+ @components.each {|component| component.shutdown}
499
+ end
500
+
501
+ # Give things time to complete
502
+ sleep(0.1)
503
+
504
+ # Standard COSMOS Shutdown
505
+ shutdown_cmd_tlm()
506
+
507
+ # Accept closure
508
+ super(event)
509
+ end
510
+
511
+ def process_config
512
+ # ensure the file exists
513
+ unless test ?f, @config_filename
514
+ raise "Configuration File Does not Exist: #{@config_filename}"
515
+ end
516
+
517
+ parser = ConfigParser.new
518
+ parser.parse_file(@config_filename) do |keyword, params|
519
+ case keyword
520
+
521
+ when 'AUTO_START'
522
+ usage = "#{keyword}"
523
+ parser.verify_num_parameters(0, 0, usage)
524
+ @auto_start = true
525
+
526
+ when 'COMPONENT'
527
+ usage = "#{keyword} <tab name> <component class filename> <component specific options...>"
528
+ parser.verify_num_parameters(2, nil, usage)
529
+ component_class = Cosmos.require_class(params[1])
530
+ if params.length >= 3
531
+ @components << component_class.new(self, params[0], *params[2..-1])
532
+ else
533
+ @components << component_class.new(self, params[0])
534
+ end
535
+
536
+ when 'PACKET'
537
+ usage = "#{keyword} <target_name> <packet_name>"
538
+ parser.verify_num_parameters(2, 2, usage)
539
+ target_name = params[0].upcase
540
+ packet_name = params[1].upcase
541
+ @packets << [target_name, packet_name]
542
+ @components[-1].add_packet(target_name, packet_name)
543
+ index = target_name + ' ' + packet_name
544
+ @packet_to_components_mapping[index] ||= []
545
+ @packet_to_components_mapping[index] << @components[-1]
546
+
547
+ # Unknown keyword
548
+ else
549
+ raise "Unhandled keyword: #{keyword}" if keyword
550
+ end
551
+ end
552
+ end
553
+
554
+ def delete_component(index)
555
+ @component_mutex.synchronize do
556
+ # Get the component to be deleted
557
+ component = @components[index]
558
+
559
+ # Delete from the components array
560
+ @components.delete_at(index)
561
+
562
+ # Delete from mapping
563
+ @packet_to_components_mapping.each do |key, components|
564
+ components.delete(component)
565
+ end
566
+ end
567
+ end
568
+
569
+ def enable_disable_component_packet(index, target_name, packet_name, enabled)
570
+ @component_mutex.synchronize do
571
+ # Get the component to be deleted
572
+ component = @components[index]
573
+
574
+ key = target_name + ' ' + packet_name
575
+ if enabled
576
+ # Add to mapping
577
+ components = @packet_to_components_mapping[key]
578
+ components << component unless components.include?(component)
579
+ else
580
+ # Delete from mapping
581
+ components = @packet_to_components_mapping[key]
582
+ components.delete(component)
583
+ end
584
+ end
585
+ end
586
+
587
+ # Handles deleting the current tab
588
+ def on_tab_delete
589
+ if @tab_book.currentIndex() and @tab_book.currentIndex() >= 0
590
+ case Qt::MessageBox.warning(self, 'Warning!', "Are you sure you want to delete the active tab?", Qt::MessageBox::Yes | Qt::MessageBox::No, Qt::MessageBox::No)
591
+ when Qt::MessageBox::Yes
592
+ # Remove component
593
+ tab_index = @tab_book.currentIndex()
594
+ delete_component(tab_index)
595
+ @tab_book.removeTab(tab_index)
596
+
597
+ statusBar.showMessage(tr("Tab Deleted"))
598
+ end
599
+ else
600
+ Qt::MessageBox.information(self, 'Info', "No tabs exist")
601
+ end
602
+ end # def on_tab_delete
603
+
604
+ #############################
605
+ # Class methods
606
+ #############################
607
+
608
+ def self.run(option_parser = nil, options = nil)
609
+ Cosmos.catch_fatal_exception do
610
+ unless option_parser and options
611
+ option_parser, options = create_default_options()
612
+ options.width = 550
613
+ options.height = 500
614
+ options.title = "Data Viewer"
615
+ options.config_file = 'data_viewer.txt'
616
+ option_parser.separator "Data Viewer Specific Options:"
617
+ option_parser.on("-c", "--config FILE", "Use the specified configuration file") do |arg|
618
+ options.config_file = arg
619
+ end
620
+ end
621
+
622
+ super(option_parser, options)
623
+ end
624
+ end
625
+
626
+ end # class DataViewer
627
+
628
+ end # module Cosmos