diff --git a/missions/auction_assign.xml b/missions/auction_assign.xml index 31e5c343f4..2623d02a1c 100644 --- a/missions/auction_assign.xml +++ b/missions/auction_assign.xml @@ -5,7 +5,7 @@ time diff --git a/missions/auction_assign2.xml b/missions/auction_assign2.xml index a36bbaf82c..c676cad659 100644 --- a/missions/auction_assign2.xml +++ b/missions/auction_assign2.xml @@ -5,7 +5,7 @@ time diff --git a/missions/auction_assign3.xml b/missions/auction_assign3.xml index 2c90cdf431..cf94a041bb 100644 --- a/missions/auction_assign3.xml +++ b/missions/auction_assign3.xml @@ -5,7 +5,7 @@ time diff --git a/missions/batch-example-mission.xml b/missions/batch-example-mission.xml index 2f8da60932..08c6affc4b 100644 --- a/missions/batch-example-mission.xml +++ b/missions/batch-example-mission.xml @@ -5,7 +5,7 @@ diff --git a/missions/capture-the-flag-simple.xml b/missions/capture-the-flag-simple.xml index b4b4222ffe..e04fe84c73 100644 --- a/missions/capture-the-flag-simple.xml +++ b/missions/capture-the-flag-simple.xml @@ -5,7 +5,7 @@ diff --git a/missions/capture-the-flag.xml b/missions/capture-the-flag.xml index d15a959a3a..65db7f6d0d 100644 --- a/missions/capture-the-flag.xml +++ b/missions/capture-the-flag.xml @@ -5,7 +5,7 @@ diff --git a/missions/cars-2d-maze.xml b/missions/cars-2d-maze.xml index 7957a3f750..e0a302f35a 100644 --- a/missions/cars-2d-maze.xml +++ b/missions/cars-2d-maze.xml @@ -5,7 +5,7 @@ diff --git a/missions/cars.xml b/missions/cars.xml index e776ed961b..97a466fd2d 100644 --- a/missions/cars.xml +++ b/missions/cars.xml @@ -5,7 +5,7 @@ diff --git a/missions/colliding_spheres.xml b/missions/colliding_spheres.xml index 7ad901e74b..02b53dba4f 100644 --- a/missions/colliding_spheres.xml +++ b/missions/colliding_spheres.xml @@ -5,7 +5,7 @@ diff --git a/missions/delay-test.xml b/missions/delay-test.xml index f8509fc53a..a0fc0e62db 100644 --- a/missions/delay-test.xml +++ b/missions/delay-test.xml @@ -1,6 +1,6 @@ - time, all_dead diff --git a/missions/fixed_wing_6dof.xml b/missions/fixed_wing_6dof.xml index dc095c8c20..085be989fe 100644 --- a/missions/fixed_wing_6dof.xml +++ b/missions/fixed_wing_6dof.xml @@ -5,7 +5,7 @@ diff --git a/missions/fsm-motor-schemas.xml b/missions/fsm-motor-schemas.xml index aace97be50..212f6f40a2 100644 --- a/missions/fsm-motor-schemas.xml +++ b/missions/fsm-motor-schemas.xml @@ -5,7 +5,7 @@ diff --git a/missions/harmonic-oscillator.xml b/missions/harmonic-oscillator.xml index 083d79cc02..0111c9e0d1 100644 --- a/missions/harmonic-oscillator.xml +++ b/missions/harmonic-oscillator.xml @@ -5,7 +5,7 @@ diff --git a/missions/joystick-jsbsim-groundstart.xml b/missions/joystick-jsbsim-groundstart.xml index d46ffa0330..dd140b09f4 100644 --- a/missions/joystick-jsbsim-groundstart.xml +++ b/missions/joystick-jsbsim-groundstart.xml @@ -5,13 +5,13 @@ diff --git a/missions/joystick-jsbsim.xml b/missions/joystick-jsbsim.xml index f562eda911..044e8ad2b4 100644 --- a/missions/joystick-jsbsim.xml +++ b/missions/joystick-jsbsim.xml @@ -5,7 +5,7 @@ diff --git a/missions/moos-ex1.xml b/missions/moos-ex1.xml index 23cbf86775..c96e1fcfa6 100644 --- a/missions/moos-ex1.xml +++ b/missions/moos-ex1.xml @@ -5,7 +5,7 @@ diff --git a/missions/moos-ex2.xml b/missions/moos-ex2.xml index b199ef8e80..aa34a05ab2 100644 --- a/missions/moos-ex2.xml +++ b/missions/moos-ex2.xml @@ -5,7 +5,7 @@ diff --git a/missions/multirotor-test.xml b/missions/multirotor-test.xml index eac1c5b158..c8c91c9cd6 100644 --- a/missions/multirotor-test.xml +++ b/missions/multirotor-test.xml @@ -5,7 +5,7 @@ diff --git a/missions/predator_prey_boids.xml b/missions/predator_prey_boids.xml index 5a17ca9642..8abb449dc7 100644 --- a/missions/predator_prey_boids.xml +++ b/missions/predator_prey_boids.xml @@ -1,6 +1,6 @@ - time, all_dead diff --git a/missions/quad-airsim-ex1.xml b/missions/quad-airsim-ex1.xml index c3695235d7..6bb17aef97 100644 --- a/missions/quad-airsim-ex1.xml +++ b/missions/quad-airsim-ex1.xml @@ -5,7 +5,7 @@ diff --git a/missions/random-attrit-test.xml b/missions/random-attrit-test.xml index a508c98b9d..ee13471400 100644 --- a/missions/random-attrit-test.xml +++ b/missions/random-attrit-test.xml @@ -5,7 +5,7 @@ diff --git a/missions/rigid_body_6dof.xml b/missions/rigid_body_6dof.xml index eccabaaf2c..7fa332e229 100644 --- a/missions/rigid_body_6dof.xml +++ b/missions/rigid_body_6dof.xml @@ -5,7 +5,7 @@ diff --git a/missions/rlconsensus.xml b/missions/rlconsensus.xml index 81ec69586e..c41f9c02ae 100644 --- a/missions/rlconsensus.xml +++ b/missions/rlconsensus.xml @@ -2,7 +2,7 @@ diff --git a/missions/straight-no-gui.xml b/missions/straight-no-gui.xml index a6f8a9f05b..5586e9c79f 100644 --- a/missions/straight-no-gui.xml +++ b/missions/straight-no-gui.xml @@ -5,7 +5,7 @@ diff --git a/missions/straight-vs-motorschemas.xml b/missions/straight-vs-motorschemas.xml index 247dcd95fe..06fb51fe9c 100644 --- a/missions/straight-vs-motorschemas.xml +++ b/missions/straight-vs-motorschemas.xml @@ -5,7 +5,7 @@ diff --git a/missions/straight.xml b/missions/straight.xml index 5be6ebb2b0..77f6733e1a 100644 --- a/missions/straight.xml +++ b/missions/straight.xml @@ -5,7 +5,7 @@ diff --git a/missions/straight_gpu.xml b/missions/straight_gpu.xml index 97709f289e..aeda23768c 100644 --- a/missions/straight_gpu.xml +++ b/missions/straight_gpu.xml @@ -5,7 +5,7 @@ - + <multi_threaded num_threads="8">false</multi_threaded> <stream_port>50051</stream_port> diff --git a/missions/straight_jsbsim.xml b/missions/straight_jsbsim.xml index e6e6d970c4..4d60c798f7 100644 --- a/missions/straight_jsbsim.xml +++ b/missions/straight_jsbsim.xml @@ -5,7 +5,7 @@ diff --git a/missions/test/test_api.xml b/missions/test/test_api.xml index e2fa5b6801..eb8158cfa2 100644 --- a/missions/test/test_api.xml +++ b/missions/test/test_api.xml @@ -5,7 +5,7 @@ diff --git a/missions/test/test_missing_autonomy.xml b/missions/test/test_missing_autonomy.xml index eaad1dbb17..e84aee887e 100644 --- a/missions/test/test_missing_autonomy.xml +++ b/missions/test/test_missing_autonomy.xml @@ -5,7 +5,7 @@ diff --git a/missions/test/test_missing_controller.xml b/missions/test/test_missing_controller.xml index 8ddb855580..06ebab05de 100644 --- a/missions/test/test_missing_controller.xml +++ b/missions/test/test_missing_controller.xml @@ -5,7 +5,7 @@ diff --git a/missions/test/test_mission_include/test_mission_parse_mission_include.xml b/missions/test/test_mission_include/test_mission_parse_mission_include.xml index cfc4a9e3ad..9e0d0fd9c3 100644 --- a/missions/test/test_mission_include/test_mission_parse_mission_include.xml +++ b/missions/test/test_mission_include/test_mission_parse_mission_include.xml @@ -6,7 +6,7 @@ name="MissionParseIncludeTest"> diff --git a/missions/unicycle.xml b/missions/unicycle.xml index 7df0146956..637949b550 100644 --- a/missions/unicycle.xml +++ b/missions/unicycle.xml @@ -5,7 +5,7 @@ diff --git a/missions/waypoint_follower.xml b/missions/waypoint_follower.xml index 3a0cb7d56a..a9b3f1c46d 100644 --- a/missions/waypoint_follower.xml +++ b/missions/waypoint_follower.xml @@ -5,7 +5,7 @@ diff --git a/share/scrimmage/main.cpp b/share/scrimmage/main.cpp index 63103aea05..97809d36fa 100644 --- a/share/scrimmage/main.cpp +++ b/share/scrimmage/main.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -95,10 +96,11 @@ int main(int argc, char* argv[]) { bool seed_set = false; std::string seed = ""; - std::string overrides = ""; + std::ostringstream overrides; + bool first_override = true; int opt; - while ((opt = getopt(argc, argv, "t:j:s:o:")) != -1) { + while ((opt = getopt(argc, argv, "t:j:s:")) != -1) { switch (opt) { case 't': task_id = std::stoi(std::string(optarg)); @@ -110,9 +112,6 @@ int main(int argc, char* argv[]) { seed = std::string(optarg); seed_set = true; break; - case 'o': - overrides = std::string(optarg); - break; case '?': if (optopt == 't') { fprintf(stderr, "Option -%d requires an integer argument.\n", optopt); @@ -126,7 +125,34 @@ int main(int argc, char* argv[]) { } if (optind >= argc || argc < 2) { - cout << "usage: " << argv[0] << " scenario.xml" << endl; + cout << "usage: " << argv[0] << " [var:=value ...] scenario.xml [var:=value ...]" << endl; + return -1; + } + + // Parse positional arguments: args with ":=" are overrides, first without is mission file + std::string mission_file; + for (int i = optind; i < argc; ++i) { + std::string arg(argv[i]); + if (arg.find(":=") != std::string::npos) { + // This is an override - normalize := to = + if (!first_override) { + overrides << ","; + } + first_override = false; + // Replace := with = + std::string normalized = arg; + size_t pos = normalized.find(":="); + normalized.replace(pos, 2, "="); + overrides << normalized; + } else if (mission_file.empty()) { + // First non-override arg is the mission file + mission_file = arg; + } + } + + if (mission_file.empty()) { + std::cerr << "Error: No mission file specified" << endl; + std::cerr << "usage: " << argv[0] << " [var:=value ...] scenario.xml [var:=value ...]" << endl; return -1; } @@ -135,10 +161,7 @@ int main(int argc, char* argv[]) { simcontrol.mp()->set_task_number(task_id); if (job_id != -1) simcontrol.mp()->set_job_number(job_id); - simcontrol.mp()->set_overrides(overrides); - - // Load in the mission file and parse mission parameters - std::string mission_file = argv[optind]; + simcontrol.mp()->set_overrides(overrides.str()); if (not simcontrol.init(mission_file)) { cout << "Failed to initialize SimControl with mission file: " << mission_file << endl; return -1; @@ -177,7 +200,9 @@ int main(int argc, char* argv[]) { } // Initialize the VTK GUI viewer - viewer->init(simcontrol.mp(), camera_params); + if (!viewer->init(simcontrol.mp(), camera_params)) { + return -1; + } // Run the viewer in its own thread auto viewer_thread_func = [&]() { viewer->run(); }; diff --git a/src/parse/MissionParse.cpp b/src/parse/MissionParse.cpp index 6327087e02..a43a1f2cc0 100644 --- a/src/parse/MissionParse.cpp +++ b/src/parse/MissionParse.cpp @@ -72,11 +72,10 @@ void MissionParse::set_overrides(const std::string& overrides) { std::vector overrides_tokens; split(overrides_tokens, overrides_no_space, ", "); for (auto& overrides_str : overrides_tokens) { - // Parse each key=value pair std::vector kv_tokens; - split(kv_tokens, overrides_str, ":= "); + split(kv_tokens, overrides_str, "="); - // Only add to the map if the key:value was parsed correctly + // Only add to the map if the key=value was parsed correctly if (kv_tokens.size() == 2) { overrides_map_[kv_tokens[0]] = kv_tokens[1]; } diff --git a/src/viewer/Viewer.cpp b/src/viewer/Viewer.cpp index a61500091c..d2c9d48189 100644 --- a/src/viewer/Viewer.cpp +++ b/src/viewer/Viewer.cpp @@ -60,6 +60,15 @@ void Viewer::set_enable_network(bool enable) { bool Viewer::init( const std::shared_ptr& mp, const std::map& camera_params) { + + // Check for display availability (X11 on Linux) + const char* display = std::getenv("DISPLAY"); + if (display == nullptr || display[0] == '\0') { + std::cerr << "Error: GUI enabled but no DISPLAY environment variable set.\n" + << "Run with enable_gui:=false or set DISPLAY for X11 forwarding." << std::endl; + return false; + } + renderer_ = vtkSmartPointer::New(); renderWindow_ = vtkSmartPointer::New();