autoverse-cli 0.4.1__tar.gz → 0.5.0__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/PKG-INFO +2 -1
  2. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/pyproject.toml +3 -2
  3. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/autoverse_cli.egg-info/PKG-INFO +2 -1
  4. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/autoverse_cli.egg-info/SOURCES.txt +11 -4
  5. autoverse_cli-0.5.0/src/autoverse_cli.egg-info/requires.txt +2 -0
  6. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/app_version.py +1 -1
  7. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/avrs.py +25 -8
  8. autoverse_cli-0.5.0/src/avrs/can_tool.py +192 -0
  9. autoverse_cli-0.5.0/src/avrs/can_tool_util.py +190 -0
  10. autoverse_cli-0.5.0/src/avrs/cfg.py +78 -0
  11. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/launcher.py +7 -1
  12. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/launcher_util.py +3 -0
  13. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/requests/demo.py +3 -7
  14. autoverse_cli-0.4.1/src/avrs/requests/edit_environment.py → autoverse_cli-0.5.0/src/avrs/requests/environment.py +15 -3
  15. autoverse_cli-0.5.0/src/avrs/requests/fault_injection.py +155 -0
  16. autoverse_cli-0.5.0/src/avrs/requests/list_sim_objects.py +26 -0
  17. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/requests/request.py +4 -1
  18. autoverse_cli-0.5.0/src/avrs/requests/scenario_control.py +43 -0
  19. autoverse_cli-0.5.0/src/avrs/requests/vehicle_input.py +21 -0
  20. autoverse_cli-0.5.0/src/avrs/requests/vehicle_replay.py +191 -0
  21. autoverse_cli-0.5.0/src/avrs/simconfig.py +61 -0
  22. autoverse_cli-0.5.0/src/avrs/simconfig_util.py +70 -0
  23. autoverse_cli-0.4.1/src/autoverse_cli.egg-info/requires.txt +0 -1
  24. autoverse_cli-0.4.1/src/avrs/cfg.py +0 -26
  25. autoverse_cli-0.4.1/src/avrs/requests/can.py +0 -131
  26. autoverse_cli-0.4.1/src/avrs/requests/input.py +0 -46
  27. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/LICENSE +0 -0
  28. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/README.md +0 -0
  29. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/setup.cfg +0 -0
  30. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/autoverse_cli.egg-info/dependency_links.txt +0 -0
  31. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/autoverse_cli.egg-info/entry_points.txt +0 -0
  32. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/autoverse_cli.egg-info/top_level.txt +0 -0
  33. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/__init__.py +0 -0
  34. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/argparse_help.py +0 -0
  35. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/requests/code_booz.py +0 -0
  36. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/requests/log_path.py +0 -0
  37. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/requests/move_to_landmark.py +0 -0
  38. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/requests/npc.py +0 -0
  39. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/requests/reserve_mv_slot.py +0 -0
  40. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/requests/reset_to_track.py +0 -0
  41. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/requests/restart.py +0 -0
  42. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/requests/teleport.py +0 -0
  43. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/requests/vd.py +0 -0
  44. {autoverse_cli-0.4.1 → autoverse_cli-0.5.0}/src/avrs/tests.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: autoverse-cli
3
- Version: 0.4.1
3
+ Version: 0.5.0
4
4
  Summary: The Autoverse CLI
5
5
  Author-email: Dan Kamrath <dan.kamrath@autonomalabs.com>
6
6
  License: # End-User License Agreement (EULA) of the Autonoma AutoVerse CLI
@@ -42,6 +42,7 @@ Requires-Python: >=3.8
42
42
  Description-Content-Type: text/markdown
43
43
  License-File: LICENSE
44
44
  Requires-Dist: boto3
45
+ Requires-Dist: cantools
45
46
 
46
47
  # Autoverse CLI
47
48
 
@@ -1,8 +1,9 @@
1
1
  [project]
2
2
  name = "autoverse-cli"
3
- version = "0.4.1"
3
+ version = "0.5.0"
4
4
  dependencies = [
5
- "boto3"
5
+ "boto3",
6
+ "cantools"
6
7
  ]
7
8
  authors = [
8
9
  { name="Dan Kamrath", email="dan.kamrath@autonomalabs.com" },
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: autoverse-cli
3
- Version: 0.4.1
3
+ Version: 0.5.0
4
4
  Summary: The Autoverse CLI
5
5
  Author-email: Dan Kamrath <dan.kamrath@autonomalabs.com>
6
6
  License: # End-User License Agreement (EULA) of the Autonoma AutoVerse CLI
@@ -42,6 +42,7 @@ Requires-Python: >=3.8
42
42
  Description-Content-Type: text/markdown
43
43
  License-File: LICENSE
44
44
  Requires-Dist: boto3
45
+ Requires-Dist: cantools
45
46
 
46
47
  # Autoverse CLI
47
48
 
@@ -11,15 +11,19 @@ src/avrs/__init__.py
11
11
  src/avrs/app_version.py
12
12
  src/avrs/argparse_help.py
13
13
  src/avrs/avrs.py
14
+ src/avrs/can_tool.py
15
+ src/avrs/can_tool_util.py
14
16
  src/avrs/cfg.py
15
17
  src/avrs/launcher.py
16
18
  src/avrs/launcher_util.py
19
+ src/avrs/simconfig.py
20
+ src/avrs/simconfig_util.py
17
21
  src/avrs/tests.py
18
- src/avrs/requests/can.py
19
22
  src/avrs/requests/code_booz.py
20
23
  src/avrs/requests/demo.py
21
- src/avrs/requests/edit_environment.py
22
- src/avrs/requests/input.py
24
+ src/avrs/requests/environment.py
25
+ src/avrs/requests/fault_injection.py
26
+ src/avrs/requests/list_sim_objects.py
23
27
  src/avrs/requests/log_path.py
24
28
  src/avrs/requests/move_to_landmark.py
25
29
  src/avrs/requests/npc.py
@@ -27,5 +31,8 @@ src/avrs/requests/request.py
27
31
  src/avrs/requests/reserve_mv_slot.py
28
32
  src/avrs/requests/reset_to_track.py
29
33
  src/avrs/requests/restart.py
34
+ src/avrs/requests/scenario_control.py
30
35
  src/avrs/requests/teleport.py
31
- src/avrs/requests/vd.py
36
+ src/avrs/requests/vd.py
37
+ src/avrs/requests/vehicle_input.py
38
+ src/avrs/requests/vehicle_replay.py
@@ -0,0 +1,2 @@
1
+ boto3
2
+ cantools
@@ -2,7 +2,7 @@ import http.client
2
2
  import json
3
3
 
4
4
  def get_app_version():
5
- return '0.4.1'
5
+ return '0.5.0'
6
6
 
7
7
  def check_app_is_latest():
8
8
  pass
@@ -6,21 +6,26 @@ from argparse import RawTextHelpFormatter
6
6
  from avrs.app_version import *
7
7
  from avrs.cfg import *
8
8
  from avrs.launcher import *
9
+ from avrs.can_tool import *
9
10
  from avrs.argparse_help import *
10
11
 
11
12
  from avrs.requests.move_to_landmark import MoveToLandmarkRequest
12
13
  from avrs.requests.restart import Restart
13
14
  from avrs.requests.reset_to_track import ResetToTrack
14
15
  from avrs.requests.teleport import Teleport
15
- #from src.requests.can import Can
16
16
  from avrs.requests.npc import Npc
17
17
  from avrs.requests.reserve_mv_slot import ReserveMvSlot
18
18
  from avrs.requests.vd import Vd
19
- from avrs.requests.input import InputRequest
19
+ from avrs.requests.vehicle_input import AvrsConfigureVehicleInputRequest
20
20
  from avrs.requests.log_path import LogPath
21
21
  from avrs.requests.demo import AvrsDemoRequest
22
- from avrs.requests.edit_environment import AvrsEditEnvironmentRequests
22
+ from avrs.requests.environment import *
23
23
  from avrs.requests.code_booz import *
24
+ from avrs.requests.vehicle_replay import *
25
+ from avrs.requests.scenario_control import *
26
+ from avrs.requests.list_sim_objects import *
27
+ from avrs.requests.fault_injection import *
28
+ from avrs.simconfig import *
24
29
 
25
30
 
26
31
  def get_version():
@@ -39,6 +44,11 @@ def main():
39
44
  action='version',
40
45
  version=get_version())
41
46
 
47
+ parser.add_argument(
48
+ '--verbose',
49
+ action='store_true',
50
+ help='request verbose output')
51
+
42
52
  sps = parser.add_subparsers(required=True, help='sub-command help')
43
53
 
44
54
  cfg = load_cfg('avrs')
@@ -50,16 +60,23 @@ def main():
50
60
  MoveToLandmarkRequest(sps, cfg)
51
61
  Restart(sps, cfg)
52
62
  ResetToTrack(sps, cfg)
53
- #Can(sps, cfg)
54
63
  Teleport(sps, cfg)
55
- Npc(sps, cfg)
64
+ #Npc(sps, cfg)
56
65
  ReserveMvSlot(sps, cfg)
57
66
  Vd(sps, cfg)
58
- #InputRequest(sps, cfg)
67
+ AvrsConfigureVehicleInputRequest(sps, cfg)
59
68
  LogPath(sps, cfg)
60
- AvrsEditEnvironmentRequests(sps, cfg)
69
+ AvrsEnvironmentRequests(sps, cfg)
61
70
  AvrsCodeBoozRequest(sps, cfg)
62
- AvrsDemoRequest(sps, cfg)
71
+ AvrsVehicleReplayRequests(sps, cfg)
72
+ AvrsCanTool(sps, cfg)
73
+ AvrsSimConfig(sps, cfg)
74
+ AvrsScenarioRequests(sps, cfg)
75
+ AvrsListSimObjectsRequest(sps, cfg)
76
+ AvrsFaultInjectionRequests(sps, cfg)
77
+
78
+ if os.environ.get('AVRS_WITH_DEMO', '0') == '1':
79
+ AvrsDemoRequest(sps, cfg)
63
80
 
64
81
  if os.environ.get('AVRS_GEN_DOCS', '0') == '1':
65
82
  generate_argparse_docs(parser)
@@ -0,0 +1,192 @@
1
+ from avrs.requests.request import AvrsApiRequest
2
+ import can
3
+ import cantools
4
+ import time
5
+ import os
6
+ import datetime
7
+
8
+ from avrs.cfg import *
9
+ from avrs.can_tool_util import *
10
+
11
+ class AvrsCanTool():
12
+ def __init__(self, parent_parser, cfg):
13
+ self.cfg = cfg
14
+ can_tool_parser = parent_parser.add_parser(
15
+ 'can-tool',
16
+ help='provides CAN utilities (echo certain signals, etc)\n\n')
17
+ sps = can_tool_parser.add_subparsers(required=True, help='can-tool options')
18
+
19
+ add_dbc_parser = sps.add_parser(
20
+ 'add-dbc',
21
+ help='save a dbc file to be used with other commands')
22
+ add_dbc_parser.add_argument(
23
+ 'dbc_file_path',
24
+ help='the path to the dbc file to add')
25
+ add_dbc_parser.add_argument(
26
+ '--overwrite-ok',
27
+ action='store_true',
28
+ help='is it ok to overwrite an existing file')
29
+ add_dbc_parser.set_defaults(func=self.add_dbc)
30
+
31
+ list_dbc_parser = sps.add_parser(
32
+ 'list-dbc',
33
+ help='list the dbc files that are known to avrs')
34
+ list_dbc_parser.set_defaults(func=self.list_dbc)
35
+
36
+ echo_parser = sps.add_parser(
37
+ 'echo',
38
+ help='echos CAN messages')
39
+ echo_parser.add_argument(
40
+ 'can_names',
41
+ nargs='+',
42
+ help='the names of the CAN interfaces, eg "vcan0 vcan1" etc')
43
+ echo_parser.add_argument(
44
+ '--dbc_names',
45
+ nargs='+',
46
+ default='',
47
+ help='the names or indeces of a cached dbc files or path to existing dbc files to use')
48
+ echo_parser.add_argument(
49
+ '--isolate',
50
+ nargs='+',
51
+ default='',
52
+ help='a list of specific signal to echo, ignoring other signals')
53
+ echo_parser.add_argument(
54
+ '--duration',
55
+ type=float,
56
+ default=1.0,
57
+ help='the duration to echo can')
58
+ echo_parser.add_argument(
59
+ '--rates',
60
+ action='store_true',
61
+ help='echo the rates for messages instead of their values')
62
+ echo_parser.add_argument(
63
+ '--save-report-as',
64
+ default='',
65
+ help='if set along with the "--rates" flag, will save results to a json file')
66
+ echo_parser.set_defaults(func=self.echo)
67
+
68
+ eav_input_parser = sps.add_parser(
69
+ 'send-eav24-input',
70
+ help='send some simple input (throttle, brake, steer etc) to an eav24 over CAN')
71
+ eav_input_parser.add_argument(
72
+ 'can_name',
73
+ help='the name of the CAN interface, eg "vcan0"')
74
+ eav_input_parser.add_argument(
75
+ 'dbc_name',
76
+ help='the name or index of a cached dbc file or path to existing dbc file to use')
77
+ eav_input_parser.add_argument(
78
+ '--throttle',
79
+ type=float,
80
+ default=0.0,
81
+ help='throttle to send 0 -> 1.0')
82
+ eav_input_parser.add_argument(
83
+ '--gear',
84
+ type=int,
85
+ default=0,
86
+ help='gear to send')
87
+ eav_input_parser.add_argument(
88
+ '--brake',
89
+ type=float,
90
+ default=0.0,
91
+ help='brake to send 0 -> 1.0')
92
+ eav_input_parser.add_argument(
93
+ '--steer',
94
+ type=float,
95
+ default=0.0,
96
+ help='steer to send -24 -> 24')
97
+ eav_input_parser.add_argument(
98
+ '--duration',
99
+ type=float,
100
+ default=1.0,
101
+ help='the duration to send the command can')
102
+ eav_input_parser.set_defaults(func=self.eav_input)
103
+
104
+ test_latency_parser = sps.add_parser(
105
+ 'test-eav24-bsu-latency',
106
+ help='test the latency in the EAV24 BSU CAN interface by waiting for command ACK')
107
+ test_latency_parser.add_argument(
108
+ 'can_name',
109
+ help='the name of the CAN interface, eg "vcan0"')
110
+ test_latency_parser.add_argument(
111
+ 'dbc_name',
112
+ help='the name or index of a cached dbc file or path to existing dbc file to use')
113
+ test_latency_parser.add_argument(
114
+ '--nsamples',
115
+ type=int,
116
+ default=5,
117
+ help='the number of samples to test')
118
+ test_latency_parser.add_argument(
119
+ '--duration',
120
+ type=float,
121
+ default=1.0,
122
+ help='the duration to send each command can to wait for a given ack')
123
+ test_latency_parser.add_argument(
124
+ '--send-rate-hz',
125
+ type=float,
126
+ default=50,
127
+ help='the rate in hz to send messages to wait for a given ack')
128
+ test_latency_parser.add_argument(
129
+ '--save-report-as',
130
+ default='',
131
+ help='if set will save results to a json file with this name')
132
+
133
+ test_latency_parser.set_defaults(func=self.test_eav24_latency)
134
+
135
+
136
+ def add_dbc(self, args):
137
+ ok, status = add_cached_file(
138
+ 'avrs', 'dbc', args.dbc_file_path, args.overwrite_ok)
139
+ print(status)
140
+
141
+ def list_dbc(self, args):
142
+ files = get_cached_file_list('avrs', 'dbc')
143
+ s = ''
144
+ for i in range(len(files)):
145
+ s += '({}) {} \n'.format(i, files[i])
146
+ print(s) if len(files) > 0 else print('(empty)')
147
+
148
+ def echo(self, args):
149
+ dbcs = self.get_dbcs(args.dbc_names)
150
+ print('echoing {} using {} dbcs'.format(args.can_names, len(dbcs)))
151
+ if len(dbcs) > 0:
152
+ echo_can(args.can_names, dbcs, args.duration, args.isolate, args.rates, args.save_report_as)
153
+ else:
154
+ print('unable to echo can (dbc or can name error)')
155
+
156
+ def eav_input(self, args):
157
+ dbcs = self.get_dbcs([args.dbc_name])
158
+ if len(dbcs) > 0:
159
+ send_eav24_can_values(
160
+ args.can_name, dbcs[0], args.throttle, args.gear, args.brake, args.steer, args.duration)
161
+ else:
162
+ print('unable to echo can (dbc or can name error)')
163
+
164
+ def test_eav24_latency(self, args):
165
+ dbcs = self.get_dbcs([args.dbc_name])
166
+ if len(dbcs) > 0:
167
+ test_eav24_can_latency(
168
+ args.can_name, dbcs[0], args.nsamples, args.send_rate_hz, args.duration, args.save_report_as)
169
+ else:
170
+ print('unable to echo can (dbc or can name error)')
171
+
172
+ def get_dbcs(self, dbc_names):
173
+ dbcs = []
174
+ # If default, find all dbcs and return them
175
+ if dbc_names == '':
176
+ for d in get_cached_file_list('avrs', 'dbc'):
177
+ ok, cache_path = get_cached_file('avrs', 'dbc', d)
178
+ if ok:
179
+ dbcs.append(cantools.database.load_file(cache_path))
180
+ else:
181
+ print(cache_path)
182
+ else:
183
+ for d in dbc_names:
184
+ if os.path.isfile(d):
185
+ dbc = cantools.database.load_file(d)
186
+ else:
187
+ ok, cache_path = get_cached_file('avrs', 'dbc', d)
188
+ if ok:
189
+ dbcs.append(cantools.database.load_file(cache_path))
190
+ else:
191
+ print(cache_path)
192
+ return dbcs
@@ -0,0 +1,190 @@
1
+ import can
2
+ import cantools
3
+ import time
4
+ import os
5
+ import datetime
6
+ import threading
7
+ import queue
8
+ import json
9
+ import math
10
+ import statistics
11
+
12
+ def get_eav24_hl0(throttle, gear, brake):
13
+ return {
14
+ "HL_TargetThrottle": throttle,
15
+ "HL_TargetGear": gear,
16
+ "HL_TargetPressure_RR": brake,
17
+ "HL_TargetPressure_RL": brake,
18
+ "HL_TargetPressure_FR": brake,
19
+ "HL_TargetPressure_FL": brake,
20
+ "HL_Alive_01": 0
21
+ }
22
+
23
+ def get_eav24_hl2(steer):
24
+ return {
25
+ "HL_Alive_02": 0,
26
+ "HL_PSA_Profile_Vel_rad_s": 0,
27
+ "HL_PSA_Profile_Dec_rad_s2": 0,
28
+ "HL_PSA_Profile_Acc_rad_s2": 0,
29
+ "HL_TargetPSAControl": steer,
30
+ "HL_PSA_ModeOfOperation": 0
31
+ }
32
+
33
+ def get_eav24_msigs(dbc, throttle, gear, brake, steer):
34
+ return {
35
+ dbc.get_message_by_name('HL_Msg_01'): get_eav24_hl0(throttle, gear, brake),
36
+ dbc.get_message_by_name('HL_Msg_02'): get_eav24_hl2(steer)
37
+ }
38
+
39
+ def send_eav24_can_values(can_name, dbc, throttle, gear, brake, steer, duration, rate = 100):
40
+ with can.interface.Bus(can_name, bustype='socketcan') as bus:
41
+ message_1 = dbc.get_message_by_name('HL_Msg_01')
42
+ message_2 = dbc.get_message_by_name('HL_Msg_02')
43
+ print('sending EAV24 CAN inputs on {} with throttle {}, gear {}, brake {}, steer {}, for {} seconds'.format(can_name, throttle, gear, brake, steer, duration))
44
+ signals_1 = get_eav24_hl0(throttle, gear, brake)
45
+ signals_2 = get_eav24_hl2(steer)
46
+
47
+ msigs = get_eav24_msigs(dbc, throttle, gear, brake, steer)
48
+ send_eav24_can_signals(bus, msigs, rate, duration)
49
+
50
+ def send_eav24_can_signals(bus, message_signals, rate, duration):
51
+ start_time = time.time()
52
+ while time.time() - start_time < duration:
53
+ for msg, sig in message_signals.items():
54
+ bus.send(can.Message(arbitration_id=msg.frame_id, data=msg.encode(sig), is_extended_id=False))
55
+ time.sleep(1.0 / rate)
56
+
57
+ def test_eav24_can_latency(can_name, dbc, nsamples, send_rate, duration, save_report_as):
58
+ with can.interface.Bus(can_name, bustype='socketcan') as bus:
59
+ delays = []
60
+ times = []
61
+
62
+ for i in range(nsamples):
63
+ print('test {}'.format(i))
64
+ start_time = time.time()
65
+ last_throttle_time = time.time()
66
+ last_throttle_value = 50;
67
+
68
+ msigs = get_eav24_msigs(dbc, last_throttle_value, 1, 0, 0)
69
+
70
+ send_thread = threading.Thread(target=send_eav24_can_signals, args=(bus, msigs, send_rate, duration))
71
+ send_thread.start()
72
+
73
+ is_back_to_zero = False
74
+ while not is_back_to_zero:
75
+ message = bus.recv()
76
+ if message is not None:
77
+ decoded = decode_can_message(dbc, message)
78
+ if decoded and decoded['name'] == 'ICE_Status_01':
79
+ ack_value = decoded['data']['ICE_TargetThrottle_ACK']
80
+ if math.isclose(ack_value, last_throttle_value):
81
+ t = time.time()
82
+ #print('got throttle ack matching command at t{}'.format(t - last_throttle_time))
83
+ delay = t - last_throttle_time
84
+ delays.append(delay)
85
+ times.append(t)
86
+ print('got throttle ack for command {} after {} seconds'.format(last_throttle_value, delay))
87
+ if last_throttle_value == 0:
88
+ is_back_to_zero = True
89
+ send_thread.join()
90
+ else:
91
+ last_throttle_value = 0
92
+ msigs = get_eav24_msigs(dbc, last_throttle_value, 1, 0, 0)
93
+ send_thread.join()
94
+ send_thread = threading.Thread(target=send_eav24_can_signals, args=(bus, msigs, send_rate, duration))
95
+ send_thread.start()
96
+ last_throttle_time = time.time()
97
+
98
+ # Plot results
99
+ avg_delay = statistics.mean(delays)
100
+ print('avg delay {}, min delay {}, max dealy {}'.format(avg_delay, min(delays), max(delays)))
101
+
102
+ if save_report_as != '':
103
+ print('saving report to {}'.format(save_report_as))
104
+ report = {
105
+ 'average_delay': avg_delay,
106
+ 'min_delay': min(delays),
107
+ 'max_delay': max(delays),
108
+ 'num_samples': nsamples
109
+ }
110
+ with open(save_report_as, 'w', encoding='utf-8') as f:
111
+ json.dump(report, f, ensure_ascii=False, indent=4)
112
+
113
+
114
+ def echo_can(can_names, dbcs, duration, isolate, do_rates, save_report_as):
115
+ start_time = time.time()
116
+ report = {}
117
+ rates = {}
118
+ print_interval = 1.0
119
+ last_print = start_time
120
+
121
+ jobs = []
122
+ print_lock = threading.Lock()
123
+ for n in can_names:
124
+ echo_thread = threading.Thread(target=echo_can_job, args=(n, dbcs, duration, isolate, do_rates, rates, print_lock))
125
+ echo_thread.start()
126
+ jobs.append(echo_thread)
127
+
128
+ while time.time() - start_time < duration:
129
+ t = time.time()
130
+ if do_rates and t - last_print > print_interval:
131
+ last_print = t
132
+ for r in rates:
133
+ print('{} rate: {}hz ({} samples)'.format(r, 1.0 / rates[r]['rate'], rates[r]['ct']))
134
+ print('=' * 15)
135
+
136
+ for j in jobs:
137
+ j.join()
138
+
139
+ if do_rates and save_report_as != '':
140
+ print('saving report to {}'.format(save_report_as))
141
+ with open(save_report_as, 'w', encoding='utf-8') as f:
142
+ json.dump(rates, f, ensure_ascii=False, indent=4)
143
+
144
+ def echo_can_job(can_name, dbcs, duration, isolate, do_rates, out_rate_data, print_lock):
145
+ start_time = time.time()
146
+ with can.interface.Bus(can_name, bustype='socketcan') as bus:
147
+ while time.time() - start_time < duration:
148
+ message = bus.recv()
149
+ if message is not None:
150
+ for db in dbcs:
151
+ decoded = decode_can_message(db, message)
152
+ if decoded is not None and (len(isolate) == 0 or decoded['name'] in isolate):
153
+ update_can_rate_stats(decoded, out_rate_data, start_time)
154
+ if not do_rates and print_lock.acquire(True):
155
+ print(decoded)
156
+ print_lock.release()
157
+
158
+ def decode_can_message(dbc, message):
159
+ try:
160
+ decoded_message = dbc.decode_message(message.arbitration_id, message.data)
161
+ message_name = dbc.get_message_by_frame_id(message.arbitration_id).name
162
+ timestamp = datetime.datetime.now().isoformat()
163
+ return {'timestamp': timestamp, 'name': message_name, 'data': decoded_message}
164
+ except KeyError:
165
+ return None
166
+
167
+ def update_can_rate_stats(message, rates, start_time):
168
+ if not message['name'] in rates:
169
+ rates[message['name']] = {
170
+ 'prev_t': start_time,
171
+ 'rate': time.time() - start_time,
172
+ 'ct': 0,
173
+ 'min': 100000000,
174
+ 'max': 0.0000001
175
+ }
176
+ r = rates[message['name']]['rate']
177
+ t = rates[message['name']]['prev_t']
178
+ ct = rates[message['name']]['ct'] + 1
179
+ dt = time.time() - t
180
+ rate_diff = dt - r
181
+ rates[message['name']]['rate'] = r + (1.0 / ct) * rate_diff
182
+ rates[message['name']]['ct'] = ct
183
+ rates[message['name']]['prev_t'] = time.time()
184
+
185
+ this_rate = 1.0 / dt
186
+ if this_rate > rates[message['name']]['max']:
187
+ rates[message['name']]['max'] = this_rate
188
+ elif this_rate < rates[message['name']]['min']:
189
+ rates[message['name']]['min'] = this_rate
190
+
@@ -0,0 +1,78 @@
1
+ import json
2
+ import os
3
+ import shutil
4
+
5
+ def get_cfg_dir(cli_name):
6
+ return os.path.join(os.environ['HOME'], '.config', cli_name)
7
+
8
+ def get_cfg_file(cli_name):
9
+ return os.path.join(get_cfg_dir(cli_name), 'config.json')
10
+
11
+ def load_cfg(cli_name):
12
+ cfg_dir = get_cfg_dir(cli_name)
13
+ if not os.path.exists(cfg_dir):
14
+ os.makedirs(cfg_dir)
15
+
16
+ cfg_path = get_cfg_file(cli_name)
17
+ cfg = {}
18
+
19
+ if os.path.exists(cfg_path):
20
+ with open(cfg_path, 'r', encoding='utf-8') as f:
21
+ cfg = json.load(f)
22
+ return cfg
23
+
24
+ def save_cfg(cli_name, cfg):
25
+ cfg_path = get_cfg_file(cli_name)
26
+ with open(cfg_path, 'w', encoding='utf-8') as f:
27
+ json.dump(cfg, f, ensure_ascii=False, indent=4)
28
+
29
+ # Save a file to be re-used later to a cached location
30
+ def add_cached_file(cli_name, category, file_to_cache, overwrite_ok):
31
+ if not os.path.exists(file_to_cache):
32
+ return (False, '{} is not a valid file'.format(file_to_cache))
33
+ cfg = load_cfg(cli_name)
34
+ if '__cached_files__' not in cfg:
35
+ cfg['__cached_files__'] = {}
36
+ if category not in cfg['__cached_files__']:
37
+ cfg['__cached_files__'][category] = []
38
+ file_to_cache_name = os.path.basename(file_to_cache)
39
+ cfg['__cached_files__'][category].append(file_to_cache_name)
40
+ cat_path = os.path.join(get_cfg_dir(cli_name), category)
41
+ if not os.path.exists(cat_path):
42
+ os.makedirs(cat_path)
43
+ cache_path = os.path.join(cat_path, file_to_cache_name)
44
+ if os.path.isfile(cache_path) and not overwrite_ok:
45
+ return (False, '{} already exists and overwrite not specified as ok'.format(cache_path))
46
+ shutil.copyfile(file_to_cache, cache_path)
47
+ save_cfg(cli_name, cfg)
48
+ return (True, '{} cached to {}'.format(file_to_cache, cache_path))
49
+
50
+ # Get a file previously cached
51
+ def get_cached_file(cli_name, category, file_to_get):
52
+ cfg = load_cfg(cli_name)
53
+ if '__cached_files__' not in cfg:
54
+ return (False, 'no cached files')
55
+ if category not in cfg['__cached_files__']:
56
+ return (False, 'cached file {} not found'.format(file_to_get))
57
+ cache_path = os.path.join(get_cfg_dir(cli_name), category, file_to_get)
58
+ cf = cfg['__cached_files__'][category]
59
+ # Check by index
60
+ try:
61
+ file_index = int(file_to_get)
62
+ if file_index > -1 and file_index < len(cf):
63
+ cache_path = os.path.join(get_cfg_dir(cli_name), category, cf[file_index])
64
+ else:
65
+ return (False, '{} is not a valid file index'.format(file_index))
66
+ except Exception as e:
67
+ pass
68
+ if not os.path.exists(cache_path):
69
+ return (False, 'failed to get cached file at {}'.format(cache_path))
70
+ return (True, cache_path)
71
+
72
+ def get_cached_file_list(cli_name, category):
73
+ cfg = load_cfg(cli_name)
74
+ if '__cached_files__' not in cfg:
75
+ return []
76
+ if category not in cfg['__cached_files__']:
77
+ return []
78
+ return cfg['__cached_files__'][category]
@@ -98,7 +98,7 @@ class AvrsLauncher:
98
98
 
99
99
  file_path = args.install_path
100
100
  if not os.path.exists(file_path):
101
- print('Cannot Install Simulator at: {} (Invalid Path)'.format(file_path))
101
+ print('Cannot Install Simulator at: {} (Invalid Path, Specify a Directory)'.format(file_path))
102
102
  return
103
103
 
104
104
  # Validate status of download keys
@@ -143,6 +143,12 @@ If you are sure, re-run with the --update-existing flag
143
143
  '''.format(unzip_path))
144
144
  return
145
145
 
146
+ if not is_installed_sim(unzip_path):
147
+ if not 'installs' in self.cfg:
148
+ self.cfg['installs'] = []
149
+ self.cfg['installs'].append(unzip_path)
150
+ save_cfg('avrs', self.cfg)
151
+
146
152
  print('Downloading {} to {}. This May Take Several Minutes Depending on Connection Speed'.format(bucket_path, dl_path))
147
153
  download_simulator_archive(self.cfg, bucket_path, dl_path)
148
154
 
@@ -124,6 +124,9 @@ def download_simulator_archive(cfg, source_path, target_path):
124
124
  aws_secret_access_key=cfg['dlkey'])
125
125
  s3_download_with_progress(s3_client, 'autoverse-builds', source_path, target_path)
126
126
 
127
+ def get_sim_saved_dir(sim_install_path):
128
+ return os.path.join(sim_install_path, 'Linux', 'Autoverse', 'Saved')
129
+
127
130
  def is_installed_sim(file_path):
128
131
  """
129
132
  Check if the given path appears to be the root of
@@ -5,9 +5,7 @@ class AvrsDemoRequest(AvrsApiRequest):
5
5
  AvrsApiRequest.__init__(self, parser, cfg, 'DemoSendConfig', '')
6
6
  psr = parser.add_parser('demo', help='Sends a request used for a demonstration')
7
7
  psr.add_argument('--ego-type-index', type=int, default=0, help='')
8
- psr.add_argument('--num-npcs', type=int, default=0, help='')
9
- psr.add_argument('--npc-trajs', type=int, default=[0, 0, 0, 0], nargs='+', help='')
10
- psr.add_argument('--npc-type-index', default=0, type=int)
8
+ psr.add_argument('--npc-density', type=int)
11
9
  psr.add_argument('--env-type-index', default=0, type=int)
12
10
  psr.add_argument('--weather-type-index', default=0, type=int)
13
11
  psr.set_defaults(func=self.send_request)
@@ -15,9 +13,7 @@ class AvrsDemoRequest(AvrsApiRequest):
15
13
  def get_request_body(self, args):
16
14
  return {
17
15
  'IndexEgoType': args.ego_type_index,
18
- 'NumberNPCS': args.num_npcs,
19
- 'NPCTrajectories': args.npc_trajs,
20
- 'IndexNPCType': args.npc_type_index,
16
+ 'NpcDensity': args.npc_density,
21
17
  'IndexEnvironmentType': args.env_type_index,
22
- 'TypeIndexIndex': args.weather_type_index
18
+ 'indexWeatherType': args.weather_type_index
23
19
  }