CARLA
SensorFactory.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2 // de Barcelona (UAB).
3 //
4 // This work is licensed under the terms of the MIT license.
5 // For a copy, see <https://opensource.org/licenses/MIT>.
6 
7 #include "Carla.h"
9 
12 #include "Carla/Sensor/Sensor.h"
13 
17 
18 #define LIBCARLA_SENSOR_REGISTRY_WITH_SENSOR_INCLUDES
20 #undef LIBCARLA_SENSOR_REGISTRY_WITH_SENSOR_INCLUDES
21 
22 #include <type_traits>
23 
24 // =============================================================================
25 // -- FSensorDefinitionGatherer ------------------------------------------------
26 // =============================================================================
27 
28 /// Retrieve the definitions of all the sensors registered in the
29 /// SensorRegistry by calling their static method
30 /// SensorType::GetSensorDefinition().
31 ///
32 /// @note To make this class ignore a given sensor, define a public member
33 /// "not_spawnable" that defines a type. If so, the sensor won't be spawned by
34 /// this factory.
36 {
38 
39 public:
40 
41  static auto GetSensorDefinitions()
42  {
43  TArray<FActorDefinition> Definitions;
44  Definitions.Reserve(Registry::size());
45  AppendDefinitions(Definitions, std::make_index_sequence<Registry::size()>());
46  return Definitions;
47  }
48 
49 private:
50 
51  // Type traits for detecting if a sensor is spawnable.
52 
53  template<typename T>
54  struct void_type { typedef void type; };
55 
56  template<typename T, typename = void>
57  struct is_spawnable : std::true_type {};
58 
59  template<typename T>
60  struct is_spawnable<T, typename void_type<typename T::not_spawnable>::type > : std::false_type {};
61 
62  // AppendDefinitions implementations.
63 
64  template <typename SensorType>
65  static typename std::enable_if<is_spawnable<SensorType>::value, void>::type
66  AppendDefinitions(TArray<FActorDefinition> &Definitions)
67  {
68  auto Def = SensorType::GetSensorDefinition();
69  // Make sure the class matches the sensor type.
70  Def.Class = SensorType::StaticClass();
71  Definitions.Emplace(Def);
72  }
73 
74  template <typename SensorType>
75  static typename std::enable_if<!is_spawnable<SensorType>::value, void>::type
76  AppendDefinitions(TArray<FActorDefinition> &) {}
77 
78  template <size_t Index>
79  static void AppendDefinitions(TArray<FActorDefinition> &Definitions)
80  {
81  using SensorPtrType = typename Registry::get_by_index<Index>::key;
82  using SensorType = typename std::remove_pointer<SensorPtrType>::type;
83  AppendDefinitions<SensorType>(Definitions);
84  }
85 
86  template <size_t... Is>
87  static void AppendDefinitions(
88  TArray<FActorDefinition> &Definitions,
89  std::index_sequence<Is...>)
90  {
91  std::initializer_list<int> ({(AppendDefinitions<Is>(Definitions), 0)...});
92  }
93 };
94 
95 // =============================================================================
96 // -- ASensorFactory -----------------------------------------------------------
97 // =============================================================================
98 
99 TArray<FActorDefinition> ASensorFactory::GetDefinitions()
100 {
102 }
103 
105  const FTransform &Transform,
106  const FActorDescription &Description)
107 {
108  auto *World = GetWorld();
109  if (World == nullptr)
110  {
111  UE_LOG(LogCarla, Error, TEXT("ASensorFactory: cannot spawn sensor into an empty world."));
112  return {};
113  }
114 
115  UCarlaGameInstance *GameInstance = UCarlaStatics::GetGameInstance(World);
116  if (GameInstance == nullptr)
117  {
118  UE_LOG(LogCarla, Error, TEXT("ASensorFactory: cannot spawn sensor, incompatible game instance."));
119  return {};
120  }
121 
122  auto *Sensor = World->SpawnActorDeferred<ASensor>(
123  Description.Class,
124  Transform,
125  this,
126  nullptr,
127  ESpawnActorCollisionHandlingMethod::AlwaysSpawn);
128  if (Sensor == nullptr)
129  {
130  UE_LOG(LogCarla, Error, TEXT("ASensorFactory: spawn sensor failed."));
131  }
132  else
133  {
134  auto *Episode = GameInstance->GetCarlaEpisode();
135  check(Episode != nullptr);
136  Sensor->SetEpisode(*Episode);
137  Sensor->Set(Description);
138  Sensor->SetDataStream(GameInstance->GetServer().OpenStream());
139  }
140  UGameplayStatics::FinishSpawningActor(Sensor, Transform);
141  return FActorSpawnResult{Sensor};
142 }
CompositeSerializer< std::pair< ACollisionSensor *, s11n::CollisionEventSerializer >, std::pair< ADepthCamera *, s11n::ImageSerializer >, std::pair< ADVSCamera *, s11n::DVSEventArraySerializer >, std::pair< AGnssSensor *, s11n::GnssSerializer >, std::pair< AInertialMeasurementUnit *, s11n::IMUSerializer >, std::pair< ALaneInvasionSensor *, s11n::NoopSerializer >, std::pair< AObstacleDetectionSensor *, s11n::ObstacleDetectionEventSerializer >, std::pair< AOpticalFlowCamera *, s11n::OpticalFlowImageSerializer >, std::pair< ARadar *, s11n::RadarSerializer >, std::pair< ARayCastSemanticLidar *, s11n::SemanticLidarSerializer >, std::pair< ARayCastLidar *, s11n::LidarSerializer >, std::pair< ARssSensor *, s11n::NoopSerializer >, std::pair< ASceneCaptureCamera *, s11n::ImageSerializer >, std::pair< ASemanticSegmentationCamera *, s11n::ImageSerializer >, std::pair< AInstanceSegmentationCamera *, s11n::ImageSerializer >, std::pair< FWorldObserver *, s11n::EpisodeStateSerializer > > SensorRegistry
Contains a registry of all the sensors available and allows serializing and deserializing sensor data...
static void AppendDefinitions(TArray< FActorDefinition > &Definitions, std::index_sequence< Is... >)
FDataStream OpenStream() const
Retrieve the definitions of all the sensors registered in the SensorRegistry by calling their static ...
The game instance contains elements that must be kept alive in between levels.
const FCarlaServer & GetServer() const
Compile-time map for mapping sensor objects to serializers.
static UCarlaGameInstance * GetGameInstance(const UObject *WorldContextObject)
Definition: CarlaStatics.h:63
static void AppendDefinitions(TArray< FActorDefinition > &Definitions)
FActorSpawnResult SpawnActor(const FTransform &SpawnAtTransform, const FActorDescription &ActorDescription) final
Spawn an actor based on ActorDescription and Transform.
static std::enable_if< is_spawnable< SensorType >::value, void >::type AppendDefinitions(TArray< FActorDefinition > &Definitions)
TSubclassOf< AActor > Class
Class of the actor to be spawned.
A description of a Carla Actor with all its variation.
typename detail::CompileTimeTypeMapImpl< sizeof...(Items), Items... >::template get_by_index< Index > get_by_index
Result of an actor spawn function.
TArray< FActorDefinition > GetDefinitions() final
Retrieve the definitions of all the sensors registered in the SensorRegistry.
geom::Transform Transform
Definition: rpc/Transform.h:16
static std::enable_if<!is_spawnable< SensorType >::value, void >::type AppendDefinitions(TArray< FActorDefinition > &)
static auto GetSensorDefinitions()
UCarlaEpisode * GetCarlaEpisode()