mirror of https://github.com/ArduPilot/ardupilot
653 lines
24 KiB
Python
Executable File
653 lines
24 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
# framework to start a simulated vehicle and connect it to MAVProxy
|
|
# Peter Barker, April 2016
|
|
# based on sim_vehicle.sh by Andrew Tridgell, October 2011
|
|
|
|
import optparse
|
|
import sys
|
|
import atexit
|
|
import os
|
|
import subprocess
|
|
import tempfile
|
|
import getpass
|
|
import time
|
|
import signal
|
|
|
|
class CompatError(Exception):
|
|
'''a custom exception class to hold state if we encounter the parse error we are looking for'''
|
|
def __init__(self,error, opts, rargs):
|
|
Exception.__init__(self,error)
|
|
self.opts = opts
|
|
self.rargs = rargs
|
|
|
|
class CompatOptionParser(optparse.OptionParser):
|
|
'''An option parser which emulates the behaviour of the old sim_vehicle.sh; if passed -C, the first argument not understood starts a list of arguments that are passed straight to mavproxy'''
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
optparse.OptionParser.__init__(self, *args, **kwargs)
|
|
|
|
def error(self, error):
|
|
'''override default error handler called by optparse.OptionParser.parse_args when a parse error occurs; raise a detailed exception which can be caught'''
|
|
if error.find("no such option") != -1:
|
|
raise CompatError(error, self.values, self.rargs)
|
|
|
|
optparse.OptionParser.error(self, error)
|
|
|
|
def parse_args(self):
|
|
'''wrap parse_args so we can catch the exception raised upon discovering the known parameter parsing error'''
|
|
mavproxy_args = []
|
|
try:
|
|
opts, args = optparse.OptionParser.parse_args(self)
|
|
except CompatError as e:
|
|
if not e.opts.sim_vehicle_sh_compatible:
|
|
print(e)
|
|
print("Perhaps you want --sim_vehicle_sh_compatible (-C)?")
|
|
sys.exit(1)
|
|
if e.opts.mavproxy_args:
|
|
print("--mavproxy-args not permitted in compat mode")
|
|
sys.exit(1)
|
|
|
|
args = []
|
|
opts = e.opts
|
|
mavproxy_args = []
|
|
mavproxy_args.append(str(e)[16:]) # this trims "no such option" off
|
|
mavproxy_args.extend(e.rargs)
|
|
opts.ensure_value("mavproxy_args", " ".join(mavproxy_args))
|
|
|
|
return opts, args
|
|
|
|
def cygwin_pidof(procName):
|
|
''' Thanks to kata198 for this:
|
|
https://github.com/kata198/cygwin-ps-misc/blob/master/pidof
|
|
'''
|
|
pipe = subprocess.Popen("ps -ea | grep " + procName, shell=True, stdout=subprocess.PIPE)
|
|
outputLines = pipe.stdout.read().replace("\r", "").split("\n")
|
|
ret = pipe.wait()
|
|
pids = []
|
|
if ret != 0:
|
|
# No results
|
|
return []
|
|
for line in outputLines:
|
|
if not line:
|
|
continue
|
|
lineSplit = [item for item in line.split(' ') if item]
|
|
cmd = lineSplit[-1].split('/')[-1]
|
|
if cmd == procName:
|
|
try:
|
|
pid = int(lineSplit[0].strip())
|
|
except:
|
|
pid = int(lineSplit[1].strip())
|
|
pid = str(pid)
|
|
if pid not in pids:
|
|
pids.append(pid)
|
|
return pids
|
|
|
|
def under_cygwin():
|
|
return os.path.exists("/usr/bin/cygstart")
|
|
|
|
def kill_tasks_cygwin(victims):
|
|
for victim in list(victims):
|
|
pids = cygwin_pidof(victim)
|
|
# progress("pids for (%s): %s" % (victim,",".join([ str(p) for p in pids])))
|
|
for apid in pids:
|
|
os.kill(apid, signal.SIGKILL)
|
|
|
|
def kill_tasks():
|
|
'''clean up stray processes by name. This is a somewhat shotgun approach'''
|
|
victim_names = set([
|
|
'JSBSim',
|
|
'lt-JSBSim',
|
|
'ArduPlane.elf',
|
|
'ArduCopter.elf',
|
|
'APMrover2.elf',
|
|
'AntennaTracker.elf',
|
|
'JSBSIm.exe',
|
|
'MAVProxy.exe',
|
|
'runsim.py',
|
|
'AntennaTracker.elf',
|
|
])
|
|
|
|
if under_cygwin():
|
|
return kill_tasks_cygwin(list(victim_names))
|
|
|
|
import psutil
|
|
for proc in psutil.process_iter():
|
|
if proc.name() in victim_names:
|
|
proc.kill()
|
|
|
|
# clean up processes at exit:
|
|
atexit.register(kill_tasks)
|
|
|
|
def check_jsbsim_version():
|
|
'''assert that the JSBSim we will run is the one we expect to run'''
|
|
jsbsim_cmd = ["JSBSim", "--version"]
|
|
progress_cmd("Get JSBSim version", jsbsim_cmd)
|
|
jsbsim_version = subprocess.Popen(jsbsim_cmd, stdout=subprocess.PIPE).communicate()[0]
|
|
try:
|
|
jsbsim_version.index("ArduPilot")
|
|
except ValueError:
|
|
print('''
|
|
=========================================================
|
|
You need the latest ArduPilot version of JSBSim installed
|
|
and in your \$PATH
|
|
|
|
Please get it from git://github.com/tridge/jsbsim.git
|
|
See
|
|
http://dev.ardupilot.org/wiki/simulation-2/sitl-simulator-software-in-the-loop/setting-up-sitl-on-linux/
|
|
for more details
|
|
=========================================================
|
|
''')
|
|
sys.exit(1)
|
|
|
|
def progress(text):
|
|
'''display sim_vehicle progress text'''
|
|
print("SIM_VEHICLE: " + text)
|
|
|
|
def find_autotest_dir():
|
|
'''return path to autotest directory'''
|
|
if os.path.exists("../Tools/autotest"):
|
|
return "../Tools/autotest"
|
|
|
|
# we are not running from one of the standard vehicle directories. Use
|
|
# the location of the sim_vehicle script to find the path
|
|
return os.path.dirname(os.path.realpath(__file__))
|
|
|
|
|
|
progress("Start")
|
|
|
|
# define and run parser
|
|
parser = CompatOptionParser("sim_vehicle.py", epilog='''
|
|
eeprom.bin in the starting directory contains the parameters for your simulated vehicle. Always start from the same directory. It is recommended that you start in the main vehicle directory for the vehicle you are simulating, for example, start in the ArduPlane directory to simulate ArduPlane
|
|
''')
|
|
|
|
parser.add_option("-v", "--vehicle", type='string', default=None, help='vehicle type (ArduPlane, ArduCopter or APMrover2)')
|
|
parser.add_option("-f", "--frame", type='string', default=None, help='''set aircraft frame type
|
|
for copters can choose +, X, quad or octa
|
|
for planes can choose elevon or vtail''')
|
|
parser.add_option("-C", "--sim_vehicle_sh_compatible", action='store_true', default=False, help='be compatible with the way sim_vehicle.sh works; make this the first option')
|
|
parser.add_option("-H", "--hil", action='store_true', default=False, help="start HIL")
|
|
|
|
group_build = optparse.OptionGroup(parser, "Build options")
|
|
group_build.add_option("-N", "--no-rebuild", action='store_true', default=False, help="don't rebuild before starting ardupilot")
|
|
group_build.add_option("-D", "--debug", action='store_true', default=False, help="build with debugging")
|
|
group_build.add_option("-c", "--clean", action='store_true', default=False, help='do a make clean before building')
|
|
group_build.add_option("-j", "--jobs", default=1, type='int', help='number of processors to use during build (default 1)')
|
|
group_build.add_option("-b", "--build-target", default=None, type='string', help='override SITL build target')
|
|
group_build.add_option("-s", "--build-system", default="waf", type='choice', choices=["make", "waf"], help='build system to use')
|
|
group_build.add_option("", "--no-rebuild-on-failure", dest="rebuild_on_failure", action='store_false', default=True, help='if build fails, do not clean and rebuild')
|
|
parser.add_option_group(group_build)
|
|
|
|
group_sim = optparse.OptionGroup(parser, "Simulation options")
|
|
group_sim.add_option("-I", "--instance", default=0, type='int', help='instance of simulator')
|
|
group_sim.add_option("-V", "--valgrind", action='store_true', default=False, help='enable valgrind for memory access checking (very slow!)')
|
|
group_sim.add_option("-T", "--tracker", action='store_true', default=False, help="start an antenna tracker instance")
|
|
group_sim.add_option("-A", "--sitl-instance-args", type='string', default=None, help='pass arguments to SITL instance')
|
|
#group_sim.add_option("-R", "--reverse-throttle", action='store_true', default=False, help="reverse throttle in plane")
|
|
group_sim.add_option("-G", "--gdb", action='store_true', default=False, help="use gdb for debugging ardupilot")
|
|
group_sim.add_option("-g", "--gdb-stopped", action='store_true', default=False, help="use gdb for debugging ardupilot (no auto-start)")
|
|
group_sim.add_option("-d", "--delay-start", default=0, type='float', help='delays the start of mavproxy by the number of seconds')
|
|
group_sim.add_option("-B", "--breakpoint", type='string', action="append", default=[], help='add a breakpoint at given location in debugger')
|
|
group_sim.add_option("-M", "--mavlink-gimbal", action='store_true', default=False, help='enable MAVLink gimbal')
|
|
group_sim.add_option("-L", "--location", type='string', default='CMAC', help='select start location from Tools/autotest/locations.txt')
|
|
group_sim.add_option("-l", "--custom-location", type='string', default=None, help='set custom start location')
|
|
group_sim.add_option("-S", "--speedup", default=1, type='int', help='set simulation speedup (1 for wall clock time)')
|
|
group_sim.add_option("-t", "--tracker-location", default='CMAC_PILOTSBOX', type='string', help='set antenna tracker start location')
|
|
group_sim.add_option("-w", "--wipe-eeprom", action='store_true', default=False, help='wipe EEPROM and reload parameters')
|
|
group_sim.add_option("-m", "--mavproxy-args", default=None, type='string', help='additional arguments to pass to mavproxy.py')
|
|
parser.add_option_group(group_sim)
|
|
|
|
|
|
# special-cased parameters for mavproxy, because some people's fingers
|
|
# have long memories, and they don't want to use -C :-)
|
|
group = optparse.OptionGroup(parser, "Compatibility MAVProxy options (consider using --mavproxy-args instead)")
|
|
group.add_option("", "--out", default=[], type='string', action="append", help='create an additional mavlink output')
|
|
group.add_option("", "--map", default=False, action='store_true', help='load map module on startup')
|
|
group.add_option("", "--console", default=False, action='store_true', help='load console module on startup')
|
|
parser.add_option_group(group)
|
|
|
|
opts, args = parser.parse_args()
|
|
|
|
# validate parameters
|
|
if opts.hil:
|
|
if opts.valgrind:
|
|
print("May not use valgrind with hil")
|
|
sys.exit(1)
|
|
if opts.gdb or opts.gdb_stopped:
|
|
print("May not use gdb with hil")
|
|
sys.exit(1)
|
|
|
|
if opts.valgrind and (opts.gdb or opts.gdb_stopped):
|
|
print("May not use valgrind with gdb")
|
|
sys.exit(1)
|
|
|
|
# magically determine vehicle type (if required):
|
|
if opts.vehicle is None:
|
|
cwd = os.getcwd()
|
|
opts.vehicle = os.path.basename(cwd)
|
|
|
|
# determine a frame type if not specified:
|
|
default_frame_for_vehicle = {
|
|
"APMrover2": "rover",
|
|
"ArduPlane": "jsbsim",
|
|
"ArduCopter": "quad",
|
|
"AntennaTracker": "tracker"
|
|
}
|
|
|
|
# try to validate vehicle
|
|
if not default_frame_for_vehicle.has_key(opts.vehicle):
|
|
progress("** Is (%s) really your vehicle type? Try -v VEHICLETYPE if not, or be in the e.g. ArduCopter subdirectory" % (opts.vehicle,))
|
|
|
|
# determine frame options (e.g. build type might be "sitl")
|
|
if opts.frame is None:
|
|
opts.frame = default_frame_for_vehicle[opts.vehicle]
|
|
|
|
# setup ports for this instance
|
|
mavlink_port = "tcp:127.0.0.1:" + str(5760 + 10*opts.instance)
|
|
simout_port = "127.0.0.1:" + str(5501 + 10*opts.instance)
|
|
|
|
'''
|
|
make_target: option passed to make to create binaries. Usually sitl, and "-debug" may be appended if -D is passed to sim_vehicle.py
|
|
default_params_filename: filename of default parameters file. Taken to be relative to autotest dir.
|
|
extra_mavlink_cmds: extra parameters that will be passed to mavproxy
|
|
'''
|
|
_options_for_frame = {
|
|
"+": {
|
|
"waf_target": "bin/arducopter-quad",
|
|
"default_params_filename": "copter_params.parm"
|
|
},
|
|
"quad": {
|
|
"model": "+",
|
|
"waf_target": "bin/arducopter-quad",
|
|
"default_params_filename": "copter_params.parm"
|
|
},
|
|
"X": {
|
|
"waf_target": "bin/arducopter-quad",
|
|
# this param set FRAME doesn't actually work because mavproxy
|
|
# won't set a parameter unless it knows of it, and the param fetch happens asynchronously
|
|
"extra_mavlink_cmds": "param fetch frame; param set FRAME 1;",
|
|
"default_params_filename": "copter_params.parm"
|
|
},
|
|
"heli-dual": {
|
|
"make_target": "sitl-heli-dual",
|
|
"waf_target": "bin/arducopter-coax", # is this correct? -pb201604301447
|
|
},
|
|
"heli-compound": {
|
|
"make_target": "sitl-heli-compound",
|
|
"waf_target": "bin/arducopter-coax", # is this correct? -pb201604301447
|
|
},
|
|
"IrisRos": {
|
|
"default_params_filename": "copter_params.parm",
|
|
"waf_target": "bin/arducopter-quad",
|
|
},
|
|
"Gazebo": {
|
|
"default_params_filename": "copter_params.parm",
|
|
"waf_target": "bin/arducopter-quad",
|
|
},
|
|
|
|
"octa": {
|
|
"make_target": "sitl-octa",
|
|
"waf_target": "bin/arducopter-octa",
|
|
"default_params_filename": "copter_params.parm",
|
|
},
|
|
"tri": {
|
|
"make_target": "sitl-tri",
|
|
"waf_target": "bin/arducopter-tri",
|
|
"default_params_filename": "tri_params.parm",
|
|
},
|
|
"y6": {
|
|
"make_target": "sitl-y6",
|
|
"waf_target": "bin/arducopter-y6",
|
|
"default_params_filename": "y6_params.parm",
|
|
},
|
|
"firefly": {
|
|
"default_params_filename": "firefly.parm",
|
|
"waf_target": "bin/arducopter-firefly",
|
|
},
|
|
"heli": {
|
|
"make_target": "sitl-heli",
|
|
"waf_target": "bin/arducopter-heli",
|
|
"default_params_filename": "Helicopter.parm",
|
|
},
|
|
"last_letter": {
|
|
"waf_target": "bin/arduplane",
|
|
},
|
|
"CRRCSim": {
|
|
"waf_target": "bin/arduplane",
|
|
},
|
|
"jsbsim": {
|
|
"waf_target": "bin/arduplane",
|
|
"default_params_filename": "ArduPlane.parm",
|
|
},
|
|
"quadplane-tilttri" : {
|
|
"build_target" : "sitl-tri",
|
|
"default_params_filename": "quadplane-tilttri.parm",
|
|
},
|
|
"quadplane": {
|
|
"waf_target": "bin/arduplane",
|
|
"default_params_filename": "quadplane.parm",
|
|
},
|
|
"plane-elevon": {
|
|
"waf_target": "bin/arduplane",
|
|
"default_params_filename": "plane-elevons.parm",
|
|
},
|
|
"plane-vtail": {
|
|
"waf_target": "bin/arduplane",
|
|
"default_params_filename": "plane-vtail.parm",
|
|
},
|
|
"plane": {
|
|
"waf_target": "bin/arduplane",
|
|
"default_params_filename": "plane.parm",
|
|
},
|
|
}
|
|
|
|
_default_waf_target = {
|
|
"ArduPlane": "bin/arduplane",
|
|
"ArduCopter": "bin/arducopter-quad",
|
|
"APMRover2": "bin/ardurover",
|
|
"AntennaTracker": "bin/antennatracker",
|
|
}
|
|
|
|
def default_waf_target(vehicle):
|
|
'''returns a waf target based on vehicle type, which is often determined by which directory the user is in'''
|
|
return _default_waf_target[vehicle]
|
|
|
|
def options_for_frame(frame, vehicle, opts):
|
|
'''return informatiom about how to sitl for frame e.g. build-type==sitl'''
|
|
ret = None
|
|
if frame in _options_for_frame:
|
|
ret = _options_for_frame[frame]
|
|
else:
|
|
for p in [ "octa", "tri", "y6", "firefly", "heli", "last_letter", "jsbsim", "quadplane", "plane-elevon", "plane-vtail", "plane" ]:
|
|
if frame.startswith(p):
|
|
ret = _options_for_frame[p]
|
|
break
|
|
if ret is None:
|
|
if frame.endswith("-heli"):
|
|
ret = _options_for_frame["heli"]
|
|
if ret is None:
|
|
ret = {}
|
|
|
|
if not ret.has_key("model"):
|
|
ret["model"] = frame
|
|
|
|
if not ret.has_key("make_target"):
|
|
ret["make_target"] = "sitl"
|
|
|
|
if not ret.has_key("waf_target"):
|
|
ret["waf_target"] = default_waf_target(vehicle)
|
|
|
|
if opts.build_target is not None:
|
|
ret["make_target"] = opts.build_target
|
|
ret["waf_target"] = opts.build_target
|
|
|
|
return ret
|
|
|
|
def do_build_waf(vehicledir, opts, frame_options):
|
|
'''build build_target (e.g. sitl) in directory vehicledir - using waf'''
|
|
progress("WAF build")
|
|
|
|
old_dir = os.getcwd()
|
|
|
|
root_dir = os.path.join(vehicledir, "..")
|
|
|
|
os.chdir(root_dir)
|
|
|
|
waf_light = "./modules/waf/waf-light"
|
|
|
|
cmd_configure = [waf_light, "configure", "--board", "sitl" ]
|
|
if opts.debug:
|
|
cmd_configure.append("--debug")
|
|
|
|
run_cmd_blocking("Configure waf", cmd_configure)
|
|
p = subprocess.Popen(cmd_configure)
|
|
pid, sts = os.waitpid(p.pid,0)
|
|
|
|
if opts.clean:
|
|
run_cmd_blocking("Building clean", [waf_light, "clean"])
|
|
|
|
cmd_build = [waf_light, "-j", str(opts.jobs), "build", "--target", frame_options["waf_target"] ]
|
|
progress_cmd("Building", cmd_build)
|
|
p = subprocess.Popen(cmd_build)
|
|
pid, sts = os.waitpid(p.pid,0)
|
|
|
|
if sts != 0: # build failed
|
|
if opts.rebuild_on_failure:
|
|
progress("Build failed; cleaning and rebuilding")
|
|
run_cmd_blocking("Building clean", [waf_light, "clean"])
|
|
|
|
progress_cmd("Building", cmd_build)
|
|
p = subprocess.Popen(cmd_build)
|
|
pid, sts = os.waitpid(p.pid,0)
|
|
if sts != 0:
|
|
progress("Build failed")
|
|
sys.exit(1)
|
|
else:
|
|
progress("Build failed")
|
|
sys.exit(1)
|
|
|
|
os.chdir(old_dir)
|
|
|
|
|
|
def do_build(vehicledir, opts, frame_options):
|
|
'''build build target (e.g. sitl) in directory vehicledir'''
|
|
|
|
if opts.build_system == 'waf':
|
|
return do_build_waf(vehicledir, opts, frame_options)
|
|
|
|
old_dir = os.getcwd()
|
|
|
|
os.chdir(vehicledir)
|
|
|
|
if opts.clean:
|
|
run_cmd_blocking("Building clean", ["make", "clean"])
|
|
|
|
build_target = frame_options["make_target"]
|
|
if opts.debug:
|
|
build_target += "-debug"
|
|
|
|
build_cmd = ["make", "-j"+str(opts.jobs), build_target]
|
|
progress_cmd("Building %s" % (build_target), build_cmd)
|
|
|
|
p = subprocess.Popen(build_cmd)
|
|
pid, sts = os.waitpid(p.pid,0)
|
|
if sts != 0:
|
|
progress("Build failed; cleaning and rebuilding")
|
|
subprocess.Popen(["make", "clean"])
|
|
p = subprocess.Popen(["make", "-j"+str(opts.jobs), build_target])
|
|
pid, sts = os.waitpid(p.pid,0)
|
|
if sts != 0:
|
|
progress("Build failed")
|
|
sys.exit(1)
|
|
|
|
os.chdir(old_dir)
|
|
|
|
def find_location_by_name(autotest, locname):
|
|
'''search locations.txt for locname, return GPS coords'''
|
|
locations_filepath = os.path.join(autotest, "locations.txt")
|
|
for line in open(locations_filepath,'r'):
|
|
line = line.rstrip("\n")
|
|
(name,loc) = line.split("=")
|
|
if name == locname:
|
|
return loc
|
|
print("Failed to find location (%s)" % (opts.location))
|
|
sys.exit(1)
|
|
|
|
def progress_cmd(what, cmd):
|
|
'''print cmd in a way a user could cut-and-paste to get the same effect'''
|
|
progress(what)
|
|
shell_text = "%s" % (" ".join([ '"%s"' % x for x in cmd ]))
|
|
progress(shell_text)
|
|
|
|
def run_cmd_blocking(what, cmd):
|
|
progress_cmd(what, cmd)
|
|
p = subprocess.Popen(cmd)
|
|
pid, sts = os.waitpid(p.pid,0)
|
|
|
|
def run_in_terminal_window(autotest, name, cmd):
|
|
'''execute the run_in_terminal_window.sh command for cmd'''
|
|
runme = [os.path.join(autotest, "run_in_terminal_window.sh"), name]
|
|
runme.extend(cmd)
|
|
progress_cmd("Run " + name, runme)
|
|
p = subprocess.Popen(runme) # bg this explicitly?!
|
|
|
|
tracker_uarta = None # blemish
|
|
|
|
def start_antenna_tracker(autotest, opts):
|
|
'''compile and run the AntennaTracker, add tracker to mavproxy'''
|
|
global tracker_uarta
|
|
progress("Preparing antenna tracker")
|
|
tracker_home = find_location_by_name(find_autotest_dir(), opts.tracker_location)
|
|
vehicledir = os.path.join(autotest, "../../" + "AntennaTracker")
|
|
do_build(vehicledir, opts, "sitl-debug")
|
|
tracker_instance = 1
|
|
os.chdir(vehicledir)
|
|
tracker_uarta = "tcp:127.0.0.1:" + str(5760+10*tracker_instance)
|
|
exe = os.path.join(vehicledir, "AntennaTracker.elf")
|
|
run_in_terminal_window(autotest, "AntennaTracker", ["nice", exe, "-I" + str(tracker_instance), "--model=tracker", "--home="+tracker_home])
|
|
|
|
def start_vehicle(vehicle_binary, autotest, opts, stuff, loc):
|
|
'''run the ArduPilot binary'''
|
|
|
|
cmd_name = opts.vehicle
|
|
cmd = []
|
|
if opts.valgrind:
|
|
cmd_name += " (valgrind)"
|
|
cmd.append("valgrind")
|
|
if opts.gdb:
|
|
cmd_name += " (gdb)"
|
|
cmd.append("gdb")
|
|
gdb_commands_file = tempfile.NamedTemporaryFile(delete=False)
|
|
atexit.register(os.unlink, gdb_commands_file.name)
|
|
|
|
for breakpoint in opts.breakpoint:
|
|
gdb_commands_file.write("b %s\n" % (breakpoint,))
|
|
gdb_commands_file.write("r\n")
|
|
gdb_commands_file.close()
|
|
cmd.extend(["-x", gdb_commands_file.name])
|
|
cmd.append("--args")
|
|
|
|
cmd.append(vehicle_binary)
|
|
cmd.append("-S")
|
|
cmd.append("-I"+str(opts.instance))
|
|
cmd.extend(["--home", loc])
|
|
if opts.wipe_eeprom:
|
|
cmd.append("-w")
|
|
cmd.extend(["--model", stuff["model"]])
|
|
cmd.extend(["--speedup", str(opts.speedup)])
|
|
if opts.sitl_instance_args:
|
|
cmd.extend(opts.sitl_instance_args.split(" ")) # this could be a lot better..
|
|
if opts.mavlink_gimbal:
|
|
cmd.append("--gimbal")
|
|
if stuff.has_key("default_params_filename"):
|
|
path = os.path.join(autotest, stuff["default_params_filename"])
|
|
progress("Using defaults from (%s)" % (path,))
|
|
cmd.extend(["--defaults", path])
|
|
|
|
run_in_terminal_window(autotest, cmd_name, cmd)
|
|
|
|
def start_mavproxy(opts, stuff):
|
|
'''run mavproxy'''
|
|
# FIXME: would be nice to e.g. "mavproxy.mavproxy(....).run" rather than shelling out
|
|
|
|
extra_cmd = ""
|
|
cmd = []
|
|
if under_cygwin():
|
|
cmd.append("/usr/bin/cygstart")
|
|
cmd.append("-w")
|
|
cmd.append("/cygdrive/c/Program Files (x86)/MAVProxy/mavproxy.exe")
|
|
else:
|
|
cmd.append("mavproxy.py")
|
|
|
|
if opts.hil:
|
|
cmd.extend(["--load-module", "HIL"])
|
|
else:
|
|
cmd.extend(["--master", mavlink_port, "--sitl", simout_port])
|
|
# If running inside of a vagrant guest, then we probably want to forward our mavlink out to the containing host OS
|
|
if getpass.getuser() == "vagrant":
|
|
cmd.extend(["--out", "10.0.2.2:14550"])
|
|
for port in [14550, 14551]:
|
|
cmd.extend(["--out", "127.0.0.1:"+str(port)])
|
|
|
|
if opts.tracker:
|
|
cmd.extend(["--load-module", "tracker"])
|
|
global tracker_uarta
|
|
# tracker_uarta is set when we start the tracker...
|
|
extra_cmd += "module load map; tracker set port %s; tracker start; tracker arm;" % (tracker_uarta,)
|
|
|
|
if opts.mavlink_gimbal:
|
|
cmd.extend(["--load-module", "gimbal"])
|
|
|
|
if stuff.has_key("extra_mavlink_cmds"):
|
|
extra_cmd += " " + stuff["extra_mavlink_cmds"]
|
|
|
|
if opts.mavproxy_args:
|
|
cmd.extend(opts.mavproxy_args.split(" ")) # this could be a lot better..
|
|
|
|
# compatability pass-through parameters (for those that don't want
|
|
# to use -C :-)
|
|
for out in opts.out:
|
|
cmd.extend(['--out', out])
|
|
if opts.map:
|
|
cmd.append('--map')
|
|
if opts.console:
|
|
cmd.append('--console')
|
|
|
|
if len(extra_cmd):
|
|
cmd.extend(['--cmd', extra_cmd])
|
|
|
|
run_cmd_blocking("Run MavProxy", cmd)
|
|
progress("MAVProxy exitted")
|
|
|
|
frame_options = options_for_frame(opts.frame, opts.vehicle, opts)
|
|
|
|
if frame_options["model"] == "jsbsim":
|
|
check_jsbsim_version()
|
|
|
|
vehicledir = os.path.join(find_autotest_dir(), "../../" + opts.vehicle)
|
|
if not os.path.exists(vehicledir):
|
|
print("vehicle directory (%s) does not exist" % (vehicledir,))
|
|
sys.exit(1)
|
|
|
|
os.environ['AUTOTEST'] = find_autotest_dir() # should we only drop this in subprocess env?
|
|
|
|
if not opts.hil:
|
|
if opts.instance == 0:
|
|
kill_tasks()
|
|
|
|
if opts.tracker:
|
|
start_antenna_tracker(find_autotest_dir(), opts)
|
|
|
|
if opts.custom_location:
|
|
loc = opts.custom_location
|
|
progress("Starting up at %s" % (loc,))
|
|
else:
|
|
loc = find_location_by_name(find_autotest_dir(), opts.location)
|
|
progress("Starting up at %s (%s)" % (loc, opts.location))
|
|
|
|
if opts.hil:
|
|
# (unlikely)
|
|
run_in_terminal_window(find_autotest_dir(), "JSBSim", [ os.path.join(find_autotest_dir(), "jsb_sim/runsim.py"), "--home", loc, "--speedup=" + str(opts.speedup)])
|
|
else:
|
|
if not opts.no_rebuild: # i.e. we should rebuild
|
|
do_build(vehicledir, opts, frame_options)
|
|
|
|
if opts.build_system == "waf":
|
|
vehicle_binary = os.path.join(vehicledir, "../build/sitl", frame_options["waf_target"])
|
|
else:
|
|
vehicle_binary = os.path.join(vehicledir, opts.vehicle+".elf")
|
|
|
|
if not os.path.exists(vehicle_binary):
|
|
print("Vehicle binary (%s) does not exist" % (vehicle_binary,))
|
|
sys.exit(1)
|
|
|
|
start_vehicle(vehicle_binary, find_autotest_dir(), opts, frame_options, loc)
|
|
|
|
if opts.delay_start:
|
|
progress("Sleeping for %f seconds" % (opts.delay_start,))
|
|
time.sleep(float(opts.delay_start))
|
|
|
|
start_mavproxy(opts, frame_options)
|
|
|
|
sys.exit(0)
|