autoverse-cli 0.4.1__tar.gz → 0.6.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/PKG-INFO +2 -1
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/pyproject.toml +3 -2
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/autoverse_cli.egg-info/PKG-INFO +2 -1
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/autoverse_cli.egg-info/SOURCES.txt +13 -4
- autoverse_cli-0.6.0/src/autoverse_cli.egg-info/requires.txt +2 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/app_version.py +1 -1
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/avrs.py +29 -8
- autoverse_cli-0.6.0/src/avrs/can_tool.py +192 -0
- autoverse_cli-0.6.0/src/avrs/can_tool_util.py +190 -0
- autoverse_cli-0.6.0/src/avrs/cfg.py +78 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/launcher.py +7 -1
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/launcher_util.py +3 -0
- autoverse_cli-0.6.0/src/avrs/requests/change_camera.py +11 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/requests/demo.py +3 -7
- autoverse_cli-0.4.1/src/avrs/requests/edit_environment.py → autoverse_cli-0.6.0/src/avrs/requests/environment.py +15 -3
- autoverse_cli-0.6.0/src/avrs/requests/fault_injection.py +186 -0
- autoverse_cli-0.6.0/src/avrs/requests/list_sim_objects.py +26 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/requests/request.py +4 -1
- autoverse_cli-0.6.0/src/avrs/requests/scenario_control.py +43 -0
- autoverse_cli-0.6.0/src/avrs/requests/toggle_hud.py +11 -0
- autoverse_cli-0.6.0/src/avrs/requests/vehicle_input.py +21 -0
- autoverse_cli-0.6.0/src/avrs/requests/vehicle_replay.py +235 -0
- autoverse_cli-0.6.0/src/avrs/simconfig.py +61 -0
- autoverse_cli-0.6.0/src/avrs/simconfig_util.py +70 -0
- autoverse_cli-0.4.1/src/autoverse_cli.egg-info/requires.txt +0 -1
- autoverse_cli-0.4.1/src/avrs/cfg.py +0 -26
- autoverse_cli-0.4.1/src/avrs/requests/can.py +0 -131
- autoverse_cli-0.4.1/src/avrs/requests/input.py +0 -46
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/LICENSE +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/README.md +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/setup.cfg +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/autoverse_cli.egg-info/dependency_links.txt +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/autoverse_cli.egg-info/entry_points.txt +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/autoverse_cli.egg-info/top_level.txt +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/__init__.py +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/argparse_help.py +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/requests/code_booz.py +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/requests/log_path.py +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/requests/move_to_landmark.py +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/requests/npc.py +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/requests/reserve_mv_slot.py +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/requests/reset_to_track.py +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/requests/restart.py +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/requests/teleport.py +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.0}/src/avrs/requests/vd.py +0 -0
- {autoverse_cli-0.4.1 → autoverse_cli-0.6.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.
|
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
|
|
@@ -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
|
|
@@ -11,15 +11,20 @@ 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/
|
22
|
+
src/avrs/requests/change_camera.py
|
19
23
|
src/avrs/requests/code_booz.py
|
20
24
|
src/avrs/requests/demo.py
|
21
|
-
src/avrs/requests/
|
22
|
-
src/avrs/requests/
|
25
|
+
src/avrs/requests/environment.py
|
26
|
+
src/avrs/requests/fault_injection.py
|
27
|
+
src/avrs/requests/list_sim_objects.py
|
23
28
|
src/avrs/requests/log_path.py
|
24
29
|
src/avrs/requests/move_to_landmark.py
|
25
30
|
src/avrs/requests/npc.py
|
@@ -27,5 +32,9 @@ src/avrs/requests/request.py
|
|
27
32
|
src/avrs/requests/reserve_mv_slot.py
|
28
33
|
src/avrs/requests/reset_to_track.py
|
29
34
|
src/avrs/requests/restart.py
|
35
|
+
src/avrs/requests/scenario_control.py
|
30
36
|
src/avrs/requests/teleport.py
|
31
|
-
src/avrs/requests/
|
37
|
+
src/avrs/requests/toggle_hud.py
|
38
|
+
src/avrs/requests/vd.py
|
39
|
+
src/avrs/requests/vehicle_input.py
|
40
|
+
src/avrs/requests/vehicle_replay.py
|
@@ -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)
|
@@ -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
|
@@ -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
|
+
}
|