@@ -29,7 +29,7 @@ ProController_SysbotBase::ProController_SysbotBase(
2929 , m_stopping(false )
3030 , m_replace_on_next(false )
3131 , m_command_queue(QUEUE_SIZE)
32- , m_is_active( false )
32+ , m_next_state_change(WallClock::max() )
3333{
3434 if (!connection.is_ready ()){
3535 return ;
@@ -74,11 +74,9 @@ void ProController_SysbotBase::cancel_all_commands(){
7474// cout << "ProController_SysbotBase::cancel_all_commands()" << endl;
7575 std::lock_guard<std::mutex> lg (m_state_lock);
7676 size_t queue_size = m_command_queue.size ();
77- if (queue_size > 0 ){
78- m_command_queue.clear ();
79- m_is_active = false ;
80- m_cv.notify_all ();
81- }
77+ m_next_state_change = WallClock::min ();
78+ m_command_queue.clear ();
79+ m_cv.notify_all ();
8280 this ->clear_on_next ();
8381 m_logger.log (" cancel_all_commands(): Command Queue Size = " + std::to_string (queue_size), COLOR_DARKGREEN);
8482}
@@ -99,7 +97,7 @@ void ProController_SysbotBase::wait_for_all(const Cancellable* cancellable){
9997 m_logger.log (" wait_for_all(): Command Queue Size = " + std::to_string (m_command_queue.size ()), COLOR_DARKGREEN);
10098 this ->issue_wait_for_all (cancellable);
10199 m_cv.wait (lg1, [this ]{
102- return m_command_queue. empty () || m_replace_on_next;
100+ return m_next_state_change == WallClock::max () || m_replace_on_next;
103101 });
104102 if (cancellable){
105103 cancellable->throw_if_cancelled ();
@@ -151,12 +149,16 @@ void ProController_SysbotBase::push_state(const Cancellable* cancellable, WallDu
151149 }
152150
153151 if (m_replace_on_next){
154- m_command_queue.clear ();
155- m_is_active = false ;
152+ // cout << "executing replace" << endl;
156153 m_replace_on_next = false ;
154+ m_command_queue.clear ();
155+ m_next_state_change = WallClock::min ();
156+ m_cv.notify_all ();
157157 }
158158
159- if (m_command_queue.empty ()){
159+ // Enqueuing into empty+idle queue.
160+ if (m_next_state_change == WallClock::max ()){
161+ m_next_state_change = WallClock::min ();
160162 m_cv.notify_all ();
161163 }
162164
@@ -298,52 +300,34 @@ void ProController_SysbotBase::thread_body(){
298300
299301 std::unique_lock<std::mutex> lg (m_state_lock);
300302 while (!m_stopping.load (std::memory_order_relaxed)){
301- if (m_command_queue.empty ()){
302- m_is_active = false ;
303- if (current_state.is_neutral ()){
304- m_cv.wait (lg);
305- continue ;
306- }
307-
308- send_diff (current_state, ProControllerState ());
309- current_state.clear ();
310- continue ;
311- }
312-
313303 WallClock now = current_time ();
314304
315- // Check the next item in the schedule.
316- Command& command = m_command_queue.front ();
317-
318- // Waking up from idle.
319- if (!m_is_active){
320- m_is_active = true ;
321- m_queue_start_time = now;
322-
323- send_diff (current_state, command.state );
324- current_state = command.state ;
325-
326- WallClock expiration = m_queue_start_time + command.duration ;
327- m_cv.wait_until (lg, expiration - EARLY_WAKE);
328- pause ();
305+ // State change.
306+ if (now >= m_next_state_change){
307+ if (m_command_queue.empty ()){
308+ send_diff (current_state, ProControllerState ());
309+ current_state.clear ();
310+ m_next_state_change = WallClock::max ();
311+ }else {
312+ Command& command = m_command_queue.front ();
313+ send_diff (current_state, command.state );
314+ current_state = command.state ;
315+ if (m_next_state_change == WallClock::min ()){
316+ m_next_state_change = now;
317+ }
318+ m_next_state_change += command.duration ;
319+ m_command_queue.pop_front ();
320+ }
321+ m_cv.notify_all ();
329322 continue ;
330323 }
331324
332- // Already running.
333- WallClock expiration = m_queue_start_time + command.duration ;
334-
335- // Current command hasn't expired yet.
336- if (now < expiration){
337- m_cv.wait_until (lg, expiration - EARLY_WAKE);
325+ if (now + EARLY_WAKE >= m_next_state_change){
338326 pause ();
339327 continue ;
340328 }
341329
342- // Command has expired. We can pop it.
343- m_is_active = false ;
344- m_queue_start_time = expiration;
345- m_command_queue.pop_front ();
346- m_cv.notify_all ();
330+ m_cv.wait_until (lg, m_next_state_change - EARLY_WAKE);
347331
348332 // Check how much we shot passed the expiration time.
349333// WallDuration delay = now - expiration;
0 commit comments