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