diff --git a/include/gz/sim/Server.hh b/include/gz/sim/Server.hh index 28b5b3feb1..ae49bd59f6 100644 --- a/include/gz/sim/Server.hh +++ b/include/gz/sim/Server.hh @@ -338,6 +338,9 @@ namespace gz /// \brief Stop the server. This will stop all running simulations. public: void Stop(); + /// \brief Reset all runners in this simulation + public: void ResetAll(); + /// \brief Private data private: std::unique_ptr dataPtr; }; diff --git a/python/src/gz/sim/Server.cc b/python/src/gz/sim/Server.cc index c148a08ff2..7ece7ec090 100644 --- a/python/src/gz/sim/Server.cc +++ b/python/src/gz/sim/Server.cc @@ -46,7 +46,9 @@ void defineSimServer(pybind11::object module) .def( "is_running", pybind11::overload_cast<>(&gz::sim::Server::Running, pybind11::const_), - "Get whether the server is running."); + "Get whether the server is running.") + .def("reset_all", &gz::sim::Server::ResetAll, + "Resets all simulation runners under this server."); } } // namespace python } // namespace sim diff --git a/src/Server.cc b/src/Server.cc index 712f273467..602eb1e569 100644 --- a/src/Server.cc +++ b/src/Server.cc @@ -485,6 +485,17 @@ bool Server::RequestRemoveEntity(const Entity _entity, return false; } +////////////////////////////////////////////////// +void Server::ResetAll() +{ + for (auto worldId = 0u; + worldId < this->dataPtr->simRunners.size(); + worldId++) + { + this->dataPtr->simRunners[worldId]->Reset(true, false, false); + } +} + ////////////////////////////////////////////////// void Server::Stop() { diff --git a/src/SimulationRunner.cc b/src/SimulationRunner.cc index baa2712adc..96ac61d7d4 100644 --- a/src/SimulationRunner.cc +++ b/src/SimulationRunner.cc @@ -1661,3 +1661,17 @@ void SimulationRunner::CreateEntities(const sdf::World &_world) // Store the initial state of the ECM; this->initialEntityCompMgr.CopyFrom(this->entityCompMgr); } + +///////////////////////////////////////////////// +void SimulationRunner::Reset(const bool _all, + const bool _time, const bool _model) +{ + WorldControl control; + std::lock_guard lock(this->msgBufferMutex); + control.rewind = _all || _time; + if (_model) + { + gzwarn << "Model reset not supported" <worldControls.push_back(control); +} diff --git a/src/SimulationRunner.hh b/src/SimulationRunner.hh index 8fe03511e7..8b5ac8bf36 100644 --- a/src/SimulationRunner.hh +++ b/src/SimulationRunner.hh @@ -369,6 +369,9 @@ namespace gz /// \brief Set the next step to be blocking and paused. public: void SetNextStepAsBlockingPaused(const bool value); + /// \brief Reset the current simulation runner + public: void Reset(const bool all, const bool time, const bool model); + /// \brief Updates the physics parameters of the simulation based on the /// Physics component of the world, if any. public: void UpdatePhysicsParams(); diff --git a/src/TestFixture_TEST.cc b/src/TestFixture_TEST.cc index f810ae64c1..21a9b7a9bd 100644 --- a/src/TestFixture_TEST.cc +++ b/src/TestFixture_TEST.cc @@ -72,6 +72,8 @@ TEST_F(TestFixtureTest, Callbacks) unsigned int preUpdates{0u}; unsigned int updates{0u}; unsigned int postUpdates{0u}; + unsigned int resets{0u}; + testFixture. OnConfigure([&](const Entity &_entity, const std::shared_ptr &_sdf, @@ -85,20 +87,33 @@ TEST_F(TestFixtureTest, Callbacks) { this->Updates(_info, _ecm); preUpdates++; - EXPECT_EQ(preUpdates, _info.iterations); + if (resets == 0) + { + EXPECT_EQ(preUpdates, _info.iterations); + } }). OnUpdate([&](const UpdateInfo &_info, EntityComponentManager &_ecm) { this->Updates(_info, _ecm); updates++; - EXPECT_EQ(updates, _info.iterations); + if (resets == 0) + { + EXPECT_EQ(updates, _info.iterations); + } }). OnPostUpdate([&](const UpdateInfo &_info, const EntityComponentManager &_ecm) { this->Updates(_info, _ecm); postUpdates++; - EXPECT_EQ(postUpdates, _info.iterations); + if (resets == 0) + { + EXPECT_EQ(postUpdates, _info.iterations); + } + }). + OnReset([&](const UpdateInfo &, EntityComponentManager &) + { + resets++; }). Finalize(); @@ -109,8 +124,19 @@ TEST_F(TestFixtureTest, Callbacks) EXPECT_EQ(expectedIterations, preUpdates); EXPECT_EQ(expectedIterations, updates); EXPECT_EQ(expectedIterations, postUpdates); + EXPECT_EQ(0u, resets); + + testFixture.Server()->ResetAll(); + + testFixture.Server()->Run(true, expectedIterations, false); + EXPECT_EQ(1u, configures); + EXPECT_EQ(expectedIterations * 2 - 1, preUpdates); + EXPECT_EQ(expectedIterations * 2 - 1, updates); + EXPECT_EQ(expectedIterations * 2 - 1, postUpdates); + EXPECT_EQ(1u, resets); } + ///////////////////////////////////////////////// TEST_F(TestFixtureTest, LoadConfig) {