Agrarsense
ROSCommands.cpp
Go to the documentation of this file.
1// Copyright (c) 2023 FrostBit Software Lab at the Lapland University of Applied Sciences
2//
3// This work is licensed under the terms of the MIT license.
4// For a copy, see <https://opensource.org/licenses/MIT>.
5
6#include "ROSCommands.h"
7
14
19
30
31#include "ROSIntegration/Classes/ROSIntegrationGameInstance.h"
32#include "ROSIntegration/Public/std_msgs/String.h"
33#include "ROSIntegration/Classes/RI/Topic.h"
34
35#include "Engine/GameViewportClient.h"
36#include "Engine/Engine.h"
37#include "Engine/World.h"
38#include "Misc/DateTime.h"
39#include "Engine/World.h"
40#include "Async/Async.h"
41
42#include <functional>
43
44TMap<FString, FCommand> UROSCommands::CommandHandlers;
45
47{
49
51 if (ROSHandler)
52 {
53 ROSHandler->OnROSStateChanged.AddUniqueDynamic(this, &UROSCommands::ROSBridgeStateChanged);
54 }
55
57}
58
60{
62}
63
64void UROSCommands::TryExecuteCommand(const FString& Command)
65{
66 ParseIncomingMessage(Command);
67}
68
70{
71 UWorld* World = nullptr;
72 if (GEngine && GEngine->GameViewport)
73 {
74 World = GEngine->GameViewport->GetWorld();
75 }
76 return World;
77}
78
80{
82}
83
85{
86 // To call from Terminal (note all in lower case)
87 // rostopic pub /agrarsense/in/commands std_msgs/String "{COMMAND} {VARIABLE}" --once
88 // rostopic pub /agrarsense/in/commands std_msgs/String "help" --once
89
90 if (!CommandHandlers.IsEmpty())
91 {
92 return;
93 }
94
96
97 // General commands
98 CommandHandlers.Add(TEXT("help"), FCommand(&UROSCommands::HandlePrintAvailableCommands, 0.1f, "Print all commands"));
99 CommandHandlers.Add(TEXT("quit"), FCommand(&UROSCommands::HandleQuit, 1.0f, "Quits the Simulator"));
100 CommandHandlers.Add(TEXT("loadmap"), FCommand(&UROSCommands::HandleChangeMap, 5.0f, TEXT("load map by name")));
101 CommandHandlers.Add(TEXT("unrealcommand"), FCommand(&UROSCommands::HandleUnrealCommand, 0.05f, TEXT("Execute Unreal engine console command")));
102
103 // Pause commands
104 CommandHandlers.Add(TEXT("pause"), FCommand(&UROSCommands::HandlePauseSimulator, 0.01f, "Pauses the Simulator after current frame has finished"));
105 CommandHandlers.Add(TEXT("unpause"), FCommand(&UROSCommands::HandleUnPauseSimulator, 0.01f, "Un pauses the Simulator immediately upon receiving the message"));
106 CommandHandlers.Add(TEXT("nextframe"), FCommand(&UROSCommands::HandleAdvanceOneFrame, 0.01f, "Advance one frame"));
107 CommandHandlers.Add(TEXT("advanceframes"), FCommand(&UROSCommands::HandleAdvanceFrames, 0.01f, "Advance given amount of frames"));
108 CommandHandlers.Add(TEXT("advancetime"), FCommand(&UROSCommands::HandleAdvanceTime, 0.01f, "Advance given amount of time in seconds"));
109
110 // Teleport commands
111 CommandHandlers.Add(TEXT("teleportspectator"), FCommand(&UROSCommands::HandleTeleportSpectator, 0.05f, TEXT("x,y,z or x,y,z,yaw,pitch,roll")));
112 CommandHandlers.Add(TEXT("teleportbyid"), FCommand(&UROSCommands::HandleTeleportActorByID, 0.05f, TEXT("ID of Actor, x,y,z or x,y,z,yaw,pitch,roll")));
113
114 // Destroy commands
115 CommandHandlers.Add(TEXT("destroyobjectbyid"), FCommand(&UROSCommands::HandleTryDestroyObjectByID, 0.05f, TEXT("Try to destroy object by id")));
116 CommandHandlers.Add(TEXT("destroyallsensors"), FCommand(&UROSCommands::HandleDestroyAllSensors, 1.0f, TEXT("Destroy all sensors")));
117 CommandHandlers.Add(TEXT("destroyallwalkers"), FCommand(&UROSCommands::HandleDestroyAllWalkers, 1.0f, TEXT("Destroy all sensors")));
118 CommandHandlers.Add(TEXT("destroyallvehicles"), FCommand(&UROSCommands::HandleDestroyAllVehicles, 1.0f, TEXT("Destroy all sensors")));
119
120 // Volume commands
121 // ex. "destroytrees 0,0,0 300,300,300" - destroys all tree actors within certain box area.
122 // ex. "destroyassets 0,0,0 300,300,300" - destroys all Instanced actors within certain box area.
123 CommandHandlers.Add(TEXT("destroytreesarea"), FCommand(&UROSCommands::HandleDestroyTreesArea, 0.05f, TEXT("x,y,z sizeX,sizeY,sizeZ")));
124 CommandHandlers.Add(TEXT("destroyassetsarea"), FCommand(&UROSCommands::HandleDestroyActorsArea, 0.05f, TEXT("x,y,z sizeX,sizeY,sizeZ")));
125
126 // Print commands
127 CommandHandlers.Add(TEXT("getmaps"), FCommand(&UROSCommands::HandlePrintMaps, 0.5f, TEXT("Print all available maps")));
128 CommandHandlers.Add(TEXT("getsensors"), FCommand(&UROSCommands::HandlePrintAllSensors, 0.1f, TEXT("Print all sensors information")));
129 CommandHandlers.Add(TEXT("getvehicles"), FCommand(&UROSCommands::HandlePrintAllVehicles, 0.1f, TEXT("Print all vehicles information")));
130 CommandHandlers.Add(TEXT("getwalkers"), FCommand(&UROSCommands::HandlePrintMaps, 0.1f, TEXT("print all walkers information")));
131 CommandHandlers.Add(TEXT("getids"), FCommand(&UROSCommands::HandlePrintIds, 0.1f, TEXT("print all ids")));
132
133 // Set commands
134 CommandHandlers.Add(TEXT("setglobaltargetframeRate"), FCommand(&UROSCommands::HandleSetGlobalTargetFrameRate, 1.0f, TEXT("0 - 300")));
135 CommandHandlers.Add(TEXT("setglobaltimedilation"), FCommand(&UROSCommands::HandleSetGlobalTimeDilation, 1.0f, TEXT("0.0f - 10.0f")));
136 CommandHandlers.Add(TEXT("setqualityLevel"), FCommand(&UROSCommands::HandleSetQualityLevel, 2.0f, TEXT("low / ultra")));
137 CommandHandlers.Add(TEXT("setworldrendering"), FCommand(&UROSCommands::HandleSetWorldRendering, 1.0f, TEXT("true / false")));
138 CommandHandlers.Add(TEXT("setsavecombinedpointcloud"), FCommand(&UROSCommands::HandleSetSaveCombinedPointcloudToDisk, 0.05f, TEXT("true / false")));
139 CommandHandlers.Add(TEXT("setwpodistance"), FCommand(&UROSCommands::HandleSetWPO, 0.5f, TEXT("Set WPO render distance in cm")));
140 CommandHandlers.Add(TEXT("setnanitemaxpixelsperedge"), FCommand(&UROSCommands::HandleSetNaniteMaxPixelsPerEdge, 0.5f, TEXT("Set Nanite max pixels per edge")));
141
142 // Sensor commands
143 CommandHandlers.Add(TEXT("setallsensorsenabled"), FCommand(&UROSCommands::HandleSetAllSensorsEnabled, 1.0f, TEXT("true / false")));
144 CommandHandlers.Add(TEXT("enableallsensors"), FCommand(&UROSCommands::HandleEnableAllSensors, 1.0f, TEXT("true / false")));
145 CommandHandlers.Add(TEXT("disableallsensors"), FCommand(&UROSCommands::HandleDisableAllSensors, 1.0f, TEXT("true / false")));
146 CommandHandlers.Add(TEXT("setsensorenabled"), FCommand(&UROSCommands::HandleSetSensorEnabled, 1.0f, TEXT("ID true/false")));
147
148 // Spawn/change objects commands. They all call the same function. They are defined separately for clarity.
149 CommandHandlers.Add(TEXT("spawnobjects"), FCommand(&UROSCommands::HandleSpawnObjects, 0.05f, TEXT("Spawn objects from JSON file")));
150 CommandHandlers.Add(TEXT("changeweather"), FCommand(&UROSCommands::HandleSpawnObjects, 0.05f, TEXT("change weather from JSON file")));
151 CommandHandlers.Add(TEXT("changecolors"), FCommand(&UROSCommands::HandleSpawnObjects, 0.05f, TEXT("change weather from JSON file")));
152
153 // Exports
154 CommandHandlers.Add(TEXT("exportall"), FCommand(&UROSCommands::HandleExportAll, 1.0f, TEXT("Export all spanwed things to JSON file")));
155 CommandHandlers.Add(TEXT("exportweather"), FCommand(&UROSCommands::HandleExportWeather, 1.0f, TEXT("Export current weather to JSON file")));
156 CommandHandlers.Add(TEXT("exportwalkers"), FCommand(&UROSCommands::HandleExportWalkers, 1.0f, TEXT("Export all Walkers to JSON file")));
157 CommandHandlers.Add(TEXT("exportvehicles"), FCommand(&UROSCommands::HandleExportVehicles, 1.0f, TEXT("Export all Vehicles to JSON file")));
158 CommandHandlers.Add(TEXT("exportsensors"), FCommand(&UROSCommands::HandleExportSensors, 1.0f, TEXT("Export all Sensors to JSON file")));
159 CommandHandlers.Add(TEXT("exportprops"), FCommand(&UROSCommands::HandleExportProps, 1.0f, TEXT("Export all props to JSON file")));
160 CommandHandlers.Add(TEXT("exportfoliage"), FCommand(&UROSCommands::HandleExportFoliage, 1.0f, TEXT("Export all Foliage to JSON file")));
161
162 // Overlap sensor commands
163 // changeoverlapbounds format: 'changeoverlapbounds sensor_id 500,500,500'
164 // changeoverlapposition format: 'changeoverlapposition sensor_id 0,0,0'
165 CommandHandlers.Add(TEXT("visoverlapbounds"), FCommand(&UROSCommands::HandleVisualizeOverlapSensorsBounds, 0.05f, TEXT("Visualize All Overlap sensors bounds")));
166 CommandHandlers.Add(TEXT("changeoverlapbounds"), FCommand(&UROSCommands::HandleChangeOverlapSensorBounds, 0.05f, TEXT("Change Overlap sensor area bounds")));
167 CommandHandlers.Add(TEXT("changeoverlapposition"), FCommand(&UROSCommands::HandleChangeOverlapSensorPosition, 0.05f, TEXT("Change Overlap sensor relative position")));
168
169 // Walker commands
170 CommandHandlers.Add(TEXT("movewalkerto"), FCommand(&UROSCommands::HandleMoveWalkerToAndStop, 0.05f, TEXT("ID (position or position,rotation)")));
171 CommandHandlers.Add(TEXT("movewalkertoanddestroy"), FCommand(&UROSCommands::HandleMoveWalkerToAndDestroy, 0.05f, TEXT("ID (position or position,rotation)")));
172 CommandHandlers.Add(TEXT("stopwalker"), FCommand(&UROSCommands::HandleStopWalker, 0.05f, TEXT("ID of the Walker")));
173 CommandHandlers.Add(TEXT("resumewalker"), FCommand(&UROSCommands::HandleResumeWalker, 0.05f, TEXT("ID of the Walker")));
174
175 // Drone commands
176 CommandHandlers.Add(TEXT("movedroneto"), FCommand(&UROSCommands::HandleMoveDroneToAndStop, 0.05f, TEXT("ID (position)")));
177}
178
180{
181 switch (state)
182 {
185 break;
186
189 break;
190 }
191}
192
194{
195 if (CommandTopic)
196 {
197 CommandTopic->Unadvertise();
198 CommandTopic->Unsubscribe();
199 CommandTopic->MarkAsDisconnected();
200 CommandTopic->ConditionalBeginDestroy();
201 CommandTopic = nullptr;
202 }
203}
204
206{
207 UWorld* World = GetGameWorld();
208 if (!World)
209 {
210 return;
211 }
212
214 if (!CommandTopic && RosInstance && RosInstance->IsROSConnected())
215 {
216 CommandTopic = NewObject<UTopic>(UTopic::StaticClass());
217 CommandTopic->Init(RosInstance->ROSIntegrationCore, TEXT("/agrarsense/in/commands"), TEXT("std_msgs/String"));
218 CommandTopic->Advertise();
219
220 // Create a std::function callback object
221 std::function<void(TSharedPtr<FROSBaseMsg>)> SubscribeCallback = [this](TSharedPtr<FROSBaseMsg> msg) -> void
222 {
223 auto Concrete = StaticCastSharedPtr<ROSMessages::std_msgs::String>(msg);
224 if (Concrete.IsValid())
225 {
226 FString message = *(Concrete->_Data);
227 AsyncTask(ENamedThreads::GameThread, [this, message]()
228 {
229 // Parse message on GameThread since many commands are NOT thread-safe
230 ParseIncomingMessage(message);
231 });
232 }
233 return;
234 };
235
236 // Subscribe to the topic
237 CommandTopic->Subscribe(SubscribeCallback);
238 }
239}
240
241void UROSCommands::ParseIncomingMessage(const FString Message)
242{
243 // Parse incoming string message into {COMMAND} {VARIABLE} format
244 int32 SpaceIndex;
245 FString Command;
246 FString Variable;
247
248 if (Message.FindChar(' ', SpaceIndex))
249 {
250 // Extract the command as the substring before the first space
251 Command = Message.Left(SpaceIndex).ToLower();
252
253 // Extract the rest of the message as the variable
254 Variable = Message.Mid(SpaceIndex + 1).ToLower();
255 }
256 else
257 {
258 // If no space is found, consider the entire message as the command
259 Command = Message.ToLower();
260 }
261
262#if WITH_EDITOR
263 UE_LOG(LogTemp, Warning, TEXT("ROSCommands.Cpp: Incoming Command: %s with variable: %s"), *Command, *Variable);
264#endif
265
266 FCommand* CommandInfo = CommandHandlers.Find(Command);
267 if (CommandInfo)
268 {
269 // Check if enough time has passed since the last execution.
270 double CurrentTime = FPlatformTime::Seconds();
271 double TimeSinceLastExecution = CurrentTime - CommandInfo->LastExecutionTime;
272
273 if (TimeSinceLastExecution >= CommandInfo->CooldownTime)
274 {
275 // Call the handler function with the variable.
276 (this->*(CommandInfo->Handler))(Variable);
277
278 // Update the last execution time.
279 CommandInfo->LastExecutionTime = CurrentTime;
280 }
281 else
282 {
283 float CoolDownTimeLeft = CommandInfo->CooldownTime - TimeSinceLastExecution;
284 FString Msg = FString::Printf(TEXT("Command '%s' on cooldown. Retry in %.2f sec."), *Command, CoolDownTimeLeft);
286 }
287 }
288 else
289 {
290 FString Msg = FString::Printf(TEXT("Couldn't find command: '%s'"), *Command);
292 }
293}
294
295bool UROSCommands::TryParseBoolean(const FString& String, bool& OutBool)
296{
297 FString LoweredString = String.ToLower();
298
299 if (LoweredString.Equals("true") || LoweredString.Equals("1"))
300 {
301 OutBool = true;
302 return true;
303 }
304 else if (LoweredString.Equals("false") || LoweredString.Equals("0"))
305 {
306 OutBool = false;
307 return true;
308 }
309
310 // Invalid boolean value
311 return false;
312}
313
315{
316 if (!CommandTopic)
317 {
318 return;
319 }
320
321 FString message = "Available Simulator ROS commands {COMMAND} {VALUE} || ";
322
323 for (const TPair<FString, FCommand>& CommandPair : CommandHandlers)
324 {
325 const FString& CommandString = CommandPair.Key;
326 const FCommand& CommandInfo = CommandPair.Value;
327 if (CommandInfo.DefaultValue.IsEmpty())
328 {
329 message += FString::Printf(TEXT("%s || "), *CommandString);
330 }
331 else
332 {
333 message += FString::Printf(TEXT("%s %s || "), *CommandString, *CommandInfo.DefaultValue);
334 }
335 }
336
337 SimulatorLog::Log(message);
338}
339
340void UROSCommands::HandleQuit(const FString& Variable)
341{
342 UWorld* World = GetGameWorld();
343 if (GEngine && World)
344 {
345 GEngine->Exec(World, TEXT("quit force"));
346 }
347}
348
349void UROSCommands::HandlePauseSimulator(const FString& Variable)
350{
351 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
352 if (AgrarsenseSettings)
353 {
354 AgrarsenseSettings->PauseSimulationEndOfThisFrame();
355 }
356}
357
358void UROSCommands::HandleUnPauseSimulator(const FString& Variable)
359{
360 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
361 if (AgrarsenseSettings)
362 {
363 AgrarsenseSettings->UnPauseSimulation();
364 }
365}
366
367void UROSCommands::HandleAdvanceOneFrame(const FString& Variable)
368{
369 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
370 if (AgrarsenseSettings)
371 {
372 AgrarsenseSettings->AdvanceFrameCount(1);
373 }
374}
375
376void UROSCommands::HandleAdvanceFrames(const FString& Variable)
377{
378 int32 FrameCount = 0;
379 if (!Variable.IsNumeric())
380 {
381 return;
382 }
383
384 FrameCount = FCString::Atoi(*Variable);
385 if (FrameCount != 0)
386 {
387 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
388 if (AgrarsenseSettings)
389 {
390 AgrarsenseSettings->AdvanceFrameCount(FrameCount);
391 }
392 }
393}
394
395void UROSCommands::HandleAdvanceTime(const FString& Variable)
396{
397 float Time = 0.0f;
398 if (!Variable.IsNumeric())
399 {
400 return;
401 }
402
403 Time = FCString::Atof(*Variable);
404 if (Time != 0.0f)
405 {
406 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
407 if (AgrarsenseSettings)
408 {
409 AgrarsenseSettings->AdvanceTime(Time);
410 }
411 }
412}
413
414void UROSCommands::HandleChangeMap(const FString& Variable)
415{
416 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
417 if (AgrarsenseSettings)
418 {
419 AgrarsenseSettings->ChangeMapByName(Variable);
420 }
421}
422
423void UROSCommands::HandleUnrealCommand(const FString& Variable)
424{
425 UWorld* World = GetGameWorld();
426 if (GEngine && World)
427 {
428 GEngine->Exec(World, *Variable);
429 }
430}
431
432void UROSCommands::HandleTeleportSpectator(const FString& Variable)
433{
434 // Split the comma-separated string into components
435 TArray<FString> Components;
436 Variable.ParseIntoArray(Components, TEXT(","), true);
437
438 if (Components.Num() >= 3)
439 {
440 FVector Location;
441 FQuat Rotation;
442
443 // Convert the first three components to float values for location
444 float X = FCString::Atof(*Components[0]);
445 float Y = FCString::Atof(*Components[1]);
446 float Z = FCString::Atof(*Components[2]);
447
448 Location = FVector(X, Y, Z);
449
450 if (Components.Num() >= 6)
451 {
452 // If there are six or more components, try to parse them as rotation values
453 float Pitch = FCString::Atof(*Components[3]);
454 float Yaw = FCString::Atof(*Components[4]);
455 float Roll = FCString::Atof(*Components[5]);
456
457 // Convert the Euler angles to a quaternion
458 Rotation = FQuat(FRotator(Pitch, Yaw, Roll));
459 }
460
461 UWorld* World = GetGameWorld();
462 if (World)
463 {
465 if (Spectator)
466 {
467 FTransform Transform;
468 Transform.SetLocation(Location);
469 Transform.SetRotation(Rotation);
470 Spectator->TeleportSpectator(Transform);
471 }
472 }
473 }
474}
475
476void UROSCommands::HandleTeleportActorByID(const FString& Variable)
477{
478 FString ID;
479 FString TransformString;
480
481 // Split the ID and rest of the message
482 TArray<FString> Tokens;
483 Variable.ParseIntoArray(Tokens, TEXT(" "), true);
484 if (Tokens.Num() >= 2)
485 {
486 ID = Tokens[0];
487 TransformString = Variable.RightChop(ID.Len() + 1);
488 }
489 else
490 {
491 // Not valid, return
492 return;
493 }
494
495 // Check if this ID matches any Actor
496 AActor* Actor = IActorInformation::GetActorByID(ID);
497 if (!Actor)
498 {
499 // Not valid, return
500 return;
501 }
502
503 // Parse rest of the string to Transform
504 TArray<FString> Components;
505 TransformString.ParseIntoArray(Components, TEXT(","), true);
506
507 if (Components.Num() >= 3)
508 {
509 FVector Location;
510 FQuat Rotation;
511
512 // Convert the first three components to float values for location
513 float X = FCString::Atof(*Components[0]);
514 float Y = FCString::Atof(*Components[1]);
515 float Z = FCString::Atof(*Components[2]);
516
517 Location = FVector(X, Y, Z);
518
519 if (Components.Num() >= 6)
520 {
521 // If there are six or more components, try to parse them as rotation values
522 float Pitch = FCString::Atof(*Components[3]);
523 float Yaw = FCString::Atof(*Components[4]);
524 float Roll = FCString::Atof(*Components[5]);
525
526 // Convert the Euler angles to a quaternion
527 Rotation = FQuat(FRotator(Pitch, Yaw, Roll));
528 }
529
530 FTransform Transform;
531 Transform.SetLocation(Location);
532 Transform.SetRotation(Rotation);
533
534#if WITH_EDITOR
535 UE_LOG(LogTemp, Warning, TEXT("Teleporting Actor with ID: %s to: %s"), *ID, *TransformString);
536#endif
537
538 // Check if this Actor is Vehicle
539 AVehicle* VehiclePtr = Cast<AVehicle>(Actor);
540 if (VehiclePtr)
541 {
542 // Disable vehicle physics so it can be teleported
543 VehiclePtr->TogglePhysics(false);
544
545 Actor->SetActorTransform(Transform);
546
547 // Enable vehicle physics back on after teleporting vehicle
548 VehiclePtr->TogglePhysics(true);
549 }
550 else
551 {
552 // Else set the Actor transform
553 Actor->SetActorTransform(Transform);
554
555 // If the Actor is InstancedActor, we need to notify it. See InstancedActor.cpp
556 AInstancedActor* InstancedActorPtr = Cast<AInstancedActor>(Actor);
557 if (InstancedActorPtr)
558 {
559 InstancedActorPtr->UpdateTransformPosition();
560 }
561 }
562 }
563}
564
565void UROSCommands::HandleTryDestroyObjectByID(const FString& Variable)
566{
567 bool success = IActorInformation::DestroyActorByID(Variable);
568
569 FString Message;
570 if (success)
571 {
572 Message = FString::Printf(TEXT("Object with ID %s successfully destroyed."), *Variable);
573 }
574 else
575 {
576 Message = FString::Printf(TEXT("Failed to destroy object with ID %s."), *Variable);
577 }
578
579 SimulatorLog::Log(Message);
580}
581
582void UROSCommands::HandleDestroyAllSensors(const FString& Variable)
583{
585}
586
587void UROSCommands::HandleDestroyAllWalkers(const FString& Variable)
588{
590}
591
592void UROSCommands::HandleDestroyAllVehicles(const FString& Variable)
593{
594 UWorld* World = GetGameWorld();
595 if (!World)
596 {
597 return;
598 }
599
600 TArray<AActor*> Vehicles;
601 UGameplayStatics::GetAllActorsOfClass(World, AVehicle::StaticClass(), Vehicles);
602 for (AActor* Actor : Vehicles)
603 {
604 AVehicle* Vehicle = Cast<AVehicle>(Actor);
605 if (Vehicle)
606 {
607 Vehicle->Destroy();
608 }
609 }
610}
611
612void UROSCommands::HandlePrintMaps(const FString& Variable)
613{
614 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
615 if (AgrarsenseSettings)
616 {
617 TArray<FString> Maps = AgrarsenseSettings->GetMapNames();
618
619 FString message;
620
621 for (const FString& map : Maps)
622 {
623 message += FString::Printf(TEXT("%s, "), *map);
624 }
625
626 SimulatorLog::Log(message);
627 }
628}
629
630void UROSCommands::HandlePrintAllSensors(const FString& Variable)
631{
632 PrintActorInformation(Variable, ASensor::StaticClass(), "sensor");
633}
634
635void UROSCommands::HandlePrintAllVehicles(const FString& Variable)
636{
637 PrintActorInformation(Variable, AVehicle::StaticClass(), "vehicle");
638}
639
640void UROSCommands::HandlePrintAllWalkers(const FString& Variable)
641{
642 PrintActorInformation(Variable, AWalker::StaticClass(), "walker");
643}
644
645void UROSCommands::PrintActorInformation(const FString& Variable, UClass* ActorClass, const FString& ActorTypeName)
646{
647 TArray<AActor*> Actors;
648 UGameplayStatics::GetAllActorsWithInterface(GetGameWorld(), UActorInformation::StaticClass(), Actors);
649
650 TArray<AActor*> TypedActors;
651 for (AActor* Actor : Actors)
652 {
653 if (Actor->IsA(ActorClass))
654 {
655 TypedActors.Add(Actor);
656 }
657 }
658
659 FString Msg;
660 if (!TypedActors.IsEmpty())
661 {
662 Msg = FString::Printf(TEXT("Simulation has %d %ss \n "), TypedActors.Num(), *ActorTypeName);
663 for (AActor* Actor : TypedActors)
664 {
665 if (Actor)
666 {
667 if (Actor->Implements<UActorInformation>())
668 {
669 FString ActorInfo = IActorInformation::Execute_GetActorInformation(Actor);
670 Msg += FString::Printf(TEXT("%s \n \n "), *ActorInfo);
671 }
672
673 }
674 }
675 }
676 else
677 {
678 Msg = FString::Printf(TEXT("Simulation has 0 %ss."), *ActorTypeName);
679 }
680
682}
683
684void UROSCommands::HandlePrintIds(const FString& Variable)
685{
687}
688
690{
691 if (Variable.IsNumeric())
692 {
693 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
694 if (AgrarsenseSettings)
695 {
696 int32 IntValue = FCString::Atoi(*Variable);
697 AgrarsenseSettings->SetGlobalTargetFrameRate(IntValue);
698 }
699 }
700}
701
702void UROSCommands::HandleSetGlobalTimeDilation(const FString& Variable)
703{
704 if (Variable.IsNumeric())
705 {
706 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
707 if (AgrarsenseSettings)
708 {
709 float FloatValue = FCString::Atof(*Variable);
710 AgrarsenseSettings->SetGlobalTimeDilation(FloatValue);
711 }
712 }
713}
714
715void UROSCommands::HandleSetQualityLevel(const FString& Variable)
716{
717 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
718 if (AgrarsenseSettings)
719 {
720 AgrarsenseSettings->SetQualityLevelFromString(Variable);
721 }
722}
723
724void UROSCommands::HandleSetWorldRendering(const FString& Variable)
725{
726 bool RenderWorld;
727 if (!TryParseBoolean(Variable, RenderWorld))
728 {
729 // Failed to parse, return
730 return;
731 }
732
733 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
734 if (AgrarsenseSettings)
735 {
736 AgrarsenseSettings->SetWorldRendering(RenderWorld);
737 }
738}
739
741{
742 bool Save;
743 if (!TryParseBoolean(Variable, Save))
744 {
745 // Failed to parse, return
746 return;
747 }
748
750 if (LidarManager)
751 {
752 LidarManager->SetSaveCombinedCloudToDisk(Save);
753 }
754}
755
756void UROSCommands::HandleSpawnObjects(const FString& Variable)
757{
759}
760
761void UROSCommands::HandleExportAll(const FString& Variable)
762{
763 // Below export functions do not need any incoming variable but require FString
764 FString EmptyString;
765
766 HandleExportWeather(EmptyString);
767 HandleExportWalkers(EmptyString);
768
769 // HandleExportSensors exports vehicles as well
770 //HandleExportVehicles(EmptyString);
771 HandleExportSensors(EmptyString);
772
773 HandleExportFoliage(EmptyString);
774 HandleExportProps(EmptyString);
775}
776
777void UROSCommands::HandleExportWeather(const FString& Variable)
778{
780 if (Weather)
781 {
782 Weather->ExportToJSON("ExportedWeather");
783 }
784}
785
786void UROSCommands::HandleExportWalkers(const FString& Variable)
787{
788 TArray<AWalker*> Walkers = UAssetLibrary::GetAllWalkers();
789 for (AWalker* Walker : Walkers)
790 {
791 if (Walker)
792 {
793 Walker->ExportToJsonFile("ExportedWalker");
794 }
795 }
796}
797
798void UROSCommands::HandleExportVehicles(const FString& Variable)
799{
800 TArray<FVehicleData> Vehicles = UAssetLibrary::GetSpawnedVehicles();
801 for (const FVehicleData& VehicleData : Vehicles)
802 {
803 AVehicle* VehiclePtr = VehicleData.Vehicle.Get();
804 if (VehiclePtr)
805 {
806 VehiclePtr->ExportToJsonFile("ExportedVehicle");
807 }
808 }
809}
810
811void UROSCommands::HandleExportSensors(const FString& Variable)
812{
813 UWorld* World = GetGameWorld();
814 if (!World)
815 {
816 return;
817 }
818
819 // Export all Vehicles and attached sensors
820 TArray<AActor*> Vehicles;
821 UGameplayStatics::GetAllActorsOfClass(World, AVehicle::StaticClass(), Vehicles);
822 for (AActor* Actor : Vehicles)
823 {
824 AVehicle* VehiclePtr = Cast<AVehicle>(Actor);
825 if (VehiclePtr)
826 {
827 VehiclePtr->ExportToJsonFile("ExportedVehicle");
828 }
829 }
830
831 // Export all Sensors separately as well
832 TArray<AActor*> Sensors;
833 UGameplayStatics::GetAllActorsOfClass(World, ASensor::StaticClass(), Sensors);
834 for (AActor* Actor : Sensors)
835 {
836 ASensor* SensorPtr = Cast<ASensor>(Actor);
837 if (SensorPtr)
838 {
839 SensorPtr->ExportToJsonFile("ExportedSensor");
840 }
841 }
842}
843
844void UROSCommands::HandleExportFoliage(const FString& Variable)
845{
846 TArray<AInstancedActor*> FoliageActors = UAssetLibrary::GetAllAddedFoliageActors();
847 USimulatorJsonExporter::ExportInstancedActorsToJSON("ExportedFoliage", FoliageActors);
848}
849
850void UROSCommands::HandleExportProps(const FString& Variable)
851{
852 TArray<AInstancedActor*> PropActors = UAssetLibrary::GetAllAddedPropActors();
853 USimulatorJsonExporter::ExportInstancedActorsToJSON("ExportedProps", PropActors);
854}
855
857{
858 bool Visualize;
859 if (!TryParseBoolean(Variable, Visualize))
860 {
861 // Failed to parse, return
862 return;
863 }
864
865 UWorld* World = GetGameWorld();
866 if (World)
867 {
868 TArray<AActor*> OverlapSensors;
869 UGameplayStatics::GetAllActorsOfClass(World, AOverlapSensor::StaticClass(), OverlapSensors);
870
871 for (AActor* SensorActor : OverlapSensors)
872 {
873 AOverlapSensor* Sensor = Cast<AOverlapSensor>(SensorActor);
874 if (Sensor)
875 {
876 Sensor->SetVisualizeOverlapArea(Visualize);
877 }
878 }
879 }
880}
881
883{
884 FString ID;
885 FString BoundsString;
886
887 TArray<FString> Tokens;
888 Variable.ParseIntoArray(Tokens, TEXT(" "), true);
889
890 if (Tokens.Num() < 2)
891 {
892 // Incoming parameters were invalid, return
893 return;
894 }
895
896 ID = Tokens[0];
897 BoundsString = Tokens[1];
898
899 FVector Bounds;
900 TArray<FString> BoundsTokens;
901 BoundsString.ParseIntoArray(BoundsTokens, TEXT(","), true);
902
903 if (BoundsTokens.Num() >= 3)
904 {
905 Bounds.X = FCString::Atof(*BoundsTokens[0]);
906 Bounds.Y = FCString::Atof(*BoundsTokens[1]);
907 Bounds.Z = FCString::Atof(*BoundsTokens[2]);
908
909 AActor* Actor = IActorInformation::GetActorByID(ID);
910 AOverlapSensor* Sensor = Cast<AOverlapSensor>(Actor);
911 if (Sensor)
912 {
913 Sensor->SetOverlapBounds(Bounds);
914 }
915 }
916}
917
919{
920 FString ID;
921 FString BoundsString;
922
923 TArray<FString> Tokens;
924 Variable.ParseIntoArray(Tokens, TEXT(" "), true);
925
926 if (Tokens.Num() < 2)
927 {
928 // Incoming parameters were invalid, return
929 return;
930 }
931
932 ID = Tokens[0];
933 BoundsString = Tokens[1];
934
935 FVector RelativePosition;
936 TArray<FString> BoundsTokens;
937 BoundsString.ParseIntoArray(BoundsTokens, TEXT(","), true);
938
939 if (BoundsTokens.Num() >= 3)
940 {
941 RelativePosition.X = FCString::Atof(*BoundsTokens[0]);
942 RelativePosition.Y = FCString::Atof(*BoundsTokens[1]);
943 RelativePosition.Z = FCString::Atof(*BoundsTokens[2]);
944
945 AActor* Actor = IActorInformation::GetActorByID(ID);
946 AOverlapSensor* Sensor = Cast<AOverlapSensor>(Actor);
947 if (Sensor)
948 {
949 Sensor->SetOverlapRelativePosition(RelativePosition);
950 }
951 }
952}
953
955{
957}
958
959void UROSCommands::HandleMoveWalkerToAndStop(const FString& Variable)
960{
962}
963
964void UROSCommands::HandleMoveDroneToAndStop(const FString& Variable)
965{
967}
968
969void UROSCommands::HandleMoveWalkerTo(const FString& Variable, EWalkerEndAction EndAction)
970{
971 // This function overrides the current parameters of the Walker identified by the given ID,
972 // moving the Walker to the specified x,y,z position and stopping upon reaching the target.
973 // Usage: "movewalkerto reindeer 0,0,0" where 'reindeer' is the Walker ID.
974
975 FString ID;
976 FString TransformString;
977
978 // Split the ID and rest of the message
979 TArray<FString> Tokens;
980 Variable.ParseIntoArray(Tokens, TEXT(" "), true);
981 if (Tokens.Num() >= 2)
982 {
983 ID = Tokens[0];
984 TransformString = Variable.RightChop(ID.Len() + 1);
985 }
986 else
987 {
988 return;
989 }
990
991 // Check if this ID matches any Actor
992 AActor* Actor = IActorInformation::GetActorByID(ID);
993 if (!Actor)
994 {
995 return;
996 }
997
998 AWalker* Walker = Cast<AWalker>(Actor);
999 if (!Walker)
1000 {
1001 return;
1002 }
1003
1004 // Parse rest of the string to Transform
1005 TArray<FString> Components;
1006 TransformString.ParseIntoArray(Components, TEXT(","), true);
1007
1008 if (Components.Num() >= 3)
1009 {
1010 FVector Location;
1011 FQuat Rotation;
1012
1013 // Convert the first three components to float values for location
1014 float X = FCString::Atof(*Components[0]);
1015 float Y = FCString::Atof(*Components[1]);
1016 float Z = FCString::Atof(*Components[2]);
1017
1018 Location = FVector(X, Y, Z);
1019
1020 if (Components.Num() >= 6)
1021 {
1022 // If there are six or more components, try to parse them as rotation values
1023 float Pitch = FCString::Atof(*Components[3]);
1024 float Yaw = FCString::Atof(*Components[4]);
1025 float Roll = FCString::Atof(*Components[5]);
1026
1027 // Convert the Euler angles to a quaternion
1028 Rotation = FQuat(FRotator(Pitch, Yaw, Roll));
1029 }
1030
1031 FTransform Transform;
1032 Transform.SetLocation(Location);
1033 Transform.SetRotation(Rotation);
1034
1035 // Create new walker parameters
1036 FWalkerParameters NewParams;
1038 NewParams.WalkerEndAction = EndAction;
1039 NewParams.Points.Add(Transform);
1040
1041 // Change Walker parameters
1042 Walker->ChangeWalkerParameters(NewParams);
1043 }
1044}
1045
1046void UROSCommands::HandleStopWalker(const FString& Variable)
1047{
1048 HandleSetWalkerMovement(Variable, true);
1049}
1050
1051void UROSCommands::HandleResumeWalker(const FString& Variable)
1052{
1053 HandleSetWalkerMovement(Variable, false);
1054}
1055
1056void UROSCommands::HandleSetWalkerMovement(const FString& Variable, bool IsPaused)
1057{
1058 AActor* Actor = IActorInformation::GetActorByID(Variable);
1059 AWalker* Walker = Cast<AWalker>(Actor);
1060 if (!Walker)
1061 {
1062 return;
1063 }
1064
1065 if (IsPaused)
1066 {
1067 Walker->PauseWalker();
1068 }
1069 else
1070 {
1071 Walker->ResumeWalker();
1072 }
1073}
1074
1075void UROSCommands::HandleMoveDroneTo(const FString& Variable, EDroneEndAction EndAction)
1076{
1077 // This function overrides the current parameters of the Drone identified by the given ID,
1078 // moving the Drone to the specified x,y,z position and stopping upon reaching the target.
1079 // Usage: "movedroneto drone 0,0,0" where 'drone' is the Drone ID.
1080
1081 FString ID;
1082 FString TransformString;
1083
1084 // Split the ID and rest of the message
1085 TArray<FString> Tokens;
1086 Variable.ParseIntoArray(Tokens, TEXT(" "), true);
1087 if (Tokens.Num() >= 2)
1088 {
1089 ID = Tokens[0];
1090 TransformString = Variable.RightChop(ID.Len() + 1);
1091 }
1092 else
1093 {
1094 return;
1095 }
1096
1097 // Check if this ID matches any Actor
1098 AActor* Actor = IActorInformation::GetActorByID(ID);
1099 if (!Actor)
1100 {
1101 return;
1102 }
1103
1104 APIDDrone* Drone = Cast<APIDDrone>(Actor);
1105 if (!Drone)
1106 {
1107 return;
1108 }
1109
1110 // Parse rest of the string to Transform
1111 TArray<FString> Components;
1112 TransformString.ParseIntoArray(Components, TEXT(","), true);
1113
1114 if (Components.Num() >= 3)
1115 {
1116 FVector Location;
1117 FQuat Rotation;
1118
1119 // Convert the first three components to float values for location
1120 float X = FCString::Atof(*Components[0]);
1121 float Y = FCString::Atof(*Components[1]);
1122 float Z = FCString::Atof(*Components[2]);
1123
1124 Location = FVector(X, Y, Z);
1125
1126 if (Components.Num() >= 6)
1127 {
1128 // If there are six or more components, try to parse them as rotation values
1129 float Pitch = FCString::Atof(*Components[3]);
1130 float Yaw = FCString::Atof(*Components[4]);
1131 float Roll = FCString::Atof(*Components[5]);
1132
1133 // Convert the Euler angles to a quaternion
1134 Rotation = FQuat(FRotator(Pitch, Yaw, Roll));
1135 }
1136
1137 FTransform Transform;
1138 Transform.SetLocation(Location);
1139 Transform.SetRotation(Rotation);
1140
1141 // Create new drone parameters
1142 FDroneParameters NewParams;
1144 NewParams.DroneEndAction = EndAction;
1145 //NewParams.Points.Add(Transform);
1146
1147 Drone->ChangeDroneParameters(NewParams);
1148
1149 // Change drone parameters
1150 Drone->MoveDroneToPosition(Transform);
1151 }
1152}
1153
1154void UROSCommands::HandleSetAllSensorsEnabled(const FString& Variable)
1155{
1156 bool EnableSensors;
1157 if (!TryParseBoolean(Variable, EnableSensors))
1158 {
1159 // Failed to parse, return
1160 return;
1161 }
1162
1163 if (EnableSensors)
1164 {
1166 }
1167 else
1168 {
1170 }
1171}
1172
1173void UROSCommands::HandleEnableAllSensors(const FString& Variable)
1174{
1176}
1177
1178void UROSCommands::HandleDisableAllSensors(const FString& Variable)
1179{
1181}
1182
1183void UROSCommands::HandleSetSensorEnabled(const FString& Variable)
1184{
1185 TArray<FString> Tokens;
1186 Variable.ParseIntoArray(Tokens, TEXT(" "), true);
1187 if (Tokens.Num() < 2)
1188 {
1189 // Not enough arguments, return
1190 return;
1191 }
1192
1193 const FString& ID = Tokens[0];
1194
1195 AActor* Actor = IActorInformation::GetActorByID(ID);
1196 if (!Actor)
1197 {
1198 return;
1199 }
1200
1201 ASensor* Sensor = Cast<ASensor>(Actor);
1202 if (!Sensor)
1203 {
1204 return;
1205 }
1206
1207 FString BooleanString = Tokens[1].ToLower();
1208
1209 bool SimulateSensor;
1210 if (!TryParseBoolean(BooleanString, SimulateSensor))
1211 {
1212 // Failed to parse, return
1213 return;
1214 }
1215
1216 Sensor->SetSimulateSensor(SimulateSensor);
1217}
1218
1219void UROSCommands::HandleSetWPO(const FString& Variable)
1220{
1221 if (Variable.IsNumeric())
1222 {
1223 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
1224 if (AgrarsenseSettings)
1225 {
1226 int32 IntValue = FCString::Atoi(*Variable);
1227 AgrarsenseSettings->SetWorldPositionOffsetRenderDistance(IntValue);
1228 }
1229 }
1230}
1231
1233{
1234 if (Variable.IsNumeric())
1235 {
1236 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
1237 if (AgrarsenseSettings)
1238 {
1239 float Value = FCString::Atof(*Variable);
1240 AgrarsenseSettings->SetNaniteMaxPixelsPerEdge(Value);
1241 }
1242 }
1243}
1244
1245void UROSCommands::HandleDestroyTreesArea(const FString& Variable)
1246{
1247 HandleDestroyActors(Variable, true);
1248}
1249
1250void UROSCommands::HandleDestroyActorsArea(const FString& Variable)
1251{
1252 HandleDestroyActors(Variable, false);
1253}
1254
1255void UROSCommands::HandleDestroyActors(const FString& Variable, bool OnlyTrees)
1256{
1257 TArray<FString> ParsedStrings;
1258 Variable.ParseIntoArray(ParsedStrings, TEXT(" "), true);
1259
1260 if (ParsedStrings.Num() != 2)
1261 {
1262 return;
1263 }
1264
1265 // Parse position
1266 TArray<FString> PositionComponents;
1267 ParsedStrings[0].ParseIntoArray(PositionComponents, TEXT(","), true);
1268
1269 if (PositionComponents.Num() != 3)
1270 {
1271 return;
1272 }
1273
1274 FVector Position(FCString::Atof(*PositionComponents[0]), FCString::Atof(*PositionComponents[1]), FCString::Atof(*PositionComponents[2]));
1275
1276 // Parse bounds
1277 TArray<FString> BoundsComponents;
1278 ParsedStrings[1].ParseIntoArray(BoundsComponents, TEXT(","), true);
1279
1280 if (BoundsComponents.Num() != 3)
1281 {
1282 return;
1283 }
1284
1285 FVector Bounds(FCString::Atof(*BoundsComponents[0]), FCString::Atof(*BoundsComponents[1]), FCString::Atof(*BoundsComponents[2]));
1286
1287 FTransform VolumeTransform;
1288 VolumeTransform.SetLocation(Position);
1289
1290 UWorld* World = GetGameWorld();
1291 if (World)
1292 {
1293 ADeletionVolume* Volume = World->SpawnActor<ADeletionVolume>(ADeletionVolume::StaticClass(), VolumeTransform);
1294 if (Volume)
1295 {
1296 // Change volume bounds
1297 Volume->ChangeOverlapBounds(Bounds);
1298
1299 // Destroy overlapping actors,
1300 // this Actor gets deleted automatically after calling this.
1301 Volume->DestroyOverlappingActors(OnlyTrees);
1302 }
1303 }
1304}
EDroneEndAction
EROSState
Definition: ROSState.h:16
EWalkerEndAction
void DestroyOverlappingActors(bool OnlyTrees)
void ChangeOverlapBounds(FVector Bounds)
void UpdateTransformPosition()
void SetSaveCombinedCloudToDisk(bool bSaveCombinedCloud)
void SetOverlapRelativePosition(const FVector &Vector)
void SetVisualizeOverlapArea(bool Visualize)
void SetOverlapBounds(const FVector &NewSize)
Definition: Sensor.h:44
void SetSimulateSensor(bool SimulateSensor)
Definition: Sensor.h:151
FString ExportToJsonFile(const FString &FileName)
Definition: Sensor.cpp:140
void TeleportSpectator(const FTransform &Transform)
Definition: Spectator.cpp:48
FString ExportToJsonFile(const FString &FileName)
Definition: Vehicle.cpp:146
void TogglePhysics(bool isOn)
Definition: Walker.h:28
FString ExportToJSON(const FString &FileName)
Definition: Weather.cpp:121
static void PrintAllIds()
static bool DestroyActorByID(const FString &ID)
static AActor * GetActorByID(const FString &ID)
static void Log(const FString &Message, bool LogToTextFile=true, bool LogToROS=true)
void SetQualityLevelFromString(const FString &QualityLevelString)
void AdvanceTime(float TimeToAdvance)
void ChangeMapByName(FString MapName)
void AdvanceFrameCount(int32 FramesToAdvance)
TArray< FString > GetMapNames() const
void SetGlobalTimeDilation(float TimeDilation)
void SetGlobalTargetFrameRate(int NewTargetFrameRate)
void SetWorldPositionOffsetRenderDistance(int32 WorldPositionOffsetDistance)
void SetWorldRendering(bool enabled)
void SetNaniteMaxPixelsPerEdge(float MaxPixelsPerEdge=1.0f)
static ASpectator * GetSpectator(const UObject *WorldContextObject)
static UAgrarsenseSettings * GetAgrarsenseSettings()
static AWeather * GetWeatherActor(const UObject *WorldContextObject)
static UROSIntegrationGameInstance * GetROSGameInstance(const UObject *WorldContextObject)
static ALidarManager * GetLidarManager(const UObject *WorldContextObject)
static UROSHandler * GetROSHandle(const UObject *WorldContextObject)
static TArray< AInstancedActor * > GetAllAddedPropActors()
static void DestroyAllWalkers()
static TArray< FVehicleData > GetSpawnedVehicles()
static TArray< AInstancedActor * > GetAllAddedFoliageActors()
static TArray< AWalker * > GetAllWalkers()
void HandleTeleportActorByID(const FString &Variable)
void HandleUnrealCommand(const FString &Variable)
void HandleChangeOverlapSensorBounds(const FString &Variable)
void HandlePrintAllWalkers(const FString &Variable)
void HandleTeleportSpectator(const FString &Variable)
void HandlePrintAllVehicles(const FString &Variable)
void HandlePrintAllSensors(const FString &Variable)
UROSIntegrationGameInstance * RosInstance
Definition: ROSCommands.h:105
void HandleDestroyActorsArea(const FString &Variable)
void HandleSetWalkerMovement(const FString &Variable, bool IsPaused)
static TMap< FString, FCommand > CommandHandlers
Definition: ROSCommands.h:73
void HandleAdvanceOneFrame(const FString &Variable)
void HandleUnPauseSimulator(const FString &Variable)
void HandlePrintAvailableCommands(const FString &Variable)
void PrintActorInformation(const FString &Variable, UClass *ActorClass, const FString &ActorTypeName)
void HandleAdvanceTime(const FString &Variable)
void HandleExportAll(const FString &Variable)
void HandleExportSensors(const FString &Variable)
void HandleExportVehicles(const FString &Variable)
void HandleSetSaveCombinedPointcloudToDisk(const FString &Variable)
void HandleDisableAllSensors(const FString &Variable)
void HandleSetWPO(const FString &Variable)
void DestroyROSTopic()
void HandleChangeMap(const FString &Variable)
void HandleExportWalkers(const FString &Variable)
void HandleResumeWalker(const FString &Variable)
UAgrarsenseSettings * GetSettings()
Definition: ROSCommands.cpp:79
void AddCommands()
Definition: ROSCommands.cpp:84
void HandleMoveDroneTo(const FString &Variable, EDroneEndAction EndAction)
void HandleSetWorldRendering(const FString &Variable)
void HandleSetGlobalTimeDilation(const FString &Variable)
void HandleDestroyAllSensors(const FString &Variable)
void ParseIncomingMessage(const FString Message)
void SetupROSCommandTopic()
void HandleMoveWalkerToAndStop(const FString &Variable)
void HandleExportWeather(const FString &Variable)
bool TryParseBoolean(const FString &String, bool &OutBool)
void HandleExportFoliage(const FString &Variable)
void HandleQuit(const FString &Variable)
void HandleSetAllSensorsEnabled(const FString &Variable)
void HandleChangeOverlapSensorPosition(const FString &Variable)
void HandleSetSensorEnabled(const FString &Variable)
void HandleTryDestroyObjectByID(const FString &Variable)
UWorld * GetGameWorld()
Definition: ROSCommands.cpp:69
void HandleVisualizeOverlapSensorsBounds(const FString &Variable)
void HandleEnableAllSensors(const FString &Variable)
void HandleMoveWalkerTo(const FString &Variable, EWalkerEndAction EndAction)
void HandleDestroyAllVehicles(const FString &Variable)
void HandleStopWalker(const FString &Variable)
void HandleDestroyActors(const FString &Variable, bool OnlyTrees)
void HandleMoveDroneToAndStop(const FString &Variable)
void HandleDestroyAllWalkers(const FString &Variable)
void HandleMoveWalkerToAndDestroy(const FString &Variable)
void HandleSetNaniteMaxPixelsPerEdge(const FString &Variable)
void HandlePrintMaps(const FString &Variable)
void HandleSpawnObjects(const FString &Variable)
UTopic * CommandTopic
Definition: ROSCommands.h:102
void HandleDestroyTreesArea(const FString &Variable)
void HandleSetGlobalTargetFrameRate(const FString &Variable)
void HandlePrintIds(const FString &Variable)
void HandleAdvanceFrames(const FString &Variable)
void HandleSetQualityLevel(const FString &Variable)
void HandlePauseSimulator(const FString &Variable)
void Destroy()
Definition: ROSCommands.cpp:59
void TryExecuteCommand(const FString &Command)
Definition: ROSCommands.cpp:64
void HandleExportProps(const FString &Variable)
void ROSBridgeStateChanged(EROSState state)
FROSDelegate_ROState OnROSStateChanged
Definition: ROSHandler.h:81
static void DestroyAllSensors(const UObject *WorldContextObject, bool DestroyDefaultVehicleSensors=false)
static void EnableAllSensors(const UObject *WorldContextObject)
static void DisableAllSensors(const UObject *WorldContextObject)
static FString ExportInstancedActorsToJSON(FString FileName, const TArray< AInstancedActor * > &Actors)
static void ParseAndOperateJSONFile(const FString &Path)
double LastExecutionTime
Definition: ROSCommands.h:33
FString DefaultValue
Definition: ROSCommands.h:34
float CooldownTime
Definition: ROSCommands.h:32
CommandHandler Handler
Definition: ROSCommands.h:31
EDroneEndAction DroneEndAction
EDroneAction DroneAction
EWalkerAction WalkerAction
TArray< FTransform > Points
EWalkerEndAction WalkerEndAction