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();