Added Traffic Lights from OpenDRIVE.
This commit is contained in:
parent
0b9084495b
commit
d533e359b6
|
@ -11,64 +11,64 @@
|
|||
namespace carla {
|
||||
namespace client {
|
||||
|
||||
void TrafficLight::SetState(rpc::TrafficLightState state) {
|
||||
GetEpisode().Lock()->SetTrafficLightState(*this, state);
|
||||
}
|
||||
|
||||
rpc::TrafficLightState TrafficLight::GetState() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.state;
|
||||
}
|
||||
|
||||
void TrafficLight::SetGreenTime(float green_time) {
|
||||
GetEpisode().Lock()->SetTrafficLightGreenTime(*this, green_time);
|
||||
}
|
||||
|
||||
float TrafficLight::GetGreenTime() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.green_time;
|
||||
}
|
||||
|
||||
void TrafficLight::SetYellowTime(float yellow_time) {
|
||||
GetEpisode().Lock()->SetTrafficLightYellowTime(*this, yellow_time);
|
||||
}
|
||||
|
||||
float TrafficLight::GetYellowTime() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.yellow_time;
|
||||
}
|
||||
|
||||
void TrafficLight::SetRedTime(float red_time) {
|
||||
GetEpisode().Lock()->SetTrafficLightRedTime(*this, red_time);
|
||||
}
|
||||
|
||||
float TrafficLight::GetRedTime() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.red_time;
|
||||
}
|
||||
|
||||
float TrafficLight::GetElapsedTime() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.elapsed_time;
|
||||
}
|
||||
|
||||
void TrafficLight::Freeze(bool freeze) {
|
||||
GetEpisode().Lock()->FreezeTrafficLight(*this, freeze);
|
||||
}
|
||||
|
||||
bool TrafficLight::IsFrozen() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.time_is_frozen;
|
||||
}
|
||||
|
||||
uint32_t TrafficLight::GetPoleIndex()
|
||||
{
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.pole_index;
|
||||
}
|
||||
|
||||
std::vector<SharedPtr<TrafficLight>> TrafficLight::GetGroupTrafficLights() {
|
||||
std::vector<SharedPtr<TrafficLight>> result;
|
||||
auto ids = GetEpisode().Lock()->GetGroupTrafficLights(*this);
|
||||
for (auto id : ids) {
|
||||
SharedPtr<Actor> actor = GetWorld().GetActors()->Find(id);
|
||||
result.push_back(boost::static_pointer_cast<TrafficLight>(actor));
|
||||
void TrafficLight::SetState(rpc::TrafficLightState state) {
|
||||
GetEpisode().Lock()->SetTrafficLightState(*this, state);
|
||||
}
|
||||
|
||||
rpc::TrafficLightState TrafficLight::GetState() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.state;
|
||||
}
|
||||
|
||||
void TrafficLight::SetGreenTime(float green_time) {
|
||||
GetEpisode().Lock()->SetTrafficLightGreenTime(*this, green_time);
|
||||
}
|
||||
|
||||
float TrafficLight::GetGreenTime() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.green_time;
|
||||
}
|
||||
|
||||
void TrafficLight::SetYellowTime(float yellow_time) {
|
||||
GetEpisode().Lock()->SetTrafficLightYellowTime(*this, yellow_time);
|
||||
}
|
||||
|
||||
float TrafficLight::GetYellowTime() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.yellow_time;
|
||||
}
|
||||
|
||||
void TrafficLight::SetRedTime(float red_time) {
|
||||
GetEpisode().Lock()->SetTrafficLightRedTime(*this, red_time);
|
||||
}
|
||||
|
||||
float TrafficLight::GetRedTime() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.red_time;
|
||||
}
|
||||
|
||||
float TrafficLight::GetElapsedTime() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.elapsed_time;
|
||||
}
|
||||
|
||||
void TrafficLight::Freeze(bool freeze) {
|
||||
GetEpisode().Lock()->FreezeTrafficLight(*this, freeze);
|
||||
}
|
||||
|
||||
bool TrafficLight::IsFrozen() const {
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.time_is_frozen;
|
||||
}
|
||||
|
||||
uint32_t TrafficLight::GetPoleIndex()
|
||||
{
|
||||
return GetEpisode().Lock()->GetActorSnapshot(*this).state.traffic_light_data.pole_index;
|
||||
}
|
||||
|
||||
std::vector<SharedPtr<TrafficLight>> TrafficLight::GetGroupTrafficLights() {
|
||||
std::vector<SharedPtr<TrafficLight>> result;
|
||||
auto ids = GetEpisode().Lock()->GetGroupTrafficLights(*this);
|
||||
for (auto id : ids) {
|
||||
SharedPtr<Actor> actor = GetWorld().GetActors()->Find(id);
|
||||
result.push_back(boost::static_pointer_cast<TrafficLight>(actor));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
} // namespace carla
|
||||
|
|
|
@ -12,57 +12,57 @@
|
|||
namespace carla {
|
||||
namespace client {
|
||||
|
||||
class TrafficLight : public Actor {
|
||||
class TrafficLight : public Actor {
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
explicit TrafficLight(ActorInitializer init) : Actor(std::move(init)) {}
|
||||
explicit TrafficLight(ActorInitializer init) : Actor(std::move(init)) {}
|
||||
|
||||
void SetState(rpc::TrafficLightState state);
|
||||
void SetState(rpc::TrafficLightState state);
|
||||
|
||||
/// Return the current state of the traffic light.
|
||||
///
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
rpc::TrafficLightState GetState() const;
|
||||
/// Return the current state of the traffic light.
|
||||
///
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
rpc::TrafficLightState GetState() const;
|
||||
|
||||
void SetGreenTime(float green_time);
|
||||
void SetGreenTime(float green_time);
|
||||
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
float GetGreenTime() const;
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
float GetGreenTime() const;
|
||||
|
||||
void SetYellowTime(float yellow_time);
|
||||
void SetYellowTime(float yellow_time);
|
||||
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
float GetYellowTime() const;
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
float GetYellowTime() const;
|
||||
|
||||
void SetRedTime(float red_time);
|
||||
void SetRedTime(float red_time);
|
||||
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
float GetRedTime() const;
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
float GetRedTime() const;
|
||||
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
float GetElapsedTime() const;
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
float GetElapsedTime() const;
|
||||
|
||||
void Freeze(bool freeze);
|
||||
void Freeze(bool freeze);
|
||||
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
bool IsFrozen() const;
|
||||
/// @note This function does not call the simulator, it returns the data
|
||||
/// received in the last tick.
|
||||
bool IsFrozen() const;
|
||||
|
||||
/// Returns the index of the pole in the traffic light group
|
||||
uint32_t GetPoleIndex();
|
||||
/// Returns the index of the pole in the traffic light group
|
||||
uint32_t GetPoleIndex();
|
||||
|
||||
/// Return all traffic lights in the group this one belongs to.
|
||||
///
|
||||
/// @note This function calls the simulator
|
||||
std::vector<SharedPtr<TrafficLight>> GetGroupTrafficLights();
|
||||
/// Return all traffic lights in the group this one belongs to.
|
||||
///
|
||||
/// @note This function calls the simulator
|
||||
std::vector<SharedPtr<TrafficLight>> GetGroupTrafficLights();
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
} // namespace carla
|
||||
|
|
|
@ -14,44 +14,44 @@ namespace carla {
|
|||
namespace opendrive {
|
||||
namespace parser {
|
||||
|
||||
void ControllerParser::Parse(
|
||||
void ControllerParser::Parse(
|
||||
const pugi::xml_document &xml,
|
||||
carla::road::MapBuilder &map_builder) {
|
||||
|
||||
// Extracting the OpenDRIVE
|
||||
const pugi::xml_node opendrive_node = xml.child("OpenDRIVE");
|
||||
for (pugi::xml_node controller_node = opendrive_node.child("controller");
|
||||
controller_node;
|
||||
controller_node = controller_node.next_sibling("controller")) {
|
||||
// Extracting the OpenDRIVE
|
||||
const pugi::xml_node opendrive_node = xml.child("OpenDRIVE");
|
||||
for (pugi::xml_node controller_node = opendrive_node.child("controller");
|
||||
controller_node;
|
||||
controller_node = controller_node.next_sibling("controller")) {
|
||||
|
||||
const road::ContId controller_id = controller_node.attribute("id").value();
|
||||
const std::string controller_name = controller_node.attribute("name").value();
|
||||
const uint32_t controller_sequence = controller_node.attribute("sequence").as_uint();
|
||||
const road::ContId controller_id = controller_node.attribute("id").value();
|
||||
const std::string controller_name = controller_node.attribute("name").value();
|
||||
const uint32_t controller_sequence = controller_node.attribute("sequence").as_uint();
|
||||
|
||||
log_debug("Controller: ",
|
||||
controller_id,
|
||||
controller_name,
|
||||
controller_sequence);
|
||||
log_debug("Controller: ",
|
||||
controller_id,
|
||||
controller_name,
|
||||
controller_sequence);
|
||||
|
||||
std::set<road::SignId> signals;
|
||||
std::set<road::SignId> signals;
|
||||
|
||||
for (pugi::xml_node control_node : controller_node.children("control")) {
|
||||
const road::SignId signal_id = control_node.attribute("signalId").value();
|
||||
// The controller_type is included in the OpenDrive format but not used yet
|
||||
// const std::string controller_type = control_node.attribute("type").value();
|
||||
signals.insert(signal_id);
|
||||
for (pugi::xml_node control_node : controller_node.children("control")) {
|
||||
const road::SignId signal_id = control_node.attribute("signalId").value();
|
||||
// The controller_type is included in the OpenDrive format but not used yet
|
||||
// const std::string controller_type = control_node.attribute("type").value();
|
||||
signals.insert(signal_id);
|
||||
}
|
||||
|
||||
map_builder.CreateController(
|
||||
controller_id,
|
||||
controller_name,
|
||||
controller_sequence,
|
||||
std::move(signals)
|
||||
);
|
||||
}
|
||||
|
||||
map_builder.CreateController(
|
||||
controller_id,
|
||||
controller_name,
|
||||
controller_sequence,
|
||||
std::move(signals)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace parser
|
||||
} // namespace opendrive
|
||||
} // namespace carla
|
||||
|
|
|
@ -14,51 +14,51 @@
|
|||
namespace carla {
|
||||
namespace road {
|
||||
|
||||
class MapBuilder;
|
||||
class MapBuilder;
|
||||
|
||||
class Controller : private MovableNonCopyable {
|
||||
class Controller : private MovableNonCopyable {
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
Controller(
|
||||
ContId id,
|
||||
std::string name,
|
||||
uint32_t sequence)
|
||||
: _id(id),
|
||||
_name(name),
|
||||
_sequence(sequence){}
|
||||
Controller(
|
||||
ContId id,
|
||||
std::string name,
|
||||
uint32_t sequence)
|
||||
: _id(id),
|
||||
_name(name),
|
||||
_sequence(sequence){}
|
||||
|
||||
const ContId& GetControllerId() const{
|
||||
return _id;
|
||||
}
|
||||
const ContId& GetControllerId() const{
|
||||
return _id;
|
||||
}
|
||||
|
||||
const std::string& GetName() const {
|
||||
return _name;
|
||||
}
|
||||
const std::string& GetName() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
const uint32_t &GetSequence() const {
|
||||
return _sequence;
|
||||
}
|
||||
const uint32_t &GetSequence() const {
|
||||
return _sequence;
|
||||
}
|
||||
|
||||
const std::set<SignId>& GetSignals() const {
|
||||
return _signals;
|
||||
}
|
||||
const std::set<SignId>& GetSignals() const {
|
||||
return _signals;
|
||||
}
|
||||
|
||||
const std::set<JuncId>& GetJunctions() const {
|
||||
return _junctions;
|
||||
}
|
||||
const std::set<JuncId>& GetJunctions() const {
|
||||
return _junctions;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
friend MapBuilder;
|
||||
friend MapBuilder;
|
||||
|
||||
ContId _id;
|
||||
std::string _name;
|
||||
uint32_t _sequence;
|
||||
ContId _id;
|
||||
std::string _name;
|
||||
uint32_t _sequence;
|
||||
|
||||
std::set<JuncId> _junctions;
|
||||
std::set<SignId> _signals;
|
||||
};
|
||||
std::set<JuncId> _junctions;
|
||||
std::set<SignId> _signals;
|
||||
};
|
||||
|
||||
} // namespace road
|
||||
} // namespace carla
|
||||
|
|
|
@ -769,6 +769,10 @@ namespace road {
|
|||
auto it = _map_data._controllers.find(controller);
|
||||
DEBUG_ASSERT(it != _map_data._controllers.end());
|
||||
it->second->_junctions.insert(junction.first);
|
||||
for(const auto & signal : it->second->_signals) {
|
||||
auto signal_it = _map_data._signals.find(signal);
|
||||
signal_it->second->_controllers.insert(controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
|
@ -173,6 +173,10 @@ namespace road {
|
|||
return _transform;
|
||||
}
|
||||
|
||||
const std::set<ContId>& GetControllers() const {
|
||||
return _controllers;
|
||||
}
|
||||
|
||||
private:
|
||||
friend MapBuilder;
|
||||
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
// 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>.
|
||||
// Copyright (c) 2020 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 "SignComponent.h"
|
||||
|
||||
|
||||
// Sets default values for this component's properties
|
||||
USignComponent::USignComponent()
|
||||
{
|
||||
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
|
||||
// off to improve performance if you don't need them.
|
||||
PrimaryComponentTick.bCanEverTick = false;
|
||||
|
||||
}
|
||||
|
||||
// Called when the game starts
|
||||
|
@ -27,3 +26,12 @@ void USignComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorC
|
|||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
}
|
||||
|
||||
const FString& USignComponent::GetSignId() const
|
||||
{
|
||||
return SignId;
|
||||
}
|
||||
|
||||
void USignComponent::SetSignId(const FString &Id) {
|
||||
SignId = Id;
|
||||
}
|
|
@ -1,40 +1,41 @@
|
|||
// 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>.
|
||||
// Copyright (c) 2020 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 "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "Components/SceneComponent.h"
|
||||
#include "Carla/OpenDrive/OpenDrive.h"
|
||||
#include "SignComponent.generated.h"
|
||||
|
||||
|
||||
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
|
||||
class CARLA_API USignComponent : public UActorComponent
|
||||
class CARLA_API USignComponent : public USceneComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Sets default values for this component's properties
|
||||
USignComponent();
|
||||
|
||||
void SetSignId(carla::road::SignId SignId)
|
||||
{
|
||||
Id = SignId;
|
||||
}
|
||||
UFUNCTION(BlueprintPure)
|
||||
const FString &GetSignId() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetSignId(const FString &Id);
|
||||
|
||||
protected:
|
||||
// Called when the game starts
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
public:
|
||||
// Called every frame
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
|
||||
private:
|
||||
carla::road::SignId Id;
|
||||
|
||||
FTransform Transform;
|
||||
|
||||
UPROPERTY(Category = "Traffic Sign", EditAnywhere)
|
||||
FString SignId;
|
||||
|
||||
};
|
||||
|
|
|
@ -1,34 +1,71 @@
|
|||
// 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>.
|
||||
// Copyright (c) 2020 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 "TrafficLightComponent.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "TrafficLightGroup.h"
|
||||
#include "TrafficLightManager.h"
|
||||
|
||||
|
||||
// Sets default values for this component's properties
|
||||
UTrafficLightComponent::UTrafficLightComponent()
|
||||
: Super()
|
||||
{
|
||||
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
|
||||
// off to improve performance if you don't need them.
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
// Called when the game starts
|
||||
void UTrafficLightComponent::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
// ...
|
||||
// Search the Traffic Light Manager
|
||||
TArray<AActor*> TrafficLightManagerArray;
|
||||
UGameplayStatics::GetAllActorsOfClass(
|
||||
GetWorld(),
|
||||
ATrafficLightManager::StaticClass(),
|
||||
TrafficLightManagerArray);
|
||||
|
||||
// Create it if missing
|
||||
if (!TrafficLightManagerArray.Num())
|
||||
{
|
||||
TrafficLightManagerArray.Add(
|
||||
GetWorld()->SpawnActor<ATrafficLightManager>());
|
||||
}
|
||||
|
||||
// Register this component
|
||||
ATrafficLightManager *TrafficLightManager = Cast<ATrafficLightManager>(TrafficLightManagerArray.Top());
|
||||
TrafficLightManager->RegisterLightComponent(this);
|
||||
}
|
||||
|
||||
|
||||
// Called every frame
|
||||
void UTrafficLightComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
||||
{
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
void UTrafficLightComponent::SetLightState(ETrafficLightState NewState)
|
||||
{
|
||||
LightState = NewState;
|
||||
LightChangeDispatcher.Broadcast();
|
||||
}
|
||||
|
||||
ETrafficLightState UTrafficLightComponent::GetLightState() const
|
||||
{
|
||||
return LightState;
|
||||
}
|
||||
|
||||
void UTrafficLightComponent::SetFrozenGroup(bool InFreeze)
|
||||
{
|
||||
if (TrafficLightGroup)
|
||||
{
|
||||
TrafficLightGroup->SetFrozenGroup(InFreeze);
|
||||
}
|
||||
}
|
||||
|
||||
ATrafficLightGroup* UTrafficLightComponent::GetGroup()
|
||||
{
|
||||
return TrafficLightGroup;
|
||||
}
|
|
@ -1,14 +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>.
|
||||
// Copyright (c) 2020 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 "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "SignComponent.h"
|
||||
#include "TrafficLightState.h"
|
||||
#include "TrafficLightComponent.generated.h"
|
||||
|
||||
class ATrafficLightManager;
|
||||
class ATrafficLightGroup;
|
||||
|
||||
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
|
||||
class CARLA_API UTrafficLightComponent : public UActorComponent
|
||||
// Delegate to define dispatcher
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FLightChangeDispatcher);
|
||||
//DECLARE_DYNAMIC_MULTICAST_DELEGATE_RetVal(ETrafficLightState, FLightChangeDispatcher);
|
||||
|
||||
UCLASS(Blueprintable, ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
|
||||
class CARLA_API UTrafficLightComponent : public USignComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
|
@ -16,12 +27,34 @@ public:
|
|||
// Sets default values for this component's properties
|
||||
UTrafficLightComponent();
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetLightState(ETrafficLightState NewState);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
ETrafficLightState GetLightState() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetFrozenGroup(bool InFreeze);
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
ATrafficLightGroup* GetGroup();
|
||||
|
||||
protected:
|
||||
// Called when the game starts
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
public:
|
||||
// Called every frame
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
private:
|
||||
|
||||
friend ATrafficLightManager;
|
||||
UPROPERTY(Category = "Traffic Light", EditAnywhere)
|
||||
ETrafficLightState LightState;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Traffic Light")
|
||||
FLightChangeDispatcher LightChangeDispatcher;
|
||||
|
||||
UPROPERTY()
|
||||
ATrafficLightGroup *TrafficLightGroup = nullptr;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright (c) 2020 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 "TrafficLightController.h"
|
||||
|
||||
UTrafficLightController::UTrafficLightController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UTrafficLightController::SetState(TArray<FTrafficLightStage> States)
|
||||
{
|
||||
LightStates = States;
|
||||
CurrentState = 0;
|
||||
}
|
||||
|
||||
const FTrafficLightStage &UTrafficLightController::GetCurrentState() const
|
||||
{
|
||||
return LightStates[CurrentState];
|
||||
}
|
||||
|
||||
float UTrafficLightController::NextState()
|
||||
{
|
||||
CurrentState = (CurrentState + 1) % LightStates.Num();
|
||||
SetTrafficLightsState(GetCurrentState().State);
|
||||
return GetCurrentState().Time;
|
||||
}
|
||||
|
||||
const TArray<UTrafficLightComponent *> &UTrafficLightController::GetTrafficLights()
|
||||
{
|
||||
return TrafficLights;
|
||||
}
|
||||
|
||||
void UTrafficLightController::AddTrafficLight(UTrafficLightComponent * TrafficLight)
|
||||
{
|
||||
TrafficLights.Add(TrafficLight);
|
||||
}
|
||||
|
||||
const FString &UTrafficLightController::GetControllerId() const
|
||||
{
|
||||
return ControllerId;
|
||||
}
|
||||
|
||||
void UTrafficLightController::SetControllerId(const FString &Id)
|
||||
{
|
||||
ControllerId = Id;
|
||||
}
|
||||
|
||||
bool UTrafficLightController::IsCycleFinished() const
|
||||
{
|
||||
return CurrentState == (LightStates.Num() - 1);
|
||||
}
|
||||
|
||||
void UTrafficLightController::SetTrafficLightsState(ETrafficLightState NewState)
|
||||
{
|
||||
for(auto *Light : TrafficLights)
|
||||
{
|
||||
Light->SetLightState(NewState);
|
||||
}
|
||||
}
|
||||
|
||||
int UTrafficLightController::GetSequence() const
|
||||
{
|
||||
return Sequence;
|
||||
}
|
||||
|
||||
void UTrafficLightController::SetSequence(int InSequence)
|
||||
{
|
||||
Sequence = InSequence;
|
||||
}
|
||||
|
||||
void UTrafficLightController::ResetState()
|
||||
{
|
||||
CurrentState = (LightStates.Num() - 1);
|
||||
SetTrafficLightsState(GetCurrentState().State);
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
// Copyright (c) 2020 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 "CoreMinimal.h"
|
||||
#include "Object.h"
|
||||
#include "TrafficLightState.h"
|
||||
#include "TrafficLightComponent.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "TrafficLightController.generated.h"
|
||||
|
||||
// Defines a stage of a semaphor with a State and
|
||||
// the time this state lasts
|
||||
USTRUCT(BlueprintType)
|
||||
struct FTrafficLightStage
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
float Time;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
ETrafficLightState State;
|
||||
};
|
||||
|
||||
// Maps a controller from OpenDrive.
|
||||
// Controls the asociated traffic lights and its cycles
|
||||
UCLASS(BlueprintType)
|
||||
class CARLA_API UTrafficLightController : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UTrafficLightController();
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetState(TArray<FTrafficLightStage> States);
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
const FTrafficLightStage &GetCurrentState() const;
|
||||
|
||||
// Updates traffic light components to the next state
|
||||
UFUNCTION(BlueprintCallable)
|
||||
float NextState();
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
const TArray<UTrafficLightComponent *> &GetTrafficLights();
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
const FString &GetControllerId() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetControllerId(const FString &Id);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void AddTrafficLight(UTrafficLightComponent * TrafficLight);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
bool IsCycleFinished() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetTrafficLightsState(ETrafficLightState NewState);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
int GetSequence() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetSequence(int InSequence);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void ResetState();
|
||||
private:
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FString ControllerId;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
int CurrentState = 0;
|
||||
|
||||
// Pairs with the state of the semaphors (time - state) e.g. 10s in green
|
||||
UPROPERTY(EditAnywhere)
|
||||
TArray<FTrafficLightStage> LightStates = {
|
||||
{10, ETrafficLightState::Green}, {3, ETrafficLightState::Yellow}, {2, ETrafficLightState::Red}};
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
TArray<UTrafficLightComponent *> TrafficLights;
|
||||
|
||||
// Sequence within junction (unused for now)
|
||||
UPROPERTY(EditAnywhere)
|
||||
int Sequence = 0;
|
||||
};
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) 2020 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.h"
|
||||
#include "TrafficLightGroup.h"
|
||||
|
||||
|
||||
// Sets default values
|
||||
ATrafficLightGroup::ATrafficLightGroup()
|
||||
{
|
||||
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
|
||||
RootComponent = SceneComponent;
|
||||
}
|
||||
|
||||
// Called when the game starts or when spawned
|
||||
void ATrafficLightGroup::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
}
|
||||
|
||||
void ATrafficLightGroup::SetFrozenGroup(bool InFreeze)
|
||||
{
|
||||
bIsFrozen = InFreeze;
|
||||
}
|
||||
|
||||
// Called every frame
|
||||
void ATrafficLightGroup::Tick(float DeltaTime)
|
||||
{
|
||||
Super::Tick(DeltaTime);
|
||||
|
||||
if (bIsFrozen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Timer -= DeltaTime;
|
||||
|
||||
if(Timer <= 0 && Controllers.Num())
|
||||
{
|
||||
NextCycleStep();
|
||||
}
|
||||
}
|
||||
|
||||
void ATrafficLightGroup::NextCycleStep()
|
||||
{
|
||||
UTrafficLightController* controller = Controllers[CurrentController];
|
||||
if (controller->IsCycleFinished())
|
||||
{
|
||||
NextController();
|
||||
}
|
||||
else
|
||||
{
|
||||
Timer = controller->NextState();
|
||||
}
|
||||
}
|
||||
|
||||
void ATrafficLightGroup::NextController()
|
||||
{
|
||||
CurrentController = (CurrentController + 1) % Controllers.Num();
|
||||
UTrafficLightController* controller = Controllers[CurrentController];
|
||||
Timer = controller->NextState();
|
||||
}
|
||||
|
||||
int ATrafficLightGroup::GetJunctionId() const
|
||||
{
|
||||
return JunctionId;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright (c) 2020 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 "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "Components/SceneComponent.h"
|
||||
#include "TrafficLightComponent.h"
|
||||
#include "TrafficLightController.h"
|
||||
#include "TrafficLightGroup.generated.h"
|
||||
|
||||
class ATrafficLightManager;
|
||||
|
||||
// Class with the logic of semaphors
|
||||
UCLASS()
|
||||
class CARLA_API ATrafficLightGroup : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Sets default values for this actor's properties
|
||||
ATrafficLightGroup();
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
TArray<UTrafficLightController*>& GetControllers() {
|
||||
return Controllers;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetFrozenGroup(bool InFreeze);
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
int GetJunctionId() const;
|
||||
|
||||
protected:
|
||||
// Called when the game starts or when spawned
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
// Called every frame
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
|
||||
private:
|
||||
|
||||
friend ATrafficLightManager;
|
||||
UPROPERTY(Category = "Traffic Group", VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
|
||||
USceneComponent *SceneComponent;
|
||||
|
||||
UPROPERTY(Category = "Traffic Group", EditAnywhere)
|
||||
TArray<UTrafficLightController*> Controllers;
|
||||
|
||||
UPROPERTY()
|
||||
float Timer = 0;
|
||||
|
||||
UPROPERTY()
|
||||
int CurrentController = 0;
|
||||
|
||||
UFUNCTION()
|
||||
void NextCycleStep();
|
||||
|
||||
UFUNCTION()
|
||||
void NextController();
|
||||
|
||||
UPROPERTY(Category = "Traffic Group", EditAnywhere)
|
||||
bool bIsFrozen = false;
|
||||
|
||||
UPROPERTY(Category = "Traffic Group", EditAnywhere)
|
||||
int JunctionId = -1;
|
||||
};
|
|
@ -0,0 +1,116 @@
|
|||
// Copyright (c) 2020 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 "TrafficLightManager.h"
|
||||
#include "Game/CarlaStatics.h"
|
||||
#include <string>
|
||||
|
||||
ATrafficLightManager::ATrafficLightManager() {
|
||||
PrimaryActorTick.bCanEverTick = false;
|
||||
}
|
||||
|
||||
void ATrafficLightManager::RegisterLightComponent(UTrafficLightComponent * TrafficLight) {
|
||||
// Cast to std::string
|
||||
carla::road::SignId SignId(TCHAR_TO_UTF8(*(TrafficLight->GetSignId())));
|
||||
|
||||
// Get OpenDRIVE signal
|
||||
if (GetMap()->GetSignals().count(SignId) == 0)
|
||||
{
|
||||
carla::log_warning("Error: missing signal with id:", SignId);
|
||||
return;
|
||||
}
|
||||
const auto &Signal = GetMap()->GetSignals().at(SignId);
|
||||
if(Signal->GetControllers().empty())
|
||||
{
|
||||
carla::log_warning("Error: no controllers in signal", SignId);
|
||||
return;
|
||||
}
|
||||
// Only one controller per signal
|
||||
auto ControllerId = *(Signal->GetControllers().begin());
|
||||
|
||||
// Get controller
|
||||
const auto &Controller = GetMap()->GetControllers().at(ControllerId);
|
||||
if(Controller->GetJunctions().empty())
|
||||
{
|
||||
carla::log_warning("Error: no junctions in controller", ControllerId);
|
||||
return;
|
||||
}
|
||||
// Get junction of the controller
|
||||
auto JunctionId = *(Controller->GetJunctions().begin());
|
||||
|
||||
// Search/create TrafficGroup (junction traffic light manager)
|
||||
if(!TrafficGroups.Contains(JunctionId))
|
||||
{
|
||||
auto * TrafficLightGroup =
|
||||
GetWorld()->SpawnActor<ATrafficLightGroup>();
|
||||
TrafficLightGroup->JunctionId = JunctionId;
|
||||
TrafficGroups.Add(JunctionId, TrafficLightGroup);
|
||||
carla::log_warning("Spawn TrafficLight Group");
|
||||
}
|
||||
auto * TrafficLightGroup = TrafficGroups[JunctionId];
|
||||
|
||||
// Search/create controller in the junction
|
||||
if(!TrafficControllers.Contains(ControllerId.c_str()))
|
||||
{
|
||||
auto *TrafficLightController = NewObject<UTrafficLightController>();
|
||||
TrafficLightController->SetControllerId(ControllerId.c_str());
|
||||
TrafficLightGroup->GetControllers().Add(TrafficLightController);
|
||||
TrafficControllers.Add(ControllerId.c_str(), TrafficLightController);
|
||||
carla::log_warning("Created Controller");
|
||||
}
|
||||
auto *TrafficLightController = TrafficControllers[ControllerId.c_str()];
|
||||
|
||||
TrafficLight->TrafficLightGroup = TrafficLightGroup;
|
||||
|
||||
// Add signal to controller
|
||||
TrafficLightController->AddTrafficLight(TrafficLight);
|
||||
TrafficLightController->ResetState();
|
||||
|
||||
// Add signal to map
|
||||
TrafficLights.Add(TrafficLight->GetSignId(), TrafficLight);
|
||||
}
|
||||
|
||||
const boost::optional<carla::road::Map>& ATrafficLightManager::GetMap() {
|
||||
if(!GameMode) {
|
||||
GameMode = UCarlaStatics::GetGameMode(this);
|
||||
}
|
||||
return GameMode->GetMap();
|
||||
}
|
||||
|
||||
// Called when the game starts
|
||||
void ATrafficLightManager::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
}
|
||||
|
||||
ATrafficLightGroup* ATrafficLightManager::GetTrafficGroup(carla::road::JuncId JunctionId)
|
||||
{
|
||||
if (TrafficGroups.Contains(JunctionId))
|
||||
{
|
||||
return TrafficGroups[JunctionId];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
UTrafficLightController* ATrafficLightManager::GetController(FString ControllerId)
|
||||
{
|
||||
if (TrafficControllers.Contains(ControllerId))
|
||||
{
|
||||
return TrafficControllers[ControllerId];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UTrafficLightComponent* ATrafficLightManager::GetTrafficLight(FString SignId)
|
||||
{
|
||||
if (!TrafficLights.Contains(SignId))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return TrafficLights[SignId];
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) 2020 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 "TrafficLightComponent.h"
|
||||
#include "TrafficLightGroup.h"
|
||||
#include "Game/CarlaGameModeBase.h"
|
||||
#include "TrafficLightManager.generated.h"
|
||||
|
||||
// Class In charge of creating and assigning traffic
|
||||
// light groups, controllers and components.
|
||||
UCLASS()
|
||||
class CARLA_API ATrafficLightManager : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
ATrafficLightManager();
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void RegisterLightComponent(UTrafficLightComponent * TrafficLight);
|
||||
|
||||
const boost::optional<carla::road::Map> &GetMap();
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
ATrafficLightGroup* GetTrafficGroup(int JunctionId);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
UTrafficLightController* GetController(FString ControllerId);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
UTrafficLightComponent* GetTrafficLight(FString SignId);
|
||||
|
||||
protected:
|
||||
// Called when the game starts or when spawned
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
private:
|
||||
|
||||
// Cached Carla Game Mode
|
||||
UPROPERTY()
|
||||
ACarlaGameModeBase *GameMode = 0;
|
||||
|
||||
// Mapped references to ATrafficLightGroup (junction)
|
||||
UPROPERTY()
|
||||
TMap<int, ATrafficLightGroup *> TrafficGroups;
|
||||
|
||||
// Mapped references to UTrafficLightController (controllers)
|
||||
UPROPERTY()
|
||||
TMap<FString, UTrafficLightController *> TrafficControllers;
|
||||
|
||||
// Mapped references to individual TrafficLightComponents
|
||||
UPROPERTY()
|
||||
TMap<FString, UTrafficLightComponent *> TrafficLights;
|
||||
};
|
Loading…
Reference in New Issue