/* * Copyright (C) 2012 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. * */ #include #include "gazebo/test/ServerFixture.hh" using namespace gazebo; class WirelessTransmitter_TEST : public ServerFixture { public: WirelessTransmitter_TEST(); public: void TestCreateWirelessTransmitter(); public: void TestSignalStrength(); public: void TestUpdateImpl(); public: void TestUpdateImplNoVisual(); public: void TestInvalidFreq(); private: void TxMsg(const ConstPropagationGridPtr &_msg); private: std::mutex mutex; private: bool receivedMsg; private: boost::shared_ptr gridMsg; private: sensors::WirelessTransmitterPtr tx; private: sensors::WirelessTransmitterPtr txNoVisual; }; static std::string transmitterSensorString = "" " " " 1" " true" " 1.0" " " " GzTest" " 2442.0" " 14.5" " 2.6" " " " " ""; ///////////////////////////////////////////////// /// \brief Constructor spawns a transmitter sensor WirelessTransmitter_TEST::WirelessTransmitter_TEST() { Load("worlds/empty.world"); std::string txModelName = "tx"; std::string txSensorName = "wirelessTransmitterConstructor"; std::string txEssid = "GzTest"; double freq = 2442.0; double power = 14.5; double gain = 2.6; ignition::math::Pose3d txPose( ignition::math::Vector3d(0.0, 0.0, 0.055), ignition::math::Quaterniond(0, 0, 0)); // Spawn a wireless transmitter with sensor visualization SpawnWirelessTransmitterSensor(txModelName, txSensorName, txPose.Pos(), txPose.Rot().Euler(), txEssid, freq, power, gain); this->tx = std::static_pointer_cast( sensors::SensorManager::Instance()->GetSensor(txSensorName)); this->receivedMsg = false; } ///////////////////////////////////////////////// /// \brief Test creation of a wireless transmitter sensor void WirelessTransmitter_TEST::TestCreateWirelessTransmitter() { sensors::SensorManager *mgr = sensors::SensorManager::Instance(); sdf::ElementPtr sdf(new sdf::Element); sdf::initFile("sensor.sdf", sdf); sdf::readString(transmitterSensorString, sdf); // Create the wireless transmitter sensor std::string sensorName = mgr->CreateSensor(sdf, "default", "ground_plane::link", 0); // Make sure the returned sensor name is correct EXPECT_EQ(sensorName, std::string("default::ground_plane::link::wirelessTransmitter")); // Update the sensor manager so that it can process new sensors. mgr->Update(); // Get a pointer to the wireless receiver sensor sensors::WirelessTransmitterPtr sensor = std::dynamic_pointer_cast( mgr->GetSensor(sensorName)); // Make sure the above dynamic cast worked. ASSERT_TRUE(sensor != NULL); EXPECT_EQ("GzTest", sensor->ESSID()); EXPECT_DOUBLE_EQ(sensor->Freq(), 2442.0); EXPECT_DOUBLE_EQ(sensor->Power(), 14.5); EXPECT_DOUBLE_EQ(sensor->Gain(), 2.6); EXPECT_TRUE(sensor->IsActive()); } ///////////////////////////////////////////////// /// \brief Test an invalid frequency value void WirelessTransmitter_TEST::TestInvalidFreq() { sensors::SensorManager *mgr = sensors::SensorManager::Instance(); sdf::ElementPtr sdf(new sdf::Element); sdf::initFile("sensor.sdf", sdf); // Replace the essid by an empty value boost::regex re(".*<\\/frequency>"); std::string transmitterSensorStringCopy = boost::regex_replace(transmitterSensorString, re, "-1.0"); sdf::readString(transmitterSensorStringCopy, sdf); // Create the wireless receiver sensor ASSERT_NO_THROW(mgr->CreateSensor(sdf, "default", "ground_plane::link", 0)); } ///////////////////////////////////////////////// /// \brief Test the signal strength function void WirelessTransmitter_TEST::TestSignalStrength() { int samples = 100; double signStrengthAvg = 0.0; ignition::math::Pose3d txPose( ignition::math::Vector3d(3.0, 3.0, 0.055), ignition::math::Quaterniond(0, 0, 0)); ignition::math::Pose3d txPoseOccluded( ignition::math::Vector3d(-3.0, -3.0, 0.055), ignition::math::Quaterniond(0, 0, 0)); // Take some samples and get the average signal strength for (int i = 0; i < samples; ++i) { this->tx->Update(true); signStrengthAvg += this->tx->SignalStrength(txPose, tx->Gain()); } signStrengthAvg /= samples; EXPECT_NEAR(signStrengthAvg, -62.0, this->tx->ModelStdDev()); } ///////////////////////////////////////////////// /// \brief Callback executed for every propagation grid message received void WirelessTransmitter_TEST::TxMsg(const ConstPropagationGridPtr &_msg) { std::lock_guard lock(this->mutex); // Just copy the message this->gridMsg = _msg; this->receivedMsg = true; } ///////////////////////////////////////////////// /// \brief Test the publication of the propagation grid used for visualization void WirelessTransmitter_TEST::TestUpdateImpl() { // Initialize gazebo transport layer transport::NodePtr node(new transport::Node()); node->Init("default"); std::string txTopic = "/gazebo/default/tx/link/wirelessTransmitterConstructor/transceiver"; transport::SubscriberPtr sub = node->Subscribe(txTopic, &WirelessTransmitter_TEST::TxMsg, this); // Make sure that the sensor is updated and some messages are published for (int i = 0; i < 10; ++i) { this->tx->Update(true); common::Time::MSleep(100); } std::lock_guard lock(this->mutex); EXPECT_TRUE(this->receivedMsg); } ///////////////////////////////////////////////// /// \brief Test the updateImpl method with the visualization disabled void WirelessTransmitter_TEST::TestUpdateImplNoVisual() { sensors::WirelessTransmitterPtr txNoVisual; std::string txModelName = "tx"; std::string txNoVisualSensorName = "wirelessTransmitterNoVisual"; std::string txEssid = "GzTest"; double freq = 2442.0; double power = 14.5; double gain = 2.6; ignition::math::Pose3d txPose( ignition::math::Vector3d(3.0, 3.0, 0.055), ignition::math::Quaterniond(0, 0, 0)); // Spawn a wireless transmitter without sensor visualization SpawnWirelessTransmitterSensor(txModelName + "NoVisual", txNoVisualSensorName, txPose.Pos(), txPose.Rot().Euler(), txEssid + "NoVisual", freq, power, gain, false); txNoVisual = std::static_pointer_cast( sensors::SensorManager::Instance()->GetSensor(txNoVisualSensorName)); // Initialize gazebo transport layer transport::NodePtr node(new transport::Node()); node->Init("default"); std::string txTopic = "/gazebo/default/txNoVisual/link/wirelessTransmitterNoVisual/transceiver"; transport::SubscriberPtr sub = node->Subscribe(txTopic, &WirelessTransmitter_TEST::TxMsg, this); // Make sure that the sensor is updated and some messages are published for (int i = 0; i < 10; ++i) { txNoVisual->Update(true); common::Time::MSleep(100); } std::lock_guard lock(this->mutex); EXPECT_FALSE(this->receivedMsg); } ///////////////////////////////////////////////// TEST_F(WirelessTransmitter_TEST, TestSensorCreation) { TestCreateWirelessTransmitter(); } ///////////////////////////////////////////////// TEST_F(WirelessTransmitter_TEST, TestInvalidFreq) { TestInvalidFreq(); } ///////////////////////////////////////////////// TEST_F(WirelessTransmitter_TEST, TestSignalStrength) { TestSignalStrength(); } ///////////////////////////////////////////////// TEST_F(WirelessTransmitter_TEST, TestUpdateImpl) { TestUpdateImpl(); } ///////////////////////////////////////////////// TEST_F(WirelessTransmitter_TEST, TestUpdateImplNoVisual) { TestUpdateImplNoVisual(); } ///////////////////////////////////////////////// int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }