2015-05-04 18:08:42 -03:00
|
|
|
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
|
|
|
|
2015-08-11 03:28:43 -03:00
|
|
|
#include <AP_HAL/AP_HAL.h>
|
2015-05-04 18:08:42 -03:00
|
|
|
|
|
|
|
#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
|
|
|
|
|
2015-08-11 03:28:43 -03:00
|
|
|
#include "AP_HAL_SITL.h"
|
2015-05-04 18:08:42 -03:00
|
|
|
#include "AP_HAL_SITL_Namespace.h"
|
|
|
|
#include "HAL_SITL_Class.h"
|
|
|
|
#include "UARTDriver.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <unistd.h>
|
2015-08-11 03:28:43 -03:00
|
|
|
#include <AP_HAL/utility/getopt_cpp.h>
|
|
|
|
|
|
|
|
#include <SITL/SIM_Multicopter.h>
|
|
|
|
#include <SITL/SIM_Helicopter.h>
|
|
|
|
#include <SITL/SIM_Rover.h>
|
|
|
|
#include <SITL/SIM_CRRCSim.h>
|
|
|
|
#include <SITL/SIM_Gazebo.h>
|
|
|
|
#include <SITL/SIM_last_letter.h>
|
|
|
|
#include <SITL/SIM_JSBSim.h>
|
|
|
|
#include <SITL/SIM_Tracker.h>
|
|
|
|
#include <SITL/SIM_Balloon.h>
|
2015-05-04 18:08:42 -03:00
|
|
|
|
|
|
|
extern const AP_HAL::HAL& hal;
|
|
|
|
|
|
|
|
using namespace HALSITL;
|
|
|
|
|
|
|
|
// catch floating point exceptions
|
|
|
|
static void _sig_fpe(int signum)
|
|
|
|
{
|
2015-05-04 21:59:07 -03:00
|
|
|
fprintf(stderr, "ERROR: Floating point exception - aborting\n");
|
2015-05-04 18:08:42 -03:00
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SITL_State::_usage(void)
|
|
|
|
{
|
2015-05-10 19:48:42 -03:00
|
|
|
printf("Options:\n"
|
|
|
|
"\t--home HOME set home location (lat,lng,alt,yaw)\n"
|
|
|
|
"\t--model MODEL set simulation model\n"
|
|
|
|
"\t--wipe wipe eeprom and dataflash\n"
|
|
|
|
"\t--rate RATE set SITL framerate\n"
|
|
|
|
"\t--console use console instead of TCP ports\n"
|
|
|
|
"\t--instance N set instance of SITL (adds 10*instance to all port numbers)\n"
|
|
|
|
"\t--speedup SPEEDUP set simulation speedup\n"
|
2015-05-24 23:11:16 -03:00
|
|
|
"\t--gimbal enable simulated MAVLink gimbal\n"
|
2015-05-25 00:04:17 -03:00
|
|
|
"\t--autotest-dir DIR set directory for additional files\n"
|
2015-05-10 19:48:42 -03:00
|
|
|
);
|
2015-05-04 18:08:42 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct {
|
|
|
|
const char *name;
|
|
|
|
Aircraft *(*constructor)(const char *home_str, const char *frame_str);
|
|
|
|
} model_constructors[] = {
|
2015-06-01 20:08:55 -03:00
|
|
|
{ "+", MultiCopter::create },
|
|
|
|
{ "quad", MultiCopter::create },
|
|
|
|
{ "copter", MultiCopter::create },
|
|
|
|
{ "x", MultiCopter::create },
|
|
|
|
{ "hexa", MultiCopter::create },
|
|
|
|
{ "octa", MultiCopter::create },
|
|
|
|
{ "heli", Helicopter::create },
|
|
|
|
{ "heli-dual", Helicopter::create },
|
|
|
|
{ "heli-compound", Helicopter::create },
|
|
|
|
{ "rover", Rover::create },
|
|
|
|
{ "crrcsim", CRRCSim::create },
|
|
|
|
{ "jsbsim", JSBSim::create },
|
|
|
|
{ "gazebo", Gazebo::create },
|
|
|
|
{ "last_letter", last_letter::create },
|
|
|
|
{ "tracker", Tracker::create },
|
|
|
|
{ "balloon", Balloon::create }
|
2015-05-04 18:08:42 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
void SITL_State::_parse_command_line(int argc, char * const argv[])
|
|
|
|
{
|
2015-05-04 21:59:07 -03:00
|
|
|
int opt;
|
2015-05-04 18:08:42 -03:00
|
|
|
const char *home_str = NULL;
|
|
|
|
const char *model_str = NULL;
|
2015-05-25 00:04:17 -03:00
|
|
|
char *autotest_dir = NULL;
|
2015-05-04 18:08:42 -03:00
|
|
|
float speedup = 1.0f;
|
|
|
|
|
2015-05-30 09:16:37 -03:00
|
|
|
if (asprintf(&autotest_dir, SKETCHBOOK "/Tools/autotest") <= 0) {
|
|
|
|
hal.scheduler->panic("out of memory");
|
|
|
|
}
|
2015-05-25 00:04:17 -03:00
|
|
|
|
2015-05-04 21:59:07 -03:00
|
|
|
signal(SIGFPE, _sig_fpe);
|
|
|
|
// No-op SIGPIPE handler
|
|
|
|
signal(SIGPIPE, SIG_IGN);
|
2015-05-04 18:08:42 -03:00
|
|
|
|
|
|
|
setvbuf(stdout, (char *)0, _IONBF, 0);
|
|
|
|
setvbuf(stderr, (char *)0, _IONBF, 0);
|
|
|
|
|
|
|
|
_synthetic_clock_mode = false;
|
|
|
|
_base_port = 5760;
|
|
|
|
_rcout_port = 5502;
|
|
|
|
_simin_port = 5501;
|
|
|
|
_fdm_address = "127.0.0.1";
|
2015-05-10 02:36:18 -03:00
|
|
|
_client_address = NULL;
|
2015-05-10 08:02:20 -03:00
|
|
|
_instance = 0;
|
2015-05-10 02:36:18 -03:00
|
|
|
|
|
|
|
enum long_options {
|
2015-05-24 23:11:16 -03:00
|
|
|
CMDLINE_CLIENT=0,
|
2015-05-25 00:04:17 -03:00
|
|
|
CMDLINE_GIMBAL,
|
|
|
|
CMDLINE_AUTOTESTDIR
|
2015-05-10 02:36:18 -03:00
|
|
|
};
|
2015-05-04 18:08:42 -03:00
|
|
|
|
2015-05-04 21:59:07 -03:00
|
|
|
const struct GetOptLong::option options[] = {
|
2015-05-04 18:08:42 -03:00
|
|
|
{"help", false, 0, 'h'},
|
|
|
|
{"wipe", false, 0, 'w'},
|
|
|
|
{"speedup", true, 0, 's'},
|
|
|
|
{"rate", true, 0, 'r'},
|
|
|
|
{"console", false, 0, 'C'},
|
|
|
|
{"instance", true, 0, 'I'},
|
|
|
|
{"param", true, 0, 'P'},
|
|
|
|
{"synthetic-clock", false, 0, 'S'},
|
|
|
|
{"home", true, 0, 'O'},
|
|
|
|
{"model", true, 0, 'M'},
|
2015-05-10 02:36:18 -03:00
|
|
|
{"client", true, 0, CMDLINE_CLIENT},
|
2015-05-24 23:11:16 -03:00
|
|
|
{"gimbal", false, 0, CMDLINE_GIMBAL},
|
2015-05-25 00:04:17 -03:00
|
|
|
{"autotest-dir", true, 0, CMDLINE_AUTOTESTDIR},
|
2015-05-04 21:59:07 -03:00
|
|
|
{0, false, 0, 0}
|
|
|
|
};
|
2015-05-04 18:08:42 -03:00
|
|
|
|
2015-05-10 19:48:42 -03:00
|
|
|
GetOptLong gopt(argc, argv, "hws:r:CI:P:SO:M:F:",
|
2015-05-04 18:08:42 -03:00
|
|
|
options);
|
|
|
|
|
|
|
|
while ((opt = gopt.getoption()) != -1) {
|
2015-05-04 21:59:07 -03:00
|
|
|
switch (opt) {
|
|
|
|
case 'w':
|
|
|
|
AP_Param::erase_all();
|
|
|
|
unlink("dataflash.bin");
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
_framerate = (unsigned)atoi(gopt.optarg);
|
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
HALSITL::SITLUARTDriver::_console = true;
|
|
|
|
break;
|
|
|
|
case 'I': {
|
2015-05-10 08:02:20 -03:00
|
|
|
_instance = atoi(gopt.optarg);
|
|
|
|
_base_port += _instance * 10;
|
|
|
|
_rcout_port += _instance * 10;
|
|
|
|
_simin_port += _instance * 10;
|
2015-05-04 18:08:42 -03:00
|
|
|
}
|
2015-05-04 21:59:07 -03:00
|
|
|
break;
|
|
|
|
case 'P':
|
2015-05-04 18:08:42 -03:00
|
|
|
_set_param_default(gopt.optarg);
|
2015-05-04 21:59:07 -03:00
|
|
|
break;
|
|
|
|
case 'S':
|
2015-05-04 18:08:42 -03:00
|
|
|
_synthetic_clock_mode = true;
|
2015-05-04 21:59:07 -03:00
|
|
|
break;
|
2015-05-04 18:08:42 -03:00
|
|
|
case 'O':
|
|
|
|
home_str = gopt.optarg;
|
|
|
|
break;
|
|
|
|
case 'M':
|
|
|
|
model_str = gopt.optarg;
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
speedup = atof(gopt.optarg);
|
|
|
|
break;
|
|
|
|
case 'F':
|
|
|
|
_fdm_address = gopt.optarg;
|
|
|
|
break;
|
2015-05-10 02:36:18 -03:00
|
|
|
case CMDLINE_CLIENT:
|
|
|
|
_client_address = gopt.optarg;
|
|
|
|
break;
|
2015-05-24 23:11:16 -03:00
|
|
|
case CMDLINE_GIMBAL:
|
|
|
|
enable_gimbal = true;
|
|
|
|
break;
|
2015-05-25 00:04:17 -03:00
|
|
|
case CMDLINE_AUTOTESTDIR:
|
|
|
|
autotest_dir = strdup(gopt.optarg);
|
|
|
|
break;
|
2015-05-04 21:59:07 -03:00
|
|
|
default:
|
|
|
|
_usage();
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
2015-05-04 18:08:42 -03:00
|
|
|
|
|
|
|
if (model_str && home_str) {
|
2015-07-20 16:53:47 -03:00
|
|
|
for (uint8_t i=0; i < ARRAY_SIZE(model_constructors); i++) {
|
2015-05-22 03:04:11 -03:00
|
|
|
if (strncasecmp(model_constructors[i].name, model_str, strlen(model_constructors[i].name)) == 0) {
|
2015-05-04 18:08:42 -03:00
|
|
|
sitl_model = model_constructors[i].constructor(home_str, model_str);
|
|
|
|
sitl_model->set_speedup(speedup);
|
2015-05-10 08:02:20 -03:00
|
|
|
sitl_model->set_instance(_instance);
|
2015-05-25 00:04:17 -03:00
|
|
|
sitl_model->set_autotest_dir(autotest_dir);
|
2015-05-04 18:08:42 -03:00
|
|
|
_synthetic_clock_mode = true;
|
|
|
|
printf("Started model %s at %s at speed %.1f\n", model_str, home_str, speedup);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-04 21:59:07 -03:00
|
|
|
fprintf(stdout, "Starting sketch '%s'\n", SKETCH);
|
|
|
|
|
|
|
|
if (strcmp(SKETCH, "ArduCopter") == 0) {
|
|
|
|
_vehicle = ArduCopter;
|
|
|
|
if (_framerate == 0) {
|
|
|
|
_framerate = 200;
|
|
|
|
}
|
|
|
|
} else if (strcmp(SKETCH, "APMrover2") == 0) {
|
|
|
|
_vehicle = APMrover2;
|
|
|
|
if (_framerate == 0) {
|
|
|
|
_framerate = 50;
|
|
|
|
}
|
|
|
|
// set right default throttle for rover (allowing for reverse)
|
2015-05-04 18:08:42 -03:00
|
|
|
pwm_input[2] = 1500;
|
2015-05-04 21:59:07 -03:00
|
|
|
} else {
|
|
|
|
_vehicle = ArduPlane;
|
|
|
|
if (_framerate == 0) {
|
|
|
|
_framerate = 50;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_sitl_setup();
|
2015-05-04 18:08:42 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|