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);
255 }
256 else
257 {
258 // If no space is found, consider the entire message as the command
259 Command = Message.ToLower();
260 }
261
262 // Log incoming message into text file for debugging purposes
263 FString CommandMsg = FString::Printf(TEXT("ROSCommands.cpp: Incoming [command variable]: %s %s"), *Command, *Variable);
264 SimulatorLog::Log(CommandMsg);
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 }
556}
557
558void UROSCommands::HandleTryDestroyObjectByID(const FString& Variable)
559{
560 bool success = IActorInformation::DestroyActorByID(Variable);
561
562 FString Message;
563 if (success)
564 {
565 Message = FString::Printf(TEXT("Object with ID %s successfully destroyed."), *Variable);
566 }
567 else
568 {
569 Message = FString::Printf(TEXT("Failed to destroy object with ID %s."), *Variable);
570 }
571
572 SimulatorLog::Log(Message);
573}
574
575void UROSCommands::HandleDestroyAllSensors(const FString& Variable)
576{
578}
579
580void UROSCommands::HandleDestroyAllWalkers(const FString& Variable)
581{
583}
584
585void UROSCommands::HandleDestroyAllVehicles(const FString& Variable)
586{
587 UWorld* World = GetGameWorld();
588 if (!World)
589 {
590 return;
591 }
592
593 TArray<AActor*> Vehicles;
594 UGameplayStatics::GetAllActorsOfClass(World, AVehicle::StaticClass(), Vehicles);
595 for (AActor* Actor : Vehicles)
596 {
597 AVehicle* Vehicle = Cast<AVehicle>(Actor);
598 if (Vehicle)
599 {
600 Vehicle->Destroy();
601 }
602 }
603}
604
605void UROSCommands::HandlePrintMaps(const FString& Variable)
606{
607 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
608 if (AgrarsenseSettings)
609 {
610 TArray<FString> Maps = AgrarsenseSettings->GetMapNames();
611
612 FString message;
613
614 for (const FString& map : Maps)
615 {
616 message += FString::Printf(TEXT("%s, "), *map);
617 }
618
619 SimulatorLog::Log(message);
620 }
621}
622
623void UROSCommands::HandlePrintAllSensors(const FString& Variable)
624{
625 PrintActorInformation(Variable, ASensor::StaticClass(), "sensor");
626}
627
628void UROSCommands::HandlePrintAllVehicles(const FString& Variable)
629{
630 PrintActorInformation(Variable, AVehicle::StaticClass(), "vehicle");
631}
632
633void UROSCommands::HandlePrintAllWalkers(const FString& Variable)
634{
635 PrintActorInformation(Variable, AWalker::StaticClass(), "walker");
636}
637
638void UROSCommands::PrintActorInformation(const FString& Variable, UClass* ActorClass, const FString& ActorTypeName)
639{
640 TArray<AActor*> Actors;
641 UGameplayStatics::GetAllActorsWithInterface(GetGameWorld(), UActorInformation::StaticClass(), Actors);
642
643 TArray<AActor*> TypedActors;
644 for (AActor* Actor : Actors)
645 {
646 if (Actor->IsA(ActorClass))
647 {
648 TypedActors.Add(Actor);
649 }
650 }
651
652 FString Msg;
653 if (!TypedActors.IsEmpty())
654 {
655 Msg = FString::Printf(TEXT("Simulation has %d %ss \n "), TypedActors.Num(), *ActorTypeName);
656 for (AActor* Actor : TypedActors)
657 {
658 if (Actor)
659 {
660 if (Actor->Implements<UActorInformation>())
661 {
662 FString ActorInfo = IActorInformation::Execute_GetActorInformation(Actor);
663 Msg += FString::Printf(TEXT("%s \n \n "), *ActorInfo);
664 }
665
666 }
667 }
668 }
669 else
670 {
671 Msg = FString::Printf(TEXT("Simulation has 0 %ss."), *ActorTypeName);
672 }
673
675}
676
677void UROSCommands::HandlePrintIds(const FString& Variable)
678{
680}
681
683{
684 if (Variable.IsNumeric())
685 {
686 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
687 if (AgrarsenseSettings)
688 {
689 int32 IntValue = FCString::Atoi(*Variable);
690 AgrarsenseSettings->SetGlobalTargetFrameRate(IntValue);
691 }
692 }
693}
694
695void UROSCommands::HandleSetGlobalTimeDilation(const FString& Variable)
696{
697 if (Variable.IsNumeric())
698 {
699 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
700 if (AgrarsenseSettings)
701 {
702 float FloatValue = FCString::Atof(*Variable);
703 AgrarsenseSettings->SetGlobalTimeDilation(FloatValue);
704 }
705 }
706}
707
708void UROSCommands::HandleSetQualityLevel(const FString& Variable)
709{
710 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
711 if (AgrarsenseSettings)
712 {
713 AgrarsenseSettings->SetQualityLevelFromString(Variable);
714 }
715}
716
717void UROSCommands::HandleSetWorldRendering(const FString& Variable)
718{
719 bool RenderWorld;
720 if (!TryParseBoolean(Variable, RenderWorld))
721 {
722 // Failed to parse, return
723 return;
724 }
725
726 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
727 if (AgrarsenseSettings)
728 {
729 AgrarsenseSettings->SetWorldRendering(RenderWorld);
730 }
731}
732
734{
735 bool Save;
736 if (!TryParseBoolean(Variable, Save))
737 {
738 // Failed to parse, return
739 return;
740 }
741
743 if (LidarManager)
744 {
745 LidarManager->SetSaveCombinedCloudToDisk(Save);
746 }
747}
748
749void UROSCommands::HandleSpawnObjects(const FString& Variable)
750{
752}
753
754void UROSCommands::HandleExportAll(const FString& Variable)
755{
756 // Below export functions do not need any incoming variable but require FString
757 FString EmptyString;
758
759 HandleExportWeather(EmptyString);
760 HandleExportWalkers(EmptyString);
761
762 // HandleExportSensors exports vehicles as well
763 //HandleExportVehicles(EmptyString);
764 HandleExportSensors(EmptyString);
765
766 HandleExportFoliage(EmptyString);
767 HandleExportProps(EmptyString);
768}
769
770void UROSCommands::HandleExportWeather(const FString& Variable)
771{
773 if (Weather)
774 {
775 Weather->ExportToJSON("ExportedWeather");
776 }
777}
778
779void UROSCommands::HandleExportWalkers(const FString& Variable)
780{
781 TArray<AWalker*> Walkers = UAssetLibrary::GetAllWalkers();
782 for (AWalker* Walker : Walkers)
783 {
784 if (Walker)
785 {
786 Walker->ExportToJsonFile("ExportedWalker");
787 }
788 }
789}
790
791void UROSCommands::HandleExportVehicles(const FString& Variable)
792{
793 TArray<FVehicleData> Vehicles = UAssetLibrary::GetSpawnedVehicles();
794 for (const FVehicleData& VehicleData : Vehicles)
795 {
796 AVehicle* VehiclePtr = VehicleData.Vehicle.Get();
797 if (VehiclePtr)
798 {
799 VehiclePtr->ExportToJsonFile("ExportedVehicle");
800 }
801 }
802}
803
804void UROSCommands::HandleExportSensors(const FString& Variable)
805{
806 UWorld* World = GetGameWorld();
807 if (!World)
808 {
809 return;
810 }
811
812 // Export all Vehicles and attached sensors
813 TArray<AActor*> Vehicles;
814 UGameplayStatics::GetAllActorsOfClass(World, AVehicle::StaticClass(), Vehicles);
815 for (AActor* Actor : Vehicles)
816 {
817 AVehicle* VehiclePtr = Cast<AVehicle>(Actor);
818 if (VehiclePtr)
819 {
820 VehiclePtr->ExportToJsonFile("ExportedVehicle");
821 }
822 }
823
824 // Export all Sensors separately as well
825 TArray<AActor*> Sensors;
826 UGameplayStatics::GetAllActorsOfClass(World, ASensor::StaticClass(), Sensors);
827 for (AActor* Actor : Sensors)
828 {
829 ASensor* SensorPtr = Cast<ASensor>(Actor);
830 if (SensorPtr)
831 {
832 SensorPtr->ExportToJsonFile("ExportedSensor");
833 }
834 }
835}
836
837void UROSCommands::HandleExportFoliage(const FString& Variable)
838{
839 TArray<AInstancedActor*> FoliageActors = UAssetLibrary::GetAllAddedFoliageActors();
840 USimulatorJsonExporter::ExportInstancedActorsToJSON("ExportedFoliage", FoliageActors);
841}
842
843void UROSCommands::HandleExportProps(const FString& Variable)
844{
845 TArray<AInstancedActor*> PropActors = UAssetLibrary::GetAllAddedPropActors();
846 USimulatorJsonExporter::ExportInstancedActorsToJSON("ExportedProps", PropActors);
847}
848
850{
851 bool Visualize;
852 if (!TryParseBoolean(Variable, Visualize))
853 {
854 // Failed to parse, return
855 return;
856 }
857
858 UWorld* World = GetGameWorld();
859 if (World)
860 {
861 TArray<AActor*> OverlapSensors;
862 UGameplayStatics::GetAllActorsOfClass(World, AOverlapSensor::StaticClass(), OverlapSensors);
863
864 for (AActor* SensorActor : OverlapSensors)
865 {
866 AOverlapSensor* Sensor = Cast<AOverlapSensor>(SensorActor);
867 if (Sensor)
868 {
869 Sensor->SetVisualizeOverlapArea(Visualize);
870 }
871 }
872 }
873}
874
876{
877 FString ID;
878 FString BoundsString;
879
880 TArray<FString> Tokens;
881 Variable.ParseIntoArray(Tokens, TEXT(" "), true);
882
883 if (Tokens.Num() < 2)
884 {
885 // Incoming parameters were invalid, return
886 return;
887 }
888
889 ID = Tokens[0];
890 BoundsString = Tokens[1];
891
892 FVector Bounds;
893 TArray<FString> BoundsTokens;
894 BoundsString.ParseIntoArray(BoundsTokens, TEXT(","), true);
895
896 if (BoundsTokens.Num() >= 3)
897 {
898 Bounds.X = FCString::Atof(*BoundsTokens[0]);
899 Bounds.Y = FCString::Atof(*BoundsTokens[1]);
900 Bounds.Z = FCString::Atof(*BoundsTokens[2]);
901
902 AActor* Actor = IActorInformation::GetActorByID(ID);
903 AOverlapSensor* Sensor = Cast<AOverlapSensor>(Actor);
904 if (Sensor)
905 {
906 Sensor->SetOverlapBounds(Bounds);
907 }
908 }
909}
910
912{
913 FString ID;
914 FString BoundsString;
915
916 TArray<FString> Tokens;
917 Variable.ParseIntoArray(Tokens, TEXT(" "), true);
918
919 if (Tokens.Num() < 2)
920 {
921 // Incoming parameters were invalid, return
922 return;
923 }
924
925 ID = Tokens[0];
926 BoundsString = Tokens[1];
927
928 FVector RelativePosition;
929 TArray<FString> BoundsTokens;
930 BoundsString.ParseIntoArray(BoundsTokens, TEXT(","), true);
931
932 if (BoundsTokens.Num() >= 3)
933 {
934 RelativePosition.X = FCString::Atof(*BoundsTokens[0]);
935 RelativePosition.Y = FCString::Atof(*BoundsTokens[1]);
936 RelativePosition.Z = FCString::Atof(*BoundsTokens[2]);
937
938 AActor* Actor = IActorInformation::GetActorByID(ID);
939 AOverlapSensor* Sensor = Cast<AOverlapSensor>(Actor);
940 if (Sensor)
941 {
942 Sensor->SetOverlapRelativePosition(RelativePosition);
943 }
944 }
945}
946
948{
950}
951
952void UROSCommands::HandleMoveWalkerToAndStop(const FString& Variable)
953{
955}
956
957void UROSCommands::HandleMoveDroneToAndStop(const FString& Variable)
958{
960}
961
962void UROSCommands::HandleMoveWalkerTo(const FString& Variable, EWalkerEndAction EndAction)
963{
964 // This function overrides the current parameters of the Walker identified by the given ID,
965 // moving the Walker to the specified x,y,z position and stopping upon reaching the target.
966 // Usage: "movewalkerto reindeer 0,0,0" where 'reindeer' is the Walker ID.
967
968 FString ID;
969 FString TransformString;
970
971 // Split the ID and rest of the message
972 TArray<FString> Tokens;
973 Variable.ParseIntoArray(Tokens, TEXT(" "), true);
974 if (Tokens.Num() >= 2)
975 {
976 ID = Tokens[0];
977 TransformString = Variable.RightChop(ID.Len() + 1);
978 }
979 else
980 {
981 return;
982 }
983
984 // Check if this ID matches any Actor
985 AActor* Actor = IActorInformation::GetActorByID(ID);
986 if (!Actor)
987 {
988 return;
989 }
990
991 AWalker* Walker = Cast<AWalker>(Actor);
992 if (!Walker)
993 {
994 return;
995 }
996
997 // Parse rest of the string to Transform
998 TArray<FString> Components;
999 TransformString.ParseIntoArray(Components, TEXT(","), true);
1000
1001 if (Components.Num() >= 3)
1002 {
1003 FVector Location;
1004 FQuat Rotation;
1005
1006 // Convert the first three components to float values for location
1007 float X = FCString::Atof(*Components[0]);
1008 float Y = FCString::Atof(*Components[1]);
1009 float Z = FCString::Atof(*Components[2]);
1010
1011 Location = FVector(X, Y, Z);
1012
1013 if (Components.Num() >= 6)
1014 {
1015 // If there are six or more components, try to parse them as rotation values
1016 float Pitch = FCString::Atof(*Components[3]);
1017 float Yaw = FCString::Atof(*Components[4]);
1018 float Roll = FCString::Atof(*Components[5]);
1019
1020 // Convert the Euler angles to a quaternion
1021 Rotation = FQuat(FRotator(Pitch, Yaw, Roll));
1022 }
1023
1024 FTransform Transform;
1025 Transform.SetLocation(Location);
1026 Transform.SetRotation(Rotation);
1027
1028 // Create new walker parameters
1029 FWalkerParameters NewParams;
1031 NewParams.WalkerEndAction = EndAction;
1032 NewParams.Points.Add(Transform);
1033
1034 // Change Walker parameters
1035 Walker->ChangeWalkerParameters(NewParams);
1036 }
1037}
1038
1039void UROSCommands::HandleStopWalker(const FString& Variable)
1040{
1041 HandleSetWalkerMovement(Variable, true);
1042}
1043
1044void UROSCommands::HandleResumeWalker(const FString& Variable)
1045{
1046 HandleSetWalkerMovement(Variable, false);
1047}
1048
1049void UROSCommands::HandleSetWalkerMovement(const FString& Variable, bool IsPaused)
1050{
1051 AActor* Actor = IActorInformation::GetActorByID(Variable);
1052 AWalker* Walker = Cast<AWalker>(Actor);
1053 if (!Walker)
1054 {
1055 return;
1056 }
1057
1058 if (IsPaused)
1059 {
1060 Walker->PauseWalker();
1061 }
1062 else
1063 {
1064 Walker->ResumeWalker();
1065 }
1066}
1067
1068void UROSCommands::HandleMoveDroneTo(const FString& Variable, EDroneEndAction EndAction)
1069{
1070 // This function overrides the current parameters of the Drone identified by the given ID,
1071 // moving the Drone to the specified x,y,z position and stopping upon reaching the target.
1072 // Usage: "movedroneto drone 0,0,0" where 'drone' is the Drone ID.
1073
1074 FString ID;
1075 FString TransformString;
1076
1077 // Split the ID and rest of the message
1078 TArray<FString> Tokens;
1079 Variable.ParseIntoArray(Tokens, TEXT(" "), true);
1080 if (Tokens.Num() >= 2)
1081 {
1082 ID = Tokens[0];
1083 TransformString = Variable.RightChop(ID.Len() + 1);
1084 }
1085 else
1086 {
1087 return;
1088 }
1089
1090 // Check if this ID matches any Actor
1091 AActor* Actor = IActorInformation::GetActorByID(ID);
1092 if (!Actor)
1093 {
1094 return;
1095 }
1096
1097 APIDDrone* Drone = Cast<APIDDrone>(Actor);
1098 if (!Drone)
1099 {
1100 return;
1101 }
1102
1103 // Parse rest of the string to Transform
1104 TArray<FString> Components;
1105 TransformString.ParseIntoArray(Components, TEXT(","), true);
1106
1107 if (Components.Num() >= 3)
1108 {
1109 FVector Location;
1110 FQuat Rotation;
1111
1112 // Convert the first three components to float values for location
1113 float X = FCString::Atof(*Components[0]);
1114 float Y = FCString::Atof(*Components[1]);
1115 float Z = FCString::Atof(*Components[2]);
1116
1117 Location = FVector(X, Y, Z);
1118
1119 if (Components.Num() >= 6)
1120 {
1121 // If there are six or more components, try to parse them as rotation values
1122 float Pitch = FCString::Atof(*Components[3]);
1123 float Yaw = FCString::Atof(*Components[4]);
1124 float Roll = FCString::Atof(*Components[5]);
1125
1126 // Convert the Euler angles to a quaternion
1127 Rotation = FQuat(FRotator(Pitch, Yaw, Roll));
1128 }
1129
1130 FTransform Transform;
1131 Transform.SetLocation(Location);
1132 Transform.SetRotation(Rotation);
1133
1134 // Create new drone parameters
1135 FDroneParameters NewParams;
1137 NewParams.DroneEndAction = EndAction;
1138 //NewParams.Points.Add(Transform);
1139
1140 Drone->ChangeDroneParameters(NewParams);
1141
1142 // Change drone parameters
1143 Drone->MoveDroneToPosition(Transform);
1144 }
1145}
1146
1147void UROSCommands::HandleSetAllSensorsEnabled(const FString& Variable)
1148{
1149 bool EnableSensors;
1150 if (!TryParseBoolean(Variable, EnableSensors))
1151 {
1152 // Failed to parse, return
1153 return;
1154 }
1155
1156 if (EnableSensors)
1157 {
1159 }
1160 else
1161 {
1163 }
1164}
1165
1166void UROSCommands::HandleEnableAllSensors(const FString& Variable)
1167{
1169}
1170
1171void UROSCommands::HandleDisableAllSensors(const FString& Variable)
1172{
1174}
1175
1176void UROSCommands::HandleSetSensorEnabled(const FString& Variable)
1177{
1178 TArray<FString> Tokens;
1179 Variable.ParseIntoArray(Tokens, TEXT(" "), true);
1180 if (Tokens.Num() < 2)
1181 {
1182 // Not enough arguments, return
1183 return;
1184 }
1185
1186 const FString& ID = Tokens[0];
1187
1188 AActor* Actor = IActorInformation::GetActorByID(ID);
1189 if (!Actor)
1190 {
1191 return;
1192 }
1193
1194 ASensor* Sensor = Cast<ASensor>(Actor);
1195 if (!Sensor)
1196 {
1197 return;
1198 }
1199
1200 FString BooleanString = Tokens[1].ToLower();
1201
1202 bool SimulateSensor;
1203 if (!TryParseBoolean(BooleanString, SimulateSensor))
1204 {
1205 // Failed to parse, return
1206 return;
1207 }
1208
1209 Sensor->SetSimulateSensor(SimulateSensor);
1210}
1211
1212void UROSCommands::HandleSetWPO(const FString& Variable)
1213{
1214 if (Variable.IsNumeric())
1215 {
1216 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
1217 if (AgrarsenseSettings)
1218 {
1219 int32 IntValue = FCString::Atoi(*Variable);
1220 AgrarsenseSettings->SetWorldPositionOffsetRenderDistance(IntValue);
1221 }
1222 }
1223}
1224
1226{
1227 if (Variable.IsNumeric())
1228 {
1229 UAgrarsenseSettings* AgrarsenseSettings = GetSettings();
1230 if (AgrarsenseSettings)
1231 {
1232 float Value = FCString::Atof(*Variable);
1233 AgrarsenseSettings->SetNaniteMaxPixelsPerEdge(Value);
1234 }
1235 }
1236}
1237
1238void UROSCommands::HandleDestroyTreesArea(const FString& Variable)
1239{
1240 HandleDestroyActors(Variable, true);
1241}
1242
1243void UROSCommands::HandleDestroyActorsArea(const FString& Variable)
1244{
1245 HandleDestroyActors(Variable, false);
1246}
1247
1248void UROSCommands::HandleDestroyActors(const FString& Variable, bool OnlyTrees)
1249{
1250 TArray<FString> ParsedStrings;
1251 Variable.ParseIntoArray(ParsedStrings, TEXT(" "), true);
1252
1253 if (ParsedStrings.Num() != 2)
1254 {
1255 return;
1256 }
1257
1258 // Parse position
1259 TArray<FString> PositionComponents;
1260 ParsedStrings[0].ParseIntoArray(PositionComponents, TEXT(","), true);
1261
1262 if (PositionComponents.Num() != 3)
1263 {
1264 return;
1265 }
1266
1267 FVector Position(FCString::Atof(*PositionComponents[0]), FCString::Atof(*PositionComponents[1]), FCString::Atof(*PositionComponents[2]));
1268
1269 // Parse bounds
1270 TArray<FString> BoundsComponents;
1271 ParsedStrings[1].ParseIntoArray(BoundsComponents, TEXT(","), true);
1272
1273 if (BoundsComponents.Num() != 3)
1274 {
1275 return;
1276 }
1277
1278 FVector Bounds(FCString::Atof(*BoundsComponents[0]), FCString::Atof(*BoundsComponents[1]), FCString::Atof(*BoundsComponents[2]));
1279
1280 FTransform VolumeTransform;
1281 VolumeTransform.SetLocation(Position);
1282
1283 UWorld* World = GetGameWorld();
1284 if (World)
1285 {
1286 ADeletionVolume* Volume = World->SpawnActor<ADeletionVolume>(ADeletionVolume::StaticClass(), VolumeTransform);
1287 if (Volume)
1288 {
1289 // Change volume bounds
1290 Volume->ChangeOverlapBounds(Bounds);
1291
1292 // Destroy overlapping actors,
1293 // this Actor gets deleted automatically after calling this.
1294 Volume->DestroyOverlappingActors(OnlyTrees);
1295 }
1296 }
1297}
EDroneEndAction
EROSState
Definition: ROSState.h:16
EWalkerEndAction
void DestroyOverlappingActors(bool OnlyTrees)
void ChangeOverlapBounds(FVector Bounds)
void SetSaveCombinedCloudToDisk(bool bSaveCombinedCloud)
void SetOverlapRelativePosition(const FVector &Vector)
void SetVisualizeOverlapArea(bool Visualize)
void SetOverlapBounds(const FVector &NewSize)
Definition: Sensor.h:45
void SetSimulateSensor(bool SimulateSensor)
Definition: Sensor.h:160
FString ExportToJsonFile(const FString &FileName)
Definition: Sensor.cpp:147
void TeleportSpectator(const FTransform &Transform)
Definition: Spectator.cpp:48
FString ExportToJsonFile(const FString &FileName)
Definition: Vehicle.cpp:176
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