Merge branch 'dev' into benchmark_branch

This commit is contained in:
nsubiron 2017-12-20 18:45:27 +01:00
commit 27967e0a77
12 changed files with 340 additions and 147 deletions

63
Docs/CONTRIBUTING.md Normal file
View File

@ -0,0 +1,63 @@
Contributing to CARLA
=====================
> _This document is a work in progress and might be incomplete._
We are more than happy to accept contributions!
How can I contribute?
* Reporting bugs
* Feature requests
* Code contributions
Reporting bugs
--------------
Use our [issue section](issueslink) on GitHub. Please check before that the
issue was not already added.
[issueslink]: https://github.com/carla-simulator/carla/issues
Feature requests
----------------
Please check first the list of [feature requests][frlink]. If it is not there
and you think is a feature that might be interesting for users, please submit
your request as a new issue.
[frlink]: https://github.com/carla-simulator/carla/issues?q=is%3Aissue+is%3Aopen+label%3A%22feature+request%22
Code contributions
------------------
Before starting hands-on on coding, please check out the
[projects page][projectslink] to see if we are already working on that. In case
of doubt or to discuss how to proceed, please contact one of us (or send an
email to carla.simulator@gmail.com).
[projectslink]: https://github.com/carla-simulator/carla/projects/1
#### What should I know before I get started?
Check out the ["CARLA Design"](carla_design.md) document to get an idea on the
different modules that compose CARLA, and chose the most appropriate one to hold
the new feature.
#### Coding style
Please follow the current coding style when submitting new code.
* Use spaces, not tabs.
* Comments should not exceed 80 columns, code may exceed this limit a bit in rare
occasions if it results in clearer code.
* Python code follows [PEP8 style guide](https://www.python.org/dev/peps/pep-0008/) (use `autopep8` whenever possible).
* Unreal C++ code, CarlaUE4 and Carla plugin, follow the [Unreal Engine's Coding Standard](https://docs.unrealengine.com/latest/INT/Programming/Development/CodingStandard/) with the exception of using spaces instead of tabs.
* CarlaServer uses [Google's style guide](https://google.github.io/styleguide/cppguide.html).
#### Pull request
Once you think your contribution is ready to be added to CARLA, please submit a
pull request and one of our team members will take a look at it.
Try to be as descriptive as possible when filling the pull-request description.

43
Docs/carla_design.md Normal file
View File

@ -0,0 +1,43 @@
CARLA Design
============
> _This document is a work in progress and might be incomplete._
CARLA is composed by the following modules
* Client side
- Python client API: "PythonClient/carla"
* Server side
- CarlaUE4 Unreal Engine project: "Unreal/CarlaUE4"
- Carla plugin for Unreal Engine: "Unreal/CarlaUE4/Plugins/Carla"
- CarlaServer: "Util/CarlaServer"
Python client API
-----------------
The client API provides a Python module for communicating with the CARLA server.
In the folder "PythonClient", we provide several examples for scripting a CARLA
client using the "carla" module.
CarlaUE4 Unreal Engine project
------------------------------
The Unreal project "CarlaUE4" contains all the assets and scenes for generating
the CARLA binary. It uses the tools provided by the Carla plugin to assemble the
cities and behavior of the agents in the scene.
Carla plugin for Unreal Engine
------------------------------
The Carla plugin contains all the functionality of CARLA. We tried to keep this
functionality separated from the assets, so the functionality in this plugin can
be used as much as possible in any Unreal project.
It uses "CarlaServer" library for the networking communication.
CarlaServer
-----------
External library for the networking communications.
See ["CarlaServer"](carla_server.md) for implementation details.

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

View File

@ -7,7 +7,6 @@ CARLA Documentation
* [CARLA settings](carla_settings.md)
* [Measurements](measurements.md)
* [Cameras and sensors](cameras_and_sensors.md)
* [F.A.Q.](faq.md)
* [Troubleshooting](troubleshooting.md)
@ -17,8 +16,13 @@ CARLA Documentation
* [How to build on Windows](how_to_build_on_windows.md)
* [How to add Automotive Materials](how_to_add_automotive_materials.md)
#### Contributing
* [Contribution guidelines](CONTRIBUTING.md)
#### Development
* [Map customization](map_customization.md)
* [How to add assets](how_to_add_assets.md)
* [CARLA design](carla_design.md)
* [CarlaServer documentation](carla_server.md)

View File

@ -116,10 +116,22 @@ If enabled, the server attaches a list of agents to the measurements package
every frame. Each of these agents has an unique id that identifies it, and
belongs to one of the following classes
* **Vehicle** Contains its transform, bounding-box, and forward speed.
* **Pedestrian** Contains its transform, bounding-box, and forward speed. (*)
* **Vehicle** Contains its transform, box-extent, and forward speed.
* **Pedestrian** Contains its transform, box-extent, and forward speed. (*)
* **Traffic light** Contains its transform and state (green, yellow, red).
* **Speed-limit sign** Contains its transform and speed-limit.
(*) At this point every pedestrian is assumed to have the same bounding-box
size.
###### Transform and bounding box
The transform defines the location and orientation of the agent. The bounding
box is assumed to be centered at the agent's location. The box extent gives the
radii dimensions of the bounding box of the agent.
![Vehicle Bounding Box](img/vehicle_bounding_box.png)
!!! important
As seen in the picture, the Z coordinate of the box is not fitted to
vehicle's height.

View File

@ -0,0 +1,141 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB), and the INTEL Visual Computing Lab.
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#include "Carla.h"
#include "RoutePlanner.h"
#include "CarlaWheeledVehicle.h"
#include "Util/RandomEngine.h"
#include "WheeledVehicleAIController.h"
#include "Engine/CollisionProfile.h"
static bool IsSplineValid(const USplineComponent *SplineComponent)
{
return (SplineComponent != nullptr) &&
(SplineComponent->GetNumberOfSplinePoints() > 1);
}
static AWheeledVehicleAIController *GetVehicleController(AActor *Actor)
{
auto *Vehicle = (Actor->IsPendingKill() ? nullptr : Cast<ACarlaWheeledVehicle>(Actor));
return (Vehicle != nullptr ?
Cast<AWheeledVehicleAIController>(Vehicle->GetController()) :
nullptr);
}
static const USplineComponent *PickARoute(
URandomEngine &RandomEngine,
const TArray<USplineComponent *> &Routes,
const TArray<float> &Probabilities)
{
check(Routes.Num() > 0);
if (Routes.Num() == 1) {
return Routes[0];
}
auto Index = RandomEngine.GetIntWithWeight(Probabilities);
check((Index >= 0) && (Index < Routes.Num()));
return Routes[Index];
}
ARoutePlanner::ARoutePlanner(const FObjectInitializer& ObjectInitializer) :
Super(ObjectInitializer)
{
RootComponent =
ObjectInitializer.CreateDefaultSubobject<USceneComponent>(this, TEXT("SceneRootComponent"));
RootComponent->SetMobility(EComponentMobility::Static);
TriggerVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerVolume"));
TriggerVolume->SetupAttachment(RootComponent);
TriggerVolume->SetHiddenInGame(true);
TriggerVolume->SetMobility(EComponentMobility::Static);
TriggerVolume->SetCollisionProfileName(FName("OverlapAll"));
TriggerVolume->bGenerateOverlapEvents = true;
}
#if WITH_EDITOR
void ARoutePlanner::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
const auto Size = Routes.Num();
if (PropertyChangedEvent.Property && (Size != Probabilities.Num())) {
Probabilities.Reset(Size);
for (auto i = 0; i < Size; ++i) {
Probabilities.Add(1.0f / static_cast<float>(Size));
if (Routes[i] == nullptr) {
Routes[i] = NewObject<USplineComponent>(this);
Routes[i]->SetupAttachment(RootComponent);
Routes[i]->SetHiddenInGame(true);
Routes[i]->SetMobility(EComponentMobility::Static);
Routes[i]->RegisterComponent();
}
}
}
}
#endif // WITH_EDITOR
void ARoutePlanner::BeginPlay()
{
Super::BeginPlay();
if (Routes.Num() < 1) {
UE_LOG(LogCarla, Warning, TEXT("ARoutePlanner has no route assigned."));
return;
}
for (auto &&Route : Routes) {
if (!IsSplineValid(Route)) {
UE_LOG(LogCarla, Error, TEXT("ARoutePlanner has a route with zero way-points."));
return;
}
}
// Register delegate on begin overlap.
if (!TriggerVolume->OnComponentBeginOverlap.IsAlreadyBound(this, &ARoutePlanner::OnTriggerBeginOverlap))
{
TriggerVolume->OnComponentBeginOverlap.AddDynamic(this, &ARoutePlanner::OnTriggerBeginOverlap);
}
}
void ARoutePlanner::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
// Deregister the delegate.
if (TriggerVolume->OnComponentBeginOverlap.IsAlreadyBound(this, &ARoutePlanner::OnTriggerBeginOverlap))
{
TriggerVolume->OnComponentBeginOverlap.RemoveDynamic(this, &ARoutePlanner::OnTriggerBeginOverlap);
}
Super::EndPlay(EndPlayReason);
}
void ARoutePlanner::OnTriggerBeginOverlap(
UPrimitiveComponent * /*OverlappedComp*/,
AActor *OtherActor,
UPrimitiveComponent * /*OtherComp*/,
int32 /*OtherBodyIndex*/,
bool /*bFromSweep*/,
const FHitResult & /*SweepResult*/)
{
auto *Controller = GetVehicleController(OtherActor);
auto *RandomEngine = (Controller != nullptr ? Controller->GetRandomEngine() : nullptr);
if (RandomEngine != nullptr)
{
auto *Route = PickARoute(*RandomEngine, Routes, Probabilities);
TArray<FVector> WayPoints;
const auto Size = Route->GetNumberOfSplinePoints();
check(Size > 1);
WayPoints.Reserve(Size);
for (auto i = 1; i < Size; ++i)
{
WayPoints.Add(Route->GetLocationAtSplinePoint(i, ESplineCoordinateSpace::World));
}
Controller->SetFixedRoute(WayPoints);
}
}

View File

@ -0,0 +1,56 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB), and the INTEL Visual Computing Lab.
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "GameFramework/Actor.h"
#include "Components/BoxComponent.h"
#include "Components/SplineComponent.h"
#include "RoutePlanner.generated.h"
/// Assign a random route to every ACarlaWheeledVehicle entering the trigger
/// volume. Routes must be added in editor after placing this actor into the
/// world. Spline tangents are ignored, only locations are taken into account
/// for making the route.
UCLASS()
class CARLA_API ARoutePlanner : public AActor
{
GENERATED_BODY()
public:
ARoutePlanner(const FObjectInitializer& ObjectInitializer);
protected:
#if WITH_EDITOR
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif // WITH_EDITOR
virtual void BeginPlay() override;
virtual void EndPlay(EEndPlayReason::Type EndPlayReason) override;
UFUNCTION()
void OnTriggerBeginOverlap(
UPrimitiveComponent* OverlappedComp,
AActor *OtherActor,
UPrimitiveComponent *OtherComp,
int32 OtherBodyIndex,
bool bFromSweep,
const FHitResult &SweepResult);
public:
UPROPERTY(EditAnywhere)
UBoxComponent *TriggerVolume;
UPROPERTY(BlueprintReadWrite, Category="Traffic Routes", EditAnywhere)
TArray<USplineComponent *> Routes;
UPROPERTY(BlueprintReadWrite, Category="Traffic Routes", EditAnywhere, EditFixedSize)
TArray<float> Probabilities;
};

View File

@ -59,6 +59,13 @@ static bool IsThereAnObstacleAhead(
RayTrace(Vehicle, StartLeft, EndLeft);
}
template <typename T>
static void ClearQueue(std::queue<T> &Queue)
{
std::queue<T> EmptyQueue;
Queue.swap(EmptyQueue);
}
// =============================================================================
// -- Constructor and destructor -----------------------------------------------
// =============================================================================
@ -118,8 +125,7 @@ void AWheeledVehicleAIController::ConfigureAutopilot(const bool Enable)
Vehicle->SetReverse(false);
Vehicle->SetHandbrakeInput(false);
TrafficLightState = ETrafficLightState::Green;
decltype(TargetLocations) EmptyQueue;
TargetLocations.swap(EmptyQueue);
ClearQueue(TargetLocations);
Vehicle->SetAIVehicleState(
bAutopilotEnabled ?
ECarlaWheeledVehicleState::FreeDriving :
@ -130,8 +136,13 @@ void AWheeledVehicleAIController::ConfigureAutopilot(const bool Enable)
// -- Traffic ------------------------------------------------------------------
// =============================================================================
void AWheeledVehicleAIController::SetFixedRoute(const TArray<FVector> &Locations)
void AWheeledVehicleAIController::SetFixedRoute(
const TArray<FVector> &Locations,
const bool bOverwriteCurrent)
{
if (bOverwriteCurrent) {
ClearQueue(TargetLocations);
}
for (auto &Location : Locations) {
TargetLocations.emplace(Location);
}

View File

@ -177,7 +177,7 @@ public:
/// Set a fixed route to follow if autopilot is enabled.
UFUNCTION(Category = "Wheeled Vehicle Controller", BlueprintCallable)
void SetFixedRoute(const TArray<FVector> &Locations);
void SetFixedRoute(const TArray<FVector> &Locations, bool bOverwriteCurrent=true);
/// @}
// ===========================================================================

View File

@ -1,77 +0,0 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB), and the INTEL Visual Computing Lab.
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#include "Carla.h"
#include "IntersectionEntrance.h"
// Sets default values
AIntersectionEntrance::AIntersectionEntrance(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
// 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 AIntersectionEntrance::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AIntersectionEntrance::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
TArray<FVector> AIntersectionEntrance::GetRoute(int it)
{
TArray<AActor*> points = Routes[it].points;
TArray<FVector> route;
for (int i = 0; i < points.Num(); ++i){
route.Add(points[i]->GetActorLocation());
}
return route;
}
float AIntersectionEntrance::GetProbability(int it)
{
return Routes[it].probability;
}
/*
#if WITH_EDITOR
void AIntersectionEntrance::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
if (PropertyChangedEvent.Property) {
if (bCreateRoutes && (GetWorld() != nullptr)) {
//ClearRoutes();
for (int i = 0; i < Routes.Num(); ++i){
for(int e = 0; e < Routes[i].points.Num(); ++e){
AActor* actor= GetWorld()->SpawnActor<AActor>();//USphereComponent* createdComp = NewObject<USphereComponent>(this);//CreateDefaultSubobject<USphereComponent>(TEXT("Sphere"));
USceneComponent* SphereMesh = NewObject<USceneComponent>(actor);
SphereMesh->AttachToComponent(RootComponent,FAttachmentTransformRules::KeepWorldTransform);
if(actor)
{
actor->RegisterAllComponents();
Routes[i].points[e] = actor;
//Routes[i].points[e].position = createdComp->GetRelativeTransform().GetLocation();
}
}
}
}
}
bCreateRoutes = false;
}
#endif // WITH_EDITOR
*/

View File

@ -1,63 +0,0 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB), and the INTEL Visual Computing Lab.
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "GameFramework/Actor.h"
#include "IntersectionEntrance.generated.h"
USTRUCT(BlueprintType)
struct FRoute {
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite, Category=TrafficRoutes, EditAnywhere)
TArray < AActor *> points;
UPROPERTY(BlueprintReadWrite, Category=TrafficRoutes, EditAnywhere)
float probability = 0.0f;
};
UCLASS(BlueprintType)
class CARLA_API AIntersectionEntrance : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AIntersectionEntrance(const FObjectInitializer& ObjectInitializer);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
protected:
UFUNCTION(BlueprintCallable, Category="Trigger")
TArray<FVector> GetRoute(int route);
UFUNCTION(BlueprintCallable, Category="Trigger")
float GetProbability(int route);
/*
#if WITH_EDITOR
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif // WITH_EDITOR
*/
public:
UPROPERTY(Category = "Routes", EditAnywhere)
bool bCreateRoutes = false;
UPROPERTY(BlueprintReadWrite, Category=TrafficRoutes, EditAnywhere)
TArray< FRoute > Routes;
};

View File

@ -15,9 +15,12 @@ pages:
- 'How to build on Linux': 'how_to_build_on_linux.md'
- 'How to build on Windows': 'how_to_build_on_windows.md'
- 'How to add Automotive Materials': 'how_to_add_automotive_materials.md'
- Contributing:
- 'Contribution guidelines': 'CONTRIBUTING.md'
- Development:
- 'Map customization': 'map_customization.md'
- 'How to add assets': 'how_to_add_assets.md'
- 'CARLA design': 'carla_design.md'
- 'CarlaServer documentation': 'carla_server.md'
markdown_extensions: