Agrarsense
BoomMovementSubscriber.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
7
11
12#include "ROSIntegration/Classes/ROSIntegrationGameInstance.h"
13#include <geometry_msgs/Twist.h>
14
15#include "Async/Async.h"
16#include "AITypes.h"
17
18UBoomMovementSubscriber::UBoomMovementSubscriber()
19{
20 PrimaryComponentTick.bCanEverTick = false;
21}
22
23void UBoomMovementSubscriber::BeginPlay()
24{
25 Super::BeginPlay();
26
27 CreateROSTopic();
28
29 UROSHandler* RosHandle = UAgrarsenseStatics::GetROSHandle(GetWorld());
30 if (RosHandle)
31 {
32 RosHandle->OnROSStateChanged.AddUniqueDynamic(this, &UBoomMovementSubscriber::ROSBridgeStateChanged);
33 }
34}
35
36void UBoomMovementSubscriber::OnUnregister()
37{
38 Super::OnUnregister();
39
40 DestroyROSTopic();
41
42 UROSHandler* RosHandle = UAgrarsenseStatics::GetROSHandle(GetWorld());
43 if (RosHandle)
44 {
45 RosHandle->OnROSStateChanged.RemoveDynamic(this, &UBoomMovementSubscriber::ROSBridgeStateChanged);
46 }
47}
48
49void UBoomMovementSubscriber::ROSBridgeStateChanged(EROSState rosState)
50{
51 switch (rosState)
52 {
54 CreateROSTopic();
55 break;
56
58 DestroyROSTopic();
59 break;
60 }
61}
62
63void UBoomMovementSubscriber::CreateROSTopic()
64{
65 if (BoomMovementTopic)
66 {
67 return;
68 }
69
70 UROSIntegrationGameInstance* ROSInstance = UAgrarsenseStatics::GetROSGameInstance(GetWorld());
71
72 if (ROSInstance && ROSInstance->IsROSConnected())
73 {
74 FString VehicleName = "Vehicle";
75
76 // Get this Actor this component is attached to
77 AActor* OwnerActor = GetOwner();
78 if (OwnerActor)
79 {
80 // Try to cast the owning actor into AVehicle and
81 // get its ID and use the ID as the vehicle name
82 AVehicle* VehiclePtr = Cast<AVehicle>(OwnerActor);
83 if (VehiclePtr)
84 {
85 VehicleName = VehiclePtr->GetActorID_Implementation();
86 }
87 else
88 {
89 VehicleName = OwnerActor->GetName();
90 }
91 }
92
93 BoomMovementTopic = NewObject<UTopic>(UTopic::StaticClass());
94 BoomMovementTopic->Init(ROSInstance->ROSIntegrationCore, FString::Printf(TEXT("/agrarsense/in/vehicles/%s/boom_movement"), *VehicleName), TEXT("geometry_msgs/Twist"));
95 BoomMovementTopic->Advertise();
96
97 // Create a std::function callback object
98 std::function<void(TSharedPtr<FROSBaseMsg>)> SubscribeCallback = [this](TSharedPtr<FROSBaseMsg> msg) -> void
99 {
100 auto Concrete = StaticCastSharedPtr<ROSMessages::geometry_msgs::Twist>(msg);
101 if (Concrete.IsValid())
102 {
103 FBoomMessageParser Movement;
104 Movement.linear = FVector(Concrete->linear.x, Concrete->linear.y, Concrete->linear.z);
105 Movement.angular = FVector(Concrete->angular.x, Concrete->angular.y, Concrete->angular.z);
106
107 AsyncTask(ENamedThreads::GameThread, [this, Movement]()
108 {
109 OnBoomMessageReceived.Broadcast(Movement);
110 });
111
112 }
113 return;
114 };
115
116 BoomMovementTopic->Subscribe(SubscribeCallback);
117 }
118}
119
120void UBoomMovementSubscriber::DestroyROSTopic()
121{
122 if (BoomMovementTopic)
123 {
124 BoomMovementTopic->Unadvertise();
125 BoomMovementTopic->Unsubscribe();
126 BoomMovementTopic->MarkAsDisconnected();
127 BoomMovementTopic->ConditionalBeginDestroy();
128 BoomMovementTopic = nullptr;
129 }
130}
EROSState
Definition: ROSState.h:16
virtual FString GetActorID_Implementation() const override
Definition: Vehicle.h:203
static UROSIntegrationGameInstance * GetROSGameInstance(const UObject *WorldContextObject)
static UROSHandler * GetROSHandle(const UObject *WorldContextObject)
FROSDelegate_ROState OnROSStateChanged
Definition: ROSHandler.h:81