Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
cd8efc1
add support for models of the same name
arjo129 Oct 8, 2021
b072901
codecheck
arjo129 Oct 8, 2021
5fb5a74
Add unit test
arjo129 Oct 8, 2021
c42aa0b
Merge branch 'ign-gazebo6' into arjo/fix/detachable_joint
arjo129 Oct 8, 2021
0bf387d
Address some feedback
arjo129 Oct 12, 2021
102e93d
Merge branch 'arjo/fix/detachable_joint' of github.com:ignitionroboti…
arjo129 Oct 12, 2021
a4cd125
Merge branch 'ign-gazebo6' into arjo/fix/detachable_joint
chapulina Nov 16, 2021
c8aec3f
🎈 3.15.1 (#2279)
mjcarroll Jan 5, 2024
a3e9f8d
Setup rendering environment before cmake runs (#1965)
azeey Mar 25, 2024
07e5d9c
Fix bug where iterator was used after the underlying item was erased …
azeey May 24, 2024
2bcfe0e
Merge 3 into 6
azeey Jul 9, 2024
894bce1
Merge pull request #2470 from azeey/3_to_6
azeey Jul 10, 2024
9d35f5c
Address a few Windows CI Issues (#1911)
mjcarroll Mar 3, 2023
a2a9c53
Fix DLL linkage/visibility issues (#2254)
mjcarroll Nov 22, 2023
9277c0b
backport lidar visualization frame_id fix
iche033 Jul 17, 2024
9891844
Disable failing testFixture_TEST for MacOS (#2499)
Crola1702 Jul 26, 2024
fb25971
Remove systems if their parent entity is removed (#2232)
arjo129 Jul 17, 2024
67cf543
Initialize threadsNeedCleanUp (#2503)
shameekganguly Jul 31, 2024
96dddad
Fix shader param test
iche033 Aug 2, 2024
2310050
Merge branch 'ign-gazebo6' into arjo/fix/detachable_joint
arjo129 Aug 7, 2024
45f6dc3
Update test files
arjo129 Aug 7, 2024
13f5c93
Fix tests
arjo129 Aug 7, 2024
2ae65a3
Use `scopedName` to support grandchildren as well.
arjo129 Aug 7, 2024
e8e1b16
Address Feedback
arjo129 Aug 12, 2024
a5c9cb6
Better logging
arjo129 Aug 12, 2024
19bdc85
Clean up tests.
arjo129 Aug 12, 2024
1a7083d
Refactor out link discovery into a new function
arjo129 Aug 13, 2024
d2e991c
Style
arjo129 Aug 13, 2024
6fa7157
Style
arjo129 Aug 13, 2024
5bf9bf5
Merge pull request #1097 from gazebosim/arjo/fix/detachable_joint
shameekganguly Aug 13, 2024
c3f271c
Disable detachable_joint integration test case on Windows (#2523)
shameekganguly Aug 13, 2024
a7ea4ac
check valid pointer (#2674) (#2675)
mergify[bot] Nov 12, 2024
8022579
Improve load times by skipping serialization of entities when unecess…
mergify[bot] Nov 20, 2024
0d3af5b
Fix uncontrolled cast of size_t to uint (#2687)
j-rivero Nov 27, 2024
5384cd8
Add parameter for adjust current sign in battery plugin (#2696)
Tacha-S Dec 17, 2024
d9b18d8
Preparation for 6.17.0 release (#2712)
j-rivero Jan 13, 2025
2f1c49f
Fix mesh import filters not displaying correctly on KDE #2731 (#2732)…
mergify[bot] Jan 27, 2025
36c1533
Reduce/Eliminate `sdf::Model` and `sdf::World` serialization warnings…
azeey Jan 31, 2025
cb6fa87
Also handle SIGTERM gracefully (#2747) (#2757)
mergify[bot] Mar 13, 2025
5e31757
Set IGN_IP=127.0.0.1 in cmd tests (#2959)
scpeters Jun 26, 2025
b2a9022
Assign new gz-sim maintainer (#3008)
azeey Aug 6, 2025
b90dd72
Add missing algorithm include (#3022)
nim65s Aug 9, 2025
b2fc6de
Merge 6 into 8
azeey Aug 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -1609,6 +1609,68 @@

## Gazebo Sim 6.x

### Gazebo Sim 6.17.0 (2025-01-10)

1. Add parameter for adjust current sign in battery plugin
* [Pull request #2696](https://github.com/gazebosim/gz-sim/pull/2696)

1. Fix uncontrolled cast of size_t to uint
* [Pull request #2687](https://github.com/gazebosim/gz-sim/pull/2687)

1. Improve load times by skipping serialization of entities when unecessary
* [Pull request #2596](https://github.com/gazebosim/gz-sim/pull/2596)

1. Fix crash in OpticalTactilePlugin by checking for valid visualize pointer
* [Pull request #2674](https://github.com/gazebosim/gz-sim/pull/2674)

1. Disable detachable_joint integration test case on Windows
* [Pull request #2523](https://github.com/gazebosim/gz-sim/pull/2523)

1. Initialize threadsNeedCleanUp
* [Pull request #2503](https://github.com/gazebosim/gz-sim/pull/2503)

1. Remove systems if their parent entity is removed
* [Pull request #2232](https://github.com/gazebosim/gz-sim/pull/2232)

1. Disable failing testFixture_TEST for MacOS
* [Pull request #2499](https://github.com/gazebosim/gz-sim/pull/2499)

1. backport lidar visualization frame_id fix
* [Pull request #2483](https://github.com/gazebosim/gz-sim/pull/2483)

1. Fix DLL linkage/visibility issues
* [Pull request #2254](https://github.com/gazebosim/gz-sim/pull/2254)

1. Address a few Windows CI Issues
* [Pull request #1911](https://github.com/gazebosim/gz-sim/pull/1911)

1. Add GravityEnabled boolean component
* [Pull request #2451](https://github.com/gazebosim/gz-sim/pull/2451)

1. Add support for no gravity link
* [Pull request #2398](https://github.com/gazebosim/gz-sim/pull/2398)

1. Use VERSION_GREATER_EQUAL in cmake logic
* [Pull request #2418](https://github.com/gazebosim/gz-sim/pull/2418)

1. Rephrase cmake comment about CMP0077
* [Pull request #2419](https://github.com/gazebosim/gz-sim/pull/2419)

1. Fix bug where iterator was used after the underlying item was erased from the container
* [Pull request #2412](https://github.com/gazebosim/gz-sim/pull/2412)

1. Fix namespace and class links in documentation references that use namespace `gz`
* [Pull request #2385](https://github.com/gazebosim/gz-sim/pull/2385)

1. Fix ModelPhotoShootTest test failures
* [Pull request #2294](https://github.com/gazebosim/gz-sim/pull/2294)

1. Setup rendering environment before cmake runs
* [Pull request #1965](https://github.com/gazebosim/gz-sim/pull/1965)

1. Detachable joint: support for nested models of the same name
* [Pull request 1097](https://github.com/gazebosim/gz-sim/pull/1097)

### Gazebo Sim 6.16.0 (2024-01-12)

1. Allow using plugin file names and environment variables compatible with Garden and later
Expand Down
4 changes: 2 additions & 2 deletions examples/worlds/shader_param.sdf
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,12 @@ ShaderParam visual plugin over time.
<include>
<name>deformable_sphere</name>
<pose>0 0 1.5 0 0 0</pose>
<uri>https://fuel.gazebosim.org/1.0/openrobotics/models/deformable_sphere</uri>
<uri>https://fuel.gazebosim.org/1.0/openrobotics/models/deformable_sphere/5</uri>
</include>
<include>
<name>waves</name>
<pose>0 0 0 0 0 0</pose>
<uri>https://fuel.gazebosim.org/1.0/openrobotics/models/waves</uri>
<uri>https://fuel.gazebosim.org/1.0/openrobotics/models/waves/4</uri>
</include>

<model name="camera">
Expand Down
148 changes: 109 additions & 39 deletions src/systems/detachable_joint/DetachableJoint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,97 @@ void DetachableJoint::Configure(const Entity &_entity,
.first;

this->validConfig = true;

this->GetChildModelAndLinkEntities(_ecm);
}

//////////////////////////////////////////////////
void DetachableJoint::GetChildModelAndLinkEntities(
EntityComponentManager &_ecm)
{
this->childLinkEntity = kNullEntity;
// Look for the child model and link
Entity modelEntity{kNullEntity};

if ("__model__" == this->childModelName)
{
modelEntity = this->model.Entity();
}
else
{
auto entitiesMatchingName = entitiesFromScopedName(
this->childModelName, _ecm);

// TODO(arjoc): There is probably a more efficient way of combining entitiesFromScopedName
// With filtering.
// Filter for entities with only models
std::vector<Entity> candidateEntities;
std::copy_if(entitiesMatchingName.begin(), entitiesMatchingName.end(),
std::back_inserter(candidateEntities),
[&_ecm](Entity e) { return _ecm.EntityHasComponentType(e, components::Model::typeId); });

if (candidateEntities.size() == 1)
{
// If there is one entity select that entity itself
modelEntity = *candidateEntities.begin();
}
else
{
std::string selectedModelName;
auto parentEntityScopedPath = scopedName(this->model.Entity(), _ecm);
// If there is more than one model with the given child model name, the plugin looks for a model which is
// - a descendant of the plugin's parent model with that name, and
// - has a child link with the given child link name
for (auto entity : candidateEntities)
{
auto childEntityScope = scopedName(entity, _ecm);
if (childEntityScope.size() < parentEntityScopedPath.size())
{
continue;
}
if (childEntityScope.rfind(parentEntityScopedPath, 0) != 0)
{
continue;
}
if (modelEntity == kNullEntity)
{

this->childLinkEntity = _ecm.EntityByComponents(
components::Link(), components::ParentEntity(entity),
components::Name(this->childLinkName));

if (kNullEntity != this->childLinkEntity)
{
// Only select this child model entity if the entity has a link with the given child link name
modelEntity = entity;
selectedModelName = childEntityScope;
gzdbg << "Selecting " << childEntityScope << " as model to be detached" << std::endl;
}
else
{
gzwarn << "Found " << childEntityScope << " with no link named " << this->childLinkName << std::endl;
}
}
else
{
gzwarn << "Found multiple models skipping " << childEntityScope
<< "Using " << selectedModelName << " instead" << std::endl;
}
}
}
}
if (kNullEntity != modelEntity)
{
this->childLinkEntity = _ecm.EntityByComponents(
components::Link(), components::ParentEntity(modelEntity),
components::Name(this->childLinkName));
}
else if (!this->suppressChildWarning)
{
gzwarn << "Child Model " << this->childModelName
<< " could not be found.\n";
}
}
//////////////////////////////////////////////////
void DetachableJoint::PreUpdate(
const UpdateInfo &/*_info*/,
Expand All @@ -225,54 +314,35 @@ void DetachableJoint::PreUpdate(
if (!this->attachRequested){
return;
}
// Look for the child model and link
Entity modelEntity{kNullEntity};

if ("__model__" == this->childModelName)
if (this->childLinkEntity == kNullEntity || !_ecm.HasEntity(this->childLinkEntity))
this->GetChildModelAndLinkEntities(_ecm);

if (kNullEntity != this->childLinkEntity)
{
modelEntity = this->model.Entity();
// Attach the models
// We do this by creating a detachable joint entity.
this->detachableJointEntity = _ecm.CreateEntity();

_ecm.CreateComponent(
this->detachableJointEntity,
components::DetachableJoint({this->parentLinkEntity,
this->childLinkEntity, "fixed"}));
this->attachRequested = false;
this->isAttached = true;
this->PublishJointState(this->isAttached);
gzdbg << "Attaching entity: " << this->detachableJointEntity
<< std::endl;
}
else
{
modelEntity = _ecm.EntityByComponents(
components::Model(), components::Name(this->childModelName));
}
if (kNullEntity != modelEntity)
{
this->childLinkEntity = _ecm.EntityByComponents(
components::Link(), components::ParentEntity(modelEntity),
components::Name(this->childLinkName));

if (kNullEntity != this->childLinkEntity)
{
// Attach the models
// We do this by creating a detachable joint entity.
this->detachableJointEntity = _ecm.CreateEntity();

_ecm.CreateComponent(
this->detachableJointEntity,
components::DetachableJoint({this->parentLinkEntity,
this->childLinkEntity, "fixed"}));
this->attachRequested = false;
this->isAttached = true;
this->PublishJointState(this->isAttached);
gzdbg << "Attaching entity: " << this->detachableJointEntity
<< std::endl;
}
else
{
gzwarn << "Child Link " << this->childLinkName
<< " could not be found.\n";
}
}
else if (!this->suppressChildWarning)
{
gzwarn << "Child Model " << this->childModelName
gzwarn << "Child Link " << this->childLinkName
<< " could not be found.\n";
}

}

// only allow detaching if child entity is attached
// only allow detaching if child entity is attached
if (this->isAttached)
{
if (this->detachRequested && (kNullEntity != this->detachableJointEntity))
Expand Down
4 changes: 4 additions & 0 deletions src/systems/detachable_joint/DetachableJoint.hh
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ namespace systems
/// \brief Callback for detach request topic
private: void OnDetachRequest(const msgs::Empty &_msg);

/// \brief Retrieve the relevant link entity
private: void GetChildModelAndLinkEntities(
gz::sim::EntityComponentManager &_ecm);

/// \brief The model associated with this system.
private: Model model;

Expand Down
80 changes: 78 additions & 2 deletions test/integration/detachable_joint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ TEST_F(DetachableJointTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(StartConnected))
{
using namespace std::chrono_literals;

this->StartServer("/test/worlds/detachable_joint.sdf");
this->StartServer(common::joinPaths("/test", "worlds",
"detachable_joint.sdf"));

// A lambda that takes a model name and a mutable reference to a vector of
// poses and returns another lambda that can be passed to
Expand Down Expand Up @@ -145,7 +146,8 @@ TEST_F(DetachableJointTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(LinksInSameModel))
{
using namespace std::chrono_literals;

this->StartServer("/test/worlds/detachable_joint.sdf");
this->StartServer(common::joinPaths("/test", "worlds",
"detachable_joint.sdf"));

// A lambda that takes a model name and a mutable reference to a vector of
// poses and returns another lambda that can be passed to
Expand Down Expand Up @@ -218,6 +220,80 @@ TEST_F(DetachableJointTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(LinksInSameModel))
EXPECT_GT(b2Poses.front().Pos().Z() - b2Poses.back().Pos().Z(), expDist);
}

/////////////////////////////////////////////////
TEST_F(DetachableJointTest,
GZ_UTILS_TEST_DISABLED_ON_WIN32(NestedModelsWithSameName))
{
using namespace std::chrono_literals;

this->StartServer(common::joinPaths("/test", "worlds",
"detachable_joint_child.sdf"));


std::vector<math::Pose3d> childM4Poses, childM5Poses;
test::Relay testSystem1;
testSystem1.OnPostUpdate([&childM4Poses, &childM5Poses](
const sim::UpdateInfo &,
const sim::EntityComponentManager &_ecm)
{
auto childModels = _ecm.EntitiesByComponents(
components::Model(), components::Name("child_model"));

auto entityM5 = _ecm.EntityByComponents(
components::Model(), components::Name("M5"));

Model modelM5(entityM5);
auto childModelsM5 = modelM5.Models(_ecm);

Entity childEntityM5{kNullEntity}, childEntityM4{kNullEntity};
for(auto entity : childModelsM5)
{
if (entity == childModels[0])
{
childEntityM5 = childModels[0];
childEntityM4 = childModels[1];
}
if (entity == childModels[1])
{
childEntityM5 = childModels[1];
childEntityM4 = childModels[0];
}
}

Model childModelM4(childEntityM4);
Model childModelM5(childEntityM5);

auto poseM4 = _ecm.Component<components::Pose>(childEntityM4);
auto poseM5 = _ecm.Component<components::Pose>(childEntityM5);

childM4Poses.push_back(poseM4->Data());
childM5Poses.push_back(poseM5->Data());
}
);

this->server->AddSystem(testSystem1.systemPtr);

const std::size_t nIters{20};
this->server->Run(true, nIters, false);

// Children of model4 and model5 should not move as they are held
// in place
EXPECT_EQ(childM4Poses.front(), childM4Poses.back());
EXPECT_EQ(childM5Poses.front(), childM5Poses.back());

// Release M5's child only
transport::Node node;
auto pub = node.Advertise<msgs::Empty>("/model/M5/detachable_joint/detach");
pub.Publish(msgs::Empty());
std::this_thread::sleep_for(250ms);

this->server->Run(true, nIters, false);
// M5 and M4 start at the same height
// Only M5 should fall.
EXPECT_LT(childM5Poses.back().Z(), childM4Poses.back().Z());
EXPECT_LT(childM5Poses.back().Z(), childM5Poses.front().Z());
EXPECT_EQ(childM4Poses.front(), childM4Poses.back());
}
/////////////////////////////////////////////////
// Test for re-attaching a detached joint. This uses the vehicle_blue and B1
// box models. The B1 model is first detached from the vehicle. Although
Expand Down
Loading
Loading