CARLA
WorldObserver.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"
12 #include "Carla/Game/CarlaEngine.h"
13 
21 
22 #include "CoreGlobals.h"
23 
25 #include <carla/rpc/String.h>
29 
30 static auto FWorldObserver_GetActorState(const FCarlaActor &View, const FActorRegistry &Registry)
31 {
32  using AType = FCarlaActor::ActorType;
33 
35 
36  if (AType::Vehicle == View.GetActorType())
37  {
38  auto Vehicle = Cast<ACarlaWheeledVehicle>(View.GetActor());
39  if (Vehicle != nullptr)
40  {
41  state.vehicle_data.control = carla::rpc::VehicleControl{Vehicle->GetVehicleControl()};
42  auto Controller = Cast<AWheeledVehicleAIController>(Vehicle->GetController());
43  if (Controller != nullptr)
44  {
46  state.vehicle_data.traffic_light_state = static_cast<TLS>(Controller->GetTrafficLightState());
47  state.vehicle_data.speed_limit = Controller->GetSpeedLimit();
48  auto TrafficLight = Controller->GetTrafficLight();
49  if (TrafficLight != nullptr)
50  {
51  state.vehicle_data.has_traffic_light = true;
52  auto* TrafficLightView = Registry.FindCarlaActor(TrafficLight);
53  if(TrafficLightView)
54  {
55  state.vehicle_data.traffic_light_id = TrafficLightView->GetActorId();
56  }
57  else
58  {
59  state.vehicle_data.has_traffic_light = false;
60  }
61  }
62  else
63  {
64  state.vehicle_data.has_traffic_light = false;
65  }
66  }
67  // Get the failure state by checking the rollover one as it is the only one currently implemented.
68  // This will have to be expanded once more states are added
69  state.vehicle_data.failure_state = Vehicle->GetFailureState();
70  }
71  }
72 
73  else if (AType::Walker == View.GetActorType())
74  {
75  auto Walker = Cast<APawn>(View.GetActor());
76  auto Controller = Walker != nullptr ? Cast<AWalkerController>(Walker->GetController()) : nullptr;
77  if (Controller != nullptr)
78  {
79  state.walker_control = carla::rpc::WalkerControl{Controller->GetWalkerControl()};
80  }
81  }
82  else if (AType::TrafficLight == View.GetActorType())
83  {
84  auto TrafficLight = Cast<ATrafficLightBase>(View.GetActor());
85  if (TrafficLight != nullptr)
86  {
87  auto* TrafficLightComponent =
88  TrafficLight->GetTrafficLightComponent();
89 
91 
92  if(TrafficLightComponent == nullptr)
93  {
94  // Old way: traffic lights are actors
95  state.traffic_light_data.sign_id[0] = '\0';
96  state.traffic_light_data.state = static_cast<TLS>(TrafficLight->GetTrafficLightState());
97  state.traffic_light_data.green_time = TrafficLight->GetGreenTime();
98  state.traffic_light_data.yellow_time = TrafficLight->GetYellowTime();
99  state.traffic_light_data.red_time = TrafficLight->GetRedTime();
100  state.traffic_light_data.elapsed_time = TrafficLight->GetElapsedTime();
101  state.traffic_light_data.time_is_frozen = TrafficLight->GetTimeIsFrozen();
102  state.traffic_light_data.pole_index = TrafficLight->GetPoleIndex();
103  }
104  else
105  {
106  const UTrafficLightController* Controller = TrafficLightComponent->GetController();
107  const ATrafficLightGroup* Group = TrafficLightComponent->GetGroup();
108 
109  if (!Controller)
110  {
111  UE_LOG(LogCarla, Error, TEXT("TrafficLightComponent doesn't have any Controller assigned"));
112  }
113  else if (!Group)
114  {
115  UE_LOG(LogCarla, Error, TEXT("TrafficLightComponent doesn't have any Group assigned"));
116  }
117  else
118  {
119  const FString fstring_sign_id = TrafficLightComponent->GetSignId();
120  const std::string sign_id = carla::rpc::FromFString(fstring_sign_id);
121  constexpr size_t max_size = sizeof(state.traffic_light_data.sign_id);
122  size_t sign_id_length = sign_id.length();
123  if(max_size < sign_id_length)
124  {
125  UE_LOG(LogCarla, Warning, TEXT("The max size of a signal id is 32. %s (%d)"), *fstring_sign_id, sign_id.length());
126  sign_id_length = max_size;
127  }
128  std::memset(state.traffic_light_data.sign_id, '\0', max_size);
129  std::memcpy(state.traffic_light_data.sign_id, sign_id.c_str(), sign_id_length);
130  state.traffic_light_data.state = static_cast<TLS>(TrafficLightComponent->GetLightState());
131  state.traffic_light_data.green_time = Controller->GetGreenTime();
132  state.traffic_light_data.yellow_time = Controller->GetYellowTime();
133  state.traffic_light_data.red_time = Controller->GetRedTime();
134  state.traffic_light_data.elapsed_time = Controller->GetElapsedTime();
135  state.traffic_light_data.time_is_frozen = Group->IsFrozen();
136  state.traffic_light_data.pole_index = TrafficLight->GetPoleIndex();
137  }
138  }
139  }
140  }
141  else if (AType::TrafficSign == View.GetActorType())
142  {
143  auto TrafficSign = Cast<ATrafficSignBase>(View.GetActor());
144  if (TrafficSign != nullptr)
145  {
146  USignComponent* TrafficSignComponent =
147  Cast<USignComponent>(TrafficSign->FindComponentByClass<USignComponent>());
148 
149  if(TrafficSignComponent)
150  {
151  const FString fstring_sign_id = TrafficSignComponent->GetSignId();
152  const std::string sign_id = carla::rpc::FromFString(fstring_sign_id);
153  constexpr size_t max_size = sizeof(state.traffic_sign_data.sign_id);
154  size_t sign_id_length = sign_id.length();
155  if(max_size < sign_id_length)
156  {
157  UE_LOG(LogCarla, Warning, TEXT("The max size of a signal id is 32. %s (%d)"), *fstring_sign_id, sign_id.length());
158  sign_id_length = max_size;
159  }
160  std::memset(state.traffic_light_data.sign_id, '\0', max_size);
161  std::memcpy(state.traffic_sign_data.sign_id, sign_id.c_str(), sign_id_length);
162  }
163  }
164  }
165  return state;
166 }
167 
168 static auto FWorldObserver_GetDormantActorState(const FCarlaActor &View, const FActorRegistry &Registry)
169 {
170  using AType = FCarlaActor::ActorType;
171 
173 
174  if (AType::Vehicle == View.GetActorType())
175  {
176  const FVehicleData* ActorData = View.GetActorData<FVehicleData>();
177  state.vehicle_data.control = carla::rpc::VehicleControl{ActorData->Control};
179  state.vehicle_data.traffic_light_state = TLS::Green;
180  state.vehicle_data.speed_limit = ActorData->SpeedLimit;
181  state.vehicle_data.has_traffic_light = false;
182  }
183  else if (AType::Walker == View.GetActorType())
184  {
185  const FWalkerData* ActorData = View.GetActorData<FWalkerData>();
186  // auto Walker = Cast<APawn>(View.GetActor());
187  // auto Controller = Walker != nullptr ? Cast<AWalkerController>(Walker->GetController()) : nullptr;
188  // if (Controller != nullptr)
189  // {
190  // state.walker_control = carla::rpc::WalkerControl{Controller->GetWalkerControl()};
191  // }
192  state.walker_control = ActorData->WalkerControl;
193  }
194  else if (AType::TrafficLight == View.GetActorType())
195  {
196  const FTrafficLightData* ActorData = View.GetActorData<FTrafficLightData>();
197  const UTrafficLightController* Controller = ActorData->Controller;
198  if(Controller)
199  {
201  const ATrafficLightGroup* Group = Controller->GetGroup();
202  if(!Group)
203  {
204  UE_LOG(LogCarla, Error, TEXT("TrafficLight doesn't have any Group assigned"));
205  }
206  else
207  {
208  const FString fstring_sign_id = ActorData->SignId;
209  const std::string sign_id = carla::rpc::FromFString(fstring_sign_id);
210  constexpr size_t max_size = sizeof(state.traffic_light_data.sign_id);
211  size_t sign_id_length = sign_id.length();
212  if(max_size < sign_id_length)
213  {
214  UE_LOG(LogCarla, Warning, TEXT("The max size of a signal id is 32. %s (%d)"), *fstring_sign_id, sign_id.length());
215  sign_id_length = max_size;
216  }
217  std::memset(state.traffic_light_data.sign_id, '\0', max_size);
218  std::memcpy(state.traffic_light_data.sign_id, sign_id.c_str(), sign_id_length);
219  state.traffic_light_data.state = static_cast<TLS>(Controller->GetCurrentState().State);
220  state.traffic_light_data.green_time = Controller->GetGreenTime();
221  state.traffic_light_data.yellow_time = Controller->GetYellowTime();
222  state.traffic_light_data.red_time = Controller->GetRedTime();
223  state.traffic_light_data.elapsed_time = Controller->GetElapsedTime();
224  state.traffic_light_data.time_is_frozen = Group->IsFrozen();
225  state.traffic_light_data.pole_index = ActorData->PoleIndex;
226  }
227  }
228  }
229  else if (AType::TrafficSign == View.GetActorType())
230  {
231  const FTrafficSignData* ActorData = View.GetActorData<FTrafficSignData>();
232  const FString fstring_sign_id = ActorData->SignId;
233  const std::string sign_id = carla::rpc::FromFString(fstring_sign_id);
234  constexpr size_t max_size = sizeof(state.traffic_sign_data.sign_id);
235  size_t sign_id_length = sign_id.length();
236  if(max_size < sign_id_length)
237  {
238  UE_LOG(LogCarla, Warning, TEXT("The max size of a signal id is 32. %s (%d)"), *fstring_sign_id, sign_id.length());
239  sign_id_length = max_size;
240  }
241  std::memset(state.traffic_light_data.sign_id, '\0', max_size);
242  std::memcpy(state.traffic_sign_data.sign_id, sign_id.c_str(), sign_id_length);
243  }
244  return state;
245 }
246 
248 {
249  const auto RootComponent = Cast<UPrimitiveComponent>(Actor.GetRootComponent());
250  const FVector AngularVelocity =
251  RootComponent != nullptr ?
252  RootComponent->GetPhysicsAngularVelocityInDegrees() :
253  FVector{0.0f, 0.0f, 0.0f};
254  return {AngularVelocity.X, AngularVelocity.Y, AngularVelocity.Z};
255 }
256 
258  const FCarlaActor &View,
259  const FVector &Velocity,
260  const float DeltaSeconds)
261 {
262  FVector &PreviousVelocity = View.GetActorInfo()->Velocity;
263  const FVector Acceleration = (Velocity - PreviousVelocity) / DeltaSeconds;
264  PreviousVelocity = Velocity;
265  return {Acceleration.X, Acceleration.Y, Acceleration.Z};
266 }
267 
269  carla::Buffer &&buffer,
270  const UCarlaEpisode &Episode,
271  float DeltaSeconds,
272  bool MapChange,
273  bool PendingLightUpdates)
274 {
275  TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
278  using ActorDynamicState = carla::sensor::data::ActorDynamicState;
279 
280 
281  const FActorRegistry &Registry = Episode.GetActorRegistry();
282 
283  auto total_size = sizeof(Serializer::Header) + sizeof(ActorDynamicState) * Registry.Num();
284  auto current_size = 0;
285  // Set up buffer for writing.
286  buffer.reset(total_size);
287  auto write_data = [&current_size, &buffer](const auto &data)
288  {
289  auto begin = buffer.begin() + current_size;
290  std::memcpy(begin, &data, sizeof(data));
291  current_size += sizeof(data);
292  };
293 
294  constexpr float TO_METERS = 1e-2;
295 
296  // Write header.
297  Serializer::Header header;
298  header.episode_id = Episode.GetId();
299  header.platform_timestamp = FPlatformTime::Seconds();
300  header.delta_seconds = DeltaSeconds;
301  FIntVector MapOrigin = Episode.GetCurrentMapOrigin();
302  FIntVector MapOriginInMeters = MapOrigin / 100;
303  header.map_origin = carla::geom::Vector3DInt{ MapOriginInMeters.X, MapOriginInMeters.Y, MapOriginInMeters.Z };
304 
305  uint8_t simulation_state = (SimulationState::MapChange * MapChange);
306  simulation_state |= (SimulationState::PendingLightUpdate * PendingLightUpdates);
307 
308  header.simulation_state = static_cast<SimulationState>(simulation_state);
309 
310  write_data(header);
311 
312  // Write every actor.
313  for (auto& It : Registry)
314  {
315  const FCarlaActor* View = It.Value.Get();
316  const FActorInfo* ActorInfo = View->GetActorInfo();
317 
318  FTransform ActorTransform;
319  FVector Velocity(0.0f);
320  carla::geom::Vector3D AngularVelocity(0.0f, 0.0f, 0.0f);
321  carla::geom::Vector3D Acceleration(0.0f, 0.0f, 0.0f);
323 
324 
325  check(View);
326 
327  if(View->IsDormant())
328  {
329  const FActorData* ActorData = View->GetActorData();
330  Velocity = TO_METERS * ActorData->Velocity;
331  AngularVelocity = carla::geom::Vector3D
332  {ActorData->AngularVelocity.X,
333  ActorData->AngularVelocity.Y,
334  ActorData->AngularVelocity.Z};
335  Acceleration = FWorldObserver_GetAcceleration(*View, Velocity, DeltaSeconds);
336  State = FWorldObserver_GetDormantActorState(*View, Registry);
337  }
338  else
339  {
340  Velocity = TO_METERS * View->GetActor()->GetVelocity();
341  AngularVelocity = FWorldObserver_GetAngularVelocity(*View->GetActor());
342  Acceleration = FWorldObserver_GetAcceleration(*View, Velocity, DeltaSeconds);
343  State = FWorldObserver_GetActorState(*View, Registry);
344  }
345  ActorTransform = View->GetActorGlobalTransform();
346 
347  ActorDynamicState info = {
348  View->GetActorId(),
349  View->GetActorState(),
350  carla::geom::Transform(ActorTransform),
351  carla::geom::Vector3D(Velocity.X, Velocity.Y, Velocity.Z),
352  AngularVelocity,
353  Acceleration,
354  State,
355  };
356  write_data(info);
357  }
358 
359  // Shrink buffer
360  buffer.resize(current_size);
361 
362  check(buffer.size() == current_size);
363 
364  return std::move(buffer);
365 }
366 
368  const UCarlaEpisode &Episode,
369  float DeltaSecond,
370  bool MapChange,
371  bool PendingLightUpdates)
372 {
373  TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
374 
375  if (!Stream.IsStreamReady())
376  return;
377 
378  auto AsyncStream = Stream.MakeAsyncDataStream(*this, Episode.GetElapsedGameTime());
379 
381  AsyncStream.PopBufferFromPool(),
382  Episode,
383  DeltaSecond,
384  MapChange,
385  PendingLightUpdates);
386 
387  AsyncStream.SerializeAndSend(*this, std::move(buffer));
388 }
Dynamic state of an actor at a certain frame.
FVector Velocity
Definition: ActorInfo.h:35
A registry of all the Carla actors.
Definition: ActorRegistry.h:20
carla::rpc::ActorState GetActorState() const
Definition: CarlaActor.h:105
FDataMultiStream Stream
Definition: WorldObserver.h:49
void BroadcastTick(const UCarlaEpisode &Episode, float DeltaSeconds, bool MapChange, bool PendingLightUpdate)
Send a message to every connected client with the info about the given Episode.
FAsyncDataStreamTmpl< T > MakeAsyncDataStream(const SensorT &Sensor, double Timestamp)
Create a FAsyncDataStream object.
Definition: DataStream.h:40
AActor * GetActor()
Definition: CarlaActor.h:90
Serializes the current state of the whole episode.
carla::rpc::WalkerControl WalkerControl
Definition: ActorData.h:84
double GetElapsedGameTime() const
Game seconds since the start of this episode.
Definition: CarlaEpisode.h:99
Class which implements the state changing of traffic lights.
static auto FWorldObserver_GetDormantActorState(const FCarlaActor &View, const FActorRegistry &Registry)
static carla::geom::Vector3D FWorldObserver_GetAcceleration(const FCarlaActor &View, const FVector &Velocity, const float DeltaSeconds)
FVector Velocity
Definition: ActorData.h:38
FVehicleControl Control
Definition: ActorData.h:61
static carla::Buffer FWorldObserver_Serialize(carla::Buffer &&buffer, const UCarlaEpisode &Episode, float DeltaSeconds, bool MapChange, bool PendingLightUpdates)
float SpeedLimit
Definition: ActorData.h:71
int32 Num() const
Definition: ActorRegistry.h:54
geom::Vector3D Vector3D
Definition: rpc/Vector3D.h:14
const FActorRegistry & GetActorRegistry() const
Definition: CarlaEpisode.h:155
FActorData * GetActorData()
Definition: CarlaActor.h:156
carla::SharedPtr< cc::Actor > Actor
A simulation episode.
Definition: CarlaEpisode.h:38
auto GetId() const
Return the unique id of this episode.
Definition: CarlaEpisode.h:86
FVector AngularVelocity
Definition: ActorData.h:40
const FActorInfo * GetActorInfo() const
Definition: CarlaActor.h:100
FIntVector GetCurrentMapOrigin() const
Definition: CarlaEpisode.h:322
A piece of raw data.
Definition: carla/Buffer.h:42
A view over an actor and its properties.
Definition: ActorInfo.h:22
FTransform GetActorGlobalTransform() const
Definition: CarlaActor.cpp:199
bool IsDormant() const
Definition: CarlaActor.h:70
static carla::geom::Vector3D FWorldObserver_GetAngularVelocity(const AActor &Actor)
IdType GetActorId() const
Definition: CarlaActor.h:80
carla::rpc::TrafficLightState TLS
FCarlaActor * FindCarlaActor(IdType Id)
Definition: ActorRegistry.h:69
FString SignId
Definition: ActorData.h:96
bool IsStreamReady()
Definition: DataStream.h:46
Maps a controller from OpenDrive.
UTrafficLightController * Controller
Definition: ActorData.h:113
static auto FWorldObserver_GetActorState(const FCarlaActor &View, const FActorRegistry &Registry)
geom::Transform Transform
Definition: rpc/Transform.h:16
ActorType GetActorType() const
Definition: CarlaActor.h:85
A view over an actor and its properties.
Definition: CarlaActor.h:23