autoverse-cli 0.10.0__py3-none-any.whl → 0.12.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- {autoverse_cli-0.10.0.dist-info → autoverse_cli-0.12.0.dist-info}/METADATA +2 -2
- {autoverse_cli-0.10.0.dist-info → autoverse_cli-0.12.0.dist-info}/RECORD +16 -12
- {autoverse_cli-0.10.0.dist-info → autoverse_cli-0.12.0.dist-info}/WHEEL +1 -1
- avrs/app_version.py +1 -1
- avrs/avrs.py +4 -2
- avrs/launcher.py +7 -1
- avrs/race_cloud.py +296 -0
- avrs/race_cloud_cfg_util.py +106 -0
- avrs/race_cloud_util.py +233 -0
- avrs/requests/dump_sim_config.py +14 -0
- avrs/requests/request.py +6 -1
- avrs/simconfig_util.py +4 -4
- avrs/util.py +13 -0
- avrs/requests/reserve_mv_slot.py +0 -112
- {autoverse_cli-0.10.0.dist-info → autoverse_cli-0.12.0.dist-info}/LICENSE +0 -0
- {autoverse_cli-0.10.0.dist-info → autoverse_cli-0.12.0.dist-info}/entry_points.txt +0 -0
- {autoverse_cli-0.10.0.dist-info → autoverse_cli-0.12.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: autoverse-cli
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.12.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
|
@@ -1,18 +1,23 @@
|
|
1
1
|
avrs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
avrs/app_version.py,sha256=
|
2
|
+
avrs/app_version.py,sha256=9ek4oQUrw4LCuL_LBEOl-PELxqV3zFIeueOnbkxOwBY,856
|
3
3
|
avrs/argparse_help.py,sha256=EoEaohGXZXqJvs1dFEzbo9vh47CYdHdSY2Im2Ps2iFo,945
|
4
|
-
avrs/avrs.py,sha256=
|
4
|
+
avrs/avrs.py,sha256=Y8rmsJiRjrnJ4U-aUvqyA4ZwFowCIAqOBGe1DED7QYs,3050
|
5
5
|
avrs/can_tool.py,sha256=IBoctKobBJ3wCq4ZdtuXuXH4AMEUxazCfYT6YP0Luw8,7161
|
6
6
|
avrs/can_tool_util.py,sha256=G3q21dTGMLc09SDq_RieoW7kSn-kXPkXxPDjavPh4hQ,7710
|
7
7
|
avrs/cfg.py,sha256=kMn08Z4Ms1PAu2-U1QI8weEJeIVEppP4A4_tFfwnjtg,2924
|
8
|
-
avrs/launcher.py,sha256=
|
8
|
+
avrs/launcher.py,sha256=Kzrxp6FYCmujiT0Y5dk-sCt8vaY6Z4qKKZk8YUTEuVw,9235
|
9
9
|
avrs/launcher_util.py,sha256=sO3k_z3A-HIQdJVkVXNXUAE_MGFwAYiZUqQBoFwOqew,5325
|
10
|
+
avrs/race_cloud.py,sha256=bSSM4jIEHEHWwOzlj244ls5kNuBShvGRcdaJJTxeJbs,10850
|
11
|
+
avrs/race_cloud_cfg_util.py,sha256=Vd7r1nILo4fW5I8sh4AiAInKSsQkFFTXaIeYlNapo5U,3292
|
12
|
+
avrs/race_cloud_util.py,sha256=v2E9DbUNFdVRx-A1frRuXKa3MHZAoXzCu2k4jFupsLk,8274
|
10
13
|
avrs/simconfig.py,sha256=UZc4FrxVHUkk2e9IglSpuojXkaL_nPrJW7trbEGgOOo,2907
|
11
|
-
avrs/simconfig_util.py,sha256=
|
14
|
+
avrs/simconfig_util.py,sha256=1RmnmhK5C4HlCicTQeqn-1ORz3Xrku_QMt1Fqr9XjZs,4839
|
12
15
|
avrs/tests.py,sha256=3JeYBjn0tRqHXERDROfzmYuW1KXeCcKur5Bw-EIegto,153
|
16
|
+
avrs/util.py,sha256=SB8Jgsh8IpFdpy3pWPuEoYExLed9XimEAMtYn4gU42g,301
|
13
17
|
avrs/requests/change_camera.py,sha256=twqdE049DHwdjgKFZbindwpK7Oz-ivCjbI8WQj8QsxI,416
|
14
18
|
avrs/requests/code_booz.py,sha256=SXaEAMTqID4lf1o_4Cc1wY9609X-dNcfNa-UZv3FWF4,2471
|
15
19
|
avrs/requests/demo.py,sha256=cbGQJK-OfeFUkQwVzafHgoWP15xoKL-ZgYkQ7moEt2A,872
|
20
|
+
avrs/requests/dump_sim_config.py,sha256=ePtJZhq3gYLgMQkbi-YObIAaPk3Z2b0NWlWM5IYkCaM,479
|
16
21
|
avrs/requests/environment.py,sha256=ORwOBxhXPcatn_W8aY5pgIy4f2paUbqIYii5oE540xA,1305
|
17
22
|
avrs/requests/fault_injection.py,sha256=EkpjPCx-UtrNbAR_vQS1zaGKN49UDCyYOoVcdlP1T0M,5948
|
18
23
|
avrs/requests/get_object_config.py,sha256=Mkwp32lfskQERsqfmAgHi4vf4C0hfjg6Ru8UjyMt3cw,654
|
@@ -21,8 +26,7 @@ avrs/requests/log_path.py,sha256=Ur24C9VqPVx78MfpicgQu2uOEe-0dXbGoWF_7dzMtZE,132
|
|
21
26
|
avrs/requests/misc.py,sha256=lejEFt5aB6tbfKXHI1DGwP4fsntFIv16NXO23R6Bfhw,1423
|
22
27
|
avrs/requests/move_to_landmark.py,sha256=cLRBKu9XEDsmCoftBJ8JwoBLqzb0IZsxFMBnus4T-kc,702
|
23
28
|
avrs/requests/npc.py,sha256=Y_WovbcLomCCcOLAMMO_DHZtc1crAzWo97qEIGS3SvU,9691
|
24
|
-
avrs/requests/request.py,sha256=
|
25
|
-
avrs/requests/reserve_mv_slot.py,sha256=ejB_RSZBXCpxY7B_2f66Or8twKdMI1gn9nEQgZ2YYEY,3843
|
29
|
+
avrs/requests/request.py,sha256=2czr4N1CndDpWOKuvWozf0oWqiVKcZS7sHdJjBrMKsk,1834
|
26
30
|
avrs/requests/reset_to_track.py,sha256=lSd2YavBxDV_hQMhVoi08_TpTFEq7G2MA18xosFYa1g,450
|
27
31
|
avrs/requests/restart.py,sha256=ih5mnWiU34q3-xhOth45CtOUXxKI0PoMDCnFJV0JbwE,415
|
28
32
|
avrs/requests/scenario_control.py,sha256=u-KQx-mdCm6IE_c88a6iEgWUsZZVOayxBo58Ocjg0ZI,1502
|
@@ -32,9 +36,9 @@ avrs/requests/toggle_hud.py,sha256=sV5t5QZc4uvRihPVk8jEKZiQNsyF9tsUwq5b4jjZplc,3
|
|
32
36
|
avrs/requests/vd.py,sha256=at6oUAGY2h0OxYU6MLOi1gnxyUn6i24vL9DUAj0L880,1600
|
33
37
|
avrs/requests/vehicle_input.py,sha256=R1b1xkRtOBkwyU6OSN4bWVlYsIUroZG0WKbYbc4pEH8,729
|
34
38
|
avrs/requests/vehicle_replay.py,sha256=nCAE21VNyKoeIjjXBGAihgOLO7zYHcu-HWvPZYxdQ2c,11099
|
35
|
-
autoverse_cli-0.
|
36
|
-
autoverse_cli-0.
|
37
|
-
autoverse_cli-0.
|
38
|
-
autoverse_cli-0.
|
39
|
-
autoverse_cli-0.
|
40
|
-
autoverse_cli-0.
|
39
|
+
autoverse_cli-0.12.0.dist-info/LICENSE,sha256=d4eWXho-u18HkBsX4K21uHX_bBb2UXZSrJdsb7Z_JlM,2647
|
40
|
+
autoverse_cli-0.12.0.dist-info/METADATA,sha256=petmY7Ss5yPLlXyS9UBIWwFvYXOGEC46Nysu8yW0igc,3342
|
41
|
+
autoverse_cli-0.12.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
42
|
+
autoverse_cli-0.12.0.dist-info/entry_points.txt,sha256=Cb9qsUyU5AKkklehCcvtfT0-N3SXbUEqvjze4iEU5kE,40
|
43
|
+
autoverse_cli-0.12.0.dist-info/top_level.txt,sha256=-AJO2e4MCVej6hY0U84pu5NfMeMW5qaAPSMisDT5rmA,5
|
44
|
+
autoverse_cli-0.12.0.dist-info/RECORD,,
|
avrs/app_version.py
CHANGED
avrs/avrs.py
CHANGED
@@ -7,6 +7,7 @@ from avrs.app_version import *
|
|
7
7
|
from avrs.cfg import *
|
8
8
|
from avrs.launcher import *
|
9
9
|
from avrs.can_tool import *
|
10
|
+
from avrs.race_cloud import *
|
10
11
|
from avrs.argparse_help import *
|
11
12
|
|
12
13
|
from avrs.requests.move_to_landmark import MoveToLandmarkRequest
|
@@ -14,7 +15,6 @@ from avrs.requests.restart import Restart
|
|
14
15
|
from avrs.requests.reset_to_track import ResetToTrack
|
15
16
|
from avrs.requests.teleport import Teleport
|
16
17
|
from avrs.requests.npc import Npc
|
17
|
-
from avrs.requests.reserve_mv_slot import ReserveMvSlot
|
18
18
|
from avrs.requests.vd import Vd
|
19
19
|
from avrs.requests.vehicle_input import AvrsConfigureVehicleInputRequest
|
20
20
|
from avrs.requests.log_path import LogPath
|
@@ -31,6 +31,7 @@ from avrs.simconfig import *
|
|
31
31
|
from avrs.requests.get_object_config import *
|
32
32
|
from avrs.requests.misc import *
|
33
33
|
from avrs.requests.spawn_object import *
|
34
|
+
from avrs.requests.dump_sim_config import *
|
34
35
|
|
35
36
|
|
36
37
|
def get_version():
|
@@ -67,7 +68,7 @@ def main():
|
|
67
68
|
ResetToTrack(sps, cfg)
|
68
69
|
Teleport(sps, cfg)
|
69
70
|
#Npc(sps, cfg)
|
70
|
-
|
71
|
+
AvrsRaceCloud(sps, cfg)
|
71
72
|
Vd(sps, cfg)
|
72
73
|
AvrsConfigureVehicleInputRequest(sps, cfg)
|
73
74
|
LogPath(sps, cfg)
|
@@ -86,6 +87,7 @@ def main():
|
|
86
87
|
AvrsPingRequest(sps, cfg)
|
87
88
|
AvrsConfigureSimLodRequest(sps, cfg)
|
88
89
|
AvrsSpawnObjectRequest(sps, cfg)
|
90
|
+
AvrsDumpSimConfigRequest(sps, cfg)
|
89
91
|
|
90
92
|
if os.environ.get('AVRS_WITH_DEMO', '0') == '1':
|
91
93
|
AvrsDemoRequest(sps, cfg)
|
avrs/launcher.py
CHANGED
@@ -40,6 +40,7 @@ class AvrsLauncher:
|
|
40
40
|
download_sim_psr = sps.add_parser('download-simulator', help='download the simulator')
|
41
41
|
download_sim_psr.add_argument('variant', help='which variant of the simulator to download (eg, \"a2rl-iron\" or \"a2rl-humble\")')
|
42
42
|
download_sim_psr.add_argument('install_path', help='path to install the simulator')
|
43
|
+
download_sim_psr.add_argument('--target-version', default='', help='specify a version other than the most recent to download')
|
43
44
|
download_sim_psr.add_argument(
|
44
45
|
'--copy-saved-from',
|
45
46
|
default='',
|
@@ -157,7 +158,12 @@ class AvrsLauncher:
|
|
157
158
|
copy_saved_cache = os.path.join(args.install_path, 'autoverse-saved-cache')
|
158
159
|
shutil.copytree(copy_from_saved_dir, copy_saved_cache)
|
159
160
|
|
160
|
-
|
161
|
+
target_version = latest_version
|
162
|
+
if args.target_version != '':
|
163
|
+
target_version = args.target_version
|
164
|
+
print('attempting to download specified version: {}'.format(target_version))
|
165
|
+
|
166
|
+
package_zip_name = 'autoverse-linux-{}.zip'.format(target_version)
|
161
167
|
package_name = 'autoverse-linux'
|
162
168
|
bucket_path = '{}/{}'.format(args.variant, package_zip_name)
|
163
169
|
dl_path = os.path.join(args.install_path, package_zip_name)
|
avrs/race_cloud.py
ADDED
@@ -0,0 +1,296 @@
|
|
1
|
+
import subprocess
|
2
|
+
import base64
|
3
|
+
from avrs.cfg import *
|
4
|
+
from avrs.race_cloud_util import *
|
5
|
+
from avrs.race_cloud_cfg_util import *
|
6
|
+
from avrs.util import *
|
7
|
+
from avrs.requests.request import AvrsApiRequest
|
8
|
+
from argparse import RawTextHelpFormatter
|
9
|
+
|
10
|
+
class AvrsRaceCloud(AvrsApiRequest):
|
11
|
+
def __init__(self, parser, cfg):
|
12
|
+
self.cfg = cfg
|
13
|
+
race_cloud_parser = parser.add_parser(
|
14
|
+
'race-cloud',
|
15
|
+
help='cloud racing\n\n')
|
16
|
+
|
17
|
+
sps = race_cloud_parser.add_subparsers(required=True, help='race-cloud options')
|
18
|
+
|
19
|
+
connect_parser = sps.add_parser(
|
20
|
+
'connect',
|
21
|
+
help='connect to an instance for cloud racing')
|
22
|
+
connect_parser.add_argument(
|
23
|
+
'sim_index',
|
24
|
+
type = int,
|
25
|
+
choices = [0, 1, 2, 3, 4, 5],
|
26
|
+
help='the index of the simulator instance to connect to')
|
27
|
+
connect_parser.add_argument(
|
28
|
+
'team_name',
|
29
|
+
help='the name of the team to race under')
|
30
|
+
connect_parser.add_argument(
|
31
|
+
'vehicle_config',
|
32
|
+
help='the path the vehicle configuration file to use when racing')
|
33
|
+
connect_parser.add_argument(
|
34
|
+
'--instance-id',
|
35
|
+
default = '',
|
36
|
+
help='can be used directly instead of instance name if needed')
|
37
|
+
connect_parser.add_argument(
|
38
|
+
'--no-check-cans',
|
39
|
+
action='store_true',
|
40
|
+
help='if set, vcan interfaces will not be checked for validity')
|
41
|
+
connect_parser.set_defaults(func=self.race_connect)
|
42
|
+
|
43
|
+
rx_connect_parser = sps.add_parser(
|
44
|
+
'rx-connection',
|
45
|
+
help='execute steps to receive a connection (only relevant to sim-side)')
|
46
|
+
rx_connect_parser.add_argument(
|
47
|
+
'team_name',
|
48
|
+
help='the name of the connecting team')
|
49
|
+
rx_connect_parser.add_argument(
|
50
|
+
'ip',
|
51
|
+
help='the ip address of the incoming connection')
|
52
|
+
rx_connect_parser.add_argument(
|
53
|
+
'cfg_data',
|
54
|
+
help='the incoming vehicle configuration data')
|
55
|
+
rx_connect_parser.set_defaults(func=self.rx_connect)
|
56
|
+
|
57
|
+
sim_ctrl_parser = sps.add_parser(
|
58
|
+
'sim-ctrl',
|
59
|
+
help='control the sim program (start, stop, restart, reset)')
|
60
|
+
sim_ctrl_parser.add_argument(
|
61
|
+
'sim_index',
|
62
|
+
type=int,
|
63
|
+
choices=[0, 1, 2, 3, 4, 5],
|
64
|
+
help='the index of the simulator instance to apply the action')
|
65
|
+
sim_ctrl_parser.add_argument(
|
66
|
+
'action',
|
67
|
+
choices=['start', 'stop', 'restart', 'reset-connection'],
|
68
|
+
help='what action to apply to the simulator program')
|
69
|
+
sim_ctrl_parser.add_argument(
|
70
|
+
'--local',
|
71
|
+
action='store_true',
|
72
|
+
help='if set, this command will run on this system locally (not for use from dev instances)')
|
73
|
+
sim_ctrl_parser.add_argument(
|
74
|
+
'--instance-id',
|
75
|
+
default = '',
|
76
|
+
help='can be used directly instead of sim index if needed')
|
77
|
+
sim_ctrl_parser.add_argument(
|
78
|
+
'--clear-autospawns',
|
79
|
+
action='store_true',
|
80
|
+
help='can be used with the reset-connection action to clear sim autospawn config')
|
81
|
+
sim_ctrl_parser.set_defaults(func=self.sim_ctrl)
|
82
|
+
|
83
|
+
reset_qos_parser = sps.add_parser(
|
84
|
+
'reset-qos',
|
85
|
+
help='reset the qos file on this system')
|
86
|
+
reset_qos_parser.set_defaults(func=self.reset_qos)
|
87
|
+
|
88
|
+
enable_peer_qos_parser = sps.add_parser(
|
89
|
+
'enable-peer-qos',
|
90
|
+
help='enable a peer in this systems qos file')
|
91
|
+
enable_peer_qos_parser.add_argument(
|
92
|
+
'peer_id',
|
93
|
+
type=int,
|
94
|
+
choices=[0, 1, 2, 3, 4, 5],
|
95
|
+
help='the id of the peer to enable')
|
96
|
+
enable_peer_qos_parser.add_argument(
|
97
|
+
'ip',
|
98
|
+
help='the ip address to add to the qos file')
|
99
|
+
enable_peer_qos_parser.set_defaults(func=self.enable_peer_qos)
|
100
|
+
|
101
|
+
disable_peer_qos_parser = sps.add_parser(
|
102
|
+
'disable-peer-qos',
|
103
|
+
help='disable a peer in this systems qos file')
|
104
|
+
disable_peer_qos_parser.add_argument(
|
105
|
+
'peer_id',
|
106
|
+
type=int,
|
107
|
+
choices=[0, 1, 2, 3, 4, 5],
|
108
|
+
help='the id of the peer to enable')
|
109
|
+
disable_peer_qos_parser.set_defaults(func=self.disable_peer_qos)
|
110
|
+
|
111
|
+
|
112
|
+
def race_connect(self, args):
|
113
|
+
print('connecting to race with team name: {}'.format(args.team_name))
|
114
|
+
|
115
|
+
# validate / load vehicle config
|
116
|
+
|
117
|
+
vcfg_ok, vcfg_data, bsu_vcan, kistler_vcan, badenia_vcan = prepare_vehicle_cfg(args.vehicle_config)
|
118
|
+
|
119
|
+
if not vcfg_ok:
|
120
|
+
print('error sending config file: {}'.format(vcfg_data))
|
121
|
+
return
|
122
|
+
|
123
|
+
vcan_ok = True
|
124
|
+
if not check_vcan_exists(bsu_vcan) and not args.no_check_cans:
|
125
|
+
print('bsu vcan {} does not appear to exist'.format(bsu_vcan))
|
126
|
+
vcan_ok = False
|
127
|
+
if not check_vcan_exists(kistler_vcan) and not args.no_check_cans:
|
128
|
+
print('kistler vcan {} does not appear to exist'.format(kistler_vcan))
|
129
|
+
vcan_ok = False
|
130
|
+
if not check_vcan_exists(badenia_vcan) and not args.no_check_cans:
|
131
|
+
print('badenia vcan {} does not appear to exist'.format(badenia_vcan))
|
132
|
+
vcan_ok = False
|
133
|
+
|
134
|
+
if not vcan_ok:
|
135
|
+
return
|
136
|
+
|
137
|
+
# make api call to begin connection
|
138
|
+
our_ip = get_local_instance_ip()
|
139
|
+
|
140
|
+
connection_request = {
|
141
|
+
'action': 'connect',
|
142
|
+
'sim_index': args.sim_index,
|
143
|
+
'ip_to_reserve': our_ip,
|
144
|
+
'team_name': args.team_name,
|
145
|
+
'sim_id_override': args.instance_id,
|
146
|
+
'ensure_instance_is_running': False,
|
147
|
+
'config_data': vcfg_data
|
148
|
+
}
|
149
|
+
|
150
|
+
ok, response = call_race_cloud_api(connection_request)
|
151
|
+
if not ok:
|
152
|
+
print('connect api error: {}'.format(response))
|
153
|
+
|
154
|
+
ok, rbody, sim_ip = get_api_script_response(response)
|
155
|
+
if not ok:
|
156
|
+
print(rbody)
|
157
|
+
return
|
158
|
+
|
159
|
+
#print(rbody)
|
160
|
+
#print(sim_ip)
|
161
|
+
|
162
|
+
slot_info = {}
|
163
|
+
for k, v in rbody.items():
|
164
|
+
#print('out: {}'.format(v['stdout']))
|
165
|
+
#print('err: {}'.format(v['stderr']))
|
166
|
+
slot_info = json.loads(v['stdout'])
|
167
|
+
|
168
|
+
if not slot_info['ok']:
|
169
|
+
print('issue reserving slot: {}'.format(slot_info['msg']))
|
170
|
+
return
|
171
|
+
|
172
|
+
sim_slot = slot_info['slot']
|
173
|
+
|
174
|
+
# enable first peer since this is on a client (only will ever have 1, the sim)
|
175
|
+
enable_peer_qos(sim_slot, sim_ip)
|
176
|
+
|
177
|
+
# will need to get port from received slot id to connect peer vcans
|
178
|
+
connect_peer_vcan(sim_slot, sim_ip, 0, bsu_vcan)
|
179
|
+
connect_peer_vcan(sim_slot, sim_ip, 1, kistler_vcan)
|
180
|
+
connect_peer_vcan(sim_slot, sim_ip, 2, badenia_vcan)
|
181
|
+
|
182
|
+
# configure the CLI to communicate with the cloud sim instance
|
183
|
+
self.cfg['sim_address'] = sim_ip
|
184
|
+
save_cfg('avrs', self.cfg)
|
185
|
+
|
186
|
+
print('connection success with team name {} and slot id {}'.format(args.team_name, sim_slot))
|
187
|
+
|
188
|
+
# this should only run on sim instances (not dev instances)
|
189
|
+
def rx_connect(self, args):
|
190
|
+
ok, msg, slot = try_get_open_slot(args.team_name, args.ip)
|
191
|
+
|
192
|
+
bsu_vcan = get_auto_vcan_name(slot, 0)
|
193
|
+
kistler_vcan = get_auto_vcan_name(slot, 1)
|
194
|
+
badenia_vcan = get_auto_vcan_name(slot, 2)
|
195
|
+
|
196
|
+
# get CAN names from this
|
197
|
+
register_received_vehicle(
|
198
|
+
args.team_name, slot, args.cfg_data, bsu_vcan, kistler_vcan, badenia_vcan)
|
199
|
+
|
200
|
+
vcan_ok = True
|
201
|
+
vcan_msg = ''
|
202
|
+
if not check_vcan_exists(bsu_vcan):
|
203
|
+
vcan_msg = 'bsu vcan {} does not appear to exist'.format()
|
204
|
+
vcan_ok = False
|
205
|
+
if not check_vcan_exists(kistler_vcan):
|
206
|
+
vcan_msg = 'kistler vcan {} does not appear to exist'.format()
|
207
|
+
vcan_ok = False
|
208
|
+
if not check_vcan_exists(badenia_vcan):
|
209
|
+
vcan_msg = 'badenia vcan {} does not appear to exist'.format()
|
210
|
+
vcan_ok = False
|
211
|
+
|
212
|
+
if not vcan_ok:
|
213
|
+
print(json.dumps({
|
214
|
+
'ok': vcan_ok,
|
215
|
+
'msg': vcan_msg,
|
216
|
+
'slot': -1
|
217
|
+
}))
|
218
|
+
return
|
219
|
+
|
220
|
+
if ok:
|
221
|
+
enable_peer_qos(slot, args.ip)
|
222
|
+
connect_peer_vcan(slot, args.ip, 0)
|
223
|
+
connect_peer_vcan(slot, args.ip, 1)
|
224
|
+
connect_peer_vcan(slot, args.ip, 2)
|
225
|
+
|
226
|
+
response = {
|
227
|
+
'ok': ok,
|
228
|
+
'msg': msg,
|
229
|
+
'slot': slot
|
230
|
+
}
|
231
|
+
|
232
|
+
print(json.dumps(response)) # print this so that when called from the ssh lambda we can get the result
|
233
|
+
|
234
|
+
def sim_ctrl(self, args):
|
235
|
+
if args.local:
|
236
|
+
self.local_sim_ctrl(args)
|
237
|
+
else:
|
238
|
+
self.remote_sim_ctrl(args)
|
239
|
+
|
240
|
+
def local_sim_ctrl(self, args):
|
241
|
+
if args.action == 'reset-connection':
|
242
|
+
print('resetting race cloud connection')
|
243
|
+
print('resetting qos file, removing CAN lock files, stopping all cannelloni instances')
|
244
|
+
reset_race_cloud_connection()
|
245
|
+
if args.clear_autospawns:
|
246
|
+
clear_autospawns()
|
247
|
+
if args.action == 'stop' or args.action == 'restart':
|
248
|
+
print('stopping sim program on sim instance {}'.format(args.sim_index))
|
249
|
+
bash_kill_process('Autoverse')
|
250
|
+
if args.action == 'start' or args.action == 'restart':
|
251
|
+
print('starting sim program on sim instance {}'.format(args.sim_index))
|
252
|
+
exe_path = os.path.join(get_sim_install_path(), 'Linux', 'Autoverse.sh')
|
253
|
+
start_exe(exe_path)
|
254
|
+
|
255
|
+
def remote_sim_ctrl(self, args):
|
256
|
+
|
257
|
+
# go ahead and reset local connection as well
|
258
|
+
if args.action == 'reset-connection':
|
259
|
+
reset_race_cloud_connection()
|
260
|
+
|
261
|
+
our_ip = get_local_instance_ip()
|
262
|
+
|
263
|
+
reset_request = {
|
264
|
+
'action': args.action,
|
265
|
+
'sim_index': args.sim_index,
|
266
|
+
'ip_to_reserve': our_ip,
|
267
|
+
'sim_id_override': args.instance_id,
|
268
|
+
'ensure_instance_is_running': False
|
269
|
+
}
|
270
|
+
|
271
|
+
ok, response = call_race_cloud_api(reset_request)
|
272
|
+
#print(response)
|
273
|
+
if not ok:
|
274
|
+
print(response)
|
275
|
+
return
|
276
|
+
|
277
|
+
ok, rbody, sim_ip = get_api_script_response(response)
|
278
|
+
if not ok:
|
279
|
+
print(rbody)
|
280
|
+
return
|
281
|
+
|
282
|
+
for k, v in rbody.items():
|
283
|
+
print(v['stdout'])
|
284
|
+
|
285
|
+
def reset_qos(self, args):
|
286
|
+
print('resetting qos file')
|
287
|
+
reset_rmw_qos()
|
288
|
+
|
289
|
+
def enable_peer_qos(self, args):
|
290
|
+
print('enabling peer qos for id {} using ip address {}'.format(
|
291
|
+
args.peer_id, args.ip))
|
292
|
+
enable_peer_qos(args.peer_id, args.ip)
|
293
|
+
|
294
|
+
def disable_peer_qos(self, args):
|
295
|
+
print('disabling peer qos for id {}'.format(args.peer_id))
|
296
|
+
disable_peer_qos(args.peer_id)
|
@@ -0,0 +1,106 @@
|
|
1
|
+
import os
|
2
|
+
import json
|
3
|
+
import base64
|
4
|
+
|
5
|
+
from avrs.simconfig_util import *
|
6
|
+
|
7
|
+
def get_payload(cfg_object, payload_name):
|
8
|
+
for p in cfg_object['payloads']:
|
9
|
+
if p['typeName'] == payload_name:
|
10
|
+
return p
|
11
|
+
return None
|
12
|
+
|
13
|
+
def clear_autospawns():
|
14
|
+
# also need to edit the yas_marina_env.json to have autospawn for this config
|
15
|
+
sim_path = os.environ.get('AVRS_INSTALL_PATH',
|
16
|
+
os.path.join(os.environ['HOME'], 'autoverse-linux'))
|
17
|
+
sim_saved = os.path.join(sim_path, 'Linux', 'Autoverse', 'Saved')
|
18
|
+
cfg_files = SimConfigFiles(sim_saved)
|
19
|
+
|
20
|
+
cfg_ok, msg = cfg_files.validate()
|
21
|
+
if not cfg_ok:
|
22
|
+
print(msg)
|
23
|
+
return
|
24
|
+
|
25
|
+
cfg_files.files['yas']['autoSpawnObjects'] = []
|
26
|
+
cfg_files.save()
|
27
|
+
|
28
|
+
def register_received_vehicle(team_name, slot, cfg_data, bsu_vcan, kistler_vcan, badenia_vcan):
|
29
|
+
cfg_string = base64.b64decode(cfg_data)
|
30
|
+
cfg_object = json.loads(cfg_string.decode('utf-8'))
|
31
|
+
|
32
|
+
# ensure perception is disabled
|
33
|
+
eav24 = get_payload(cfg_object, 'Eav24Initializer')
|
34
|
+
if eav24 is None:
|
35
|
+
return (False, 'no eav24 payload found')
|
36
|
+
|
37
|
+
eav24['body']['bLidarEnabled'] = False
|
38
|
+
eav24['body']['bCameraEnabled'] = False
|
39
|
+
eav24['body']['bRadarEnabled'] = False
|
40
|
+
eav24['body']['bPublishGroundTruth'] = False
|
41
|
+
eav24['body']['bPublishInputs'] = False
|
42
|
+
eav24['body']['bsuCanName'] = bsu_vcan
|
43
|
+
eav24['body']['kistlerCanName'] = kistler_vcan
|
44
|
+
eav24['body']['badeniaCanName'] = badenia_vcan
|
45
|
+
|
46
|
+
# do not allow default object name (collision)
|
47
|
+
if cfg_object['name'] == 'eav24':
|
48
|
+
cfg_object['name'] = team_name
|
49
|
+
cfg_object['specName'] = 'eav24_{}'.format(team_name)
|
50
|
+
|
51
|
+
# also need to edit the yas_marina_env.json to have autospawn for this config
|
52
|
+
sim_path = os.environ.get('AVRS_INSTALL_PATH',
|
53
|
+
os.path.join(os.environ['HOME'], 'autoverse-linux'))
|
54
|
+
sim_saved = os.path.join(sim_path, 'Linux', 'Autoverse', 'Saved')
|
55
|
+
cfg_files = SimConfigFiles(sim_saved)
|
56
|
+
|
57
|
+
cfg_ok, msg = cfg_files.validate()
|
58
|
+
if not cfg_ok:
|
59
|
+
print(msg)
|
60
|
+
return
|
61
|
+
|
62
|
+
start_landmark = 'MvStart{}'.format(slot)
|
63
|
+
|
64
|
+
entry_exists = False
|
65
|
+
for i in cfg_files.files['yas']['autoSpawnObjects']:
|
66
|
+
if 'objectSpec' in i and i['objectSpec'] == cfg_object['specName']:
|
67
|
+
entry_exists = True
|
68
|
+
|
69
|
+
if not entry_exists:
|
70
|
+
cfg_files.files['yas']['autoSpawnObjects'].append({
|
71
|
+
'bShouldSpawn': True,
|
72
|
+
'objectType': 'Eav24',
|
73
|
+
'objectSpec': cfg_object['specName'],
|
74
|
+
'bSpawnAtLandmark': True,
|
75
|
+
'spawnLandmarkName': start_landmark
|
76
|
+
})
|
77
|
+
cfg_files.save()
|
78
|
+
|
79
|
+
target_path = os.path.join(os.environ['HOME'], 'test_cfg.json')
|
80
|
+
with open(target_path, 'w', encoding='utf-8') as f:
|
81
|
+
json.dump(cfg_object, f, ensure_ascii=False, indent=4)
|
82
|
+
|
83
|
+
def prepare_vehicle_cfg(cfg_path):
|
84
|
+
|
85
|
+
#print('preparing config for transmission: {}'.format(cfg_path))
|
86
|
+
|
87
|
+
if not os.path.isfile(cfg_path):
|
88
|
+
return (False, '{} is not a valid file'.format(cfg_path))
|
89
|
+
|
90
|
+
cfg_object = {}
|
91
|
+
with open(cfg_path, 'r', encoding='utf-8') as f:
|
92
|
+
cfg_object = json.load(f)
|
93
|
+
|
94
|
+
|
95
|
+
# obtain desired CAN names to start cannelloni
|
96
|
+
eav24 = get_payload(cfg_object, 'Eav24Initializer')
|
97
|
+
if eav24 is None:
|
98
|
+
return (False, 'no eav24 payload found')
|
99
|
+
|
100
|
+
bsu_vcan = eav24['body']['bsuCanName']
|
101
|
+
kistler_vcan = eav24['body']['kistlerCanName']
|
102
|
+
badenia_vcan = eav24['body']['badeniaCanName']
|
103
|
+
|
104
|
+
cfg_data = base64.b64encode(json.dumps(cfg_object).encode('utf-8')).decode('utf-8')
|
105
|
+
return (True, cfg_data, bsu_vcan, kistler_vcan, badenia_vcan)
|
106
|
+
|
avrs/race_cloud_util.py
ADDED
@@ -0,0 +1,233 @@
|
|
1
|
+
import os
|
2
|
+
import json
|
3
|
+
import http.client
|
4
|
+
from avrs.util import *
|
5
|
+
|
6
|
+
BASH_KILL_PROCESS_SCRIPT = '''
|
7
|
+
PROC_NAME={pname}
|
8
|
+
I=0
|
9
|
+
TRIES=20
|
10
|
+
while [ $I -le $TRIES ]; do
|
11
|
+
|
12
|
+
pkill $PROC_NAME
|
13
|
+
PROC_RUNNING=$(ps -A | grep $PROC_NAME)
|
14
|
+
if [[ ! -z $PROC_RUNNING ]]; then
|
15
|
+
echo process $PROC_NAME is still running
|
16
|
+
if [ $I == $(( TRIES - 1 )) ]; then
|
17
|
+
echo process is resisting. crushing its dreams with sigkill
|
18
|
+
pkill -SIGKILL $PROC_NAME
|
19
|
+
fi
|
20
|
+
else
|
21
|
+
echo process $PROC_NAME is not running
|
22
|
+
break
|
23
|
+
fi
|
24
|
+
I=$(( I + 1 ))
|
25
|
+
sleep 1
|
26
|
+
done
|
27
|
+
'''
|
28
|
+
|
29
|
+
DEFAULT_RMW_QOS = '''
|
30
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
31
|
+
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
|
32
|
+
<transport_descriptors>
|
33
|
+
<transport_descriptor>
|
34
|
+
<transport_id>morepeers</transport_id> <!-- string -->
|
35
|
+
<type>UDPv4</type> <!-- string -->
|
36
|
+
<maxInitialPeersRange>100</maxInitialPeersRange> <!-- uint32 -->
|
37
|
+
</transport_descriptor>
|
38
|
+
</transport_descriptors>
|
39
|
+
<participant profile_name="participant_profile_ros2" is_default_profile="true">
|
40
|
+
<rtps>
|
41
|
+
<builtin>
|
42
|
+
<metatrafficUnicastLocatorList>
|
43
|
+
<locator/>
|
44
|
+
</metatrafficUnicastLocatorList>
|
45
|
+
<initialPeersList>
|
46
|
+
<locator> <udpv4> <address>127.0.0.1</address> </udpv4> </locator>
|
47
|
+
<!--<locator> <udpv4> <address>PEER_0</address> </udpv4> </locator>PEER0-->
|
48
|
+
<!--<locator> <udpv4> <address>PEER_1</address> </udpv4> </locator>PEER1-->
|
49
|
+
<!--<locator> <udpv4> <address>PEER_2</address> </udpv4> </locator>PEER2-->
|
50
|
+
<!--<locator> <udpv4> <address>PEER_3</address> </udpv4> </locator>PEER3-->
|
51
|
+
<!--<locator> <udpv4> <address>PEER_4</address> </udpv4> </locator>PEER4-->
|
52
|
+
<!--<locator> <udpv4> <address>PEER_5</address> </udpv4> </locator>PEER5-->
|
53
|
+
</initialPeersList>
|
54
|
+
</builtin>
|
55
|
+
<userTransports>
|
56
|
+
<transport_id>morepeers</transport_id>
|
57
|
+
</userTransports>
|
58
|
+
<useBuiltinTransports>false</useBuiltinTransports>
|
59
|
+
</rtps>
|
60
|
+
</participant>
|
61
|
+
</profiles>
|
62
|
+
'''
|
63
|
+
|
64
|
+
DISABLE_PEER_QOS_SCRIPT = '''
|
65
|
+
QOS_FILE_PATH={qos_path}
|
66
|
+
PEER_ID={peer_id}
|
67
|
+
sed -i -E "s,(<locator> <udpv4> <address>)(.+)(</address> </udpv4> </locator>)<!--(PEER$PEER_ID-->),<!--\\1PEER$PEER_ID\\3\\4,g" $QOS_FILE_PATH
|
68
|
+
|
69
|
+
VCAN_NAME=vcan$PEER_ID
|
70
|
+
if [[ -e $VCAN_NAME.lock ]]; then
|
71
|
+
echo "stopping existing cannelloni connection with pid $(cat $VCAN_NAME.lock)"
|
72
|
+
kill $(cat $VCAN_NAME.lock)
|
73
|
+
rm $VCAN_NAME.lock
|
74
|
+
fi
|
75
|
+
'''
|
76
|
+
|
77
|
+
ENABLE_PEER_QOS_SCRIPT = '''
|
78
|
+
QOS_FILE_PATH={qos_path}
|
79
|
+
PEER_ID={peer_id}
|
80
|
+
PEER_ADDRESS={peer_ip}
|
81
|
+
sed -i -E "s,(<!--?)(<locator> <udpv4> <address>)(.+)(</address> </udpv4> </locator>)(PEER$PEER_ID-->),\\2$PEER_ADDRESS\\4<!--\\5,g" $QOS_FILE_PATH
|
82
|
+
'''
|
83
|
+
|
84
|
+
CONNECT_PEER_VCAN_SCRIPT = '''
|
85
|
+
PEER_ID={peer_id}
|
86
|
+
PEER_ADDRESS={peer_ip}
|
87
|
+
REMOTE_PORT={remote_port}
|
88
|
+
LOCAL_PORT={local_port}
|
89
|
+
VCAN_NAME={vcan_name}
|
90
|
+
LOCK_FILE=$HOME/.$VCAN_NAME.lock
|
91
|
+
LOG_FILE="$HOME/.$VCAN_NAME.log"
|
92
|
+
if [[ -z $VCAN_NAME ]]; then
|
93
|
+
VCAN_NAME=vcan$PEER_ID
|
94
|
+
fi
|
95
|
+
echo "connecting peer id $PEER_ID using local port $LOCAL_PORT and remote port $REMOTE_PORT and vcan name $VCAN_NAME"
|
96
|
+
|
97
|
+
if [[ -e $LOCK_FILE ]]; then
|
98
|
+
echo "stopping existing cannelloni connection with pid $(cat $LOCK_FILE)"
|
99
|
+
kill $(cat $LOCK_FILE)
|
100
|
+
fi
|
101
|
+
|
102
|
+
# https://stackoverflow.com/questions/29142/getting-ssh-to-execute-a-command-in-the-background-on-target-machine
|
103
|
+
# nohup to avoid SSH issues, send stdout to loni.log, send stderr to stdout, dont expect input, and background with "&"
|
104
|
+
nohup cannelloni -I $VCAN_NAME -R $PEER_ADDRESS -r $REMOTE_PORT -l $LOCAL_PORT >"$LOG_FILE" 2>&1 < /dev/null &
|
105
|
+
echo "$!" > $LOCK_FILE
|
106
|
+
'''
|
107
|
+
|
108
|
+
CHECK_VCAN_EXISTS_SCRIPT = '''
|
109
|
+
if [[ -z $(ip addr show | grep {vcan_name}) ]]; then
|
110
|
+
echo -n "no"
|
111
|
+
else
|
112
|
+
echo -n "yes"
|
113
|
+
fi
|
114
|
+
'''
|
115
|
+
|
116
|
+
# kill a process with a given name
|
117
|
+
def bash_kill_process(pname):
|
118
|
+
return run_process(['bash', '-c',
|
119
|
+
BASH_KILL_PROCESS_SCRIPT.format(**{'pname': pname})])
|
120
|
+
|
121
|
+
# start an exectuable in the background, sending output to a file
|
122
|
+
# stored at root with its name
|
123
|
+
def start_exe(exe_path):
|
124
|
+
return run_process(['bash', '-c',
|
125
|
+
'nohup {} > ~/{}_output.log 2>&1 < /dev/null &'.format(exe_path, os.path.basename(exe_path))])
|
126
|
+
|
127
|
+
def get_sim_install_path():
|
128
|
+
sim_path = os.environ.get('AVRS_INSTALL_PATH',
|
129
|
+
os.path.join(os.environ['HOME'], 'autoverse-linux'))
|
130
|
+
return sim_path
|
131
|
+
|
132
|
+
def get_rmw_qos_path():
|
133
|
+
return os.path.join(os.environ['HOME'], '.rmw_qos.xml')
|
134
|
+
|
135
|
+
def reset_rmw_qos():
|
136
|
+
with open(get_rmw_qos_path(), 'w', encoding='utf-8') as f:
|
137
|
+
f.write(DEFAULT_RMW_QOS)
|
138
|
+
|
139
|
+
def disable_peer_qos(peer_id):
|
140
|
+
if not os.path.isfile(get_rmw_qos_path()):
|
141
|
+
reset_rmw_qos()
|
142
|
+
pargs = {
|
143
|
+
'qos_path': get_rmw_qos_path(),
|
144
|
+
'peer_id': peer_id
|
145
|
+
}
|
146
|
+
return run_process(['bash', '-c',
|
147
|
+
DISABLE_PEER_QOS_SCRIPT.format(**pargs)])
|
148
|
+
|
149
|
+
def enable_peer_qos(peer_id, peer_ip):
|
150
|
+
disable_peer_qos(peer_ip) # disable first
|
151
|
+
pargs = {
|
152
|
+
'qos_path': get_rmw_qos_path(),
|
153
|
+
'peer_id': peer_id,
|
154
|
+
'peer_ip': peer_ip
|
155
|
+
}
|
156
|
+
return run_process(['bash', '-c',
|
157
|
+
ENABLE_PEER_QOS_SCRIPT.format(**pargs)])
|
158
|
+
|
159
|
+
def check_vcan_exists(vcan_name):
|
160
|
+
pargs = {
|
161
|
+
'vcan_name': vcan_name
|
162
|
+
}
|
163
|
+
pres = run_process(['bash', '-c',
|
164
|
+
CHECK_VCAN_EXISTS_SCRIPT.format(**pargs)])
|
165
|
+
return pres.out == 'yes'
|
166
|
+
|
167
|
+
def get_auto_vcan_name(peer_id, vcan_id):
|
168
|
+
return 'vcan{}_{}'.format(peer_id, vcan_id)
|
169
|
+
|
170
|
+
def connect_peer_vcan(peer_id, peer_ip, vcan_id, vcan_name=''):
|
171
|
+
vcan_id = 0
|
172
|
+
pargs = {
|
173
|
+
'peer_id': peer_id,
|
174
|
+
'peer_ip': peer_ip,
|
175
|
+
'remote_port': 20000 + peer_id * 3 + vcan_id, # three ports per peer_id
|
176
|
+
'local_port': 20000 + peer_id * 3 + vcan_id,
|
177
|
+
'vcan_name': vcan_name if vcan_name != '' else get_auto_vcan_name(peer_id, vcan_id)
|
178
|
+
}
|
179
|
+
return run_process(['bash', '-c',
|
180
|
+
CONNECT_PEER_VCAN_SCRIPT.format(**pargs)])
|
181
|
+
|
182
|
+
def get_local_instance_ip():
|
183
|
+
try:
|
184
|
+
pres = run_process(['ec2metadata', '--local-ipv4'])
|
185
|
+
return pres.out
|
186
|
+
except:
|
187
|
+
return '127.0.0.1'
|
188
|
+
|
189
|
+
def reset_race_cloud_connection():
|
190
|
+
reset_rmw_qos()
|
191
|
+
run_process(['bash', '-c', 'rm ~/.simslot*']) # remove slot reservations
|
192
|
+
run_process(['bash', '-c', 'rm ~/.vcan*']) # remove lock files
|
193
|
+
bash_kill_process('cannelloni')
|
194
|
+
|
195
|
+
def try_get_open_slot(team_name, ip):
|
196
|
+
|
197
|
+
slot_file_dir = os.environ['HOME']
|
198
|
+
for i in range(6):
|
199
|
+
slot_file_path = os.path.join(slot_file_dir, '.simslot_{}'.format(i))
|
200
|
+
|
201
|
+
if os.path.isfile(slot_file_path):
|
202
|
+
with open(slot_file_path, 'r', encoding='utf-8') as f:
|
203
|
+
content = f.read()
|
204
|
+
if content == ip:
|
205
|
+
return (True, 'slot {} is already reserved by you'.format(i), i)
|
206
|
+
else:
|
207
|
+
with open(slot_file_path, 'w', encoding='utf-8') as f:
|
208
|
+
f.write(ip)
|
209
|
+
return (True, 'reserved slot {}'.format(i), i)
|
210
|
+
return (False, 'no open slots', i)
|
211
|
+
|
212
|
+
|
213
|
+
def call_race_cloud_api(body):
|
214
|
+
api_url = 'gitzels0l7.execute-api.us-east-1.amazonaws.com'
|
215
|
+
|
216
|
+
connection = http.client.HTTPSConnection(api_url)
|
217
|
+
headers = {
|
218
|
+
'Content-type': 'application/json',
|
219
|
+
'x-api-key': '7aQ83sJ89Q2DZ8NdIi9aUTBuUS2uyix5QoDwrl1j'
|
220
|
+
}
|
221
|
+
body = json.dumps(body).encode('utf-8')
|
222
|
+
connection.request('POST', '/beta/connect', body, headers)
|
223
|
+
response = connection.getresponse()
|
224
|
+
if response.status != 200:
|
225
|
+
return (False, 'response had status code {}'.format(response))
|
226
|
+
return (True, response.read().decode('utf-8'))
|
227
|
+
|
228
|
+
def get_api_script_response(raw):
|
229
|
+
decoded = json.loads(raw)['body']
|
230
|
+
if decoded['script_response']['statusCode'] != 200:
|
231
|
+
return (False, 'inner response had bad status code {}'.format(decoded))
|
232
|
+
#print(decoded)
|
233
|
+
return (True, json.loads(decoded['script_response']['body']), decoded['sim_private_ip'])
|
@@ -0,0 +1,14 @@
|
|
1
|
+
from avrs.requests.request import AvrsApiRequest
|
2
|
+
|
3
|
+
class AvrsDumpSimConfigRequest(AvrsApiRequest):
|
4
|
+
def __init__(self, parser, cfg):
|
5
|
+
AvrsApiRequest.__init__(self, parser, cfg, 'DumpSimConfig', '')
|
6
|
+
psr = parser.add_parser(
|
7
|
+
'dump-sim-config',
|
8
|
+
help='dump all currently loaded configuration from the simulation')
|
9
|
+
|
10
|
+
psr.set_defaults(func=self.send_request)
|
11
|
+
|
12
|
+
def get_request_body(self, args):
|
13
|
+
return {
|
14
|
+
}
|
avrs/requests/request.py
CHANGED
@@ -12,6 +12,7 @@ class AvrsApiRequest:
|
|
12
12
|
self.target_object_id = target_id
|
13
13
|
self.request_type = request_type
|
14
14
|
self.verbose = False
|
15
|
+
self.cfg = cfg
|
15
16
|
|
16
17
|
def get_request(self, args):
|
17
18
|
body = self.get_request_body(args)
|
@@ -38,7 +39,11 @@ class AvrsApiRequest:
|
|
38
39
|
# print('{}'.format(response))
|
39
40
|
|
40
41
|
def send_http_request(self, args):
|
41
|
-
|
42
|
+
sim_address = 'localhost'
|
43
|
+
if 'sim_address' in self.cfg:
|
44
|
+
sim_address = self.cfg['sim_address']
|
45
|
+
connection_addr = os.environ.get('AVRS_SIM_ADDRESS', 'localhost')
|
46
|
+
connection = http.client.HTTPConnection(connection_addr, 30313, timeout=10)
|
42
47
|
headers = {'Content-type': 'application/json'}
|
43
48
|
body = json.dumps(self.get_request(args)).encode('utf-8')
|
44
49
|
connection.request('POST', '/post', body, headers)
|
avrs/simconfig_util.py
CHANGED
@@ -11,13 +11,13 @@ class SimConfigFiles():
|
|
11
11
|
}
|
12
12
|
self.files = {}
|
13
13
|
|
14
|
-
ok, status = self.
|
14
|
+
ok, status = self.validate()
|
15
15
|
if ok:
|
16
16
|
for name, path in self.required_files.items():
|
17
17
|
with open(path, 'r', encoding='utf-8') as f:
|
18
18
|
self.files[name] = json.load(f)
|
19
19
|
|
20
|
-
def
|
20
|
+
def validate(self):
|
21
21
|
for name, path in self.required_files.items():
|
22
22
|
if not os.path.exists(path):
|
23
23
|
return (False, '{} not found'.format(path))
|
@@ -32,11 +32,11 @@ def compare_simconfig_defaults(sim_saved_dir, new_defaults_dir):
|
|
32
32
|
old_cfg_files = SimConfigFiles(sim_saved_dir)
|
33
33
|
new_cfg_files = SimConfigFiles(new_defaults_dir)
|
34
34
|
|
35
|
-
ok, status = old_cfg_files.
|
35
|
+
ok, status = old_cfg_files.validate()
|
36
36
|
if not ok:
|
37
37
|
print(status)
|
38
38
|
return
|
39
|
-
ok, status = new_cfg_files.
|
39
|
+
ok, status = new_cfg_files.validate()
|
40
40
|
if not ok:
|
41
41
|
print(status)
|
42
42
|
return
|
avrs/util.py
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
import subprocess
|
2
|
+
|
3
|
+
class ProcessResult():
|
4
|
+
def __init__(self, pres):
|
5
|
+
self.out = pres.stdout.decode('utf-8')
|
6
|
+
self.err = pres.stderr.decode('utf-8')
|
7
|
+
|
8
|
+
def run_process(args):
|
9
|
+
result = subprocess.run(
|
10
|
+
args,
|
11
|
+
stdout=subprocess.PIPE,
|
12
|
+
stderr=subprocess.PIPE)
|
13
|
+
return ProcessResult(result)
|
avrs/requests/reserve_mv_slot.py
DELETED
@@ -1,112 +0,0 @@
|
|
1
|
-
from avrs.requests.request import AvrsApiRequest
|
2
|
-
from argparse import RawTextHelpFormatter
|
3
|
-
|
4
|
-
RESERVE_MV_SLOT_HELP = '''
|
5
|
-
slot (if an open slot exists, there are 4 total) using the given name to add a new vehicle and the appropriate topics.
|
6
|
-
It will despawn the default vehicle and remove the default ROS topics when it is first run. Each vehicle added will be
|
7
|
-
given its own topics prefixed by the given name, and the slot index will correspond to the vcan it will use.
|
8
|
-
Note that this will require having active vcans for each vehicle you wish to use.
|
9
|
-
(eg, if you want to use 4 vehicles, you will need vcan0, vcan1, vcan2, and vcan3)
|
10
|
-
'''
|
11
|
-
|
12
|
-
# use these to spawn MVs
|
13
|
-
MV_LANDMARKS = [
|
14
|
-
'MvStart0',
|
15
|
-
'MvStart1',
|
16
|
-
'MvStart2',
|
17
|
-
'MvStart3'
|
18
|
-
]
|
19
|
-
|
20
|
-
class ReserveMvSlot(AvrsApiRequest):
|
21
|
-
def __init__(self, parser, cfg):
|
22
|
-
AvrsApiRequest.__init__(self, parser, cfg, 'SpawnObject', 0)
|
23
|
-
psr = parser.add_parser('reserve-mv-slot', help=RESERVE_MV_SLOT_HELP, formatter_class=RawTextHelpFormatter)
|
24
|
-
|
25
|
-
psr.add_argument(
|
26
|
-
'slot_name',
|
27
|
-
help='the name of the vehicle to put in the specified slot')
|
28
|
-
|
29
|
-
psr.add_argument(
|
30
|
-
'slot_index',
|
31
|
-
type=int,
|
32
|
-
choices=[0, 1, 2, 3],
|
33
|
-
help='the slot index (0-4) to reserve')
|
34
|
-
|
35
|
-
psr.add_argument(
|
36
|
-
'--bsu-can-name',
|
37
|
-
default='vcan0',
|
38
|
-
help='the name of the CAN interface to use for the BSU CAN bus on the new vehicle')
|
39
|
-
|
40
|
-
psr.add_argument(
|
41
|
-
'--kistler-can-name',
|
42
|
-
default='vcan1',
|
43
|
-
help='the name of the CAN interface to use for the Kistler CAN bus on the new vehicle')
|
44
|
-
|
45
|
-
psr.add_argument(
|
46
|
-
'--badenia-can-name',
|
47
|
-
default='vcan2',
|
48
|
-
help='the name of the CAN interface to use for the bandanania CAN bus on the new vehicle')
|
49
|
-
|
50
|
-
psr.add_argument(
|
51
|
-
'--with-view-cameras',
|
52
|
-
action='store_true',
|
53
|
-
help='if the new vehicle should have cameras attached to it')
|
54
|
-
|
55
|
-
psr.add_argument(
|
56
|
-
'--enable-lidar',
|
57
|
-
action='store_true',
|
58
|
-
help='if set, the lidar will be enabled on the new vehicle')
|
59
|
-
|
60
|
-
psr.add_argument(
|
61
|
-
'--enable-camera-sensor',
|
62
|
-
action='store_true',
|
63
|
-
help='if set, the camera will be enabled on the new vehicle')
|
64
|
-
|
65
|
-
psr.add_argument(
|
66
|
-
'--disable-hud',
|
67
|
-
action='store_true',
|
68
|
-
help='if set, the new vehicle will not create a HUD (mutiple HUDs will clutter the screen)')
|
69
|
-
|
70
|
-
|
71
|
-
psr.set_defaults(func=self.send_request)
|
72
|
-
|
73
|
-
def get_request_body(self, args):
|
74
|
-
|
75
|
-
eav_init_pld = {
|
76
|
-
'TypeName': 'Eav24Initializer',
|
77
|
-
'Body': {
|
78
|
-
'bsuCanName': args.bsu_can_name,
|
79
|
-
'kistlerCanNam': args.kistler_can_name,
|
80
|
-
'badeniaCanName': args.badenia_can_name,
|
81
|
-
'bHudEnabled': not args.disable_hud,
|
82
|
-
'bEnableLidar': args.enable_lidar,
|
83
|
-
'bEnableCameraSensor': args.enable_camera_sensor
|
84
|
-
}
|
85
|
-
}
|
86
|
-
|
87
|
-
plds = [
|
88
|
-
eav_init_pld
|
89
|
-
]
|
90
|
-
|
91
|
-
if args.with_view_cameras:
|
92
|
-
plds.append(
|
93
|
-
{
|
94
|
-
'TypeName': 'InitializerTemplates',
|
95
|
-
'Body': {
|
96
|
-
'Templates': [
|
97
|
-
{
|
98
|
-
'PayloadType': 'SimViewTargetIpd',
|
99
|
-
'PayloadSpec': 'DefaultCarCams'
|
100
|
-
}
|
101
|
-
]
|
102
|
-
}
|
103
|
-
})
|
104
|
-
|
105
|
-
return {
|
106
|
-
'Name': args.slot_name,
|
107
|
-
'Type': 'Eav24',
|
108
|
-
'Location': {},
|
109
|
-
'Rotation': {},
|
110
|
-
'Landmark': MV_LANDMARKS[args.slot_index],
|
111
|
-
'Payloads': plds
|
112
|
-
}
|
File without changes
|
File without changes
|
File without changes
|