Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Code for tutorial "How to add a new sensor to CARLA Simulator" https://carla.readthedocs.io/en/latest/dev/how_to_add_a_new_sensor/
// Copyright (c) 2019 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/rpc/ActorId.h"
#include "carla/sensor/data/Array.h"
namespace carla {
namespace sensor {
namespace data {
class SafeDistanceEvent : public Array<rpc::ActorId> {
public:
explicit SafeDistanceEvent(RawData &&data)
: Array<rpc::ActorId>(std::move(data)) {}
};
} // namespace data
} // namespace sensor
} // namespace carla
// Copyright (c) 2019 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/Sensor/SafeDistanceSensor.h"
#include "Carla/Actor/ActorBlueprintFunctionLibrary.h"
#include "Carla/Game/CarlaEpisode.h"
#include "Carla/Util/BoundingBoxCalculator.h"
#include "Carla/Vehicle/CarlaWheeledVehicle.h"
ASafeDistanceSensor::ASafeDistanceSensor(const FObjectInitializer &ObjectInitializer)
: Super(ObjectInitializer)
{
Box = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxOverlap"));
Box->SetupAttachment(RootComponent);
Box->SetHiddenInGame(true); // Disable for debugging.
Box->SetCollisionProfileName(FName("OverlapAll"));
PrimaryActorTick.bCanEverTick = true;
}
FActorDefinition ASafeDistanceSensor::GetSensorDefinition()
{
auto Definition = UActorBlueprintFunctionLibrary::MakeGenericSensorDefinition(
TEXT("other"),
TEXT("safe_distance"));
FActorVariation Front;
Front.Id = TEXT("safe_distance_front");
Front.Type = EActorAttributeType::Float;
Front.RecommendedValues = { TEXT("1.0") };
Front.bRestrictToRecommended = false;
FActorVariation Back;
Back.Id = TEXT("safe_distance_back");
Back.Type = EActorAttributeType::Float;
Back.RecommendedValues = { TEXT("0.5") };
Back.bRestrictToRecommended = false;
FActorVariation Lateral;
Lateral.Id = TEXT("safe_distance_lateral");
Lateral.Type = EActorAttributeType::Float;
Lateral.RecommendedValues = { TEXT("0.5") };
Lateral.bRestrictToRecommended = false;
Definition.Variations.Append({ Front, Back, Lateral });
return Definition;
}
void ASafeDistanceSensor::Set(const FActorDescription &Description)
{
Super::Set(Description);
float Front = UActorBlueprintFunctionLibrary::RetrieveActorAttributeToFloat(
"safe_distance_front",
Description.Variations,
1.0f);
float Back = UActorBlueprintFunctionLibrary::RetrieveActorAttributeToFloat(
"safe_distance_back",
Description.Variations,
0.5f);
float Lateral = UActorBlueprintFunctionLibrary::RetrieveActorAttributeToFloat(
"safe_distance_lateral",
Description.Variations,
0.5f);
constexpr float M_TO_CM = 100.0f; // Unit conversion.
float LocationX = M_TO_CM * (Front - Back) / 2.0f;
float ExtentX = M_TO_CM * (Front + Back) / 2.0f;
float ExtentY = M_TO_CM * Lateral;
Box->SetRelativeLocation(FVector{LocationX, 0.0f, 0.0f});
Box->SetBoxExtent(FVector{ExtentX, ExtentY, 0.0f});
}
void ASafeDistanceSensor::SetOwner(AActor *Owner)
{
Super::SetOwner(Owner);
auto BoundingBox = UBoundingBoxCalculator::GetActorBoundingBox(Owner);
Box->SetBoxExtent(BoundingBox.Extent + Box->GetUnscaledBoxExtent());
}
void ASafeDistanceSensor::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
TSet<AActor *> DetectedActors;
Box->GetOverlappingActors(DetectedActors, ACarlaWheeledVehicle::StaticClass());
DetectedActors.Remove(GetOwner());
if (DetectedActors.Num() > 0)
{
auto Stream = GetDataStream(*this);
Stream.Send(*this, GetEpisode(), DetectedActors);
}
}
// Copyright (c) 2019 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/Sensor/Sensor.h"
#include "Carla/Actor/ActorDefinition.h"
#include "Carla/Actor/ActorDescription.h"
#include "Components/BoxComponent.h"
#include "SafeDistanceSensor.generated.h"
UCLASS()
class CARLA_API ASafeDistanceSensor : public ASensor
{
GENERATED_BODY()
public:
ASafeDistanceSensor(const FObjectInitializer &ObjectInitializer);
static FActorDefinition GetSensorDefinition();
void Set(const FActorDescription &ActorDescription) override;
void SetOwner(AActor *Owner) override;
void Tick(float DeltaSeconds) override;
private:
UPROPERTY()
UBoxComponent *Box = nullptr;
};
// Copyright (c) 2019 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/sensor/s11n/SafeDistanceSerializer.h"
#include "carla/sensor/data/SafeDistanceEvent.h"
namespace carla {
namespace sensor {
namespace s11n {
SharedPtr<SensorData> SafeDistanceSerializer::Deserialize(RawData &&data) {
return SharedPtr<SensorData>(new data::SafeDistanceEvent(std::move(data)));
}
} // namespace s11n
} // namespace sensor
} // namespace carla
// Copyright (c) 2019 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/Memory.h"
#include "carla/rpc/ActorId.h"
#include "carla/sensor/RawData.h"
#include <cstdint>
#include <cstring>
namespace carla {
namespace sensor {
class SensorData;
namespace s11n {
class SafeDistanceSerializer {
public:
template <typename SensorT, typename EpisodeT, typename ActorListT>
static Buffer Serialize(
const SensorT &,
const EpisodeT &episode,
const ActorListT &detected_actors) {
const uint32_t size_in_bytes = sizeof(ActorId) * detected_actors.Num();
Buffer buffer{size_in_bytes};
unsigned char *it = buffer.data();
for (auto *actor : detected_actors) {
ActorId id = episode.FindActor(actor).GetActorId();
std::memcpy(it, &id, sizeof(ActorId));
it += sizeof(ActorId);
}
return buffer;
}
static SharedPtr<SensorData> Deserialize(RawData &&data);
};
} // namespace s11n
} // namespace sensor
} // namespace carla
@replica6
Copy link

replica6 commented Jun 10, 2021

Hello!
I have tried to test 'sensor creation' with this example, but I got errors during the build, and Python egg is not generated (cannot use pythonAPI).
Can you help?
C:\CARLA\carla\LibCarla\source\carla/sensor/data/SafeDistanceEvent.h(20): error C2665: 'carla::sensor::data::Arraycarla::rpc::ActorId::Array': none of the 2 overloads could convert all the argument types [C:\CARLA\carla\Build\libcarla-visualstudio\LibCarla\cmake\client\carla_client_debug.vcxproj]

C:\CARLA\carla\Unreal\CarlaUE4\Plugins\Carla\Source\Carla\Sensor\SafeDistanceSensor.h(33) error C3248: 'ASensor::Tick': function declared as 'final' cannot be overridden by 'ASafeDistanceSensor::Tick'

@thbake
Copy link

thbake commented Nov 4, 2021

Hi! I'm also followed the guide but run into the following error:

In file included from ../../LibCarla/source/carla/sensor/s11n/SafeDistanceSerializer.cpp:9:
../../LibCarla/cmake/../source/carla/sensor/data/SafeDistanceEvent.h:20:9: error: no matching constructor for initialization of 'Array<rpc::ActorId>' (aka 'Array<unsigned int>')
      : Array<rpc::ActorId>(std::move(data)) {}
        ^                   ~~~~~~~~~~~~~~~
../../LibCarla/cmake/../source/carla/sensor/data/Array.h:23:9: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'typename std::remove_reference<RawData &>::type' (aka 'carla::sensor::RawData') to 'const carla::sensor::data::Array<unsigned int>' for 1st argument
  class Array : public SensorData {
        ^
../../LibCarla/cmake/../source/carla/sensor/data/Array.h:127:14: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
    explicit Array(RawData &&data, FuncT get_offset)
             ^
../../LibCarla/cmake/../source/carla/sensor/data/Array.h:136:14: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
    explicit Array(size_t offset, RawData &&data)
             ^
1 error generated.

Any clue on why this could be happening? In the end I literally copy and pasted the code to see if I had made a typo.

Thanks in advance!

@roque2205
Copy link

roque2205 commented Nov 9, 2021

Hi guys, try changing Array<rpc::ActorId>(std::move(data)) {} to Array<rpc::ActorId>(0u, std::move(data)) {}.

EDIT: You will also need to change ActorId id = episode.FindActor(actor).GetActorId(); to ActorId id = episode.FindCarlaActor(actor)->GetActorId();.

Best, Robert

@IKAROS93
Copy link

IKAROS93 commented Jan 19, 2022

@replica6 delete final in Sensor.h and try again.

@IKAROS93
Copy link

IKAROS93 commented Jan 19, 2022

after make rebuild , I got this problem:

x86_64-linux-gnu-gcc: error: /home/ikaros/carla/PythonAPI/carla/dependencies/lib/libxerces-c.a:  No such file or directory
x86_64-linux-gnu-gcc: error: /home/ikaros/carla/PythonAPI/carla/dependencies/lib/libproj.a:  No such file or directory
x86_64-linux-gnu-gcc: error: /home/ikaros/carla/PythonAPI/carla/dependencies/lib/libsqlite3.a:  No such file or directory

and the solution is:
DO NOT make rebuild
just make clean and make PythonAPI and make launch

@kaermorhen97
Copy link

kaermorhen97 commented Mar 5, 2022

C:\CARLA\carla\Unreal\CarlaUE4\Plugins\Carla\Source\Carla\Sensor\SafeDistanceSensor.h(33) error C3248: 'ASensor::Tick': function declared as 'final' cannot be overridden by 'ASafeDistanceSensor::Tick'

Hi @replica6, do you solve your issue? I also have this issue.
Thanks for help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment