CARLA
 
载入中...
搜索中...
未找到
DVSCamera.cpp
浏览该文件的文档.
1// Copyright (c) 2020 Robotics and Perception Group (GPR)
2// University of Zurich and ETH Zurich
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7
8#include <random>
9#include <cmath>
10#include <algorithm>
11
12#include "Carla.h"
16
18#include "carla/ros2/ROS2.h"
19#include <carla/Buffer.h>
20#include <carla/BufferView.h>
22
23static float FColorToGrayScaleFloat(FColor Color)
24{
25 return 0.2989 * Color.R + 0.587 * Color.G + 0.114 * Color.B;
26}
27
28ADVSCamera::ADVSCamera(const FObjectInitializer &ObjectInitializer)
29 : Super(ObjectInitializer)
30{
33 TEXT("Material'/Carla/PostProcessingMaterials/PhysicLensDistortion.PhysicLensDistortion'"));
34
35 RandomEngine = CreateDefaultSubobject<URandomEngine>(TEXT("RandomEngine"));
36}
37
39{
40 constexpr bool bEnableModifyingPostProcessEffects = true;
41 auto Definition = UActorBlueprintFunctionLibrary::MakeCameraDefinition(TEXT("dvs"), bEnableModifyingPostProcessEffects);
42
44 Cp.Id = TEXT("positive_threshold");
46 Cp.RecommendedValues = { TEXT("0.3") };
47 Cp.bRestrictToRecommended = false;
48
50 Cm.Id = TEXT("negative_threshold");
52 Cm.RecommendedValues = { TEXT("0.3") };
53 Cm.bRestrictToRecommended = false;
54
55 FActorVariation Sigma_Cp;
56 Sigma_Cp.Id = TEXT("sigma_positive_threshold");
58 Sigma_Cp.RecommendedValues = { TEXT("0.0") };
59 Sigma_Cp.bRestrictToRecommended = false;
60
61 FActorVariation Sigma_Cm;
62 Sigma_Cm.Id = TEXT("sigma_negative_threshold");
64 Sigma_Cm.RecommendedValues = { TEXT("0.0") };
65 Sigma_Cm.bRestrictToRecommended = false;
66
67 FActorVariation Refractory_Period;
68 Refractory_Period.Id = TEXT("refractory_period_ns");
69 Refractory_Period.Type = EActorAttributeType::Int;
70 Refractory_Period.RecommendedValues = { TEXT("0") };
71 Refractory_Period.bRestrictToRecommended = false;
72
73 FActorVariation Use_Log;
74 Use_Log.Id = TEXT("use_log");
76 Use_Log.RecommendedValues = { TEXT("True") };
77 Use_Log.bRestrictToRecommended = false;
78
79 FActorVariation Log_EPS;
80 Log_EPS.Id = TEXT("log_eps");
82 Log_EPS.RecommendedValues = { TEXT("0.001") };
83 Log_EPS.bRestrictToRecommended = false;
84
85 Definition.Variations.Append({ Cp, Cm, Sigma_Cp, Sigma_Cm, Refractory_Period, Use_Log, Log_EPS });
86
87 return Definition;
88}
89
90void ADVSCamera::Set(const FActorDescription &Description)
91{
92 Super::Set(Description);
93
95 "positive_threshold",
96 Description.Variations,
97 0.5f);
98
100 "negative_threshold",
101 Description.Variations,
102 0.5f);
103
105 "sigma_positive_threshold",
106 Description.Variations,
107 0.0f);
108
110 "sigma_negative_threshold",
111 Description.Variations,
112 0.0f);
113
115 "refractory_period_ns",
116 Description.Variations,
117 0.0);
118
120 "use_log",
121 Description.Variations,
122 true);
123
125 "log_eps",
126 Description.Variations,
127 1e-03);
128}
129
130void ADVSCamera::PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime)
131{
132 TRACE_CPUPROFILER_EVENT_SCOPE(ADVSCamera::PostPhysTick);
133 check(CaptureRenderTarget != nullptr);
134 if (!HasActorBegunPlay() || IsPendingKill())
135 {
136 return;
137 }
138
139 /// Immediate enqueues render commands of the scene at the current time.
142
143 //Super (ASceneCaptureSensor) Capture the Scene in a (UTextureRenderTarget2D) CaptureRenderTarge from the CaptureComponent2D
144 /** Read the image **/
145 TArray<FColor> RawImage;
146 this->ReadPixels(RawImage);
147
148 /** Convert image to gray scale **/
149 if (this->config.use_log)
150 {
151 this->ImageToLogGray(RawImage);
152 }
153 else
154 {
155 this->ImageToGray(RawImage);
156 }
157
158 /** DVS Simulator **/
159 ADVSCamera::DVSEventArray events = this->Simulation(DeltaTime);
160
161 auto Stream = GetDataStream(*this);
162 auto Buff = Stream.PopBufferFromPool();
163
164 // serialize data
165 carla::Buffer BufferReady(carla::sensor::SensorRegistry::Serialize(*this, events, std::move(Buff)));
166 carla::SharedBufferView BufView = carla::BufferView::CreateFrom(std::move(BufferReady));
167
168 // ROS2
169 #if defined(WITH_ROS2)
170 auto ROS2 = carla::ros2::ROS2::GetInstance();
171 if (ROS2->IsEnabled())
172 {
173 TRACE_CPUPROFILER_EVENT_SCOPE_STR("ROS2 Send");
175 {
176 // get resolution of camera
177 int W = -1, H = -1;
178 float Fov = -1.0f;
179 auto WidthOpt = GetAttribute("image_size_x");
180 if (WidthOpt.has_value())
181 W = FCString::Atoi(*WidthOpt->Value);
182 auto HeightOpt = GetAttribute("image_size_y");
183 if (HeightOpt.has_value())
184 H = FCString::Atoi(*HeightOpt->Value);
185 auto FovOpt = GetAttribute("fov");
186 if (FovOpt.has_value())
187 Fov = FCString::Atof(*FovOpt->Value);
188 AActor* ParentActor = GetAttachParentActor();
189 if (ParentActor)
190 {
191 FTransform LocalTransformRelativeToParent = GetActorTransform().GetRelativeTransform(ParentActor->GetActorTransform());
192 ROS2->ProcessDataFromDVS(Stream.GetSensorType(), StreamId, LocalTransformRelativeToParent, BufView, W, H, Fov, this);
193 }
194 else
195 {
196 ROS2->ProcessDataFromDVS(Stream.GetSensorType(), StreamId, Stream.GetSensorTransform(), BufView, W, H, Fov, this);
197 }
198 }
199 }
200 #endif
201 if (events.size() > 0)
202 {
203 TRACE_CPUPROFILER_EVENT_SCOPE_STR("ADVSCamera Stream Send");
204 /** Send the events **/
205 Stream.Send(*this, BufView);
206 }
207}
208
209void ADVSCamera::ImageToGray(const TArray<FColor> &image)
210{
211 /** Sanity check **/
212 if (image.Num() != (this->GetImageHeight() * this->GetImageWidth()))
213 return;
214
215 /** Reserve HxW elements **/
216 last_image.SetNumUninitialized(image.Num());
217
218 /** Convert image to gray raw image values **/
219 for (size_t i = 0; i < image.Num(); ++i)
220 {
221 last_image[i] = FColorToGrayScaleFloat(image[i]);
222 }
223}
224
225void ADVSCamera::ImageToLogGray(const TArray<FColor> &image)
226{
227 /** Sanity check **/
228 if (image.Num() != (this->GetImageHeight() * this->GetImageWidth()))
229 return;
230
231 /** Reserve HxW elements **/
232 last_image.SetNumUninitialized(image.Num());
233
234 /** Convert image to gray raw image values **/
235 for (size_t i = 0; i < image.Num(); ++i)
236 {
237 last_image[i] = std::log(this->config.log_eps + (FColorToGrayScaleFloat(image[i]) / 255.0));
238 }
239}
240
242{
243 /** Array of events **/
245
246 /** Sanity check **/
247 if (this->last_image.Num() != (this->GetImageHeight() * this->GetImageWidth()))
248 return events;
249
250 /** Check initialization **/
251 if(this->prev_image.Num() == 0)
252 {
253 /** Set the first rendered image **/
254 this->ref_values = this->last_image;
255 this->prev_image = this->last_image;
256
257 /** Resizes array to given number of elements. New elements will be zeroed.**/
258 this->last_event_timestamp.SetNumZeroed(this->last_image.Num());
259
260 /** Reset current time **/
261 this->current_time = dvs::secToNanosec(this->GetEpisode().GetElapsedGameTime());
262
263 return events;
264 }
265
266 static constexpr float tolerance = 1e-6;
267
268 /** delta time in nanoseconds **/
269 const std::uint64_t delta_t_ns = dvs::secToNanosec(
270 this->GetEpisode().GetElapsedGameTime()) - this->current_time;
271
272 /** Loop along the image size **/
273 for (uint32 y = 0; y < this->GetImageHeight(); ++y)
274 {
275 for (uint32 x = 0; x < this->GetImageWidth(); ++x)
276 {
277 const uint32 i = (this->GetImageWidth() * y) + x;
278 const float itdt = this->last_image[i];
279 const float it = this->prev_image[i];
280 const float prev_cross = this->ref_values[i];
281
282 if (std::fabs (it - itdt) > tolerance)
283 {
284 const float pol = (itdt >= it) ? +1.0 : -1.0;
285 float C = (pol > 0) ? this->config.Cp : this->config.Cm;
286 const float sigma_C = (pol > 0) ? this->config.sigma_Cp : this->config.sigma_Cm;
287
288 if(sigma_C > 0)
289 {
290 C += RandomEngine->GetNormalDistribution(0, sigma_C);
291 constexpr float minimum_contrast_threshold = 0.01;
292 C = std::max(minimum_contrast_threshold, C);
293 }
294 float curr_cross = prev_cross;
295 bool all_crossings = false;
296
297 do
298 {
299 curr_cross += pol * C;
300
301 if ((pol > 0 && curr_cross > it && curr_cross <= itdt)
302 || (pol < 0 && curr_cross < it && curr_cross >= itdt))
303 {
304 const std::uint64_t edt = (curr_cross - it) * delta_t_ns / (itdt - it);
305 const std::int64_t t = this->current_time + edt;
306
307 // check that pixel (x,y) is not currently in a "refractory" state
308 // i.e. |t-that last_timestamp(x,y)| >= refractory_period
309 const std::int64_t last_stamp_at_xy = dvs::secToNanosec(this->last_event_timestamp[i]);
310 if (t >= last_stamp_at_xy)
311 {
312 const std::uint64_t dt = t - last_stamp_at_xy;
313 if(this->last_event_timestamp[i] == 0 || dt >= this->config.refractory_period_ns)
314 {
315 events.push_back(::carla::sensor::data::DVSEvent(x, y, t, pol > 0));
317 }
318 else
319 {
320 /** Dropping event because time since last event < refractory_period_ns **/
321 }
322 this->ref_values[i] = curr_cross;
323 }
324 }
325 else
326 {
327 all_crossings = true;
328 }
329 } while (!all_crossings);
330 } // end tolerance
331 } // end for each pixel
332 }
333
334 /** Update current time **/
335 this->current_time = dvs::secToNanosec(this->GetEpisode().GetElapsedGameTime());
336
337 this->prev_image = this->last_image;
338
339 // Sort the events by increasing timestamps, since this is what
340 // most event processing algorithms expect
341 std::sort(events.begin(), events.end(), [](const ::carla::sensor::data::DVSEvent& it1, const ::carla::sensor::data::DVSEvent& it2){return it1.t < it2.t;});
342
343 return events;
344}
static float FColorToGrayScaleFloat(FColor Color)
Definition DVSCamera.cpp:23
std::vector<::carla::sensor::data::DVSEvent > DVSEventArray
Definition DVSCamera.h:46
ADVSCamera(const FObjectInitializer &ObjectInitializer)
Definition DVSCamera.cpp:28
TArray< float > prev_image
Definition DVSCamera.h:61
dvs::Config config
DVS simulation configuration
Definition DVSCamera.h:73
void Set(const FActorDescription &ActorDescription) override
Definition DVSCamera.cpp:90
TArray< double > last_event_timestamp
Image containing time of last event in seconds
Definition DVSCamera.h:67
ADVSCamera::DVSEventArray Simulation(float DeltaTime)
static FActorDefinition GetSensorDefinition()
Definition DVSCamera.cpp:38
void ImageToLogGray(const TArray< FColor > &image)
TArray< float > last_image
Images containing last (current) and previous image
Definition DVSCamera.h:61
void ImageToGray(const TArray< FColor > &image)
TArray< float > ref_values
Image containing the last reference value to trigger event
Definition DVSCamera.h:64
virtual void PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime) override
std::int64_t current_time
Current time in nanoseconds
Definition DVSCamera.h:70
bool ReadPixels(TArray< FColor > &BitMap) const
Use for debugging purposes only.
void EnablePostProcessingEffects(bool Enable=true)
UTextureRenderTarget2D * CaptureRenderTarget
Render target necessary for scene capture.
void EnqueueRenderSceneImmediate()
Immediate enqueues render commands of the scene at the current time.
uint32 GetImageHeight() const
uint32 GetImageWidth() const
void WaitForRenderThreadToFinish()
Blocks until the render thread has finished all it's tasks.
boost::optional< FActorAttribute > GetAttribute(const FString Name)
Definition Sensor.cpp:49
auto GetToken() const
Return the token that allows subscribing to this sensor's stream.
FAsyncDataStream GetDataStream(const SensorT &Self)
Return the FDataStream associated with this sensor.
URandomEngine * RandomEngine
Random Engine used to provide noise for sensor output.
bool AddPostProcessingMaterial(const FString &Path)
Load the UMaterialInstanceDynamic at the given Path and append it to the list of shaders with Weight.
uint64_t GetSensorType()
Definition DataStream.h:58
static int32 RetrieveActorAttributeToInt(const FString &Id, const TMap< FString, FActorAttribute > &Attributes, int32 Default)
static FActorDefinition MakeCameraDefinition(const FString &Id, bool bEnableModifyingPostProcessEffects=false)
static float RetrieveActorAttributeToFloat(const FString &Id, const TMap< FString, FActorAttribute > &Attributes, float Default)
static bool RetrieveActorAttributeToBool(const FString &Id, const TMap< FString, FActorAttribute > &Attributes, bool Default)
float GetNormalDistribution(float Mean, float StandardDeviation)
static std::shared_ptr< BufferView > CreateFrom(Buffer &&buffer)
Definition BufferView.h:56
A piece of raw data.
static std::shared_ptr< ROS2 > GetInstance()
Definition ROS2.h:51
static Buffer Serialize(Sensor &sensor, Args &&... args)
Serialize the arguments provided into a Buffer by calling to the serializer registered for the given ...
Serializes a stream endpoint.
std::shared_ptr< BufferView > SharedBufferView
Definition BufferView.h:151
constexpr std::int64_t secToNanosec(double seconds)
Definition DVSCamera.h:29
constexpr double nanosecToSecTrunc(std::int64_t nanoseconds)
Definition DVSCamera.h:34
A definition of a Carla Actor with all the variation and attributes.
A description of a Carla Actor with all its variation.
TMap< FString, FActorAttribute > Variations
User selected variations of the actor.
float sigma_Cp
Definition DVSCamera.h:22
std::uint64_t refractory_period_ns
Definition DVSCamera.h:24
bool use_log
Definition DVSCamera.h:25
float log_eps
Definition DVSCamera.h:26
float sigma_Cm
Definition DVSCamera.h:23