autoverse-cli 0.28.1__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 (51) hide show
  1. autoverse_cli-0.28.1.dist-info/METADATA +91 -0
  2. autoverse_cli-0.28.1.dist-info/RECORD +51 -0
  3. autoverse_cli-0.28.1.dist-info/WHEEL +5 -0
  4. autoverse_cli-0.28.1.dist-info/entry_points.txt +2 -0
  5. autoverse_cli-0.28.1.dist-info/licenses/LICENSE +33 -0
  6. autoverse_cli-0.28.1.dist-info/top_level.txt +1 -0
  7. avrs/__init__.py +0 -0
  8. avrs/app_version.py +24 -0
  9. avrs/argparse_help.py +30 -0
  10. avrs/avrs.py +183 -0
  11. avrs/can_tool.py +192 -0
  12. avrs/can_tool_util.py +190 -0
  13. avrs/cfg.py +78 -0
  14. avrs/launcher.py +256 -0
  15. avrs/launcher_util.py +203 -0
  16. avrs/race_cloud.py +506 -0
  17. avrs/race_cloud_bridge_can.py +100 -0
  18. avrs/race_cloud_cfg_util.py +310 -0
  19. avrs/race_cloud_fwd_api.py +49 -0
  20. avrs/race_cloud_util.py +384 -0
  21. avrs/requests/change_camera.py +24 -0
  22. avrs/requests/code_booz.py +69 -0
  23. avrs/requests/demo.py +19 -0
  24. avrs/requests/dump_sim_config.py +14 -0
  25. avrs/requests/environment.py +46 -0
  26. avrs/requests/fault_injection.py +186 -0
  27. avrs/requests/get_object_config.py +18 -0
  28. avrs/requests/get_web_viz_meta.py +11 -0
  29. avrs/requests/leaderboard.py +74 -0
  30. avrs/requests/list_sim_objects.py +26 -0
  31. avrs/requests/log_path.py +28 -0
  32. avrs/requests/misc.py +70 -0
  33. avrs/requests/move_to_landmark.py +16 -0
  34. avrs/requests/npc.py +289 -0
  35. avrs/requests/race_control.py +48 -0
  36. avrs/requests/request.py +61 -0
  37. avrs/requests/reset_to_track.py +21 -0
  38. avrs/requests/rest_request.py +45 -0
  39. avrs/requests/restart.py +12 -0
  40. avrs/requests/scenario_control.py +43 -0
  41. avrs/requests/spawn_object.py +44 -0
  42. avrs/requests/teleport.py +40 -0
  43. avrs/requests/toggle_hud.py +11 -0
  44. avrs/requests/vd.py +64 -0
  45. avrs/requests/vehicle_input.py +21 -0
  46. avrs/requests/vehicle_replay.py +454 -0
  47. avrs/shell_completion.py +121 -0
  48. avrs/simconfig.py +75 -0
  49. avrs/simconfig_util.py +170 -0
  50. avrs/tests.py +9 -0
  51. avrs/util.py +13 -0
@@ -0,0 +1,21 @@
1
+ from avrs.requests.request import AvrsApiRequest
2
+
3
+ class AvrsConfigureVehicleInputRequest(AvrsApiRequest):
4
+ def __init__(self, parser, cfg):
5
+ AvrsApiRequest.__init__(self, parser, cfg, 'ConfigureVehicleInput', 'Ego')
6
+ psr = parser.add_parser(
7
+ 'configure-vehicle-input',
8
+ help='Allows different input modes to be set for a vehicle')
9
+
10
+ psr.add_argument(
11
+ 'input_mode',
12
+ default='None',
13
+ choices=['None', 'Keyboard', 'WheelAndPedals', 'CAN'],
14
+ help='the type of input mode to set')
15
+
16
+ psr.set_defaults(func=self.send_request)
17
+
18
+ def get_request_body(self, args):
19
+ return {
20
+ "InputMode": args.input_mode
21
+ }
@@ -0,0 +1,454 @@
1
+ import random
2
+ from avrs.requests.request import AvrsApiRequest
3
+ from argparse import RawDescriptionHelpFormatter
4
+ from argparse import RawTextHelpFormatter
5
+
6
+ class AvrsVehicleReplayRequests():
7
+ def __init__(self, parser, cfg):
8
+ psr = parser.add_parser('vehicle-replay', help='utilty for recording and replaying vehicle motion')
9
+ sps = psr.add_subparsers(required= True, help='sub-command vehicle-replay')
10
+ SpawnReplayVehicle(sps, cfg)
11
+ StartVehicleReplayRecording(sps, cfg)
12
+ StopVehicleReplayRecording(sps, cfg)
13
+ DespawnReplayVehicle(sps, cfg)
14
+ SpawnVehicleReplayGroup(sps, cfg)
15
+
16
+ class SpawnReplayVehicle(AvrsApiRequest):
17
+ def __init__(self, parser, cfg):
18
+ AvrsApiRequest.__init__(self, parser, cfg, 'SpawnObject', '')
19
+ psr = parser.add_parser(
20
+ 'spawn', help='spawn a vehicle intended to replay motion', formatter_class=RawTextHelpFormatter)
21
+
22
+ psr.add_argument(
23
+ 'replay_file',
24
+ default='',
25
+ help='the replay file to use ("random" for a random profile)')
26
+
27
+ psr.add_argument(
28
+ '--name',
29
+ default='',
30
+ help='name of the replay vehicle to spawn')
31
+
32
+ psr.add_argument(
33
+ '--vehicle-type',
34
+ default='EAV24',
35
+ help='what type of vehicle to spawn for replay')
36
+
37
+ # psr.add_argument(
38
+ # '--position',
39
+ # choices=('relative', 'absolute'),
40
+ # default='absolute',
41
+ # help=NPC_SPAWN_POSITION_HELP)
42
+
43
+
44
+ # psr.add_argument(
45
+ # '--velocity-type',
46
+ # default='constant',
47
+ # help='the path the NPC follows is a constant velocity or speed')
48
+
49
+ # psr.add_argument(
50
+ # '--speed',
51
+ # type=float,
52
+ # default=20,
53
+ # help='the speed of the npc is m/s')
54
+
55
+ psr.add_argument(
56
+ '--rate',
57
+ type=float,
58
+ default=1.0,
59
+ help='the playback rate, 1.0 is normal')
60
+
61
+ psr.add_argument(
62
+ '--random-start',
63
+ action='store_true',
64
+ help='if set, will start at a random point in the replay')
65
+
66
+ psr.add_argument(
67
+ '--relative-dist',
68
+ type=float,
69
+ default=40.0,
70
+ help='the distance relative to ego to start the playback (-1 to start at playback start)')
71
+
72
+ psr.add_argument(
73
+ '--auto-start',
74
+ action='store_true',
75
+ help='if set, the npc will begin moving immediately')
76
+
77
+ psr.add_argument(
78
+ '--count',
79
+ type=int,
80
+ default=1,
81
+ help='the number of npcs to spawn (only works with automatic name)')
82
+
83
+ psr.add_argument(
84
+ '--group-name',
85
+ default="",
86
+ help="if specified, all vehicles will begin recording with the given group name")
87
+
88
+ psr.add_argument(
89
+ '--enable-front-lidar',
90
+ action='store_true',
91
+ help='if set, will enable the front lidar on the replay vehicle')
92
+
93
+ psr.add_argument(
94
+ '--enable-left-lidar',
95
+ action='store_true',
96
+ help='if set, will enable the left lidar on the replay vehicle')
97
+
98
+ psr.add_argument(
99
+ '--enable-right-lidar',
100
+ action='store_true',
101
+ help='if set, will enable the right lidar on the replay vehicle')
102
+
103
+ # psr.add_argument(
104
+ # '--enable-sensors',
105
+ # type=bool,
106
+ # default=False,
107
+ # help='whether to enable sensors on the replay vehicle')
108
+
109
+ psr.add_argument(
110
+ '--with-view-cameras',
111
+ action='store_true',
112
+ help='if set, will attach viewing cameras to the replay vehicle')
113
+
114
+ psr.set_defaults(func=self.send_request)
115
+
116
+ def send_request(self, args):
117
+ for i in range(args.count):
118
+ self.send_http_request(args)
119
+
120
+ def get_request_body(self, args):
121
+
122
+ replay_ipd = {
123
+ 'bEnableRecording': False,
124
+ 'bRecordOnPhysicsTick': False,
125
+ 'recordMotionMinSpeedThreshold': 0.01,
126
+ 'bEnableReplay': True,
127
+ 'bApplyInitialConfig': True,
128
+ 'initialConfig': {
129
+ 'playRate': args.rate,
130
+ 'profile': args.replay_file,
131
+ 'bUseRandomProfile': args.replay_file == 'random',
132
+ 'replayAction': 'start' if args.auto_start else '',
133
+ 'bStartReplayAtRandomTime': args.random_start,
134
+ 'relativeDistance': args.relative_dist,
135
+ 'bRecordAllVehiclesAsGroup': args.group_name != "",
136
+ 'RecordingGroupName': args.group_name
137
+ }
138
+ }
139
+
140
+ eav_init_pld = {
141
+ "bEnablePrimaryCan": False,
142
+ "bEnableSecondaryCan": False,
143
+ "bEnableBadeniaCan": False,
144
+ "bHudEnabled": False,
145
+ "bLidarEnabled": True,
146
+ "bCameraEnabled": False,
147
+ "bPublishInputs": False,
148
+ "bPublishGroundTruth": False
149
+ }
150
+
151
+ lidar_front_pld = {
152
+ 'componentConfig': {
153
+ 'instanceName': 'lidar_front'
154
+ },
155
+ 'sensorDesc': {
156
+ 'frame': 'lidar_front',
157
+ 'leverarm': {
158
+ 'translation': {
159
+ 'x': 85,
160
+ 'y': 0,
161
+ 'z': 73
162
+ },
163
+ 'translationUnits': 'centimeters',
164
+ 'rotation': {
165
+ 'pitch': 0,
166
+ 'yaw': 0,
167
+ 'roll': 0
168
+ },
169
+ 'rotationUnits': 'degrees'
170
+ },
171
+ 'dataStream': {
172
+ 'streamName': 'lidar_front/points',
173
+ 'rateHz': 15
174
+ }
175
+ }
176
+ }
177
+
178
+ lidar_left_pld = {
179
+ 'componentConfig': {
180
+ 'instanceName': 'lidar_left'
181
+ },
182
+ 'sensorDesc': {
183
+ 'frame': 'lidar_left',
184
+ 'leverarm': {
185
+ 'translation': {
186
+ 'x': 15,
187
+ 'y': -20,
188
+ 'z': 82
189
+ },
190
+ 'translationUnits': 'centimeters',
191
+ 'rotation': {
192
+ 'pitch': 0,
193
+ 'yaw': 240,
194
+ 'roll': 0
195
+ },
196
+ 'rotationUnits': 'degrees'
197
+ },
198
+ 'dataStream': {
199
+ 'streamName': 'lidar_left/points',
200
+ 'rateHz': 15
201
+ }
202
+ }
203
+ }
204
+
205
+ lidar_right_pld = {
206
+ 'componentConfig': {
207
+ 'instanceName': 'lidar_right'
208
+ },
209
+ 'sensorDesc': {
210
+ 'frame': 'lidar_right',
211
+ 'leverarm': {
212
+ 'translation': {
213
+ 'x': 15,
214
+ 'y': 20,
215
+ 'z': 82
216
+ },
217
+ 'translationUnits': 'centimeters',
218
+ 'rotation': {
219
+ 'pitch': 0,
220
+ 'yaw': 120,
221
+ 'roll': 0
222
+ },
223
+ 'rotationUnits': 'degrees'
224
+ },
225
+ 'dataStream': {
226
+ 'streamName': 'lidar_right/points',
227
+ 'rateHz': 15
228
+ }
229
+ }
230
+ }
231
+
232
+ world_label_pld = {
233
+ "typeName": "WorldTextComponent",
234
+ "bEnabled": True,
235
+ "body": {
236
+ "bUseObjectName": False,
237
+ "defaultString": "",
238
+ "fontSize": 34,
239
+ "offsetCm": {
240
+ "x": 0,
241
+ "y": 0,
242
+ "z": 150
243
+ }
244
+ }
245
+ }
246
+
247
+ plds = [
248
+ {
249
+ 'typeName': 'WheeledVehicleReplayIpd',
250
+ 'body': replay_ipd
251
+ },
252
+ {
253
+ 'typeName': 'Eav24Initializer',
254
+ 'body': eav_init_pld
255
+ },
256
+ {
257
+ 'typeName': 'GenericLidarIpd',
258
+ 'bEnabled': args.enable_front_lidar,
259
+ 'body': lidar_front_pld
260
+ },
261
+ {
262
+ 'typeName': 'GenericLidarIpd',
263
+ 'bEnabled': args.enable_left_lidar,
264
+ 'body': lidar_left_pld
265
+ },
266
+ {
267
+ 'typeName': 'GenericLidarIpd',
268
+ 'bEnabled': args.enable_right_lidar,
269
+ 'body': lidar_right_pld
270
+ },
271
+ world_label_pld
272
+ ]
273
+
274
+ if args.with_view_cameras:
275
+ plds.append(
276
+ {
277
+ 'typeName': 'InitializerTemplates',
278
+ 'body': {
279
+ 'templates': [
280
+ {
281
+ 'payloadType': 'SimViewTargetIpd',
282
+ 'payloadSpec': 'DefaultCarCams'
283
+ }
284
+ ]
285
+ }
286
+ })
287
+
288
+ # Create time based name if not specified
289
+ name = args.name
290
+ if name == '':
291
+ name = 'npc_{}'.format(random.randint(0, 100000))
292
+
293
+ return {
294
+ 'Name': name,
295
+ 'Type': args.vehicle_type,
296
+ 'Location': {},
297
+ 'Rotation': {},
298
+ 'Payloads': plds
299
+ }
300
+
301
+ class SpawnVehicleReplayGroup(AvrsApiRequest):
302
+ def __init__(self, parser, cfg):
303
+ AvrsApiRequest.__init__(self, parser, cfg, 'ConfigureVehicleReplay', '')
304
+ psr = parser.add_parser(
305
+ 'spawn-group', help='spawn each replay vehicle for a given group', formatter_class=RawTextHelpFormatter)
306
+
307
+ psr.add_argument(
308
+ 'group_name',
309
+ default="",
310
+ help="if specified, all vehicles will begin recording with the given group name")
311
+
312
+ psr.add_argument(
313
+ '--start-time',
314
+ type=float,
315
+ default=-1.0,
316
+ help="start the replay this many seconds in")
317
+
318
+ psr.add_argument(
319
+ '--rate',
320
+ type=float,
321
+ default=-1.0,
322
+ help="")
323
+
324
+ psr.set_defaults(func=self.send_request)
325
+
326
+ def get_request_body(self, args):
327
+
328
+ return {
329
+ 'PlayRate': args.rate,
330
+ 'startTime': args.start_time,
331
+ 'profile': '',
332
+ 'replayAction': 'start',
333
+ #'teleportLocation': '',
334
+ 'recordAction': '',
335
+ 'bShouldOverrideRecordSingleLap': False,
336
+ 'bRecordSingleLapOverride': False,
337
+ 'bShouldOverrideRecordMinSpeedThresh': False,
338
+ 'RecordMinSpeedThreshOverride': -1.0,
339
+ 'recordFileName': '',
340
+ 'recordRateHz': 100,
341
+ "RecordingGroupName": args.group_name
342
+ }
343
+
344
+ class StartVehicleReplayRecording(AvrsApiRequest):
345
+ def __init__(self, parser, cfg):
346
+ AvrsApiRequest.__init__(self, parser, cfg, 'ConfigureVehicleReplay', 'Ego')
347
+ psr = parser.add_parser(
348
+ 'start-recording', help='begin recording vehicle motion', formatter_class=RawTextHelpFormatter)
349
+
350
+ psr.add_argument(
351
+ 'out_file',
352
+ help='the file name to use for the saved recording')
353
+
354
+ psr.add_argument('--object-name', default='Ego', help='the name of the object to record')
355
+
356
+ psr.add_argument(
357
+ '--rate-hz',
358
+ type=float,
359
+ default=100.0,
360
+ help='the rate to record vehicle motion. high rates will produce large files')
361
+
362
+ psr.add_argument(
363
+ '--group-name',
364
+ default="",
365
+ help="if specified, all vehicles will begin recording with the given group name")
366
+
367
+ psr.add_argument(
368
+ '--not-single-lap',
369
+ action='store_true',
370
+ help='if set, recording will not try to capture exactly one lap and must be stopped by the user')
371
+
372
+ psr.set_defaults(func=self.send_request)
373
+
374
+
375
+ def get_request_body(self, args):
376
+ self.target_object_id = args.object_name
377
+
378
+ # we do not want to default to ego for group recordings
379
+ # because we want the replay manager to handle them
380
+ if args.group_name != "":
381
+ self.target_object_id = ""
382
+ # it doesnt make sense to do group recordings as single laps
383
+ args.not_single_lap = True
384
+
385
+ return {
386
+ 'PlayRate': -1.0,
387
+ 'profile': '',
388
+ 'replayAction': '',
389
+ #'teleportLocation': '',
390
+ 'recordAction': 'start',
391
+ 'bShouldOverrideRecordSingleLap': args.not_single_lap,
392
+ 'bRecordSingleLapOverride': not args.not_single_lap,
393
+ 'bShouldOverrideRecordMinSpeedThresh': args.group_name != "", # no min speed for groups
394
+ 'RecordMinSpeedThreshOverride': -1.0,
395
+ 'recordFileName': args.out_file,
396
+ 'recordRateHz': args.rate_hz,
397
+ "RecordingGroupName": args.group_name
398
+ }
399
+
400
+ class StopVehicleReplayRecording(AvrsApiRequest):
401
+ def __init__(self, parser, cfg):
402
+ AvrsApiRequest.__init__(self, parser, cfg, 'ConfigureVehicleReplay', 'Ego')
403
+ psr = parser.add_parser(
404
+ 'stop-recording', help='begin recording vehicle motion', formatter_class=RawTextHelpFormatter)
405
+
406
+ psr.add_argument('--object-name', default='Ego', help='the name of the object to record')
407
+
408
+ psr.add_argument(
409
+ '--group-name',
410
+ default="",
411
+ help="if specified, all vehicles will begin recording with the given group name")
412
+
413
+ psr.set_defaults(func=self.send_request)
414
+
415
+
416
+ def get_request_body(self, args):
417
+ self.target_object_id = args.object_name
418
+
419
+ # we do not want to default to ego for group recordings
420
+ # because we want the replay manager to handle them
421
+ if args.group_name != "":
422
+ self.target_object_id = ""
423
+ return {
424
+ 'recordAction': 'stop',
425
+ "RecordingGroupName": args.group_name
426
+ }
427
+
428
+ class DespawnReplayVehicle(AvrsApiRequest):
429
+ def __init__(self, parser, cfg):
430
+ AvrsApiRequest.__init__(self, parser, cfg, 'DespawnObject', 'Ego')
431
+ psr = parser.add_parser(
432
+ 'despawn', help='despawn a replay vehicle or all replay vehicles', formatter_class=RawTextHelpFormatter)
433
+
434
+ psr.add_argument(
435
+ '--name',
436
+ default='',
437
+ help='name of the replay vehicle to despawn')
438
+
439
+ psr.add_argument(
440
+ '--all',
441
+ action='store_true',
442
+ help='if set, will despawn all replay vehicles')
443
+
444
+ psr.set_defaults(func=self.send_request)
445
+
446
+
447
+ def get_request_body(self, args):
448
+ self.target_object_id = args.name
449
+ tags = ["Npc"] if args.all else []
450
+
451
+ return {
452
+ 'tags': tags,
453
+ 'bMatchAnyTag': True
454
+ }
@@ -0,0 +1,121 @@
1
+ import os
2
+ import sys
3
+ import subprocess
4
+ from pathlib import Path
5
+
6
+ def get_shell_name():
7
+ """Detect the current shell from SHELL environment variable or parent process."""
8
+ shell = os.environ.get('SHELL', '')
9
+ if shell:
10
+ return os.path.basename(shell)
11
+
12
+ # Fallback: try to get parent shell
13
+ try:
14
+ parent_pid = os.getppid()
15
+ with open(f'/proc/{parent_pid}/comm', 'r') as f:
16
+ return f.read().strip()
17
+ except:
18
+ return 'bash'
19
+
20
+ def get_shell_config_file():
21
+ """Get the config file path for the detected shell."""
22
+ shell = get_shell_name()
23
+ home = str(Path.home())
24
+
25
+ if 'zsh' in shell:
26
+ return os.path.join(home, '.zshrc')
27
+ elif 'fish' in shell:
28
+ return os.path.join(home, '.config/fish/config.fish')
29
+ elif 'tcsh' in shell:
30
+ return os.path.join(home, '.tcshrc')
31
+ else: # bash and others
32
+ return os.path.join(home, '.bashrc')
33
+
34
+ def get_completion_command():
35
+ """Get the shell-specific completion registration command."""
36
+ shell = get_shell_name()
37
+
38
+ # Try to use register-python-argcomplete if available, fall back to register-python-argcomplete3
39
+ # This makes it compatible with both pip-installed and system-package versions
40
+ register_cmd = "register-python-argcomplete"
41
+
42
+ if 'zsh' in shell:
43
+ return f'eval "$({register_cmd} --shell zsh avrs 2>/dev/null || {register_cmd}3 --shell zsh avrs)"'
44
+ elif 'fish' in shell:
45
+ return f'{register_cmd} --shell fish avrs 2>/dev/null | source || {register_cmd}3 --shell fish avrs | source'
46
+ elif 'tcsh' in shell:
47
+ return f'eval "$({register_cmd} --shell tcsh avrs 2>/dev/null || {register_cmd}3 --shell tcsh avrs)"'
48
+ else: # bash
49
+ return f'eval "$({register_cmd} avrs 2>/dev/null || {register_cmd}3 avrs)"'
50
+
51
+ def install_completion():
52
+ """Install shell completion for the avrs CLI."""
53
+ shell = get_shell_name()
54
+ config_file = get_shell_config_file()
55
+ completion_command = get_completion_command()
56
+
57
+ print(f"Installing shell completion for {shell}...")
58
+
59
+ # Check if completion already installed
60
+ if os.path.exists(config_file):
61
+ with open(config_file, 'r') as f:
62
+ content = f.read()
63
+ if 'register-python-argcomplete' in content and 'avrs' in content:
64
+ print(f"✓ Completion already installed in {config_file}")
65
+ return True
66
+
67
+ # Ensure config file exists
68
+ Path(config_file).parent.mkdir(parents=True, exist_ok=True)
69
+
70
+ # Append completion command
71
+ try:
72
+ with open(config_file, 'a') as f:
73
+ f.write('\n\n# avrs CLI completion\n')
74
+ f.write(completion_command + '\n')
75
+ print(f"✓ Completion installed successfully!")
76
+ print(f"✓ Added to {config_file}")
77
+ print(f"\nTo activate completion in current shell, run:")
78
+ print(f" source {config_file}")
79
+ return True
80
+ except Exception as e:
81
+ print(f"✗ Error installing completion: {e}")
82
+ print(f"\nManually add this line to {config_file}:")
83
+ print(f" {completion_command}")
84
+ return False
85
+
86
+ def uninstall_completion():
87
+ """Remove shell completion for the avrs CLI."""
88
+ shell = get_shell_name()
89
+ config_file = get_shell_config_file()
90
+
91
+ print(f"Uninstalling shell completion from {config_file}...")
92
+
93
+ if not os.path.exists(config_file):
94
+ print("Config file not found.")
95
+ return False
96
+
97
+ try:
98
+ with open(config_file, 'r') as f:
99
+ lines = f.readlines()
100
+
101
+ # Filter out avrs completion lines
102
+ new_lines = [
103
+ line for line in lines
104
+ if 'register-python-argcomplete' not in line or 'avrs' not in line
105
+ ]
106
+
107
+ # Also remove the comment line if it's there
108
+ filtered_lines = []
109
+ for i, line in enumerate(new_lines):
110
+ if line.strip() == '# avrs CLI completion':
111
+ continue
112
+ filtered_lines.append(line)
113
+
114
+ with open(config_file, 'w') as f:
115
+ f.writelines(filtered_lines)
116
+
117
+ print(f"✓ Completion uninstalled successfully!")
118
+ return True
119
+ except Exception as e:
120
+ print(f"✗ Error uninstalling completion: {e}")
121
+ return False
avrs/simconfig.py ADDED
@@ -0,0 +1,75 @@
1
+ import os
2
+ import stat
3
+ import json
4
+ import http.client
5
+ from avrs.cfg import *
6
+ from avrs.launcher_util import *
7
+ from avrs.simconfig_util import *
8
+
9
+ class AvrsSimConfig:
10
+ def __init__(self, parent_parser, cfg):
11
+ self.cfg = cfg
12
+ sim_config_parser = parent_parser.add_parser(
13
+ 'sim-config',
14
+ help='utilities for easily configuring the simulator\n\n')
15
+
16
+ sps = sim_config_parser.add_subparsers(required=True, help='sim-config options')
17
+
18
+ compare_parser = sps.add_parser(
19
+ 'compare-configs',
20
+ help='compare two sets of configuration files')
21
+ compare_parser.add_argument(
22
+ 'a',
23
+ help='the path to the first set of config files')
24
+ compare_parser.add_argument(
25
+ 'b',
26
+ help='the path to the second set of config files')
27
+ compare_parser.set_defaults(func=self.compare_configs)
28
+
29
+ apply_preset_parser = sps.add_parser(
30
+ 'apply-preset',
31
+ help='apply a preset configuration for a certain use-case')
32
+ apply_preset_parser.add_argument(
33
+ 'preset_name',
34
+ choices=['default', 'lightweight', 'a2rl'],
35
+ help='the name of the preset to apply')
36
+ apply_preset_parser.add_argument(
37
+ '--sim-path',
38
+ default='',
39
+ help='''
40
+ the path to the simulator installation having the intended config to modify, or the
41
+ index of a known installation. if there is only one known installation, it will be used as
42
+ the target
43
+ ''')
44
+ apply_preset_parser.set_defaults(func=self.apply_preset)
45
+
46
+
47
+ def apply_preset(self, args):
48
+ sim_path = args.sim_path
49
+ if sim_path == '':
50
+ if 'installs' in self.cfg and len(self.cfg['installs']) > 0:
51
+ if len(self.cfg['installs']) > 1:
52
+ print('multiple known installs. specify path or index')
53
+ for i in range(len(self.cfg['installs'])):
54
+ print('({}) {}'.format(i, self.cfg['installs'][i]))
55
+ return
56
+ else:
57
+ sim_path = self.cfg['installs'][0]
58
+ else:
59
+ print('sim_path not specified and no known existing installations')
60
+ return
61
+ try:
62
+ sim_path_index = int(sim_path)
63
+ if 'installs' in self.cfg and len(self.cfg['installs']) > sim_path_index:
64
+ sim_path = self.cfg['installs'][sim_path_index]
65
+ except Exception as e:
66
+ pass
67
+ if not is_installed_sim(sim_path):
68
+ print('{} is not a valid sim installation'.format(sim_path))
69
+ return
70
+
71
+ print('applying preset {} to sim install at {}'.format(args.preset_name, sim_path))
72
+ apply_simconfig_preset(get_sim_saved_dir(sim_path), args.preset_name)
73
+
74
+ def compare_configs(self, args):
75
+ compare_simconfig_defaults(args.a, args.b)