diff --git a/CHANGELOG.md b/CHANGELOG.md index 00829764b..c4f14d373 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ * Added "sensor_tick" attribute to sensors (cameras and lidars) to specify the capture rate in seconds * Added "get_forward_vector()" to rotation and transform, retrieves the unit vector on the rotation's X-axis * Added support for Deepin in PythonAPI's setup.py - * Rename vehicle.get_vehicle_control() to vehicle.get_control() to be consistent with walkers + * Added support for spawning and controlling walkers (pedestrians) + * Renamed vehicle.get_vehicle_control() to vehicle.get_control() to be consistent with walkers ## CARLA 0.9.2 diff --git a/LibCarla/source/carla/client/Walker.cpp b/LibCarla/source/carla/client/Walker.cpp new file mode 100644 index 000000000..145f9bc5f --- /dev/null +++ b/LibCarla/source/carla/client/Walker.cpp @@ -0,0 +1,26 @@ +// 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 . + +#include "carla/client/Walker.h" + +#include "carla/client/detail/Simulator.h" + +namespace carla { +namespace client { + + void Walker::ApplyControl(const Control &control) { + if (control != _control) { + GetEpisode().Lock()->ApplyControlToWalker(*this, control); + _control = control; + } + } + + Walker::Control Walker::GetWalkerControl() const { + return GetEpisode().Lock()->GetActorDynamicState(*this).state.walker_control; + } + +} // namespace client +} // namespace carla diff --git a/LibCarla/source/carla/client/Walker.h b/LibCarla/source/carla/client/Walker.h new file mode 100644 index 000000000..d4648116b --- /dev/null +++ b/LibCarla/source/carla/client/Walker.h @@ -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 . + +#pragma once + +#include "carla/client/Actor.h" +#include "carla/rpc/WalkerControl.h" + +namespace carla { +namespace client { + + class Walker : public Actor { + public: + + using Control = rpc::WalkerControl; + + explicit Walker(ActorInitializer init) : Actor(std::move(init)) {} + + /// Apply @a control to this Walker. + void ApplyControl(const Control &control); + + /// Return the control last applied to this Walker. + /// + /// @note This function does not call the simulator, it returns the Control + /// received in the last tick. + Control GetWalkerControl() const; + + private: + + Control _control; + }; + +} // namespace client +} // namespace carla diff --git a/LibCarla/source/carla/client/detail/ActorFactory.cpp b/LibCarla/source/carla/client/detail/ActorFactory.cpp index 9a03e7e28..ed32069ae 100644 --- a/LibCarla/source/carla/client/detail/ActorFactory.cpp +++ b/LibCarla/source/carla/client/detail/ActorFactory.cpp @@ -13,6 +13,7 @@ #include "carla/client/ServerSideSensor.h" #include "carla/client/TrafficLight.h" #include "carla/client/Vehicle.h" +#include "carla/client/Walker.h" #include "carla/client/World.h" #include "carla/client/detail/Client.h" @@ -76,6 +77,8 @@ namespace detail { return MakeActorImpl(std::move(init), gc); } else if (StringUtil::StartsWith(description.description.id, "vehicle.")) { return MakeActorImpl(std::move(init), gc); + } else if (StringUtil::StartsWith(description.description.id, "walker.")) { + return MakeActorImpl(std::move(init), gc); } else if (StringUtil::StartsWith(description.description.id, "traffic.traffic_light")) { return MakeActorImpl(std::move(init), gc); } diff --git a/LibCarla/source/carla/client/detail/Client.cpp b/LibCarla/source/carla/client/detail/Client.cpp index 62b9fa772..112ef8eec 100644 --- a/LibCarla/source/carla/client/detail/Client.cpp +++ b/LibCarla/source/carla/client/detail/Client.cpp @@ -11,6 +11,7 @@ #include "carla/rpc/Client.h" #include "carla/rpc/DebugShape.h" #include "carla/rpc/VehicleControl.h" +#include "carla/rpc/WalkerControl.h" #include "carla/streaming/Client.h" #include @@ -143,6 +144,10 @@ namespace detail { _pimpl->AsyncCall("apply_control_to_vehicle", vehicle, control); } + void Client::ApplyControlToWalker(const rpc::Actor &walker, const rpc::WalkerControl &control) { + _pimpl->AsyncCall("apply_control_to_walker", walker, control); + } + void Client::SubscribeToStream( const streaming::Token &token, std::function callback) { diff --git a/LibCarla/source/carla/client/detail/Client.h b/LibCarla/source/carla/client/detail/Client.h index b00bd878b..5f7ebff56 100644 --- a/LibCarla/source/carla/client/detail/Client.h +++ b/LibCarla/source/carla/client/detail/Client.h @@ -28,6 +28,7 @@ namespace rpc { class ActorDescription; class DebugShape; class VehicleControl; + class WalkerControl; } namespace sensor { class SensorData; } namespace streaming { class Token; } @@ -102,6 +103,10 @@ namespace detail { const rpc::Actor &vehicle, const rpc::VehicleControl &control); + void ApplyControlToWalker( + const rpc::Actor &walker, + const rpc::WalkerControl &control); + void SubscribeToStream( const streaming::Token &token, std::function callback); diff --git a/LibCarla/source/carla/client/detail/Simulator.h b/LibCarla/source/carla/client/detail/Simulator.h index 4db4d08ab..5e37b583e 100644 --- a/LibCarla/source/carla/client/detail/Simulator.h +++ b/LibCarla/source/carla/client/detail/Simulator.h @@ -13,6 +13,7 @@ #include "carla/client/Actor.h" #include "carla/client/GarbageCollectionPolicy.h" #include "carla/client/Vehicle.h" +#include "carla/client/Walker.h" #include "carla/client/detail/Client.h" #include "carla/client/detail/Episode.h" #include "carla/client/detail/EpisodeProxy.h" @@ -202,6 +203,10 @@ namespace detail { _client.ApplyControlToVehicle(vehicle.Serialize(), control); } + void ApplyControlToWalker(Walker &walker, const rpc::WalkerControl &control) { + _client.ApplyControlToWalker(walker.Serialize(), control); + } + /// @} // ========================================================================= /// @name Operations with sensors diff --git a/LibCarla/source/carla/rpc/WalkerControl.h b/LibCarla/source/carla/rpc/WalkerControl.h new file mode 100644 index 000000000..9bfb635d1 --- /dev/null +++ b/LibCarla/source/carla/rpc/WalkerControl.h @@ -0,0 +1,59 @@ +// 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 . + +#pragma once + +#include "carla/MsgPack.h" + +#ifdef LIBCARLA_INCLUDED_FROM_UE4 +# include "Carla/Walker/WalkerControl.h" +#endif // LIBCARLA_INCLUDED_FROM_UE4 + +namespace carla { +namespace rpc { + + class WalkerControl { + public: + + WalkerControl() = default; + + WalkerControl( + geom::Vector3D in_direction, + float in_speed) + : direction(in_direction), + speed(in_speed) {} + + geom::Vector3D direction = {1.0f, 0.0f, 0.0f}; + float speed = 0.0f; + +#ifdef LIBCARLA_INCLUDED_FROM_UE4 + + WalkerControl(const FWalkerControl &Control) + : direction(Control.Direction.X, Control.Direction.Y, Control.Direction.Z), + speed(1e-2f * Control.Speed) {} + + operator FWalkerControl() const { + FWalkerControl Control; + Control.Direction = {direction.x, direction.y, direction.z}; + Control.Speed = 1e2f * speed; + return Control; + } + +#endif // LIBCARLA_INCLUDED_FROM_UE4 + + bool operator!=(const WalkerControl &rhs) const { + return direction != rhs.direction || speed != rhs.speed; + } + + bool operator==(const WalkerControl &rhs) const { + return !(*this != rhs); + } + + MSGPACK_DEFINE_ARRAY(direction, speed); + }; + +} // namespace rpc +} // namespace carla diff --git a/LibCarla/source/carla/sensor/data/ActorDynamicState.h b/LibCarla/source/carla/sensor/data/ActorDynamicState.h index afa69a8b3..35da136b1 100644 --- a/LibCarla/source/carla/sensor/data/ActorDynamicState.h +++ b/LibCarla/source/carla/sensor/data/ActorDynamicState.h @@ -11,6 +11,7 @@ #include "carla/rpc/ActorId.h" #include "carla/rpc/TrafficLightState.h" #include "carla/rpc/VehicleControl.h" +#include "carla/rpc/WalkerControl.h" #include @@ -51,6 +52,27 @@ namespace detail { }; #pragma pack(pop) +#pragma pack(push, 1) + class PackedWalkerControl { + public: + + PackedWalkerControl() = default; + + PackedWalkerControl(const rpc::WalkerControl &control) + : direction{control.direction.x, control.direction.y, control.direction.z}, + speed(control.speed) {} + + operator rpc::WalkerControl() const { + return {geom::Vector3D{direction[0u], direction[1u], direction[2u]}, speed}; + } + + private: + + float direction[3u]; + float speed; + }; +#pragma pack(pop) + } // namespace detail #pragma pack(push, 1) @@ -67,6 +89,7 @@ namespace detail { union TypeDependentState { rpc::TrafficLightState traffic_light_state; detail::PackedVehicleControl vehicle_control; + detail::PackedWalkerControl walker_control; } state; }; diff --git a/PythonAPI/source/libcarla/Actor.cpp b/PythonAPI/source/libcarla/Actor.cpp index 2cbed1ae8..3137c9311 100644 --- a/PythonAPI/source/libcarla/Actor.cpp +++ b/PythonAPI/source/libcarla/Actor.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -74,6 +75,12 @@ void export_actor() { .def(self_ns::str(self_ns::self)) ; + class_, boost::noncopyable, boost::shared_ptr>("Walker", no_init) + .def("apply_control", &cc::Walker::ApplyControl, (arg("control"))) + .def("get_control", &cc::Walker::GetWalkerControl) + .def(self_ns::str(self_ns::self)) + ; + enum_("TrafficLightState") .value("Off", cr::TrafficLightState::Off) .value("Red", cr::TrafficLightState::Red) diff --git a/PythonAPI/source/libcarla/Control.cpp b/PythonAPI/source/libcarla/Control.cpp index dc28734af..2713ad995 100644 --- a/PythonAPI/source/libcarla/Control.cpp +++ b/PythonAPI/source/libcarla/Control.cpp @@ -5,6 +5,7 @@ // For a copy, see . #include +#include #include @@ -23,12 +24,19 @@ namespace rpc { return out; } + std::ostream &operator<<(std::ostream &out, const WalkerControl &control) { + out << "WalkerControl(direction=" << control.direction + << ", speed=" << control.speed << ')'; + return out; + } + } // namespace rpc } // namespace carla void export_control() { using namespace boost::python; namespace cr = carla::rpc; + namespace cg = carla::geom; class_("VehicleControl") .def(init( @@ -50,4 +58,15 @@ void export_control() { .def("__ne__", &cr::VehicleControl::operator!=) .def(self_ns::str(self_ns::self)) ; + + class_("WalkerControl") + .def(init( + (arg("direction")=cg::Vector3D{1.0f, 0.0f, 0.0f}, + arg("speed")=0.0f))) + .def_readwrite("direction", &cr::WalkerControl::direction) + .def_readwrite("speed", &cr::WalkerControl::speed) + .def("__eq__", &cr::WalkerControl::operator==) + .def("__ne__", &cr::WalkerControl::operator!=) + .def(self_ns::str(self_ns::self)) + ; } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.cpp index 15d68e033..c6340eee7 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.cpp @@ -407,6 +407,40 @@ void UActorBlueprintFunctionLibrary::MakeVehicleDefinitions( FillActorDefinitionArray(ParameterArray, Definitions, &MakeVehicleDefinition); } +void UActorBlueprintFunctionLibrary::MakePedestrianDefinition( + const FPedestrianParameters &Parameters, + bool &Success, + FActorDefinition &Definition) +{ + /// @todo We need to validate here the params. + FillIdAndTags(Definition, TEXT("walker"), TEXT("pedestrian"), Parameters.Id); + AddRecommendedValuesForActorRoleName(Definition, {TEXT("pedestrian")}); + Definition.Class = Parameters.Class; + + auto GetGender = [](EPedestrianGender Value) { + switch (Value) + { + case EPedestrianGender::Female: return TEXT("female"); + case EPedestrianGender::Male: return TEXT("male"); + default: return TEXT("other"); + } + }; + + Definition.Attributes.Emplace(FActorAttribute{ + TEXT("gender"), + EActorAttributeType::String, + GetGender(Parameters.Gender)}); + + Success = CheckActorDefinition(Definition); +} + +void UActorBlueprintFunctionLibrary::MakePedestrianDefinitions( + const TArray &ParameterArray, + TArray &Definitions) +{ + FillActorDefinitionArray(ParameterArray, Definitions, &MakePedestrianDefinition); +} + /// ============================================================================ /// -- Helpers to retrieve attribute values ------------------------------------ /// ============================================================================ diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.h index 96028c4a9..6ea5af95a 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.h @@ -8,7 +8,8 @@ #include "Carla/Actor/ActorDefinition.h" #include "Carla/Actor/ActorDescription.h" -#include "Carla/Vehicle/CarlaWheeledVehicle.h" +#include "Carla/Actor/PedestrianParameters.h" +#include "Carla/Actor/VehicleParameters.h" #include "Kismet/BlueprintFunctionLibrary.h" @@ -17,30 +18,6 @@ class ASceneCaptureSensor; struct FLidarDescription; -USTRUCT(BlueprintType) -struct CARLA_API FVehicleParameters -{ - GENERATED_BODY() - - UPROPERTY(EditAnywhere, BlueprintReadWrite) - FString Make; - - UPROPERTY(EditAnywhere, BlueprintReadWrite) - FString Model; - - UPROPERTY(EditAnywhere, BlueprintReadWrite) - TSubclassOf Class; - - UPROPERTY(EditAnywhere, BlueprintReadWrite) - int32 NumberOfWheels = 4; - - UPROPERTY(EditAnywhere, BlueprintReadWrite) - FString ObjectType; - - UPROPERTY(EditAnywhere, BlueprintReadWrite) - TArray RecommendedColors; -}; - UCLASS() class UActorBlueprintFunctionLibrary : public UBlueprintFunctionLibrary { @@ -103,6 +80,17 @@ public: const TArray &ParameterArray, TArray &Definitions); + UFUNCTION(Category = "Carla Actor", BlueprintCallable) + static void MakePedestrianDefinition( + const FPedestrianParameters &Parameters, + bool &Success, + FActorDefinition &Definition); + + UFUNCTION(Category = "Carla Actor", BlueprintCallable) + static void MakePedestrianDefinitions( + const TArray &ParameterArray, + TArray &Definitions); + /// @} /// ========================================================================== /// @name Helpers to retrieve attribute values diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp index c12301611..b25a65923 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp @@ -20,6 +20,10 @@ static FActorView::ActorType FActorRegistry_GetActorType(const FActorView &View) { return FActorView::ActorType::Vehicle; } + else if (nullptr != Cast(View.GetActor())) + { + return FActorView::ActorType::Walker; + } else if (nullptr != Cast(View.GetActor())) { return FActorView::ActorType::TrafficLight; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorView.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorView.h index 61c69660c..abe6c46d7 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorView.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorView.h @@ -21,6 +21,7 @@ public: enum class ActorType : uint8 { Other, Vehicle, + Walker, TrafficLight }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/PedestrianParameters.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/PedestrianParameters.h new file mode 100644 index 000000000..8dcabef4d --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/PedestrianParameters.h @@ -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 . + +#pragma once + +#include "GameFramework/Character.h" + +#include "PedestrianParameters.generated.h" + +UENUM(BlueprintType) +enum class EPedestrianGender : uint8 +{ + Other UMETA(DisplayName = "Other"), + Female UMETA(DisplayName = "Female"), + Male UMETA(DisplayName = "Male"), + + SIZE UMETA(Hidden), + INVALID UMETA(Hidden) +}; + +USTRUCT(BlueprintType) +struct CARLA_API FPedestrianParameters +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FString Id; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + TSubclassOf Class; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + EPedestrianGender Gender = EPedestrianGender::Other; +}; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/VehicleParameters.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/VehicleParameters.h new file mode 100644 index 000000000..feadd267d --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/VehicleParameters.h @@ -0,0 +1,36 @@ +// 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 . + +#pragma once + +#include "Carla/Vehicle/CarlaWheeledVehicle.h" + +#include "VehicleParameters.generated.h" + +USTRUCT(BlueprintType) +struct CARLA_API FVehicleParameters +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FString Make; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FString Model; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + TSubclassOf Class; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + int32 NumberOfWheels = 4; + + /// (OPTIONAL) Use for custom classification of vehicles. + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FString ObjectType; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + TArray RecommendedColors; +}; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp index a1b414798..4990334ee 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp @@ -8,6 +8,7 @@ #include "Carla/Sensor/WorldObserver.h" #include "Carla/Traffic/TrafficLightBase.h" +#include "Carla/Walker/WalkerController.h" #include "CoreGlobals.h" @@ -30,6 +31,15 @@ static auto AWorldObserver_GetActorState(const FActorView &View) state.vehicle_control = carla::rpc::VehicleControl{Vehicle->GetVehicleControl()}; } } + else if (AType::Walker == View.GetActorType()) + { + auto Walker = Cast(View.GetActor()); + auto Controller = Walker != nullptr ? Cast(Walker->GetController()) : nullptr; + if (Controller != nullptr) + { + state.walker_control = carla::rpc::WalkerControl{Controller->GetWalkerControl()}; + } + } else if (AType::TrafficLight == View.GetActorType()) { auto TrafficLight = Cast(View.GetActor()); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp index eb5614455..000be00b3 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp @@ -11,6 +11,7 @@ #include "Carla/Util/DebugShapeDrawer.h" #include "Carla/Util/OpenDrive.h" #include "Carla/Vehicle/CarlaWheeledVehicle.h" +#include "Carla/Walker/WalkerController.h" #include "GameFramework/SpectatorPawn.h" @@ -25,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -369,6 +371,23 @@ void FTheNewCarlaServer::FPimpl::BindActions() Vehicle->ApplyVehicleControl(Control); }); + Server.BindSync("apply_control_to_walker", [this](cr::Actor Actor, cr::WalkerControl Control) { + RequireEpisode(); + auto ActorView = Episode->GetActorRegistry().Find(Actor.id); + if (!ActorView.IsValid() || ActorView.GetActor()->IsPendingKill()) { + RespondErrorStr("unable to apply control: actor not found"); + } + auto Pawn = Cast(ActorView.GetActor()); + if (Pawn == nullptr) { + RespondErrorStr("unable to apply control: actor is not a walker"); + } + auto Controller = Cast(Pawn->GetController()); + if (Controller == nullptr) { + RespondErrorStr("unable to apply control: walker has an incompatible controller"); + } + Controller->ApplyWalkerControl(Control); + }); + Server.BindSync("set_actor_autopilot", [this](cr::Actor Actor, bool bEnabled) { RequireEpisode(); auto ActorView = Episode->GetActorRegistry().Find(Actor.id); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Walker/WalkerControl.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Walker/WalkerControl.h new file mode 100644 index 000000000..34c7fca62 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Walker/WalkerControl.h @@ -0,0 +1,21 @@ +// 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 . + +#pragma once + +#include "WalkerControl.generated.h" + +USTRUCT(BlueprintType) +struct CARLA_API FWalkerControl +{ + GENERATED_BODY() + + UPROPERTY(Category = "Walker Control", EditAnywhere, BlueprintReadWrite) + FVector Direction = {1.0f, 0.0f, 0.0f}; + + UPROPERTY(Category = "Walker Control", EditAnywhere, BlueprintReadWrite) + float Speed = 0.0f; +}; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Walker/WalkerController.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Walker/WalkerController.cpp new file mode 100644 index 000000000..3d12e4642 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Walker/WalkerController.cpp @@ -0,0 +1,50 @@ +// 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 . + +#include "Carla.h" +#include "Carla/Walker/WalkerController.h" + +#include "GameFramework/CharacterMovementComponent.h" +#include "GameFramework/Pawn.h" + +AWalkerController::AWalkerController(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + PrimaryActorTick.bCanEverTick = true; +} + +void AWalkerController::Possess(APawn *InPawn) +{ + Super::Possess(InPawn); + + auto *Character = Cast(InPawn); + if (Character == nullptr) + { + UE_LOG(LogCarla, Error, TEXT("Walker is not a character!")); + return; + } + + auto *MovementComponent = Character->GetCharacterMovement(); + if (MovementComponent == nullptr) + { + UE_LOG(LogCarla, Error, TEXT("Walker missing character movement component!")); + return; + } + + MovementComponent->MaxWalkSpeed = GetMaximumWalkSpeed(); +} + +void AWalkerController::Tick(float DeltaSeconds) +{ + Super::Tick(DeltaSeconds); + + auto *Pawn = GetPawn(); + + if (Pawn != nullptr) + { + Pawn->AddMovementInput(Control.Direction, Control.Speed / GetMaximumWalkSpeed()); + } +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Walker/WalkerController.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Walker/WalkerController.h new file mode 100644 index 000000000..d41b2ee91 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Walker/WalkerController.h @@ -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 . + +#pragma once + +#include "Carla/Walker/WalkerControl.h" + +#include "CoreMinimal.h" +#include "GameFramework/Controller.h" + +#include "WalkerController.generated.h" + +UCLASS() +class CARLA_API AWalkerController : public AController +{ + GENERATED_BODY() + +public: + + AWalkerController(const FObjectInitializer& ObjectInitializer); + + void Possess(APawn *InPawn) override; + + void Tick(float DeltaSeconds) override; + + /// Maximum walk speed allowed in centimetres per second. + UFUNCTION(BlueprintCallable) + float GetMaximumWalkSpeed() const + { + return 4096.0f; // ~147 km/h + } + + UFUNCTION(BlueprintCallable) + void ApplyWalkerControl(const FWalkerControl &InControl) + { + Control = InControl; + } + + UFUNCTION(BlueprintCallable) + const FWalkerControl &GetWalkerControl() const + { + return Control; + } + +private: + + UPROPERTY(VisibleAnywhere) + FWalkerControl Control; +};