Skip to content

Commit 2cdd4fe

Browse files
committed
Distributed: Add LevelDebug system
- Use update info and performer affinity to control update. - Display model properties. Signed-off-by: Rhys Mainwaring <[email protected]>
1 parent e7a97b3 commit 2cdd4fe

File tree

4 files changed

+237
-0
lines changed

4 files changed

+237
-0
lines changed

src/systems/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ add_subdirectory(joint_traj_control)
114114
add_subdirectory(kinetic_energy_monitor)
115115
add_subdirectory(label)
116116
add_subdirectory(lens_flare)
117+
add_subdirectory(level_debug)
117118
add_subdirectory(lift_drag)
118119
add_subdirectory(lighter_than_air_dynamics)
119120
add_subdirectory(log)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
gz_add_system(level-debug
2+
SOURCES
3+
LevelDebug.cc
4+
)
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Copyright (C) 2019 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+
18+
#include "LevelDebug.hh"
19+
20+
#include <cmath>
21+
#include <string>
22+
#include <vector>
23+
24+
#include <gz/common/Profiler.hh>
25+
#include <gz/plugin/Register.hh>
26+
#include <gz/transport/Node.hh>
27+
28+
#include <sdf/Element.hh>
29+
30+
#include "gz/sim/Model.hh"
31+
#include "gz/sim/Util.hh"
32+
33+
#include "gz/sim/components/Model.hh"
34+
#include "gz/sim/components/Name.hh"
35+
#include "gz/sim/components/Performer.hh"
36+
#include "gz/sim/components/PerformerAffinity.hh"
37+
#include "gz/sim/components/PerformerLevels.hh"
38+
39+
using namespace gz;
40+
using namespace sim;
41+
using namespace systems;
42+
43+
class gz::sim::systems::LevelDebugPrivate
44+
{
45+
/// \brief Model interface
46+
public: Model model{kNullEntity};
47+
};
48+
49+
//////////////////////////////////////////////////
50+
LevelDebug::LevelDebug()
51+
: System(), dataPtr(std::make_unique<LevelDebugPrivate>())
52+
{
53+
}
54+
55+
//////////////////////////////////////////////////
56+
void LevelDebug::Configure(const Entity &_entity,
57+
const std::shared_ptr<const sdf::Element> &/*_sdf*/,
58+
EntityComponentManager &_ecm,
59+
EventManager &/*_eventMgr*/)
60+
{
61+
this->dataPtr->model = Model(_entity);
62+
63+
if (!this->dataPtr->model.Valid(_ecm))
64+
{
65+
gzerr << "The LevelDebug system should be attached to a model entity. "
66+
<< "Failed to initialize." << std::endl;
67+
return;
68+
}
69+
}
70+
71+
//////////////////////////////////////////////////
72+
void LevelDebug::PreUpdate(const UpdateInfo &_info,
73+
EntityComponentManager &_ecm)
74+
{
75+
GZ_PROFILE("LevelDebug::PreUpdate");
76+
77+
//! @todo - all of these checks could be run at load
78+
// and re-run only of the affinity changes. The expensive
79+
// check for ChildrenByComponents only needs to run at configure/load.
80+
81+
std::string modelName = this->dataPtr->model.Name(_ecm);
82+
83+
if (_info.secondaryNamespace.empty())
84+
{
85+
gzmsg << "System is not a NetworkManagerSecondary"
86+
<< std::endl;
87+
return;
88+
}
89+
90+
// Is this model a performer?
91+
//! @note expensive - returns a std::vector by value. Move to Configure.
92+
auto performerEntities = _ecm.ChildrenByComponents(
93+
this->dataPtr->model.Entity(), components::Performer());
94+
95+
if (performerEntities.empty())
96+
{
97+
gzmsg << "Model: [" << modelName << "] "
98+
<< "is not a performer" << std::endl;
99+
return;
100+
}
101+
102+
if (performerEntities.size() > 1)
103+
{
104+
gzerr << "Model: [" << modelName << "] "
105+
<< "is associated with performers" << std::endl;
106+
return;
107+
}
108+
109+
auto performerEntity = performerEntities[0];
110+
auto performerAffinity =
111+
_ecm.Component<components::PerformerAffinity>(performerEntity);
112+
113+
auto performerRef = _ecm.Component<components::PerformerRef>(performerEntity);
114+
auto PerformerLevels = _ecm.Component<components::PerformerLevels>(performerEntity);
115+
auto performerName = _ecm.Component<components::Name>(performerEntity);
116+
117+
if (performerName == nullptr || performerRef == nullptr)
118+
{
119+
gzerr << "Model: [" << modelName << "] "
120+
<< "has an incorrectly configured performer"
121+
<< std::endl;
122+
return;
123+
}
124+
125+
if (performerAffinity == nullptr ||
126+
performerAffinity->Data() != _info.secondaryNamespace)
127+
{
128+
gzmsg << "Model: [" << modelName << "] "
129+
<< "is not updated by Secondary: ["
130+
<< _info.secondaryNamespace << "]"
131+
<< std::endl;
132+
return;
133+
}
134+
135+
{
136+
gzmsg << "Name: [" << performerName->Data() << "] "
137+
<< std::endl;
138+
}
139+
140+
{
141+
gzmsg << "Ref: [" << performerRef->Data() << "] "
142+
<< std::endl;
143+
}
144+
145+
{
146+
gzmsg << "Affinity: [" << performerAffinity->Data() << "] "
147+
<< std::endl;
148+
}
149+
150+
// List all the model components in this ECM instance
151+
gzmsg << "All Models:" << std::endl;
152+
auto modelEntities = _ecm.EntitiesByComponents(components::Model());
153+
for (const auto &entity : modelEntities)
154+
{
155+
auto model = Model(entity);
156+
auto name = model.Name(_ecm);
157+
gzmsg << "[" << entity << "] " << name << std::endl;
158+
}
159+
}
160+
161+
GZ_ADD_PLUGIN(LevelDebug,
162+
System,
163+
LevelDebug::ISystemConfigure,
164+
LevelDebug::ISystemPreUpdate)
165+
166+
GZ_ADD_PLUGIN_ALIAS(LevelDebug, "gz::sim::systems::LevelDebug")
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (C) 2025 Rhys Mainwaring
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+
18+
#ifndef GZ_SIM_SYSTEMS_LEVEL_DEBUG_HH_
19+
#define GZ_SIM_SYSTEMS_LEVEL_DEBUG_HH_
20+
21+
#include <memory>
22+
#include <gz/sim/System.hh>
23+
24+
namespace gz
25+
{
26+
namespace sim
27+
{
28+
// Inline bracket to help doxygen filtering.
29+
inline namespace GZ_SIM_VERSION_NAMESPACE {
30+
namespace systems
31+
{
32+
// Forward declaration
33+
class LevelDebugPrivate;
34+
35+
/// \brief The LevelDebug system prints entity properties.
36+
///
37+
class LevelDebug
38+
: public System,
39+
public ISystemConfigure,
40+
public ISystemPreUpdate
41+
{
42+
/// \brief Constructor
43+
public: LevelDebug();
44+
45+
/// \brief Destructor
46+
public: ~LevelDebug() override = default;
47+
48+
// Documentation inherited
49+
public: void Configure(const Entity &_entity,
50+
const std::shared_ptr<const sdf::Element> &_sdf,
51+
EntityComponentManager &_ecm,
52+
EventManager &_eventMgr) override;
53+
54+
/// Documentation inherited
55+
public: void PreUpdate(const UpdateInfo &_info,
56+
EntityComponentManager &_ecm) final;
57+
58+
/// \brief Private data pointer
59+
private: std::unique_ptr<LevelDebugPrivate> dataPtr;
60+
};
61+
}
62+
}
63+
}
64+
}
65+
66+
#endif

0 commit comments

Comments
 (0)