autoverse-cli 0.4.1__py3-none-any.whl → 0.6.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: autoverse-cli
3
- Version: 0.4.1
3
+ Version: 0.6.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
 
@@ -0,0 +1,37 @@
1
+ avrs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ avrs/app_version.py,sha256=MRoy99DwudgXSSMa5eP0kVNc3PCETDrhmmPJC6NtIc8,855
3
+ avrs/argparse_help.py,sha256=EoEaohGXZXqJvs1dFEzbo9vh47CYdHdSY2Im2Ps2iFo,945
4
+ avrs/avrs.py,sha256=6fV-br7njgk1fOmv2G2gz0JDqBMpz_OhecZRojG4B-c,2685
5
+ avrs/can_tool.py,sha256=IBoctKobBJ3wCq4ZdtuXuXH4AMEUxazCfYT6YP0Luw8,7161
6
+ avrs/can_tool_util.py,sha256=G3q21dTGMLc09SDq_RieoW7kSn-kXPkXxPDjavPh4hQ,7710
7
+ avrs/cfg.py,sha256=kMn08Z4Ms1PAu2-U1QI8weEJeIVEppP4A4_tFfwnjtg,2924
8
+ avrs/launcher.py,sha256=u7COEMvvkqxeGyW0kd2m6KK4375nWY5ONO4TxKJ2Xt4,7710
9
+ avrs/launcher_util.py,sha256=y_F2YvIe81l3B1_lCjpoOgkbE4hAr2C9eaPio0es34o,5236
10
+ avrs/simconfig.py,sha256=CtpIeU32Lfsek37Z4XR4mjSKwF27IlYvC92184VOuuQ,2389
11
+ avrs/simconfig_util.py,sha256=R3ggjx1fIdOAHpUroNLjH6gg0G07PbFTI4PfwUOWtdw,2277
12
+ avrs/tests.py,sha256=3JeYBjn0tRqHXERDROfzmYuW1KXeCcKur5Bw-EIegto,153
13
+ avrs/requests/change_camera.py,sha256=twqdE049DHwdjgKFZbindwpK7Oz-ivCjbI8WQj8QsxI,416
14
+ avrs/requests/code_booz.py,sha256=5bzT8Ra6EIwI19TqXMxkHG_llnyFgqSzTSo7yLNV9Vc,2274
15
+ avrs/requests/demo.py,sha256=cbGQJK-OfeFUkQwVzafHgoWP15xoKL-ZgYkQ7moEt2A,872
16
+ avrs/requests/environment.py,sha256=ORwOBxhXPcatn_W8aY5pgIy4f2paUbqIYii5oE540xA,1305
17
+ avrs/requests/fault_injection.py,sha256=EkpjPCx-UtrNbAR_vQS1zaGKN49UDCyYOoVcdlP1T0M,5948
18
+ avrs/requests/list_sim_objects.py,sha256=YWpqHdCHijerPxI5606_KjeFvezcLFN33wO4YOr9G3U,977
19
+ avrs/requests/log_path.py,sha256=Ur24C9VqPVx78MfpicgQu2uOEe-0dXbGoWF_7dzMtZE,1326
20
+ avrs/requests/move_to_landmark.py,sha256=cLRBKu9XEDsmCoftBJ8JwoBLqzb0IZsxFMBnus4T-kc,702
21
+ avrs/requests/npc.py,sha256=Y_WovbcLomCCcOLAMMO_DHZtc1crAzWo97qEIGS3SvU,9691
22
+ avrs/requests/request.py,sha256=1g_0NLpKRRdHW10LAPa9N1jW3zZSdq8yUQFeAPyErtE,1595
23
+ avrs/requests/reserve_mv_slot.py,sha256=p_jiTV7rcoyJU6u3UR9sqPBpSaq8-PWMEs0Ckm2Hf8w,3843
24
+ avrs/requests/reset_to_track.py,sha256=lSd2YavBxDV_hQMhVoi08_TpTFEq7G2MA18xosFYa1g,450
25
+ avrs/requests/restart.py,sha256=ih5mnWiU34q3-xhOth45CtOUXxKI0PoMDCnFJV0JbwE,415
26
+ avrs/requests/scenario_control.py,sha256=u-KQx-mdCm6IE_c88a6iEgWUsZZVOayxBo58Ocjg0ZI,1502
27
+ avrs/requests/teleport.py,sha256=WpnB2-Ii0FGI11EXTAHlaF5zqZIsgEyJnJ2j_w4rDFY,824
28
+ avrs/requests/toggle_hud.py,sha256=sV5t5QZc4uvRihPVk8jEKZiQNsyF9tsUwq5b4jjZplc,397
29
+ avrs/requests/vd.py,sha256=at6oUAGY2h0OxYU6MLOi1gnxyUn6i24vL9DUAj0L880,1600
30
+ avrs/requests/vehicle_input.py,sha256=R1b1xkRtOBkwyU6OSN4bWVlYsIUroZG0WKbYbc4pEH8,729
31
+ avrs/requests/vehicle_replay.py,sha256=wlfkieaSrpXZCsyjtM6fociRXWpBLGZXhaJAS1sNS0o,7603
32
+ autoverse_cli-0.6.0.dist-info/LICENSE,sha256=d4eWXho-u18HkBsX4K21uHX_bBb2UXZSrJdsb7Z_JlM,2647
33
+ autoverse_cli-0.6.0.dist-info/METADATA,sha256=a4uddOOnI-EuiR0BH9prt_l7aLEPJXVjJ1CouGs5bdU,3341
34
+ autoverse_cli-0.6.0.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
35
+ autoverse_cli-0.6.0.dist-info/entry_points.txt,sha256=Cb9qsUyU5AKkklehCcvtfT0-N3SXbUEqvjze4iEU5kE,40
36
+ autoverse_cli-0.6.0.dist-info/top_level.txt,sha256=-AJO2e4MCVej6hY0U84pu5NfMeMW5qaAPSMisDT5rmA,5
37
+ autoverse_cli-0.6.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.1.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
avrs/app_version.py CHANGED
@@ -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.6.0'
6
6
 
7
7
  def check_app_is_latest():
8
8
  pass
avrs/avrs.py CHANGED
@@ -6,21 +6,28 @@ 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.requests.change_camera import *
29
+ from avrs.requests.toggle_hud import *
30
+ from avrs.simconfig import *
24
31
 
25
32
 
26
33
  def get_version():
@@ -39,6 +46,11 @@ def main():
39
46
  action='version',
40
47
  version=get_version())
41
48
 
49
+ parser.add_argument(
50
+ '--verbose',
51
+ action='store_true',
52
+ help='request verbose output')
53
+
42
54
  sps = parser.add_subparsers(required=True, help='sub-command help')
43
55
 
44
56
  cfg = load_cfg('avrs')
@@ -50,16 +62,25 @@ def main():
50
62
  MoveToLandmarkRequest(sps, cfg)
51
63
  Restart(sps, cfg)
52
64
  ResetToTrack(sps, cfg)
53
- #Can(sps, cfg)
54
65
  Teleport(sps, cfg)
55
- Npc(sps, cfg)
66
+ #Npc(sps, cfg)
56
67
  ReserveMvSlot(sps, cfg)
57
68
  Vd(sps, cfg)
58
- #InputRequest(sps, cfg)
69
+ AvrsConfigureVehicleInputRequest(sps, cfg)
59
70
  LogPath(sps, cfg)
60
- AvrsEditEnvironmentRequests(sps, cfg)
71
+ AvrsEnvironmentRequests(sps, cfg)
61
72
  AvrsCodeBoozRequest(sps, cfg)
62
- AvrsDemoRequest(sps, cfg)
73
+ AvrsVehicleReplayRequests(sps, cfg)
74
+ AvrsCanTool(sps, cfg)
75
+ AvrsSimConfig(sps, cfg)
76
+ AvrsScenarioRequests(sps, cfg)
77
+ AvrsListSimObjectsRequest(sps, cfg)
78
+ AvrsFaultInjectionRequests(sps, cfg)
79
+ AvrsChangeCameraRequest(sps, cfg)
80
+ AvrsToggleHudRequest(sps, cfg)
81
+
82
+ if os.environ.get('AVRS_WITH_DEMO', '0') == '1':
83
+ AvrsDemoRequest(sps, cfg)
63
84
 
64
85
  if os.environ.get('AVRS_GEN_DOCS', '0') == '1':
65
86
  generate_argparse_docs(parser)
avrs/can_tool.py ADDED
@@ -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
avrs/can_tool_util.py ADDED
@@ -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
+
avrs/cfg.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import json
2
2
  import os
3
+ import shutil
3
4
 
4
5
  def get_cfg_dir(cli_name):
5
6
  return os.path.join(os.environ['HOME'], '.config', cli_name)
@@ -23,4 +24,55 @@ def load_cfg(cli_name):
23
24
  def save_cfg(cli_name, cfg):
24
25
  cfg_path = get_cfg_file(cli_name)
25
26
  with open(cfg_path, 'w', encoding='utf-8') as f:
26
- json.dump(cfg, f, ensure_ascii=False, indent=4)
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]
avrs/launcher.py CHANGED
@@ -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
 
avrs/launcher_util.py CHANGED
@@ -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
@@ -0,0 +1,11 @@
1
+ from avrs.requests.request import AvrsApiRequest
2
+
3
+ class AvrsChangeCameraRequest(AvrsApiRequest):
4
+ def __init__(self, parser, cfg):
5
+ AvrsApiRequest.__init__(self, parser, cfg, 'ChangeCamera', '')
6
+ psr = parser.add_parser('change-camera', help='changes the active camera on an object')
7
+ psr.set_defaults(func=self.send_request)
8
+
9
+ def get_request_body(self, args):
10
+ return {
11
+ }
avrs/requests/demo.py CHANGED
@@ -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
  }