Reparent and rename Lidar

This commit is contained in:
nsubiron 2018-09-29 18:28:55 +02:00
parent 282789548e
commit 283ab21581
4 changed files with 109 additions and 56 deletions

View File

@ -0,0 +1,45 @@
// 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 "LidarDescription.generated.h"
USTRUCT()
struct CARLA_API FLidarDescription
{
GENERATED_BODY()
/// Number of lasers.
UPROPERTY(EditAnywhere)
uint32 Channels = 32u;
/// Measure distance in centimeters.
UPROPERTY(EditAnywhere)
float Range = 5000.0f;
/// Points generated by all lasers per second.
UPROPERTY(EditAnywhere)
uint32 PointsPerSecond = 56000u;
/// Lidar rotation frequency.
UPROPERTY(EditAnywhere)
float RotationFrequency = 10.0f;
/// Upper laser angle, counts from horizontal, positive values means above
/// horizontal line.
UPROPERTY(EditAnywhere)
float UpperFovLimit = 10.0f;
/// Lower laser angle, counts from horizontal, negative values means under
/// horizontal line.
UPROPERTY(EditAnywhere)
float LowerFovLimit = -30.0f;
/// Wether to show debug points of laser hits in simulator.
UPROPERTY(EditAnywhere)
bool ShowDebugPoints = false;
};

View File

@ -6,7 +6,9 @@
#pragma once
#include "Sensor/SensorDataView.h"
#include <compiler/disable-ue4-macros.h>
#include <carla/Buffer.h>
#include <compiler/enable-ue4-macros.h>
#include "Containers/Array.h"
@ -15,7 +17,6 @@
/// The header consists of an array of uint32's in the following layout
///
/// {
/// Frame number (uint64)
/// Horizontal angle (float),
/// Channel count,
/// Point count of channel 0,
@ -35,67 +36,65 @@ class FLidarMeasurement {
static_assert(sizeof(float) == sizeof(uint32), "Invalid float size");
public:
explicit FLidarMeasurement(uint32 SensorId = 0u, uint32 ChannelCount = 0u)
: SensorId(SensorId)
explicit FLidarMeasurement(uint32 ChannelCount = 0u)
{
Header.AddDefaulted(4u + ChannelCount);
Header[3] = ChannelCount;
Header.AddDefaulted(2u + ChannelCount);
Header[1] = ChannelCount;
}
FLidarMeasurement &operator=(FLidarMeasurement &&Other)
{
SensorId = Other.SensorId;
Header = std::move(Other.Header);
Points = std::move(Other.Points);
Other.SensorId = 0u;
return *this;
}
void SetFrameNumber(uint64 FrameNumber)
{
std::memcpy(Header.GetData(), reinterpret_cast<const void *>(&FrameNumber), 2u);
}
float GetHorizontalAngle() const
{
return reinterpret_cast<const float &>(Header[2]);
return reinterpret_cast<const float &>(Header[0]);
}
void SetHorizontalAngle(float HorizontalAngle)
{
Header[2] = reinterpret_cast<const uint32 &>(HorizontalAngle);
Header[0] = reinterpret_cast<const uint32 &>(HorizontalAngle);
}
uint32 GetChannelCount() const
{
return Header[3];
return Header[1];
}
void Reset(uint32 TotalPointCount)
{
std::memset(Header.GetData() + 4u, 0, sizeof(uint32) * GetChannelCount());
std::memset(Header.GetData() + 2u, 0, sizeof(uint32) * GetChannelCount());
Points.Reset(3u * TotalPointCount);
}
void WritePoint(uint32 Channel, const FVector &Point)
{
check(Header[3] > Channel);
Header[4u + Channel] += 1u;
check(GetChannelCount() > Channel);
Header[2u + Channel] += 1u;
constexpr float TO_METERS = 1e-2f;
Points.Emplace(TO_METERS * Point.X);
Points.Emplace(TO_METERS * Point.Y);
Points.Emplace(TO_METERS * Point.Z);
}
FSensorDataView GetView() const
void CopyToBuffer(carla::Buffer &Buffer) const
{
return FSensorDataView(SensorId, Header, Points);
/// @todo This should be moved to its own serializer.
std::array<boost::asio::const_buffer, 2u> BufSequence = {{
boost::asio::buffer(
reinterpret_cast<const unsigned char *>(Header.GetData()),
sizeof(uint32) * Header.Num()),
boost::asio::buffer(
reinterpret_cast<const unsigned char *>(Points.GetData()),
sizeof(float) * Points.Num())}};
Buffer.copy_from(BufSequence);
}
private:
uint32 SensorId;
TArray<uint32> Header;
TArray<float> Points;

View File

@ -1,19 +1,23 @@
// Fill out your copyright notice in the Description page of Project Settings.
// 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/Sensor/Lidar.h"
#include "Carla/Sensor/RayTraceLidar.h"
#include "DrawDebugHelpers.h"
#include "Engine/CollisionProfile.h"
#include "Runtime/Engine/Classes/Kismet/KismetMathLibrary.h"
#include "StaticMeshResources.h"
ALidar::ALidar(const FObjectInitializer& ObjectInitializer)
ARayTraceLidar::ARayTraceLidar(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
PrimaryActorTick.bCanEverTick = true;
auto MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CamMesh0"));
auto MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("RootComponent"));
MeshComp->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
MeshComp->bHiddenInGame = true;
MeshComp->CastShadow = false;
@ -21,45 +25,48 @@ ALidar::ALidar(const FObjectInitializer& ObjectInitializer)
RootComponent = MeshComp;
}
void ALidar::Set(const ULidarDescription &LidarDescription)
void ARayTraceLidar::Set(const FLidarDescription &LidarDescription)
{
Super::Set(LidarDescription);
Description = &LidarDescription;
LidarMeasurement = FLidarMeasurement(GetId(), Description->Channels);
Description = LidarDescription;
LidarMeasurement = FLidarMeasurement(Description.Channels);
CreateLasers();
}
void ALidar::CreateLasers()
void ARayTraceLidar::CreateLasers()
{
check(Description != nullptr);
const auto NumberOfLasers = Description->Channels;
const auto NumberOfLasers = Description.Channels;
check(NumberOfLasers > 0u);
const float DeltaAngle = NumberOfLasers == 1u ? 0.f :
(Description->UpperFovLimit - Description->LowerFovLimit) /
(Description.UpperFovLimit - Description.LowerFovLimit) /
static_cast<float>(NumberOfLasers - 1);
LaserAngles.Empty(NumberOfLasers);
for(auto i = 0u; i < NumberOfLasers; ++i)
{
const float VerticalAngle =
Description->UpperFovLimit - static_cast<float>(i) * DeltaAngle;
Description.UpperFovLimit - static_cast<float>(i) * DeltaAngle;
LaserAngles.Emplace(VerticalAngle);
}
}
void ALidar::Tick(const float DeltaTime)
void ARayTraceLidar::Tick(const float DeltaTime)
{
Super::Tick(DeltaTime);
ReadPoints(DeltaTime);
WriteSensorData(LidarMeasurement.GetView());
/// @todo Here we send the data.
// auto &Stream = GetDataStream();
// auto Buffer = Stream.PopBufferFromPool();
// LidarMeasurement.CopyToBuffer(Buffer);
// Stream.Send_GameThread(*this, std::move(Buffer));
}
void ALidar::ReadPoints(const float DeltaTime)
void ARayTraceLidar::ReadPoints(const float DeltaTime)
{
const uint32 ChannelCount = Description->Channels;
const uint32 ChannelCount = Description.Channels;
const uint32 PointsToScanWithOneLaser =
FMath::RoundHalfFromZero(
Description->PointsPerSecond * DeltaTime / float(ChannelCount));
Description.PointsPerSecond * DeltaTime / float(ChannelCount));
if (PointsToScanWithOneLaser <= 0)
{
@ -72,10 +79,9 @@ void ALidar::ReadPoints(const float DeltaTime)
}
check(ChannelCount == LaserAngles.Num());
check(Description != nullptr);
const float CurrentHorizontalAngle = LidarMeasurement.GetHorizontalAngle();
const float AngleDistanceOfTick = Description->RotationFrequency * 360.0f * DeltaTime;
const float AngleDistanceOfTick = Description.RotationFrequency * 360.0f * DeltaTime;
const float AngleDistanceOfLaserMeasure = AngleDistanceOfTick / PointsToScanWithOneLaser;
LidarMeasurement.Reset(ChannelCount * PointsToScanWithOneLaser);
@ -94,11 +100,10 @@ void ALidar::ReadPoints(const float DeltaTime)
}
const float HorizontalAngle = std::fmod(CurrentHorizontalAngle + AngleDistanceOfTick, 360.0f);
LidarMeasurement.SetFrameNumber(GFrameCounter);
LidarMeasurement.SetHorizontalAngle(HorizontalAngle);
}
bool ALidar::ShootLaser(const uint32 Channel, const float HorizontalAngle, FVector &XYZ) const
bool ARayTraceLidar::ShootLaser(const uint32 Channel, const float HorizontalAngle, FVector &XYZ) const
{
const float VerticalAngle = LaserAngles[Channel];
@ -115,7 +120,7 @@ bool ALidar::ShootLaser(const uint32 Channel, const float HorizontalAngle, FVect
LaserRot,
LidarBodyRot
);
const auto Range = Description->Range;
const auto Range = Description.Range;
FVector EndTrace = Range * UKismetMathLibrary::GetForwardVector(ResultRot) + LidarBodyLoc;
GetWorld()->LineTraceSingleByChannel(
@ -129,7 +134,7 @@ bool ALidar::ShootLaser(const uint32 Channel, const float HorizontalAngle, FVect
if (HitInfo.bBlockingHit)
{
if (Description->ShowDebugPoints)
if (Description.ShowDebugPoints)
{
DrawDebugPoint(
GetWorld(),

View File

@ -1,25 +1,29 @@
// Fill out your copyright notice in the Description page of Project Settings.
// 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/Sensor/DeprecatedSensor.h"
#include "Carla/Sensor/Sensor.h"
#include "Carla/Sensor/LidarDescription.h"
#include "Carla/Sensor/LidarMeasurement.h"
#include "Carla/Settings/LidarDescription.h"
#include "Lidar.generated.h"
#include "RayTraceLidar.generated.h"
/// A ray-trace based Lidar sensor.
UCLASS()
class CARLA_API ALidar : public ADeprecatedSensor
class CARLA_API ARayTraceLidar : public ASensor
{
GENERATED_BODY()
public:
ALidar(const FObjectInitializer &ObjectInitializer);
ARayTraceLidar(const FObjectInitializer &ObjectInitializer);
void Set(const ULidarDescription &LidarDescription);
void Set(const FLidarDescription &LidarDescription);
protected:
@ -36,8 +40,8 @@ private:
/// Shoot a laser ray-trace, return whether the laser hit something.
bool ShootLaser(uint32 Channel, float HorizontalAngle, FVector &Point) const;
UPROPERTY(Category = "Lidar", VisibleAnywhere)
const ULidarDescription *Description = nullptr;
UPROPERTY(EditAnywhere)
FLidarDescription Description;
TArray<float> LaserAngles;