Add traffic lights and signs as actors

This commit is contained in:
nsubiron 2018-10-21 23:35:03 +02:00
parent cf8a758146
commit d5392c7408
11 changed files with 143 additions and 4 deletions

View File

@ -0,0 +1,25 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#include "carla/client/TrafficLight.h"
#include "carla/client/detail/Simulator.h"
namespace carla {
namespace client {
TrafficLightState TrafficLight::GetState() {
auto state = GetEpisode().Lock()->GetActorDynamicState(*this).state;
switch (state) {
case 1u: return TrafficLightState::Red;
case 2u: return TrafficLightState::Yellow;
case 3u: return TrafficLightState::Green;
default: return TrafficLightState::Unknown;
}
}
} // namespace client
} // namespace carla

View File

@ -0,0 +1,30 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/client/Actor.h"
namespace carla {
namespace client {
enum class TrafficLightState {
Unknown,
Red,
Yellow,
Green
};
class TrafficLight : public Actor {
public:
explicit TrafficLight(ActorInitializer init) : Actor(std::move(init)) {}
TrafficLightState GetState();
};
} // namespace client
} // namespace carla

View File

@ -10,6 +10,7 @@
#include "carla/StringUtil.h"
#include "carla/client/Actor.h"
#include "carla/client/Sensor.h"
#include "carla/client/TrafficLight.h"
#include "carla/client/Vehicle.h"
#include "carla/client/World.h"
#include "carla/client/detail/Client.h"
@ -70,6 +71,8 @@ namespace detail {
return MakeActorImpl<Sensor>(ActorInitializer{description, episode}, gc);
} else if (StringUtil::StartsWith(description.description.id, "vehicle.")) {
return MakeActorImpl<Vehicle>(ActorInitializer{description, episode}, gc);
} else if (StringUtil::StartsWith(description.description.id, "traffic.traffic_light")) {
return MakeActorImpl<TrafficLight>(ActorInitializer{description, episode}, gc);
}
return MakeActorImpl<Actor>(ActorInitializer{description, episode}, gc);
}

View File

@ -38,7 +38,7 @@ namespace detail {
DEBUG_ONLY(auto result = )
next->_actors.emplace(
actor.id,
ActorState{actor.transform, actor.velocity, acceleration});
ActorState{actor.transform, actor.velocity, acceleration, actor.state});
DEBUG_ASSERT(result.second);
}
return next;

View File

@ -30,6 +30,7 @@ namespace detail {
geom::Transform transform;
geom::Vector3D velocity;
geom::Vector3D acceleration;
uint8_t state = 0u;
};
const auto &GetTimestamp() const {

View File

@ -26,11 +26,13 @@ namespace data {
geom::Transform transform;
geom::Vector3D velocity;
uint8_t state;
};
#pragma pack(pop)
static_assert(sizeof(ActorDynamicState) == 10u * sizeof(uint32_t), "Invalid ActorDynamicState size!");
static_assert(sizeof(ActorDynamicState) == 1u + 10u * sizeof(uint32_t), "Invalid ActorDynamicState size!");
} // namespace data
} // namespace sensor

View File

@ -5,6 +5,7 @@
// For a copy, see <https://opensource.org/licenses/MIT>.
#include <carla/client/Actor.h>
#include <carla/client/TrafficLight.h>
#include <carla/client/Vehicle.h>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
@ -62,4 +63,16 @@ void export_actor() {
.def("set_autopilot", &cc::Vehicle::SetAutopilot, (arg("enabled")=true))
.def(self_ns::str(self_ns::self))
;
enum_<cc::TrafficLightState>("TrafficLightState")
.value("Unknown", cc::TrafficLightState::Unknown)
.value("Red", cc::TrafficLightState::Red)
.value("Yellow", cc::TrafficLightState::Yellow)
.value("Green", cc::TrafficLightState::Green)
;
class_<cc::TrafficLight, bases<cc::Actor>, boost::noncopyable, boost::shared_ptr<cc::TrafficLight>>("TrafficLight", no_init)
.add_property("state", &cc::TrafficLight::GetState)
.def(self_ns::str(self_ns::self))
;
}

View File

@ -8,7 +8,17 @@
#include "Carla.h"
#include "Carla/Actor/ActorRegistry.h"
#include "Carla/Game/Tagger.h"
#include "Carla/Traffic/TrafficLightBase.h"
static bool FActorRegistry_IsTrafficLight(const FActorView &View)
{
return
View.IsValid() &&
View.GetSemanticTags().Contains(ECityObjectLabel::TrafficSigns) &&
(nullptr != Cast<ATrafficLightBase>(View.GetActor()));
}
static FString GetRelevantTagAsString(const FActorView &View)
{
@ -41,6 +51,8 @@ FActorView FActorRegistry::Register(AActor &Actor, FActorDescription Description
auto View = FActorView(Id, Actor, std::move(Description));
ATagger::GetTagsOfTaggedActor(Actor, View.SemanticTags);
View.bIsTrafficLight = FActorRegistry_IsTrafficLight(View);
auto Result = ActorDatabase.emplace(Id, View);
check(Result.second);
check(static_cast<size_t>(Actors.Num()) == ActorDatabase.size());

View File

@ -51,6 +51,11 @@ public:
return SemanticTags;
}
bool IsTrafficLight() const
{
return bIsTrafficLight;
}
private:
friend class FActorRegistry;
@ -67,4 +72,7 @@ private:
TSharedPtr<const FActorDescription> Description = nullptr;
TSet<ECityObjectLabel> SemanticTags;
/// @todo
bool bIsTrafficLight = false;
};

View File

@ -10,6 +10,25 @@
#include "EngineUtils.h"
#include "GameFramework/SpectatorPawn.h"
static FString UCarlaEpisode_GetTrafficSignId(ETrafficSignState State)
{
using TSS = ETrafficSignState;
switch (State) {
case TSS::TrafficLightRed:
case TSS::TrafficLightYellow:
case TSS::TrafficLightGreen: return TEXT("traffic.traffic_light");
case TSS::SpeedLimit_30: return TEXT("traffic.speed_limit.30");
case TSS::SpeedLimit_40: return TEXT("traffic.speed_limit.40");
case TSS::SpeedLimit_50: return TEXT("traffic.speed_limit.50");
case TSS::SpeedLimit_60: return TEXT("traffic.speed_limit.60");
case TSS::SpeedLimit_90: return TEXT("traffic.speed_limit.90");
case TSS::SpeedLimit_100: return TEXT("traffic.speed_limit.100");
case TSS::SpeedLimit_120: return TEXT("traffic.speed_limit.120");
case TSS::SpeedLimit_130: return TEXT("traffic.speed_limit.130");
default: return TEXT("traffic.unknown");
}
}
UCarlaEpisode::UCarlaEpisode(const FObjectInitializer &ObjectInitializer)
: Super(ObjectInitializer),
Id([]() {
@ -57,4 +76,14 @@ void UCarlaEpisode::InitializeAtBeginPlay()
{
UE_LOG(LogCarla, Error, TEXT("Can't find spectator!"));
}
for (TActorIterator<ATrafficSignBase> It(World); It; ++It)
{
ATrafficSignBase *Actor = *It;
check(Actor != nullptr);
FActorDescription Description;
Description.Id = UCarlaEpisode_GetTrafficSignId(Actor->GetTrafficSignState());
Description.Class = Actor->GetClass();
ActorDispatcher.GetActorRegistry().Register(*Actor, Description);
}
}

View File

@ -7,18 +7,33 @@
#include "Carla.h"
#include "Carla/Sensor/WorldObserver.h"
#include "Carla/Traffic/TrafficLightBase.h"
#include "CoreGlobals.h"
#include <compiler/disable-ue4-macros.h>
#include <carla/sensor/SensorRegistry.h>
#include <compiler/enable-ue4-macros.h>
static uint8 AWorldObserver_GetActorState(const FActorView &View)
{
if (View.IsTrafficLight())
{
auto TrafficLight = Cast<ATrafficLightBase>(View.GetActor());
if (TrafficLight != nullptr)
{
return static_cast<uint8>(TrafficLight->GetTrafficSignState());
}
}
return 0u;
}
static carla::Buffer AWorldObserver_Serialize(
carla::Buffer buffer,
double game_timestamp,
double platform_timestamp,
const FActorRegistry &Registry) {
const FActorRegistry &Registry)
{
using Serializer = carla::sensor::s11n::EpisodeStateSerializer;
using ActorDynamicState = carla::sensor::data::ActorDynamicState;
@ -43,7 +58,8 @@ static carla::Buffer AWorldObserver_Serialize(
ActorDynamicState info = {
actor_view.GetActorId(),
actor_view.GetActor()->GetActorTransform(),
carla::geom::Vector3D{velocity.X, velocity.Y, velocity.Z}
carla::geom::Vector3D{velocity.X, velocity.Y, velocity.Z},
AWorldObserver_GetActorState(actor_view)
};
write_data(info);
}