From 91bce2a4616877ba6d7443cfb112917f6be0e177 Mon Sep 17 00:00:00 2001 From: Arjo Chakravarty Date: Thu, 12 May 2022 15:44:13 +0800 Subject: [PATCH 1/5] Adds time interpolation. This PR moves all the logic for lookup in the science sensor to a separate function `ScienceSensorsSystemPrivate::InterpolateInTime()`. It also adds time based interpolation to the science sensor. Signed-off-by: Arjo Chakravarty --- .../src/ScienceSensorsSystem.cc | 161 +++++++++--------- 1 file changed, 84 insertions(+), 77 deletions(-) diff --git a/lrauv_ignition_plugins/src/ScienceSensorsSystem.cc b/lrauv_ignition_plugins/src/ScienceSensorsSystem.cc index 5ce46d45..7008d3a6 100644 --- a/lrauv_ignition_plugins/src/ScienceSensorsSystem.cc +++ b/lrauv_ignition_plugins/src/ScienceSensorsSystem.cc @@ -85,6 +85,11 @@ class tethys::ScienceSensorsSystemPrivate /// \brief Returns a point cloud message populated with the latest sensor data public: ignition::msgs::PointCloudPacked PointCloudMsg(); + public: float InterpolateInTime( + const ignition::math::Vector3d &_point, + const double simTimeSeconds, + const std::vector> &_dataArray); + /////////////////////////////// // Constants for data manipulation @@ -160,7 +165,7 @@ class tethys::ScienceSensorsSystemPrivate public: bool multipleTimeSlices {false}; /// \brief Index of the latest time slice - public: int timeIdx {0}; + public: std::size_t timeIdx {0}; /// \brief Timestamps to index slices of data public: std::vector timestamps; @@ -302,6 +307,63 @@ ScienceSensorsSystem::ScienceSensorsSystem() { } +///////////////////////////////////////////////// +float ScienceSensorsSystemPrivate::InterpolateInTime( + const ignition::math::Vector3d &_point, + const double _simTimeSeconds, + const std::vector> &_dataArray) +{ + const auto& timeslice1 = this->timeSpaceIndex[this->timeIdx]; + auto interpolatorsTime1 = timeslice1.GetInterpolators(_point); + + auto nextTimeIdx = std::min(this->timeIdx + 1, + this->timestamps.size() - 1); + const auto& timeslice2 = this->timeSpaceIndex[nextTimeIdx]; + auto interpolatorsTime2 = timeslice2.GetInterpolators(_point); + + if (interpolatorsTime1.size() == 0) return std::nanf(""); + if (!interpolatorsTime1[0].index.has_value()) return std::nanf(""); + + if (interpolatorsTime2.size() == 0) return std::nanf(""); + if (!interpolatorsTime2[0].index.has_value()) return std::nanf(""); + + const auto data1 = timeslice1.EstimateValueUsingTrilinear( + interpolatorsTime1, + _point, + _dataArray[this->timeIdx] + ); + const auto data2 = timeslice2.EstimateValueUsingTrilinear( + interpolatorsTime2, + _point, + _dataArray[nextTimeIdx] + ); + + + auto prevTimeStamp = this->timestamps[this->timeIdx]; + auto nextTimeStamp = this->timestamps[nextTimeIdx]; + + auto dist = nextTimeStamp - prevTimeStamp; + if (dist == 0) + { + if (data1.has_value()) + return data1.value(); + else + return std::nanf(""); + } + else + { + if (data1.has_value() && data2.has_value()) + { + return (data1.value() * (nextTimeStamp - _simTimeSeconds) + + data2.value() * (_simTimeSeconds - prevTimeStamp)) / dist; + } + else + { + return std::nanf(""); + } + } +} + ///////////////////////////////////////////////// void ScienceSensorsSystemPrivate::ReadData( const ignition::gazebo::EntityComponentManager &_ecm) @@ -680,97 +742,42 @@ void ScienceSensorsSystem::PostUpdate(const ignition::gazebo::UpdateInfo &_info, auto sphericalDepthCorrected = ignition::math::Vector3d{spherical.X(), spherical.Y(), -spherical.Z()}; - const auto& timeslice = this->dataPtr->timeSpaceIndex[this->dataPtr->timeIdx]; - auto interpolators = timeslice.GetInterpolators(sphericalDepthCorrected); - - IGN_PROFILE("ScienceSensorsSystem::Interpolation"); - if (interpolators.size() == 0) return; - if (!interpolators[0].index.has_value()) return; - if (auto casted = std::dynamic_pointer_cast(sensor)) { - const auto sal = timeslice.EstimateValueUsingTrilinear( - interpolators, - sphericalDepthCorrected, - this->dataPtr->salinityArr[this->dataPtr->timeIdx] - ); - - if (sal.has_value()) - casted->SetData(sal.value()); - else - casted->SetData(std::nanf("")); + casted->SetData( + this->dataPtr->InterpolateInTime( + sphericalDepthCorrected, simTimeSeconds, this->dataPtr->salinityArr)); } else if (auto casted = std::dynamic_pointer_cast( sensor)) { - const auto temp = timeslice.EstimateValueUsingTrilinear( - interpolators, - sphericalDepthCorrected, - this->dataPtr->temperatureArr[this->dataPtr->timeIdx] - ); + const auto temp = this->dataPtr->InterpolateInTime( + sphericalDepthCorrected, simTimeSeconds, this->dataPtr->temperatureArr); - if (temp.has_value()) - { - ignition::math::Temperature tempC; - tempC.SetCelsius(temp.value()); - casted->SetData(tempC); - } - else - { - ignition::math::Temperature tempC; - tempC.SetCelsius(std::nanf("")); - casted->SetData(tempC); - } + ignition::math::Temperature tempC; + tempC.SetCelsius(temp); + casted->SetData(tempC); } else if (auto casted = std::dynamic_pointer_cast( sensor)) { - /// Uncomment to debug - /// igndbg << "------------------" << std::endl; - /// igndbg << "Sensor position: " << sphericalDepthCorrected << std::endl; - /// igndbg << "Got" << interpolators.size() << " interpolators" << std::endl; - /// for (auto interp: interpolators) - /// { - /// if (!interp.index.has_value()) continue; - /// igndbg << "Chlorophyll sensor: " << - /// this->dataPtr->chlorophyllArr[this->dataPtr->timeIdx][ - /// interp.index.value()] << "@" << interp.position << std::endl; - /// igndbg << "My distance is " << interp.position.X() - sphericalDepthCorrected.X() - /// << ", " << interp.position.Y() - sphericalDepthCorrected.Y() << std::endl; - /// } - const auto chlor = timeslice.EstimateValueUsingTrilinear( - interpolators, - sphericalDepthCorrected, - this->dataPtr->chlorophyllArr[this->dataPtr->timeIdx] - ); - if (chlor.has_value()) - casted->SetData(chlor.value()); - else - casted->SetData(std::nanf("")); + casted->SetData( + this->dataPtr->InterpolateInTime( + sphericalDepthCorrected, simTimeSeconds, + this->dataPtr->chlorophyllArr)); } else if (auto casted = std::dynamic_pointer_cast( sensor)) { - const auto nCurr = timeslice.EstimateValueUsingTrilinear( - interpolators, - sphericalDepthCorrected, - this->dataPtr->northCurrentArr[this->dataPtr->timeIdx] - ); - const auto eCurr = timeslice.EstimateValueUsingTrilinear( - interpolators, - sphericalDepthCorrected, - this->dataPtr->eastCurrentArr[this->dataPtr->timeIdx] - ); - if (nCurr.has_value() && eCurr.has_value()) - { - ignition::math::Vector3d current(nCurr.value(), eCurr.value(), 0); - casted->SetData(current); - } - else - { - ignition::math::Vector3d current(std::nan(""), std::nan(""), 0); - casted->SetData(current); - } + const auto nCurr = this->dataPtr->InterpolateInTime( + sphericalDepthCorrected, simTimeSeconds, this->dataPtr->northCurrentArr); + + const auto eCurr = this->dataPtr->InterpolateInTime( + sphericalDepthCorrected, simTimeSeconds, this->dataPtr->eastCurrentArr); + + + ignition::math::Vector3d current(nCurr, eCurr, 0); + casted->SetData(current); } else { From cd2b23c051eea711ff1c15d1101a77f899615ef4 Mon Sep 17 00:00:00 2001 From: Arjo Chakravarty Date: Fri, 13 May 2022 13:27:18 +0800 Subject: [PATCH 2/5] Add unit test and fix them :bug:s Signed-off-by: Arjo Chakravarty --- .../src/ScienceSensorsSystem.cc | 44 +++-- .../data/minimal_time_varying.csv | 17 ++ .../test/vehicle/CMakeLists.txt | 1 + .../test/vehicle/test_sensor.cc | 2 +- .../vehicle/test_sensor_timeinterpolation.cc | 171 ++++++++++++++++++ 5 files changed, 220 insertions(+), 15 deletions(-) create mode 100644 lrauv_system_tests/data/minimal_time_varying.csv create mode 100644 lrauv_system_tests/test/vehicle/test_sensor_timeinterpolation.cc diff --git a/lrauv_ignition_plugins/src/ScienceSensorsSystem.cc b/lrauv_ignition_plugins/src/ScienceSensorsSystem.cc index 7008d3a6..562914b5 100644 --- a/lrauv_ignition_plugins/src/ScienceSensorsSystem.cc +++ b/lrauv_ignition_plugins/src/ScienceSensorsSystem.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -52,6 +53,17 @@ class tethys::ScienceSensorsSystemPrivate ////////////////////////////////// // Functions for data manipulation + /// \brief Called when plugin is asked to reload file. + /// \param[in] _filepath Path to file to reload. + public: void OnReloadData(const ignition::msgs::StringMsg &_filepath) + { + igndbg << "Reloading file " << _filepath.data() << "\n"; + + // Trigger reload and reread data + this->sphericalCoordinatesInitialized = false; + this->dataPath = _filepath.data(); + } + /// \brief Reads csv file and populate various data fields /// \param[in] _ecm Immutable reference to the ECM public: void ReadData(const ignition::gazebo::EntityComponentManager &_ecm); @@ -161,9 +173,6 @@ class tethys::ScienceSensorsSystemPrivate ////////////////////////////////// // Variables for data manipulation - /// \brief Whether using more than one time slices of data - public: bool multipleTimeSlices {false}; - /// \brief Index of the latest time slice public: std::size_t timeIdx {0}; @@ -179,7 +188,7 @@ class tethys::ScienceSensorsSystemPrivate /// the visuallization. public: std::vector::Ptr> timeSpaceCoords; - public: std::vector> + public: std::vector> timeSpaceCoordsLatLon; /// \brief Spatial index of data. @@ -381,6 +390,16 @@ void ScienceSensorsSystemPrivate::ReadData( // reading and transforming data std::lock_guard lock(mtx); + // Reset all data + timeSpaceCoords.clear(); + timeSpaceCoordsLatLon.clear(); + timeSpaceIndex.clear(); + temperatureArr.clear(); + salinityArr.clear(); + chlorophyllArr.clear(); + eastCurrentArr.clear(); + northCurrentArr.clear(); + std::fstream fs; fs.open(this->dataPath, std::ios::in); @@ -614,6 +633,10 @@ void ScienceSensorsSystem::Configure( ignmsg << "Loading science data from [" << this->dataPtr->dataPath << "]" << std::endl; } + + this->dataPtr->node.Subscribe("/world/science_sensor/environment_data_path", + &ScienceSensorsSystemPrivate::OnReloadData, + this->dataPtr.get()); } ///////////////////////////////////////////////// @@ -697,21 +720,14 @@ void ScienceSensorsSystem::PostUpdate(const ignition::gazebo::UpdateInfo &_info, } } - double simTimeSeconds = std::chrono::duration_cast( + double simTimeSeconds = std::chrono::duration( _info.simTime).count(); - // Update time index - if (this->dataPtr->multipleTimeSlices) + if(this->dataPtr->timeIdx + 1 < this->dataPtr->timestamps.size()) { - // Only update if sim time exceeds the elapsed timestamp in data - if (!this->dataPtr->timestamps.empty() && - simTimeSeconds >= this->dataPtr->timestamps[this->dataPtr->timeIdx]) + if(simTimeSeconds >= this->dataPtr->timestamps[this->dataPtr->timeIdx + 1]) { - // Increment for next point in time this->dataPtr->timeIdx++; - - // Publish science data at the next timestamp - this->dataPtr->PublishData(); } } diff --git a/lrauv_system_tests/data/minimal_time_varying.csv b/lrauv_system_tests/data/minimal_time_varying.csv new file mode 100644 index 00000000..a3c07e8d --- /dev/null +++ b/lrauv_system_tests/data/minimal_time_varying.csv @@ -0,0 +1,17 @@ +elapsed_time_second,latitude_degree,longitude_degree,depth_meter,sea_water_temperature_degC,sea_water_salinity_psu,mass_concentration_of_chlorophyll_in_sea_water_ugram_per_liter,eastward_sea_water_velocity_meter_per_sec,northward_sea_water_velocity_meter_per_sec +0,0.00001,0.00000,0,5.0,0.001,0,-1,0.5 +0,0.00001,0.00000,10,5.0,0.001,0,-1,0.5 +0,0.00001,0.00001,0,5.0,0.001,0,-1,0.5 +0,0.00001,0.00001,10,5.0,0.001,0,-1,0.5 +0,0.00000,0.00000,0,5.0,0.001,0,-1,0.5 +0,0.00000,0.00000,10,5.0,0.001,0,-1,0.5 +0,0.00000,0.00001,0,5.0,0.001,0,-1,0.5 +0,0.00000,0.00001,10,5.0,0.001,0,-1,0.5 +10,0.00001,0.00000,0,10.0,0.001,0,-1,0.5 +10,0.00001,0.00000,10,10.0,0.001,0,-1,0.5 +10,0.00001,0.00001,0,10.0,0.001,0,-1,0.5 +10,0.00001,0.00001,10,10.0,0.001,0,-1,0.5 +10,0.00000,0.00000,00,10.0,0.001,0,-1,0.5 +10,0.00000,0.00000,10,10.0,0.001,0,-1,0.5 +10,0.00000,0.00001,0,10.0,0.001,0,-1,0.5 +10,0.00000,0.00001,10,10.0,0.001,0,-1,0.5 \ No newline at end of file diff --git a/lrauv_system_tests/test/vehicle/CMakeLists.txt b/lrauv_system_tests/test/vehicle/CMakeLists.txt index fbea9318..3880bb0f 100644 --- a/lrauv_system_tests/test/vehicle/CMakeLists.txt +++ b/lrauv_system_tests/test/vehicle/CMakeLists.txt @@ -24,6 +24,7 @@ foreach(_test test_mass_shifter test_propeller_action test_rudder_action + test_sensor_timeinterpolation test_sensor) add_executable(${_test} ${_test}.cc) target_link_libraries(${_test} diff --git a/lrauv_system_tests/test/vehicle/test_sensor.cc b/lrauv_system_tests/test/vehicle/test_sensor.cc index 1caf1490..825b9ee8 100644 --- a/lrauv_system_tests/test/vehicle/test_sensor.cc +++ b/lrauv_system_tests/test/vehicle/test_sensor.cc @@ -99,7 +99,7 @@ void SpawnVehicle( } ////////////////////////////////////////////////// -TEST(SensorTest, Sensor) +TEST(SensorTest, PositionInterpolation) { ignition::common::Console::SetVerbosity(4); diff --git a/lrauv_system_tests/test/vehicle/test_sensor_timeinterpolation.cc b/lrauv_system_tests/test/vehicle/test_sensor_timeinterpolation.cc new file mode 100644 index 00000000..4cba0fe6 --- /dev/null +++ b/lrauv_system_tests/test/vehicle/test_sensor_timeinterpolation.cc @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * 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 + * + * 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. + * + */ + +/* + * Development of this module has been funded by the Monterey Bay Aquarium + * Research Institute (MBARI) and the David and Lucile Packard Foundation + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "TestConstants.hh" + +using namespace std::chrono_literals; + +std::atomic duration; + +/////////////////////////////////////////////// +void TemperatureVeh1Cb(const ignition::msgs::Double &_msg) +{ + auto timeNow = std::chrono::duration(duration.load()).count(); + auto temperature = _msg.data(); + + if (timeNow < 10) + { + // At time 0 according to the csv file the temperature is 5. + // Using linear interpolation the temparature at timeNow will be + // (10 * timeNow + (10-timeNow) * 5) / 10 + EXPECT_NEAR(temperature, (10 * timeNow + (10-timeNow) * 5) / 10, 0.1); + } + else + { + // At time 10 according to the csv file temperature is 10. + // Since theres no more data we will just keep the temperature as is. + EXPECT_NEAR(temperature, 10.0, 0.1); + } +} + +/////////////////////////////////////////////// +void SpawnVehicle( + ignition::transport::Node::Publisher &_spawnPub, + const std::string &_modelName, + const double _lat, const double _lon, const double _depth, + const int _acommsAddr) +{ + ignition::math::Angle lat1 = IGN_DTOR(_lat); + ignition::math::Angle lon1 = IGN_DTOR(_lon); + + lrauv_ignition_plugins::msgs::LRAUVInit spawnMsg; + spawnMsg.mutable_id_()->set_data(_modelName); + spawnMsg.set_initlat_(lat1.Degree()); + spawnMsg.set_initlon_(lon1.Degree()); + spawnMsg.set_initz_(_depth); + spawnMsg.set_acommsaddress_(_acommsAddr); + + _spawnPub.Publish(spawnMsg); +} + +////////////////////////////////////////////////// +TEST(SensorTest, TimeInterpolation) +{ + ignition::common::Console::SetVerbosity(4); + + // Setup fixture + auto fixture = std::make_unique( + ignition::common::joinPaths( + std::string(PROJECT_SOURCE_PATH), "worlds", "empty_environment.sdf")); + unsigned int iterations{0u}; + + bool spawnedAllVehicles = {false}; + static const std::string vehicles[] = + {"vehicle1"}; + + fixture->OnPostUpdate( + [&](const ignition::gazebo::UpdateInfo &_info, + const ignition::gazebo::EntityComponentManager &_ecm) + { + auto worldEntity = ignition::gazebo::worldEntity(_ecm); + ignition::gazebo::World world(worldEntity); + int numVehiclesSpawned{0}; + for (auto v1 : vehicles) + { + if (world.ModelByName(_ecm, v1) != ignition::gazebo::kNullEntity) + { + numVehiclesSpawned++; + } + } + + if (numVehiclesSpawned == 1) + { + spawnedAllVehicles = true; + } + iterations++; + duration = _info.simTime; + }); + fixture->Finalize(); + + // Check that vehicles don't exist + fixture->Server()->RunOnce(); + EXPECT_EQ(1, iterations); + + int sleep{0}; + int maxSleep{30}; + + // Change the dataconfig + igndbg << "Switching file" <( + "/world/science_sensor/environment_data_path"); + ignition::msgs::StringMsg configMsg; + configMsg.set_data(ignition::common::joinPaths( + std::string(PROJECT_SOURCE_PATH), "data", "minimal_time_varying.csv")); + for (; !configPub.HasConnections() && sleep < maxSleep; ++sleep) + { + std::this_thread::sleep_for(100ms); + } + configPub.Publish(configMsg); + + // Spawn first vehicle + auto spawnPub = node.Advertise( + "/lrauv/init"); + for (; !spawnPub.HasConnections() && sleep < maxSleep; ++sleep) + { + std::this_thread::sleep_for(100ms); + } + ASSERT_LE(sleep, maxSleep); + + + // On a depth coplanar to a piece of data + SpawnVehicle( + spawnPub, "vehicle1", 0.000005, 0.000005, 5, 0); + node.Subscribe("/model/vehicle1/temperature", &TemperatureVeh1Cb); + + // Check that vehicle was spawned + int expectedIterations = iterations; + for (sleep = 0; !spawnedAllVehicles && sleep < maxSleep; + ++sleep) + { + std::this_thread::sleep_for(100ms); + // Run paused so we avoid the physics moving the vehicles + fixture->Server()->RunOnce(true); + expectedIterations++; + igndbg << "Waiting for vehicles to spawn" << std::endl; + } + EXPECT_TRUE(spawnedAllVehicles); + + fixture->Server()->Run(true, 1000, false); +} From 46093b509cae881518be484b2107f819228f8be2 Mon Sep 17 00:00:00 2001 From: Arjo Chakravarty Date: Fri, 13 May 2022 14:19:42 +0800 Subject: [PATCH 3/5] Add support for loading CSV files vis the UI This PR adds support for loading environment files using the gui instead of having to edit the XML file. Signed-off-by: Arjo Chakravarty --- lrauv_ignition_plugins/CMakeLists.txt | 1 + .../src/WorldConfigPlugin.cc | 70 +++++++++++++++++++ .../src/WorldConfigPlugin.hh | 60 ++++++++++++++++ .../src/WorldConfigPlugin.qml | 65 +++++++++++++++++ .../src/WorldConfigPlugin.qrc | 5 ++ .../worlds/buoyant_tethys.sdf | 8 +++ .../worlds/empty_environment.sdf | 8 +++ .../worlds/portuguese_ledge.sdf.em | 7 ++ 8 files changed, 224 insertions(+) create mode 100644 lrauv_ignition_plugins/src/WorldConfigPlugin.cc create mode 100644 lrauv_ignition_plugins/src/WorldConfigPlugin.hh create mode 100644 lrauv_ignition_plugins/src/WorldConfigPlugin.qml create mode 100644 lrauv_ignition_plugins/src/WorldConfigPlugin.qrc diff --git a/lrauv_ignition_plugins/CMakeLists.txt b/lrauv_ignition_plugins/CMakeLists.txt index eaa53188..aa06d554 100644 --- a/lrauv_ignition_plugins/CMakeLists.txt +++ b/lrauv_ignition_plugins/CMakeLists.txt @@ -181,6 +181,7 @@ add_lrauv_plugin(TimeAnalysisPlugin) add_lrauv_plugin(WorldCommPlugin PROTO lrauv_init) +add_lrauv_plugin(WorldConfigPlugin GUI) #============================================================================ # Install public headers diff --git a/lrauv_ignition_plugins/src/WorldConfigPlugin.cc b/lrauv_ignition_plugins/src/WorldConfigPlugin.cc new file mode 100644 index 00000000..ae777758 --- /dev/null +++ b/lrauv_ignition_plugins/src/WorldConfigPlugin.cc @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2022 Open Source Robotics Foundation + * + * 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 + * + * 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. + * + */ + +/* + * Development of this module has been funded by the Monterey Bay Aquarium + * Research Institute (MBARI) and the David and Lucile Packard Foundation + */ + +#include "WorldConfigPlugin.hh" +#include +#include + +#include +#include +#include +#include + +namespace tethys +{ + +WorldConfig::WorldConfig() : ignition::gui::Plugin() +{ + ignition::gui::App()->Engine()->rootContext()->setContextProperty( + "WorldConfig", this); + this->pub = + this->node.Advertise( + "/world/science_sensor/environment_data_path"); +} + +WorldConfig::~WorldConfig() +{ + +} + +void WorldConfig::LoadConfig(const tinyxml2::XMLElement *_pluginElem) +{ + if (this->title.empty()) + this->title = "World Configuration"; + + ignition::gui::App()->findChild< + ignition::gui::MainWindow *>()->installEventFilter(this); +} + +void WorldConfig::SetFilePath(QUrl _filePath) +{ + igndbg << "setting file path "<< _filePath.path().toStdString() <<"\n"; + + ignition::msgs::StringMsg msg; + msg.set_data(_filePath.path().toStdString()); + this->pub.Publish(msg); +} + +} +// Register this plugin +IGNITION_ADD_PLUGIN(tethys::WorldConfig, + ignition::gui::Plugin) \ No newline at end of file diff --git a/lrauv_ignition_plugins/src/WorldConfigPlugin.hh b/lrauv_ignition_plugins/src/WorldConfigPlugin.hh new file mode 100644 index 00000000..d3acf868 --- /dev/null +++ b/lrauv_ignition_plugins/src/WorldConfigPlugin.hh @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * 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 + * + * 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. + * + */ + +/* + * Development of this module has been funded by the Monterey Bay Aquarium + * Research Institute (MBARI) and the David and Lucile Packard Foundation + */ + +#ifndef TETHYS_CONTROLPANEL_HH_ +#define TETHYS_CONTROLPANEL_HH_ + +#include + +#include + +namespace tethys +{ + +/// \brief Control Panel for controlling the tethys using the GUI. +class WorldConfig : public ignition::gui::Plugin +{ + Q_OBJECT + + /// \brief Constructor + public: WorldConfig(); + + /// \brief Destructor + public: ~WorldConfig(); + + /// \brief Documentation inherited + public: void LoadConfig(const tinyxml2::XMLElement *_pluginElem) override; + + /// \brief Set the file path to be loaded + /// \param[in] _filePath The file path to be loaded + public: Q_INVOKABLE void SetFilePath(QUrl _filePath); + + /// \brief Transport node + private: ignition::transport::Node node; + + /// \brief Transport publisher + private: ignition::transport::Node::Publisher pub; +}; + +} + +#endif \ No newline at end of file diff --git a/lrauv_ignition_plugins/src/WorldConfigPlugin.qml b/lrauv_ignition_plugins/src/WorldConfigPlugin.qml new file mode 100644 index 00000000..525b2c8f --- /dev/null +++ b/lrauv_ignition_plugins/src/WorldConfigPlugin.qml @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * 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 + * + * 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. + * +*/ + + +/* + * Development of this module has been funded by the Monterey Bay Aquarium + * Research Institute (MBARI) and the David and Lucile Packard Foundation + */ + +import QtQuick 2.9 +import QtQuick.Controls 2.1 +import QtQuick.Controls.Material 2.1 +import QtQuick.Layouts 1.3 +import QtQuick.Dialogs 1.0 + +GridLayout { + id: mainLayout + columns: 5 + rowSpacing: 2 + columnSpacing: 2 + anchors.fill: parent + anchors.leftMargin: 10 + anchors.rightMargin: 10 + Layout.minimumWidth: 400 + Layout.minimumHeight: 300 + + Label { + text: "Load Environment Data CSV" + Layout.columnSpan: 3 + } + Button { + id: vehicleNameValue + Layout.columnSpan: 2 + Layout.fillWidth: true + text: "Browse files..." + onClicked: fileDialog.open() + } + + FileDialog { + id: fileDialog + title: "Please choose a file" + folder: shortcuts.home + visible: false + onAccepted: { + WorldConfig.SetFilePath(fileDialog.fileUrl) + } + onRejected: { + } + //Component.onCompleted: visible = true + } +} \ No newline at end of file diff --git a/lrauv_ignition_plugins/src/WorldConfigPlugin.qrc b/lrauv_ignition_plugins/src/WorldConfigPlugin.qrc new file mode 100644 index 00000000..3fe66779 --- /dev/null +++ b/lrauv_ignition_plugins/src/WorldConfigPlugin.qrc @@ -0,0 +1,5 @@ + + + WorldConfigPlugin.qml + + \ No newline at end of file diff --git a/lrauv_ignition_plugins/worlds/buoyant_tethys.sdf b/lrauv_ignition_plugins/worlds/buoyant_tethys.sdf index 0d36a2d3..d0596009 100644 --- a/lrauv_ignition_plugins/worlds/buoyant_tethys.sdf +++ b/lrauv_ignition_plugins/worlds/buoyant_tethys.sdf @@ -334,6 +334,14 @@ /tethys/navsat true + + + + + Environmental Configuration + docked_collapsed + + diff --git a/lrauv_ignition_plugins/worlds/empty_environment.sdf b/lrauv_ignition_plugins/worlds/empty_environment.sdf index d00d48d1..ffc0b252 100644 --- a/lrauv_ignition_plugins/worlds/empty_environment.sdf +++ b/lrauv_ignition_plugins/worlds/empty_environment.sdf @@ -318,6 +318,14 @@ /tethys/navsat true + + + + + Environmental Configuration + docked_collapsed + + diff --git a/lrauv_ignition_plugins/worlds/portuguese_ledge.sdf.em b/lrauv_ignition_plugins/worlds/portuguese_ledge.sdf.em index b910f938..d10e605d 100644 --- a/lrauv_ignition_plugins/worlds/portuguese_ledge.sdf.em +++ b/lrauv_ignition_plugins/worlds/portuguese_ledge.sdf.em @@ -359,6 +359,13 @@ for tile in tiles: docked_collapsed + + + + Environmental Configuration + docked_collapsed + + Reference axis From 26126b0240891252c9d97b7554f836cf307e47a9 Mon Sep 17 00:00:00 2001 From: Arjo Chakravarty Date: Wed, 15 Jun 2022 13:47:26 +0800 Subject: [PATCH 4/5] ign ->gz and PR feedback Signed-off-by: Arjo Chakravarty --- .../src/WorldConfigPlugin.cc | 28 +++++++++---------- .../src/WorldConfigPlugin.hh | 10 +++---- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lrauv_ignition_plugins/src/WorldConfigPlugin.cc b/lrauv_ignition_plugins/src/WorldConfigPlugin.cc index ae777758..831bb346 100644 --- a/lrauv_ignition_plugins/src/WorldConfigPlugin.cc +++ b/lrauv_ignition_plugins/src/WorldConfigPlugin.cc @@ -21,23 +21,23 @@ */ #include "WorldConfigPlugin.hh" -#include -#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include namespace tethys { -WorldConfig::WorldConfig() : ignition::gui::Plugin() +WorldConfig::WorldConfig() : gz::gui::Plugin() { - ignition::gui::App()->Engine()->rootContext()->setContextProperty( + gz::gui::App()->Engine()->rootContext()->setContextProperty( "WorldConfig", this); this->pub = - this->node.Advertise( + this->node.Advertise( "/world/science_sensor/environment_data_path"); } @@ -51,15 +51,15 @@ void WorldConfig::LoadConfig(const tinyxml2::XMLElement *_pluginElem) if (this->title.empty()) this->title = "World Configuration"; - ignition::gui::App()->findChild< - ignition::gui::MainWindow *>()->installEventFilter(this); + gz::gui::App()->findChild< + gz::gui::MainWindow *>()->installEventFilter(this); } void WorldConfig::SetFilePath(QUrl _filePath) { - igndbg << "setting file path "<< _filePath.path().toStdString() <<"\n"; + igndbg << "setting file path "<< _filePath.path().toStdString() << std::endl; - ignition::msgs::StringMsg msg; + gz::msgs::StringMsg msg; msg.set_data(_filePath.path().toStdString()); this->pub.Publish(msg); } @@ -67,4 +67,4 @@ void WorldConfig::SetFilePath(QUrl _filePath) } // Register this plugin IGNITION_ADD_PLUGIN(tethys::WorldConfig, - ignition::gui::Plugin) \ No newline at end of file + gz::gui::Plugin) diff --git a/lrauv_ignition_plugins/src/WorldConfigPlugin.hh b/lrauv_ignition_plugins/src/WorldConfigPlugin.hh index d3acf868..46b20945 100644 --- a/lrauv_ignition_plugins/src/WorldConfigPlugin.hh +++ b/lrauv_ignition_plugins/src/WorldConfigPlugin.hh @@ -23,15 +23,15 @@ #ifndef TETHYS_CONTROLPANEL_HH_ #define TETHYS_CONTROLPANEL_HH_ -#include +#include -#include +#include namespace tethys { /// \brief Control Panel for controlling the tethys using the GUI. -class WorldConfig : public ignition::gui::Plugin +class WorldConfig : public gz::gui::Plugin { Q_OBJECT @@ -49,10 +49,10 @@ class WorldConfig : public ignition::gui::Plugin public: Q_INVOKABLE void SetFilePath(QUrl _filePath); /// \brief Transport node - private: ignition::transport::Node node; + private: gz::transport::Node node; /// \brief Transport publisher - private: ignition::transport::Node::Publisher pub; + private: gz::transport::Node::Publisher pub; }; } From 3ee5b97ffa76a10a2c61d2cd74d886a5f67c80e2 Mon Sep 17 00:00:00 2001 From: Arjo Chakravarty Date: Wed, 15 Jun 2022 13:48:17 +0800 Subject: [PATCH 5/5] fix knit Signed-off-by: Arjo Chakravarty --- lrauv_ignition_plugins/src/WorldConfigPlugin.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lrauv_ignition_plugins/src/WorldConfigPlugin.cc b/lrauv_ignition_plugins/src/WorldConfigPlugin.cc index 831bb346..6d8ef5b7 100644 --- a/lrauv_ignition_plugins/src/WorldConfigPlugin.cc +++ b/lrauv_ignition_plugins/src/WorldConfigPlugin.cc @@ -57,7 +57,7 @@ void WorldConfig::LoadConfig(const tinyxml2::XMLElement *_pluginElem) void WorldConfig::SetFilePath(QUrl _filePath) { - igndbg << "setting file path "<< _filePath.path().toStdString() << std::endl; + igndbg << "setting file path " << _filePath.path().toStdString() << std::endl; gz::msgs::StringMsg msg; msg.set_data(_filePath.path().toStdString());