diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ad7e9ed65..c909d42a13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5.1 FATAL_ERROR) #============================================================================ # Initialize the project #============================================================================ -project(ignition-gazebo2 VERSION 2.17.0) +project(ignition-gazebo2 VERSION 2.18.0) #============================================================================ # Find ignition-cmake diff --git a/Changelog.md b/Changelog.md index 4cd4a50ee5..5b4b1bc9e0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,9 @@ ## Ignition Gazebo 2.x -### Ignition Gazebo 2.xx.xx (2020-xx-xx) +### Ignition Gazebo 2.18.0 (2020-05-20) + +1. Added a `/world//create_multiple` service that parallels the current `/world//create` service. The `create_multiple` service can handle an `ignition::msgs::EntityFactory_V` message that may contain one or more entities to spawn. + * [Pull Request 146](https://github.com/ignitionrobotics/ign-gazebo/pull/146) ### Ignition Gazebo 2.17.0 (2020-05-13) diff --git a/src/systems/user_commands/UserCommands.cc b/src/systems/user_commands/UserCommands.cc index c41749532e..a3ad13250c 100644 --- a/src/systems/user_commands/UserCommands.cc +++ b/src/systems/user_commands/UserCommands.cc @@ -157,6 +157,14 @@ class ignition::gazebo::systems::UserCommandsPrivate public: bool CreateService(const msgs::EntityFactory &_req, msgs::Boolean &_res); + /// \brief Callback for multiple create service + /// \param[in] _req Request containing one or more entity descriptions. + /// \param[in] _res True if message successfully received and queued. + /// It does not mean that the entities will be successfully spawned. + /// \return True if successful. + public: bool CreateServiceMultiple( + const msgs::EntityFactory_V &_req, msgs::Boolean &_res); + /// \brief Callback for remove service /// \param[in] _req Request containing identification of entity to be removed. /// \param[in] _res True if message successfully received and queued. @@ -215,6 +223,11 @@ void UserCommands::Configure(const Entity &_entity, this->dataPtr->node.Advertise(createService, &UserCommandsPrivate::CreateService, this->dataPtr.get()); + // Create service for EntityFactory_V + std::string createServiceMultiple{"/world/" + worldName + "/create_multiple"}; + this->dataPtr->node.Advertise(createServiceMultiple, + &UserCommandsPrivate::CreateServiceMultiple, this->dataPtr.get()); + ignmsg << "Create service on [" << createService << "]" << std::endl; // Remove service @@ -265,6 +278,25 @@ void UserCommands::PreUpdate(const UpdateInfo &/*_info*/, // TODO(louise) Clear redo list } +////////////////////////////////////////////////// +bool UserCommandsPrivate::CreateServiceMultiple( + const msgs::EntityFactory_V &_req, msgs::Boolean &_res) +{ + std::lock_guard lock(this->pendingMutex); + for (int i = 0; i < _req.data_size(); ++i) + { + const msgs::EntityFactory &msg = _req.data(i); + // Create command and push it to queue + auto msgCopy = msg.New(); + msgCopy->CopyFrom(msg); + auto cmd = std::make_unique(msgCopy, this->iface); + this->pendingCmds.push_back(std::move(cmd)); + } + + _res.set_data(true); + return true; +} + ////////////////////////////////////////////////// bool UserCommandsPrivate::CreateService(const msgs::EntityFactory &_req, msgs::Boolean &_res) diff --git a/src/systems/user_commands/UserCommands.hh b/src/systems/user_commands/UserCommands.hh index 0d5ea4cddf..d7f659eeae 100644 --- a/src/systems/user_commands/UserCommands.hh +++ b/src/systems/user_commands/UserCommands.hh @@ -45,6 +45,15 @@ namespace systems /// * **Request type*: ignition.msgs.EntityFactory /// * **Response type*: ignition.msgs.Boolean /// + /// # Spawn multiple entities + /// + /// This service can spawn multiple entities in the same iteration, + /// thereby eliminating simulation steps between entity spawn times. + /// + /// * **Service**: `/world//create_multiple` + /// * **Request type*: ignition.msgs.EntityFactory_V + /// * **Response type*: ignition.msgs.Boolean + /// /// Try some examples described on examples/worlds/empty.sdf class IGNITION_GAZEBO_VISIBLE UserCommands: public System,