pxmlw6n2f/Gazebo_Distributed_TCP/gazebo/gui/ModelListWidget_TEST.cc

1046 lines
34 KiB
C++
Raw Permalink Normal View History

2019-03-28 10:57:49 +08:00
/*
* 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 <boost/filesystem.hpp>
#include <memory>
#include "gazebo/math/Helpers.hh"
#include "gazebo/msgs/msgs.hh"
#include "gazebo/transport/TransportIface.hh"
#include "gazebo/gui/GuiEvents.hh"
#include "gazebo/gui/GuiIface.hh"
#include "gazebo/gui/qtpropertybrowser/qttreepropertybrowser.h"
#include "gazebo/gui/qtpropertybrowser/qtvariantproperty.h"
#include "gazebo/gui/ModelListWidget.hh"
#include "gazebo/gui/ModelListWidget_TEST.hh"
#include "test_config.h"
/////////////////////////////////////////////////
void ModelListWidget_TEST::TreeWidget()
{
QBENCHMARK
{
this->Load("worlds/empty.world");
gazebo::gui::ModelListWidget *modelListWidget
= new gazebo::gui::ModelListWidget;
QCoreApplication::processEvents();
// Get tree widget
QTreeWidget *modelTreeWidget = modelListWidget->findChild<QTreeWidget*>(
"modelTreeWidget");
QVERIFY(modelTreeWidget != NULL);
QList<QTreeWidgetItem *> treeSceneItems =
modelTreeWidget->findItems(tr("Scene"), Qt::MatchExactly);
QCOMPARE(treeSceneItems.size(), 1);
QList<QTreeWidgetItem *> treePhysicsItems =
modelTreeWidget->findItems(tr("Physics"), Qt::MatchExactly);
QCOMPARE(treePhysicsItems.size(), 1);
QList<QTreeWidgetItem *> treeLightItems =
modelTreeWidget->findItems(tr("Lights"), Qt::MatchExactly);
QCOMPARE(treeLightItems.size(), 1);
QList<QTreeWidgetItem *> treeModelItems =
modelTreeWidget->findItems(tr("Models"), Qt::MatchExactly);
QCOMPARE(treeModelItems.size(), 1);
QTreeWidgetItem *modelsItem = treeModelItems.front();
QVERIFY(modelsItem != NULL);
delete modelListWidget;
}
}
/////////////////////////////////////////////////
void ModelListWidget_TEST::OnResponse(ConstResponsePtr &_msg)
{
gazebo::msgs::Model_V modelVMsg;
if (_msg->has_type() && _msg->type() == modelVMsg.GetTypeName())
{
modelVMsg.ParseFromString(_msg->serialized_data());
for (int i = 0; i < modelVMsg.models_size(); i++)
{
gazebo::gui::Events::modelUpdate(modelVMsg.models(i));
}
}
}
/////////////////////////////////////////////////
void ModelListWidget_TEST::CheckVector3Property(QList<QtProperty *> _properties,
const ignition::math::Vector3d &_xyz)
{
QVERIFY(_properties.size() >= 3);
for (unsigned char c = 0; c < 3; ++c)
{
QtVariantProperty *property =
static_cast<QtVariantProperty *>(_properties[c]);
Q_ASSERT(property);
std::string name(1, 'x' + c);
QCOMPARE(property->propertyName(), tr(name.c_str()));
QCOMPARE(property->value().toDouble(), _xyz[c]);
}
}
/////////////////////////////////////////////////
void ModelListWidget_TEST::CheckPoseProperty(QList<QtProperty *> _properties,
const gazebo::math::Pose &_pose)
{
QCOMPARE(_properties.size(), 6);
this->CheckVector3Property(_properties, _pose.pos.Ign());
QtVariantProperty *property;
property = static_cast<QtVariantProperty *>(_properties[3]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("roll"));
QCOMPARE(property->value().toDouble(), _pose.rot.GetAsEuler().x);
property = static_cast<QtVariantProperty *>(_properties[4]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("pitch"));
QCOMPARE(property->value().toDouble(), _pose.rot.GetAsEuler().y);
property = static_cast<QtVariantProperty *>(_properties[5]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("yaw"));
QCOMPARE(property->value().toDouble(), _pose.rot.GetAsEuler().z);
}
/////////////////////////////////////////////////
void ModelListWidget_TEST::SetVector3Property(
QtTreePropertyBrowser *_propTreeBrowser,
QList<QtProperty *> _properties,
const ignition::math::Vector3d &_xyz)
{
QVERIFY(_properties.size() >= 3);
for (unsigned char c = 0; c < 3; ++c)
{
QtVariantProperty *property =
static_cast<QtVariantProperty *>(_properties[c]);
Q_ASSERT(property);
std::string name(1, 'x' + c);
QCOMPARE(property->propertyName(), tr(name.c_str()));
QVERIFY(_propTreeBrowser->items(property).size() == 1);
_propTreeBrowser->setCurrentItem(_propTreeBrowser->items(property)[0]);
property->setValue(_xyz[c]);
}
QTest::qWait(500);
}
/////////////////////////////////////////////////
void ModelListWidget_TEST::SetPoseProperty(
QtTreePropertyBrowser *_propTreeBrowser,
QList<QtProperty *> _properties,
const gazebo::math::Pose &_pose)
{
QCOMPARE(_properties.size(), 6);
this->SetVector3Property(_propTreeBrowser, _properties, _pose.pos.Ign());
QtVariantProperty *property;
property = static_cast<QtVariantProperty *>(_properties[3]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("roll"));
QVERIFY(_propTreeBrowser->items(property).size() == 1);
_propTreeBrowser->setCurrentItem(_propTreeBrowser->items(property)[0]);
property->setValue(_pose.rot.GetAsEuler().x);
property = static_cast<QtVariantProperty *>(_properties[4]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("pitch"));
QVERIFY(_propTreeBrowser->items(property).size() == 1);
_propTreeBrowser->setCurrentItem(_propTreeBrowser->items(property)[0]);
property->setValue(_pose.rot.GetAsEuler().y);
property = static_cast<QtVariantProperty *>(_properties[5]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("yaw"));
QVERIFY(_propTreeBrowser->items(property).size() == 1);
_propTreeBrowser->setCurrentItem(_propTreeBrowser->items(property)[0]);
property->setValue(_pose.rot.GetAsEuler().z);
QTest::qWait(500);
}
/////////////////////////////////////////////////
void ModelListWidget_TEST::CheckLinkProperty(QList<QtProperty *> _properties,
const std::string &_name, bool _selfCollide, bool _gravity, bool _kinematic,
bool _canonical, const gazebo::math::Pose &_pose)
{
// ignore checking link id in _properties[0]
QtVariantProperty *property =
static_cast<QtVariantProperty *>(_properties[1]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("name"));
QCOMPARE(property->valueText(), tr(_name.c_str()));
property = static_cast<QtVariantProperty *>(_properties[2]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("self_collide"));
QCOMPARE(property->value().toBool(), _selfCollide);
property = static_cast<QtVariantProperty *>(_properties[3]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("gravity"));
QCOMPARE(property->value().toBool(), _gravity);
property = static_cast<QtVariantProperty *>(_properties[4]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("kinematic"));
QCOMPARE(property->value().toBool(), _kinematic);
property = static_cast<QtVariantProperty *>(_properties[5]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("canonical"));
QCOMPARE(property->value().toBool(), _canonical);
property = static_cast<QtVariantProperty *>(_properties[6]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("pose"));
CheckPoseProperty(property->subProperties(), _pose);
// pose settings for canonical links should be disabled
QCOMPARE(property->isEnabled(), !_canonical);
/// TODO check inertial, collision, visual properties
}
/////////////////////////////////////////////////
void ModelListWidget_TEST::SetLinkProperty(
QtTreePropertyBrowser *propTreeBrowser, QList<QtProperty *> _properties,
const std::string &_name, bool _selfCollide, bool _gravity, bool _kinematic,
bool _canonical, const gazebo::math::Pose &_pose)
{
QtVariantProperty *property =
static_cast<QtVariantProperty *>(_properties[1]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("name"));
QVERIFY(propTreeBrowser->items(property).size() == 1);
propTreeBrowser->setCurrentItem(propTreeBrowser->items(property)[0]);
property->setValue(tr(_name.c_str()));
property = static_cast<QtVariantProperty *>(_properties[2]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("self_collide"));
QVERIFY(propTreeBrowser->items(property).size() == 1);
propTreeBrowser->setCurrentItem(propTreeBrowser->items(property)[0]);
property->setValue(_selfCollide);
property = static_cast<QtVariantProperty *>(_properties[3]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("gravity"));
QVERIFY(propTreeBrowser->items(property).size() == 1);
propTreeBrowser->setCurrentItem(propTreeBrowser->items(property)[0]);
property->setValue(_gravity);
property = static_cast<QtVariantProperty *>(_properties[4]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("kinematic"));
QVERIFY(propTreeBrowser->items(property).size() == 1);
propTreeBrowser->setCurrentItem(propTreeBrowser->items(property)[0]);
property->setValue(_kinematic);
property = static_cast<QtVariantProperty *>(_properties[5]);
Q_ASSERT(property);
// only set the pose for non-canonical links
QCOMPARE(property->propertyName(), tr("canonical"));
QCOMPARE(property->value().toBool(), _canonical);
if (!property->value().toBool())
{
property = static_cast<QtVariantProperty *>(_properties[6]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("pose"));
QVERIFY(propTreeBrowser->items(property).size() == 1);
propTreeBrowser->setCurrentItem(propTreeBrowser->items(property)[0]);
propTreeBrowser->setExpanded(propTreeBrowser->topLevelItem(property), true);
this->SetPoseProperty(propTreeBrowser, property->subProperties(), _pose);
}
QTest::qWait(1000);
/// TODO set inertial, collision, visual properties
}
/////////////////////////////////////////////////
void ModelListWidget_TEST::ModelsTree()
{
gazebo::gui::ModelListWidget *modelListWidget
= new gazebo::gui::ModelListWidget;
QCoreApplication::processEvents();
this->Load("worlds/shapes.world");
gazebo::transport::NodePtr node;
node = gazebo::transport::NodePtr(new gazebo::transport::Node());
node->Init();
gazebo::transport::PublisherPtr requestPub =
node->Advertise<gazebo::msgs::Request>("~/request");
gazebo::transport::SubscriberPtr responseSub = node->Subscribe("~/response",
&ModelListWidget_TEST::OnResponse, this);
gazebo::msgs::Request *requestMsg =
gazebo::msgs::CreateRequest("entity_list");
requestPub->Publish(*requestMsg);
// Get tree widget
QTreeWidget *modelTreeWidget = modelListWidget->findChild<QTreeWidget *>(
"modelTreeWidget");
QList<QTreeWidgetItem *> treeModelItems =
modelTreeWidget->findItems(tr("Models"), Qt::MatchExactly);
QCOMPARE(treeModelItems.size(), 1);
QTreeWidgetItem *modelsItem = treeModelItems.front();
QVERIFY(modelsItem != NULL);
// verify that there are 4 models, ground plane, sphere, box, and cylinder
int modelCount = 4;
int maxSleep = 10;
int sleep = 0;
while (modelsItem->childCount() < modelCount && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(sleep < maxSleep);
// process more events and make sure the child count remain the same
sleep = 0;
maxSleep = 5;
while (sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
QCOMPARE(modelsItem->childCount(), modelCount);
sleep++;
}
// find all models in the tree
QTreeWidgetItem *groundPlaneItem = NULL;
QTreeWidgetItem *boxItem = NULL;
QTreeWidgetItem *sphereItem = NULL;
QTreeWidgetItem *cylinderItem = NULL;
for (int i = 0; i < modelsItem->childCount(); ++i)
{
QTreeWidgetItem *item = modelsItem->child(i);
if (item->text(0) == "ground_plane")
groundPlaneItem = item;
else if (item->text(0) == "box")
boxItem = item;
else if (item->text(0) == "sphere")
sphereItem = item;
else if (item->text(0) == "cylinder")
cylinderItem = item;
}
// verify all models are present
QVERIFY(groundPlaneItem != NULL);
QVERIFY(boxItem != NULL);
QVERIFY(sphereItem != NULL);
QVERIFY(cylinderItem != NULL);
node.reset();
delete requestMsg;
delete modelListWidget;
modelListWidget = NULL;
}
/////////////////////////////////////////////////
void ModelListWidget_TEST::ModelProperties()
{
gazebo::gui::ModelListWidget *modelListWidget
= new gazebo::gui::ModelListWidget;
modelListWidget->show();
QCoreApplication::processEvents();
this->Load("worlds/multilink_shape.world");
gazebo::transport::NodePtr node;
node = gazebo::transport::NodePtr(new gazebo::transport::Node());
node->Init();
gazebo::transport::PublisherPtr requestPub =
node->Advertise<gazebo::msgs::Request>("~/request");
gazebo::transport::SubscriberPtr responseSub = node->Subscribe("~/response",
&ModelListWidget_TEST::OnResponse, this);
gazebo::msgs::Request *requestMsg =
gazebo::msgs::CreateRequest("entity_list");
requestPub->Publish(*requestMsg);
// Get tree widget
QTreeWidget *modelTreeWidget = modelListWidget->findChild<QTreeWidget *>(
"modelTreeWidget");
QList<QTreeWidgetItem *> treeModelItems =
modelTreeWidget->findItems(tr("Models"), Qt::MatchExactly);
QCOMPARE(treeModelItems.size(), 1);
QTreeWidgetItem *modelsItem = treeModelItems.front();
QVERIFY(modelsItem != NULL);
// verify that there is only 1 model
int modelCount = 1;
int maxSleep = 10;
int sleep = 0;
while (modelsItem->childCount() < modelCount && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(sleep < maxSleep);
// Get the model item
QTreeWidgetItem *modelItem = modelsItem->child(0);
QVERIFY(modelItem != NULL);
std::string modelName = "multilink";
QCOMPARE(modelItem->text(0), tr(modelName.c_str()));
// Get propery browser widget
QObject *propTreeObj =
modelListWidget->findChild<QObject *>("propTreeBrowser");
QtTreePropertyBrowser *propTreeBrowser =
dynamic_cast<QtTreePropertyBrowser *>(propTreeObj);
QVERIFY(propTreeBrowser != NULL);
QCOMPARE(propTreeBrowser->properties().size(), 0);
// select the models item
QRect modelsRect = modelTreeWidget->visualItemRect(modelsItem);
QTest::mouseClick(modelTreeWidget->viewport(), Qt::LeftButton, 0,
modelsRect.center() );
QCoreApplication::processEvents();
// wait for the model to be selected
sleep = 0;
maxSleep = 5;
while (!modelsItem->isSelected() && sleep < maxSleep)
{
QTest::qWait(10);
sleep++;
}
QVERIFY(modelsItem->isSelected());
// select the multi-link model
QRect modelRect = modelTreeWidget->visualItemRect(modelItem);
QTest::mouseClick(modelTreeWidget->viewport(), Qt::LeftButton, 0,
modelRect.center() );
QCoreApplication::processEvents();
sleep = 0;
maxSleep = 5;
while (!modelItem->isSelected() && sleep < maxSleep)
{
QTest::qWait(10);
sleep++;
}
QVERIFY(modelItem->isSelected());
// wait for the model properties to appear
sleep = 0;
maxSleep = 10;
while (propTreeBrowser->properties().size() == 0 && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(propTreeBrowser->properties().size() > 0);
// check the model properties
bool hasName = false;
bool hasStatic = false;
bool hasPose = false;
int numLinks = 0;
int nameIndex = 1;
QList<QtProperty *> modelProperties = propTreeBrowser->properties();
for (int i = 0; i < modelProperties.size(); ++i)
{
QtVariantProperty *property =
static_cast<QtVariantProperty *>(modelProperties[i]);
if (property->propertyName() == tr("name"))
{
QCOMPARE(property->valueText(), tr(modelName.c_str()));
hasName = true;
}
else if (property->propertyName() == tr("is_static"))
{
QCOMPARE(property->value().toBool(), false);
hasStatic = true;
}
else if (property->propertyName() == tr("pose"))
{
this->CheckPoseProperty(property->subProperties(),
gazebo::math::Pose(0, 0, 0.5, 0, 0, 0));
hasPose = true;
}
else if (property->propertyName() == tr("link"))
{
QVERIFY(property->subProperties().size() > 0);
if (property->subProperties()[nameIndex]->valueText().toStdString().
find("box_link") != std::string::npos)
{
this->CheckLinkProperty(property->subProperties(),
modelName + "::box_link", false, true, false, true,
gazebo::math::Pose(1.0, 0, 0, 0, 0, 0));
numLinks++;
}
else if (property->subProperties()[nameIndex]->valueText().toStdString().
find("sphere_link") != std::string::npos)
{
this->CheckLinkProperty(property->subProperties(),
modelName + "::sphere_link", false, true, false, false,
gazebo::math::Pose(-1.5, 0, 0, 0, 0, 1.57));
numLinks++;
}
}
}
QVERIFY(hasName);
QVERIFY(hasStatic);
QVERIFY(hasPose);
// there should be 2 links
QCOMPARE(numLinks, 2);
numLinks = 0;
// change model properties
for (int i = 0; i < modelProperties.size(); ++i)
{
QtVariantProperty *property =
static_cast<QtVariantProperty *>(modelProperties[i]);
// TODO changing model name currently fails
// if (property->propertyName() == tr("name"))
// {
// propTreeBrowser->setCurrentItem(propTreeBrowser->items(property)[0]);
// property->setValue(true);
// }
if (property->propertyName() == tr("is_static"))
{
propTreeBrowser->setCurrentItem(propTreeBrowser->items(property)[0]);
property->setValue(true);
}
else if (property->propertyName() == tr("pose"))
{
this->SetPoseProperty(propTreeBrowser, property->subProperties(),
gazebo::math::Pose(0, 0, 1.0, 0, 0, 0));
}
else if (property->propertyName() == tr("link"))
{
QVERIFY(property->subProperties().size() > 0);
if (property->subProperties()[nameIndex]->valueText().toStdString().
find("box_link") != std::string::npos)
{
this->SetLinkProperty(propTreeBrowser, property->subProperties(),
modelName + "::box_link", true, false, true, true,
gazebo::math::Pose(1.5, 2.0, 3.2, 0.6, 0.7, 0.8));
numLinks++;
}
else if (property->subProperties()[nameIndex]->valueText().toStdString().
find("sphere_link") != std::string::npos)
{
this->SetLinkProperty(propTreeBrowser, property->subProperties(),
modelName + "::sphere_link", true, false, true, false,
gazebo::math::Pose(-2.0, 0.5, 1.0, 3.14, 0, 0));
numLinks++;
}
}
}
QCOMPARE(numLinks, 2);
// select the multi-link model again to refresh the property browser
QTest::mouseClick(modelTreeWidget->viewport(), Qt::LeftButton, 0,
modelRect.center() );
QCoreApplication::processEvents();
QTest::qWait(100);
sleep = 0;
maxSleep = 5;
while (!modelItem->isSelected() && sleep < maxSleep)
{
QTest::qWait(10);
sleep++;
}
QVERIFY(modelItem->isSelected());
// wait for the model properties to appear
sleep = 0;
maxSleep = 10;
while (propTreeBrowser->properties().size() == 0 && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(propTreeBrowser->properties().size() > 0);
numLinks = 0;
// verify the model properties are sucessfully set
for (int i = 0; i < modelProperties.size(); ++i)
{
QtVariantProperty *property =
static_cast<QtVariantProperty *>(modelProperties[i]);
if (property->propertyName() == tr("is_static"))
{
QCOMPARE(property->value().toBool(), true);
}
else if (property->propertyName() == tr("pose"))
{
this->CheckPoseProperty(property->subProperties(),
gazebo::math::Pose(0, 0, 1.0, 0, 0, 0));
}
else if (property->propertyName() == tr("link"))
{
QVERIFY(property->subProperties().size() > 0);
if (property->subProperties()[nameIndex]->valueText().toStdString().
find("box_link") != std::string::npos)
{
// as this is the canonical link, the pose properties should remain
// unchanged
this->CheckLinkProperty(property->subProperties(),
modelName + "::box_link", true, false, true, true,
gazebo::math::Pose(1.0, 0, 0, 0, 0, 0));
numLinks++;
}
else if (property->subProperties()[nameIndex]->valueText().toStdString().
find("sphere_link") != std::string::npos)
{
this->CheckLinkProperty(property->subProperties(),
modelName + "::sphere_link", true, false, true, false,
gazebo::math::Pose(-2.0, 0.5, 1.0, 3.14, 0, 0));
numLinks++;
}
}
}
QCOMPARE(numLinks, 2);
modelListWidget->hide();
node.reset();
delete requestMsg;
delete modelListWidget;
}
/////////////////////////////////////////////////
void ModelListWidget_TEST::LinkProperties()
{
gazebo::gui::ModelListWidget *modelListWidget
= new gazebo::gui::ModelListWidget;
modelListWidget->show();
modelListWidget->setGeometry(0, 0, 400, 800);
QCoreApplication::processEvents();
this->Load("worlds/multilink_shape.world");
gazebo::transport::NodePtr node;
node = gazebo::transport::NodePtr(new gazebo::transport::Node());
node->Init();
gazebo::transport::PublisherPtr requestPub =
node->Advertise<gazebo::msgs::Request>("~/request");
gazebo::transport::SubscriberPtr responseSub = node->Subscribe("~/response",
&ModelListWidget_TEST::OnResponse, this);
gazebo::msgs::Request *requestMsg =
gazebo::msgs::CreateRequest("entity_list");
requestPub->Publish(*requestMsg);
// Get tree widget
QTreeWidget *modelTreeWidget = modelListWidget->findChild<QTreeWidget *>(
"modelTreeWidget");
QList<QTreeWidgetItem *> treeModelItems =
modelTreeWidget->findItems(tr("Models"), Qt::MatchExactly);
QCOMPARE(treeModelItems.size(), 1);
QTreeWidgetItem *modelsItem = treeModelItems.front();
QVERIFY(modelsItem != NULL);
// verify that there is only 1 model
int modelCount = 1;
int maxSleep = 10;
int sleep = 0;
while (modelsItem->childCount() < modelCount && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(sleep < maxSleep);
// Get the model item
QTreeWidgetItem *modelItem = modelsItem->child(0);
QVERIFY(modelItem != NULL);
std::string modelName = "multilink";
QCOMPARE(modelItem->text(0), tr(modelName.c_str()));
// Get propery browser widget
QObject *propTreeObj =
modelListWidget->findChild<QObject *>("propTreeBrowser");
QtTreePropertyBrowser *propTreeBrowser =
dynamic_cast<QtTreePropertyBrowser *>(propTreeObj);
QVERIFY(propTreeBrowser != NULL);
QCOMPARE(propTreeBrowser->properties().size(), 0);
// select the models item
QRect modelsRect = modelTreeWidget->visualItemRect(modelsItem);
QTest::mouseClick(modelTreeWidget->viewport(), Qt::LeftButton, 0,
modelsRect.center() );
QCoreApplication::processEvents();
// wait for the models item to be selected
sleep = 0;
maxSleep = 5;
while (!modelsItem->isSelected() && sleep < maxSleep)
{
QTest::qWait(10);
sleep++;
}
QVERIFY(modelsItem->isSelected());
// select the multi-link model
QRect modelRect = modelTreeWidget->visualItemRect(modelItem);
QTest::mouseClick(modelTreeWidget->viewport(), Qt::LeftButton, 0,
modelRect.center());
QCoreApplication::processEvents();
sleep = 0;
maxSleep = 5;
while (!modelItem->isSelected() && sleep < maxSleep)
{
QTest::qWait(10);
sleep++;
}
QVERIFY(modelItem->isSelected());
// wait for the model properties to appear
sleep = 0;
maxSleep = 10;
while (propTreeBrowser->properties().size() == 0 && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(propTreeBrowser->properties().size() > 0);
// select the box link
QTreeWidgetItem *boxLinkItem = modelItem->child(0);
QVERIFY(boxLinkItem != NULL);
std::string boxLinkName = "box_link";
QCOMPARE(boxLinkItem->text(0), tr(boxLinkName.c_str()));
QRect boxLinkRect = modelTreeWidget->visualItemRect(boxLinkItem);
QTest::mouseClick(modelTreeWidget->viewport(), Qt::LeftButton, 0,
boxLinkRect.center() );
QCoreApplication::processEvents();
sleep = 0;
maxSleep = 5;
while (!boxLinkItem->isSelected() && sleep < maxSleep)
{
QTest::qWait(10);
sleep++;
}
QVERIFY(boxLinkItem->isSelected());
// wait for the box link properties to appear
sleep = 0;
maxSleep = 10;
while (propTreeBrowser->properties().size() == 0 && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(propTreeBrowser->properties().size() > 0);
// check the box link properties
this->CheckLinkProperty(propTreeBrowser->properties(),
modelName + "::" + boxLinkName, false, true, false, true,
gazebo::math::Pose(1.0, 0, 0, 0, 0, 0));
// change box link properties
// TODO changing link name currently fails.
this->SetLinkProperty(propTreeBrowser, propTreeBrowser->properties(),
modelName + "::" + boxLinkName, true, false, true, true,
gazebo::math::Pose(2.5, 1.0, 4.2, 0.8, 0.5, 0.1));
// select the box link again to refresh the property browser
QTest::mouseClick(modelTreeWidget->viewport(), Qt::LeftButton, 0,
boxLinkRect.center() );
QCoreApplication::processEvents();
QTest::qWait(100);
sleep = 0;
maxSleep = 5;
while (!boxLinkItem->isSelected() && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(10);
sleep++;
}
QVERIFY(boxLinkItem->isSelected());
// wait for the box link properties to appear
sleep = 0;
maxSleep = 10;
while (propTreeBrowser->properties().size() == 0 && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(propTreeBrowser->properties().size() > 0);
// verify the link properties are sucessfully set
// the link is canonical so the pose should remain the same
this->CheckLinkProperty(propTreeBrowser->properties(),
modelName + "::" + boxLinkName, true, false, true, true,
gazebo::math::Pose(1.0, 0, 0, 0, 0, 0));
// select the sphere link
QTreeWidgetItem *sphereLinkItem = modelItem->child(1);
QVERIFY(sphereLinkItem != NULL);
std::string sphereLinkName = "sphere_link";
QCOMPARE(sphereLinkItem->text(0), tr(sphereLinkName.c_str()));
QRect sphereLinkRect = modelTreeWidget->visualItemRect(sphereLinkItem);
QTest::mouseClick(modelTreeWidget->viewport(), Qt::LeftButton, 0,
sphereLinkRect.center() );
QCoreApplication::processEvents();
QTest::qWait(100);
sleep = 0;
maxSleep = 5;
while (!sphereLinkItem->isSelected() && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(10);
sleep++;
}
QVERIFY(sphereLinkItem->isSelected());
// wait for the sphere link properties to appear
sleep = 0;
maxSleep = 10;
while (propTreeBrowser->properties().size() == 0 && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(propTreeBrowser->properties().size() > 0);
// check the sphere link properties
this->CheckLinkProperty(propTreeBrowser->properties(),
modelName + "::" + sphereLinkName, false, true, false, false,
gazebo::math::Pose(-1.5, 0, 0, 0, 0, 1.57));
// change sphere link properties
// TODO changing link name currently fails.
this->SetLinkProperty(propTreeBrowser, propTreeBrowser->properties(),
modelName + "::" + sphereLinkName, true, false, true, false,
gazebo::math::Pose(-2.0, 0.1, -1.2, 0, 1.57, 0));
// select the sphere link again to refresh the property browser
QTest::mouseClick(modelTreeWidget->viewport(), Qt::LeftButton, 0,
sphereLinkRect.center() );
QCoreApplication::processEvents();
QTest::qWait(100);
sleep = 0;
maxSleep = 5;
while (!sphereLinkItem->isSelected() && sleep < maxSleep)
{
QTest::qWait(10);
sleep++;
}
QVERIFY(sphereLinkItem->isSelected());
// wait for the sphere link properties to appear
sleep = 0;
maxSleep = 10;
while (propTreeBrowser->properties().size() == 0 && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(propTreeBrowser->properties().size() > 0);
// verify the link properties are sucessfully set
this->CheckLinkProperty(propTreeBrowser->properties(),
modelName + "::" + sphereLinkName, true, false, true, false,
gazebo::math::Pose(-2.0, 0.1, -1.2, 0, 1.57, 0));
modelListWidget->hide();
node.reset();
delete requestMsg;
delete modelListWidget;
}
/////////////////////////////////////////////////
void ModelListWidget_TEST::PhysicsProperties()
{
std::unique_ptr<gazebo::gui::ModelListWidget> modelListWidget(
new gazebo::gui::ModelListWidget);
modelListWidget->show();
modelListWidget->setGeometry(0, 0, 400, 800);
QCoreApplication::processEvents();
this->Load("worlds/empty.world");
// Verify that property browser widget is initially empty
QObject *propTreeObj =
modelListWidget->findChild<QObject *>("propTreeBrowser");
QtTreePropertyBrowser *propTreeBrowser =
dynamic_cast<QtTreePropertyBrowser *>(propTreeObj);
QVERIFY(propTreeBrowser != NULL);
QCOMPARE(propTreeBrowser->properties().size(), 0);
// Get the physics item from the model tree
QTreeWidget *modelTreeWidget = modelListWidget->findChild<QTreeWidget *>(
"modelTreeWidget");
QList<QTreeWidgetItem *> treePhysicsItems =
modelTreeWidget->findItems(tr("Physics"), Qt::MatchExactly);
QCOMPARE(treePhysicsItems.size(), 1);
QTreeWidgetItem *physicsItem = treePhysicsItems.front();
QVERIFY(physicsItem != NULL);
// select the physics item after giving it time to be rendered
QTest::qWait(10);
QRect physicsRect;
{
physicsRect = modelTreeWidget->visualItemRect(physicsItem);
QTest::mouseClick(modelTreeWidget->viewport(), Qt::LeftButton, 0,
physicsRect.center() );
QCoreApplication::processEvents();
// wait for the physics item to be selected
int sleep = 0;
int maxSleep = 5;
while (!physicsItem->isSelected() && sleep < maxSleep)
{
QTest::qWait(10);
sleep++;
}
QVERIFY(physicsItem->isSelected());
}
// wait for the physics properties to appear
{
int sleep = 0;
int maxSleep = 10;
while (propTreeBrowser->properties().size() == 0 && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(propTreeBrowser->properties().size() > 0);
}
// verify that there are 8 physics properties
QCOMPARE(propTreeBrowser->properties().size(), 8);
// check default values of each parameter
// physics engine type: ODE
{
auto properties = propTreeBrowser->properties();
QtVariantProperty *property =
static_cast<QtVariantProperty *>(properties[0]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("physics engine"));
QCOMPARE(property->valueText(), tr("ODE"));
}
// physics enabled: true
{
auto properties = propTreeBrowser->properties();
QtVariantProperty *property =
static_cast<QtVariantProperty *>(properties[1]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("enable physics"));
QCOMPARE(property->value().toBool(), true);
}
// real time update rate: 1000
{
auto properties = propTreeBrowser->properties();
QtVariantProperty *property =
static_cast<QtVariantProperty *>(properties[2]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("real time update rate"));
QCOMPARE(property->value().toDouble(), 1e3);
}
// max step size: 0.001
{
auto properties = propTreeBrowser->properties();
QtVariantProperty *property =
static_cast<QtVariantProperty *>(properties[3]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("max step size"));
QCOMPARE(property->value().toDouble(), 1e-3);
}
// gravity: 0 0 -9.8
{
const ignition::math::Vector3d gravity(0, 0, -9.8);
auto properties = propTreeBrowser->properties();
QtVariantProperty *property =
static_cast<QtVariantProperty *>(properties[4]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("gravity"));
this->CheckVector3Property(property->subProperties(), gravity);
// set gravity to 0 0 0
this->SetVector3Property(propTreeBrowser, property->subProperties(),
ignition::math::Vector3d::Zero);
}
// magnetic field: 6e-6 2.3e-5 -4.2e-5
{
const ignition::math::Vector3d xyz(6e-6, 2.3e-5, -4.2e-5);
auto properties = propTreeBrowser->properties();
QtVariantProperty *property =
static_cast<QtVariantProperty *>(properties[5]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("magnetic field"));
CheckVector3Property(property->subProperties(), xyz);
}
// select the box link again to refresh the property browser
QTest::mouseClick(modelTreeWidget->viewport(), Qt::LeftButton, 0,
physicsRect.center() );
{
QCoreApplication::processEvents();
QTest::qWait(100);
int sleep = 0;
int maxSleep = 5;
while (!physicsItem->isSelected() && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(10);
sleep++;
}
QVERIFY(physicsItem->isSelected());
}
// wait for the box link properties to appear
{
int sleep = 0;
int maxSleep = 10;
while (propTreeBrowser->properties().size() == 0 && sleep < maxSleep)
{
QCoreApplication::processEvents();
QTest::qWait(500);
sleep++;
}
QVERIFY(propTreeBrowser->properties().size() > 0);
}
// check gravity: 0 0 0
{
auto properties = propTreeBrowser->properties();
QtVariantProperty *property =
static_cast<QtVariantProperty *>(properties[4]);
Q_ASSERT(property);
QCOMPARE(property->propertyName(), tr("gravity"));
this->CheckVector3Property(property->subProperties(),
ignition::math::Vector3d::Zero);
}
modelListWidget->hide();
}
// Generate a main function for the test
QTEST_MAIN(ModelListWidget_TEST)