Skip to content

Commit 1c15547

Browse files
committed
LockStepPlugin: ensure lock-step is started in PreUpdate
- Ensure lock-stepping always starts in PreUpdate and ends in PostUpdate. - Add debug messages. Signed-off-by: Rhys Mainwaring <rhys.mainwaring@me.com>
1 parent 4fc40d4 commit 1c15547

1 file changed

Lines changed: 101 additions & 19 deletions

File tree

src/LockStepPlugin.cc

Lines changed: 101 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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
//////////////////////////////////////////////////
112119
void 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
//////////////////////////////////////////////////
127143
void 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
//////////////////////////////////////////////////
136169
LockStepPlugin::~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

Comments
 (0)