From e55d5750e91549dc47a7f6ce5e65841f918053d0 Mon Sep 17 00:00:00 2001 From: Praveen Kumar Date: Mon, 9 Mar 2020 18:34:35 +0530 Subject: [PATCH] Sychronous mode bug resolution --- .../trafficmanager/BatchControlStage.cpp | 44 +++++++++++++------ .../carla/trafficmanager/BatchControlStage.h | 3 +- .../carla/trafficmanager/Parameters.cpp | 3 -- .../source/carla/trafficmanager/Parameters.h | 2 +- .../carla/source/libcarla/TrafficManager.cpp | 3 +- PythonAPI/examples/spawn_npc.py | 1 + 6 files changed, 37 insertions(+), 19 deletions(-) diff --git a/LibCarla/source/carla/trafficmanager/BatchControlStage.cpp b/LibCarla/source/carla/trafficmanager/BatchControlStage.cpp index 37ce8f614..abd556420 100644 --- a/LibCarla/source/carla/trafficmanager/BatchControlStage.cpp +++ b/LibCarla/source/carla/trafficmanager/BatchControlStage.cpp @@ -65,28 +65,46 @@ void BatchControlStage::DataSender() { messenger->Pop(); bool synch_mode = parameters.GetSynchronousMode(); - if (commands != nullptr) { - // Run asynchronous mode commands. - episode_proxy_bcs.Lock()->ApplyBatch(*commands.get(), false); - } - - // Limiting updates to 100 frames per second. + // Asynchronous mode. if (!synch_mode) { + // Apply batch command through an asynchronous RPC call. + if (commands != nullptr) { + episode_proxy_bcs.Lock()->ApplyBatch(*commands.get(), false); + } + // Limiting updates to 100 frames per second. std::this_thread::sleep_for(10ms); - } else { + } + // Synchronous mode. + else { std::unique_lock lock(step_execution_mutex); - // Get timeout value in milliseconds. - double timeout = parameters.GetSynchronousModeTimeOutInMiliSecond(); - // Wait for service to finish. - step_execution_notifier.wait_for(lock, timeout * 1ms, [this]() { return run_step.load(); }); + // TODO: Re-introduce timeout while waiting for RunStep() call. + while (!run_step.load()) { + step_execution_notifier.wait_for(lock, 1ms, [this]() {return run_step.load();}); + } + // Apply batch command in synchronous RPC call. + if (commands != nullptr) { + episode_proxy_bcs.Lock()->ApplyBatchSync(*commands.get(), false); + } + // Set flag to false, unblock RunStep() call and release mutex lock. run_step.store(false); + step_complete_notifier.notify_one(); + lock.unlock(); } } bool BatchControlStage::RunStep() { - // Set run set flag. - run_step.store(true); + + bool synch_mode = parameters.GetSynchronousMode(); + if (synch_mode) { + std::unique_lock lock(step_execution_mutex); + // Set flag to true, notify DataSender and wait for a return notification + run_step.store(true); + step_execution_notifier.notify_one(); + while (run_step.load()) { + step_complete_notifier.wait_for(lock, 1ms, [this]() {return !run_step.load();}); + } + } return true; } diff --git a/LibCarla/source/carla/trafficmanager/BatchControlStage.h b/LibCarla/source/carla/trafficmanager/BatchControlStage.h index 880962cb3..4e0a9ced5 100644 --- a/LibCarla/source/carla/trafficmanager/BatchControlStage.h +++ b/LibCarla/source/carla/trafficmanager/BatchControlStage.h @@ -47,11 +47,12 @@ private: /// Parameter object for changing synchronous behaviour. Parameters ¶meters; /// Step runner flag. - std::atomic run_step; + std::atomic run_step {false}; /// Mutex for progressing synchronous execution. std::mutex step_execution_mutex; /// Condition variables for progressing synchronous execution. std::condition_variable step_execution_notifier; + std::condition_variable step_complete_notifier; public: diff --git a/LibCarla/source/carla/trafficmanager/Parameters.cpp b/LibCarla/source/carla/trafficmanager/Parameters.cpp index 91c848043..7b9dce9d1 100644 --- a/LibCarla/source/carla/trafficmanager/Parameters.cpp +++ b/LibCarla/source/carla/trafficmanager/Parameters.cpp @@ -13,9 +13,6 @@ namespace traffic_manager { Parameters::Parameters() { - /// Set default synchronous mode to false. - synchronous_mode.store(false); - /// Set default synchronous mode time out. synchronous_time_out = std::chrono::duration(10); } diff --git a/LibCarla/source/carla/trafficmanager/Parameters.h b/LibCarla/source/carla/trafficmanager/Parameters.h index d2d9d8e58..beb0295fd 100644 --- a/LibCarla/source/carla/trafficmanager/Parameters.h +++ b/LibCarla/source/carla/trafficmanager/Parameters.h @@ -57,7 +57,7 @@ namespace traffic_manager { /// Map containing % of keep right rule. AtomicMap perc_keep_right; /// Synchronous mode switch. - std::atomic synchronous_mode; + std::atomic synchronous_mode {false}; /// Distance Margin std::atomic distance_margin {2.0}; diff --git a/PythonAPI/carla/source/libcarla/TrafficManager.cpp b/PythonAPI/carla/source/libcarla/TrafficManager.cpp index a0b54a840..b7bbcf28b 100644 --- a/PythonAPI/carla/source/libcarla/TrafficManager.cpp +++ b/PythonAPI/carla/source/libcarla/TrafficManager.cpp @@ -29,5 +29,6 @@ void export_trafficmanager() { .def("ignore_lights_percentage", &carla::traffic_manager::TrafficManager::SetPercentageRunningLight) .def("ignore_signs_percentage", &carla::traffic_manager::TrafficManager::SetPercentageRunningSign) .def("set_global_distance_to_leading_vehicle", &carla::traffic_manager::TrafficManager::SetGlobalDistanceToLeadingVehicle) - .def("set_percentage_keep_right_rule", &carla::traffic_manager::TrafficManager::SetKeepRightPercentage); + .def("set_percentage_keep_right_rule", &carla::traffic_manager::TrafficManager::SetKeepRightPercentage) + .def("set_synchronous_mode", &carla::traffic_manager::TrafficManager::SetSynchronousMode); } diff --git a/PythonAPI/examples/spawn_npc.py b/PythonAPI/examples/spawn_npc.py index fc0fb5920..b5063c3e6 100755 --- a/PythonAPI/examples/spawn_npc.py +++ b/PythonAPI/examples/spawn_npc.py @@ -98,6 +98,7 @@ def main(): if args.sync: settings = world.get_settings() + traffic_manager.set_synchronous_mode(True) if not settings.synchronous_mode: synchronous_master = True settings.synchronous_mode = True