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.
- {autoverse_cli-0.4.1.dist-info → autoverse_cli-0.6.0.dist-info}/METADATA +2 -1
- autoverse_cli-0.6.0.dist-info/RECORD +37 -0
- {autoverse_cli-0.4.1.dist-info → autoverse_cli-0.6.0.dist-info}/WHEEL +1 -1
- avrs/app_version.py +1 -1
- avrs/avrs.py +29 -8
- avrs/can_tool.py +192 -0
- avrs/can_tool_util.py +190 -0
- avrs/cfg.py +53 -1
- avrs/launcher.py +7 -1
- avrs/launcher_util.py +3 -0
- avrs/requests/change_camera.py +11 -0
- avrs/requests/demo.py +3 -7
- avrs/requests/{edit_environment.py → environment.py} +15 -3
- avrs/requests/fault_injection.py +186 -0
- avrs/requests/list_sim_objects.py +26 -0
- avrs/requests/request.py +4 -1
- avrs/requests/scenario_control.py +43 -0
- avrs/requests/toggle_hud.py +11 -0
- avrs/requests/vehicle_input.py +21 -0
- avrs/requests/vehicle_replay.py +235 -0
- avrs/simconfig.py +61 -0
- avrs/simconfig_util.py +70 -0
- autoverse_cli-0.4.1.dist-info/RECORD +0 -28
- avrs/requests/can.py +0 -131
- avrs/requests/input.py +0 -46
- {autoverse_cli-0.4.1.dist-info → autoverse_cli-0.6.0.dist-info}/LICENSE +0 -0
- {autoverse_cli-0.4.1.dist-info → autoverse_cli-0.6.0.dist-info}/entry_points.txt +0 -0
- {autoverse_cli-0.4.1.dist-info → autoverse_cli-0.6.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: autoverse-cli
|
3
|
-
Version: 0.
|
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,,
|
avrs/app_version.py
CHANGED
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.
|
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.
|
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
|
-
|
69
|
+
AvrsConfigureVehicleInputRequest(sps, cfg)
|
59
70
|
LogPath(sps, cfg)
|
60
|
-
|
71
|
+
AvrsEnvironmentRequests(sps, cfg)
|
61
72
|
AvrsCodeBoozRequest(sps, cfg)
|
62
|
-
|
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('--
|
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
|
-
'
|
19
|
-
'NPCTrajectories': args.npc_trajs,
|
20
|
-
'IndexNPCType': args.npc_type_index,
|
16
|
+
'NpcDensity': args.npc_density,
|
21
17
|
'IndexEnvironmentType': args.env_type_index,
|
22
|
-
'
|
18
|
+
'indexWeatherType': args.weather_type_index
|
23
19
|
}
|