diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bd14ed68..ca539218 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: name: Ubuntu Focal CI steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Compile and test id: ci uses: gazebo-tooling/action-gz-ci@focal @@ -21,7 +21,7 @@ jobs: name: Ubuntu Jammy CI steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Compile and test id: ci uses: gazebo-tooling/action-gz-ci@jammy diff --git a/COPYING b/COPYING deleted file mode 100644 index 4909afd0..00000000 --- a/COPYING +++ /dev/null @@ -1,178 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - diff --git a/Changelog.md b/Changelog.md index 46c6eca4..21e4cddf 100644 --- a/Changelog.md +++ b/Changelog.md @@ -188,6 +188,24 @@ ## Gazebo Launch 2.x +### Gazebo Launch 2.3.0 (2022-08-15) + +1. Remove redundant namespace references + * [Pull request #190](https://github.com/gazebosim/gz-launch/pull/190) + +1. Add code coverage ignore file + * [Pull request #179](https://github.com/gazebosim/gz-launch/pull/179) + +1. Change `IGN_DESIGNATION` to `GZ_DESIGNATION` + * [Pull request #181](https://github.com/gazebosim/gz-launch/pull/181) + * [Pull request #182](https://github.com/gazebosim/gz-launch/pull/182) + +1. Ignition -> Gazebo + * [Pull request #178](https://github.com/gazebosim/gz-launch/pull/178) + +1. Bash completion for flags + * [Pull request #167](https://github.com/gazebosim/gz-launch/pull/167) + ### Gazebo Launch 2.2.2 (2021-10-11) 1. Master branch updates. @@ -252,7 +270,7 @@ ### Gazebo Launch 1.10.0 (2020-09-25) * Modernize Github Actions CI. - * [Pull request 42](https://github.com/gazebosim/gz-launch/pull/42) + * [Pull request 42](https://github.com/gazebosim/gz-launch/pull/42) 1. Add PKGCONFIG information to gz-tools gz_find_package * [Pull Request 44](https://github.com/gazebosim/gz-launch/pull/44) diff --git a/LICENSE b/LICENSE index 69fc1e10..4909afd0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,15 +1,178 @@ -Software License Agreement (Apache License) + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Copyright 2018 Open Source Robotics Foundation + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/include/gz/launch/Plugin.hh b/include/gz/launch/Plugin.hh index 3409c9b1..e77886f7 100644 --- a/include/gz/launch/Plugin.hh +++ b/include/gz/launch/Plugin.hh @@ -30,6 +30,9 @@ namespace gz /// \brief Base class for launch plugins. class Plugin { + // Default destructor + public: virtual ~Plugin() {} + /// \brief Load function that each launch plugin must implement. /// \param[in] _elem Pointer to the XML for this plugin. /// \return True to keep the plugin alive. Return false to have the diff --git a/plugins/joy_to_twist/JoyToTwist.cc b/plugins/joy_to_twist/JoyToTwist.cc index 862d634a..5242c66a 100644 --- a/plugins/joy_to_twist/JoyToTwist.cc +++ b/plugins/joy_to_twist/JoyToTwist.cc @@ -51,7 +51,7 @@ void setVectorFromString(const std::string &_str, ///////////////////////////////////////////////// JoyToTwist::JoyToTwist() - : gz::launch::Plugin() + : Plugin() { } diff --git a/plugins/joystick/Joystick.cc b/plugins/joystick/Joystick.cc index 796db43c..5ce871af 100644 --- a/plugins/joystick/Joystick.cc +++ b/plugins/joystick/Joystick.cc @@ -33,7 +33,7 @@ using namespace gz::launch; ///////////////////////////////////////////////// Joystick::Joystick() - : gz::launch::Plugin() + : Plugin() { } diff --git a/plugins/sim_factory/SimFactory.cc b/plugins/sim_factory/SimFactory.cc index 600a7df9..cee409db 100644 --- a/plugins/sim_factory/SimFactory.cc +++ b/plugins/sim_factory/SimFactory.cc @@ -29,7 +29,7 @@ using namespace gz::launch; ///////////////////////////////////////////////// SimFactory::SimFactory() - : gz::launch::Plugin() + : launch::Plugin() { } @@ -125,7 +125,7 @@ void SimFactory::ProcessSpawn(const tinyxml2::XMLElement *_elem) elem = _elem->FirstChildElement("pose"); if (elem) { - gz::math::Pose3d pose; + math::Pose3d pose; std::stringstream stream; stream << elem->GetText(); stream >> pose; diff --git a/plugins/sim_gui/SimGui.cc b/plugins/sim_gui/SimGui.cc index e63b3914..bca44f23 100644 --- a/plugins/sim_gui/SimGui.cc +++ b/plugins/sim_gui/SimGui.cc @@ -30,7 +30,7 @@ using namespace gz::launch; ///////////////////////////////////////////////// SimGui::SimGui() - : gz::launch::Plugin() + : launch::Plugin() { } @@ -47,18 +47,18 @@ bool SimGui::Load(const tinyxml2::XMLElement *_elem) // Set default config file for Launch std::string defaultConfigPath; - gz::common::env(GZ_HOMEDIR, defaultConfigPath); - defaultConfigPath = gz::common::joinPaths(defaultConfigPath, + common::env(GZ_HOMEDIR, defaultConfigPath); + defaultConfigPath = common::joinPaths(defaultConfigPath, ".gz", "launch"); - auto defaultConfigFile = gz::common::joinPaths(defaultConfigPath, + auto defaultConfigFile = common::joinPaths(defaultConfigPath, "gui.config"); // Check if there's a default config file under // ~/.gz/launch and use that. If there isn't, create it - if (!gz::common::exists(defaultConfigFile)) + if (!common::exists(defaultConfigFile)) { - gz::common::createDirectories(defaultConfigPath); + common::createDirectories(defaultConfigPath); std::ofstream configFile(defaultConfigFile); if (configFile.is_open()) @@ -98,7 +98,7 @@ bool SimGui::Load(const tinyxml2::XMLElement *_elem) auto app = sim::gui::createGui(argc, argv, defaultConfigFile.c_str(), defaultConfigFile.c_str(), false); - auto win = app->findChild()->QuickWindow(); + auto win = app->findChild()->QuickWindow(); // Customize window std::string windowTitle{"Gazebo"}; diff --git a/plugins/sim_server/SimServer.cc b/plugins/sim_server/SimServer.cc index f56bee37..5d2458cc 100644 --- a/plugins/sim_server/SimServer.cc +++ b/plugins/sim_server/SimServer.cc @@ -52,7 +52,7 @@ void copyElement(sdf::ElementPtr _sdf, const tinyxml2::XMLElement *_xml) ///////////////////////////////////////////////// SimServer::SimServer() - : gz::launch::Plugin() + : launch::Plugin() { } @@ -116,7 +116,7 @@ bool SimServer::Load(const tinyxml2::XMLElement *_elem) // Update compressed file path to name of recording directory path std::string cmpPath = std::string(recordPathMod); - if (!std::string(1, cmpPath.back()).compare(gz::common::separator(""))) + if (!std::string(1, cmpPath.back()).compare(common::separator(""))) // Remove the separator at end of path cmpPath = cmpPath.substr(0, cmpPath.length() - 1); cmpPath += ".zip"; @@ -132,30 +132,30 @@ bool SimServer::Load(const tinyxml2::XMLElement *_elem) { // Update compressed file path to name of recording directory path cmpPath = std::string(recordPathMod); - if (!std::string(1, cmpPath.back()).compare(gz::common::separator( + if (!std::string(1, cmpPath.back()).compare(common::separator( ""))) // Remove the separator at end of path cmpPath = cmpPath.substr(0, cmpPath.length() - 1); cmpPath += ".zip"; // Check if path or compressed file with same prefix exists - if (gz::common::exists(recordPathMod) || - gz::common::exists(cmpPath)) + if (common::exists(recordPathMod) || + common::exists(cmpPath)) { // Overwrite if flag specified if (overwrite) { bool recordMsg = false, cmpMsg = false; // Remove files before initializing console log files on top of them - if (gz::common::exists(recordPathMod)) + if (common::exists(recordPathMod)) { recordMsg = true; - gz::common::removeAll(recordPathMod); + common::removeAll(recordPathMod); } - if (gz::common::exists(cmpPath)) + if (common::exists(cmpPath)) { cmpMsg = true; - gz::common::removeFile(cmpPath); + common::removeFile(cmpPath); } // Create log file before printing any messages so they can be logged @@ -180,21 +180,21 @@ bool SimServer::Load(const tinyxml2::XMLElement *_elem) { // Remove the separator at end of path if (!std::string(1, recordPathMod.back()).compare( - gz::common::separator(""))) + common::separator(""))) recordPathMod = recordPathMod.substr(0, recordPathMod.length() - 1); - recordPathMod = gz::common::uniqueDirectoryPath(recordPathMod); + recordPathMod = common::uniqueDirectoryPath(recordPathMod); cmpPath = std::string(recordPathMod); // Remove the separator at end of path if (!std::string(1, cmpPath.back()).compare( - gz::common::separator(""))) + common::separator(""))) cmpPath = cmpPath.substr(0, cmpPath.length() - 1); cmpPath += ".zip"; // If compressed file exists, rename again - if (gz::common::exists(cmpPath)) + if (common::exists(cmpPath)) { - cmpPath = gz::common::uniqueFilePath(recordPathMod, "zip"); + cmpPath = common::uniqueFilePath(recordPathMod, "zip"); size_t extIdx = cmpPath.find_last_of("."); recordPathMod = cmpPath.substr(0, extIdx); diff --git a/plugins/websocket_server/MessageDefinitions.hh.in b/plugins/websocket_server/MessageDefinitions.hh.in index 28f71120..18309a4e 100644 --- a/plugins/websocket_server/MessageDefinitions.hh.in +++ b/plugins/websocket_server/MessageDefinitions.hh.in @@ -17,6 +17,8 @@ #ifndef GZ_LAUNCH_WEBSOCKETSERVER_MESSAGEDEFINITIONS_HH_ #define GZ_LAUNCH_WEBSOCKETSERVER_MESSAGEDEFINITIONS_HH_ +#include + namespace gz { namespace launch diff --git a/plugins/websocket_server/WebsocketServer.cc b/plugins/websocket_server/WebsocketServer.cc index a5ed5120..b146e28c 100644 --- a/plugins/websocket_server/WebsocketServer.cc +++ b/plugins/websocket_server/WebsocketServer.cc @@ -1010,6 +1010,61 @@ void WebsocketServer::OnMessage(int _socketId, const std::string _msg) { this->OnAsset(_socketId, frameParts); } + else if (frameParts[0] == this->operations[REQUEST]) + { + this->OnRequest(_socketId, frameParts); + } +} + +////////////////////////////////////////////////// +void WebsocketServer::OnRequest(int _socketId, + const std::vector &_frameParts) +{ + std::string service = _frameParts[1]; + std::string msgTypeName = _frameParts[2]; + std::string msgData = _frameParts[3]; + + gzdbg << "Calling service [" << service << "]\n"; + bool result; + unsigned int timeout = 2000; + + std::vector publishers; + this->node.ServiceInfo(service, publishers); + + if (publishers.empty()) + { + std::cerr << "Node::RequestRaw(): Error getting response type for " + << "service [" << service << "]\n"; + + gz::msgs::StringMsg msg; + msg.set_data("service_not_found"); + std::string data = BUILD_MSG(this->operations[REQUEST], service, + msg.GetTypeName(), msg.SerializeAsString()); + + // Queue the message for delivery. + this->QueueMessage(this->connections[_socketId].get(), + data.c_str(), data.length()); + + return; + } + + std::string repTypeName = publishers.front().RepTypeName(); + + std::string repStr; + bool executed = this->node.RequestRaw(service, msgData, msgTypeName, + repTypeName, timeout, repStr, result); + if (!executed) + { + gzerr << "Unable to call service [" << service << "]\n"; + } + + // Construct the response message + std::string data = BUILD_MSG(this->operations[REQUEST], service, + repTypeName, repStr); + + // Queue the message for delivery. + this->QueueMessage(this->connections[_socketId].get(), + data.c_str(), data.length()); } ////////////////////////////////////////////////// @@ -1019,6 +1074,16 @@ void WebsocketServer::OnAsset(int _socketId, if (_frameParts.size() <= 1) { gzerr << "Asset requested, but asset URI is missing\n"; + + gz::msgs::StringMsg msg; + msg.set_data("asset_uri_missing"); + std::string data = BUILD_MSG(this->operations[ASSET], "", + msg.GetTypeName(), msg.SerializeAsString()); + + // Queue the message for delivery. + this->QueueMessage(this->connections[_socketId].get(), + data.c_str(), data.length()); + return; } @@ -1059,7 +1124,18 @@ void WebsocketServer::OnAsset(int _socketId, // Construct the response message std::string data = BUILD_MSG(this->operations[ASSET], assetUri, - std::string("gz.msgs.Bytes"), bytes.SerializeAsString()); + bytes.GetTypeName(), bytes.SerializeAsString()); + + // Queue the message for delivery. + this->QueueMessage(this->connections[_socketId].get(), + data.c_str(), data.length()); + } + else + { + gz::msgs::StringMsg msg; + msg.set_data("asset_not_found"); + std::string data = BUILD_MSG(this->operations[ASSET], assetUri, + msg.GetTypeName(), msg.SerializeAsString()); // Queue the message for delivery. this->QueueMessage(this->connections[_socketId].get(), diff --git a/plugins/websocket_server/WebsocketServer.hh b/plugins/websocket_server/WebsocketServer.hh index f8d82f66..fed91690 100644 --- a/plugins/websocket_server/WebsocketServer.hh +++ b/plugins/websocket_server/WebsocketServer.hh @@ -103,17 +103,27 @@ namespace gz /// 8. "asset": Get a file as a byte array from a running Gazebo /// server. Set the payload to the file URI that is /// being requested. + /// 9. "worlds": Get world info. + /// 10. "scene": Get scene info. + /// 11. "image": Subscribe to an image in the `topic_name` component. + /// 12. "throttle": Throttle a topic in the `topic_name` component by + /// the rate in the `payload` component. + /// 13. "req": Request a service, passing in the optional request + /// message. The payload should be a serialized + /// protobuf message. The response payload holds the + /// serialized protobuf response, if any. /// - /// The `topic_name` component is mandatory for the "sub", "pub", and - /// "unsub" operations. If present, it must be the name of a Gazebo + /// The `topic_name` component is mandatory for the "sub", "pub", "unsub", + /// and "req" operations. If present, it must be the name of a Gazebo /// Transport topic. /// - /// The `message_type` component is mandatory for the "pub" operation. If - /// present it names the Gazebo Message type, such as + /// The `message_type` component is mandatory for the "pub" and "req" + /// operations. If present it names the Gazebo Message type, such as /// "gz.msgs.Clock". /// - /// The `payload` component is mandatory for the "pub" operation. If - /// present, it contains a serialized string of a Gazebo Message. + /// The `payload` component is mandatory for the "pub" and "req" + /// operations. If present, it contains a serialized string of a + /// Gazebo Message. /// /// ## Example frames /// @@ -186,8 +196,6 @@ namespace gz /// \param[in] _msg The incoming message. public: void OnMessage(int _socketId, const std::string _msg); - public: void OnRequestMessage(int _socketId, const std::string &_msg); - /// \brief Check and update subscription count for a message type. If /// a client has more subscriptions to a topic of a specified type than /// the subscription limit, this will block subscription. On the other @@ -207,6 +215,12 @@ namespace gz private: void OnAsset(int _socketId, const std::vector &_frameParts); + /// \brief Handles service requests. + /// \param[in] _socketId Id of the socket associated with the message. + /// \param[in] _frameParts The request message in frame parts. + private: void OnRequest(int _socketId, + const std::vector &_frameParts); + private: gz::transport::Node node; private: bool run = true; @@ -304,13 +318,16 @@ namespace gz /// \brief Get an asset as a byte array. ASSET = 4, + + /// \brief Request a service + REQUEST = 5, }; - /// \brief The set of valid operations, in string form. These values + /// \brief The set of valid operations, in string form. These values /// can be sent in websocket message frames. - /// These valus must align with the `Operation` enum. + /// These values must align with the `Operation` enum. private: std::vector operations{ - "sub", "pub", "topics", "protos", "asset"}; + "sub", "pub", "topics", "protos", "asset", "req"}; /// \brief Store publish headers for topics. This is here to improve /// performance. Keys are topic names and values are frame headers.