pxmlw6n2f/Gazebo_Distributed_MPI/test/integration/touch_plugin.cc

253 lines
7.3 KiB
C++

/*
* Copyright (C) 2017 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 "gazebo/test/ServerFixture.hh"
#include "gazebo/physics/physics.hh"
#include "gazebo/test/helper_physics_generator.hh"
using namespace gazebo;
class TouchPluginTest : public ServerFixture,
public testing::WithParamInterface<const char*>
{
/// \brief Test observing only one link in a model
/// \param[in] _physicsEngine Physics engine to use.
public: void OneLink(const std::string &_physicsEngine);
/// \brief Test observing more than one link in a model
/// \param[in] _physicsEngine Physics engine to use.
public: void MultiLink(const std::string &_physicsEngine);
/// \brief Test a plugin which starts disabled.
/// \param[in] _physicsEngine Physics engine to use.
public: void StartDisabled(const std::string &_physicsEngine);
/// \brief Callback when white box plugin touches.
/// \param[in] _msg Unused
public: void WhiteTouch(ConstIntPtr &/*_msg*/);
/// \brief Callback when red / yellow box plugin touches.
/// \param[in] _msg Unused
public: void RedTouch(ConstIntPtr &/*_msg*/);
/// \brief Callback when blue box plugin touches.
/// \param[in] _msg Unused
public: void BlueTouch(ConstIntPtr &/*_msg*/);
/// \brief Flag turned to true once white touches.
private: bool whiteTouched = false;
/// \brief Flag turned to true once red/yellow touches.
private: bool redTouched = false;
/// \brief Flag turned to true once blue touches.
private: bool blueTouched = false;
};
//////////////////////////////////////////////////
void TouchPluginTest::WhiteTouch(ConstIntPtr &/*_msg*/)
{
this->whiteTouched = true;
}
//////////////////////////////////////////////////
void TouchPluginTest::RedTouch(ConstIntPtr &/*_msg*/)
{
this->redTouched = true;
}
//////////////////////////////////////////////////
void TouchPluginTest::BlueTouch(ConstIntPtr &/*_msg*/)
{
this->blueTouched = true;
}
//////////////////////////////////////////////////
void TouchPluginTest::OneLink(const std::string &_physicsEngine)
{
this->Load("worlds/touch_plugin_demo.world", true, _physicsEngine);
auto world = physics::get_world();
ASSERT_NE(world , nullptr);
// Get models
auto whiteBox = world->GetModel("white_box");
// Subscribe to plugin notifications
auto whiteSub = this->node->Subscribe("/white_touches_only_green/touched",
&TouchPluginTest::WhiteTouch, this);
// Check boxes haven't touched yet
EXPECT_FALSE(this->whiteTouched);
// Place white box on top of green box
whiteBox->SetWorldPose(ignition::math::Pose3d(4.0, 0, 2.0, 0, 0, 0));
// Give it time to drop and touch
world->Step(1000);
// Check it hasn't touched for long enough
EXPECT_FALSE(this->whiteTouched);
// Give it time to touch for 3 seconds
world->Step(4000);
// Check it has touched for long enough
EXPECT_TRUE(this->whiteTouched);
// Wait more and check it doesn't notify again
this->whiteTouched = false;
world->Step(5000);
EXPECT_FALSE(this->whiteTouched);
// Enable plugin again
auto enablePub = this->node->Advertise<msgs::Int>(
"/white_touches_only_green/enable");
msgs::Int msg;
msg.set_data(1);
enablePub->Publish(msg);
// Wait and see it notifies again
this->whiteTouched = false;
world->Step(5000);
EXPECT_TRUE(this->whiteTouched);
}
//////////////////////////////////////////////////
TEST_P(TouchPluginTest, OneLink)
{
const std::string physicsEngine = GetParam();
if (physicsEngine != "ode")
{
gzwarn << "This test depends on continuous contacts, which are achieved on"
<< " ODE using <max_vel> and <min_depth>. Skipping test for ["
<< physicsEngine << "]. See issue #2213." << std::endl;
return;
}
OneLink(GetParam());
}
//////////////////////////////////////////////////
void TouchPluginTest::MultiLink(const std::string &_physicsEngine)
{
this->Load("worlds/touch_plugin_demo.world", true, _physicsEngine);
auto world = physics::get_world();
ASSERT_NE(world , nullptr);
// Get models
auto redYellowBox = world->GetModel("red_yellow_box");
// Subscribe to plugin notifications
auto redSub = this->node->Subscribe(
"/red_and_yellow_touch_only_green/touched",
&TouchPluginTest::RedTouch, this);
// Check boxes haven't touched yet
EXPECT_FALSE(this->redTouched);
// Place red and yellow boxes on top of green box
redYellowBox->SetWorldPose(
ignition::math::Pose3d(4.0, 0, 2.0, IGN_PI*0.5, 0, 0));
// Give it time to drop and touch
world->Step(1000);
// Check it hasn't touched for long enough
EXPECT_FALSE(this->redTouched);
// Give it time to touch for 5 seconds
world->Step(5000);
// Check it has touched for long enough
EXPECT_TRUE(this->redTouched);
}
//////////////////////////////////////////////////
TEST_P(TouchPluginTest, MultiLink)
{
const std::string physicsEngine = GetParam();
if (physicsEngine != "ode")
{
gzwarn << "This test depends on continuous contacts, which are achieved on"
<< " ODE using <max_vel> and <min_depth>. Skipping test for ["
<< physicsEngine << "]. See issue #2213." << std::endl;
return;
}
MultiLink(GetParam());
}
//////////////////////////////////////////////////
void TouchPluginTest::StartDisabled(const std::string &_physicsEngine)
{
this->Load("worlds/touch_plugin_demo.world", true, _physicsEngine);
auto world = physics::get_world();
ASSERT_NE(world , nullptr);
// Get models
auto blueBox = world->GetModel("blue_box");
// Subscribe to plugin notifications
auto blueSub = this->node->Subscribe("/blue_touches_only_green/touched",
&TouchPluginTest::BlueTouch, this);
// Check boxes haven't touched yet
EXPECT_FALSE(this->blueTouched);
// Place blue box on top of green box
blueBox->SetWorldPose(ignition::math::Pose3d(4.0, 0, 2.0, 0, 0, 0));
// Give it time to drop and touch for a while
world->Step(3000);
// Verify we don't get a notification
EXPECT_FALSE(this->blueTouched);
// Enable plugin
auto enablePub = this->node->Advertise<msgs::Int>(
"/blue_touches_only_green/enable");
msgs::Int msg;
msg.set_data(1);
enablePub->Publish(msg);
// Wait and see it notifies now
this->blueTouched = false;
world->Step(3000);
EXPECT_TRUE(this->blueTouched);
}
//////////////////////////////////////////////////
TEST_P(TouchPluginTest, StartDisabled)
{
const std::string physicsEngine = GetParam();
if (physicsEngine != "ode")
{
gzwarn << "This test depends on continuous contacts, which are achieved on"
<< " ODE using <max_vel> and <min_depth>. Skipping test for ["
<< physicsEngine << "]. See issue #2213." << std::endl;
return;
}
StartDisabled(GetParam());
}
INSTANTIATE_TEST_CASE_P(PhysicsEngines, TouchPluginTest, PHYSICS_ENGINE_VALUES);
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}