sierra-research 1.3.11__py3-none-any.whl → 1.5.0__py3-none-any.whl

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 (254) hide show
  1. sierra/__init__.py +3 -3
  2. sierra/core/__init__.py +3 -3
  3. sierra/core/batchroot.py +223 -0
  4. sierra/core/cmdline.py +681 -1057
  5. sierra/core/compare.py +11 -0
  6. sierra/core/config.py +96 -88
  7. sierra/core/engine.py +306 -0
  8. sierra/core/execenv.py +380 -0
  9. sierra/core/expdef.py +11 -0
  10. sierra/core/experiment/__init__.py +1 -0
  11. sierra/core/experiment/bindings.py +150 -101
  12. sierra/core/experiment/definition.py +414 -245
  13. sierra/core/experiment/spec.py +83 -85
  14. sierra/core/exproot.py +44 -0
  15. sierra/core/generators/__init__.py +10 -0
  16. sierra/core/generators/experiment.py +528 -0
  17. sierra/core/generators/generator_factory.py +138 -137
  18. sierra/core/graphs/__init__.py +23 -0
  19. sierra/core/graphs/bcbridge.py +94 -0
  20. sierra/core/graphs/heatmap.py +245 -324
  21. sierra/core/graphs/pathset.py +27 -0
  22. sierra/core/graphs/schema.py +77 -0
  23. sierra/core/graphs/stacked_line.py +341 -0
  24. sierra/core/graphs/summary_line.py +506 -0
  25. sierra/core/logging.py +3 -2
  26. sierra/core/models/__init__.py +3 -1
  27. sierra/core/models/info.py +19 -0
  28. sierra/core/models/interface.py +52 -122
  29. sierra/core/pipeline/__init__.py +2 -5
  30. sierra/core/pipeline/pipeline.py +228 -126
  31. sierra/core/pipeline/stage1/__init__.py +10 -0
  32. sierra/core/pipeline/stage1/pipeline_stage1.py +45 -31
  33. sierra/core/pipeline/stage2/__init__.py +10 -0
  34. sierra/core/pipeline/stage2/pipeline_stage2.py +8 -11
  35. sierra/core/pipeline/stage2/runner.py +401 -0
  36. sierra/core/pipeline/stage3/__init__.py +12 -0
  37. sierra/core/pipeline/stage3/gather.py +321 -0
  38. sierra/core/pipeline/stage3/pipeline_stage3.py +37 -84
  39. sierra/core/pipeline/stage4/__init__.py +12 -2
  40. sierra/core/pipeline/stage4/pipeline_stage4.py +36 -354
  41. sierra/core/pipeline/stage5/__init__.py +12 -0
  42. sierra/core/pipeline/stage5/pipeline_stage5.py +33 -208
  43. sierra/core/pipeline/yaml.py +48 -0
  44. sierra/core/plugin.py +529 -62
  45. sierra/core/proc.py +11 -0
  46. sierra/core/prod.py +11 -0
  47. sierra/core/ros1/__init__.py +5 -1
  48. sierra/core/ros1/callbacks.py +22 -21
  49. sierra/core/ros1/cmdline.py +59 -88
  50. sierra/core/ros1/generators.py +159 -175
  51. sierra/core/ros1/variables/__init__.py +3 -0
  52. sierra/core/ros1/variables/exp_setup.py +122 -116
  53. sierra/core/startup.py +106 -76
  54. sierra/core/stat_kernels.py +4 -5
  55. sierra/core/storage.py +13 -32
  56. sierra/core/trampoline.py +30 -0
  57. sierra/core/types.py +116 -71
  58. sierra/core/utils.py +103 -106
  59. sierra/core/variables/__init__.py +1 -1
  60. sierra/core/variables/base_variable.py +12 -17
  61. sierra/core/variables/batch_criteria.py +387 -481
  62. sierra/core/variables/builtin.py +135 -0
  63. sierra/core/variables/exp_setup.py +19 -39
  64. sierra/core/variables/population_size.py +72 -76
  65. sierra/core/variables/variable_density.py +44 -68
  66. sierra/core/vector.py +1 -1
  67. sierra/main.py +256 -88
  68. sierra/plugins/__init__.py +119 -0
  69. sierra/plugins/compare/__init__.py +14 -0
  70. sierra/plugins/compare/graphs/__init__.py +19 -0
  71. sierra/plugins/compare/graphs/cmdline.py +120 -0
  72. sierra/plugins/compare/graphs/comparator.py +291 -0
  73. sierra/plugins/compare/graphs/inter_controller.py +531 -0
  74. sierra/plugins/compare/graphs/inter_scenario.py +297 -0
  75. sierra/plugins/compare/graphs/namecalc.py +53 -0
  76. sierra/plugins/compare/graphs/outputroot.py +73 -0
  77. sierra/plugins/compare/graphs/plugin.py +147 -0
  78. sierra/plugins/compare/graphs/preprocess.py +172 -0
  79. sierra/plugins/compare/graphs/schema.py +37 -0
  80. sierra/plugins/engine/__init__.py +14 -0
  81. sierra/plugins/engine/argos/__init__.py +18 -0
  82. sierra/plugins/{platform → engine}/argos/cmdline.py +144 -151
  83. sierra/plugins/{platform/argos/variables → engine/argos/generators}/__init__.py +5 -0
  84. sierra/plugins/engine/argos/generators/engine.py +394 -0
  85. sierra/plugins/engine/argos/plugin.py +393 -0
  86. sierra/plugins/{platform/argos/generators → engine/argos/variables}/__init__.py +5 -0
  87. sierra/plugins/engine/argos/variables/arena_shape.py +183 -0
  88. sierra/plugins/engine/argos/variables/cameras.py +240 -0
  89. sierra/plugins/engine/argos/variables/constant_density.py +112 -0
  90. sierra/plugins/engine/argos/variables/exp_setup.py +82 -0
  91. sierra/plugins/{platform → engine}/argos/variables/physics_engines.py +83 -87
  92. sierra/plugins/engine/argos/variables/population_constant_density.py +178 -0
  93. sierra/plugins/engine/argos/variables/population_size.py +115 -0
  94. sierra/plugins/engine/argos/variables/population_variable_density.py +123 -0
  95. sierra/plugins/engine/argos/variables/rendering.py +108 -0
  96. sierra/plugins/engine/ros1gazebo/__init__.py +18 -0
  97. sierra/plugins/engine/ros1gazebo/cmdline.py +175 -0
  98. sierra/plugins/{platform/ros1robot → engine/ros1gazebo}/generators/__init__.py +5 -0
  99. sierra/plugins/engine/ros1gazebo/generators/engine.py +125 -0
  100. sierra/plugins/engine/ros1gazebo/plugin.py +404 -0
  101. sierra/plugins/engine/ros1gazebo/variables/__init__.py +15 -0
  102. sierra/plugins/engine/ros1gazebo/variables/population_size.py +214 -0
  103. sierra/plugins/engine/ros1robot/__init__.py +18 -0
  104. sierra/plugins/engine/ros1robot/cmdline.py +159 -0
  105. sierra/plugins/{platform/ros1gazebo → engine/ros1robot}/generators/__init__.py +4 -0
  106. sierra/plugins/engine/ros1robot/generators/engine.py +95 -0
  107. sierra/plugins/engine/ros1robot/plugin.py +410 -0
  108. sierra/plugins/{hpc/local → engine/ros1robot/variables}/__init__.py +5 -0
  109. sierra/plugins/engine/ros1robot/variables/population_size.py +146 -0
  110. sierra/plugins/execenv/__init__.py +11 -0
  111. sierra/plugins/execenv/hpc/__init__.py +18 -0
  112. sierra/plugins/execenv/hpc/adhoc/__init__.py +18 -0
  113. sierra/plugins/execenv/hpc/adhoc/cmdline.py +30 -0
  114. sierra/plugins/execenv/hpc/adhoc/plugin.py +131 -0
  115. sierra/plugins/execenv/hpc/cmdline.py +137 -0
  116. sierra/plugins/execenv/hpc/local/__init__.py +18 -0
  117. sierra/plugins/execenv/hpc/local/cmdline.py +31 -0
  118. sierra/plugins/execenv/hpc/local/plugin.py +145 -0
  119. sierra/plugins/execenv/hpc/pbs/__init__.py +18 -0
  120. sierra/plugins/execenv/hpc/pbs/cmdline.py +30 -0
  121. sierra/plugins/execenv/hpc/pbs/plugin.py +121 -0
  122. sierra/plugins/execenv/hpc/slurm/__init__.py +18 -0
  123. sierra/plugins/execenv/hpc/slurm/cmdline.py +30 -0
  124. sierra/plugins/execenv/hpc/slurm/plugin.py +133 -0
  125. sierra/plugins/execenv/prefectserver/__init__.py +18 -0
  126. sierra/plugins/execenv/prefectserver/cmdline.py +66 -0
  127. sierra/plugins/execenv/prefectserver/dockerremote/__init__.py +18 -0
  128. sierra/plugins/execenv/prefectserver/dockerremote/cmdline.py +66 -0
  129. sierra/plugins/execenv/prefectserver/dockerremote/plugin.py +132 -0
  130. sierra/plugins/execenv/prefectserver/flow.py +66 -0
  131. sierra/plugins/execenv/prefectserver/local/__init__.py +18 -0
  132. sierra/plugins/execenv/prefectserver/local/cmdline.py +29 -0
  133. sierra/plugins/execenv/prefectserver/local/plugin.py +133 -0
  134. sierra/plugins/{hpc/adhoc → execenv/robot}/__init__.py +1 -0
  135. sierra/plugins/execenv/robot/turtlebot3/__init__.py +18 -0
  136. sierra/plugins/execenv/robot/turtlebot3/plugin.py +204 -0
  137. sierra/plugins/expdef/__init__.py +14 -0
  138. sierra/plugins/expdef/json/__init__.py +14 -0
  139. sierra/plugins/expdef/json/plugin.py +504 -0
  140. sierra/plugins/expdef/xml/__init__.py +14 -0
  141. sierra/plugins/expdef/xml/plugin.py +386 -0
  142. sierra/{core/hpc → plugins/proc}/__init__.py +1 -1
  143. sierra/plugins/proc/collate/__init__.py +15 -0
  144. sierra/plugins/proc/collate/cmdline.py +47 -0
  145. sierra/plugins/proc/collate/plugin.py +271 -0
  146. sierra/plugins/proc/compress/__init__.py +18 -0
  147. sierra/plugins/proc/compress/cmdline.py +47 -0
  148. sierra/plugins/proc/compress/plugin.py +123 -0
  149. sierra/plugins/proc/decompress/__init__.py +18 -0
  150. sierra/plugins/proc/decompress/plugin.py +96 -0
  151. sierra/plugins/proc/imagize/__init__.py +15 -0
  152. sierra/plugins/proc/imagize/cmdline.py +49 -0
  153. sierra/plugins/proc/imagize/plugin.py +270 -0
  154. sierra/plugins/proc/modelrunner/__init__.py +16 -0
  155. sierra/plugins/proc/modelrunner/plugin.py +250 -0
  156. sierra/plugins/proc/statistics/__init__.py +15 -0
  157. sierra/plugins/proc/statistics/cmdline.py +64 -0
  158. sierra/plugins/proc/statistics/plugin.py +390 -0
  159. sierra/plugins/{hpc → prod}/__init__.py +1 -0
  160. sierra/plugins/prod/graphs/__init__.py +18 -0
  161. sierra/plugins/prod/graphs/cmdline.py +269 -0
  162. sierra/plugins/prod/graphs/collate.py +279 -0
  163. sierra/plugins/prod/graphs/inter/__init__.py +13 -0
  164. sierra/plugins/prod/graphs/inter/generate.py +83 -0
  165. sierra/plugins/prod/graphs/inter/heatmap.py +86 -0
  166. sierra/plugins/prod/graphs/inter/line.py +134 -0
  167. sierra/plugins/prod/graphs/intra/__init__.py +15 -0
  168. sierra/plugins/prod/graphs/intra/generate.py +202 -0
  169. sierra/plugins/prod/graphs/intra/heatmap.py +74 -0
  170. sierra/plugins/prod/graphs/intra/line.py +114 -0
  171. sierra/plugins/prod/graphs/plugin.py +103 -0
  172. sierra/plugins/prod/graphs/targets.py +63 -0
  173. sierra/plugins/prod/render/__init__.py +18 -0
  174. sierra/plugins/prod/render/cmdline.py +72 -0
  175. sierra/plugins/prod/render/plugin.py +282 -0
  176. sierra/plugins/storage/__init__.py +5 -0
  177. sierra/plugins/storage/arrow/__init__.py +18 -0
  178. sierra/plugins/storage/arrow/plugin.py +38 -0
  179. sierra/plugins/storage/csv/__init__.py +9 -0
  180. sierra/plugins/storage/csv/plugin.py +12 -5
  181. sierra/version.py +3 -2
  182. sierra_research-1.5.0.dist-info/METADATA +238 -0
  183. sierra_research-1.5.0.dist-info/RECORD +186 -0
  184. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/WHEEL +1 -2
  185. sierra/core/experiment/xml.py +0 -454
  186. sierra/core/generators/controller_generator_parser.py +0 -34
  187. sierra/core/generators/exp_creator.py +0 -351
  188. sierra/core/generators/exp_generators.py +0 -142
  189. sierra/core/graphs/scatterplot2D.py +0 -109
  190. sierra/core/graphs/stacked_line_graph.py +0 -251
  191. sierra/core/graphs/stacked_surface_graph.py +0 -220
  192. sierra/core/graphs/summary_line_graph.py +0 -371
  193. sierra/core/hpc/cmdline.py +0 -142
  194. sierra/core/models/graphs.py +0 -87
  195. sierra/core/pipeline/stage2/exp_runner.py +0 -286
  196. sierra/core/pipeline/stage3/imagizer.py +0 -149
  197. sierra/core/pipeline/stage3/run_collator.py +0 -317
  198. sierra/core/pipeline/stage3/statistics_calculator.py +0 -478
  199. sierra/core/pipeline/stage4/graph_collator.py +0 -320
  200. sierra/core/pipeline/stage4/inter_exp_graph_generator.py +0 -240
  201. sierra/core/pipeline/stage4/intra_exp_graph_generator.py +0 -317
  202. sierra/core/pipeline/stage4/model_runner.py +0 -168
  203. sierra/core/pipeline/stage4/rendering.py +0 -283
  204. sierra/core/pipeline/stage4/yaml_config_loader.py +0 -103
  205. sierra/core/pipeline/stage5/inter_scenario_comparator.py +0 -328
  206. sierra/core/pipeline/stage5/intra_scenario_comparator.py +0 -989
  207. sierra/core/platform.py +0 -493
  208. sierra/core/plugin_manager.py +0 -369
  209. sierra/core/root_dirpath_generator.py +0 -241
  210. sierra/plugins/hpc/adhoc/plugin.py +0 -125
  211. sierra/plugins/hpc/local/plugin.py +0 -81
  212. sierra/plugins/hpc/pbs/__init__.py +0 -9
  213. sierra/plugins/hpc/pbs/plugin.py +0 -126
  214. sierra/plugins/hpc/slurm/__init__.py +0 -9
  215. sierra/plugins/hpc/slurm/plugin.py +0 -130
  216. sierra/plugins/platform/__init__.py +0 -9
  217. sierra/plugins/platform/argos/__init__.py +0 -9
  218. sierra/plugins/platform/argos/generators/platform_generators.py +0 -383
  219. sierra/plugins/platform/argos/plugin.py +0 -337
  220. sierra/plugins/platform/argos/variables/arena_shape.py +0 -145
  221. sierra/plugins/platform/argos/variables/cameras.py +0 -243
  222. sierra/plugins/platform/argos/variables/constant_density.py +0 -136
  223. sierra/plugins/platform/argos/variables/exp_setup.py +0 -113
  224. sierra/plugins/platform/argos/variables/population_constant_density.py +0 -175
  225. sierra/plugins/platform/argos/variables/population_size.py +0 -102
  226. sierra/plugins/platform/argos/variables/population_variable_density.py +0 -132
  227. sierra/plugins/platform/argos/variables/rendering.py +0 -104
  228. sierra/plugins/platform/ros1gazebo/__init__.py +0 -9
  229. sierra/plugins/platform/ros1gazebo/cmdline.py +0 -213
  230. sierra/plugins/platform/ros1gazebo/generators/platform_generators.py +0 -137
  231. sierra/plugins/platform/ros1gazebo/plugin.py +0 -335
  232. sierra/plugins/platform/ros1gazebo/variables/__init__.py +0 -10
  233. sierra/plugins/platform/ros1gazebo/variables/population_size.py +0 -204
  234. sierra/plugins/platform/ros1robot/__init__.py +0 -9
  235. sierra/plugins/platform/ros1robot/cmdline.py +0 -175
  236. sierra/plugins/platform/ros1robot/generators/platform_generators.py +0 -112
  237. sierra/plugins/platform/ros1robot/plugin.py +0 -373
  238. sierra/plugins/platform/ros1robot/variables/__init__.py +0 -10
  239. sierra/plugins/platform/ros1robot/variables/population_size.py +0 -146
  240. sierra/plugins/robot/__init__.py +0 -9
  241. sierra/plugins/robot/turtlebot3/__init__.py +0 -9
  242. sierra/plugins/robot/turtlebot3/plugin.py +0 -194
  243. sierra_research-1.3.11.data/data/share/man/man1/sierra-cli.1 +0 -2349
  244. sierra_research-1.3.11.data/data/share/man/man7/sierra-examples.7 +0 -508
  245. sierra_research-1.3.11.data/data/share/man/man7/sierra-exec-envs.7 +0 -331
  246. sierra_research-1.3.11.data/data/share/man/man7/sierra-glossary.7 +0 -285
  247. sierra_research-1.3.11.data/data/share/man/man7/sierra-platforms.7 +0 -358
  248. sierra_research-1.3.11.data/data/share/man/man7/sierra-usage.7 +0 -729
  249. sierra_research-1.3.11.data/data/share/man/man7/sierra.7 +0 -78
  250. sierra_research-1.3.11.dist-info/METADATA +0 -492
  251. sierra_research-1.3.11.dist-info/RECORD +0 -133
  252. sierra_research-1.3.11.dist-info/top_level.txt +0 -1
  253. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/entry_points.txt +0 -0
  254. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info/licenses}/LICENSE +0 -0
@@ -1,137 +0,0 @@
1
- # Copyright 2021 John Harwell, All rights reserved.
2
- #
3
- # SPDX-License-Identifier: MIT
4
- """Classes for generating common XML modifications for :term:`ROS1+Gazebo`.
5
-
6
- I.e., changes which are platform-specific, but applicable to all projects using
7
- the platform.
8
-
9
- """
10
- # Core packages
11
- import logging
12
-
13
- # 3rd party packages
14
-
15
- # Project packages
16
- from sierra.core.experiment import spec, definition
17
- from sierra.core import types, ros1, config
18
-
19
-
20
- class PlatformExpDefGenerator(ros1.generators.ROSExpDefGenerator):
21
- """
22
- Init the object.
23
-
24
- Attributes:
25
-
26
- controller: The controller used for the experiment.
27
-
28
- cmdopts: Dictionary of parsed cmdline parameters.
29
- """
30
-
31
- def __init__(self,
32
- exp_spec: spec.ExperimentSpec,
33
- controller: str,
34
- cmdopts: types.Cmdopts,
35
- **kwargs) -> None:
36
- super().__init__(exp_spec, controller, cmdopts, **kwargs)
37
- self.logger = logging.getLogger(__name__)
38
-
39
- def generate(self) -> definition.XMLExpDef:
40
- exp_def = super().generate()
41
-
42
- exp_def.write_config.add({
43
- 'src_parent': ".",
44
- 'src_tag': "master",
45
- 'opath_leaf': "_master" + config.kROS['launch_file_ext'],
46
- 'create_tags': None,
47
- 'dest_parent': None,
48
- 'rename_to': 'launch'
49
- })
50
-
51
- exp_def.write_config.add({
52
- 'src_parent': ".",
53
- 'src_tag': "robot",
54
- 'opath_leaf': "_robots" + config.kROS['launch_file_ext'],
55
- 'create_tags': None,
56
- 'dest_parent': None,
57
- 'rename_to': 'launch'
58
- })
59
-
60
- # Setup gazebo experiment
61
- self._generate_gazebo_core(exp_def)
62
-
63
- # Setup gazebo visualization
64
- self._generate_gazebo_vis(exp_def)
65
-
66
- return exp_def
67
-
68
- def _generate_gazebo_core(self, exp_def: definition.XMLExpDef) -> None:
69
- """
70
- Generate XML tag changes to setup Gazebo core experiment parameters.
71
-
72
- Does not write generated changes to the run definition pickle
73
- file.
74
- """
75
- self.logger.debug("Generating Gazebo experiment changes (all runs)")
76
-
77
- # Start Gazebo/ROS in debug mode to make post-mortem analysis easier.
78
- exp_def.tag_add("./master/include",
79
- "arg",
80
- {
81
- "name": "verbose",
82
- "value": "true"
83
- })
84
-
85
- # Terminate Gazebo server whenever the launch script that invoked it
86
- # exits.
87
- exp_def.tag_add("./master/include",
88
- "arg",
89
- {
90
- "name": "server_required",
91
- "value": "true"
92
- })
93
-
94
- # Don't record stuff
95
- exp_def.tag_remove("./master/include", "arg/[@name='headless']")
96
- exp_def.tag_remove("./master/include", "arg/[@name='recording']")
97
-
98
- # Don't start paused
99
- exp_def.tag_remove("./master/include", "arg/[@name='paused']")
100
-
101
- # Don't start gazebo under gdb
102
- exp_def.tag_remove("./master/include", "arg/[@name='debug']")
103
-
104
- def _generate_gazebo_vis(self, exp_def: definition.XMLExpDef) -> None:
105
- """
106
- Generate XML changes to configure Gazebo visualizations.
107
-
108
- Does not write generated changes to the simulation definition pickle
109
- file.
110
- """
111
- exp_def.tag_remove_all("./master/include", "arg/[@name='gui']")
112
- exp_def.tag_add("./master/include",
113
- "arg",
114
- {
115
- "name": "gui",
116
- "value": "false"
117
- })
118
-
119
-
120
- class PlatformExpRunDefUniqueGenerator(ros1.generators.ROSExpRunDefUniqueGenerator):
121
- def __init__(self,
122
- *args,
123
- **kwargs) -> None:
124
- ros1.generators.ROSExpRunDefUniqueGenerator.__init__(
125
- self, *args, **kwargs)
126
-
127
- def generate(self, exp_def: definition.XMLExpDef):
128
- exp_def = super().generate(exp_def)
129
-
130
- self.generate_random(exp_def)
131
- self.generate_paramfile(exp_def)
132
-
133
-
134
- __api__ = [
135
- 'PlatformExpDefGenerator',
136
- 'PlatformExpRunDefUniqueGenerator'
137
- ]
@@ -1,335 +0,0 @@
1
- # Copyright 2021 John Harwell, All rights reserved.
2
- #
3
- # SPDX-License-Identifier: MIT
4
- """
5
- Provides platform-specific callbacks for the :term:`ROS1+Gazebo` platform.
6
- """
7
- # Core packages
8
- import argparse
9
- import logging
10
- import os
11
- import re
12
- import typing as tp
13
- import sys
14
- import pathlib
15
- import psutil
16
-
17
- # 3rd party packages
18
- import packaging.version
19
- import implements
20
-
21
- # Project packages
22
- from sierra.plugins.platform.ros1gazebo import cmdline
23
- from sierra.core import hpc, platform, config, ros1, types
24
- from sierra.core.experiment import bindings, definition, xml
25
- import sierra.core.variables.batch_criteria as bc
26
-
27
-
28
- class CmdlineParserGenerator():
29
- def __call__(self) -> argparse.ArgumentParser:
30
- parent1 = hpc.cmdline.HPCCmdline([-1, 1, 2, 3, 4, 5]).parser
31
- parent2 = ros1.cmdline.ROSCmdline([-1, 1, 2, 3, 4, 5]).parser
32
- return cmdline.PlatformCmdline(parents=[parent1, parent2],
33
- stages=[-1, 1, 2, 3, 4, 5]).parser
34
-
35
-
36
- @implements.implements(bindings.IParsedCmdlineConfigurer)
37
- class ParsedCmdlineConfigurer():
38
- def __init__(self, exec_env: str) -> None:
39
- self.exec_env = exec_env
40
- self.logger = logging.getLogger('ros1gazebo.plugin')
41
-
42
- def __call__(self, args: argparse.Namespace) -> None:
43
- # No configuration needed for stages 3-5
44
- if not any(stage in args.pipeline for stage in [1, 2]):
45
- return
46
-
47
- if self.exec_env == 'hpc.local':
48
- self._hpc_local(args)
49
- elif self.exec_env == 'hpc.adhoc':
50
- self._hpc_adhoc(args)
51
- elif self.exec_env == 'hpc.slurm':
52
- self._hpc_slurm(args)
53
- elif self.exec_env == 'hpc.pbs':
54
- self._hpc_pbs(args)
55
- else:
56
- raise RuntimeError(f"'{self.exec_env}' unsupported on ROS1+Gazebo")
57
-
58
- def _hpc_pbs(self, args: argparse.Namespace) -> None:
59
- # For now, nothing to do. If more stuff with physics engine
60
- # configuration is implemented, this may change.
61
- self.logger.debug("Allocated %s physics threads/run, %s parallel runs/node",
62
- args.physics_n_threads,
63
- args.exec_jobs_per_node)
64
-
65
- def _hpc_slurm(self, args: argparse.Namespace) -> None:
66
- # We rely on the user to request their job intelligently so that
67
- # SLURM_TASKS_PER_NODE is appropriate.
68
- if args.exec_jobs_per_node is None:
69
- res = re.search(r"^[^\(]+", os.environ['SLURM_TASKS_PER_NODE'])
70
- assert res is not None, \
71
- "Unexpected format in SLURM_TASKS_PER_NODE: '{0}'".format(
72
- os.environ['SLURM_TASKS_PER_NODE'])
73
- args.exec_jobs_per_node = int(res.group(0))
74
-
75
- self.logger.debug("Allocated %s physics threads/run, %s parallel runs/node",
76
- args.physics_n_threads,
77
- args.exec_jobs_per_node)
78
-
79
- def _hpc_adhoc(self, args: argparse.Namespace) -> None:
80
- nodes = platform.ExecEnvChecker.parse_nodefile(args.nodefile)
81
- ppn = sys.maxsize
82
- for node in nodes:
83
- ppn = min(ppn, node.n_cores)
84
-
85
- if args.exec_jobs_per_node is None:
86
- args.exec_jobs_per_node = int(float(args.n_runs) / len(nodes))
87
-
88
- self.logger.debug("Allocated %s physics threads/run, %s parallel runs/node",
89
- args.physics_n_threads,
90
- args.exec_jobs_per_node)
91
-
92
- def _hpc_local(self, args: argparse.Namespace) -> None:
93
- # For now. If more physics engine configuration is added, this will
94
- # change.
95
- ppn_per_run_req = 1
96
-
97
- if args.exec_jobs_per_node is None:
98
- parallel_jobs = int(psutil.cpu_count() / float(ppn_per_run_req))
99
-
100
- if parallel_jobs == 0:
101
- self.logger.warning(("Local machine has %s logical cores, but "
102
- "%s threads/run requested; "
103
- "allocating anyway"),
104
- psutil.cpu_count(),
105
- ppn_per_run_req)
106
- parallel_jobs = 1
107
-
108
- # Make sure we don't oversubscribe cores--each simulation needs at
109
- # least 1 core.
110
- args.exec_jobs_per_node = min(args.n_runs, parallel_jobs)
111
-
112
- self.logger.debug("Allocated %s physics threads/run, %s parallel runs/node",
113
- args.physics_n_threads,
114
- args.exec_jobs_per_node)
115
-
116
-
117
- @implements.implements(bindings.IExpRunShellCmdsGenerator)
118
- class ExpRunShellCmdsGenerator():
119
- def __init__(self,
120
- cmdopts: types.Cmdopts,
121
- criteria: bc.BatchCriteria,
122
- n_robots: int,
123
- exp_num: int) -> None:
124
- self.cmdopts = cmdopts
125
- self.gazebo_port = -1
126
- self.roscore_port = -1
127
-
128
- def pre_run_cmds(self,
129
- host: str,
130
- input_fpath: pathlib.Path,
131
- run_num: int) -> tp.List[types.ShellCmdSpec]:
132
- if host == 'master':
133
- return []
134
-
135
- # First, the cmd to start roscore. We need to be on a unique port so
136
- # that multiple ROS instances corresponding to multiple Gazebo
137
- # instances with the same topic names are considered distinct/not
138
- # accessible between instances of Gazebo.
139
- self.roscore_port = config.kROS['port_base'] + run_num * 2
140
-
141
- # roscore will run on each slave node used during stage 2, so we have to
142
- # use 'localhost' for binding.
143
- roscore_uri = types.ShellCmdSpec(
144
- cmd=f'export ROS_MASTER_URI=http://localhost:{self.roscore_port};',
145
- shell=True,
146
- wait=True,
147
- env=True)
148
-
149
- # Each experiment gets their own roscore. Because each roscore has a
150
- # different port, this prevents any robots from pre-emptively starting
151
- # the next experiment before the rest of the robots have finished the
152
- # current one.
153
- roscore_process = types.ShellCmdSpec(
154
- cmd=f'roscore -p {self.roscore_port} & ',
155
- shell=True,
156
- wait=False)
157
-
158
- # Second, the command to give Gazebo a unique port on the host during
159
- # stage 2. We need to be on a unique port so that multiple Gazebo
160
- # instances can be run in parallel.
161
- self.gazebo_port = config.kROS['port_base'] + run_num * 2 + 1
162
-
163
- # 2021/12/13: You can't use HTTPS for some reason or gazebo won't
164
- # start...
165
- gazebo_uri = types.ShellCmdSpec(
166
- cmd=f'export GAZEBO_MASTER_URI=http://localhost:{self.gazebo_port};',
167
- shell=True,
168
- env=True,
169
- wait=True
170
- )
171
-
172
- return [roscore_uri, roscore_process, gazebo_uri]
173
-
174
- def exec_run_cmds(self,
175
- host: str,
176
- input_fpath: pathlib.Path,
177
- run_num: int) -> tp.List[types.ShellCmdSpec]:
178
- if host == 'master':
179
- return []
180
-
181
- # For ROS+gazebo, we have two files per experimental run:
182
- #
183
- # - One for the stuff that is run on the ROS master (can be
184
- # nothing/empty file).
185
- #
186
- # - One for the stuff that describes what to run on each robot/how many
187
- # robots to spawn.
188
- #
189
- # We COULD do it all in a single file, but in order to share base code
190
- # with the ROS+robot platform, we need to do it this way.
191
- #
192
- # 2022/02/28: I don't use the -u argument here to set ROS_MASTER_URI,
193
- # because ROS works well enough when only running on the localhost, in
194
- # terms of respecting whatever the envvar is set to.
195
- master = str(input_fpath) + "_master" + config.kROS['launch_file_ext']
196
- robots = str(input_fpath) + "_robots" + config.kROS['launch_file_ext']
197
-
198
- cmd = '{0} --wait {1} {2} '.format(config.kROS['launch_cmd'],
199
- master,
200
- robots)
201
-
202
- # ROS/Gazebo don't provide options to not print stuff, so we have to use
203
- # the nuclear option.
204
- if self.cmdopts['exec_devnull']:
205
- cmd += '2>&1 > /dev/null'
206
-
207
- cmd += ';'
208
-
209
- return [types.ShellCmdSpec(cmd=cmd, shell=True, wait=True)]
210
-
211
- def post_run_cmds(self, host: str) -> tp.List[types.ShellCmdSpec]:
212
- return []
213
-
214
-
215
- @implements.implements(bindings.IExpShellCmdsGenerator)
216
- class ExpShellCmdsGenerator():
217
- def __init__(self,
218
- cmdopts: types.Cmdopts,
219
- exp_num: int) -> None:
220
- self.cmdopts = cmdopts
221
- self.exp_num = exp_num
222
-
223
- def pre_exp_cmds(self) -> tp.List[types.ShellCmdSpec]:
224
- return []
225
-
226
- def exec_exp_cmds(self,
227
- exec_opts: types.StrDict) -> tp.List[types.ShellCmdSpec]:
228
- return []
229
-
230
- def post_exp_cmds(self) -> tp.List[types.ShellCmdSpec]:
231
- # Cleanup roscore and gazebo processes which are still active because
232
- # they don't know how to clean up after themselves.
233
- #
234
- # This is OK to do even when we have multiple Gazebo+ROS instances on
235
- # the same machine, because we only run these commands after an
236
- # experiment finishes, so there isn't anything currently running we
237
- # might accidentally kill.
238
- #
239
- # Can't use killall, because that returns non-zero if things
240
- # are cleaned up nicely.
241
- return [types.ShellCmdSpec(cmd='if pgrep gzserver; then pkill gzserver; fi;',
242
- shell=True,
243
- wait=True),
244
- types.ShellCmdSpec(cmd='if pgrep rosmaster; then pkill rosmaster; fi;',
245
- shell=True,
246
- wait=True),
247
- types.ShellCmdSpec(cmd='if pgrep roscore; then pkill roscore; fi;',
248
- shell=True,
249
- wait=True),
250
- types.ShellCmdSpec(cmd='if pgrep rosout; then pkill rosout; fi;',
251
- shell=True,
252
- wait=True)]
253
-
254
-
255
- @implements.implements(bindings.IExpConfigurer)
256
- class ExpConfigurer():
257
- def __init__(self, cmdopts: types.Cmdopts) -> None:
258
- self.cmdopts = cmdopts
259
-
260
- def for_exp_run(self,
261
- exp_input_root: pathlib.Path,
262
- run_output_root: pathlib.Path) -> None:
263
- pass
264
-
265
- def for_exp(self, exp_input_root: pathlib.Path) -> None:
266
- pass
267
-
268
- def cmdfile_paradigm(self) -> str:
269
- return 'per-exp'
270
-
271
-
272
- @implements.implements(bindings.IExecEnvChecker)
273
- class ExecEnvChecker(platform.ExecEnvChecker):
274
- def __init__(self, cmdopts: types.Cmdopts) -> None:
275
- super().__init__(cmdopts)
276
-
277
- def __call__(self) -> None:
278
- keys = ['ROS_DISTRO', 'ROS_VERSION']
279
-
280
- for k in keys:
281
- assert k in os.environ,\
282
- f"Non-ROS+Gazebo environment detected: '{k}' not found"
283
-
284
- # Check ROS distro
285
- assert os.environ['ROS_DISTRO'] in ['kinetic', 'noetic'],\
286
- "SIERRA only supports ROS1 kinetic,noetic"
287
-
288
- # Check ROS version
289
- assert os.environ['ROS_VERSION'] == "1",\
290
- "Wrong ROS version: this plugin is for ROS1"
291
-
292
- # Check we can find Gazebo
293
- version = self.check_for_simulator(config.kGazebo['launch_cmd'])
294
-
295
- # Check Gazebo version
296
- res = re.search(r'[0-9]+.[0-9]+.[0-9]+', version.stdout.decode('utf-8'))
297
- assert res is not None, "Gazebo version not in -v output"
298
-
299
- version = packaging.version.parse(res.group(0))
300
- min_version = packaging.version.parse(config.kGazebo['min_version'])
301
-
302
- assert version >= min_version,\
303
- f"Gazebo version {version} < min required {min_version}"
304
-
305
-
306
- def population_size_from_pickle(adds_def: tp.Union[xml.AttrChangeSet,
307
- xml.TagAddList],
308
- main_config: types.YAMLDict,
309
- cmdopts: types.Cmdopts) -> int:
310
- return ros1.callbacks.population_size_from_pickle(adds_def,
311
- main_config,
312
- cmdopts)
313
-
314
-
315
- def population_size_from_def(exp_def: definition.XMLExpDef,
316
- main_config: types.YAMLDict,
317
- cmdopts: types.Cmdopts) -> int:
318
- return ros1.callbacks.population_size_from_def(exp_def,
319
- main_config,
320
- cmdopts)
321
-
322
-
323
- def robot_prefix_extract(main_config: types.YAMLDict,
324
- cmdopts: types.Cmdopts) -> str:
325
- return ros1.callbacks.robot_prefix_extract(main_config, cmdopts)
326
-
327
-
328
- def pre_exp_diagnostics(cmdopts: types.Cmdopts,
329
- logger: logging.Logger) -> None:
330
- s = "batch_exp_root='%s',runs/exp=%s,threads/job=%s,n_jobs=%s"
331
- logger.info(s,
332
- cmdopts['batch_root'],
333
- cmdopts['n_runs'],
334
- cmdopts['physics_n_threads'],
335
- cmdopts['exec_jobs_per_node'])
@@ -1,10 +0,0 @@
1
- # Copyright 2021 John Harwell, All rights reserved.
2
- #
3
- # SPDX-License-Identifier: MIT
4
-
5
- # Core packages
6
-
7
- # 3rd party packages
8
-
9
- # Project packages
10
- from sierra.core.ros1.variables import exp_setup
@@ -1,204 +0,0 @@
1
- # Copyright 2020 John Harwell, All rights reserved.
2
- #
3
- # SPDX-License-Identifier: MIT
4
- """Classes for the population size batch criteria.
5
-
6
- See :ref:`ln-sierra-platform-ros1gazebo-bc-population-size` for usage
7
- documentation.
8
-
9
- """
10
-
11
- # Core packages
12
- import typing as tp
13
- import random
14
- import logging
15
- import pathlib
16
-
17
- # 3rd party packages
18
- import implements
19
-
20
- # Project packages
21
- from sierra.core.variables import batch_criteria as bc
22
- from sierra.core.experiment import xml
23
- from sierra.core import types, utils
24
- from sierra.core.vector import Vector3D
25
- from sierra.core.variables import population_size
26
-
27
-
28
- @implements.implements(bc.IConcreteBatchCriteria)
29
- @implements.implements(bc.IQueryableBatchCriteria)
30
- class PopulationSize(population_size.BasePopulationSize):
31
- """A univariate range of system sizes used to define batch experiments.
32
-
33
- This class is a base class which should (almost) never be used on its
34
- own. Instead, the ``factory()`` function should be used to dynamically
35
- create derived classes expressing the user's desired size distribution.
36
-
37
- Note: Usage of this class assumes homogeneous systems.
38
-
39
- Attributes:
40
-
41
- size_list: List of integer system sizes defining the range of the
42
- variable for the batch experiment.
43
-
44
- """
45
-
46
- def __init__(self,
47
- cli_arg: str,
48
- main_config: types.YAMLDict,
49
- batch_input_root: pathlib.Path,
50
- robot: str,
51
- sizes: tp.List[int],
52
- positions: tp.List[Vector3D]) -> None:
53
- population_size.BasePopulationSize.__init__(self,
54
- cli_arg,
55
- main_config,
56
- batch_input_root)
57
- self.sizes = sizes
58
- self.robot = robot
59
- self.positions = positions
60
- self.logger = logging.getLogger(__name__)
61
- if len(positions) < self.sizes[-1]:
62
- self.logger.warning("# possible positions < # robots: %s < %s",
63
- len(positions),
64
- self.sizes[-1])
65
- self.tag_adds = [] # type: tp.List[xml.TagAddList]
66
-
67
- def gen_tag_addlist(self) -> tp.List[xml.TagAddList]:
68
- """Generate XML modifications to set system sizes.
69
-
70
- """
71
- if not self.tag_adds:
72
- robot_config = self.main_config['ros']['robots'][self.robot]
73
- prefix = robot_config['prefix']
74
- model_base = robot_config['model']
75
- model_variant = robot_config.get('model_variant', '')
76
-
77
- if model_variant != '':
78
- model = f"{model_base}_{model_variant}"
79
- else:
80
- model = model_base
81
-
82
- desc_cmd = f"$(find xacro)/xacro $(find {model_base}_description)/urdf/{model}.urdf.xacro"
83
- for s in self.sizes:
84
- exp_adds = xml.TagAddList()
85
- pos_i = random.randint(0, len(self.positions) - 1)
86
-
87
- exp_adds.append(xml.TagAdd(".",
88
- "master",
89
- {},
90
- True))
91
- exp_adds.append(xml.TagAdd("./master",
92
- "group",
93
- {
94
- 'ns': 'sierra'
95
- },
96
- False))
97
- exp_adds.append(xml.TagAdd("./master/group/[@ns='sierra']",
98
- "param",
99
- {
100
- 'name': 'experiment/n_robots',
101
- 'value': str(s)
102
- },
103
- False))
104
-
105
- for i in range(0, s):
106
-
107
- ns = f'{prefix}{i}'
108
- pos = self.positions[pos_i]
109
- pos_i = (pos_i + 1) % len(self.positions)
110
- spawn_cmd_args = f"-urdf -model {model}_{ns} -x {pos.x} -y {pos.y} -z {pos.z} -param robot_description"
111
-
112
- exp_adds.append(xml.TagAdd("./robot",
113
- "group",
114
- {
115
- 'ns': ns
116
- },
117
- True))
118
-
119
- exp_adds.append(xml.TagAdd(f"./robot/group/[@ns='{ns}']",
120
- "param",
121
- {
122
- "name": "tf_prefix",
123
- "value": ns
124
- },
125
- True))
126
-
127
- # These two tag adds are OK to use because:
128
- #
129
- # - All robots in Gazebo are created using spawn_model
130
- # initially.
131
- #
132
- # - All robots in Gazebo will provide a robot description
133
- # .urdf.xacro per ROS naming conventions
134
- exp_adds.append(xml.TagAdd(f"./robot/group/[@ns='{ns}']",
135
- "param",
136
- {
137
- "name": "robot_description",
138
- "command": desc_cmd
139
- },
140
- True))
141
-
142
- exp_adds.append(xml.TagAdd(f"./robot/group/[@ns='{ns}']",
143
- "node",
144
- {
145
- "name": "spawn_urdf",
146
- "pkg": "gazebo_ros",
147
- "type": "spawn_model",
148
- "args": spawn_cmd_args
149
- },
150
- True))
151
-
152
- self.tag_adds.append(exp_adds)
153
-
154
- return self.tag_adds
155
-
156
- def gen_exp_names(self, cmdopts: types.Cmdopts) -> tp.List[str]:
157
- adds = self.gen_tag_addlist()
158
- return ['exp' + str(x) for x in range(0, len(adds))]
159
-
160
- def n_robots(self, exp_num: int) -> int:
161
- return int(len(self.tag_adds[exp_num]) / len(self.tag_adds[0]))
162
-
163
-
164
- def factory(cli_arg: str,
165
- main_config: types.YAMLDict,
166
- cmdopts: types.Cmdopts,
167
- **kwargs) -> PopulationSize:
168
- """Create a :class:`PopulationSize` derived class from the cmdline definition.
169
-
170
- """
171
- parser = population_size.Parser()
172
- attr = parser(cli_arg)
173
- max_sizes = parser.to_sizes(attr)
174
-
175
- if cmdopts['robot_positions']:
176
- positions = [Vector3D.from_str(s,
177
- astype=float) for s in cmdopts['robot_positions']]
178
- else:
179
- # Get the dimensions of the effective arena from the scenario so we can
180
- # place robots randomly within it.
181
- kw = utils.gen_scenario_spec(cmdopts, **kwargs)
182
-
183
- xs = random.choices(range(0, kw['arena_x']), k=max_sizes[-1]) # type: ignore
184
- ys = random.choices(range(0, kw['arena_y']), k=max_sizes[-1]) # type: ignore
185
- zs = random.choices(range(0, kw['arena_z']), k=max_sizes[-1]) # type: ignore
186
- positions = [Vector3D(x, y, z) for x, y, z in zip(xs, ys, zs)]
187
-
188
- def __init__(self) -> None:
189
- PopulationSize.__init__(self,
190
- cli_arg,
191
- main_config,
192
- cmdopts['batch_input_root'],
193
- cmdopts['robot'],
194
- max_sizes,
195
- positions)
196
-
197
- return type(cli_arg, # type: ignore
198
- (PopulationSize,),
199
- {"__init__": __init__})
200
-
201
-
202
- __api__ = [
203
- 'PopulationSize'
204
- ]
@@ -1,9 +0,0 @@
1
- # Copyright 2021 John Harwell, All rights reserved.
2
- #
3
- # SPDX-License-Identifier: MIT
4
-
5
- # Core packages
6
-
7
- # 3rd party packages
8
-
9
- # Project packages