@@ -74,9 +74,12 @@ class LockStepPlugin::Impl
7474 // / \brief Mutex used when accessing lock step message.
7575 public: std::mutex enableLockStepMutex;
7676
77- // / \brief True if lock-step is enabled.
77+ // / \brief True if lock-step is to be enabled.
7878 public: bool enableLockStep{false };
7979
80+ // / \brief True if lock-step is enabled.
81+ public: bool isLockStep{false };
82+
8083 // / \brief Mutex used when accessing start step message.
8184 public: std::mutex startStepMutex;
8285
@@ -106,13 +109,20 @@ class LockStepPlugin::Impl
106109
107110 // / \brief Signal handler callback.
108111 public: void OnSignal (int _sig);
112+
113+ // / \brief Publish lock step complete.
114+ public: void PublishLockStepComplete (
115+ const std::chrono::steady_clock::duration &_simTime);
109116};
110117
111118// ////////////////////////////////////////////////
112119void LockStepPlugin::Impl::OnEnable (const msgs::Boolean &_msg)
113120{
114121 std::lock_guard<std::mutex> lock (this ->enableLockStepMutex );
115122 this ->enableLockStep = _msg.data ();
123+ gzdbg << " LockStepPlugin: Received Enable Lock Step: "
124+ << " [" << this ->enableLockStep << " ]"
125+ << std::endl;
116126}
117127
118128// ////////////////////////////////////////////////
@@ -121,16 +131,39 @@ void LockStepPlugin::Impl::OnStart(const msgs::Time &_msg)
121131 std::lock_guard<std::mutex> lock (this ->startStepMutex );
122132 this ->startStepMsg = _msg;
123133 this ->startStep = true ;
134+ gzdbg << " LockStepPlugin: Received Lock Step Start "
135+ << " ["
136+ << this ->startStepMsg .sec () << " s, "
137+ << this ->startStepMsg .nsec () << " ns"
138+ << " ]"
139+ << std::endl;
124140}
125141
126142// ////////////////////////////////////////////////
127143void LockStepPlugin::Impl::OnSignal (int _sig)
128144{
129- gzdbg << " LockStepPlugin received signal [" << _sig << " ]"
145+ gzdbg << " LockStepPlugin: Received Signal [" << _sig << " ]"
130146 << std::endl;
131147 this ->signal = _sig;
132148}
133149
150+ // ////////////////////////////////////////////////
151+ void LockStepPlugin::Impl::PublishLockStepComplete (
152+ const std::chrono::steady_clock::duration &_simTime)
153+ {
154+ auto simTimeSecNsec = math::durationToSecNsec (_simTime);
155+ msgs::Time msg;
156+ msg.set_sec (simTimeSecNsec.first );
157+ msg.set_nsec (simTimeSecNsec.second );
158+ this ->stepCompletePub .Publish (msg);
159+ gzdbg << " LockStepPlugin: Send Lock Step Complete "
160+ << " ["
161+ << msg.sec () << " s, "
162+ << msg.nsec () << " ns"
163+ << " ]"
164+ << std::endl;
165+ }
166+
134167// ////////////////////////////////////////////////
135168// ////////////////////////////////////////////////
136169LockStepPlugin::~LockStepPlugin () = default ;
@@ -183,24 +216,24 @@ void LockStepPlugin::Configure(
183216 &LockStepPlugin::Impl::OnEnable, this ->impl .get ());
184217
185218 gzdbg << " LockStepPlugin subscribing to messages on "
186- << " [" << enableTopic << " ]"
187- << std::endl;
219+ << " [" << enableTopic << " ]"
220+ << std::endl;
188221
189222 this ->impl ->node .Subscribe (
190223 startTopic,
191224 &LockStepPlugin::Impl::OnStart, this ->impl .get ());
192225
193226 gzdbg << " LockStepPlugin subscribing to messages on "
194- << " [" << startTopic << " ]"
195- << std::endl;
227+ << " [" << startTopic << " ]"
228+ << std::endl;
196229
197230 // Publishers
198231 this ->impl ->stepCompletePub =
199232 this ->impl ->node .Advertise <msgs::Time>(completeTopic);
200233
201234 gzdbg << " LockStepPlugin publishing messages on "
202- << " [" << completeTopic << " ]"
203- << std::endl;
235+ << " [" << completeTopic << " ]"
236+ << std::endl;
204237
205238 // Signal handler
206239 this ->impl ->sigHandler .AddCallback (
@@ -218,7 +251,7 @@ void LockStepPlugin::PreUpdate(
218251 const UpdateInfo &_info,
219252 EntityComponentManager &_ecm)
220253{
221- using namespace std ::literals ;
254+ using namespace std ::chrono_literals ;
222255
223256 GZ_PROFILE (" LockStepPlugin::PreUpdate" );
224257
@@ -227,21 +260,49 @@ void LockStepPlugin::PreUpdate(
227260 return ;
228261 }
229262
230- if (!_info.paused && _info.simTime > this ->impl ->lastUpdateSimTime
231- && this ->impl ->enableLockStep )
263+ // Ensure that when lock-step is enabled, it always starts in PreUpdate.
264+ if (this ->impl ->enableLockStep && !this ->impl ->isLockStep )
265+ {
266+ this ->impl ->isLockStep = true ;
267+ gzdbg << " LockStepPlugin: Initiate Lock-Stepping." << std::endl;
268+ }
269+
270+ if (!this ->impl ->isLockStep )
271+ {
272+ return ;
273+ }
274+
275+ if (!_info.paused && _info.simTime > this ->impl ->lastUpdateSimTime )
276+ // if (!_info.paused)
232277 {
233278 while (!this ->impl ->startStep )
234279 {
235- // SIGNINT should interrupt this loop.
280+ // Break if lock-step disabled.
281+ if (!this ->impl ->enableLockStep )
282+ {
283+ gzdbg << " LockStepPlugin: Lock-Step Disabled." << std::endl;
284+ break ;
285+ }
286+
287+ // Break on SIGNINT.
236288 if (this ->impl ->signal != 0 )
237289 {
290+ gzdbg << " LockStepPlugin: SIGNINT." << std::endl;
238291 break ;
239292 }
240- std::this_thread::sleep_for (100us );
293+ std::this_thread::sleep_for (1us );
241294 }
242295 {
243296 std::lock_guard<std::mutex> lock (this ->impl ->startStepMutex );
244297 this ->impl ->startStep = false ;
298+
299+ auto simTimeSecNsec = math::durationToSecNsec (_info.simTime );
300+ gzdbg << " LockStepPlugin: PreUpdate Complete: "
301+ << " ["
302+ << simTimeSecNsec.first << " s, "
303+ << simTimeSecNsec.second << " ns"
304+ << " ]"
305+ << std::endl;
245306 }
246307 }
247308}
@@ -253,16 +314,37 @@ void LockStepPlugin::PostUpdate(
253314{
254315 GZ_PROFILE (" LockStepPlugin::PostUpdate" );
255316
256- if (!_info.paused && _info.simTime > this ->impl ->lastUpdateSimTime
257- && this ->impl ->enableLockStep )
317+ if (!this ->impl ->isValidConfig )
318+ {
319+ return ;
320+ }
321+
322+ if (!this ->impl ->isLockStep )
323+ {
324+ return ;
325+ }
326+
327+ // Ensure that when lock-step is disabled, it always stops in PostUpdate.
328+ if (!this ->impl ->enableLockStep )
329+ {
330+ this ->impl ->isLockStep = false ;
331+ gzdbg << " LockStepPlugin: Terminate Lock-Stepping." << std::endl;
332+ }
333+
334+ if (!_info.paused && _info.simTime > this ->impl ->lastUpdateSimTime )
335+ // if (!_info.paused)
258336 {
259337 this ->impl ->lastUpdateSimTime = _info.simTime ;
338+ this ->impl ->PublishLockStepComplete (_info.simTime );
260339
261340 auto simTimeSecNsec = math::durationToSecNsec (_info.simTime );
262- msgs::Time stepCompleteMsg;
263- stepCompleteMsg.set_sec (simTimeSecNsec.first );
264- stepCompleteMsg.set_nsec (simTimeSecNsec.second );
265- this ->impl ->stepCompletePub .Publish (stepCompleteMsg);
341+ gzdbg << " LockStepPlugin: PostUpdate Complete: "
342+ << " ["
343+ << simTimeSecNsec.first << " s, "
344+ << simTimeSecNsec.second << " ns"
345+ << " ]\n "
346+ << std::endl;
347+
266348 }
267349}
268350
0 commit comments