2
* Copyright (C) 2019 Open Source Robotics Foundation
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
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
18
#include <ignition/common/Console.hh>
19
#include <ignition/common/Profiler.hh>
20
#include <sdf/Types.hh>
22
#include "ignition/gazebo/Events.hh"
23
#include "ignition/gazebo/SdfEntityCreator.hh"
25
#include "ignition/gazebo/components/Actor.hh"
26
#include "ignition/gazebo/components/AirPressureSensor.hh"
27
#include "ignition/gazebo/components/Altimeter.hh"
28
#include "ignition/gazebo/components/AngularVelocity.hh"
29
#include "ignition/gazebo/components/Atmosphere.hh"
30
#include "ignition/gazebo/components/Camera.hh"
31
#include "ignition/gazebo/components/CanonicalLink.hh"
32
#include "ignition/gazebo/components/CastShadows.hh"
33
#include "ignition/gazebo/components/ChildLinkName.hh"
34
#include "ignition/gazebo/components/Collision.hh"
35
#include "ignition/gazebo/components/ContactSensor.hh"
36
#include "ignition/gazebo/components/CustomSensor.hh"
37
#include "ignition/gazebo/components/DepthCamera.hh"
38
#include "ignition/gazebo/components/ForceTorque.hh"
39
#include "ignition/gazebo/components/Geometry.hh"
40
#include "ignition/gazebo/components/GpuLidar.hh"
41
#include "ignition/gazebo/components/Gravity.hh"
42
#include "ignition/gazebo/components/Imu.hh"
43
#include "ignition/gazebo/components/Inertial.hh"
44
#include "ignition/gazebo/components/Joint.hh"
45
#include "ignition/gazebo/components/JointAxis.hh"
46
#include "ignition/gazebo/components/JointType.hh"
47
#include "ignition/gazebo/components/LaserRetro.hh"
48
#include "ignition/gazebo/components/Lidar.hh"
49
#include "ignition/gazebo/components/Light.hh"
50
#include "ignition/gazebo/components/LightType.hh"
51
#include "ignition/gazebo/components/LinearAcceleration.hh"
52
#include "ignition/gazebo/components/LinearVelocity.hh"
53
#include "ignition/gazebo/components/Link.hh"
54
#include "ignition/gazebo/components/LogicalCamera.hh"
55
#include "ignition/gazebo/components/MagneticField.hh"
56
#include "ignition/gazebo/components/Magnetometer.hh"
57
#include "ignition/gazebo/components/Material.hh"
58
#include "ignition/gazebo/components/Model.hh"
59
#include "ignition/gazebo/components/Name.hh"
60
#include "ignition/gazebo/components/NavSat.hh"
61
#include "ignition/gazebo/components/ParentLinkName.hh"
62
#include "ignition/gazebo/components/ParentEntity.hh"
63
#include <ignition/gazebo/components/ParticleEmitter.hh>
64
#include "ignition/gazebo/components/Physics.hh"
65
#include "ignition/gazebo/components/Pose.hh"
66
#include "ignition/gazebo/components/RgbdCamera.hh"
67
#include "ignition/gazebo/components/Scene.hh"
68
#include "ignition/gazebo/components/SegmentationCamera.hh"
69
#include "ignition/gazebo/components/SelfCollide.hh"
70
#include "ignition/gazebo/components/Sensor.hh"
71
#include "ignition/gazebo/components/SourceFilePath.hh"
72
#include "ignition/gazebo/components/SphericalCoordinates.hh"
73
#include "ignition/gazebo/components/Static.hh"
74
#include "ignition/gazebo/components/ThermalCamera.hh"
75
#include "ignition/gazebo/components/ThreadPitch.hh"
76
#include "ignition/gazebo/components/Transparency.hh"
77
#include "ignition/gazebo/components/Visibility.hh"
78
#include "ignition/gazebo/components/Visual.hh"
79
#include "ignition/gazebo/components/WindMode.hh"
80
#include "ignition/gazebo/components/World.hh"
82
class ignition::gazebo::SdfEntityCreatorPrivate
84
/// \brief Pointer to entity component manager. We don't assume ownership.
85
public: EntityComponentManager *ecm{nullptr};
87
/// \brief Pointer to event manager. We don't assume ownership.
88
public: EventManager *eventManager{nullptr};
90
/// \brief Keep track of new sensors being added, so we load their plugins
91
/// only after we have their scoped name.
92
public: std::map<Entity, sdf::ElementPtr> newSensors;
94
/// \brief Keep track of new models being added, so we load their plugins
95
/// only after we have their scoped name.
96
public: std::map<Entity, sdf::ElementPtr> newModels;
98
/// \brief Keep track of new visuals being added, so we load their plugins
99
/// only after we have their scoped name.
100
public: std::map<Entity, sdf::ElementPtr> newVisuals;
103
using namespace ignition;
104
using namespace gazebo;
106
/////////////////////////////////////////////////
107
/// \brief Resolve the pose of an SDF DOM object with respect to its relative_to
108
/// frame. If that fails, return the raw pose
109
static math::Pose3d ResolveSdfPose(const sdf::SemanticPose &_semPose)
112
::sdf::Errors errors = _semPose.Resolve(pose);
115
pose = _semPose.RawPose();
121
/////////////////////////////////////////////////
122
static std::optional<sdf::JointAxis> ResolveJointAxis(
123
const sdf::JointAxis &_unresolvedAxis)
125
math::Vector3d axisXyz;
126
const sdf::Errors resolveAxisErrors = _unresolvedAxis.ResolveXyz(axisXyz);
127
if (!resolveAxisErrors.empty())
129
ignerr << "Failed to resolve axis" << std::endl;
133
sdf::JointAxis resolvedAxis = _unresolvedAxis;
135
const sdf::Errors setXyzErrors = resolvedAxis.SetXyz(axisXyz);
136
if (!setXyzErrors.empty())
138
ignerr << "Failed to resolve axis" << std::endl;
142
resolvedAxis.SetXyzExpressedIn("");
146
//////////////////////////////////////////////////
147
/// \brief Find a descendent child link entity by name.
148
/// \param[in] _name The relative name of the link with "::" as the scope
150
/// \param[in] _model Model entity that defines the scope
151
/// \param[in] _ecm Entity component manager
152
/// \return The Entity of the descendent link or kNullEntity if link was not
154
static Entity FindDescendentLinkEntityByName(const std::string &_name,
155
const Entity &_model,
156
const EntityComponentManager &_ecm)
158
auto ind = _name.find(sdf::kSdfScopeDelimiter);
159
std::vector<Entity> candidates;
160
if (ind != std::string::npos)
162
candidates = _ecm.ChildrenByComponents(
163
_model, components::Model(), components::Name(_name.substr(0, ind)));
164
if (candidates.size() != 1 || (ind + 2 >= _name.size()))
168
return FindDescendentLinkEntityByName(_name.substr(ind + 2),
169
candidates.front(), _ecm);
173
candidates = _ecm.ChildrenByComponents(_model, components::Link(),
174
components::Name(_name));
176
if (candidates.size() != 1)
180
return candidates.front();
184
//////////////////////////////////////////////////
185
SdfEntityCreator::SdfEntityCreator(EntityComponentManager &_ecm,
186
EventManager &_eventManager)
187
: dataPtr(std::make_unique<SdfEntityCreatorPrivate>())
189
this->dataPtr->ecm = &_ecm;
190
this->dataPtr->eventManager = &_eventManager;
193
/////////////////////////////////////////////////
194
SdfEntityCreator::SdfEntityCreator(const SdfEntityCreator &_creator)
195
: dataPtr(std::make_unique<SdfEntityCreatorPrivate>(*_creator.dataPtr))
199
/////////////////////////////////////////////////
200
SdfEntityCreator::SdfEntityCreator(SdfEntityCreator &&_creator) noexcept
203
//////////////////////////////////////////////////
204
SdfEntityCreator::~SdfEntityCreator() = default;
206
/////////////////////////////////////////////////
207
SdfEntityCreator &SdfEntityCreator::operator=(const SdfEntityCreator &_creator)
209
*this->dataPtr = (*_creator.dataPtr);
213
/////////////////////////////////////////////////
214
SdfEntityCreator &SdfEntityCreator::operator=(SdfEntityCreator &&_creator)
217
//////////////////////////////////////////////////
218
Entity SdfEntityCreator::CreateEntities(const sdf::World *_world)
220
IGN_PROFILE("SdfEntityCreator::CreateEntities(sdf::World)");
223
Entity worldEntity = this->dataPtr->ecm->CreateEntity();
226
this->dataPtr->ecm->CreateComponent(worldEntity, components::World());
227
this->dataPtr->ecm->CreateComponent(worldEntity,
228
components::Name(_world->Name()));
233
this->dataPtr->ecm->CreateComponent(worldEntity,
234
components::Scene(*_world->Scene()));
238
if (_world->Atmosphere())
240
this->dataPtr->ecm->CreateComponent(worldEntity,
241
components::Atmosphere(*_world->Atmosphere()));
244
// spherical coordinates
245
if (_world->SphericalCoordinates())
247
this->dataPtr->ecm->CreateComponent(worldEntity,
248
components::SphericalCoordinates(*_world->SphericalCoordinates()));
252
for (uint64_t modelIndex = 0; modelIndex < _world->ModelCount();
255
auto model = _world->ModelByIndex(modelIndex);
256
auto modelEntity = this->CreateEntities(model);
258
this->SetParent(modelEntity, worldEntity);
262
for (uint64_t actorIndex = 0; actorIndex < _world->ActorCount();
265
auto actor = _world->ActorByIndex(actorIndex);
266
auto actorEntity = this->CreateEntities(actor);
268
this->SetParent(actorEntity, worldEntity);
272
for (uint64_t lightIndex = 0; lightIndex < _world->LightCount();
275
auto light = _world->LightByIndex(lightIndex);
276
auto lightEntity = this->CreateEntities(light);
278
this->SetParent(lightEntity, worldEntity);
282
this->dataPtr->ecm->CreateComponent(worldEntity,
283
components::Gravity(_world->Gravity()));
286
// \todo(anyone) Support picking a specific physics profile
287
auto physics = _world->PhysicsByIndex(0);
290
physics = _world->PhysicsDefault();
292
this->dataPtr->ecm->CreateComponent(worldEntity,
293
components::Physics(*physics));
295
// Populate physics options that aren't accessible outside the Element()
296
// See https://github.com/osrf/sdformat/issues/508
297
if (physics->Element() && physics->Element()->HasElement("dart"))
299
auto dartElem = physics->Element()->GetElement("dart");
301
if (dartElem->HasElement("collision_detector"))
303
auto collisionDetector =
304
dartElem->Get<std::string>("collision_detector");
306
this->dataPtr->ecm->CreateComponent(worldEntity,
307
components::PhysicsCollisionDetector(collisionDetector));
309
if (dartElem->HasElement("solver") &&
310
dartElem->GetElement("solver")->HasElement("solver_type"))
313
dartElem->GetElement("solver")->Get<std::string>("solver_type");
315
this->dataPtr->ecm->CreateComponent(worldEntity,
316
components::PhysicsSolver(solver));
321
this->dataPtr->ecm->CreateComponent(worldEntity,
322
components::MagneticField(_world->MagneticField()));
324
this->dataPtr->eventManager->Emit<events::LoadPlugins>(worldEntity,
327
// Store the world's SDF DOM to be used when saving the world to file
328
this->dataPtr->ecm->CreateComponent(
329
worldEntity, components::WorldSdf(*_world));
334
//////////////////////////////////////////////////
335
Entity SdfEntityCreator::CreateEntities(const sdf::Model *_model)
337
IGN_PROFILE("SdfEntityCreator::CreateEntities(sdf::Model)");
339
auto ent = this->CreateEntities(_model, false);
341
// Load all model plugins afterwards, so we get scoped name for nested models.
342
for (const auto &[entity, element] : this->dataPtr->newModels)
344
this->dataPtr->eventManager->Emit<events::LoadPlugins>(entity, element);
346
this->dataPtr->newModels.clear();
348
// Load sensor plugins after model, so we get scoped name.
349
for (const auto &[entity, element] : this->dataPtr->newSensors)
351
this->dataPtr->eventManager->Emit<events::LoadPlugins>(entity, element);
353
this->dataPtr->newSensors.clear();
355
// Load visual plugins after model, so we get scoped name.
356
for (const auto &[entity, element] : this->dataPtr->newVisuals)
358
this->dataPtr->eventManager->Emit<events::LoadPlugins>(entity, element);
360
this->dataPtr->newVisuals.clear();
365
//////////////////////////////////////////////////
366
Entity SdfEntityCreator::CreateEntities(const sdf::Model *_model,
370
Entity modelEntity = this->dataPtr->ecm->CreateEntity();
373
this->dataPtr->ecm->CreateComponent(modelEntity, components::Model());
374
this->dataPtr->ecm->CreateComponent(modelEntity,
375
components::Pose(ResolveSdfPose(_model->SemanticPose())));
376
this->dataPtr->ecm->CreateComponent(modelEntity,
377
components::Name(_model->Name()));
378
bool isStatic = _model->Static() || _staticParent;
379
this->dataPtr->ecm->CreateComponent(modelEntity,
380
components::Static(isStatic));
381
this->dataPtr->ecm->CreateComponent(
382
modelEntity, components::WindMode(_model->EnableWind()));
383
this->dataPtr->ecm->CreateComponent(
384
modelEntity, components::SelfCollide(_model->SelfCollide()));
385
this->dataPtr->ecm->CreateComponent(
386
modelEntity, components::SourceFilePath(_model->Element()->FilePath()));
388
// NOTE: Pose components of links, visuals, and collisions are expressed in
389
// the parent frame until we get frames working.
392
const auto *canonicalLink = _model->CanonicalLink();
394
for (uint64_t linkIndex = 0; linkIndex < _model->LinkCount();
397
auto link = _model->LinkByIndex(linkIndex);
398
auto linkEntity = this->CreateEntities(link);
400
this->SetParent(linkEntity, modelEntity);
402
if (canonicalLink == link)
404
this->dataPtr->ecm->CreateComponent(linkEntity,
405
components::CanonicalLink());
408
// Set wind mode if the link didn't override it
409
if (!this->dataPtr->ecm->Component<components::WindMode>(linkEntity))
411
this->dataPtr->ecm->CreateComponent(
412
linkEntity, components::WindMode(_model->EnableWind()));
417
for (uint64_t jointIndex = 0; jointIndex < _model->JointCount();
420
auto joint = _model->JointByIndex(jointIndex);
421
auto jointEntity = this->CreateEntities(joint);
423
this->SetParent(jointEntity, modelEntity);
427
for (uint64_t modelIndex = 0; modelIndex < _model->ModelCount();
430
auto nestedModel = _model->ModelByIndex(modelIndex);
431
auto nestedModelEntity = this->CreateEntities(nestedModel, isStatic);
433
this->SetParent(nestedModelEntity, modelEntity);
436
// Find canonical link
437
const auto canonicalLinkPair = _model->CanonicalLinkAndRelativeName();
438
if (canonicalLinkPair.first)
440
Entity canonicalLinkEntity = FindDescendentLinkEntityByName(
441
canonicalLinkPair.second, modelEntity, *this->dataPtr->ecm);
442
if (kNullEntity != canonicalLinkEntity)
444
this->dataPtr->ecm->CreateComponent(
445
modelEntity, components::ModelCanonicalLink(canonicalLinkEntity));
449
ignerr << "Could not find the canonical link entity for "
450
<< canonicalLinkPair.second << "\n";
455
ignerr << "Could not resolve the canonical link for " << _model->Name()
459
// Store the model's SDF DOM to be used when saving the world to file
460
this->dataPtr->ecm->CreateComponent(
461
modelEntity, components::ModelSdf(*_model));
463
// Keep track of models so we can load their plugins after loading the entire
464
// model and having its full scoped name.
465
this->dataPtr->newModels[modelEntity] = _model->Element();
470
//////////////////////////////////////////////////
471
Entity SdfEntityCreator::CreateEntities(const sdf::Actor *_actor)
473
IGN_PROFILE("SdfEntityCreator::CreateEntities(sdf::Actor)");
476
Entity actorEntity = this->dataPtr->ecm->CreateEntity();
479
this->dataPtr->ecm->CreateComponent(actorEntity, components::Actor(*_actor));
480
this->dataPtr->ecm->CreateComponent(actorEntity,
481
components::Pose(_actor->RawPose()));
482
this->dataPtr->ecm->CreateComponent(actorEntity,
483
components::Name(_actor->Name()));
486
this->dataPtr->eventManager->Emit<events::LoadPlugins>(actorEntity,
492
//////////////////////////////////////////////////
493
Entity SdfEntityCreator::CreateEntities(const sdf::Light *_light)
495
IGN_PROFILE("SdfEntityCreator::CreateEntities(sdf::Light)");
498
Entity lightEntity = this->dataPtr->ecm->CreateEntity();
501
this->dataPtr->ecm->CreateComponent(lightEntity, components::Light(*_light));
502
this->dataPtr->ecm->CreateComponent(lightEntity,
503
components::Pose(ResolveSdfPose(_light->SemanticPose())));
504
this->dataPtr->ecm->CreateComponent(lightEntity,
505
components::Name(_light->Name()));
507
this->dataPtr->ecm->CreateComponent(lightEntity,
508
components::LightType(convert(_light->Type())));
513
//////////////////////////////////////////////////
514
Entity SdfEntityCreator::CreateEntities(const sdf::Link *_link)
516
IGN_PROFILE("SdfEntityCreator::CreateEntities(sdf::Link)");
519
Entity linkEntity = this->dataPtr->ecm->CreateEntity();
522
this->dataPtr->ecm->CreateComponent(linkEntity, components::Link());
524
this->dataPtr->ecm->CreateComponent(linkEntity,
525
components::Pose(ResolveSdfPose(_link->SemanticPose())));
526
this->dataPtr->ecm->CreateComponent(linkEntity,
527
components::Name(_link->Name()));
528
this->dataPtr->ecm->CreateComponent(linkEntity,
529
components::Inertial(_link->Inertial()));
531
if (_link->EnableWind())
533
this->dataPtr->ecm->CreateComponent(
534
linkEntity, components::WindMode(_link->EnableWind()));
538
for (uint64_t visualIndex = 0; visualIndex < _link->VisualCount();
541
auto visual = _link->VisualByIndex(visualIndex);
542
auto visualEntity = this->CreateEntities(visual);
544
this->SetParent(visualEntity, linkEntity);
548
for (uint64_t collisionIndex = 0; collisionIndex < _link->CollisionCount();
551
auto collision = _link->CollisionByIndex(collisionIndex);
552
auto collisionEntity = this->CreateEntities(collision);
554
this->SetParent(collisionEntity, linkEntity);
558
for (uint64_t lightIndex = 0; lightIndex < _link->LightCount();
561
auto light = _link->LightByIndex(lightIndex);
562
auto lightEntity = this->CreateEntities(light);
564
this->SetParent(lightEntity, linkEntity);
568
for (uint64_t sensorIndex = 0; sensorIndex < _link->SensorCount();
571
auto sensor = _link->SensorByIndex(sensorIndex);
572
auto sensorEntity = this->CreateEntities(sensor);
574
this->SetParent(sensorEntity, linkEntity);
578
for (uint64_t emitterIndex = 0; emitterIndex < _link->ParticleEmitterCount();
581
auto emitter = _link->ParticleEmitterByIndex(emitterIndex);
582
auto emitterEntity = this->CreateEntities(emitter);
584
this->SetParent(emitterEntity, linkEntity);
590
//////////////////////////////////////////////////
591
Entity SdfEntityCreator::CreateEntities(const sdf::Joint *_joint)
593
return this->CreateEntities(_joint, false);
596
//////////////////////////////////////////////////
597
Entity SdfEntityCreator::CreateEntities(const sdf::Joint *_joint,
600
IGN_PROFILE("SdfEntityCreator::CreateEntities(sdf::Joint)");
603
Entity jointEntity = this->dataPtr->ecm->CreateEntity();
606
this->dataPtr->ecm->CreateComponent(jointEntity,
607
components::Joint());
608
this->dataPtr->ecm->CreateComponent(jointEntity,
609
components::JointType(_joint->Type()));
612
for (uint64_t sensorIndex = 0; sensorIndex < _joint->SensorCount();
615
auto sensor = _joint->SensorByIndex(sensorIndex);
616
auto sensorEntity = this->CreateEntities(sensor);
618
this->SetParent(sensorEntity, jointEntity);
623
auto resolvedAxis = ResolveJointAxis(*_joint->Axis(0));
626
ignerr << "Failed to resolve joint axis 0 for joint '" << _joint->Name()
631
this->dataPtr->ecm->CreateComponent(jointEntity,
632
components::JointAxis(std::move(*resolvedAxis)));
637
auto resolvedAxis = ResolveJointAxis(*_joint->Axis(1));
640
ignerr << "Failed to resolve joint axis 1 for joint '" << _joint->Name()
645
this->dataPtr->ecm->CreateComponent(jointEntity,
646
components::JointAxis2(std::move(*resolvedAxis)));
649
this->dataPtr->ecm->CreateComponent(jointEntity,
650
components::Pose(ResolveSdfPose(_joint->SemanticPose())));
651
this->dataPtr->ecm->CreateComponent(jointEntity ,
652
components::Name(_joint->Name()));
653
this->dataPtr->ecm->CreateComponent(jointEntity ,
654
components::ThreadPitch(_joint->ThreadPitch()));
657
std::string resolvedParentLinkName;
660
resolvedParentLinkName = _joint->ParentLinkName();
665
const auto resolveParentErrors =
666
_joint->ResolveParentLink(resolvedParentLinkName);
667
if (!resolveParentErrors.empty())
669
ignerr << "Failed to resolve parent link for joint '" << _joint->Name()
670
<< "' with parent name '" << _joint->ParentLinkName() << "'"
672
for (const auto &error : resolveParentErrors)
674
ignerr << error << std::endl;
680
this->dataPtr->ecm->CreateComponent(
681
jointEntity, components::ParentLinkName(resolvedParentLinkName));
683
std::string resolvedChildLinkName;
686
resolvedChildLinkName = _joint->ChildLinkName();
690
const auto resolveChildErrors =
691
_joint->ResolveChildLink(resolvedChildLinkName);
692
if (!resolveChildErrors.empty())
694
ignerr << "Failed to resolve child link for joint '" << _joint->Name()
695
<< "' with child name '" << _joint->ChildLinkName() << "'"
697
for (const auto &error : resolveChildErrors)
699
ignerr << error << std::endl;
706
this->dataPtr->ecm->CreateComponent(
707
jointEntity, components::ChildLinkName(resolvedChildLinkName));
712
//////////////////////////////////////////////////
713
Entity SdfEntityCreator::CreateEntities(const sdf::Visual *_visual)
715
IGN_PROFILE("SdfEntityCreator::CreateEntities(sdf::Visual)");
718
Entity visualEntity = this->dataPtr->ecm->CreateEntity();
721
this->dataPtr->ecm->CreateComponent(visualEntity, components::Visual());
722
this->dataPtr->ecm->CreateComponent(visualEntity,
723
components::Pose(ResolveSdfPose(_visual->SemanticPose())));
724
this->dataPtr->ecm->CreateComponent(visualEntity,
725
components::Name(_visual->Name()));
726
this->dataPtr->ecm->CreateComponent(visualEntity,
727
components::CastShadows(_visual->CastShadows()));
728
this->dataPtr->ecm->CreateComponent(visualEntity,
729
components::Transparency(_visual->Transparency()));
730
this->dataPtr->ecm->CreateComponent(visualEntity,
731
components::VisibilityFlags(_visual->VisibilityFlags()));
733
if (_visual->HasLaserRetro())
735
this->dataPtr->ecm->CreateComponent(visualEntity,
736
components::LaserRetro(_visual->LaserRetro()));
741
this->dataPtr->ecm->CreateComponent(visualEntity,
742
components::Geometry(*_visual->Geom()));
745
// \todo(louise) Populate with default material if undefined
746
if (_visual->Material())
748
this->dataPtr->ecm->CreateComponent(visualEntity,
749
components::Material(*_visual->Material()));
752
// Keep track of visuals so we can load their plugins after loading the
753
// entire model and having its full scoped name.
754
this->dataPtr->newVisuals[visualEntity] = _visual->Element();
759
//////////////////////////////////////////////////
760
Entity SdfEntityCreator::CreateEntities(const sdf::ParticleEmitter *_emitter)
762
IGN_PROFILE("SdfEntityCreator::CreateEntities(sdf::ParticleEmitter)");
765
Entity emitterEntity = this->dataPtr->ecm->CreateEntity();
768
this->dataPtr->ecm->CreateComponent(emitterEntity,
769
components::ParticleEmitter(convert<msgs::ParticleEmitter>(*_emitter)));
770
this->dataPtr->ecm->CreateComponent(emitterEntity,
771
components::Pose(ResolveSdfPose(_emitter->SemanticPose())));
772
this->dataPtr->ecm->CreateComponent(emitterEntity,
773
components::Name(_emitter->Name()));
775
return emitterEntity;
778
//////////////////////////////////////////////////
779
Entity SdfEntityCreator::CreateEntities(const sdf::Collision *_collision)
781
IGN_PROFILE("SdfEntityCreator::CreateEntities(sdf::Collision)");
784
Entity collisionEntity = this->dataPtr->ecm->CreateEntity();
787
this->dataPtr->ecm->CreateComponent(collisionEntity,
788
components::Collision());
789
this->dataPtr->ecm->CreateComponent(collisionEntity,
790
components::Pose(ResolveSdfPose(_collision->SemanticPose())));
791
this->dataPtr->ecm->CreateComponent(collisionEntity,
792
components::Name(_collision->Name()));
794
if (_collision->Geom())
796
this->dataPtr->ecm->CreateComponent(collisionEntity,
797
components::Geometry(*_collision->Geom()));
800
this->dataPtr->ecm->CreateComponent(collisionEntity,
801
components::CollisionElement(*_collision));
803
return collisionEntity;
806
//////////////////////////////////////////////////
807
Entity SdfEntityCreator::CreateEntities(const sdf::Sensor *_sensor)
809
IGN_PROFILE("SdfEntityCreator::CreateEntities(sdf::Sensor)");
812
Entity sensorEntity = this->dataPtr->ecm->CreateEntity();
815
this->dataPtr->ecm->CreateComponent(sensorEntity,
816
components::Sensor());
817
this->dataPtr->ecm->CreateComponent(sensorEntity,
818
components::Pose(ResolveSdfPose(_sensor->SemanticPose())));
819
this->dataPtr->ecm->CreateComponent(sensorEntity,
820
components::Name(_sensor->Name()));
822
if (_sensor->Type() == sdf::SensorType::CAMERA)
824
this->dataPtr->ecm->CreateComponent(sensorEntity,
825
components::Camera(*_sensor));
827
else if (_sensor->Type() == sdf::SensorType::GPU_LIDAR)
829
this->dataPtr->ecm->CreateComponent(sensorEntity,
830
components::GpuLidar(*_sensor));
832
else if (_sensor->Type() == sdf::SensorType::LIDAR)
834
// \todo(anyone) Implement CPU-based lidar
835
// this->dataPtr->ecm->CreateComponent(sensorEntity,
836
// components::Lidar(*_sensor));
837
ignwarn << "Sensor type LIDAR not supported yet. Try using"
838
<< "a GPU LIDAR instead." << std::endl;
840
else if (_sensor->Type() == sdf::SensorType::DEPTH_CAMERA)
842
this->dataPtr->ecm->CreateComponent(sensorEntity,
843
components::DepthCamera(*_sensor));
845
else if (_sensor->Type() == sdf::SensorType::RGBD_CAMERA)
847
this->dataPtr->ecm->CreateComponent(sensorEntity,
848
components::RgbdCamera(*_sensor));
850
else if (_sensor->Type() == sdf::SensorType::THERMAL_CAMERA)
852
this->dataPtr->ecm->CreateComponent(sensorEntity,
853
components::ThermalCamera(*_sensor));
855
else if (_sensor->Type() == sdf::SensorType::SEGMENTATION_CAMERA)
857
this->dataPtr->ecm->CreateComponent(sensorEntity,
858
components::SegmentationCamera(*_sensor));
860
else if (_sensor->Type() == sdf::SensorType::AIR_PRESSURE)
862
this->dataPtr->ecm->CreateComponent(sensorEntity,
863
components::AirPressureSensor(*_sensor));
865
// create components to be filled by physics
866
this->dataPtr->ecm->CreateComponent(sensorEntity,
867
components::WorldPose(math::Pose3d::Zero));
869
else if (_sensor->Type() == sdf::SensorType::ALTIMETER)
871
this->dataPtr->ecm->CreateComponent(sensorEntity,
872
components::Altimeter(*_sensor));
874
// create components to be filled by physics
875
this->dataPtr->ecm->CreateComponent(sensorEntity,
876
components::WorldPose(math::Pose3d::Zero));
877
this->dataPtr->ecm->CreateComponent(sensorEntity,
878
components::WorldLinearVelocity(math::Vector3d::Zero));
880
else if (_sensor->Type() == sdf::SensorType::GPS ||
881
_sensor->Type() == sdf::SensorType::NAVSAT)
883
this->dataPtr->ecm->CreateComponent(sensorEntity,
884
components::NavSat(*_sensor));
886
// Create components to be filled by physics.
887
this->dataPtr->ecm->CreateComponent(sensorEntity,
888
components::WorldLinearVelocity(math::Vector3d::Zero));
890
else if (_sensor->Type() == sdf::SensorType::IMU)
892
this->dataPtr->ecm->CreateComponent(sensorEntity,
893
components::Imu(*_sensor));
895
// create components to be filled by physics
896
this->dataPtr->ecm->CreateComponent(sensorEntity,
897
components::WorldPose(math::Pose3d::Zero));
898
this->dataPtr->ecm->CreateComponent(sensorEntity,
899
components::AngularVelocity(math::Vector3d::Zero));
900
this->dataPtr->ecm->CreateComponent(sensorEntity,
901
components::LinearAcceleration(math::Vector3d::Zero));
903
else if (_sensor->Type() == sdf::SensorType::FORCE_TORQUE)
905
this->dataPtr->ecm->CreateComponent(sensorEntity,
906
components::ForceTorque(*_sensor));
908
else if (_sensor->Type() == sdf::SensorType::LOGICAL_CAMERA)
910
auto elem = _sensor->Element();
912
this->dataPtr->ecm->CreateComponent(sensorEntity,
913
components::LogicalCamera(elem));
915
// create components to be filled by physics
916
this->dataPtr->ecm->CreateComponent(sensorEntity,
917
components::WorldPose(math::Pose3d::Zero));
919
else if (_sensor->Type() == sdf::SensorType::MAGNETOMETER)
921
this->dataPtr->ecm->CreateComponent(sensorEntity,
922
components::Magnetometer(*_sensor));
924
// create components to be filled by physics
925
this->dataPtr->ecm->CreateComponent(sensorEntity,
926
components::WorldPose(math::Pose3d::Zero));
928
else if (_sensor->Type() == sdf::SensorType::CONTACT)
930
auto elem = _sensor->Element();
932
this->dataPtr->ecm->CreateComponent(sensorEntity,
933
components::ContactSensor(elem));
934
// We will let the contact system create the necessary components for
935
// physics to populate.
937
else if (_sensor->Type() == sdf::SensorType::CUSTOM)
939
auto elem = _sensor->Element();
940
this->dataPtr->ecm->CreateComponent(sensorEntity,
941
components::CustomSensor(*_sensor));
945
ignwarn << "Sensor type [" << static_cast<int>(_sensor->Type())
946
<< "] not supported yet." << std::endl;
949
// Keep track of sensors so we can load their plugins after loading the entire
950
// model and having its full scoped name.
951
this->dataPtr->newSensors[sensorEntity] = _sensor->Element();
956
//////////////////////////////////////////////////
957
void SdfEntityCreator::RequestRemoveEntity(Entity _entity, bool _recursive)
959
// Leave children parentless
962
auto childEntities = this->dataPtr->ecm->ChildrenByComponents(_entity,
963
components::ParentEntity(_entity));
964
for (const auto childEntity : childEntities)
966
this->dataPtr->ecm->RemoveComponent<components::ParentEntity>(
971
this->dataPtr->ecm->RequestRemoveEntity(_entity, _recursive);
974
//////////////////////////////////////////////////
975
void SdfEntityCreator::SetParent(Entity _child, Entity _parent)
977
// TODO(louise) Figure out a way to avoid duplication while keeping all
978
// state in components and also keeping a convenient graph in the ECM
979
this->dataPtr->ecm->SetParentEntity(_child, _parent);
980
this->dataPtr->ecm->CreateComponent(_child,
981
components::ParentEntity(_parent));