Skip to content

Commit 22c8644

Browse files
author
Nate Koenig
committed
merged and addressed comments
Signed-off-by: Nate Koenig <[email protected]>
2 parents 345755f + 747f595 commit 22c8644

24 files changed

+1635
-167
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ set(IGN_PHYSICS_VER ${ignition-physics5_VERSION_MAJOR})
110110

111111
#--------------------------------------
112112
# Find ignition-sensors
113-
ign_find_package(ignition-sensors6 REQUIRED
113+
ign_find_package(ignition-sensors6 REQUIRED VERSION 6.0.1
114114
# component order is important
115115
COMPONENTS
116116
# non-rendering
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (C) 2021 Open Source Robotics Foundation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
#ifndef IGNITION_GAZEBO_COMPONENTS_RECREATE_HH_
18+
#define IGNITION_GAZEBO_COMPONENTS_RECREATE_HH_
19+
20+
#include <ignition/gazebo/components/Factory.hh>
21+
#include <ignition/gazebo/components/Component.hh>
22+
#include <ignition/gazebo/config.hh>
23+
24+
namespace ignition
25+
{
26+
namespace gazebo
27+
{
28+
// Inline bracket to help doxygen filtering.
29+
inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
30+
namespace components
31+
{
32+
/// \brief A component that identifies an entity needs to be recreated.
33+
/// Currently, only Models will be processed for recreation by the
34+
/// SimulationRunner in the ProcessRecreateEntitiesRemove and
35+
/// ProcessRecreateEntitiesCreate functions.
36+
///
37+
/// The GUI ModelEditor contains example code on how to use this
38+
/// component. For example, the ModelEditor allows a user to add a link to an
39+
/// existing model. The existing model is tagged with this component so
40+
/// that it can be recreated by the server.
41+
using Recreate = Component<NoData, class RecreateTag>;
42+
IGN_GAZEBO_REGISTER_COMPONENT("ign_gazebo_components.Recreate", Recreate)
43+
}
44+
}
45+
}
46+
}
47+
48+
#endif

include/ignition/gazebo/detail/View.hh

+4
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,10 @@ template<typename ...ComponentTypeTs>
280280
bool View<ComponentTypeTs...>::NotifyComponentRemoval(const Entity _entity,
281281
const ComponentTypeId _typeId)
282282
{
283+
// if entity is still marked as to add, remove from the view
284+
if (this->RequiresComponent(_typeId))
285+
this->toAddEntities.erase(_entity);
286+
283287
// make sure that _typeId is a type required by the view and that _entity is
284288
// already a part of the view
285289
if (!this->RequiresComponent(_typeId) ||

src/EntityComponentManager.cc

+91-21
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#include "ignition/gazebo/components/Name.hh"
4040
#include "ignition/gazebo/components/ParentEntity.hh"
4141
#include "ignition/gazebo/components/ParentLinkName.hh"
42+
#include "ignition/gazebo/components/Recreate.hh"
43+
#include "ignition/gazebo/components/World.hh"
4244

4345
using namespace ignition;
4446
using namespace gazebo;
@@ -420,7 +422,30 @@ Entity EntityComponentManager::CloneImpl(Entity _entity, Entity _parent,
420422
}
421423
else if (!_name.empty() && !_allowRename)
422424
{
423-
if (kNullEntity != this->EntityByComponents(components::Name(_name)))
425+
// Get the entity's original parent. This is used to make sure we get
426+
// the correct entity. For example, two different models may have a
427+
// child with the name "link".
428+
auto origParentComp =
429+
this->Component<components::ParentEntity>(_entity);
430+
431+
// If there is an entity with the same name and user indicated renaming is
432+
// not allowed then return null entity.
433+
// If the entity or one of its ancestor has a Recreate component then carry
434+
// on since the ECM is supposed to create a new entity with the same name.
435+
Entity ent = this->EntityByComponents(components::Name(_name),
436+
components::ParentEntity(origParentComp->Data()));
437+
438+
bool hasRecreateComp = false;
439+
Entity recreateEnt = ent;
440+
while (recreateEnt != kNullEntity && !hasRecreateComp)
441+
{
442+
hasRecreateComp = this->Component<components::Recreate>(recreateEnt) !=
443+
nullptr;
444+
auto parentComp = this->Component<components::ParentEntity>(recreateEnt);
445+
recreateEnt = parentComp ? parentComp->Data() : kNullEntity;
446+
}
447+
448+
if (kNullEntity != ent && !hasRecreateComp)
424449
{
425450
ignerr << "Requested to clone entity [" << _entity
426451
<< "] with a name of [" << _name << "], but another entity already "
@@ -497,19 +522,35 @@ Entity EntityComponentManager::CloneImpl(Entity _entity, Entity _parent,
497522
Entity originalParentLink = kNullEntity;
498523
Entity originalChildLink = kNullEntity;
499524

525+
auto origParentComp =
526+
this->Component<components::ParentEntity>(_entity);
527+
500528
const auto &parentName =
501529
this->Component<components::ParentLinkName>(_entity);
502-
if (parentName)
530+
if (parentName && origParentComp)
503531
{
504-
originalParentLink = this->EntityByComponents<components::Name>(
505-
components::Name(parentName->Data()));
532+
// CHangel the case where the parent link name is the world.
533+
if (common::lowercase(parentName->Data()) == "world")
534+
{
535+
originalParentLink = this->Component<components::ParentEntity>(
536+
origParentComp->Data())->Data();
537+
}
538+
else
539+
{
540+
originalParentLink =
541+
this->EntityByComponents<components::Name, components::ParentEntity>(
542+
components::Name(parentName->Data()),
543+
components::ParentEntity(origParentComp->Data()));
544+
}
506545
}
507546

508547
const auto &childName = this->Component<components::ChildLinkName>(_entity);
509-
if (childName)
548+
if (childName && origParentComp)
510549
{
511-
originalChildLink = this->EntityByComponents<components::Name>(
512-
components::Name(childName->Data()));
550+
originalChildLink =
551+
this->EntityByComponents<components::Name, components::ParentEntity>(
552+
components::Name(childName->Data()),
553+
components::ParentEntity(origParentComp->Data()));
513554
}
514555

515556
if (!originalParentLink || !originalChildLink)
@@ -533,7 +574,14 @@ Entity EntityComponentManager::CloneImpl(Entity _entity, Entity _parent,
533574
for (const auto &childEntity :
534575
this->EntitiesByComponents(components::ParentEntity(_entity)))
535576
{
536-
auto clonedChild = this->CloneImpl(childEntity, clonedEntity, "", true);
577+
std::string name;
578+
if (!_allowRename)
579+
{
580+
auto nameComp = this->Component<components::Name>(childEntity);
581+
name = nameComp->Data();
582+
}
583+
auto clonedChild = this->CloneImpl(childEntity, clonedEntity, name,
584+
_allowRename);
537585
if (kNullEntity == clonedChild)
538586
{
539587
ignerr << "Cloning child entity [" << childEntity << "] failed.\n";
@@ -1038,6 +1086,14 @@ bool EntityComponentManager::CreateComponentImplementation(
10381086

10391087
this->dataPtr->createdCompTypes.insert(_componentTypeId);
10401088

1089+
// If the component is a components::ParentEntity, then make sure to
1090+
// update the entities graph.
1091+
if (_componentTypeId == components::ParentEntity::typeId)
1092+
{
1093+
auto parentComp = this->Component<components::ParentEntity>(_entity);
1094+
this->SetParentEntity(_entity, parentComp->Data());
1095+
}
1096+
10411097
return updateData;
10421098
}
10431099

@@ -1937,24 +1993,38 @@ bool EntityComponentManagerPrivate::ClonedJointLinkName(Entity _joint,
19371993
return false;
19381994
}
19391995

1940-
auto iter = this->originalToClonedLink.find(_originalLink);
1941-
if (iter == this->originalToClonedLink.end())
1996+
Entity clonedLink = kNullEntity;
1997+
1998+
1999+
std::string name;
2000+
// Handle the case where the link coule have been the world.
2001+
if (_ecm->Component<components::World>(_originalLink) != nullptr)
19422002
{
1943-
ignerr << "Error: attempted to clone links, but link ["
1944-
<< _originalLink << "] was never cloned.\n";
1945-
return false;
2003+
// Use the special identifier "world".
2004+
name = "world";
19462005
}
1947-
auto clonedLink = iter->second;
1948-
1949-
auto name = _ecm->Component<components::Name>(clonedLink);
1950-
if (!name)
2006+
else
19512007
{
1952-
ignerr << "Link [" << _originalLink << "] was cloned, but its clone has no "
1953-
<< "name.\n";
1954-
return false;
2008+
auto iter = this->originalToClonedLink.find(_originalLink);
2009+
if (iter == this->originalToClonedLink.end())
2010+
{
2011+
ignerr << "Error: attempted to clone links, but link ["
2012+
<< _originalLink << "] was never cloned.\n";
2013+
return false;
2014+
}
2015+
clonedLink = iter->second;
2016+
2017+
auto nameComp = _ecm->Component<components::Name>(clonedLink);
2018+
if (!nameComp)
2019+
{
2020+
ignerr << "Link [" << _originalLink
2021+
<< "] was cloned, but its clone has no name.\n";
2022+
return false;
2023+
}
2024+
name = nameComp->Data();
19552025
}
19562026

1957-
_ecm->SetComponentData<ComponentTypeT>(_joint, name->Data());
2027+
_ecm->SetComponentData<ComponentTypeT>(_joint, name);
19582028
return true;
19592029
}
19602030

src/EntityComponentManager_TEST.cc

+30-15
Original file line numberDiff line numberDiff line change
@@ -2795,15 +2795,21 @@ TEST_P(EntityComponentManagerFixture, CloneEntities)
27952795
EXPECT_EQ(kNullEntity, failedClonedEntity);
27962796

27972797
// create a joint with a parent and child link
2798+
const std::string parentModelEntityName = "parentModelEntity";
27982799
const std::string parentLinkEntityName = "parentLinkEntity";
27992800
const std::string childLinkEntityName = "childLinkEntity";
2801+
Entity parentModelEntity = manager.CreateEntity();
2802+
manager.CreateComponent(parentModelEntity,
2803+
components::Name(parentModelEntityName));
28002804
Entity parentLinkEntity = manager.CreateEntity();
28012805
manager.CreateComponent(parentLinkEntity,
28022806
components::Name(parentLinkEntityName));
28032807
manager.CreateComponent(parentLinkEntity, components::CanonicalLink());
2808+
manager.CreateComponent(parentLinkEntity,
2809+
components::ParentEntity(parentModelEntity));
28042810
Entity jointEntity = manager.CreateEntity();
28052811
manager.CreateComponent(jointEntity,
2806-
components::ParentEntity(parentLinkEntity));
2812+
components::ParentEntity(parentModelEntity));
28072813
manager.CreateComponent(jointEntity, components::Name("jointEntity"));
28082814
manager.CreateComponent(jointEntity, components::Joint());
28092815
manager.CreateComponent(jointEntity,
@@ -2812,26 +2818,33 @@ TEST_P(EntityComponentManagerFixture, CloneEntities)
28122818
components::ChildLinkName(childLinkEntityName));
28132819
Entity childLinkEntity = manager.CreateEntity();
28142820
manager.CreateComponent(childLinkEntity,
2815-
components::ParentEntity(jointEntity));
2821+
components::ParentEntity(parentModelEntity));
28162822
manager.CreateComponent(childLinkEntity,
28172823
components::Name(childLinkEntityName));
28182824
manager.CreateComponent(childLinkEntity, components::Link());
2819-
EXPECT_EQ(13u, manager.EntityCount());
2825+
EXPECT_EQ(14u, manager.EntityCount());
28202826

28212827
// clone a joint that has a parent and child link.
2822-
auto clonedParentLinkEntity = manager.Clone(parentLinkEntity, kNullEntity,
2828+
auto clonedParentModelEntity = manager.Clone(parentModelEntity, kNullEntity,
28232829
"", true);
2824-
ASSERT_NE(kNullEntity, clonedParentLinkEntity);
2825-
EXPECT_EQ(16u, manager.EntityCount());
2826-
clonedEntities.insert(clonedParentLinkEntity);
2830+
ASSERT_NE(kNullEntity, clonedParentModelEntity);
2831+
// We just cloned a model with two links and a joint, a total of 4 new
2832+
// entities.
2833+
EXPECT_EQ(18u, manager.EntityCount());
2834+
clonedEntities.insert(clonedParentModelEntity);
28272835
auto clonedJoints = manager.EntitiesByComponents(
2828-
components::ParentEntity(clonedParentLinkEntity));
2836+
components::ParentEntity(clonedParentModelEntity), components::Joint());
28292837
ASSERT_EQ(1u, clonedJoints.size());
28302838
clonedEntities.insert(clonedJoints[0]);
28312839
auto clonedChildLinks = manager.EntitiesByComponents(
2832-
components::ParentEntity(clonedJoints[0]));
2840+
components::ParentEntity(clonedParentModelEntity), components::Link());
28332841
ASSERT_EQ(1u, clonedChildLinks.size());
28342842
clonedEntities.insert(clonedChildLinks[0]);
2843+
auto clonedChildCanonicalLinks = manager.EntitiesByComponents(
2844+
components::ParentEntity(clonedParentModelEntity),
2845+
components::CanonicalLink());
2846+
ASSERT_EQ(1u, clonedChildCanonicalLinks.size());
2847+
clonedEntities.insert(clonedChildCanonicalLinks[0]);
28352848

28362849
// The cloned joint should have the cloned parent/child link names attached to
28372850
// it, not the original parent/child link names
@@ -2843,17 +2856,19 @@ TEST_P(EntityComponentManagerFixture, CloneEntities)
28432856
manager.Component<components::ChildLinkName>(clonedJoints[0]);
28442857
ASSERT_NE(nullptr, clonedJointChildLinkName);
28452858
EXPECT_NE(clonedJointChildLinkName->Data(), childLinkEntityName);
2846-
auto clonedParentLinkName =
2847-
manager.Component<components::Name>(clonedParentLinkEntity);
2848-
ASSERT_NE(nullptr, clonedParentLinkName);
2849-
EXPECT_EQ(clonedParentLinkName->Data(), clonedJointParentLinkName->Data());
2859+
auto clonedParentModelName =
2860+
manager.Component<components::Name>(clonedParentModelEntity);
2861+
ASSERT_NE(nullptr, clonedParentModelName);
2862+
auto clonedJointParentModelName = manager.Component<components::Name>(
2863+
manager.Component<components::ParentEntity>(clonedJoints[0])->Data());
2864+
EXPECT_EQ(clonedParentModelName->Data(), clonedJointParentModelName->Data());
28502865
auto clonedChildLinkName =
28512866
manager.Component<components::Name>(clonedChildLinks[0]);
28522867
ASSERT_NE(nullptr, clonedChildLinkName);
28532868
EXPECT_EQ(clonedJointChildLinkName->Data(), clonedChildLinkName->Data());
28542869

28552870
// make sure that the name given to each cloned entity is unique
2856-
EXPECT_EQ(8u, clonedEntities.size());
2871+
EXPECT_EQ(9u, clonedEntities.size());
28572872
for (const auto &entity : clonedEntities)
28582873
{
28592874
auto nameComp = manager.Component<components::Name>(entity);
@@ -2864,7 +2879,7 @@ TEST_P(EntityComponentManagerFixture, CloneEntities)
28642879
// try to clone an entity that does not exist
28652880
EXPECT_EQ(kNullEntity, manager.Clone(kNullEntity, topLevelEntity, "",
28662881
allowRename));
2867-
EXPECT_EQ(16u, manager.EntityCount());
2882+
EXPECT_EQ(18u, manager.EntityCount());
28682883
}
28692884

28702885
/////////////////////////////////////////////////

0 commit comments

Comments
 (0)