Add game mode for new RPC server
This commit is contained in:
parent
5a8bb66c5d
commit
03c5ccc9d2
|
@ -6,10 +6,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "carla/Time.h"
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
|
||||
#include <rpc/server.h>
|
||||
|
||||
#include <future>
|
||||
|
||||
namespace carla {
|
||||
namespace rpc {
|
||||
|
||||
|
@ -94,10 +98,9 @@ namespace detail {
|
|||
_server.async_run(worker_threads);
|
||||
}
|
||||
|
||||
template <typename Duration>
|
||||
void SyncRunFor(Duration duration) {
|
||||
void SyncRunFor(time_duration duration) {
|
||||
_sync_io_service.reset();
|
||||
_sync_io_service.run_for(duration);
|
||||
_sync_io_service.run_for(duration.to_chrono());
|
||||
}
|
||||
|
||||
/// @warning does not stop the game thread.
|
||||
|
|
|
@ -13,7 +13,7 @@ AppliedDefaultGraphicsPerformance=Maximum
|
|||
EditorStartupMap=/Game/Maps/Town01.Town01
|
||||
GameDefaultMap=/Game/Maps/Town01.Town01
|
||||
ServerDefaultMap=/Game/Maps/Town01.Town01
|
||||
GlobalDefaultGameMode=/Game/Blueprints/Game/CarlaGameMode.CarlaGameMode_C
|
||||
GlobalDefaultGameMode=/Script/Carla.TheNewCarlaGameModeBase
|
||||
GameInstanceClass=/Script/Carla.CarlaGameInstance
|
||||
TransitionMap=/Game/Maps/Town01.Town01
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "Carla/Actor/ActorBlueprintFunctionLibrary.h"
|
||||
#include "Carla/Actor/ActorSpawner.h"
|
||||
|
||||
void AActorDispatcher::Bind(FActorDefinition Definition, SpawnFunctionType Functor)
|
||||
void FActorDispatcher::Bind(FActorDefinition Definition, SpawnFunctionType Functor)
|
||||
{
|
||||
if (UActorBlueprintFunctionLibrary::CheckActorDefinition(Definition))
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ void AActorDispatcher::Bind(FActorDefinition Definition, SpawnFunctionType Funct
|
|||
}
|
||||
}
|
||||
|
||||
void AActorDispatcher::Bind(IActorSpawner &ActorSpawner)
|
||||
void FActorDispatcher::Bind(IActorSpawner &ActorSpawner)
|
||||
{
|
||||
for (const auto &Definition : ActorSpawner.MakeDefinitions())
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ void AActorDispatcher::Bind(IActorSpawner &ActorSpawner)
|
|||
}
|
||||
}
|
||||
|
||||
AActor *AActorDispatcher::SpawnActor(
|
||||
AActor *FActorDispatcher::SpawnActor(
|
||||
const FTransform &Transform,
|
||||
const FActorDescription &Description)
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ AActor *AActorDispatcher::SpawnActor(
|
|||
return Actor;
|
||||
}
|
||||
|
||||
void AActorDispatcher::DestroyActor(AActor *Actor)
|
||||
void FActorDispatcher::DestroyActor(AActor *Actor)
|
||||
{
|
||||
if (Actor != nullptr)
|
||||
{
|
||||
|
|
|
@ -11,20 +11,14 @@
|
|||
#include "Carla/Actor/ActorRegistry.h"
|
||||
|
||||
#include "Containers/Array.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "Templates/Function.h"
|
||||
|
||||
#include "ActorDispatcher.generated.h"
|
||||
|
||||
class IActorSpawner;
|
||||
|
||||
/// Actor in charge of binding ActorDefinitions to spawn functions, as well as
|
||||
/// keeping the registry of all the actors spawned.
|
||||
UCLASS()
|
||||
class CARLA_API AActorDispatcher : public AActor
|
||||
class FActorDispatcher
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
using SpawnFunctionType = TFunction<AActor*(const FTransform &, const FActorDescription &)>;
|
||||
|
@ -44,16 +38,13 @@ public:
|
|||
/// despawn an actor created with this function call DestroyActor.
|
||||
///
|
||||
/// Return nullptr on failure.
|
||||
UFUNCTION(BlueprintCallable)
|
||||
AActor *SpawnActor(
|
||||
const FTransform &Transform,
|
||||
const FActorDescription &ActorDescription);
|
||||
|
||||
/// Destroys an actor, properly removing it from the registry.
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void DestroyActor(AActor *Actor);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
const TArray<FActorDefinition> &GetActorDefinitions() const
|
||||
{
|
||||
return Definitions;
|
||||
|
|
|
@ -14,12 +14,11 @@
|
|||
#include "Engine/Engine.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
static FDataRouter &GetDataRouter(UWorld *World)
|
||||
static FDataRouter *GetDataRouter(UWorld *World)
|
||||
{
|
||||
check(World != nullptr);
|
||||
ACarlaGameModeBase *GameMode = Cast<ACarlaGameModeBase>(World->GetAuthGameMode());
|
||||
check(GameMode != nullptr);
|
||||
return GameMode->GetDataRouter();
|
||||
return GameMode != nullptr ? &GameMode->GetDataRouter() : nullptr;
|
||||
}
|
||||
|
||||
UAgentComponent::UAgentComponent(const FObjectInitializer& ObjectInitializer)
|
||||
|
@ -43,14 +42,18 @@ void UAgentComponent::BeginPlay()
|
|||
if (bRegisterAgentComponent)
|
||||
{
|
||||
/**
|
||||
* This only returns true if the current game mode is not null
|
||||
* This only returns true if the current game mode is not null
|
||||
* because you can only access a game mode if you are the host
|
||||
* @param oftheworld UWorld is needed to access the game mode
|
||||
* @return true if there is a game mode and it is not null
|
||||
*/
|
||||
if(UGameplayStatics::GetGameMode(GetWorld())!=nullptr)
|
||||
{
|
||||
GetDataRouter(GetWorld()).RegisterAgent(this);
|
||||
auto *DataRouter = GetDataRouter(GetWorld());
|
||||
if (DataRouter != nullptr)
|
||||
{
|
||||
DataRouter->RegisterAgent(this);
|
||||
}
|
||||
} else
|
||||
{
|
||||
UCarlaGameInstance* GameInstance = Cast<UCarlaGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()));
|
||||
|
@ -64,15 +67,22 @@ void UAgentComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
|||
{
|
||||
if (bAgentComponentIsRegistered)
|
||||
{
|
||||
FDataRouter *DataRouter = nullptr;
|
||||
if(UGameplayStatics::GetGameMode(GetWorld())!=nullptr)
|
||||
{
|
||||
GetDataRouter(GetWorld()).DeregisterAgent(this);
|
||||
DataRouter = GetDataRouter(GetWorld());
|
||||
}
|
||||
else
|
||||
{
|
||||
UCarlaGameInstance* GameInstance = Cast<UCarlaGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()));
|
||||
if(GameInstance)
|
||||
GameInstance->GetDataRouter().DeregisterAgent(this);
|
||||
UCarlaGameInstance *GameInstance = Cast<UCarlaGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()));
|
||||
if(GameInstance)
|
||||
{
|
||||
DataRouter = &GameInstance->GetDataRouter();
|
||||
}
|
||||
}
|
||||
if (DataRouter != nullptr)
|
||||
{
|
||||
DataRouter->DeregisterAgent(this);
|
||||
}
|
||||
bAgentComponentIsRegistered = false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
// 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/Actor/ActorDispatcher.h"
|
||||
|
||||
#include "CarlaEpisode.generated.h"
|
||||
|
||||
/// A simulation episode.
|
||||
///
|
||||
/// Each time the level is restarted a new episode is created.
|
||||
UCLASS(BlueprintType, Blueprintable)
|
||||
class CARLA_API UCarlaEpisode : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
void Initialize(const FString &InMapName)
|
||||
{
|
||||
MapName = InMapName;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
const FString &GetMapName() const
|
||||
{
|
||||
return MapName;
|
||||
}
|
||||
|
||||
void RegisterActorSpawner(IActorSpawner &ActorSpawner)
|
||||
{
|
||||
ActorDispatcher.Bind(ActorSpawner);
|
||||
}
|
||||
|
||||
/// Return the list of actor definitions that are available to be spawned this
|
||||
/// episode.
|
||||
UFUNCTION(BlueprintCallable)
|
||||
const TArray<FActorDefinition> &GetActorDefinitions() const
|
||||
{
|
||||
return ActorDispatcher.GetActorDefinitions();
|
||||
}
|
||||
|
||||
/// Spawns an actor based on @a ActorDescription at @a Transform. To properly
|
||||
/// despawn an actor created with this function call DestroyActor.
|
||||
///
|
||||
/// Return nullptr on failure.
|
||||
UFUNCTION(BlueprintCallable)
|
||||
AActor *SpawnActor(
|
||||
const FTransform &Transform,
|
||||
const FActorDescription &ActorDescription)
|
||||
{
|
||||
return ActorDispatcher.SpawnActor(Transform, ActorDescription);
|
||||
}
|
||||
|
||||
/// Destroys an actor, properly removing it from the registry.
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void DestroyActor(AActor *Actor)
|
||||
{
|
||||
ActorDispatcher.DestroyActor(Actor);
|
||||
}
|
||||
|
||||
const FActorRegistry &GetActorRegistry() const
|
||||
{
|
||||
return ActorDispatcher.GetActorRegistry();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FString MapName;
|
||||
|
||||
FActorDispatcher ActorDispatcher;
|
||||
};
|
|
@ -11,6 +11,13 @@
|
|||
#include "Server/ServerGameController.h"
|
||||
#include "Settings/CarlaSettings.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
static uint32 GetNumberOfThreadsForRPCServer()
|
||||
{
|
||||
return std::max(std::thread::hardware_concurrency(), 4u) - 2u;
|
||||
}
|
||||
|
||||
UCarlaGameInstance::UCarlaGameInstance() {
|
||||
CarlaSettings = CreateDefaultSubobject<UCarlaSettings>(TEXT("CarlaSettings"));
|
||||
check(CarlaSettings != nullptr);
|
||||
|
@ -32,3 +39,19 @@ void UCarlaGameInstance::InitializeGameControllerIfNotPresent(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UCarlaGameInstance::NotifyBeginEpisode(UCarlaEpisode &Episode)
|
||||
{
|
||||
if (!bServerIsRunning)
|
||||
{
|
||||
Server.Start(CarlaSettings->WorldPort);
|
||||
Server.AsyncRun(GetNumberOfThreadsForRPCServer());
|
||||
bServerIsRunning = true;
|
||||
}
|
||||
Server.NotifyBeginEpisode(Episode);
|
||||
}
|
||||
|
||||
void UCarlaGameInstance::NotifyEndEpisode()
|
||||
{
|
||||
Server.NotifyEndEpisode();
|
||||
}
|
||||
|
|
|
@ -8,8 +8,9 @@
|
|||
|
||||
#include "Engine/GameInstance.h"
|
||||
|
||||
#include "Game/CarlaGameControllerBase.h"
|
||||
#include "Game/DataRouter.h"
|
||||
#include "Carla/Game/CarlaGameControllerBase.h"
|
||||
#include "Carla/Game/DataRouter.h"
|
||||
#include "Carla/Server/TheNewCarlaServer.h"
|
||||
|
||||
#include "CarlaGameInstance.generated.h"
|
||||
|
||||
|
@ -62,12 +63,26 @@ public:
|
|||
return DataRouter;
|
||||
}
|
||||
|
||||
void NotifyBeginEpisode(UCarlaEpisode &Episode);
|
||||
|
||||
void Tick(float /*DeltaSeconds*/)
|
||||
{
|
||||
Server.RunSome(10u); /// @todo
|
||||
}
|
||||
|
||||
void NotifyEndEpisode();
|
||||
|
||||
private:
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
bool bServerIsRunning = false;
|
||||
|
||||
UPROPERTY(Category = "CARLA Settings", EditAnywhere)
|
||||
UCarlaSettings *CarlaSettings;
|
||||
UCarlaSettings *CarlaSettings = nullptr;
|
||||
|
||||
FDataRouter DataRouter;
|
||||
|
||||
TUniquePtr<ICarlaGameControllerBase> GameController;
|
||||
|
||||
FTheNewCarlaServer Server;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
// 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.h"
|
||||
#include "Carla/Game/TheNewCarlaGameModeBase.h"
|
||||
|
||||
ATheNewCarlaGameModeBase::ATheNewCarlaGameModeBase(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
PrimaryActorTick.TickGroup = TG_PrePhysics;
|
||||
bAllowTickBeforeBeginPlay = false;
|
||||
|
||||
Episode = CreateDefaultSubobject<UCarlaEpisode>(TEXT("Episode"));
|
||||
}
|
||||
|
||||
void ATheNewCarlaGameModeBase::InitGame(
|
||||
const FString &MapName,
|
||||
const FString &Options,
|
||||
FString &ErrorMessage)
|
||||
{
|
||||
Super::InitGame(MapName, Options, ErrorMessage);
|
||||
|
||||
check(Episode != nullptr);
|
||||
Episode->Initialize(MapName);
|
||||
|
||||
GameInstance = Cast<UCarlaGameInstance>(GetGameInstance());
|
||||
checkf(
|
||||
GameInstance != nullptr,
|
||||
TEXT("GameInstance is not a UCarlaGameInstance, did you forget to set it in the project settings?"));
|
||||
|
||||
SpawnActorSpawners();
|
||||
}
|
||||
|
||||
void ATheNewCarlaGameModeBase::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
GameInstance->NotifyBeginEpisode(*Episode);
|
||||
}
|
||||
|
||||
void ATheNewCarlaGameModeBase::Tick(float DeltaSeconds)
|
||||
{
|
||||
Super::Tick(DeltaSeconds);
|
||||
|
||||
GameInstance->Tick(DeltaSeconds);
|
||||
}
|
||||
|
||||
void ATheNewCarlaGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
{
|
||||
GameInstance->NotifyEndEpisode();
|
||||
|
||||
Super::EndPlay(EndPlayReason);
|
||||
}
|
||||
|
||||
void ATheNewCarlaGameModeBase::SpawnActorSpawners()
|
||||
{
|
||||
auto *World = GetWorld();
|
||||
check(World != nullptr);
|
||||
|
||||
for (auto &SpawnerClass : BlueprintSpawners)
|
||||
{
|
||||
if (SpawnerClass != nullptr)
|
||||
{
|
||||
auto *Spawner = World->SpawnActor<AActorSpawnerBlueprintBase>(SpawnerClass);
|
||||
if (Spawner != nullptr)
|
||||
{
|
||||
Episode->RegisterActorSpawner(*Spawner);
|
||||
BlueprintSpawnerInstances.Add(Spawner);
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("Failed to spawn actor spawner"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
// 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/Actor/ActorSpawnerBlueprintBase.h"
|
||||
#include "Carla/Game/CarlaEpisode.h"
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/GameModeBase.h"
|
||||
|
||||
#include "TheNewCarlaGameModeBase.generated.h"
|
||||
|
||||
/// Base class for the CARLA Game Mode.
|
||||
UCLASS(HideCategories=(ActorTick))
|
||||
class CARLA_API ATheNewCarlaGameModeBase : public AGameModeBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
ATheNewCarlaGameModeBase(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
protected:
|
||||
|
||||
void InitGame(const FString &MapName, const FString &Options, FString &ErrorMessage) override;
|
||||
|
||||
void BeginPlay() override;
|
||||
|
||||
void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
|
||||
void Tick(float DeltaSeconds) override;
|
||||
|
||||
private:
|
||||
|
||||
void SpawnActorSpawners();
|
||||
|
||||
UPROPERTY()
|
||||
UCarlaGameInstance *GameInstance = nullptr;
|
||||
|
||||
UPROPERTY()
|
||||
UCarlaEpisode *Episode = nullptr;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
TArray<TSubclassOf<AActorSpawnerBlueprintBase>> BlueprintSpawners;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<AActorSpawnerBlueprintBase *> BlueprintSpawnerInstances;
|
||||
};
|
|
@ -1,90 +0,0 @@
|
|||
// 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.h"
|
||||
#include "Server.h"
|
||||
|
||||
#include <compiler/disable-ue4-macros.h>
|
||||
#include <carla/Version.h>
|
||||
#include <carla/rpc/Actor.h>
|
||||
#include <carla/rpc/Server.h>
|
||||
#include <carla/rpc/Transform.h>
|
||||
#include <carla/rpc/VehicleControl.h>
|
||||
#include <compiler/enable-ue4-macros.h>
|
||||
|
||||
static FVehicleControl MakeControl(const carla::rpc::VehicleControl &cControl)
|
||||
{
|
||||
FVehicleControl Control;
|
||||
Control.Throttle = cControl.throttle;
|
||||
Control.Steer = cControl.steer;
|
||||
Control.Brake = cControl.brake;
|
||||
Control.bHandBrake = cControl.hand_brake;
|
||||
Control.bReverse = cControl.reverse;
|
||||
return Control;
|
||||
}
|
||||
|
||||
class FRPCServer::Pimpl
|
||||
{
|
||||
public:
|
||||
Pimpl(uint16_t port) : Server(port) {}
|
||||
carla::rpc::Server Server;
|
||||
};
|
||||
|
||||
FRPCServer::FRPCServer() : _Pimpl(nullptr) {}
|
||||
|
||||
FRPCServer::~FRPCServer() {}
|
||||
|
||||
void FRPCServer::Initialize(AServer &Server, uint16_t Port)
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("Initializing rpc-server at port %d"), Port);
|
||||
|
||||
_Pimpl = std::make_unique<Pimpl>(Port);
|
||||
|
||||
namespace cr = carla::rpc;
|
||||
|
||||
auto &srv = _Pimpl->Server;
|
||||
|
||||
srv.BindAsync("ping", []() { return true; });
|
||||
|
||||
srv.BindAsync("version", []() { return std::string(carla::version()); });
|
||||
|
||||
// srv.BindAsync("get_blueprints", []() {
|
||||
// return std::vector<cr::ActorBlueprint>{
|
||||
// cr::ActorBlueprint{"vehicle.mustang.red"},
|
||||
// cr::ActorBlueprint{"vehicle.mustang.also_red"},
|
||||
// cr::ActorBlueprint{"vehicle.mustang.still_red"}
|
||||
// };
|
||||
// });
|
||||
|
||||
// srv.BindSync("spawn_actor", [&](
|
||||
// const cr::ActorBlueprint &blueprint,
|
||||
// const cr::Transform &transform) {
|
||||
// auto id = Server.SpawnAgent(transform);
|
||||
// return cr::Actor{static_cast<cr::Actor::id_type>(id), blueprint};
|
||||
// });
|
||||
|
||||
srv.BindSync("apply_control_to_actor", [&](
|
||||
const cr::Actor &actor,
|
||||
const cr::VehicleControl &control) {
|
||||
Server.ApplyControl(actor.id, MakeControl(control));
|
||||
});
|
||||
}
|
||||
|
||||
void FRPCServer::Run()
|
||||
{
|
||||
_Pimpl->Server.AsyncRun(4);
|
||||
}
|
||||
|
||||
void FRPCServer::RunSome()
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
_Pimpl->Server.SyncRunFor(20ms);
|
||||
}
|
||||
|
||||
void FRPCServer::Stop()
|
||||
{
|
||||
_Pimpl->Server.Stop();
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// 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 "CoreMinimal.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class AServer;
|
||||
|
||||
class FRPCServer
|
||||
{
|
||||
public:
|
||||
|
||||
FRPCServer();
|
||||
|
||||
~FRPCServer();
|
||||
|
||||
void Initialize(AServer &Server, uint16_t Port = 8080u);
|
||||
|
||||
void Run();
|
||||
|
||||
void RunSome();
|
||||
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
|
||||
class Pimpl;
|
||||
std::unique_ptr<Pimpl> _Pimpl;
|
||||
};
|
|
@ -1,72 +0,0 @@
|
|||
// 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.h"
|
||||
#include "Server.h"
|
||||
|
||||
|
||||
// Sets default values
|
||||
AServer::AServer()
|
||||
{
|
||||
// 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;
|
||||
|
||||
}
|
||||
|
||||
// Called when the game starts or when spawned
|
||||
void AServer::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
_Server.Initialize(*this);
|
||||
_Server.Run();
|
||||
}
|
||||
|
||||
void AServer::EndPlay(EEndPlayReason::Type EndPlayReason)
|
||||
{
|
||||
_Server.Stop();
|
||||
}
|
||||
|
||||
// Called every frame
|
||||
void AServer::Tick(float DeltaTime)
|
||||
{
|
||||
Super::Tick(DeltaTime);
|
||||
|
||||
_Server.RunSome();
|
||||
}
|
||||
|
||||
int32 AServer::SpawnAgent(const FTransform &Transform)
|
||||
{
|
||||
check(IsInGameThread());
|
||||
UE_LOG(LogTemp, Warning, TEXT("Spawning vehicle at %s"), *Transform.ToString());
|
||||
|
||||
static int32 COUNT = 0u;
|
||||
++COUNT;
|
||||
|
||||
ACarlaWheeledVehicle *Vehicle;
|
||||
SpawnVehicle(Transform, Vehicle);
|
||||
if ((Vehicle != nullptr) && !Vehicle->IsPendingKill())
|
||||
{
|
||||
// Vehicle->AIControllerClass = AWheeledVehicleAIController::StaticClass();
|
||||
Vehicle->SpawnDefaultController();
|
||||
_Agents.Add(COUNT, Vehicle);
|
||||
return COUNT;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool AServer::ApplyControl(int32 AgentId, const FVehicleControl &Control)
|
||||
{
|
||||
UE_LOG(LogTemp, Log, TEXT("Applying control to vehicle %d: throttle = %f, steer = %f"), AgentId, Control.Throttle, Control.Steer);
|
||||
if (!_Agents.Contains(AgentId))
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("Vehicle %d does not exist!"), AgentId);
|
||||
return false;
|
||||
}
|
||||
auto *Vehicle = _Agents[AgentId];
|
||||
Vehicle->ApplyVehicleControl(Control);
|
||||
return true;
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
// 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 "Vehicle/CarlaWheeledVehicle.h"
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "RPCServer.h"
|
||||
#include "Vehicle/VehicleControl.h"
|
||||
#include <future>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include "Server.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class CARLA_API AServer : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Sets default values for this actor's properties
|
||||
AServer();
|
||||
|
||||
protected:
|
||||
// Called when the game starts or when spawned
|
||||
virtual void BeginPlay() override;
|
||||
virtual void EndPlay(EEndPlayReason::Type EndPlayReason) override;
|
||||
|
||||
public:
|
||||
// Called every frame
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
int32 SpawnAgent(const FTransform &Transform);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
bool ApplyControl(int32 AgentId, const FVehicleControl &Control);
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void SpawnVehicle(const FTransform &SpawnTransform, ACarlaWheeledVehicle *&SpawnedCharacter);
|
||||
|
||||
private:
|
||||
|
||||
FRPCServer _Server;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
TMap<uint32, ACarlaWheeledVehicle *> _Agents;
|
||||
};
|
|
@ -0,0 +1,69 @@
|
|||
// 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.h"
|
||||
#include "TheNewCarlaServer.h"
|
||||
|
||||
#include <compiler/disable-ue4-macros.h>
|
||||
#include <carla/Version.h>
|
||||
#include <carla/rpc/Server.h>
|
||||
#include <compiler/enable-ue4-macros.h>
|
||||
|
||||
class FTheNewCarlaServer::FPimpl
|
||||
{
|
||||
public:
|
||||
|
||||
FPimpl(uint16_t port) : Server(port) {}
|
||||
|
||||
carla::rpc::Server Server;
|
||||
|
||||
UCarlaEpisode *CurrentEpisode = nullptr;
|
||||
};
|
||||
|
||||
FTheNewCarlaServer::FTheNewCarlaServer() : Pimpl(nullptr) {}
|
||||
|
||||
FTheNewCarlaServer::~FTheNewCarlaServer() {}
|
||||
|
||||
void FTheNewCarlaServer::Start(uint16_t Port)
|
||||
{
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("Initializing rpc-server at port %d"), Port);
|
||||
|
||||
Pimpl = MakeUnique<FPimpl>(Port);
|
||||
|
||||
namespace cr = carla::rpc;
|
||||
|
||||
auto &srv = Pimpl->Server;
|
||||
|
||||
srv.BindAsync("ping", []() { return true; });
|
||||
|
||||
srv.BindAsync("version", []() { return std::string(carla::version()); });
|
||||
}
|
||||
|
||||
void FTheNewCarlaServer::NotifyBeginEpisode(UCarlaEpisode &Episode)
|
||||
{
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("New episode '%s' started"), *Episode.GetMapName());
|
||||
Pimpl->CurrentEpisode = &Episode;
|
||||
}
|
||||
|
||||
void FTheNewCarlaServer::NotifyEndEpisode()
|
||||
{
|
||||
Pimpl->CurrentEpisode = nullptr;
|
||||
}
|
||||
|
||||
void FTheNewCarlaServer::AsyncRun(uint32 NumberOfWorkerThreads)
|
||||
{
|
||||
Pimpl->Server.AsyncRun(NumberOfWorkerThreads);
|
||||
}
|
||||
|
||||
void FTheNewCarlaServer::RunSome(uint32 Milliseconds)
|
||||
{
|
||||
Pimpl->Server.SyncRunFor(carla::time_duration::milliseconds(Milliseconds));
|
||||
}
|
||||
|
||||
void FTheNewCarlaServer::Stop()
|
||||
{
|
||||
Pimpl->Server.Stop();
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// 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 "CoreMinimal.h"
|
||||
|
||||
class UCarlaEpisode;
|
||||
|
||||
class FTheNewCarlaServer
|
||||
{
|
||||
public:
|
||||
|
||||
FTheNewCarlaServer();
|
||||
|
||||
~FTheNewCarlaServer();
|
||||
|
||||
void Start(uint16_t Port);
|
||||
|
||||
void NotifyBeginEpisode(UCarlaEpisode &Episode);
|
||||
|
||||
void NotifyEndEpisode();
|
||||
|
||||
void AsyncRun(uint32 NumberOfWorkerThreads);
|
||||
|
||||
void RunSome(uint32 Milliseconds);
|
||||
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
|
||||
class FPimpl;
|
||||
TUniquePtr<FPimpl> Pimpl;
|
||||
};
|
Loading…
Reference in New Issue